Commit dbc17a7e94909d232420f25f166b732623f9451b

Etienne Samson 2019-09-21T08:46:08

negotiate: use GSS.framework on macOS

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 01f8c2d..e000de5 100644
--- a/src/features.h.in
+++ b/src/features.h.in
@@ -27,6 +27,7 @@
 
 #cmakedefine GIT_NTLM 1
 #cmakedefine GIT_GSSAPI 1
+#cmakedefine GIT_GSSFRAMEWORK 1
 
 #cmakedefine GIT_WINHTTP 1
 #cmakedefine GIT_HTTPS 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,