Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS build isn't usable #237

Closed
simmel opened this issue Jan 7, 2021 · 19 comments
Closed

macOS build isn't usable #237

simmel opened this issue Jan 7, 2021 · 19 comments

Comments

@simmel
Copy link
Contributor

simmel commented Jan 7, 2021

What went wrong?

Tried to use ldap3 with gssapi and I can't get SASL GSSAPI auth over LDAPS to work.

  • GSSAPI over LDAP works
  • NO AUTH/PLAIN over LDAPS works
  • GSSAPI over LDAPS doesn't work

GSSAPI over LDAPS works on Linux (I tried ArchLinux but should work on any)

How do we reproduce?

$ python3 -m venv ldap3gssapitest
$ cd ldap3gssapitest
$ source bin/activate
$ pip3 install ldap3 gssapi cryptography
$ cat > search.py <<EOF
#!/usr/bin/env python3
from ldap3 import Server, Connection, Tls, SASL, KERBEROS
import ssl
tls = Tls(validate=ssl.CERT_NONE, version=ssl.PROTOCOL_TLSv1_2)
server = Server('yourldapserver', use_ssl=True, tls=tls)
c = Connection(
        server, authentication=SASL, sasl_mechanism=KERBEROS)
c.bind()
print(c.extend.standard.who_am_i())
EOF
$ python3 search.py
dn:uid=simlu,cn=gssapi,cn=auth

That should yield an LDAP dn which should match your Kerberos principal.

With macOS 11.1 I get:

