Merge topic 'ep-tls-verify'

dcbc36572f ExternalProject: Respect TLS_VERIFY for git update step
8fdce89f70 Help: Clarify default TLS_VERIFY behavior for git download method

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !8516
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index bac126c..574b339 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -232,7 +232,12 @@
         measure.
 
         .. versionchanged:: 3.6
-          This option also applies to ``git clone`` invocations.
+          This option also applies to ``git clone`` invocations, although the
+          default behavior is different.  If ``TLS_VERIFY`` is not given and
+          :variable:`CMAKE_TLS_VERIFY` is not set, the behavior will be
+          determined by git's defaults.  Normally, the ``sslVerify`` git
+          config setting defaults to true, but the user may have overridden
+          this at a global level.
 
       ``TLS_CAINFO <file>``
         Specify a custom certificate authority file to use if ``TLS_VERIFY``
@@ -1328,6 +1333,8 @@
     message(FATAL_ERROR "Tag for git checkout should not be empty.")
   endif()
 
+  set(git_submodules_config_options "")
+
   if(GIT_VERSION_STRING VERSION_LESS 2.20 OR
      2.21 VERSION_LESS_EQUAL GIT_VERSION_STRING)
     set(git_clone_options "--no-checkout")
@@ -1350,18 +1357,26 @@
   if(NOT ${git_remote_name} STREQUAL "origin")
     list(APPEND git_clone_options --origin \"${git_remote_name}\")
   endif()
+  if(NOT "x${tls_verify}" STREQUAL "x")
+    # The clone config option is sticky, it will apply to all subsequent git
+    # update operations. The submodules config option is not sticky, because
+    # git doesn't provide any way to do that. Thus, we will have to pass the
+    # same config option in the update step too for submodules, but not for
+    # the main git repo.
+    if(tls_verify)
+      # Default git behavior is "true", but the user might have changed the
+      # global default to "false". Since TLS_VERIFY was given, ensure we honor
+      # the specified setting regardless of what the global default might be.
+      list(APPEND git_clone_options -c http.sslVerify=true)
+      set(git_submodules_config_options -c http.sslVerify=true)
+    else()
+      list(APPEND git_clone_options -c http.sslVerify=false)
+      set(git_submodules_config_options -c http.sslVerify=false)
+    endif()
+  endif()
 
   string (REPLACE ";" " " git_clone_options "${git_clone_options}")
 
-  set(git_options)
-  # disable cert checking if explicitly told not to do it
-  if(NOT "x${tls_verify}" STREQUAL "x" AND NOT tls_verify)
-    set(git_options
-      -c http.sslVerify=false
-    )
-  endif()
-  string (REPLACE ";" " " git_options "${git_options}")
-
   configure_file(
     ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/gitclone.cmake.in
     ${script_filename}
@@ -1404,6 +1419,7 @@
   git_repository
   work_dir
   git_update_strategy
+  tls_verify
 )
 
   if("${git_tag}" STREQUAL "")
@@ -1418,6 +1434,22 @@
     list(APPEND git_stash_save_options --all)
   endif()
 
+  set(git_submodules_config_options "")
+  if(NOT "x${tls_verify}" STREQUAL "x")
+    # The submodules config option is not sticky, git doesn't provide any way
+    # to do that. We have to pass this config option for the update step too.
+    # 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.
+    if(tls_verify)
+      # Default git behavior is "true", but the user might have changed the
+      # global default to "false". Since TLS_VERIFY was given, ensure we honor
+      # the specified setting regardless of what the global default might be.
+      set(git_submodules_config_options -c http.sslVerify=true)
+    else()
+      set(git_submodules_config_options -c http.sslVerify=false)
+    endif()
+  endif()
+
   configure_file(
       "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/gitupdate.cmake.in"
       "${script_filename}"
@@ -3356,6 +3388,11 @@
 
     _ep_get_git_submodules_recurse(git_submodules_recurse)
 
+    get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY)
+    if("x${tls_verify}" STREQUAL "x" AND DEFINED CMAKE_TLS_VERIFY)
+      set(tls_verify "${CMAKE_TLS_VERIFY}")
+    endif()
+
     set(update_script "${tmp_dir}/${name}-gitupdate.cmake")
     list(APPEND file_deps ${update_script})
     _ep_write_gitupdate_script(
@@ -3369,6 +3406,7 @@
       "${git_repository}"
       "${work_dir}"
       "${git_update_strategy}"
+      "${tls_verify}"
     )
     set(cmd              ${CMAKE_COMMAND} -Dcan_fetch=YES -P ${update_script})
     set(cmd_disconnected ${CMAKE_COMMAND} -Dcan_fetch=NO  -P ${update_script})
diff --git a/Modules/ExternalProject/gitclone.cmake.in b/Modules/ExternalProject/gitclone.cmake.in
index 3312171..94b329a 100644
--- a/Modules/ExternalProject/gitclone.cmake.in
+++ b/Modules/ExternalProject/gitclone.cmake.in
@@ -25,7 +25,7 @@
 set(number_of_tries 0)
 while(error_code AND number_of_tries LESS 3)
   execute_process(
-    COMMAND "@git_EXECUTABLE@" @git_options@
+    COMMAND "@git_EXECUTABLE@"
             clone @git_clone_options@ "@git_repository@" "@src_name@"
     WORKING_DIRECTORY "@work_dir@"
     RESULT_VARIABLE error_code
@@ -40,7 +40,7 @@
 endif()
 
 execute_process(
-  COMMAND "@git_EXECUTABLE@" @git_options@
+  COMMAND "@git_EXECUTABLE@"
           checkout "@git_tag@" @git_checkout_explicit--@
   WORKING_DIRECTORY "@work_dir@/@src_name@"
   RESULT_VARIABLE error_code
@@ -52,7 +52,7 @@
 set(init_submodules @init_submodules@)
 if(init_submodules)
   execute_process(
-    COMMAND "@git_EXECUTABLE@" @git_options@
+    COMMAND "@git_EXECUTABLE@" @git_submodules_config_options@
             submodule update @git_submodules_recurse@ --init @git_submodules@
     WORKING_DIRECTORY "@work_dir@/@src_name@"
     RESULT_VARIABLE error_code
diff --git a/Modules/ExternalProject/gitupdate.cmake.in b/Modules/ExternalProject/gitupdate.cmake.in
index eb3cda7..171aa7b 100644
--- a/Modules/ExternalProject/gitupdate.cmake.in
+++ b/Modules/ExternalProject/gitupdate.cmake.in
@@ -283,7 +283,9 @@
 set(init_submodules "@init_submodules@")
 if(init_submodules)
   execute_process(
-    COMMAND "@git_EXECUTABLE@" --git-dir=.git submodule update @git_submodules_recurse@ --init @git_submodules@
+    COMMAND "@git_EXECUTABLE@"
+            --git-dir=.git @git_submodules_config_options@
+            submodule update @git_submodules_recurse@ --init @git_submodules@
     WORKING_DIRECTORY "@work_dir@"
     COMMAND_ERROR_IS_FATAL ANY
   )