diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index f79b61760..3be8a3504 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -66,6 +66,8 @@ namespace NLGUI
std::vector< std::string > trustedDomains;
/// Maximum concurrent MultiCurl connections per CGroupHTML instance
sint32 curlMaxConnections;
+ /// cacert.pem location
+ std::string curlCABundle;
SWebOptions(): curlMaxConnections(2)
{
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 99c35ca07..b943c4dfc 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -395,13 +395,18 @@ namespace NLGUI
return false;
}
-#if defined(NL_OS_WINDOWS)
// https://
if (toLower(download.url.substr(0, 8)) == "https://")
{
+#if defined(NL_OS_WINDOWS)
curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, &CCurlCertificates::sslCtxFunction);
- }
+#else
+ if (!options.curlCABundle.empty())
+ {
+ curl_easy_setopt(curl, CURLOPT_CAINFO, options.curlCABundle.c_str());
+ }
#endif
+ }
download.data = new CCurlWWWData(curl, download.url);
download.fp = fp;
@@ -5356,13 +5361,18 @@ namespace NLGUI
return;
}
-#if defined(NL_OS_WINDOWS)
// https://
if (toLower(url.substr(0, 8)) == "https://")
{
+#if defined(NL_OS_WINDOWS)
curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, &CCurlCertificates::sslCtxFunction);
- }
+#else
+ if (!options.curlCABundle.empty())
+ {
+ curl_easy_setopt(curl, CURLOPT_CAINFO, options.curlCABundle.c_str());
+ }
#endif
+ }
// do not follow redirects, we have own handler
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0);
diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg
index b99d5b287..6552e63d1 100644
--- a/code/ryzom/client/client_default.cfg
+++ b/code/ryzom/client/client_default.cfg
@@ -48,6 +48,11 @@ ConditionsTermsURL = "http://app.ryzom.com/app_forum/index.php?page=topic/view/2
LoginSupportURL = "http://app.ryzom.com/app_forum/index.php?page=topic/view/22047/1&post149889=en#1";
NamingPolicyURL = "http://app.ryzom.com/app_forum/index.php?page=topic/view/21885/1&post148784=en#3";
+// Full path and filename where cURL can find certificate bundle file
+// cacert.pem file can be downloaded from https://curl.haxx.se/docs/caextract.html
+// and added to client data path or system specific bundle can be used
+// Ubuntu has "/etc/ssl/certs/ca-certificates.crt"
+//CurlCABundle = "cacert.pem";
////////////////
// INTERFACES //
diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp
index d51047015..5d8d968d2 100644
--- a/code/ryzom/client/src/client_cfg.cpp
+++ b/code/ryzom/client/src/client_cfg.cpp
@@ -426,6 +426,7 @@ CClientConfig::CClientConfig()
WebIgTrustedDomains.push_back(WebIgMainDomain);
CurlMaxConnections = 2;
+ CurlCABundle.clear();
RingReleaseNotePath = "http://" + WebIgMainDomain + "/releasenotes_ring/index.php";
ReleaseNotePath = "http://" + WebIgMainDomain + "/releasenotes/index.php";
@@ -1077,6 +1078,8 @@ void CClientConfig::setValues()
if (ClientCfg.CurlMaxConnections < 0)
ClientCfg.CurlMaxConnections = 2;
+ READ_STRING_FV(CurlCABundle);
+
///////////////
// ANIMATION //
// AnimatedAngleThreshold
diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h
index aa9eba8c2..f562dfde0 100644
--- a/code/ryzom/client/src/client_cfg.h
+++ b/code/ryzom/client/src/client_cfg.h
@@ -308,6 +308,7 @@ struct CClientConfig
std::vector WebIgTrustedDomains;
sint32 CurlMaxConnections;
+ string CurlCABundle;
///////////////
// ANIMATION //
diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp
index 45b960a8f..bdf577c8f 100644
--- a/code/ryzom/client/src/interface_v3/interface_manager.cpp
+++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp
@@ -471,6 +471,16 @@ CInterfaceManager::CInterfaceManager()
CGroupHTML::options.appName = getUserAgentName();
CGroupHTML::options.appVersion = getUserAgentVersion();
CGroupHTML::options.curlMaxConnections = ClientCfg.CurlMaxConnections;
+ if (!ClientCfg.CurlCABundle.empty())
+ {
+ string filename = CPath::lookup(ClientCfg.CurlCABundle, false);
+ if (!filename.empty())
+ {
+ filename = CPath::getFullPath(filename, false);
+ CGroupHTML::options.curlCABundle = filename;
+ nlinfo("curl ca bundle '%s'", filename.c_str());
+ }
+ }
NLGUI::CDBManager::getInstance()->resizeBanks( NB_CDB_BANKS );
interfaceLinkUpdater = new CInterfaceLink::CInterfaceLinkUpdater();