pythongssapi / python-gssapi

A Python interface to RFC 2743/2744 (plus common extensions)
ISC License
104 stars 46 forks source link

cred_store extension not supported on macOS #347

Closed ronf closed 2 months ago

ronf commented 2 months ago

What went wrong?

I'm trying to use python-gssapi on macOS 14.6 and trying to take advantage of the cred store extension. However, when I build python-gssapi, I get back:

Skipping the cred_store extension because it is not supported by your GSSAPI implementation...

How do we reproduce?

Create a gssapi.Credentials object with the 'store' argument, such as:

creds = gssapi.Credentials(usage="initiate", store={"ccache": "MEMORY:username"})

(Remember to use fenced code blocks and consider placing in a gist if large)

Component versions (python-gssapi, Kerberos, OS / distro, etc.)

MIT Kerberos 5 version 1.21.3, from MacPorts 2.10.1 python-gssapi 1.8.3 from PyPI running on Python 3.12.5

I also tried getting the latest python-gssapi from Git (1.8.4) and installing that, but I ran into the same result.

The problem seems to be in the "support detection" in setup.py, but from what I can tell the version of Kerberos I have installed does have the symbol (gss_store_cred_into) that setup.py is looking for:

nm -gU /opt/local/lib/libgssapi_krb5.dylib | grep store_cred
0000000000011594 T _gss_store_cred
00000000000115c0 T _gss_store_cred_into

I think it might be finding the wrong library -- when I printed what it found, it reported:

/System/Library/Frameworks/GSS.framework/GSS

However, on my system that's a broken symlink to /System/Library/Frameworks/GSS.framework/Versions/Current/GSS, which points at /System/Library/Frameworks/GSS.framework/Versions/A/GSS, which doesn't seem to exist:

ls -l /System/Library/Frameworks/GSS.framework/Versions/A/
total 0
drwxr-xr-x  7 root  wheel  224 Aug  4 03:31 Resources/
drwxr-xr-x  3 root  wheel   96 Aug  4 03:31 _CodeSignature/

I then tried setting GSSAPI_MAIN_LIB=/opt/local/lib/libgssapi_krb5.dylib and running "setup.py build" rather than building with pip, but for this to work I needed to comment out a bit of setup.py:

diff --git a/setup.py b/setup.py
index a71967f..39779df 100755
--- a/setup.py
+++ b/setup.py
@@ -45,9 +45,9 @@ link_args, compile_args = [
 ]

 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 sys.platform == 'darwin':
+#    mac_ver = [int(v) for v in platform.mac_ver()[0].split('.')]
+#    osx_has_gss_framework = (mac_ver >= [10, 7, 0])

 winkrb_path = None
 if os.name == 'nt':

This basically made sure the osx_has_gss_framework remained false, and avoided code later which tried to point at the OS X framework.

With the above change and specifying the path the library manually via GSSAPI_MAIN_LIB, I was able to get the credential store extension to build, and was able to use it successfully.

jborean93 commented 2 months ago

The default behaviour on macOS is to favour the GSS Framework which is Apple's fork of Heimdal that ships with the OS. It's an OS provided lib which is why some of those paths don't actually exist but Apple's loader is able to handle them properly. There are a few hardcoded things in setup.py to make this work by default but if you are using another GSSAPI library on macOS then you'll need to set these env vars (krb5-config will need to be your MIT krb5 version not the one provided by GSS Framework).

You've probably noticed already but we do ship a wheel for macOS, so if you are installing from pip you'll have to favour the sdist and build it locally.

ronf commented 2 months ago

Thanks very much for getting back to me!

After setting all three of the environment variables as described above, I was able to get the latest gssapi code to install on macOS using the Kerberos 5 library from MacPorts without any changes to setup.py. The version I built this way supports the cred-store extension I was looking to use.

You've probably noticed already but we do ship a wheel for macOS, so if you are installing from pip you'll have to favour the sdist and build it locally.

Yeah - I originally tried installing from pip directly from PyPI, but that appears to be using Apple's version of gssapi, which doesn't support the cred-store extension I needed.

jborean93 commented 2 months ago

I do see a bug in that the wrap_iov calls will not be present, I'll try and submit a PR to fix that soon.