1#*************************************************************************** 2# _ _ ____ _ 3# Project ___| | | | _ \| | 4# / __| | | | |_) | | 5# | (__| |_| | _ <| |___ 6# \___|\___/|_| \_\_____| 7# 8# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9# 10# This software is licensed as described in the file COPYING, which 11# you should have received as part of this distribution. The terms 12# are also available at https://curl.se/docs/copyright.html. 13# 14# You may opt to use, copy, modify, merge, publish, distribute and/or sell 15# copies of the Software, and permit persons to whom the Software is 16# furnished to do so, under the terms of the COPYING file. 17# 18# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19# KIND, either express or implied. 20# 21# SPDX-License-Identifier: curl 22# 23########################################################################### 24# - Try to find the GSS Kerberos library 25# Once done this will define 26# 27# GSS_ROOT_DIR - Set this variable to the root installation of GSS 28# 29# Read-Only variables: 30# GSS_FOUND - system has the Heimdal library 31# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found. 32# GSS_INCLUDE_DIR - the Heimdal include directory 33# GSS_LIBRARIES - The libraries needed to use GSS 34# GSS_LINK_DIRECTORIES - Directories to add to linker search path 35# GSS_LINKER_FLAGS - Additional linker flags 36# GSS_COMPILER_FLAGS - Additional compiler flags 37# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest. 38# In case the library is found but no version info available it'll be set to "unknown" 39 40set(_MIT_MODNAME mit-krb5-gssapi) 41set(_HEIMDAL_MODNAME heimdal-gssapi) 42 43include(CheckIncludeFile) 44include(CheckIncludeFiles) 45include(CheckTypeSize) 46 47set(_GSS_ROOT_HINTS 48 "${GSS_ROOT_DIR}" 49 "$ENV{GSS_ROOT_DIR}" 50) 51 52# try to find library using system pkg-config if user didn't specify root dir 53if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}") 54 if(UNIX) 55 find_package(PkgConfig QUIET) 56 pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME}) 57 list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}") 58 elseif(WIN32) 59 list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]") 60 endif() 61endif() 62 63if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach. 64 find_file(_GSS_CONFIGURE_SCRIPT 65 NAMES 66 "krb5-config" 67 HINTS 68 ${_GSS_ROOT_HINTS} 69 PATH_SUFFIXES 70 bin 71 NO_CMAKE_PATH 72 NO_CMAKE_ENVIRONMENT_PATH 73 ) 74 75 # if not found in user-supplied directories, maybe system knows better 76 find_file(_GSS_CONFIGURE_SCRIPT 77 NAMES 78 "krb5-config" 79 PATH_SUFFIXES 80 bin 81 ) 82 83 if(_GSS_CONFIGURE_SCRIPT) 84 execute_process( 85 COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi" 86 OUTPUT_VARIABLE _GSS_CFLAGS 87 RESULT_VARIABLE _GSS_CONFIGURE_FAILED 88 OUTPUT_STRIP_TRAILING_WHITESPACE 89 ) 90 message(STATUS "CFLAGS: ${_GSS_CFLAGS}") 91 if(NOT _GSS_CONFIGURE_FAILED) # 0 means success 92 # should also work in an odd case when multiple directories are given 93 string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS) 94 string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}") 95 string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}") 96 97 foreach(_flag ${_GSS_CFLAGS}) 98 if(_flag MATCHES "^-I.*") 99 string(REGEX REPLACE "^-I" "" _val "${_flag}") 100 list(APPEND _GSS_INCLUDE_DIR "${_val}") 101 else() 102 list(APPEND _GSS_COMPILER_FLAGS "${_flag}") 103 endif() 104 endforeach() 105 endif() 106 107 execute_process( 108 COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi" 109 OUTPUT_VARIABLE _GSS_LIB_FLAGS 110 RESULT_VARIABLE _GSS_CONFIGURE_FAILED 111 OUTPUT_STRIP_TRAILING_WHITESPACE 112 ) 113 message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}") 114 115 if(NOT _GSS_CONFIGURE_FAILED) # 0 means success 116 # this script gives us libraries and link directories. Blah. We have to deal with it. 117 string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS) 118 string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}") 119 string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}") 120 121 foreach(_flag ${_GSS_LIB_FLAGS}) 122 if(_flag MATCHES "^-l.*") 123 string(REGEX REPLACE "^-l" "" _val "${_flag}") 124 list(APPEND _GSS_LIBRARIES "${_val}") 125 elseif(_flag MATCHES "^-L.*") 126 string(REGEX REPLACE "^-L" "" _val "${_flag}") 127 list(APPEND _GSS_LINK_DIRECTORIES "${_val}") 128 else() 129 list(APPEND _GSS_LINKER_FLAGS "${_flag}") 130 endif() 131 endforeach() 132 endif() 133 134 execute_process( 135 COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version" 136 OUTPUT_VARIABLE _GSS_VERSION 137 RESULT_VARIABLE _GSS_CONFIGURE_FAILED 138 OUTPUT_STRIP_TRAILING_WHITESPACE 139 ) 140 141 # older versions may not have the "--version" parameter. In this case we just don't care. 142 if(_GSS_CONFIGURE_FAILED) 143 set(_GSS_VERSION 0) 144 endif() 145 146 execute_process( 147 COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor" 148 OUTPUT_VARIABLE _GSS_VENDOR 149 RESULT_VARIABLE _GSS_CONFIGURE_FAILED 150 OUTPUT_STRIP_TRAILING_WHITESPACE 151 ) 152 153 # older versions may not have the "--vendor" parameter. In this case we just don't care. 154 if(_GSS_CONFIGURE_FAILED) 155 set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter 156 else() 157 if(_GSS_VENDOR MATCHES ".*H|heimdal.*") 158 set(GSS_FLAVOUR "Heimdal") 159 else() 160 set(GSS_FLAVOUR "MIT") 161 endif() 162 endif() 163 164 else() # either there is no config script or we are on a platform that doesn't provide one (Windows?) 165 166 find_path(_GSS_INCLUDE_DIR 167 NAMES 168 "gssapi/gssapi.h" 169 HINTS 170 ${_GSS_ROOT_HINTS} 171 PATH_SUFFIXES 172 include 173 inc 174 ) 175 176 if(_GSS_INCLUDE_DIR) #jay, we've found something 177 set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}") 178 check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS) 179 180 if(_GSS_HAVE_MIT_HEADERS) 181 set(GSS_FLAVOUR "MIT") 182 else() 183 # prevent compiling the header - just check if we can include it 184 list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__) 185 check_include_file( "roken.h" _GSS_HAVE_ROKEN_H) 186 187 check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H) 188 if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H) 189 set(GSS_FLAVOUR "Heimdal") 190 endif() 191 list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__) 192 endif() 193 else() 194 # I'm not convinced if this is the right way but this is what autotools do at the moment 195 find_path(_GSS_INCLUDE_DIR 196 NAMES 197 "gssapi.h" 198 HINTS 199 ${_GSS_ROOT_HINTS} 200 PATH_SUFFIXES 201 include 202 inc 203 ) 204 205 if(_GSS_INCLUDE_DIR) 206 set(GSS_FLAVOUR "Heimdal") 207 endif() 208 endif() 209 210 # if we have headers, check if we can link libraries 211 if(GSS_FLAVOUR) 212 set(_GSS_LIBDIR_SUFFIXES "") 213 set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS}) 214 get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH) 215 list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT}) 216 217 if(WIN32) 218 if(CMAKE_SIZEOF_VOID_P EQUAL 8) 219 list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64") 220 if(GSS_FLAVOUR STREQUAL "MIT") 221 set(_GSS_LIBNAME "gssapi64") 222 else() 223 set(_GSS_LIBNAME "libgssapi") 224 endif() 225 else() 226 list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386") 227 if(GSS_FLAVOUR STREQUAL "MIT") 228 set(_GSS_LIBNAME "gssapi32") 229 else() 230 set(_GSS_LIBNAME "libgssapi") 231 endif() 232 endif() 233 else() 234 list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS 235 if(GSS_FLAVOUR STREQUAL "MIT") 236 set(_GSS_LIBNAME "gssapi_krb5") 237 else() 238 set(_GSS_LIBNAME "gssapi") 239 endif() 240 endif() 241 242 find_library(_GSS_LIBRARIES 243 NAMES 244 ${_GSS_LIBNAME} 245 HINTS 246 ${_GSS_LIBDIR_HINTS} 247 PATH_SUFFIXES 248 ${_GSS_LIBDIR_SUFFIXES} 249 ) 250 251 endif() 252 endif() 253else() 254 if(_GSS_PKG_${_MIT_MODNAME}_VERSION) 255 set(GSS_FLAVOUR "MIT") 256 set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION) 257 else() 258 set(GSS_FLAVOUR "Heimdal") 259 set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION) 260 endif() 261endif() 262 263set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR}) 264set(GSS_LIBRARIES ${_GSS_LIBRARIES}) 265set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES}) 266set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS}) 267set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS}) 268set(GSS_VERSION ${_GSS_VERSION}) 269 270if(GSS_FLAVOUR) 271 if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal") 272 if(CMAKE_SIZEOF_VOID_P EQUAL 8) 273 set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest") 274 else() 275 set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest") 276 endif() 277 278 if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}") 279 file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str 280 REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$") 281 282 string(REGEX MATCH "[0-9]\\.[^\"]+" 283 GSS_VERSION "${heimdal_version_str}") 284 endif() 285 286 if(NOT GSS_VERSION) 287 set(GSS_VERSION "Heimdal Unknown") 288 endif() 289 elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT") 290 get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE) 291 if(WIN32 AND _MIT_VERSION) 292 set(GSS_VERSION "${_MIT_VERSION}") 293 else() 294 set(GSS_VERSION "MIT Unknown") 295 endif() 296 endif() 297endif() 298 299include(FindPackageHandleStandardArgs) 300 301set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR) 302 303find_package_handle_standard_args(GSS 304 REQUIRED_VARS 305 ${_GSS_REQUIRED_VARS} 306 VERSION_VAR 307 GSS_VERSION 308 FAIL_MESSAGE 309 "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR" 310) 311 312mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES) 313