negotiate: use GSS.framework on macOS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
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,