$ python3 search.py
Traceback (most recent call last):
  File "/private/tmp/ldap3gssapitest/search.py", line 8, in <module>
    c.bind()
  File "/private/tmp/ldap3gssapitest/lib/python3.9/site-packages/ldap3/core/connection.py", line 608, in bind
    response = self.do_sasl_bind(controls)
  File "/private/tmp/ldap3gssapitest/lib/python3.9/site-packages/ldap3/core/connection.py", line 1336, in do_sasl_bind
    result = sasl_gssapi(self, controls)
  File "/private/tmp/ldap3gssapitest/lib/python3.9/site-packages/ldap3/protocol/sasl/kerberos.py", line 118, in sasl_gssapi
    out_token = ctx.step(in_token)
  File "<decorator-gen-15>", line 2, in step
  File "/private/tmp/ldap3gssapitest/lib/python3.9/site-packages/gssapi/_utils.py", line 155, in check_last_err
    return func(self, *args, **kwargs)
  File "<decorator-gen-5>", line 2, in step
  File "/private/tmp/ldap3gssapitest/lib/python3.9/site-packages/gssapi/_utils.py", line 128, in catch_and_return_token
    return func(self, *args, **kwargs)
  File "/private/tmp/ldap3gssapitest/lib/python3.9/site-packages/gssapi/sec_contexts.py", line 519, in step
    return self._initiator_step(token=token)
  File "/private/tmp/ldap3gssapitest/lib/python3.9/site-packages/gssapi/sec_contexts.py", line 535, in _initiator_step
    res = rsec_contexts.init_sec_context(self._target_name, self._creds,
  File "gssapi/raw/sec_contexts.pyx", line 245, in gssapi.raw.sec_contexts.init_sec_context
gssapi.raw.exceptions.MalformedParameterError: Major (51183616): A parameter was malformed Miscellaneous failure (see text), Minor (0): Success
$

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

$ pip3 freeze
cffi==1.14.4
cryptography==3.3.1
decorator==4.4.2
gssapi==1.6.12
ldap3==2.8.1
pyasn1==0.4.8
pycparser==2.20
six==1.15.0
$ pacman -Qi krb5 | grep Version
Version         : 1.18.2-1
@simmel
Copy link
Contributor Author

simmel commented Jan 7, 2021

Refer to #235 and I cc-spam: @jborean93 (sorry!)

@frozencemetery
Copy link
Member

Hi @simmel, thanks for the report. Can you clarify what in #235 we should refer to? Everything we're aware of being an issue in that report should be fixed.

@simmel
Copy link
Contributor Author

simmel commented Jan 8, 2021

I meant that macOS +11.* was fixed in #235 but really it was #236.

Since no code was changed maybe it's Kerberos or SSL or possibly the combination that is broken in macOS 11.*?

Since I hit it in Python with ldap3 and gssapi I could easily reproduce it. I'll try something else also like Net::LDAP and GSSAPI. I'll report back!

@jborean93
Copy link
Contributor

The issue mentioned was really just an issue with building the library where the extension detection wasn’t working. Your error comes from calling the C functions and it returning this error. Maybe there is some ABI/data marshalling issue but that’s outside the realms of my expertise. From a basic look at the error I wouldn’t classify this as a problem in gssapi but I could be wrong.

@frozencemetery
Copy link
Member

One idea, maybe - do the versions of every python package you're using match on Arch and MacOS?

If they don't, that points at something; if they do, maybe it's Heimdal-specific or (hopefully not) macOS specific.

@jborean93
Copy link
Contributor

maybe it's Heimdal-specific or (hopefully not) macOS specific

Heh wouldn’t be the first time macOS’ Heimdal implementation has an issue.

@simmel
Copy link
Contributor Author

simmel commented Jan 9, 2021 via email

@jborean93
Copy link
Contributor

Is it possible to use the heimdal from Homebrew somehow?

It looks like it is possible you just need to specify these 3 things manually when installing as well as ensure the krb5-config in Homebrew install is higher in the PATH than the builtin one supplied by Apple

  • The linker args GSSAPI_LINKER_ARGS="$( krb5-config --libs gssapi )"
  • The compiler args GSSAPI_COMPILER_ARGS="$( krb5-config --cflags gssapi )"
  • The path to the main library GSSAPI_MAIN_LIB=path to libgssapi.dylib

This is not tested at all and in the past I've had to manually edit the setup.py file to do this but from what I can see today that may not be required anymore.

@simmel
Copy link
Contributor Author

simmel commented Jan 11, 2021

Well well well, what do you know.. It's broken again = D

$ python3 -m venv ldap3gssapitest
$ cd ldap3gssapitest
$ source bin/activate
$ brew info --json heimdal | jq '.[].versions'
{
  "stable": "7.7.0",
  "head": null,
  "bottle": true
}
$ export PATH=$(brew --prefix heimdal)/bin:$PATH
$ export GSSAPI_LINKER_ARGS="$(krb5-config --libs gssapi)"
$ export GSSAPI_COMPILER_ARGS="$(krb5-config --cflags gssapi)"
$ export GSSAPI_MAIN_LIB=$(brew --prefix heimdal)/lib/libgssapi.dylib
$ pip3 install ldap3 gssapi cryptography
$ otool -L ./lib/python3.9/site-packages/gssapi/raw/mech_krb5.cpython-39-darwin.so
./lib/python3.9/site-packages/gssapi/raw/mech_krb5.cpython-39-darwin.so:
        /usr/local/opt/heimdal/lib/libgssapi.3.dylib (compatibility version 4.0.0, current version 4.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.60.1)
$ cat > search.py <<EOF
#!/usr/bin/env python3
from ldap3 import Server, Connection, Tls, SASL, KERBEROS
import ssl
tls = Tls(validate=ssl.CERT_NONE, version=ssl.PROTOCOL_TLSv1_2)
server = Server('yourldapserver', use_ssl=True, tls=tls)
c = Connection(
        server, authentication=SASL, sasl_mechanism=KERBEROS)
c.bind()
print(c.extend.standard.who_am_i())
EOF
$ python3 search.py
dn:uid=simlu,dc=it,dc=su,dc=se
$

@jborean93
Copy link
Contributor

So if your Heimdal brew version is working then I don’t think the bug exists in python-gssapi but rather the GSS framework that Apple provides. I could still be wrong though but I’m not sure what else it could be.

@jborean93
Copy link
Contributor

Just as an FYI I've tried out your code on macOS Big Sur using the built-in Heimdal implementation. The script was slightly tweaked as my test domain didn't have LDAPS enabled.

#!/usr/bin/env python3

import sys

from ldap3 import Server, Connection, SASL, KERBEROS

server = Server(sys.argv[1], use_ssl=False)
c = Connection(server, authentication=SASL, sasl_mechanism=KERBEROS)
c.bind()

print(c.extend.standard.who_am_i())
$ ./search.py dc01.domain.test
u:DOMAIN\vagrant-domain

It worked without any issues although I'm getting a different format for the user compared to yours. I'm just running this after doing kinit vagrant-domain@DOMAIN.TEST.

@simmel
Copy link
Contributor Author

simmel commented Jan 12, 2021

That's correct. Like I stated in my OP:

With macOS 11.1's builtin Heimdal:

  • GSSAPI over LDAP works ✅
  • NO AUTH/PLAIN over LDAPS works ✅
  • GSSAPI over LDAPS doesn't work ❌

@simmel simmel closed this as completed Jan 12, 2021
@jborean93
Copy link
Contributor

Oh sorry I did not read that initial part. I'll have another check tomorrow after setting up LDAPS on my test domain. I remember having problems with LDAPS and GSSAPI before https://github.com/jborean93/ansible-lookup-laps_password#known-issues but that was with a different LDAP library and way before Big Sur came into the picture.

@simo5
Copy link
Contributor

simo5 commented Jan 12, 2021

That's correct. Like I stated in my OP:

With macOS 11.1's builtin Heimdal:

* GSSAPI over LDAP works white_check_mark

* NO AUTH/PLAIN over LDAPS works white_check_mark

* GSSAPI over LDAPS doesn't work x

What are you testing this against ?
If it is AD it may be because AD now enforces channel bindings when you use GSSAPI on LDAPS

@jborean93
Copy link
Contributor

Just as an FYI I've tried out LDAPS and it works just fine on my box. I've also made sure I've enable LDAP signing and CBT enforcing on AD to see if that's the case.

@simmel
Copy link
Contributor Author

simmel commented Jan 13, 2021 via email

@simmel
Copy link
Contributor Author

simmel commented Jan 13, 2021 via email

@simmel
Copy link
Contributor Author

simmel commented Jan 13, 2021

I've debugged with my co-worker @eest and when we looked at the decrypted LDAP communication we found that the LDAP bindRequest -> SASL -> GSSAPI -> Kerberos -> authenticator size is the same (242 bytes) when using Homebrew Heimdal no matter if SSL or plain is used. But with macOS 11 Heimdal the size of the authenticator value differs (it's 461 bytes when it fails with SSL and it's 421 bytes when it works with plain).

Also maybe worth noting, when using macOS 11 Heimdal and using plain, in the AP-REQs AP-options the reserved field is set to True. There is no documentation what this field does (well, it's reserved) and @eest looked in Heimdals code but couldn't see that it was used or at least changed in the recent years (right @eest?).

kaka:~$ /usr/bin/kinit --version 2>&1 | head -n1
kinit (Heimdal 1.5.1apple1)
kaka:~$ /usr/local/opt/heimdal/bin/kinit --version 2>&1 | head -n1
kinit (Heimdal 7.7.0)
kaka:~$

1.5.1 is from 2011 but apple has probably added patches. I can't remember what version of Heimdal 10.14 (which I used before) had.

I can send you the .pcap off Github if you want. Well not the .pcap because that would require you to have our RSA key to decrypt it but I see that Wireshark can export to JSON.

@simmel
Copy link
Contributor Author

simmel commented Jan 13, 2021

Possibly it's lib/krb5/build_auth.c that populates authticator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants