• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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