diff options
author | Roxanne Skelly <roxie@lindenlab.com> | 2009-07-09 21:45:04 +0000 |
---|---|---|
committer | Roxanne Skelly <roxie@lindenlab.com> | 2009-07-09 21:45:04 +0000 |
commit | e65b6d96957fd92fdc8c5a42b1ad4b1a153552b3 (patch) | |
tree | 0eff61a199c8c9386d6ef19b27f243150b557dd2 | |
parent | 7a64aad1def1b0612addbf2e66c66db061d7e182 (diff) |
DEV-34822
svn merge -c120157 svn+ssh://svn.lindenlab.com/svn/linden/branches/giab-viewer/giab-viewer-2
-rw-r--r-- | indra/llmessage/llhttpclient.cpp | 16 | ||||
-rw-r--r-- | indra/llmessage/llhttpclient.h | 11 | ||||
-rw-r--r-- | indra/llmessage/llurlrequest.cpp | 52 | ||||
-rw-r--r-- | indra/llmessage/llurlrequest.h | 68 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llsecapi.cpp | 37 | ||||
-rw-r--r-- | indra/newview/llsecapi.h | 4 | ||||
-rw-r--r-- | indra/newview/llworld.cpp | 3 |
8 files changed, 119 insertions, 73 deletions
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 12ecbb36eb..345b76d1a1 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -31,7 +31,7 @@ */ #include "linden_common.h" - +#include <openssl/x509_vfy.h> #include "llhttpclient.h" #include "llassetstorage.h" @@ -46,7 +46,10 @@ #include "message.h" #include <curl/curl.h> + const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; +LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL; + //////////////////////////////////////////////////////////////////////////// // Responder class moved to LLCurl @@ -206,13 +209,19 @@ namespace LLPumpIO* theClientPump = NULL; } +void LLHTTPClient::setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback) +{ + LLHTTPClient::mCertVerifyCallback = callback; +} + static void request( const std::string& url, LLURLRequest::ERequestAction method, Injector* body_injector, LLCurl::ResponderPtr responder, const F32 timeout = HTTP_REQUEST_EXPIRY_SECS, - const LLSD& headers = LLSD()) + const LLSD& headers = LLSD() + ) { if (!LLHTTPClient::hasPump()) { @@ -222,7 +231,7 @@ static void request( LLPumpIO::chain_t chain; LLURLRequest* req = new LLURLRequest(method, url); - req->checkRootCertificate(true); + req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req); lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " " @@ -417,7 +426,6 @@ static LLSD blocking_request( std::string body_str; // other request method checks root cert first, we skip? - //req->checkRootCertificate(true); // * Set curl handle options curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 3d0646e5fe..8afbc9e0fc 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -40,7 +40,8 @@ #include <string> #include <boost/intrusive_ptr.hpp> - +#include <openssl/x509_vfy.h> +#include "llurlrequest.h" #include "llassettype.h" #include "llcurl.h" #include "lliopipe.h" @@ -61,6 +62,7 @@ public: typedef LLCurl::Responder Responder; typedef LLCurl::ResponderPtr ResponderPtr; + /** @name non-blocking API */ //@{ static void head( @@ -155,7 +157,12 @@ public: static void setPump(LLPumpIO& pump); ///< must be called before any of the above calls are made static bool hasPump(); - ///< for testing + + static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback); + static LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; } + +protected: + static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback; }; #endif // LL_LLHTTPCLIENT_H diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 81b7761ed5..752be49663 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -36,7 +36,8 @@ #include "llurlrequest.h" #include <algorithm> - +#include <openssl/x509_vfy.h> +#include <openssl/ssl.h> #include "llcurl.h" #include "llioutil.h" #include "llmemtype.h" @@ -56,6 +57,8 @@ const std::string CONTEXT_TRANSFERED_BYTES("transfered_bytes"); static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user); + + /** * class LLURLRequestDetail */ @@ -72,6 +75,8 @@ public: U32 mBodyLimit; S32 mByteAccumulator; bool mIsBodyLimitSet; + LLURLRequest::SSLCertVerifyCallback mSSLVerifyCallback; + void * mSSLVerifyParam; }; LLURLRequestDetail::LLURLRequestDetail() : @@ -80,7 +85,8 @@ LLURLRequestDetail::LLURLRequestDetail() : mLastRead(NULL), mBodyLimit(0), mByteAccumulator(0), - mIsBodyLimitSet(false) + mIsBodyLimitSet(false), + mSSLVerifyCallback(NULL) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mCurlRequest = new LLCurlEasyRequest(); @@ -94,6 +100,37 @@ LLURLRequestDetail::~LLURLRequestDetail() mLastRead = NULL; } +void LLURLRequest::setSSLVerifyCallback(SSLCertVerifyCallback callback, void *param) +{ + mDetail->mSSLVerifyCallback = callback; + mDetail->mSSLVerifyParam = param; + mDetail->mCurlRequest->setSSLCtxCallback(LLURLRequest::_sslCtxCallback, (void *)this); + mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, true); + mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, 2); +} + + +// _sslCtxFunction +// Callback function called when an SSL Context is created via CURL +// used to configure the context for custom cert validation + +CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param) +{ + LLURLRequest *req = (LLURLRequest *)param; + if(req == NULL || req->mDetail->mSSLVerifyCallback == NULL) + { + SSL_CTX_set_cert_verify_callback((SSL_CTX *)sslctx, NULL, NULL); + return CURLE_OK; + } + SSL_CTX * ctx = (SSL_CTX *) sslctx; + // disable any default verification for server certs + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + // set the verification callback. + SSL_CTX_set_cert_verify_callback(ctx, req->mDetail->mSSLVerifyCallback, (void *)req); + // the calls are void + return CURLE_OK; + +} /** * class LLURLRequest @@ -148,6 +185,11 @@ void LLURLRequest::setURL(const std::string& url) mDetail->mURL = url; } +std::string LLURLRequest::getURL() const +{ + return mDetail->mURL; +} + void LLURLRequest::addHeader(const char* header) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); @@ -160,12 +202,6 @@ void LLURLRequest::setBodyLimit(U32 size) mDetail->mIsBodyLimitSet = true; } -void LLURLRequest::checkRootCertificate(bool check) -{ - mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE)); - mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, ""); -} - void LLURLRequest::setCallback(LLURLRequestComplete* callback) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index cb3c466440..69fd22e592 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -44,6 +44,8 @@ #include "lliopipe.h" #include "llchainio.h" #include "llerror.h" +#include <openssl/x509_vfy.h> +#include "llcurl.h" extern const std::string CONTEXT_REQUEST; @@ -72,6 +74,8 @@ class LLURLRequest : public LLIOPipe { LOG_CLASS(LLURLRequest); public: + + typedef int (* SSLCertVerifyCallback)(X509_STORE_CTX *ctx, void *param); /** * @brief This enumeration is for specifying the type of request. */ @@ -125,7 +129,7 @@ public: * */ void setURL(const std::string& url); - + std::string getURL() const; /** * @brief Add a header to the http post. * @@ -143,8 +147,9 @@ public: * Set whether request will check that remote server * certificates are signed by a known root CA when using HTTPS. */ - void checkRootCertificate(bool check); + void setSSLVerifyCallback(SSLCertVerifyCallback callback, void * param); + /** * @brief Return at most size bytes of body. * @@ -189,6 +194,7 @@ public: * @brief Give this pipe a chance to handle a generated error */ virtual EStatus handleError(EStatus status, LLPumpIO* pump); + protected: /** @@ -217,6 +223,8 @@ protected: S32 mRequestTransferedBytes; S32 mResponseTransferedBytes; + static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param); + private: /** * @brief Initialize the object. Called during construction. @@ -364,62 +372,6 @@ protected: }; -/** - * @class LLURLRequestClientFactory - * @brief Template class to build url request based client chains - * - * This class eases construction of a basic sd rpc client. Here is an - * example of it's use: - * <code> - * class LLUsefulService : public LLService { ... }<br> - * LLService::registerCreator(<br> - * "useful",<br> - * LLService::creator_t(new LLURLRequestClientFactory<LLUsefulService>))<br> - * </code> - * - * This class should work, but I never got around to using/testing it. - * - */ -#if 0 -template<class Client> -class LLURLRequestClientFactory : public LLChainIOFactory -{ -public: - LLURLRequestClientFactory(LLURLRequest::ERequestAction action) {} - LLURLRequestClientFactory( - LLURLRequest::ERequestAction action, - const std::string& fixed_url) : - mAction(action), - mURL(fixed_url) - { - } - virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const - { - lldebugs << "LLURLRequestClientFactory::build" << llendl; - LLIOPipe::ptr_t service(new Client); - chain.push_back(service); - LLURLRequest* http(new LLURLRequest(mAction)); - LLIOPipe::ptr_t http_pipe(http); - // *FIX: how do we know the content type? - //http->addHeader("Content-Type: text/llsd"); - if(mURL.empty()) - { - chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http))); - } - else - { - http->setURL(mURL); - } - chain.push_back(http_pipe); - chain.push_back(service); - return true; - } - -protected: - LLURLRequest::ERequestAction mAction; - std::string mURL; -}; -#endif /** * External constants diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d1e33fa91a..187038ab15 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -621,6 +621,7 @@ bool LLAppViewer::init() initThreads(); initializeSecHandler(); + LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback); writeSystemInfo(); // Build a string representing the current version number. diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp index 70c247c2de..26bdfd19da 100644 --- a/indra/newview/llsecapi.cpp +++ b/indra/newview/llsecapi.cpp @@ -36,6 +36,8 @@ #include "llsechandler_basic.h" #include <openssl/evp.h> #include <map> +#include "llhttpclient.h" + std::map<std::string, LLPointer<LLSecAPIHandler> > gHandlerMap; @@ -79,7 +81,42 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred) return s << (std::string)cred; } + +// secapiSSLCertVerifyCallback +// basic callback called when a cert verification is requested. +// calls SECAPI to validate the context +// not initialized in the above initialization function, due to unit tests +// see llappviewer +int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param) +{ + LLURLRequest *req = (LLURLRequest *)param; + LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore(""); + LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx); + LLSD validation_params = LLSD::emptyMap(); + LLURI uri(req->getURL()); + validation_params[CERT_HOSTNAME] = uri.hostName(); + try + { + chain->validate(VALIDATION_POLICY_SSL, store, validation_params); + } + catch (LLCertValidationTrustException& cert_exception) + { + LL_WARNS("AppInit") << "Cert not trusted: " << cert_exception.getMessage() << LL_ENDL; + return 0; + } + catch (LLCertException& cert_exception) + { + LL_WARNS("AppInit") << "cert error " << cert_exception.getMessage() << LL_ENDL; + return 0; + } + catch (...) + { + LL_WARNS("AppInit") << "cert error " << LL_ENDL; + return 0; + } + return 1; +} LLSD LLCredential::getLoginParams() { diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index 6fd12c044a..d3fb3c4c07 100644 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -474,4 +474,8 @@ void registerSecHandler(const std::string& handler_type, extern LLPointer<LLSecAPIHandler> gSecAPIHandler; + +int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param); + + #endif // LL_SECAPI_H diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 118d7f8d08..ed70be7b9f 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -132,10 +132,11 @@ void LLWorld::destroyClass() LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) { LLMemType mt(LLMemType::MTYPE_REGIONS); - + llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl; LLViewerRegion *regionp = getRegionFromHandle(region_handle); if (regionp) { + llinfos << "Region exists, removing it " << llendl; LLHost old_host = regionp->getHost(); // region already exists! if (host == old_host && regionp->isAlive()) |