comparison Core/HttpClient.cpp @ 1534:95b3b0260240

Options to validate peers against CA certificates in HTTPS requests
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 13 Aug 2015 12:42:32 +0200
parents 0011cc99443c
children ba0226474e22
comparison
equal deleted inserted replaced
1533:0011cc99443c 1534:95b3b0260240
40 #include <string.h> 40 #include <string.h>
41 #include <curl/curl.h> 41 #include <curl/curl.h>
42 #include <boost/algorithm/string/predicate.hpp> 42 #include <boost/algorithm/string/predicate.hpp>
43 43
44 44
45 static std::string cacert_; 45 static std::string globalCACertificates_;
46 static bool httpsVerifyPeers_ = true; 46 static bool globalVerifyPeers_ = true;
47 47
48 extern "C" 48 extern "C"
49 { 49 {
50 static CURLcode GetHttpStatus(CURLcode code, CURL* curl, long* status) 50 static CURLcode GetHttpStatus(CURLcode code, CURL* curl, long* status)
51 { 51 {
129 129
130 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEFUNCTION, &CurlCallback)); 130 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEFUNCTION, &CurlCallback));
131 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADER, 0)); 131 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADER, 0));
132 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_FOLLOWLOCATION, 1)); 132 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_FOLLOWLOCATION, 1));
133 133
134 #if ORTHANC_SSL_ENABLED == 1
135 if (httpsVerifyPeers_)
136 {
137 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CAINFO, cacert_.c_str()));
138 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 1));
139 }
140 else
141 {
142 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 0));
143 }
144 #endif
145
146 // This fixes the "longjmp causes uninitialized stack frame" crash 134 // This fixes the "longjmp causes uninitialized stack frame" crash
147 // that happens on modern Linux versions. 135 // that happens on modern Linux versions.
148 // http://stackoverflow.com/questions/9191668/error-longjmp-causes-uninitialized-stack-frame 136 // http://stackoverflow.com/questions/9191668/error-longjmp-causes-uninitialized-stack-frame
149 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_NOSIGNAL, 1)); 137 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_NOSIGNAL, 1));
150 138
151 url_ = ""; 139 url_ = "";
152 method_ = HttpMethod_Get; 140 method_ = HttpMethod_Get;
153 lastStatus_ = HttpStatus_200_Ok; 141 lastStatus_ = HttpStatus_200_Ok;
154 isVerbose_ = false; 142 isVerbose_ = false;
155 timeout_ = 0; 143 timeout_ = 0;
144 verifyPeers_ = globalVerifyPeers_;
156 } 145 }
157 146
158 147
159 HttpClient::HttpClient() : pimpl_(new PImpl) 148 HttpClient::HttpClient() : pimpl_(new PImpl)
160 { 149 {
203 bool HttpClient::Apply(std::string& answer) 192 bool HttpClient::Apply(std::string& answer)
204 { 193 {
205 answer.clear(); 194 answer.clear();
206 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_URL, url_.c_str())); 195 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_URL, url_.c_str()));
207 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEDATA, &answer)); 196 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEDATA, &answer));
197
198 // Setup HTTPS-related options
199 #if ORTHANC_SSL_ENABLED == 1
200 if (IsHttpsVerifyPeers())
201 {
202 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CAINFO, GetHttpsCACertificates().c_str()));
203 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 1));
204 }
205 else
206 {
207 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 0));
208 }
209 #endif
208 210
209 // Reset the parameters from previous calls to Apply() 211 // Reset the parameters from previous calls to Apply()
210 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPHEADER, NULL)); 212 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPHEADER, NULL));
211 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPGET, 0L)); 213 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPGET, 0L));
212 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POST, 0L)); 214 CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POST, 0L));
334 { 336 {
335 credentials_ = std::string(username) + ":" + std::string(password); 337 credentials_ = std::string(username) + ":" + std::string(password);
336 } 338 }
337 339
338 340
341 const std::string& HttpClient::GetHttpsCACertificates() const
342 {
343 if (caCertificates_.empty())
344 {
345 return globalCACertificates_;
346 }
347 else
348 {
349 return caCertificates_;
350 }
351 }
352
353
339 void HttpClient::GlobalInitialize(bool httpsVerifyPeers, 354 void HttpClient::GlobalInitialize(bool httpsVerifyPeers,
340 const std::string& httpsVerifyCertificates) 355 const std::string& httpsVerifyCertificates)
341 { 356 {
357 globalVerifyPeers_ = httpsVerifyPeers;
358 globalCACertificates_ = httpsVerifyCertificates;
359
342 #if ORTHANC_SSL_ENABLED == 1 360 #if ORTHANC_SSL_ENABLED == 1
343 httpsVerifyPeers_ = httpsVerifyPeers;
344 cacert_ = httpsVerifyCertificates;
345
346 // TODO
347 /*if (cacert_.empty())
348 {
349 cacert_ = "/etc/ssl/certs/ca-certificates.crt";
350 }*/
351
352 if (httpsVerifyPeers) 361 if (httpsVerifyPeers)
353 { 362 {
354 if (cacert_.empty()) 363 if (globalCACertificates_.empty())
355 { 364 {
356 LOG(WARNING) << "No certificates are provided to validate peers, " 365 LOG(WARNING) << "No certificates are provided to validate peers, "
357 << "set \"HttpsCertificatesFile\" if you need to do HTTPS requests"; 366 << "set \"HttpsCACertificates\" if you need to do HTTPS requests";
358 } 367 }
359 else 368 else
360 { 369 {
361 LOG(WARNING) << "HTTPS will use the certificates from this file: " << cacert_; 370 LOG(WARNING) << "HTTPS will use the CA certificates from this file: " << globalCACertificates_;
362 } 371 }
363 } 372 }
364 else 373 else
365 { 374 {
366 LOG(WARNING) << "The verification of the peers in HTTPS requests is disabled!"; 375 LOG(WARNING) << "The verification of the peers in HTTPS requests is disabled!";