From df7e5dd1dc491e6f2a8bcff44d75f8e2113b8b6f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 20 Jan 2010 15:48:13 -0500
Subject: [PATCH] DEV-35248: Allow NoVerifySSLCert to uniformly disable
 verification Introduce static LLCurl SSL verification flag, default 'true',
 accessed by LLCurl::setSSLVerify() and getSSLVerify(). Make
 LLCurl::Easy::prepRequest() check LLCurl::getSSLVerify() instead of
 unconditionally setting CURLOPT_SSL_VERIFYPEER 'true'. Also set
 CURLOPT_SSL_VERIFYHOST to match. Make LLXMLRPCTransaction::Impl::init()
 examine LLCurl::getSSLVerify(), instead of directly examining
 gSavedSettings.getBOOL("NoVerifySSLCert"). Make
 LLURLRequest::checkRootCertificate() set CURLOPT_SSL_VERIFYHOST as well as
 CURLOPT_SSL_VERIFYPEER. Make request() in llhttpclient.cpp (used by
 LLHTTPClient::getByteRange(), head(), get(), getHeaderOnly(), put(), post(),
 postRaw(), postFile(), del(), move()) pass LLCurl::getSSLVerify() to
 checkRootCertificate(), rather than constant 'true'. Make
 LLAppViewer::mainLoop() call     LLCurl::setSSLVerify(!
 gSavedSettings.getBOOL("NoVerifySSLCert")) at the same time it calls
 LLCurl::setCAFile(), a comparable bit of static setup.

---
 indra/llmessage/llcurl.cpp            | 20 ++++++++++++++++++--
 indra/llmessage/llcurl.h              | 11 +++++++++++
 indra/llmessage/llhttpclient.cpp      |  2 +-
 indra/llmessage/llurlrequest.cpp      |  1 +
 indra/newview/llappviewer.cpp         |  4 ++--
 indra/newview/llxmlrpctransaction.cpp |  5 ++---
 6 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index dc02367a622..024e17a7779 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -89,6 +89,10 @@ S32 gCurlMultiCount = 0;
 std::vector<LLMutex*> LLCurl::sSSLMutex;
 std::string LLCurl::sCAPath;
 std::string LLCurl::sCAFile;
+// Verify SSL certificates by default (matches libcurl default). The ability
+// to alter this flag is only to allow us to suppress verification if it's
+// broken for some reason.
+bool LLCurl::sSSLVerify = true;
 
 //static
 void LLCurl::setCAPath(const std::string& path)
@@ -102,6 +106,18 @@ void LLCurl::setCAFile(const std::string& file)
 	sCAFile = file;
 }
 
+//static
+void LLCurl::setSSLVerify(bool verify)
+{
+	sSSLVerify = verify;
+}
+
+//static
+bool LLCurl::getSSLVerify()
+{
+	return sSSLVerify;
+}
+
 //static
 std::string LLCurl::getVersionString()
 {
@@ -465,7 +481,8 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 	setErrorBuffer();
 	setCA();
 
-	setopt(CURLOPT_SSL_VERIFYPEER, true);
+	setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify());
+	setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify()? 2 : 0);
 	setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
 
 	setoptString(CURLOPT_URL, url);
@@ -1044,4 +1061,3 @@ void LLCurl::cleanupClass()
 #endif
 	curl_global_cleanup();
 }
-
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 1bc17679669..caf02cccd90 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -157,6 +157,16 @@ class LLCurl
 	 */
 	static const std::string& getCAPath() { return sCAPath; }
 
+	/**
+	 * @ brief Set flag controlling whether to verify HTTPS certs.
+	 */
+	static void setSSLVerify(bool verify);
+
+	/**
+	 * @ brief Get flag controlling whether to verify HTTPS certs.
+	 */
+	static bool getSSLVerify();
+
 	/**
 	 * @ brief Initialize LLCurl class
 	 */
@@ -182,6 +192,7 @@ class LLCurl
 private:
 	static std::string sCAPath;
 	static std::string sCAFile;
+	static bool sSSLVerify;
 };
 
 namespace boost
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 12ecbb36eb8..dd56e18caf8 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -222,7 +222,7 @@ static void request(
 	LLPumpIO::chain_t chain;
 
 	LLURLRequest* req = new LLURLRequest(method, url);
-	req->checkRootCertificate(true);
+	req->checkRootCertificate(LLCurl::getSSLVerify());
 
 	
 	lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 81b7761ed5f..4e7ceff9843 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -163,6 +163,7 @@ void LLURLRequest::setBodyLimit(U32 size)
 void LLURLRequest::checkRootCertificate(bool check)
 {
 	mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE));
+	mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, (check? 2 : 0));
 	mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
 }
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 638a8f759db..0e248ff88bf 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -926,7 +926,6 @@ bool LLAppViewer::mainLoop()
 {
 	LLMemType mt1(LLMemType::MTYPE_MAIN);
 	mMainloopTimeout = new LLWatchdogTimeout();
-	// *FIX:Mani - Make this a setting, once new settings exist in this branch.
 	
 	//-------------------------------------------
 	// Run main loop until time to quit
@@ -936,12 +935,13 @@ bool LLAppViewer::mainLoop()
 	gServicePump = new LLPumpIO(gAPRPoolp);
 	LLHTTPClient::setPump(*gServicePump);
 	LLCurl::setCAFile(gDirUtilp->getCAFile());
+	LLCurl::setSSLVerify(! gSavedSettings.getBOOL("NoVerifySSLCert"));
 	
 	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
 
 	LLVoiceChannel::initClass();
 	LLVoiceClient::init(gServicePump);
-				
+
 	LLTimer frameTimer,idleTimer;
 	LLTimer debugTime;
 	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 70859e8ea51..c19be37e75c 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -252,9 +252,8 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
 //	mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
 	mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
 	mCurlRequest->setWriteCallback(&curlDownloadCallback, (void*)this);
-    	BOOL vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
-	mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, vefifySSLCert);
-	mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, vefifySSLCert ? 2 : 0);
+	mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, LLCurl::getSSLVerify());
+	mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, LLCurl::getSSLVerify() ? 2 : 0);
 	// Be a little impatient about establishing connections.
 	mCurlRequest->setopt(CURLOPT_CONNECTTIMEOUT, 40L);
 
-- 
GitLab