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