Commit 9980be03c29169265ad45591925e88e4c8b90327

Etienne Samson 2017-09-06T22:13:58

cmake: Add USE_HTTPS as a CMake option It defaults to ON, e.g. "pick whatever default is appropriate for the platform". It accepts one of SecureTransport, OpenSSL, WinHTTP, or OFF. It errors if the backend library couldn't be found.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index cc52530..8f16443 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@ OPTION( LIBGIT2_FILENAME	"Name of the produced binary"			OFF )
 OPTION( USE_SHA1DC			"Use SHA-1 with collision detection"	OFF )
 OPTION( USE_ICONV			"Link with and use iconv library" 		OFF )
 OPTION( USE_SSH				"Link with libssh to enable SSH support" ON )
+OPTION( USE_HTTPS			"Enable HTTPS support. Can be set to a specific backend"	ON )
 OPTION( USE_GSSAPI			"Link with libgssapi for SPNEGO auth"   OFF )
 OPTION( VALGRIND			"Configure build for valgrind"			OFF )
 OPTION( CURL			"Use curl for HTTP if available" ON)
@@ -91,10 +92,6 @@ IF(MSVC)
 	OPTION(MSVC_CRTDBG "Enable CRTDBG memory leak reporting" OFF)
 ENDIF()
 
-IF (NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
-	OPTION( USE_OPENSSL                     "Link with and use openssl library"             ON )
-ENDIF()
-
 CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtim "sys/types.h;sys/stat.h"
 	HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C)
 CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtimespec "sys/types.h;sys/stat.h"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b873953..e81dfb1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -97,15 +97,6 @@ IF(THREADSAFE)
 ENDIF()
 ADD_FEATURE_INFO(threadsafe THREADSAFE "threadsafe support")
 
-IF (SECURITY_FOUND)
-	IF (SECURITY_HAS_SSLCREATECONTEXT)
-		LIST(APPEND LIBGIT2_PC_LIBS ${SECURITY_LDFLAGS})
-	ELSE()
-		MESSAGE("-- Security framework is too old, falling back to OpenSSL")
-		SET(USE_OPENSSL "ON")
-	ENDIF()
-ENDIF()
-
 IF (COREFOUNDATION_FOUND)
 	LIST(APPEND LIBGIT2_LIBS ${COREFOUNDATION_LIBRARIES})
 	LIST(APPEND LIBGIT2_PC_LIBS ${COREFOUNDATION_LDFLAGS})
@@ -121,7 +112,6 @@ ENDIF()
 
 IF (WIN32 AND WINHTTP)
 	SET(GIT_WINHTTP 1)
-	SET(GIT_HTTPS 1)
 
 	# Since MinGW does not come with headers or an import library for winhttp,
 	# we have to include a private header and generate our own import library
@@ -142,7 +132,7 @@ ELSE ()
 		PKG_CHECK_MODULES(CURL libcurl)
 	ENDIF ()
 
-	IF (NOT AMIGA AND USE_OPENSSL)
+	IF (NOT AMIGA AND (USE_HTTPS STREQUAL "OpenSSL" OR USE_HTTPS STREQUAL "ON"))
 		FIND_PACKAGE(OpenSSL)
 	ENDIF ()
 
@@ -156,6 +146,60 @@ ELSE ()
 	ADD_FEATURE_INFO(cURL GIT_CURL "cURL for HTTP proxy support")
 ENDIF()
 
+IF (USE_HTTPS)
+	# Auto-select TLS backend
+	IF (USE_HTTPS STREQUAL ON)
+		IF (SECURITY_FOUND)
+			IF (SECURITY_HAS_SSLCREATECONTEXT)
+				SET(HTTPS_BACKEND "SecureTransport")
+			ELSE()
+				MESSAGE("-- Security framework is too old, falling back to OpenSSL")
+				SET(HTTPS_BACKEND "OpenSSL")
+			ENDIF()
+		ELSEIF (WINHTTP)
+			SET(HTTPS_BACKEND "WinHTTP")
+		ELSE()
+			SET(HTTPS_BACKEND "OpenSSL")
+		ENDIF()
+	ELSE()
+		# Backend was explicitly set
+		SET(HTTPS_BACKEND ${USE_HTTPS})
+	ENDIF()
+
+	# Check that we can find what's required for the selected backend
+	IF (HTTPS_BACKEND STREQUAL "SecureTransport")
+		IF (NOT SECURITY_FOUND)
+			MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, Security.framework not found")
+		ENDIF()
+		IF (NOT SECURITY_HAS_SSLCREATECONTEXT)
+			MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, SSLCreateContext not supported")
+		ENDIF()
+
+		SET(GIT_SECURE_TRANSPORT 1)
+		LIST(APPEND LIBGIT2_INCLUDES ${SECURITY_INCLUDE_DIR})
+		LIST(APPEND LIBGIT2_LIBS ${SECURITY_LIBRARIES})
+		LIST(APPEND LIBGIT2_PC_LIBS ${SECURITY_LDFLAGS})
+	ELSEIF (HTTPS_BACKEND STREQUAL "OpenSSL")
+		IF (NOT OPENSSL_FOUND)
+			MESSAGE(FATAL_ERROR "Asked for OpenSSL TLS backend, but it wasn't found")
+		ENDIF()
+
+		SET(GIT_OPENSSL 1)
+		LIST(APPEND LIBGIT2_INCLUDES ${OPENSSL_INCLUDE_DIR})
+		LIST(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES})
+		LIST(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS})
+	ELSEIF (HTTPS_BACKEND STREQUAL "WinHTTP")
+		# WinHTTP setup was handled in the WinHTTP-specific block above
+	ELSE()
+		MESSAGE(FATAL_ERROR "Asked for backend ${HTTPS_BACKEND} but it wasn't found")
+	ENDIF()
+
+	ADD_FEATURE_INFO(HTTPS ON "using ${HTTPS_BACKEND}")
+	SET(GIT_HTTPS 1)
+ELSE()
+	ADD_FEATURE_INFO(HTTPS OFF "no support")
+ENDIF()
+
 # Specify sha1 implementation
 IF (USE_SHA1DC)
 	ADD_FEATURE_INFO(SHA ON "using SHA1DC")
@@ -270,20 +314,6 @@ IF (ICONV_FOUND)
 ENDIF()
 ADD_FEATURE_INFO(iconv GIT_USE_ICONV "iconv encoding conversion support")
 
-IF (SECURITY_FOUND)
-	SET(GIT_SECURE_TRANSPORT 1)
-	SET(GIT_HTTPS 1)
-	LIST(APPEND LIBGIT2_INCLUDES ${SECURITY_INCLUDE_DIR})
-ENDIF ()
-
-IF (OPENSSL_FOUND)
-	SET(GIT_OPENSSL 1)
-	SET(GIT_HTTPS 1)
-	LIST(APPEND LIBGIT2_INCLUDES ${OPENSSL_INCLUDE_DIR})
-	LIST(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES})
-ENDIF()
-
-
 
 IF (THREADSAFE)
 	IF (NOT WIN32)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index f3becef..08ecb39 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -52,7 +52,7 @@ IF (MSVC_IDE)
 	SET_SOURCE_FILES_PROPERTIES("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h")
 ENDIF ()
 
-IF (GIT_HTTPS)
+IF (USE_HTTPS)
 	ADD_TEST(libgit2_clar "${libgit2_BINARY_DIR}/libgit2_clar" -ionline -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
 ELSE ()
 	ADD_TEST(libgit2_clar "${libgit2_BINARY_DIR}/libgit2_clar" -v -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)