Commit 0298e0a68ce60e314b5b9c19014d4cb13d1d1f01

Patrick Steinhardt 2019-10-17T12:24:25

Merge pull request #5238 from tiennou/feature/macos-gss macOS GSS Support

diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 00cca7e..d74b514 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -79,7 +79,7 @@ jobs:
         TMPDIR: $(Agent.TempDirectory)
         PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
         CMAKE_GENERATOR: Ninja
-        CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks
+        CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON
         SKIP_SSH_TESTS: true
 
 - job: windows_vs_amd64
diff --git a/azure-pipelines/nightly.yml b/azure-pipelines/nightly.yml
index b8d550f..a193747 100644
--- a/azure-pipelines/nightly.yml
+++ b/azure-pipelines/nightly.yml
@@ -79,7 +79,7 @@ jobs:
         TMPDIR: $(Agent.TempDirectory)
         PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
         CMAKE_GENERATOR: Ninja
-        CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks
+        CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON
         RUN_INVASIVE_TESTS: true
         SKIP_SSH_TESTS: true
 
diff --git a/cmake/Modules/FindGSSFramework.cmake b/cmake/Modules/FindGSSFramework.cmake
new file mode 100644
index 0000000..dcf7249
--- /dev/null
+++ b/cmake/Modules/FindGSSFramework.cmake
@@ -0,0 +1,28 @@
+# Find GSS.framework
+# This will define :
+#
+# GSSFRAMEWORK_FOUND
+# GSSFRAMEWORK_INCLUDE_DIR
+# GSSFRAMEWORK_LIBRARIES
+# GSSFRAMEWORK_LDFLAGS
+#
+
+FIND_PATH(GSSFRAMEWORK_INCLUDE_DIR NAMES GSS.h)
+FIND_LIBRARY(GSSFRAMEWORK_LIBRARIES NAMES GSS)
+IF (GSSFRAMEWORK_INCLUDE_DIR AND GSSFRAMEWORK_LIBRARIES)
+	IF (NOT CoreFoundation_FIND_QUIETLY)
+		MESSAGE(STATUS "Found GSS.framework ${GSSFRAMEWORK_LIBRARIES}")
+	ENDIF()
+	SET(GSSFRAMEWORK_FOUND TRUE)
+	SET(GSSFRAMEWORK_LDFLAGS "-framework GSS")
+ENDIF ()
+
+IF (GSS_FIND_REQUIRED AND NOT GSSFRAMEWORK_FOUND)
+	MESSAGE(FATAL_ERROR "CoreFoundation not found")
+ENDIF()
+
+MARK_AS_ADVANCED(
+	GSSFRAMEWORK_INCLUDE_DIR
+	GSSFRAMEWORK_LIBRARIES
+	GSSFRAMEWORK_LDFLAGS
+)
diff --git a/cmake/Modules/SelectGSSAPI.cmake b/cmake/Modules/SelectGSSAPI.cmake
new file mode 100644
index 0000000..41f8375
--- /dev/null
+++ b/cmake/Modules/SelectGSSAPI.cmake
@@ -0,0 +1,53 @@
+# Select the backend to use
+
+# We try to find any packages our backends might use
+
+FIND_PACKAGE(GSSAPI)
+IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+	INCLUDE(FindGSSFramework)
+ENDIF()
+
+# Auto-select GSS backend
+IF (USE_GSSAPI STREQUAL ON)
+	IF (GSSFRAMEWORK_FOUND)
+		SET(GSS_BACKEND "GSS.framework")
+	ELSEIF(GSSAPI_FOUND)
+		SET(GSS_BACKEND "gssapi")
+	ELSE()
+		MESSAGE(FATAL_ERROR "Unable to autodetect a usable GSS backend."
+			"Please pass the backend name explicitly (-DUSE_GSS=backend)")
+	ENDIF()
+ELSEIF(USE_GSSAPI)
+	# Backend was explicitly set
+	SET(GSS_BACKEND ${USE_GSSAPI})
+ELSE()
+	SET(GSS_BACKEND NO)
+ENDIF()
+
+IF(GSS_BACKEND)
+	# Check that we can find what's required for the selected backend
+	IF (GSS_BACKEND STREQUAL "GSS.framework")
+		IF (NOT GSSFRAMEWORK_FOUND)
+			MESSAGE(FATAL_ERROR "Asked for GSS.framework backend, but it wasn't found")
+		ENDIF()
+
+		LIST(APPEND LIBGIT2_LIBS ${GSSFRAMEWORK_LIBRARIES})
+
+		SET(GIT_GSSFRAMEWORK 1)
+		ADD_FEATURE_INFO(SPNEGO GIT_GSSFRAMEWORK "SPNEGO authentication support (${GSS_BACKEND})")
+	ELSEIF (GSS_BACKEND STREQUAL "gssapi")
+		IF (NOT GSSAPI_FOUND)
+			MESSAGE(FATAL_ERROR "Asked for gssapi GSS backend, but it wasn't found")
+		ENDIF()
+
+		LIST(APPEND LIBGIT2_LIBS ${GSSAPI_LIBRARIES})
+
+		SET(GIT_GSSAPI 1)
+		ADD_FEATURE_INFO(SPNEGO GIT_GSSAPI "SPNEGO authentication support (${GSS_BACKEND})")
+	ELSE()
+		MESSAGE(FATAL_ERROR "Asked for backend ${GSS_BACKEND} but it wasn't found")
+	ENDIF()
+ELSE()
+	SET(GIT_GSSAPI 0)
+	ADD_FEATURE_INFO(SPNEGO NO "")
+ENDIF()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9d2b022..0ca1e73 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -233,15 +233,9 @@ IF (USE_NTLMCLIENT)
 ENDIF()
 ADD_FEATURE_INFO(ntlmclient GIT_NTLM "NTLM authentication support for Unix")
 
