Skip to content

Commit

Permalink
Use GSS.framework on Mac OS X
Browse files Browse the repository at this point in the history
On Mac OS X, Apple wants us to use the GSS.framework to compile
against GSSAPI, instead of <gssapi/gssapi.h>. With this change we can
choose headers to link against at compile time, without changing our
source and header files.
  • Loading branch information
sigmaris authored and DirectXMan12 committed Jan 28, 2015
1 parent 416d20c commit d3b83e8
Show file tree
Hide file tree
Showing 19 changed files with 59 additions and 39 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Expand Up @@ -2,3 +2,4 @@ include *.txt
recursive-include docs *.txt
recursive-include gssapi *.pxd
recursive-include gssapi *.c
recursive-include gssapi *.h
2 changes: 1 addition & 1 deletion gssapi/raw/creds.pyx
Expand Up @@ -13,7 +13,7 @@ from gssapi.raw.named_tuples import AcquireCredResult, AddCredResult
from gssapi.raw.named_tuples import InquireCredResult, InquireCredByMechResult


cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
OM_uint32 gss_acquire_cred(OM_uint32 *min_stat,
const gss_name_t name,
OM_uint32 ttl,
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/cython_types.pxd
@@ -1,7 +1,7 @@
from libc.stdint cimport uint32_t


cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
# basic types
ctypedef uint32_t OM_uint32

Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/exceptions.pyx
Expand Up @@ -5,7 +5,7 @@ from gssapi.raw.misc import GSSError
"""Specific exceptions for GSSAPI errors"""


cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
# calling errors
OM_uint32 GSS_S_CALL_INACCESSIBLE_READ
OM_uint32 GSS_S_CALL_INACCESSIBLE_WRITE
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/ext_cred_imp_exp.pyx
Expand Up @@ -12,7 +12,7 @@ from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import AcquireCredResult, AddCredResult


cdef extern from "gssapi/gssapi_ext.h":
cdef extern from "python_gssapi_ext.h":
OM_uint32 gss_export_cred(OM_uint32 *min_stat, gss_cred_id_t cred_handle,
gss_buffer_t token) nogil

Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/ext_cred_store.pyx
Expand Up @@ -18,7 +18,7 @@ from gssapi.raw.named_tuples import StoreCredResult
from gssapi.raw.misc import GSSError


cdef extern from "gssapi/gssapi_ext.h":
cdef extern from "python_gssapi_ext.h":
ctypedef struct gss_key_value_element_desc:
const char *key
const char *value
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/ext_password.pyx
Expand Up @@ -15,7 +15,7 @@ from gssapi.raw.names cimport Name
from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import AcquireCredResult

cdef extern from "gssapi/gssapi_ext.h":
cdef extern from "python_gssapi_ext.h":
OM_uint32 gss_acquire_cred_with_password(OM_uint32 *min_stat,
const gss_name_t desired_name,
const gss_buffer_t password,
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/ext_password_add.pyx
Expand Up @@ -16,7 +16,7 @@ from gssapi.raw.oids cimport OID
from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import AddCredResult

cdef extern from "gssapi/gssapi_ext.h":
cdef extern from "python_gssapi_ext.h":
OM_uint32 gss_add_cred_with_password(OM_uint32 *min_stat,
const gss_cred_id_t input_cred_handle,
const gss_name_t desired_name,
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/ext_rfc5588.pyx
Expand Up @@ -11,7 +11,7 @@ from gssapi.raw.cython_converters cimport c_c_ttl_to_py, c_py_ttl_to_c
from gssapi.raw.named_tuples import StoreCredResult
from gssapi.raw.misc import GSSError

cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
OM_uint32 gss_store_cred(OM_uint32 *min_stat,
gss_cred_id_t input_creds,
gss_cred_usage_t cred_usage,
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/ext_s4u.pyx
Expand Up @@ -12,7 +12,7 @@ from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import AcquireCredResult, AddCredResult


cdef extern from "gssapi/gssapi_ext.h":
cdef extern from "python_gssapi_ext.h":
OM_uint32 gss_acquire_cred_impersonate_name(OM_uint32 *min_stat,
const gss_cred_id_t imp_creds,
const gss_name_t name,
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/mech_krb5.pyx
Expand Up @@ -13,7 +13,7 @@ and MechType.
"""


cdef extern from "gssapi/gssapi_krb5.h":
cdef extern from "python_gssapi_krb5.h":
gss_OID gss_mech_krb5
gss_OID GSS_KRB5_NT_PRINCIPAL_NAME

Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/message.pyx
Expand Up @@ -7,7 +7,7 @@ from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import VerifyMICResult, WrapResult, UnwrapResult


cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
OM_uint32 gss_get_mic(OM_uint32 *min_stat,
const gss_ctx_id_t context,
gss_qop_t qop,
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/misc.pyx
Expand Up @@ -12,7 +12,7 @@ from gssapi.raw.oids cimport OID
from gssapi.raw.types import MechType


cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
OM_uint32 gss_display_status(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
Expand Down
2 changes: 1 addition & 1 deletion gssapi/raw/names.pyx
Expand Up @@ -7,7 +7,7 @@ from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import DisplayNameResult


cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
OM_uint32 gss_import_name(OM_uint32 *min_stat,
const gss_buffer_t input_buffer,
const gss_OID name_type,
Expand Down
5 changes: 5 additions & 0 deletions gssapi/raw/python_gssapi.h
@@ -0,0 +1,5 @@
#ifdef OSX_HAS_GSS_FRAMEWORK
#include <GSS/GSS.h>
#else
#include <gssapi/gssapi.h>
#endif
9 changes: 9 additions & 0 deletions gssapi/raw/python_gssapi_ext.h
@@ -0,0 +1,9 @@
#ifdef OSX_HAS_GSS_FRAMEWORK
#include <GSS/GSS.h>
#else
#ifdef HAS_GSSAPI_EXT_H
#include <gssapi/gssapi_ext.h>
#else
#include <gssapi/gssapi.h>
#endif
#endif
5 changes: 5 additions & 0 deletions gssapi/raw/python_gssapi_krb5.h
@@ -0,0 +1,5 @@
#ifdef OSX_HAS_GSS_FRAMEWORK
#include <GSS/gssapi_krb5.h>
#else
#include <gssapi/gssapi_krb5.h>
#endif
2 changes: 1 addition & 1 deletion gssapi/raw/sec_contexts.pyx
Expand Up @@ -16,7 +16,7 @@ from gssapi.raw.named_tuples import InitSecContextResult
from gssapi.raw.named_tuples import InquireContextResult


cdef extern from "gssapi.h":
cdef extern from "python_gssapi.h":
OM_uint32 gss_init_sec_context(OM_uint32 *min_stat,
const gss_cred_id_t initiator_creds,
gss_ctx_id_t *context,
Expand Down
50 changes: 25 additions & 25 deletions setup.py
Expand Up @@ -5,6 +5,7 @@
from setuptools.command.build_ext import build_ext
from setuptools.command.sdist import sdist
from setuptools.extension import Extension
import platform
import re
import sys
import os
Expand All @@ -21,7 +22,7 @@
print("Building from Cython files...", file=sys.stderr)
SOURCE_EXT = 'pyx'
except ImportError:
print("Cython not found, building from Cython files...",
print("Cython not found, building from C files...",
file=sys.stderr)
SOURCE_EXT = 'c'

Expand All @@ -43,12 +44,22 @@ def _get_output(*args, **kwargs):
# get the compile and link args
link_args = os.environ.get('GSSAPI_LINKER_ARGS', None)
compile_args = os.environ.get('GSSAPI_COMPILER_ARGS', None)
osx_has_gss_framework = False
if sys.platform == 'darwin':
mac_ver = [int(v) for v in platform.mac_ver()[0].split('.')]
osx_has_gss_framework = (mac_ver >= [10, 7, 0])

if link_args is None:
link_args = get_output('krb5-config --libs gssapi')
if osx_has_gss_framework:
link_args = '-framework GSS'
else:
link_args = get_output('krb5-config --libs gssapi')

if compile_args is None:
compile_args = get_output('krb5-config --cflags gssapi')
if osx_has_gss_framework:
compile_args = '-framework GSS -DOSX_HAS_GSS_FRAMEWORK'
else:
compile_args = get_output('krb5-config --cflags gssapi')

link_args = link_args.split()
compile_args = compile_args.split()
Expand All @@ -57,42 +68,31 @@ def _get_output(*args, **kwargs):
(os.environ.get('GSSAPI_SUPPORT_DETECT', 'true').lower() == 'true')

if ENABLE_SUPPORT_DETECTION:
import ctypes.util

main_lib = os.environ.get('GSSAPI_MAIN_LIB', None)
if main_lib is None:
if main_lib is None and osx_has_gss_framework:
main_lib = ctypes.util.find_library('GSS')
elif main_lib is None:
for opt in link_args:
if opt.startswith('-lgssapi'):
main_lib = 'lib%s.so' % opt[2:]

if main_lib is None:
raise Exception("Could not find main GSSAPI shared libary. Please "
raise Exception("Could not find main GSSAPI shared library. Please "
"try setting GSSAPI_MAIN_LIB yourself or setting "
"ENABLE_SUPPORT_DETECTION to 'false'")

import ctypes
GSSAPI_LIB = ctypes.CDLL(main_lib)


class build_gssapi_ext(build_ext):
def run(self):
if not self.dry_run:
# optionally fake gssapi_ext.h using gssapi.h
prefix = get_output('krb5-config gssapi --prefix')
gssapi_ext_h = os.path.join(prefix, 'include/gssapi/gssapi_ext.h')

if not os.path.exists(gssapi_ext_h):
target_dir = os.path.join(self.build_temp, 'c_include')
gssapi_dir = os.path.join(target_dir, 'gssapi')
if not os.path.exists(gssapi_dir):
os.makedirs(gssapi_dir)

target_file = os.path.join(target_dir, 'gssapi/gssapi_ext.h')
if not os.path.exists(target_file):
with open(target_file, 'w') as header:
header.write('#include "gssapi.h"')

for ext in self.extensions:
ext.extra_compile_args.append("-I%s" %
os.path.abspath(target_dir))
prefix = get_output('krb5-config gssapi --prefix')
gssapi_ext_h = os.path.join(prefix, 'include/gssapi/gssapi_ext.h')
if os.path.exists(gssapi_ext_h):
for ext in self.extensions:
ext.extra_compile_args.append("-DHAS_GSSAPI_EXT_H")

build_ext.run(self)

Expand Down

5 comments on commit d3b83e8

@c4milo
Copy link

@c4milo c4milo commented on d3b83e8 Dec 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sigmaris, do you know how we can enable credential store manipulation in GSS.Framework? I'm getting this error in MacOS:

File "/usr/local/lib/python3.6/site-packages/gssapi/creds.py", line 140, in acquire
raise NotImplementedError("Your GSSAPI implementation does "
NotImplementedError: Your GSSAPI implementation does not have support for manipulating credential stores

@sigmaris
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@c4milo The MacOS implementation of GSSAPI doesn't support the credential store extensions, so it's not possible to use them on MacOS. I suggest filing a bug with Apple to request this functionality: https://bugreport.apple.com/

@c4milo
Copy link

@c4milo c4milo commented on d3b83e8 Jan 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sigmaris, I haven't been able to find anything on the internet. Have you ever replaced MacOS kerberos implementation with MIT's or Heimdal's? I'm not too concern about security, I just need to smooth out my development workflow.

@c4milo
Copy link

@c4milo c4milo commented on d3b83e8 Jan 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or a better question perhaps, how can I recompile python-gssapi, so that it uses Heimdal's or MIT's headers instead?

@frozencemetery
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't speak to better or worse, and don't have MacOS system to test this on. However, we do support non-default installation prefixes in our setup scripts. This uses the environment variables $GSSAPI_LINKER_ARGS and $GSSAPI_COMPILER_ARGS. (Otherwise we fall back to -framework GSS on OSX.) You'll also want the first krb5-config in $PATH to be the one from your custom installation. Finally, $GSSAPI_MAIN_LIB then needs to be set to the path to the .so for libgssapi.

We should probably document this in our README.

Please sign in to comment.