diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index b1a457dcdf..21e2617c93 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -39,7 +39,7 @@ permissions: {} # - 10.9 Mavericks (2013) - LDAP (build-time, deprecated), memset_s(), OCSP (runtime) # - 10.11 El Capitan (2015) - connectx() (runtime) # - 10.12 Sierra (2016) - clock_gettime() (build-time, runtime) -# - 10.14 Mojave (2018) - SecTrustEvaluateWithError() (runtime) +# - 10.14 Mojave (2018) - SecTrustEvaluateWithError() (runtime), GSS Framework env: CURL_CI: github @@ -328,12 +328,12 @@ jobs: -DCURL_CLANG_TIDY=ON -DCLANG_TIDY=/opt/homebrew/opt/llvm/bin/clang-tidy -DCURL_ENABLE_NTLM=ON -DUSE_PROXY_HTTP3=ON - - name: 'LibreSSL openldap krb5 c-ares +examples' + - name: 'LibreSSL openldap AppleGSS c-ares +examples' compiler: clang install: libressl krb5 openldap generate: >- - -DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/libressl -DENABLE_ARES=ON -DCURL_USE_GSSAPI=ON - -DGSS_ROOT_DIR=/opt/homebrew/opt/krb5 + -DENABLE_DEBUG=ON -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/libressl -DENABLE_ARES=ON + -DCURL_USE_GSSAPI=ON -DCURL_GSS_FLAVOR=Apple -DLDAP_INCLUDE_DIR=/opt/homebrew/opt/openldap/include -DLDAP_LIBRARY=/opt/homebrew/opt/openldap/lib/libldap.dylib -DLDAP_LBER_LIBRARY=/opt/homebrew/opt/openldap/lib/liblber.dylib @@ -737,6 +737,7 @@ jobs: -DUSE_NGHTTP2=OFF -DUSE_LIBIDN2=OFF \ -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF \ -DUSE_APPLE_IDN=ON -DUSE_APPLE_SECTRUST=ON \ + -DCURL_USE_GSSAPI=ON -DCURL_GSS_FLAVOR=Apple \ ${options} else export CFLAGS @@ -756,6 +757,7 @@ jobs: --without-nghttp2 --without-libidn2 \ --without-libpsl \ --with-apple-idn --with-apple-sectrust \ + --enable-gssapi-apple \ ${options} fi diff --git a/CMake/FindGSS.cmake b/CMake/FindGSS.cmake index a49d529d81..46d768699d 100644 --- a/CMake/FindGSS.cmake +++ b/CMake/FindGSS.cmake @@ -23,6 +23,10 @@ ########################################################################### # Find the GSS Kerberos library # +# This module accepts optional COMPONENTS to control the GSS library flavor: +# +# - Apple +# # Input variables: # # - `GSS_ROOT_DIR`: Absolute path to the root installation of GSS. (also supported as environment) @@ -32,7 +36,7 @@ # - `GSS_FOUND`: System has GSS. # - `GSS_VERSION`: Version of GSS. # - `CURL::gss`: GSS library target. -# - `INTERFACE_CURL_GSS_FLAVOR`: Custom property. "GNU" or "MIT" if detected. +# - `INTERFACE_CURL_GSS_FLAVOR`: Custom property. "Apple", "GNU" or "MIT" if detected. set(_gnu_modname "gss") set(_mit_modname "mit-krb5-gssapi") @@ -46,8 +50,12 @@ set(_gss_root_hints "${GSS_ROOT_DIR}" "$ENV{GSS_ROOT_DIR}") set(_gss_CFLAGS "") set(_gss_LIBRARY_DIRS "") +if(NOT APPLE AND GSS_FIND_COMPONENTS STREQUAL "Apple") + set(GSS_FIND_COMPONENTS "") +endif() + # Try to find library using system pkg-config if user did not specify root dir -if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}") +if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}" AND NOT GSS_FIND_COMPONENTS STREQUAL "Apple") if(CURL_USE_PKGCONFIG) find_package(PkgConfig QUIET) pkg_search_module(_gss ${_mit_modname} ${_gnu_modname}) @@ -60,136 +68,146 @@ if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}") endif() if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional approach. - find_file(_gss_configure_script NAMES "krb5-config" PATH_SUFFIXES "bin" HINTS ${_gss_root_hints} - NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH) - # If not found in user-supplied directories, maybe system knows better - find_file(_gss_configure_script NAMES "krb5-config" PATH_SUFFIXES "bin") + if(GSS_FIND_COMPONENTS STREQUAL "Apple") + find_path(_gss_INCLUDE_DIRS NAMES "GSS/gssapi.h" PATH_SUFFIXES "include") + find_library(_gss_LIBRARIES NAMES "GSS") - if(_gss_configure_script) - - set(_gss_INCLUDE_DIRS "") - set(_gss_LIBRARIES "") - - execute_process(COMMAND ${_gss_configure_script} "--cflags" "gssapi" - OUTPUT_VARIABLE _gss_cflags_raw - RESULT_VARIABLE _gss_configure_failed - OUTPUT_STRIP_TRAILING_WHITESPACE) - message(STATUS "FindGSS krb5-config --cflags: ${_gss_cflags_raw}") - - if(NOT _gss_configure_failed) # 0 means success - # Should also work in an odd case when multiple directories are given. - string(STRIP "${_gss_cflags_raw}" _gss_cflags_raw) - string(REGEX REPLACE " +-(I)" ";-\\1" _gss_cflags_raw "${_gss_cflags_raw}") - string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _gss_cflags_raw "${_gss_cflags_raw}") - - foreach(_flag IN LISTS _gss_cflags_raw) - if(_flag MATCHES "^-I") - string(REGEX REPLACE "^-I" "" _flag "${_flag}") - list(APPEND _gss_INCLUDE_DIRS "${_flag}") - else() - list(APPEND _gss_CFLAGS "${_flag}") - endif() - endforeach() + if(_gss_INCLUDE_DIRS AND _gss_LIBRARIES) + message(STATUS "Found AppleGSS: ${_gss_INCLUDE_DIRS}") + set(_gss_flavor "Apple") endif() + else() + find_file(_gss_configure_script NAMES "krb5-config" PATH_SUFFIXES "bin" HINTS ${_gss_root_hints} + NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH) + # If not found in user-supplied directories, maybe system knows better + find_file(_gss_configure_script NAMES "krb5-config" PATH_SUFFIXES "bin") - execute_process(COMMAND ${_gss_configure_script} "--libs" "gssapi" - OUTPUT_VARIABLE _gss_lib_flags - RESULT_VARIABLE _gss_configure_failed - OUTPUT_STRIP_TRAILING_WHITESPACE) - message(STATUS "FindGSS krb5-config --libs: ${_gss_lib_flags}") + if(_gss_configure_script) - if(NOT _gss_configure_failed) # 0 means success - # This script gives us libraries and link directories. - string(STRIP "${_gss_lib_flags}" _gss_lib_flags) - string(REGEX REPLACE " +-(L|l)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") - string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") + set(_gss_INCLUDE_DIRS "") + set(_gss_LIBRARIES "") - foreach(_flag IN LISTS _gss_lib_flags) - if(_flag MATCHES "^-l") - string(REGEX REPLACE "^-l" "" _flag "${_flag}") - list(APPEND _gss_LIBRARIES "${_flag}") - elseif(_flag MATCHES "^-L") - string(REGEX REPLACE "^-L" "" _flag "${_flag}") - list(APPEND _gss_LIBRARY_DIRS "${_flag}") - endif() - endforeach() - endif() + execute_process(COMMAND ${_gss_configure_script} "--cflags" "gssapi" + OUTPUT_VARIABLE _gss_cflags_raw + RESULT_VARIABLE _gss_configure_failed + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "FindGSS krb5-config --cflags: ${_gss_cflags_raw}") - execute_process(COMMAND ${_gss_configure_script} "--version" - OUTPUT_VARIABLE _gss_version - RESULT_VARIABLE _gss_configure_failed - OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT _gss_configure_failed) # 0 means success + # Should also work in an odd case when multiple directories are given. + string(STRIP "${_gss_cflags_raw}" _gss_cflags_raw) + string(REGEX REPLACE " +-(I)" ";-\\1" _gss_cflags_raw "${_gss_cflags_raw}") + string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _gss_cflags_raw "${_gss_cflags_raw}") - # Older versions may not have the "--version" parameter. In this case we do not care. - if(_gss_configure_failed) - set(_gss_version 0) - else() - # Strip prefix string to leave the version number only - string(REPLACE "Kerberos 5 release " "" _gss_version "${_gss_version}") - endif() - - execute_process(COMMAND ${_gss_configure_script} "--vendor" - OUTPUT_VARIABLE _gss_vendor - RESULT_VARIABLE _gss_configure_failed - OUTPUT_STRIP_TRAILING_WHITESPACE) - - # Older versions may not have the "--vendor" parameter. In this case we do not care. - if(NOT _gss_configure_failed AND NOT _gss_vendor MATCHES "Heimdal|heimdal") - set(_gss_flavor "MIT") # assume a default, should not really matter - endif() - - else() # Either there is no config script or we are on a platform that does not provide one (Windows?) - - find_path(_gss_INCLUDE_DIRS NAMES "gssapi/gssapi.h" HINTS ${_gss_root_hints} PATH_SUFFIXES "include" "inc") - - if(_gss_INCLUDE_DIRS) # We have found something - set(_gss_libdir_suffixes "") - - cmake_push_check_state() - list(APPEND CMAKE_REQUIRED_INCLUDES "${_gss_INCLUDE_DIRS}") - check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers) - cmake_pop_check_state() - - if(_gss_have_mit_headers) - set(_gss_flavor "MIT") - if(WIN32) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - list(APPEND _gss_libdir_suffixes "lib/AMD64") - set(_gss_libname "gssapi64") + foreach(_flag IN LISTS _gss_cflags_raw) + if(_flag MATCHES "^-I") + string(REGEX REPLACE "^-I" "" _flag "${_flag}") + list(APPEND _gss_INCLUDE_DIRS "${_flag}") else() - list(APPEND _gss_libdir_suffixes "lib/i386") - set(_gss_libname "gssapi32") + list(APPEND _gss_CFLAGS "${_flag}") endif() - else() - list(APPEND _gss_libdir_suffixes "lib" "lib64") # those suffixes are not checked for HINTS - set(_gss_libname "gssapi_krb5") + endforeach() + endif() + + execute_process(COMMAND ${_gss_configure_script} "--libs" "gssapi" + OUTPUT_VARIABLE _gss_lib_flags + RESULT_VARIABLE _gss_configure_failed + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "FindGSS krb5-config --libs: ${_gss_lib_flags}") + + if(NOT _gss_configure_failed) # 0 means success + # This script gives us libraries and link directories. + string(STRIP "${_gss_lib_flags}" _gss_lib_flags) + string(REGEX REPLACE " +-(L|l)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") + string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") + + foreach(_flag IN LISTS _gss_lib_flags) + if(_flag MATCHES "^-l") + string(REGEX REPLACE "^-l" "" _flag "${_flag}") + list(APPEND _gss_LIBRARIES "${_flag}") + elseif(_flag MATCHES "^-L") + string(REGEX REPLACE "^-L" "" _flag "${_flag}") + list(APPEND _gss_LIBRARY_DIRS "${_flag}") + endif() + endforeach() + endif() + + execute_process(COMMAND ${_gss_configure_script} "--version" + OUTPUT_VARIABLE _gss_version + RESULT_VARIABLE _gss_configure_failed + OUTPUT_STRIP_TRAILING_WHITESPACE) + + # Older versions may not have the "--version" parameter. In this case we do not care. + if(_gss_configure_failed) + set(_gss_version 0) + else() + # Strip prefix string to leave the version number only + string(REPLACE "Kerberos 5 release " "" _gss_version "${_gss_version}") + endif() + + execute_process(COMMAND ${_gss_configure_script} "--vendor" + OUTPUT_VARIABLE _gss_vendor + RESULT_VARIABLE _gss_configure_failed + OUTPUT_STRIP_TRAILING_WHITESPACE) + + # Older versions may not have the "--vendor" parameter. In this case we do not care. + if(NOT _gss_configure_failed AND NOT _gss_vendor MATCHES "Heimdal|heimdal") + set(_gss_flavor "MIT") # assume a default, should not really matter + endif() + + else() # Either there is no config script or we are on a platform that does not provide one (Windows?) + + find_path(_gss_INCLUDE_DIRS NAMES "gssapi/gssapi.h" HINTS ${_gss_root_hints} PATH_SUFFIXES "include" "inc") + + if(_gss_INCLUDE_DIRS) # We have found something + set(_gss_libdir_suffixes "") + + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_INCLUDES "${_gss_INCLUDE_DIRS}") + check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers) + cmake_pop_check_state() + + if(_gss_have_mit_headers) + set(_gss_flavor "MIT") + if(WIN32) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + list(APPEND _gss_libdir_suffixes "lib/AMD64") + set(_gss_libname "gssapi64") + else() + list(APPEND _gss_libdir_suffixes "lib/i386") + set(_gss_libname "gssapi32") + endif() + else() + list(APPEND _gss_libdir_suffixes "lib" "lib64") # those suffixes are not checked for HINTS + set(_gss_libname "gssapi_krb5") + endif() + endif() + else() + find_path(_gss_INCLUDE_DIRS NAMES "gss.h" HINTS ${_gss_root_hints} PATH_SUFFIXES "include") + + if(_gss_INCLUDE_DIRS) + set(_gss_flavor "GNU") + set(_gss_pc_requires ${_gnu_modname}) + set(_gss_libname "gss") endif() endif() - else() - find_path(_gss_INCLUDE_DIRS NAMES "gss.h" HINTS ${_gss_root_hints} PATH_SUFFIXES "include") - if(_gss_INCLUDE_DIRS) - set(_gss_flavor "GNU") - set(_gss_pc_requires ${_gnu_modname}) - set(_gss_libname "gss") + # If we have headers, look up libraries + if(_gss_flavor) + set(_gss_libdir_hints ${_gss_root_hints}) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20) + cmake_path(GET _gss_INCLUDE_DIRS PARENT_PATH _gss_calculated_potential_root) + else() + get_filename_component(_gss_calculated_potential_root "${_gss_INCLUDE_DIRS}" DIRECTORY) + endif() + list(APPEND _gss_libdir_hints ${_gss_calculated_potential_root}) + + find_library(_gss_LIBRARIES NAMES ${_gss_libname} HINTS ${_gss_libdir_hints} PATH_SUFFIXES ${_gss_libdir_suffixes}) endif() endif() - - # If we have headers, look up libraries - if(_gss_flavor) - set(_gss_libdir_hints ${_gss_root_hints}) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20) - cmake_path(GET _gss_INCLUDE_DIRS PARENT_PATH _gss_calculated_potential_root) - else() - get_filename_component(_gss_calculated_potential_root "${_gss_INCLUDE_DIRS}" DIRECTORY) - endif() - list(APPEND _gss_libdir_hints ${_gss_calculated_potential_root}) - - find_library(_gss_LIBRARIES NAMES ${_gss_libname} HINTS ${_gss_libdir_hints} PATH_SUFFIXES ${_gss_libdir_suffixes}) - endif() endif() if(NOT _gss_flavor) - message(FATAL_ERROR "MIT or GNU GSS is required") + message(FATAL_ERROR "MIT, GNU or Apple GSS is required") endif() else() if(_gss_MODULE_NAME STREQUAL _gnu_modname) @@ -199,7 +217,7 @@ else() set(_gss_flavor "MIT") set(_gss_pc_requires ${_mit_modname}) else() - message(FATAL_ERROR "MIT or GNU GSS is required") + message(FATAL_ERROR "MIT, GNU or Apple GSS is required") endif() message(STATUS "Found GSS/${_gss_flavor} (via pkg-config): ${_gss_INCLUDE_DIRS} (found version \"${_gss_version}\")") endif() diff --git a/CMake/curl-config.in.cmake b/CMake/curl-config.in.cmake index b4300ca210..e782cb5e92 100644 --- a/CMake/curl-config.in.cmake +++ b/CMake/curl-config.in.cmake @@ -74,7 +74,7 @@ if("@USE_ARES@") list(APPEND _curl_libs CURL::cares) endif() if("@HAVE_GSSAPI@") - find_dependency(GSS MODULE) + find_dependency(GSS MODULE COMPONENTS "@GSS_FLAVOR@") list(APPEND _curl_libs CURL::gss) endif() if("@USE_BACKTRACE@") diff --git a/CMakeLists.txt b/CMakeLists.txt index 5aa412fc98..8fe4822265 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1345,14 +1345,18 @@ option(CURL_USE_GSSAPI "Use GSSAPI implementation" OFF) mark_as_advanced(CURL_USE_GSSAPI) if(CURL_USE_GSSAPI) - find_package(GSS MODULE) + set(CURL_GSS_FLAVOR "" CACHE STRING "Set preferred GSSAPI implementation ('Apple'). Default: MIT, then GNU (experimental)") + + find_package(GSS MODULE COMPONENTS "${CURL_GSS_FLAVOR}") set(HAVE_GSSAPI ${GSS_FOUND}) if(GSS_FOUND) list(APPEND CURL_LIBS CURL::gss) - get_target_property(_gss_flavor CURL::gss INTERFACE_CURL_GSS_FLAVOR) - if(_gss_flavor STREQUAL "GNU") + get_target_property(GSS_FLAVOR CURL::gss INTERFACE_CURL_GSS_FLAVOR) + if(GSS_FLAVOR STREQUAL "Apple") + set(HAVE_GSSAPPLE 1) + elseif(GSS_FLAVOR STREQUAL "GNU") set(HAVE_GSSGNU 1) elseif(GSS_VERSION) # MIT set(CURL_KRB5_VERSION "\"${GSS_VERSION}\"") @@ -2388,6 +2392,7 @@ if(NOT CURL_DISABLE_INSTALL) # CURL_SUPPORTED_PROTOCOLS_LIST # CURL_USE_CMAKECONFIG # CURL_USE_PKGCONFIG + # GSS_FLAVOR # HAVE_BROTLI # HAVE_GSSAPI # HAVE_LIBIDN2 diff --git a/configure.ac b/configure.ac index a8bf9703fa..f376793bff 100644 --- a/configure.ac +++ b/configure.ac @@ -1914,6 +1914,27 @@ AC_ARG_WITH(gssapi, ] ) +want_gss_apple="no" +if test "$curl_cv_apple" = "yes"; then + AC_MSG_CHECKING([whether to use Apple GSS Framework for GSS-API]) + AC_ARG_ENABLE(gssapi-apple, +AS_HELP_STRING([--enable-gssapi-apple],[Enable Apple GSS Framework (experimental)]) +AS_HELP_STRING([--disable-gssapi-apple],[Disable Apple GSS Framework (experimental) (default)]), [ + case "$enableval" in + yes) + want_gss="yes" + want_gss_apple="yes" + AC_MSG_RESULT([yes]) + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac + ], + AC_MSG_RESULT([no]) + ) +fi + : ${KRB5CONFIG:="$GSSAPI_ROOT/bin/krb5-config"} save_CPPFLAGS="$CPPFLAGS" @@ -1921,130 +1942,146 @@ AC_MSG_CHECKING([if GSS-API support is requested]) if test "$want_gss" = "yes"; then AC_MSG_RESULT(yes) - if test "$GSSAPI_ROOT" != "/usr"; then - CURL_CHECK_PKGCONFIG(mit-krb5-gssapi, $GSSAPI_ROOT/lib/pkgconfig) + if test "$want_gss_apple" = "yes"; then + AC_CHECK_HEADER(GSS/gssapi.h, [ + AC_DEFINE(HAVE_GSSAPPLE, 1, [if you have Apple GSS Framework]) + ],[ + AC_MSG_ERROR([--enable-gssapi-apple was specified, but GSS/gssapi.h was not found]) + ]) else - CURL_CHECK_PKGCONFIG(mit-krb5-gssapi) - fi - if test -z "$GSSAPI_INCS"; then - if test -n "$host_alias" && test -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then - GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi` - elif test "$PKGCONFIG" != "no"; then - GSSAPI_INCS=`$PKGCONFIG --cflags mit-krb5-gssapi` - elif test -f "$KRB5CONFIG"; then - GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi` - elif test "$GSSAPI_ROOT" != "yes"; then - GSSAPI_INCS="-I$GSSAPI_ROOT/include" + if test "$GSSAPI_ROOT" != "/usr"; then + CURL_CHECK_PKGCONFIG(mit-krb5-gssapi, $GSSAPI_ROOT/lib/pkgconfig) + else + CURL_CHECK_PKGCONFIG(mit-krb5-gssapi) fi - fi - - CPPFLAGS="$CPPFLAGS $GSSAPI_INCS" - - AC_CHECK_HEADER(gss.h, - [ - dnl found in the given dirs - AC_DEFINE(HAVE_GSSGNU, 1, [if you have GNU GSS]) - gnu_gss=yes - ], - [ - dnl not found, check for MIT - AC_CHECK_HEADERS( - [gssapi/gssapi.h gssapi/gssapi_generic.h gssapi/gssapi_krb5.h], - [], - [not_mit=1]) - if test "$not_mit" = "1"; then - dnl MIT not found - AC_MSG_ERROR([MIT or GNU GSS library required, but not found]) + if test -z "$GSSAPI_INCS"; then + if test -n "$host_alias" && test -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then + GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi` + elif test "$PKGCONFIG" != "no"; then + GSSAPI_INCS=`$PKGCONFIG --cflags mit-krb5-gssapi` + elif test -f "$KRB5CONFIG"; then + GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi` + elif test "$GSSAPI_ROOT" != "yes"; then + GSSAPI_INCS="-I$GSSAPI_ROOT/include" fi - ] - ) + fi + + CPPFLAGS="$CPPFLAGS $GSSAPI_INCS" + + AC_CHECK_HEADER(gss.h, + [ + dnl found in the given dirs + AC_DEFINE(HAVE_GSSGNU, 1, [if you have GNU GSS]) + gnu_gss=yes + ], + [ + dnl not found, check for MIT + AC_CHECK_HEADERS( + [gssapi/gssapi.h gssapi/gssapi_generic.h gssapi/gssapi_krb5.h], + [], + [not_mit=1]) + if test "$not_mit" = "1"; then + dnl MIT not found + AC_MSG_ERROR([MIT or GNU GSS library required, but not found]) + fi + ] + ) + fi else AC_MSG_RESULT(no) fi if test "$want_gss" = "yes"; then AC_DEFINE(HAVE_GSSAPI, 1, [if you have GSS-API libraries]) HAVE_GSSAPI=1 - curl_gss_msg="enabled (MIT Kerberos)" - link_pkgconfig='' - if test -n "$gnu_gss"; then - curl_gss_msg="enabled (GNU GSS)" - LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" - LDFLAGSPC="$LDFLAGSPC $GSSAPI_LIB_DIR" - LIBS="-lgss $LIBS" - link_pkgconfig=1 - elif test -z "$GSSAPI_LIB_DIR"; then - if test "$curl_cv_apple" = "yes"; then - LIBS="-lgssapi_krb5 -lresolv $LIBS" - else - if test "$GSSAPI_ROOT" != "/usr"; then - CURL_CHECK_PKGCONFIG(mit-krb5-gssapi, $GSSAPI_ROOT/lib/pkgconfig) - else - CURL_CHECK_PKGCONFIG(mit-krb5-gssapi) - fi - if test -n "$host_alias" && test -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then - dnl krb5-config does not have --libs-only-L or similar, put everything - dnl into LIBS - gss_libs=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --libs gssapi` - LIBS="$gss_libs $LIBS" - elif test "$PKGCONFIG" != "no"; then - gss_libs=`$PKGCONFIG --libs mit-krb5-gssapi` - LIBS="$gss_libs $LIBS" - link_pkgconfig=1 - elif test -f "$KRB5CONFIG"; then - dnl krb5-config does not have --libs-only-L or similar, put everything - dnl into LIBS - gss_libs=`$KRB5CONFIG --libs gssapi` - LIBS="$gss_libs $LIBS" - link_pkgconfig=1 - else - case $host in - *-hp-hpux*) - gss_libname="gss" - ;; - *) - gss_libname="gssapi" - ;; - esac + if test "$want_gss_apple" = "yes"; then + curl_gss_msg="enabled (Apple GSS)" + GSS_LDFLAGS='-framework GSS' + LDFLAGS="$LDFLAGS $GSS_LDFLAGS" + LDFLAGSPC="$LDFLAGSPC $GSS_LDFLAGS" + else + curl_gss_msg="enabled (MIT Kerberos)" + link_pkgconfig='' - if test "$GSSAPI_ROOT" != "yes"; then - LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff" - LDFLAGSPC="$LDFLAGSPC -L$GSSAPI_ROOT/lib$libsuff" - LIBS="-l$gss_libname $LIBS" + if test -n "$gnu_gss"; then + curl_gss_msg="enabled (GNU GSS)" + LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" + LDFLAGSPC="$LDFLAGSPC $GSSAPI_LIB_DIR" + LIBS="-lgss $LIBS" + link_pkgconfig=1 + elif test -z "$GSSAPI_LIB_DIR"; then + if test "$curl_cv_apple" = "yes"; then + LIBS="-lgssapi_krb5 -lresolv $LIBS" + else + if test "$GSSAPI_ROOT" != "/usr"; then + CURL_CHECK_PKGCONFIG(mit-krb5-gssapi, $GSSAPI_ROOT/lib/pkgconfig) else - LIBS="-l$gss_libname $LIBS" + CURL_CHECK_PKGCONFIG(mit-krb5-gssapi) + fi + if test -n "$host_alias" && test -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then + dnl krb5-config does not have --libs-only-L or similar, put everything + dnl into LIBS + gss_libs=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --libs gssapi` + LIBS="$gss_libs $LIBS" + elif test "$PKGCONFIG" != "no"; then + gss_libs=`$PKGCONFIG --libs mit-krb5-gssapi` + LIBS="$gss_libs $LIBS" + link_pkgconfig=1 + elif test -f "$KRB5CONFIG"; then + dnl krb5-config does not have --libs-only-L or similar, put everything + dnl into LIBS + gss_libs=`$KRB5CONFIG --libs gssapi` + LIBS="$gss_libs $LIBS" + link_pkgconfig=1 + else + case $host in + *-hp-hpux*) + gss_libname="gss" + ;; + *) + gss_libname="gssapi" + ;; + esac + + if test "$GSSAPI_ROOT" != "yes"; then + LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff" + LDFLAGSPC="$LDFLAGSPC -L$GSSAPI_ROOT/lib$libsuff" + LIBS="-l$gss_libname $LIBS" + else + LIBS="-l$gss_libname $LIBS" + fi fi fi - fi - gss_version="" - if test -n "$host_alias" && test -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then - gss_version=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --version | $SED 's/Kerberos 5 release //'` - elif test "$PKGCONFIG" != "no"; then - gss_version=`$PKGCONFIG --modversion mit-krb5-gssapi` - elif test -f "$KRB5CONFIG"; then - gss_version=`$KRB5CONFIG --version | $SED 's/Kerberos 5 release //'` - fi - if test -n "$gss_version"; then - AC_MSG_NOTICE([GSS-API MIT Kerberos version detected: $gss_version]) - AC_DEFINE_UNQUOTED([CURL_KRB5_VERSION], ["$gss_version"], [MIT Kerberos version]) - fi - else - LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" - LDFLAGSPC="$LDFLAGSPC $GSSAPI_LIB_DIR" - case $host in - *-hp-hpux*) - LIBS="-lgss $LIBS" - ;; - *) - LIBS="-lgssapi $LIBS" - ;; - esac - fi - if test -n "$link_pkgconfig"; then - if test -n "$gnu_gss"; then - LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE gss" + gss_version="" + if test -n "$host_alias" && test -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then + gss_version=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --version | $SED 's/Kerberos 5 release //'` + elif test "$PKGCONFIG" != "no"; then + gss_version=`$PKGCONFIG --modversion mit-krb5-gssapi` + elif test -f "$KRB5CONFIG"; then + gss_version=`$KRB5CONFIG --version | $SED 's/Kerberos 5 release //'` + fi + if test -n "$gss_version"; then + AC_MSG_NOTICE([GSS-API MIT Kerberos version detected: $gss_version]) + AC_DEFINE_UNQUOTED([CURL_KRB5_VERSION], ["$gss_version"], [MIT Kerberos version]) + fi else - LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE mit-krb5-gssapi" + LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" + LDFLAGSPC="$LDFLAGSPC $GSSAPI_LIB_DIR" + case $host in + *-hp-hpux*) + LIBS="-lgss $LIBS" + ;; + *) + LIBS="-lgssapi $LIBS" + ;; + esac + fi + if test -n "$link_pkgconfig"; then + if test -n "$gnu_gss"; then + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE gss" + else + LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE mit-krb5-gssapi" + fi fi fi else diff --git a/docs/INSTALL-CMAKE.md b/docs/INSTALL-CMAKE.md index 52fc596cdb..d1e5251d4f 100644 --- a/docs/INSTALL-CMAKE.md +++ b/docs/INSTALL-CMAKE.md @@ -346,6 +346,7 @@ Details via CMake - `CURL_BROTLI`: Use brotli (`ON`, `OFF` or `AUTO`). Default: `AUTO` - `CURL_USE_CMAKECONFIG`: Enable detecting dependencies via CMake Config. Default: `ON` for MSVC (except under vcpkg), if not cross-compiling. (experimental) +- `CURL_GSS_FLAVOR`: Set preferred GSSAPI implementation (`Apple`). Default: MIT, then GNU (experimental) - `CURL_USE_GNUTLS`: Enable GnuTLS for SSL/TLS. Default: `OFF` - `CURL_USE_GSASL`: Use libgsasl. Default: `OFF` - `CURL_USE_GSSAPI`: Use GSSAPI implementation. Default: `OFF` diff --git a/lib/curl_config-cmake.h.in b/lib/curl_config-cmake.h.in index add3b26aad..caedb552ad 100644 --- a/lib/curl_config-cmake.h.in +++ b/lib/curl_config-cmake.h.in @@ -321,6 +321,9 @@ /* if you have the gssapi libraries */ #cmakedefine HAVE_GSSAPI 1 +/* if you have Apple GSS */ +#cmakedefine HAVE_GSSAPPLE 1 + /* if you have the GNU gssapi libraries */ #cmakedefine HAVE_GSSGNU 1 diff --git a/lib/curl_gssapi.c b/lib/curl_gssapi.c index 07a6c1e7ed..fbc3c262f1 100644 --- a/lib/curl_gssapi.c +++ b/lib/curl_gssapi.c @@ -55,7 +55,7 @@ #define CURL_ALIGN8 #endif -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif @@ -440,7 +440,7 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, } #endif /* CURLVERBOSE */ -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic pop #endif diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c index e10899c7e7..9a5ad62f5c 100644 --- a/lib/socks_gssapi.c +++ b/lib/socks_gssapi.c @@ -35,7 +35,7 @@ #include "socks.h" #include "curlx/strdup.h" -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif @@ -593,7 +593,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, return result; } -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic pop #endif diff --git a/lib/urldata.h b/lib/urldata.h index 8a716d5590..89ca31a0f7 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -98,7 +98,10 @@ typedef CURLcode (Curl_recv)(struct Curl_easy *data, /* transfer */ #include "cf-socket.h" #ifdef HAVE_GSSAPI -# ifdef HAVE_GSSGNU +# ifdef HAVE_GSSAPPLE +# include +# include +# elif defined(HAVE_GSSGNU) # include # elif defined(HAVE_GSSAPI_H) # include diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c index 738ce9a744..41c47c055d 100644 --- a/lib/vauth/krb5_gssapi.c +++ b/lib/vauth/krb5_gssapi.c @@ -33,7 +33,7 @@ #include "curl_gssapi.h" #include "curl_trc.h" -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif @@ -318,7 +318,7 @@ void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) } } -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic pop #endif diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c index 869a27fdc9..1483b1f1e5 100644 --- a/lib/vauth/spnego_gssapi.c +++ b/lib/vauth/spnego_gssapi.c @@ -32,7 +32,7 @@ #include "curl_gssapi.h" #include "curl_trc.h" -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif @@ -288,7 +288,7 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego) nego->havemultiplerequests = FALSE; } -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) +#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) && !defined(HAVE_GSSAPPLE) #pragma GCC diagnostic pop #endif diff --git a/lib/version.c b/lib/version.c index 299caee9fb..94d6c0bf43 100644 --- a/lib/version.c +++ b/lib/version.c @@ -242,7 +242,9 @@ char *curl_version(void) src[i++] = gsasl_buf; #endif #ifdef HAVE_GSSAPI -#ifdef HAVE_GSSGNU +#ifdef HAVE_GSSAPPLE + curl_msnprintf(gss_buf, sizeof(gss_buf), "AppleGSS"); +#elif defined(HAVE_GSSGNU) curl_msnprintf(gss_buf, sizeof(gss_buf), "libgss/%s", GSS_VERSION); #elif defined(CURL_KRB5_VERSION) curl_msnprintf(gss_buf, sizeof(gss_buf), "mit-krb5/%s", CURL_KRB5_VERSION);