diff options
author | Brad King <brad.king@kitware.com> | 2024-02-26 16:44:20 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2024-02-29 00:11:29 (GMT) |
commit | 2ef3bd9186e58d6486176417b5ef2de99b815820 (patch) | |
tree | fe9b2772d1e04c987d9686977bc9b47a6eb46a3a | |
parent | f0a36b1a7636e827893df9adc6c472023605e67e (diff) | |
download | CMake-2ef3bd9186e58d6486176417b5ef2de99b815820.zip CMake-2ef3bd9186e58d6486176417b5ef2de99b815820.tar.gz CMake-2ef3bd9186e58d6486176417b5ef2de99b815820.tar.bz2 |
ExternalProject: Add TLS version options for https connections
Add a `TLS_VERSION` option and honor `CMAKE_TLS_VERSION` variables.
Also map the version to Git options as we already do for `TLS_VERIFY`.
Issue: #25701
17 files changed, 127 insertions, 0 deletions
diff --git a/Help/envvar/CMAKE_TLS_VERSION.rst b/Help/envvar/CMAKE_TLS_VERSION.rst index 3bb2c97..c411861 100644 --- a/Help/envvar/CMAKE_TLS_VERSION.rst +++ b/Help/envvar/CMAKE_TLS_VERSION.rst @@ -10,3 +10,7 @@ Specify the default value for the :command:`file(DOWNLOAD)` and This environment variable is used if the option is not given and the :variable:`CMAKE_TLS_VERSION` cmake variable is not set. See that variable for allowed values. + +This variable is also used by the :module:`ExternalProject` and +:module:`FetchContent` modules for internal calls to +:command:`file(DOWNLOAD)` and ``git clone``. diff --git a/Help/release/dev/curl-tls-version.rst b/Help/release/dev/curl-tls-version.rst index 999e20c..4b7fe44 100644 --- a/Help/release/dev/curl-tls-version.rst +++ b/Help/release/dev/curl-tls-version.rst @@ -9,3 +9,9 @@ curl-tls-version environment variable were added to specify a default minimum TLS version for connections to ``https://`` URLs by the :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands. + +* The :module:`ExternalProject` module's :command:`ExternalProject_Add` + command gained a ``TLS_VERSION <min>`` option, and support for the + :variable:`CMAKE_TLS_VERSION` variable and :envvar:`CMAKE_TLS_VERSION` + environment variable, to specify the minimum TLS version for connections + to ``https://`` URLs. diff --git a/Help/variable/CMAKE_TLS_VERSION.rst b/Help/variable/CMAKE_TLS_VERSION.rst index e4d9e7b..ed93081 100644 --- a/Help/variable/CMAKE_TLS_VERSION.rst +++ b/Help/variable/CMAKE_TLS_VERSION.rst @@ -17,3 +17,7 @@ The value may be one of: * ``1.2`` * ``1.3`` + +This variable is also used by the :module:`ExternalProject` and +:module:`FetchContent` modules for internal calls to +:command:`file(DOWNLOAD)` and ``git clone``. diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 2844b93..5644cf5 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -225,6 +225,21 @@ URL Provides an arbitrary list of HTTP headers for the download operation. This can be useful for accessing content in systems like AWS, etc. +``TLS_VERSION <min>`` + .. versionadded:: 3.30 + + Specify minimum TLS version for ``https://`` URLs. If this option is + not provided, the value of the :variable:`CMAKE_TLS_VERSION` variable + or the :envvar:`CMAKE_TLS_VERSION` environment variable will be used + instead (see :command:`file(DOWNLOAD)`). + + This option also applies to ``git clone`` invocations, although the + default behavior is different. If none of the ``TLS_VERSION`` option, + :variable:`CMAKE_TLS_VERSION` variable, or :envvar:`CMAKE_TLS_VERSION` + environment variable is specified, the behavior will be determined by + git's default or a ``http.sslVersion`` git config option the user may + have set at a global level. + ``TLS_VERIFY <bool>`` Specifies whether certificate verification should be performed for ``https://`` URLs. If this option is not provided, the default behavior @@ -1345,6 +1360,27 @@ define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED) define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED) define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED) +function(_ep_get_tls_version name tls_version_var) + set(tls_version_regex "^1\\.[0-3]$") + get_property(tls_version TARGET ${name} PROPERTY _EP_TLS_VERSION) + if(NOT "x${tls_version}" STREQUAL "x") + if(NOT tls_version MATCHES "${tls_version_regex}") + message(FATAL_ERROR "TLS_VERSION '${tls_version}' not known") + endif() + elseif(NOT "x${CMAKE_TLS_VERSION}" STREQUAL "x") + set(tls_version "${CMAKE_TLS_VERSION}") + if(NOT tls_version MATCHES "${tls_version_regex}") + message(FATAL_ERROR "CMAKE_TLS_VERSION '${tls_version}' not known") + endif() + elseif(NOT "x$ENV{CMAKE_TLS_VERSION}" STREQUAL "x") + set(tls_version "$ENV{CMAKE_TLS_VERSION}") + if(NOT tls_version MATCHES "${tls_version_regex}") + message(FATAL_ERROR "ENV{CMAKE_TLS_VERSION} '${tls_version}' not known") + endif() + endif() + set("${tls_version_var}" "${tls_version}" PARENT_SCOPE) +endfunction() + function(_ep_get_tls_verify name tls_verify_var) get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY) if("x${tls_verify}" STREQUAL "x" AND DEFINED CMAKE_TLS_VERIFY) @@ -1394,6 +1430,7 @@ function(_ep_write_gitclone_script work_dir gitclone_infofile gitclone_stampfile + tls_version tls_verify ) @@ -1439,6 +1476,10 @@ function(_ep_write_gitclone_script # same config option in the update step too for submodules, but not for # the main git repo. set(git_submodules_config_options "") + if(NOT "x${tls_version}" STREQUAL "x") + list(APPEND git_clone_options -c http.sslVersion=tlsv${tls_version}) + list(APPEND git_submodules_config_options -c http.sslVersion=tlsv${tls_version}) + endif() if(NOT "x${tls_verify}" STREQUAL "x") if(tls_verify) # Default git behavior is "true", but the user might have changed the @@ -1496,6 +1537,7 @@ function(_ep_write_gitupdate_script git_repository work_dir git_update_strategy + tls_version tls_verify ) @@ -1516,6 +1558,9 @@ function(_ep_write_gitupdate_script # We don't need to set it for the non-submodule update because it gets # recorded as part of the clone operation in a sticky manner. set(git_submodules_config_options "") + if(NOT "x${tls_version}" STREQUAL "x") + list(APPEND git_submodules_config_options -c http.sslVersion=tlsv${tls_version}) + endif() if(NOT "x${tls_verify}" STREQUAL "x") if(tls_verify) # Default git behavior is "true", but the user might have changed the @@ -1542,6 +1587,7 @@ function(_ep_write_downloadfile_script inactivity_timeout no_progress hash + tls_version tls_verify tls_cainfo userpwd @@ -1594,6 +1640,11 @@ function(_ep_write_downloadfile_script set(EXPECT_VALUE "") endif() + set(TLS_VERSION_CODE "") + if(NOT "x${tls_version}" STREQUAL "x") + set(TLS_VERSION_CODE "set(CMAKE_TLS_VERSION \"${tls_version}\")") + endif() + set(TLS_VERIFY_CODE "") if(NOT "x${tls_verify}" STREQUAL "x") set(TLS_VERIFY_CODE "set(CMAKE_TLS_VERIFY \"${tls_verify}\")") @@ -1630,6 +1681,7 @@ function(_ep_write_downloadfile_script endif() # Used variables: + # * TLS_VERSION_CODE # * TLS_VERIFY_CODE # * TLS_CAINFO_CODE # * ALGO @@ -2967,6 +3019,7 @@ function(_ep_add_download_command name) set(git_remote_name "origin") endif() + _ep_get_tls_version(${name} tls_version) _ep_get_tls_verify(${name} tls_verify) get_property(git_shallow TARGET ${name} PROPERTY _EP_GIT_SHALLOW) get_property(git_progress TARGET ${name} PROPERTY _EP_GIT_PROGRESS) @@ -3017,6 +3070,7 @@ CMP0097=${_EP_CMP0097} ${work_dir} ${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt + "${tls_version}" "${tls_verify}" ) set(comment "Performing download step (git clone) for '${name}'") @@ -3151,6 +3205,7 @@ hash=${hash} TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS ) + _ep_get_tls_version(${name} tls_version) _ep_get_tls_verify(${name} tls_verify) _ep_get_tls_cainfo(${name} tls_cainfo) _ep_get_netrc(${name} netrc) @@ -3167,6 +3222,7 @@ hash=${hash} "${inactivity_timeout}" "${no_progress}" "${hash}" + "${tls_version}" "${tls_verify}" "${tls_cainfo}" "${http_username}:${http_password}" @@ -3477,6 +3533,7 @@ function(_ep_add_update_command name) _ep_get_git_submodules_recurse(git_submodules_recurse) + _ep_get_tls_version(${name} tls_version) _ep_get_tls_verify(${name} tls_verify) set(update_script "${tmp_dir}/${name}-gitupdate.cmake") @@ -3492,6 +3549,7 @@ function(_ep_add_update_command name) "${git_repository}" "${work_dir}" "${git_update_strategy}" + "${tls_version}" "${tls_verify}" ) set(cmd ${CMAKE_COMMAND} -Dcan_fetch=YES -P ${update_script}) @@ -4265,6 +4323,7 @@ function(ExternalProject_Add name) HTTP_USERNAME HTTP_PASSWORD HTTP_HEADER + TLS_VERSION # Also used for git clone operations TLS_VERIFY # Also used for git clone operations TLS_CAINFO NETRC diff --git a/Modules/ExternalProject/download.cmake.in b/Modules/ExternalProject/download.cmake.in index 0ad0dd3..2158ffd 100644 --- a/Modules/ExternalProject/download.cmake.in +++ b/Modules/ExternalProject/download.cmake.in @@ -111,6 +111,7 @@ foreach(i RANGE ${retry_number}) if(NOT url IN_LIST skip_url_list) message(STATUS "Using src='${url}'") + @TLS_VERSION_CODE@ @TLS_VERIFY_CODE@ @TLS_CAINFO_CODE@ @NETRC_CODE@ diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 48cdaf4..3d58cb0 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -1650,6 +1650,7 @@ ExternalProject_Add_Step(${contentName}-populate copyfile set(__FETCHCONTENT_CACHED_INFO "") set(__passthrough_vars CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY + CMAKE_TLS_VERSION CMAKE_TLS_VERIFY CMAKE_TLS_CAINFO CMAKE_NETRC diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake index ffaa46c..f16e479 100644 --- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake @@ -15,6 +15,9 @@ endif() run_cmake(BadIndependentStep1) run_cmake(BadIndependentStep2) +run_cmake(TLSVersionBadArg) +run_cmake(TLSVersionBadVar) +run_cmake(TLSVersionBadEnv) run_cmake(NoOptions) run_cmake(SourceEmpty) run_cmake(SourceMissing) diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadArg-result.txt b/Tests/RunCMake/ExternalProject/TLSVersionBadArg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadArg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadArg-stderr.txt b/Tests/RunCMake/ExternalProject/TLSVersionBadArg-stderr.txt new file mode 100644 index 0000000..1231797 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadArg-stderr.txt @@ -0,0 +1,10 @@ +^CMake Error at [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(message\): + TLS_VERSION 'bad-arg' not known +Call Stack \(most recent call first\): + [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(_ep_get_tls_version\) + [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(_ep_add_download_command\) + TLSVersionBadArg\.cmake:[0-9]+ \(ExternalProject_Add\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadArg.cmake b/Tests/RunCMake/ExternalProject/TLSVersionBadArg.cmake new file mode 100644 index 0000000..d212982 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadArg.cmake @@ -0,0 +1,4 @@ +include(ExternalProject) +set(ENV{CMAKE_TLS_VERSION} bad-env) +set(CMAKE_TLS_VERSION bad-var) +ExternalProject_Add(MyProj GIT_REPOSITORY "fake" TLS_VERSION bad-arg) diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadEnv-result.txt b/Tests/RunCMake/ExternalProject/TLSVersionBadEnv-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadEnv-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadEnv-stderr.txt b/Tests/RunCMake/ExternalProject/TLSVersionBadEnv-stderr.txt new file mode 100644 index 0000000..38b0fb8 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadEnv-stderr.txt @@ -0,0 +1,10 @@ +^CMake Error at [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(message\): + ENV{CMAKE_TLS_VERSION} 'bad-env' not known +Call Stack \(most recent call first\): + [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(_ep_get_tls_version\) + [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(_ep_add_download_command\) + TLSVersionBadEnv\.cmake:[0-9]+ \(ExternalProject_Add\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadEnv.cmake b/Tests/RunCMake/ExternalProject/TLSVersionBadEnv.cmake new file mode 100644 index 0000000..8018642 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadEnv.cmake @@ -0,0 +1,3 @@ +include(ExternalProject) +set(ENV{CMAKE_TLS_VERSION} bad-env) +ExternalProject_Add(MyProj GIT_REPOSITORY "fake") diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadVar-result.txt b/Tests/RunCMake/ExternalProject/TLSVersionBadVar-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadVar-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadVar-stderr.txt b/Tests/RunCMake/ExternalProject/TLSVersionBadVar-stderr.txt new file mode 100644 index 0000000..aaec60b --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadVar-stderr.txt @@ -0,0 +1,10 @@ +^CMake Error at [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(message\): + CMAKE_TLS_VERSION 'bad-var' not known +Call Stack \(most recent call first\): + [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(_ep_get_tls_version\) + [^ +]*/Modules/ExternalProject\.cmake:[0-9]+ \(_ep_add_download_command\) + TLSVersionBadVar\.cmake:[0-9]+ \(ExternalProject_Add\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/ExternalProject/TLSVersionBadVar.cmake b/Tests/RunCMake/ExternalProject/TLSVersionBadVar.cmake new file mode 100644 index 0000000..f52dd2e --- /dev/null +++ b/Tests/RunCMake/ExternalProject/TLSVersionBadVar.cmake @@ -0,0 +1,4 @@ +include(ExternalProject) +set(ENV{CMAKE_TLS_VERSION} bad-env) +set(CMAKE_TLS_VERSION bad-var) +ExternalProject_Add(MyProj GIT_REPOSITORY "fake") diff --git a/Tests/RunCMake/FetchContent/VarPassthroughs.cmake b/Tests/RunCMake/FetchContent/VarPassthroughs.cmake index ad743d8..279c127 100644 --- a/Tests/RunCMake/FetchContent/VarPassthroughs.cmake +++ b/Tests/RunCMake/FetchContent/VarPassthroughs.cmake @@ -5,6 +5,7 @@ set(CMAKE_TLS_VERIFY BBBB) set(CMAKE_TLS_CAINFO CCCC) set(CMAKE_NETRC DDDD) set(CMAKE_NETRC_FILE EEEE) +set(CMAKE_TLS_VERSION FFFF) FetchContent_Declare(PassThrough DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E echo "Download command executed" @@ -21,6 +22,10 @@ if(NOT contents MATCHES "CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY \\[==\\[AAAA\\]==\\ message(FATAL_ERROR "Missing CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY") endif() +if(NOT contents MATCHES "CMAKE_TLS_VERSION \\[==\\[FFFF\\]==\\]") + message(FATAL_ERROR "Missing CMAKE_TLS_VERSION") +endif() + if(NOT contents MATCHES "CMAKE_TLS_VERIFY \\[==\\[BBBB\\]==\\]") message(FATAL_ERROR "Missing CMAKE_TLS_VERIFY") endif() |