From e1c89f08bb78127e20383bffb3d28dfccbe816a0 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Tue, 21 Aug 2012 18:41:24 -0400 Subject: [PATCH] file(DOWNLOAD): Add options for SSL Add the ability to request that downloads disable or enable Certificate Authority checking with https ssl downloads. When the option to verify the servers CA is disabled, one may verify download contents with SHA hashes. --- Source/cmFileCommand.cxx | 67 ++++++++++++++++++++++++++++++++++++++++ Source/cmFileCommand.h | 11 ++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index b0c107071..bb129804e 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2667,6 +2667,9 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) long inactivity_timeout = 0; std::string verboseLog; std::string statusVar; + std::string caFile; + bool checkSSL = false; + bool verifySSL = false; std::string expectedHash; std::string hashMatchMSG; cmsys::auto_ptr hash; @@ -2720,6 +2723,33 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) } statusVar = *i; } + else if(*i == "SSL_VERIFY") + { + ++i; + if(i != args.end()) + { + verifySSL = cmSystemTools::IsOn(i->c_str()); + checkSSL = true; + } + else + { + this->SetError("SSL_VERIFY missing bool value."); + return false; + } + } + else if(*i == "SSL_CAINFO_FILE") + { + ++i; + if(i != args.end()) + { + caFile = *i; + } + else + { + this->SetError("SSL_CAFILE missing file value."); + return false; + } + } else if(*i == "EXPECTED_MD5") { ++i; @@ -2835,6 +2865,43 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) cmFileCommandCurlDebugCallback); check_curl_result(res, "DOWNLOAD cannot set debug function: "); + // check to see if SSL verification is requested + const char* verifyValue = + this->Makefile->GetDefinition("CMAKE_CURLOPT_SSL_VERIFYPEER"); + // if there is a cmake variable or if the command has SSL_VERIFY requested + if(verifyValue || checkSSL) + { + // the args to the command come first + bool verify = verifySSL; + if(!verify && verifyValue) + { + verify = cmSystemTools::IsOn(verifyValue); + } + if(verify) + { + res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); + check_curl_result(res, "Unable to set SSL Verify on: "); + } + else + { + res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + check_curl_result(res, "Unable to set SSL Verify off: "); + } + } + // check to see if a CAINFO file has been specified + const char* cainfo = + this->Makefile->GetDefinition("CMAKE_CURLOPT_CAINFO_FILE"); + // command arg comes first + if(caFile.size()) + { + cainfo = caFile.c_str(); + } + if(cainfo) + { + res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cainfo); + check_curl_result(res, "Unable to set SSL Verify CAINFO: "); + } + cmFileCommandVectorOfChar chunkDebug; res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fout); diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index ca2bdfda6..413e2f4e2 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -84,7 +84,8 @@ public: " file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n" " [EXPECTED_HASH MD5|SHA1|SHA224|SHA256|SHA384|SHA512 hash]\n" - " [EXPECTED_MD5 sum])\n" + " [EXPECTED_MD5 sum]\n" + " [SSL_VERIFY on|off] [SSL_CAINFO_FILE file])\n" " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n" "WRITE will write a message into a file called 'filename'. It " @@ -175,6 +176,14 @@ public: "(EXPECTED_MD5 is short-hand for EXPECTED_HASH MD5.) " "If SHOW_PROGRESS is specified, progress information will be printed " "as status messages until the operation is complete. " + "For https URLs CMake must be built with OpenSSL. " + "SSL certificates are not checked by default. " + "Set SSL_VERIFY to ON to check certificates and/or use " + "EXPECTED_HASH to verify downloaded content. " + "Set SSL_CAINFO_FILE to specify a custom Certificate Authority file. " + "If either SSL option is not given CMake will check variables " + "CMAKE_CURLOPT_SSL_VERIFYPEER and CMAKE_CURLOPT_CAINFO_FILE, " + "respectively." "\n" "UPLOAD will upload the given file to the given URL. " "If LOG var is specified a log of the upload will be put in var. "