[cmake] simplify krb5 detection

This commit is contained in:
akallabeth 2023-02-24 15:31:36 +01:00 committed by Martin Fleisz
parent acc415442a
commit c9e61ff0c5
8 changed files with 222 additions and 478 deletions

View File

@ -1,465 +1,222 @@
# - Try to find the Kerberos libraries
# Once done this will define
#
# KRB_ROOT_DIR - Set this variable to the root installation of Kerberos
# KRB_ROOT_FLAVOUR - Set this variable to the flavour of Kerberos installation (MIT or Heimdal)
# KRB5_ROOT_CONFIG - Set this variable to the full path of krb5-config of Kerberos
# KRB5_ROOT_FLAVOUR - Set this variable to the flavour of Kerberos installation (MIT or Heimdal)
#
# Read-Only variables:
# KRB5_FOUND - system has the Heimdal library
# KRB5_FLAVOUR - "MIT" or "Heimdal" if anything found.
# KRB5_INCLUDE_DIR - the Heimdal include directory
# KRB5_INCLUDE_DIRS - the Heimdal include directory
# KRB5_LIBRARIES - The libraries needed to use Kerberos
# KRB5_LINK_DIRECTORIES - Directories to add to linker search path
# KRB5_LINKER_FLAGS - Additional linker flags
# KRB5_COMPILER_FLAGS - Additional compiler flags
# KRB5_LIBRARY_DIRS - Directories to add to linker search path
# KRB5_LDFLAGS - Additional linker flags
# KRB5_CFLAGS - Additional compiler flags
# KRB5_VERSION - This is set to version advertised by pkg-config or read from manifest.
# In case the library is found but no version info availabe it'll be set to "unknown"
set(_MIT_MODNAME mit-krb5)
set(_HEIMDAL_MODNAME heimdal-krb5)
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckTypeSize)
# export KRB_ROOT_FLAVOUR to use pkg-config system under UNIX
if (NOT KRB_ROOT_FLAVOUR)
set(KRB_ROOT_FLAVOUR $ENV{KRB_ROOT_FLAVOUR})
endif()
set(_KRB5_REQUIRED_VARS
KRB5_FOUND
KRB5_VERSION
KRB5_FLAVOUR
KRB5_INCLUDE_DIRS
KRB5_LIBRARIES)
if (NOT KRB_ROOT_DIR)
set(KRB_ROOT_DIR $ENV{KRB_ROOT_DIR})
endif()
macro(PROVIDES_KRB5)
set(PREFIX "MACRO_KRB5")
if(UNIX)
if(NOT "${KRB_ROOT_FLAVOUR} " STREQUAL " ")
string(REGEX MATCH "^[M|m]it$" MIT_FLAVOUR "${KRB_ROOT_FLAVOUR}")
if(NOT MIT_FLAVOUR)
string(REGEX MATCH "^MIT$" MIT_FLAVOUR "${KRB_ROOT_FLAVOUR}")
endif()
string(REGEX MATCH "^[H|h]eimdal$" HEIMDAL_FLAVOUR "${KRB_ROOT_FLAVOUR}")
if(NOT HEIMDAL_FLAVOUR)
string(REGEX MATCH "^HEIMDAL$" HEIMDAL_FLAVOUR "${KRB_ROOT_FLAVOUR}")
endif()
if(MIT_FLAVOUR)
set(KRB5_FLAVOUR "MIT")
elseif(HEIMDAL_FLAVOUR)
set(KRB5_FLAVOUR "Heimdal")
else()
message(SEND_ERROR "Kerberos flavour unknown (${KRB_ROOT_FLAVOUR}). Choose MIT or Heimdal.")
endif()
cmake_parse_arguments(
"${PREFIX}"
""
"NAME"
""
${ARGN})
set(KRB5_FLAVOUR ${MACRO_KRB5_NAME})
string(TOUPPER "${MACRO_KRB5_NAME}" MACRO_KRB5_NAME)
# This is a list of all variables that pkg_check_modules exports.
set(VARIABLES "CFLAGS;CFLAGS_I;CFLAGS_OTHER;FOUND;INCLUDEDIR;INCLUDE_DIRS;LDFLAGS;LDFLAGS_OTHER;LIBDIR;LIBRARIES;LIBRARY_DIRS;LIBS;LIBS_L;LIBS_OTHER;LIBS_PATHS;LINK_LIBRARIS;MODULE_NAME;PREFIX;VERSION;STATIC_CFLAGS;STATIC_CFLAGS_I;STATIC_CFLAGS_OTHER;STATIC_INCLUDE_DIRS;STATIC_LDFLAGS;STATIC_LDFLAGS_OTHER;STATIC_LIBDIR;STATIC_LIBRARIES;STATIC_LIBRARY_DIRS;STATIC_LIBS;STATIC_LIBS_L;STATIC_LIBS_OTHER;STATIC_LIBS_PATHS")
foreach(VAR ${VARIABLES})
set(KRB5_${VAR} ${KRB5_${MACRO_KRB5_NAME}_${VAR}})
endforeach()
# Bugfix for older installations:
# KRB5_INCLUDE_DIRS might not be set, fall back to KRB5_INCLUDEDIR
if (NOT KRB5_INCLUDE_DIRS)
set(KRB5_INCLUDE_DIRS ${KRB5_INCLUDEDIR})
endif()
endif()
endmacro()
set(_KRB5_ROOT_HINTS
"${KRB_ROOT_DIR}"
)
# try to find library using system pkg-config if user did not specify root dir
if(UNIX)
if("${KRB_ROOT_DIR} " STREQUAL " ")
if (NOT KRB5_FLAVOUR)
message("KRB5_FLAVOUR not defined, defaulting to MIT")
set(KRB5_FLAVOUR "MIT")
endif()
if(KRB5_FLAVOUR)
find_package(PkgConfig QUIET)
if(KRB5_FLAVOUR STREQUAL "MIT")
pkg_search_module(_KRB5_PKG ${_MIT_MODNAME})
else()
pkg_search_module(_KRB5_PKG ${_HEIMDAL_MODNAME})
endif()
if("${_KRB5_PKG_PREFIX} " STREQUAL " ")
if(NOT "$ENV{PKG_CONFIG_PATH} " STREQUAL " ")
list(APPEND _KRB5_ROOT_HINTS "$ENV{PKG_CONFIG_PATH}")
else()
message(WARNING "pkg_search_module failed : try to set PKG_CONFIG_PATH to PREFIX_OF_KERBEROS/lib/pkgconfig")
endif()
else()
if("${KRB_ROOT_FLAVOUR}" STREQUAL "Heimdal")
string(FIND "${_KRB5_PKG_PREFIX}" "heimdal" PKG_HEIMDAL_PREFIX_POSITION)
if(PKG_HEIMDAL_PREFIX_POSITION STREQUAL "-1")
message(WARNING "Try to set PKG_CONFIG_PATH to \"PREFIX_OF_KERBEROS/lib/pkgconfig\"")
else()
list(APPEND _KRB5_ROOT_HINTS "${_KRB5_PKG_PREFIX}")
endif()
else()
list(APPEND _KRB5_ROOT_HINTS "${_KRB5_PKG_PREFIX}")
endif()
endif()
else()
message(WARNING "export KRB_ROOT_FLAVOUR to use pkg-config")
endif()
endif()
elseif(WIN32)
list(APPEND _KRB5_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
endif()
if(NOT KRB5_FOUND) # not found by pkg-config. Let's take more traditional approach.
if(KRB5_FLAVOUR STREQUAL "MIT")
set(_KRB5_CONFIGURE_SCRIPT_SUFFIX ".mit")
elseif(KRB5_FLAVOUR STREQUAL "Heimdal")
set(_KRB5_CONFIGURE_SCRIPT_SUFFIX ".heimdal")
endif()
find_file(_KRB5_CONFIGURE_SCRIPT
NAMES
"krb5-config${_KRB5_CONFIGURE_SCRIPT_SUFFIX}"
"krb5-config"
HINTS
${_KRB5_ROOT_HINTS}
PATH_SUFFIXES
bin
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
function(GET_KRB5_CONFIG KRB5_CONFIG COMMAND RESULT)
execute_process(
COMMAND ${KRB5_CONFIG} ${COMMAND}
OUTPUT_VARIABLE _KRB5_RESULT
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
)
if (_KRB5_CONFIGURE_FAILED)
message(FATAL_ERROR "Failed to detect krb5-config [${COMMAND}]")
endif()
if (${_KRB5_CONFIGURE_SCRIPT} STREQUAL "_KRB5_CONFIGURE_SCRIPT-NOTFOUND")
# if not found in user-supplied directories, maybe system knows better
find_file(_KRB5_CONFIGURE_SCRIPT
NAMES
"krb5-config${_KRB5_CONFIGURE_SCRIPT_SUFFIX}"
PATH_SUFFIXES
string(REGEX REPLACE "[\r\n]" "" _KRB5_RESULT ${_KRB5_RESULT})
set(${RESULT} "${_KRB5_RESULT}" PARENT_SCOPE)
endfunction()
function(string_starts_with str search RES)
string(FIND "${str}" "${search}" out)
if("${out}" EQUAL 0)
set(${RES} ON PARENT_SCOPE)
else()
set(${RES} OFF PARENT_SCOPE)
endif()
endfunction()
function(GET_KRB5_BY_CONFIG KRB5_CONFIG)
if (NOT KRB5_CONFIG)
find_file(KRB5_CONFIG
NAMES
"krb5-config"
"krb5-config.mit"
"krb5-config.heimdal"
PATH_SUFFIXES
bin
)
endif()
if (NOT ${_KRB5_CONFIGURE_SCRIPT} STREQUAL "_KRB5_CONFIGURE_SCRIPT-NOTFOUND")
execute_process(
COMMAND ${_KRB5_CONFIGURE_SCRIPT} "--vendor"
OUTPUT_VARIABLE _KRB5_VENDOR
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
)
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
REQUIRED
)
message("autodetected krb5-config at ${KRB5_CONFIG}")
else()
set(_KRB5_CONFIGURE_FAILED 1)
message("using krb5-config ${KRB5_CONFIG} provided by KRB5_ROOT_CONFIG")
endif()
if(NOT _KRB5_CONFIGURE_FAILED)
string(STRIP "${_KRB5_VENDOR}" _KRB5_VENDOR)
if( (KRB5_FLAVOUR STREQUAL "Heimdal" AND NOT _KRB5_VENDOR STREQUAL "Heimdal")
OR (KRB5_FLAVOUR STREQUAL "MIT" AND NOT _KRB5_VENDOR STREQUAL "Apple MITKerberosShim")
OR (KRB5_FLAVOUR STREQUAL "MIT" AND NOT _KRB5_VENDOR STREQUAL "Massachusetts Institute of Technology"))
message(WARNING "Kerberos vendor and Kerberos flavour are not matching : _KRB5_VENDOR=${_KRB5_VENDOR} ; KRB5_FLAVOUR=${KRB5_FLAVOUR}")
message(STATUS "Try to set the path to Kerberos root folder in the system variable KRB_ROOT_DIR")
endif()
GET_KRB5_CONFIG("${KRB5_CONFIG}" "--vendor" _KRB5_VENDOR)
if ("${_KRB5_VENDOR}" STREQUAL "Apple MITKerberosShim")
message(FATAL_ERROR "Apple MITKerberosShim is deprecated and not supported")
elseif ("${_KRB5_VENDOR}" STREQUAL "Massachusetts Institute of Technology")
set(KRB5_FLAVOUR "MIT")
else()
message(SEND_ERROR "Kerberos configure script failed to get vendor")
set(KRB5_FLAVOUR "${_KRB5_VENDOR}")
endif()
# NOTE: fail to link Heimdal libraries using configure script due to limitations
# during Heimdal linking process. Then, we do it "manually".
if(NOT "${_KRB5_CONFIGURE_SCRIPT} " STREQUAL " " AND KRB5_FLAVOUR AND NOT _KRB5_VENDOR STREQUAL "Heimdal")
execute_process(
COMMAND ${_KRB5_CONFIGURE_SCRIPT} "--cflags"
OUTPUT_VARIABLE _KRB5_CFLAGS
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
GET_KRB5_CONFIG("${KRB5_CONFIG}" "--cflags" KRB5_CFLAGS)
GET_KRB5_CONFIG("${KRB5_CONFIG}" "--version" KRB5_VERSION_RAW)
string(REGEX REPLACE "[ ]" ";" KRB5_VERSION_LIST "${KRB5_VERSION_RAW}")
list(LENGTH KRB5_VERSION_LIST KRB5_VERSION_LIST_LEN)
math(EXPR KRB5_VERSION_LIST_LAST "${KRB5_VERSION_LIST_LEN} - 1")
list(GET KRB5_VERSION_LIST ${KRB5_VERSION_LIST_LAST} KRB5_VERSION)
if (KRB5_FLAVOUR STREQUAL "MIT")
if (KRB5_VERSION VERSION_LESS "1.14")
message(FATAL_ERROR "MIT kerberos ${KRB5_VERSION} < 1.14 is not supported, upgrade the library!")
endif()
endif()
GET_KRB5_CONFIG("${KRB5_CONFIG}" "--libs" KRB5_LDFLAGS)
string(REGEX REPLACE "[ ]" ";" KRB5_CFLAG_LIST "${KRB5_CFLAGS}")
foreach(FLAG ${KRB5_CFLAG_LIST})
string_starts_with("${FLAG}" "-I" RES)
if (RES)
string(SUBSTRING "${FLAG}" 2 -1 FLAG)
endif()
if (IS_DIRECTORY "${FLAG}")
list(APPEND KRB5_INCLUDEDIR ${FLAG})
endif()
endforeach()
if (NOT KRB5_INCLUDEDIR)
find_file(KRB5_INCLUDEDIR_HEADER
NAMES krb5.h
REQUIRED
)
get_filename_component(KRB5_INCLUDEDIR "${KRB5_INCLUDEDIR_HEADER}" DIRECTORY)
endif()
if(NOT _KRB5_CONFIGURE_FAILED) # 0 means success
# should also work in an odd case when multiple directories are given
string(STRIP "${_KRB5_CFLAGS}" _KRB5_CFLAGS)
string(REGEX REPLACE " +-I" ";" _KRB5_CFLAGS "${_KRB5_CFLAGS}")
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _KRB5_CFLAGS "${_KRB5_CFLAGS}")
foreach(_flag ${_KRB5_CFLAGS})
if(_flag MATCHES "^-I.*")
string(REGEX REPLACE "^-I" "" _val "${_flag}")
list(APPEND _KRB5_INCLUDE_DIR "${_val}")
else()
list(APPEND _KRB5_COMPILER_FLAGS "${_flag}")
endif()
endforeach()
string(REGEX REPLACE "[ ]" ";" KRB5_LDFLAG_LIST "${KRB5_LDFLAGS}")
foreach(FLAG ${KRB5_LDFLAG_LIST})
string_starts_with("${FLAG}" "-L" RES)
if (RES)
string(SUBSTRING "${FLAG}" 2 -1 SUBFLAG)
list(APPEND KRB5_LIBRARY_DIRS ${SUBFLAG})
endif()
if(_KRB5_VENDOR STREQUAL "Apple MITKerberosShim")
execute_process(
COMMAND ${_KRB5_CONFIGURE_SCRIPT} "--libs"
OUTPUT_VARIABLE _KRB5_LIB_FLAGS
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
)
elseif(_KRB5_VENDOR STREQUAL "Massachusetts Institute of Technology")
execute_process(
COMMAND ${_KRB5_CONFIGURE_SCRIPT} "--libs"
OUTPUT_VARIABLE _KRB5_LIB_FLAGS
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
)
elseif(_KRB5_VENDOR STREQUAL "Heimdal")
execute_process(
COMMAND ${_KRB5_CONFIGURE_SCRIPT} "--deps --libs"
OUTPUT_VARIABLE _KRB5_LIB_FLAGS
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
)
else()
message(SEND_ERROR "Unknown vendor '${_KRB5_VENDOR}'")
string_starts_with("${FLAG}" "-l" RES)
if (RES)
string(SUBSTRING "${FLAG}" 2 -1 SUBFLAG)
list(APPEND KRB5_LIBRARIES ${SUBFLAG})
endif()
endforeach()
if(NOT _KRB5_CONFIGURE_FAILED) # 0 means success
# this script gives us libraries and link directories. We have to deal with it.
string(STRIP "${_KRB5_LIB_FLAGS}" _KRB5_LIB_FLAGS)
string(REGEX REPLACE " +-(L|l)" ";-\\1" _KRB5_LIB_FLAGS "${_KRB5_LIB_FLAGS}")
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _KRB5_LIB_FLAGS "${_KRB5_LIB_FLAGS}")
set(KRB5_FOUND ON PARENT_SCOPE)
set(KRB5_VERSION ${KRB5_VERSION} PARENT_SCOPE)
set(KRB5_FLAVOUR ${KRB5_FLAVOUR} PARENT_SCOPE)
set(KRB5_CFLAGS ${KRB5_CFLAGS} PARENT_SCOPE)
set(KRB5_LDFLAGS ${KRB5_LDFLAGS} PARENT_SCOPE)
set(KRB5_INCLUDEDIR ${KRB5_INCLUDEDIR} PARENT_SCOPE)
set(KRB5_INCLUDE_DIRS ${KRB5_INCLUDEDIR} PARENT_SCOPE)
set(KRB5_LIBRARIES ${KRB5_LIBRARIES} PARENT_SCOPE)
set(KRB5_LIBRARY_DIRS ${KRB5_LIBRARY_DIRS} PARENT_SCOPE)
endfunction()
foreach(_flag ${_KRB5_LIB_FLAGS})
if(_flag MATCHES "^-l.*")
string(REGEX REPLACE "^-l" "" _val "${_flag}")
list(APPEND _KRB5_LIBRARIES "${_val}")
elseif(_flag MATCHES "^-L.*")
string(REGEX REPLACE "^-L" "" _val "${_flag}")
list(APPEND _KRB5_LINK_DIRECTORIES "${_val}")
else()
list(APPEND _KRB5_LINKER_FLAGS "${_flag}")
endif()
endforeach()
# try to find kerberos to compile against.
#
# * First search with pkg-config (prefer MIT over Heimdal)
# * Then try to find krb5-config (generic, krb5-config.mit and last krb5-config.heimdal)
include(FindPkgConfig)
find_package(PkgConfig REQUIRED)
endif()
execute_process(
COMMAND ${_KRB5_CONFIGURE_SCRIPT} "--version"
OUTPUT_VARIABLE _KRB5_VERSION
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
)
# older versions may not have the "--version" parameter. In this case we just don't care.
if(_KRB5_CONFIGURE_FAILED)
set(_KRB5_VERSION 0)
endif()
else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
if(_KRB5_VENDOR STREQUAL "Massachusetts Institute of Technology")
find_path(_KRB5_INCLUDE_DIR
NAMES
"gssapi/gssapi_generic.h"
HINTS
${_KRB5_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_KRB5_INCLUDE_DIR) # we've found something
set(CMAKE_REQUIRED_INCLUDES "${_KRB5_INCLUDE_DIR}")
check_include_files( "krb5/krb5.h" _KRB5_HAVE_MIT_HEADERS)
if(_KRB5_HAVE_MIT_HEADERS)
set(KRB5_FLAVOUR "MIT")
else()
message(SEND_ERROR "Try to set the Kerberos flavour (KRB_ROOT_FLAVOUR)")
endif()
elseif("$ENV{PKG_CONFIG_PATH} " STREQUAL " ")
message(WARNING "Try to set PKG_CONFIG_PATH to PREFIX_OF_KERBEROS/lib/pkgconfig")
endif()
elseif(_KRB5_VENDOR STREQUAL "Heimdal")
find_path(_KRB5_INCLUDE_DIR
NAMES
"gssapi/gssapi_spnego.h"
HINTS
${_KRB5_ROOT_HINTS}
PATHS
/usr/heimdal
/usr/local/heimdal
PATH_SUFFIXES
include
inc
)
if(_KRB5_INCLUDE_DIR) # we've found something
set(CMAKE_REQUIRED_INCLUDES "${_KRB5_INCLUDE_DIR}")
# prevent compiling the header - just check if we can include it
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
check_include_file( "roken.h" _KRB5_HAVE_ROKEN_H)
check_include_file( "heimdal/roken.h" _KRB5_HAVE_HEIMDAL_ROKEN_H)
if(_KRB5_HAVE_ROKEN_H OR _KRB5_HAVE_HEIMDAL_ROKEN_H)
set(KRB5_FLAVOUR "Heimdal")
endif()
set(CMAKE_REQUIRED_DEFINITIONS "")
elseif("$ENV{PKG_CONFIG_PATH} " STREQUAL " ")
message(WARNING "Try to set PKG_CONFIG_PATH to PREFIX_OF_KERBEROS/lib/pkgconfig")
endif()
else()
message(SEND_ERROR "Kerberos vendor unknown (${_KRB5_VENDOR})")
endif()
# if we have headers, check if we can link libraries
if(KRB5_FLAVOUR)
set(_KRB5_LIBDIR_SUFFIXES "")
set(_KRB5_LIBDIR_HINTS ${_KRB5_ROOT_HINTS})
get_filename_component(_KRB5_CALCULATED_POTENTIAL_ROOT "${_KRB5_INCLUDE_DIR}" PATH)
list(APPEND _KRB5_LIBDIR_HINTS ${_KRB5_CALCULATED_POTENTIAL_ROOT})
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND _KRB5_LIBDIR_SUFFIXES "lib/AMD64")
if(KRB5_FLAVOUR STREQUAL "MIT")
set(_KRB5_LIBNAME "krb5_64")
else()
set(_KRB5_LIBNAME "libkrb5")
endif()
else()
list(APPEND _KRB5_LIBDIR_SUFFIXES "lib/i386")
if(KRB5_FLAVOUR STREQUAL "MIT")
set(_KRB5_LIBNAME "krb5_32")
else()
set(_KRB5_LIBNAME "libkrb5")
endif()
endif()
else()
list(APPEND _KRB5_LIBDIR_SUFFIXES "lib;lib64;x86_64-linux-gnu") # those suffixes are not checked for HINTS
if(KRB5_FLAVOUR STREQUAL "MIT")
set(_KRB5_LIBNAME "krb5")
set(_COMERR_LIBNAME "com_err")
set(_KRB5SUPPORT_LIBNAME "krb5support")
else()
set(_KRB5_LIBNAME "krb5")
set(_ROKEN_LIBNAME "roken")
endif()
endif()
if(KRB5_FLAVOUR STREQUAL "MIT")
find_library(_KRB5_LIBRARY
NAMES
${_KRB5_LIBNAME}
HINTS
${_KRB5_LIBDIR_HINTS}
PATH_SUFFIXES
${_KRB5_LIBDIR_SUFFIXES}
)
find_library(_COMERR_LIBRARY
NAMES
${_COMERR_LIBNAME}
HINTS
${_KRB5_LIBDIR_HINTS}
PATH_SUFFIXES
${_KRB5_LIBDIR_SUFFIXES}
)
find_library(_KRB5SUPPORT_LIBRARY
NAMES
${_KRB5SUPPORT_LIBNAME}
HINTS
${_KRB5_LIBDIR_HINTS}
PATH_SUFFIXES
${_KRB5_LIBDIR_SUFFIXES}
)
list(APPEND _KRB5_LIBRARIES ${_KRB5_LIBRARY} ${_KRB5SUPPORT_LIBRARY} ${_COMERR_LIBRARY})
endif()
if(KRB5_FLAVOUR STREQUAL "Heimdal")
find_library(_KRB5_LIBRARY
NAMES
${_KRB5_LIBNAME}
HINTS
${_KRB5_LIBDIR_HINTS}
PATH_SUFFIXES
${_KRB5_LIBDIR_SUFFIXES}
)
find_library(_ROKEN_LIBRARY
NAMES
${_ROKEN_LIBNAME}
HINTS
${_KRB5_LIBDIR_HINTS}
PATH_SUFFIXES
${_KRB5_LIBDIR_SUFFIXES}
)
list(APPEND _KRB5_LIBRARIES ${_KRB5_LIBRARY})
endif()
endif()
execute_process(
COMMAND ${_KRB5_CONFIGURE_SCRIPT} "--version"
OUTPUT_VARIABLE _KRB5_VERSION
RESULT_VARIABLE _KRB5_CONFIGURE_FAILED
)
# older versions may not have the "--version" parameter. In this case we just don't care.
if(_KRB5_CONFIGURE_FAILED)
set(_KRB5_VERSION 0)
endif()
if (KRB5_ROOT_CONFIG)
elseif (KRB5_ROOT_FLAVOUR)
if (KRB5_ROOT_FLAVOUR STREQUAL "Heimdal")
pkg_check_modules(KRB5_HEIMDAL heimdal-krb5)
elseif (KRB5_ROOT_FLAVOUR STREQUAL "MIT")
pkg_check_modules(KRB5_HEIMDAL mit-krb5)
else()
message(FATAL_ERROR "Invalid KRB5_ROOT_FLAVOUR=${KRB5_ROOT_FLAVOUR}, only 'MIT' or 'Heimdal' are supported")
endif()
else()
if(_KRB5_PKG_${_MIT_MODNAME}_VERSION)
set(KRB5_FLAVOUR "MIT")
set(_KRB5_VERSION _KRB5_PKG_${_MIT_MODNAME}_VERSION)
else()
set(KRB5_FLAVOUR "Heimdal")
set(_KRB5_VERSION _KRB5_PKG_${_HEIMDAL_MODNAME}_VERSION)
endif()
pkg_check_modules(KRB5_MIT mit-krb5)
pkg_check_modules(KRB5_HEIMDAL heimdal-krb5)
endif()
set(KRB5_INCLUDE_DIR ${_KRB5_INCLUDE_DIR})
set(KRB5_LIBRARIES ${_KRB5_LIBRARIES})
set(KRB5_LINK_DIRECTORIES ${_KRB5_LINK_DIRECTORIES})
set(KRB5_LINKER_FLAGS ${_KRB5_LINKER_FLAGS})
set(KRB5_COMPILER_FLAGS ${_KRB5_COMPILER_FLAGS})
set(KRB5_VERSION ${_KRB5_VERSION})
if(KRB5_FLAVOUR)
if(NOT KRB5_VERSION AND KRB5_FLAVOUR STREQUAL "Heimdal")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
else()
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
endif()
if(EXISTS "${KRB5_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
file(STRINGS "${KRB5_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
string(REGEX MATCH "[0-9]\\.[^\"]+"
KRB5_VERSION "${heimdal_version_str}")
endif()
if(NOT KRB5_VERSION)
set(KRB5_VERSION "Heimdal Unknown")
endif()
elseif(NOT KRB5_VERSION AND KRB5_FLAVOUR STREQUAL "MIT")
get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
if(WIN32 AND _MIT_VERSION)
set(KRB5_VERSION "${_MIT_VERSION}")
else()
set(KRB5_VERSION "MIT Unknown")
endif()
if (KRB5_MIT_FOUND)
PROVIDES_KRB5(NAME "MIT")
if (KRB5_VERSION VERSION_LESS "1.14")
message(FATAL_ERROR "MIT kerberos < 1.14 is not supported, upgrade the library!")
endif()
elseif(KRB5_HEIMDAL_FOUND)
PROVIDES_KRB5(NAME "Heimdal")
elseif(KRB5_ANY_FOUND)
GET_KRB5_VENDOR(ANY_VENDOR)
PROVIDES_KRB5(NAME "${ANY_VENDOR}")
else()
GET_KRB5_BY_CONFIG(${KRB5_ROOT_CONFIG})
endif()
#message("using KRB5_FOUND ${KRB5_FOUND} ")
#message("using KRB5_VERSION ${KRB5_VERSION} ")
#message("using KRB5_FLAVOUR ${KRB5_FLAVOUR} ")
#message("using KRB5_CFLAGS ${KRB5_CFLAGS} ")
#message("using KRB5_LDFLAGS ${KRB5_LDFLAGS} ")
#message("using KRB5_INCLUDEDIR ${KRB5_INCLUDEDIR} ")
#message("using KRB5_INCLUDE_DIRS ${KRB5_INCLUDEDIR} ")
#message("using KRB5_LIBRARIES ${KRB5_LIBRARIES} ")
include(FindPackageHandleStandardArgs)
set(_KRB5_REQUIRED_VARS KRB5_LIBRARIES KRB5_FLAVOUR)
find_package_handle_standard_args(KRB5
REQUIRED_VARS
${_KRB5_REQUIRED_VARS}
VERSION_VAR
KRB5_VERSION
FAIL_MESSAGE
"Could NOT find Kerberos, try to set the path to Kerberos root folder in the system variable KRB_ROOT_DIR"
REQUIRED_VARS
${_KRB5_REQUIRED_VARS}
VERSION_VAR
KRB5_VERSION
FAIL_MESSAGE
"Could NOT find Kerberos, try to set the path to Kerberos root folder in the system variable KRB_ROOT_DIR"
)
if(KRB5_FLAVOUR STREQUAL "MIT")
string(STRIP "${KRB5_VERSION}" KRB5_VERSION)
string(SUBSTRING ${KRB5_VERSION} 19 -1 KRB5_RELEASE_NUMBER)
string(REGEX MATCH "([0-9]+)\\." KRB5_VERSION_MAJOR ${KRB5_RELEASE_NUMBER})
string(REGEX REPLACE "\\." "" KRB5_VERSION_MAJOR "${KRB5_VERSION_MAJOR}")
string(REGEX MATCH "\\.([0-9]+)$" KRB5_VERSION_MINOR ${KRB5_RELEASE_NUMBER})
if(NOT KRB5_VERSION_MINOR)
string(REGEX MATCH "\\.([0-9]+)[-\\.]" KRB5_VERSION_MINOR ${KRB5_RELEASE_NUMBER})
string(REGEX REPLACE "\\." "" KRB5_VERSION_MINOR "${KRB5_VERSION_MINOR}")
string(REGEX REPLACE "\\." "" KRB5_VERSION_MINOR "${KRB5_VERSION_MINOR}")
string(REGEX REPLACE "-" "" KRB5_VERSION_MINOR "${KRB5_VERSION_MINOR}")
string(REGEX MATCH "\\.([0-9]+)$" KRB5_VERSION_PATCH "${KRB5_RELEASE_NUMBER}")
string(REGEX REPLACE "\\." "" KRB5_VERSION_PATCH "${KRB5_VERSION_PATCH}")
if(NOT KRB5_VERSION_PATCH)
set(KRB5_VERSION_PATCH "0")
endif()
else()
string(REGEX REPLACE "\\." "" KRB5_VERSION_MINOR "${KRB5_VERSION_MINOR}")
set(KRB5_VERSION_PATCH "0")
endif()
if(KRB5_VERSION_MAJOR AND KRB5_VERSION_MINOR)
string(COMPARE GREATER ${KRB5_VERSION_MAJOR} 0 KRB5_VERSION_1)
string(COMPARE GREATER ${KRB5_VERSION_MINOR} 12 KRB5_VERSION_1_13)
else()
message(SEND_ERROR "Failed to retrieved Kerberos version number")
endif()
message(STATUS "Located Kerberos ${KRB5_VERSION_MAJOR}.${KRB5_VERSION_MINOR}.${KRB5_VERSION_PATCH}")
endif()
mark_as_advanced(KRB5_INCLUDE_DIR KRB5_LIBRARIES)
mark_as_advanced(${_KRB5_REQUIRED_VARS})

View File

@ -67,36 +67,6 @@ option(WITH_DEBUG_MUTEX "Print mutex debug messages" ${DEFAULT_DEBUG_OPTION})
option(WITH_INTERNAL_MD4 "Use compiled in md4 hash functions instead of OpenSSL/MBedTLS" OFF)
option(WITH_INTERNAL_MD5 "Use compiled in md5 hash functions instead of OpenSSL/MBedTLS" OFF)
if (NOT WIN32 AND NOT ANDROID AND NOT IOS)
option(WITH_KRB5 "Compile support for kerberos authentication. (EXPERIMENTAL)" OFF)
if (WITH_KRB5)
find_package(KRB5 REQUIRED)
endif()
if ( (WITH_KRB5) AND (NOT KRB5_FOUND))
message(WARNING "-DWITH_KRB5=ON is set, but no kerberos implementation was found, disabling")
elseif(WITH_KRB5)
if(KRB5_FLAVOUR STREQUAL "MIT")
add_definitions("-DWITH_KRB5 -DWITH_KRB5_MIT")
if(KRB5_VERSION_1_13)
add_definitions("-DWINPR_HAVE_AT_LEAST_KRB_V1_13")
endif()
include_directories(${_KRB5_INCLUDE_DIR})
elseif(KRB5_FLAVOUR STREQUAL "Heimdal")
add_definitions("-DWITH_KRB5 -DWITH_KRB5_HEIMDAL")
include_directories(${_KRB5_INCLUDE_DIR})
else()
message(WARNING "Kerberos version not detected")
endif()
endif()
include(CMakeDependentOption)
CMAKE_DEPENDENT_OPTION(WITH_KRB5_NO_NTLM_FALLBACK "Do not fall back to NTLM if no kerberos ticket available" OFF "WITH_KRB5" OFF)
if (WITH_KRB5_NO_NTLM_FALLBACK)
add_definitions("-DWITH_KRB5_NO_NTLM_FALLBACK")
endif()
endif()
# This option MUST be off to avoid symbol conflicts when loading an external SSPI module library
option(SSPI_DLL "Define and export SSPI API symbols for usage as a Windows SSPI DLL replacement" OFF)

View File

@ -32,13 +32,6 @@ set(${MODULE_PREFIX}_KERBEROS_SRCS
Kerberos/kerberos.c
Kerberos/kerberos.h)
if(KRB5_FOUND)
list(APPEND ${MODULE_PREFIX}_KERBEROS_SRCS
Kerberos/krb5glue_mit.c
Kerberos/krb5glue_heimdal.c
Kerberos/krb5glue.h)
endif()
set(${MODULE_PREFIX}_NEGOTIATE_SRCS
Negotiate/negotiate.c
Negotiate/negotiate.h)
@ -62,6 +55,45 @@ set(${MODULE_PREFIX}_SRCS
sspi.c
sspi.h)
set(KRB5_DEFAULT OFF)
if (NOT WIN32 AND NOT ANDROID AND NOT IOS AND NOT APPLE)
set(KRB5_DEFAULT ON)
endif()
option(WITH_KRB5 "Compile support for kerberos authentication." ${KRB5_DEFAULT})
if (WITH_KRB5)
find_package(KRB5 REQUIRED)
list(APPEND ${MODULE_PREFIX}_KERBEROS_SRCS
Kerberos/krb5glue_mit.c
Kerberos/krb5glue_heimdal.c
Kerberos/krb5glue.h)
winpr_include_directory_add(${KRB5_INCLUDEDIR})
winpr_include_directory_add(${KRB5_INCLUDE_DIRS})
winpr_library_add_private(${KRB5_LIBRARIES})
winpr_library_add_private(${KRB5_LIBRARY})
winpr_library_add_compile_options(${KRB5_CFLAGS})
winpr_library_add_link_options(${KRB5_LDFLAGS})
winpr_library_add_link_directory(${KRB5_LIBRARY_DIRS})
winpr_definition_add("-DWITH_KRB5")
if(KRB5_FLAVOUR STREQUAL "MIT")
winpr_definition_add("-DWITH_KRB5_MIT")
elseif(KRB5_FLAVOUR STREQUAL "Heimdal")
winpr_definition_add("-DWITH_KRB5_HEIMDAL")
else()
message(WARNING "Kerberos version not detected")
endif()
include(CMakeDependentOption)
CMAKE_DEPENDENT_OPTION(WITH_KRB5_NO_NTLM_FALLBACK "Do not fall back to NTLM if no kerberos ticket available" OFF "WITH_KRB5" OFF)
if (WITH_KRB5_NO_NTLM_FALLBACK)
add_definitions("-DWITH_KRB5_NO_NTLM_FALLBACK")
endif()
endif()
winpr_module_add(${${MODULE_PREFIX}_CREDSSP_SRCS}
${${MODULE_PREFIX}_NTLM_SRCS}
${${MODULE_PREFIX}_KERBEROS_SRCS}
@ -79,11 +111,6 @@ if(MBEDTLS_FOUND)
winpr_library_add_private(${MBEDTLS_LIBRARIES})
endif()
if(KRB5_FOUND)
winpr_include_directory_add(${KRB5_INCLUDE_DIR})
winpr_library_add_private(${KRB5_LIBRARIES})
endif()
if(WIN32)
winpr_library_add_public(ws2_32)
endif()

View File

@ -41,13 +41,14 @@
#include <winpr/path.h>
#include "kerberos.h"
#include "krb5glue.h"
#ifdef WITH_KRB5_MIT
#include "krb5glue.h"
#include <profile.h>
#endif
#ifdef WITH_KRB5_HEIMDAL
#include "krb5glue.h"
#include <krb5-protos.h>
#endif

View File

@ -27,12 +27,6 @@
#include "../sspi.h"
#include "../../log.h"
#ifdef WITH_KRB5_MIT
#include <krb5/krb5.h>
#elif defined(WITH_KRB5_HEIMDAL)
#include <krb5.h>
#endif
typedef struct s_KRB_CONTEXT KRB_CONTEXT;
extern const SecPkgInfoA KERBEROS_SecPkgInfoA;

View File

@ -20,13 +20,12 @@
#ifndef WINPR_SSPI_KERBEROS_GLUE_PRIVATE_H
#define WINPR_SSPI_KERBEROS_GLUE_PRIVATE_H
#ifdef WITH_KRB5
#include <winpr/winpr.h>
#include <winpr/sspi.h>
#ifdef WITH_KRB5_MIT
#include <krb5/krb5.h>
#include <krb5.h>
#if defined(WITH_KRB5_MIT)
typedef krb5_key krb5glue_key;
typedef krb5_authenticator* krb5glue_authenticator;
@ -54,8 +53,7 @@ krb5_prompt_type krb5glue_get_prompt_type(krb5_context ctx, krb5_prompt prompts[
#define krb5glue_creds_getkey(creds) creds.keyblock
#else
#include <krb5.h>
#elif defined(WITH_KRB5_HEIMDAL)
typedef krb5_crypto krb5glue_key;
typedef krb5_authenticator krb5glue_authenticator;
@ -82,7 +80,8 @@ krb5_error_code krb5glue_verify_checksum_iov(krb5_context ctx, krb5glue_key key,
#define krb5glue_get_prompt_type(ctx, prompts, index) prompts[index].type
#define krb5glue_creds_getkey(creds) creds.session
#else
#error "Missing implementation for KRB5 provider"
#endif
struct krb5glue_keyset
@ -102,6 +101,4 @@ krb5_error_code krb5glue_get_init_creds(krb5_context ctx, krb5_principal princ,
krb5_prompter_fct prompter, char* password,
SEC_WINPR_KERBEROS_SETTINGS* krb_settings);
#endif /* WITH_KRB5 */
#endif /* WINPR_SSPI_KERBEROS_GLUE_PRIVATE_H */

View File

@ -198,9 +198,7 @@ krb5_error_code krb5glue_get_init_creds(krb5_context ctx, krb5_principal princ,
cleanup:
krb5_init_creds_free(ctx, creds_ctx);
#ifdef WINPR_HAVE_AT_LEAST_KRB_V1_13
krb5_get_init_creds_opt_free(ctx, gic_opt);
#endif
winpr_DeleteFile(tmp_profile_path);
free(tmp_profile_path);

View File

@ -26,7 +26,7 @@
#include <winpr/asn1.h>
#ifdef WITH_KRB5_MIT
#include <krb5/krb5.h>
#include <krb5.h>
typedef krb5_data sspi_gss_data;
#elif defined(WITH_KRB5_HEIMDAL)
#include <krb5.h>