Mercurial > hg > orthanc
diff Core/HttpClient.cpp @ 1533:0011cc99443c
improving HTTPS support
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 12 Aug 2015 17:52:10 +0200 |
parents | 8a330b258491 |
children | 95b3b0260240 |
line wrap: on
line diff
--- a/Core/HttpClient.cpp Wed Aug 12 15:04:12 2015 +0200 +++ b/Core/HttpClient.cpp Wed Aug 12 17:52:10 2015 +0200 @@ -35,9 +35,43 @@ #include "Toolbox.h" #include "OrthancException.h" +#include "Logging.h" #include <string.h> #include <curl/curl.h> +#include <boost/algorithm/string/predicate.hpp> + + +static std::string cacert_; +static bool httpsVerifyPeers_ = true; + +extern "C" +{ + static CURLcode GetHttpStatus(CURLcode code, CURL* curl, long* status) + { + if (code == CURLE_OK) + { + code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, status); + return code; + } + else + { + *status = 0; + return code; + } + } + + // This is a dummy wrapper function to suppress any OpenSSL-related + // problem in valgrind. Inlining is prevented. +#if defined(__GNUC__) || defined(__clang__) + __attribute__((noinline)) +#endif + static CURLcode OrthancHttpClientPerformSSL(CURL* curl, long* status) + { + return GetHttpStatus(curl_easy_perform(curl), curl, status); + } +} + namespace Orthanc @@ -53,7 +87,8 @@ { if (code != CURLE_OK) { - throw OrthancException("libCURL error: " + std::string(curl_easy_strerror(code))); + LOG(ERROR) << "libCURL error: " + std::string(curl_easy_strerror(code)); + throw OrthancException(ErrorCode_NetworkProtocol); } return code; @@ -97,7 +132,15 @@ CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_FOLLOWLOCATION, 1)); #if ORTHANC_SSL_ENABLED == 1 - CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 0)); + if (httpsVerifyPeers_) + { + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CAINFO, cacert_.c_str())); + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 1)); + } + else + { + CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 0)); + } #endif // This fixes the "longjmp causes uninitialized stack frame" crash @@ -243,10 +286,19 @@ // Do the actual request - CheckCode(curl_easy_perform(pimpl_->curl_)); + CURLcode code; + long status = 0; - long status; - CheckCode(curl_easy_getinfo(pimpl_->curl_, CURLINFO_RESPONSE_CODE, &status)); + if (boost::starts_with(url_, "https://")) + { + code = OrthancHttpClientPerformSSL(pimpl_->curl_, &status); + } + else + { + code = GetHttpStatus(curl_easy_perform(pimpl_->curl_), pimpl_->curl_, &status); + } + + CheckCode(code); if (status == 0) { @@ -284,10 +336,40 @@ } - void HttpClient::GlobalInitialize() + void HttpClient::GlobalInitialize(bool httpsVerifyPeers, + const std::string& httpsVerifyCertificates) { +#if ORTHANC_SSL_ENABLED == 1 + httpsVerifyPeers_ = httpsVerifyPeers; + cacert_ = httpsVerifyCertificates; + + // TODO + /*if (cacert_.empty()) + { + cacert_ = "/etc/ssl/certs/ca-certificates.crt"; + }*/ + + if (httpsVerifyPeers) + { + if (cacert_.empty()) + { + LOG(WARNING) << "No certificates are provided to validate peers, " + << "set \"HttpsCertificatesFile\" if you need to do HTTPS requests"; + } + else + { + LOG(WARNING) << "HTTPS will use the certificates from this file: " << cacert_; + } + } + else + { + LOG(WARNING) << "The verification of the peers in HTTPS requests is disabled!"; + } +#endif + CheckCode(curl_global_init(CURL_GLOBAL_DEFAULT)); } + void HttpClient::GlobalFinalize() {