-# Optional external dependency: libgssapi
-IF (USE_GSSAPI)
-	FIND_PACKAGE(GSSAPI)
-ENDIF()
-IF (GSSAPI_FOUND)
-	SET(GIT_GSSAPI 1)
-	LIST(APPEND LIBGIT2_LIBS ${GSSAPI_LIBRARIES})
-ENDIF()
-ADD_FEATURE_INFO(SPNEGO GIT_GSSAPI "SPNEGO authentication support")
+# Optional external dependency: GSSAPI
+
+INCLUDE(SelectGSSAPI)
 
 # Optional external dependency: iconv
 IF (USE_ICONV)
diff --git a/src/features.h.in b/src/features.h.in
index f2931cb..e000de5 100644
--- a/src/features.h.in
+++ b/src/features.h.in
@@ -27,9 +27,9 @@
 
 #cmakedefine GIT_NTLM 1
 #cmakedefine GIT_GSSAPI 1
-#cmakedefine GIT_WINHTTP 1
-#cmakedefine GIT_NTLM 1
+#cmakedefine GIT_GSSFRAMEWORK 1
 
+#cmakedefine GIT_WINHTTP 1
 #cmakedefine GIT_HTTPS 1
 #cmakedefine GIT_OPENSSL 1
 #cmakedefine GIT_SECURE_TRANSPORT 1
diff --git a/src/transports/auth_negotiate.c b/src/transports/auth_negotiate.c
index b7eb425..2631543 100644
--- a/src/transports/auth_negotiate.c
+++ b/src/transports/auth_negotiate.c
@@ -7,15 +7,19 @@
 
 #include "auth_negotiate.h"
 
-#ifdef GIT_GSSAPI
+#if defined(GIT_GSSAPI) || defined(GIT_GSSFRAMEWORK)
 
 #include "git2.h"
 #include "buffer.h"
 #include "auth.h"
 #include "git2/sys/cred.h"
 
+#ifdef GIT_GSSFRAMEWORK
+#import <GSS/GSS.h>
+#elif defined(GIT_GSSAPI)
 #include <gssapi.h>
 #include <krb5.h>
+#endif
 
 static gss_OID_desc negotiate_oid_spnego =
 	{ 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
diff --git a/src/transports/auth_negotiate.h b/src/transports/auth_negotiate.h
index d3f2ba2..34aff29 100644
--- a/src/transports/auth_negotiate.h
+++ b/src/transports/auth_negotiate.h
@@ -12,7 +12,7 @@
 #include "git2.h"
 #include "auth.h"
 
-#ifdef GIT_GSSAPI
+#if defined(GIT_GSSAPI) || defined(GIT_GSSFRAMEWORK)
 
 extern int git_http_auth_negotiate(
 	git_http_auth_context **out,
diff --git a/src/util.c b/src/util.c
index fdd8e9a..859e0a8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -719,6 +719,10 @@ static int GIT_STDLIB_CALL git__qsort_r_glue_cmp(
 }
 #endif
 
+
+#if !defined(HAVE_QSORT_R_BSD) && \
+	!defined(HAVE_QSORT_R_GNU) && \
+	!defined(HAVE_QSORT_S)
 static void swap(uint8_t *a, uint8_t *b, size_t elsize)
 {
 	char tmp[256];
@@ -744,6 +748,7 @@ static void insertsort(
 		for (j = i; j > base && cmp(j, j - elsize, payload) < 0; j -= elsize)
 			swap(j, j - elsize, elsize);
 }
+#endif
 
 void git__qsort_r(
 	void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload)