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

Support collection credential caches #15

Closed
grawity opened this issue Sep 7, 2021 · 6 comments · Fixed by #16
Closed

Support collection credential caches #15

grawity opened this issue Sep 7, 2021 · 6 comments · Fixed by #16

Comments

@grawity
Copy link

grawity commented Sep 7, 2021

In MIT Kerberos (and probably also Heimdal), the DIR: and KCM: credential cache types support multiple sets of credentials, e.g. TGTs and tickets for completely disjoint realms. When GSSAPI isn't given any specific credentials it'll choose the correct ones based on the server principal (either by matching the realm, or by custom rules in ~/.k5identity).

However, when spnego/gss.py in _get_gssapi_credential() explicitly retrieves the credentials, it always gets those from the "primary" cache in the collection (chosen using kswitch, but by default it's the last one that was kinit'd). This makes it difficult to authenticate against servers in non-primary realms, unless I manually kswitch to the correct principal – which rather defeats the point of using "collection" types. (I wanted to migrate from my kc script that switches between several file-based caches...)

It seems that everything works as expected if I patch _get_gssapi_credential() to simply return None when the mechanism is Kerberos, the usage is "initiate", and the username/password aren't provided. I believe the module should do that and not try to pass explicit credentials if the user isn't specifying any.

Rough steps for using collection caches:

export KRB5CCNAME=DIR:/run/user/1000/krb5cc
kinit user.one@REALM.ONE
kinit user.two@REALM.TWO
klist -A  # expect two caches and two TGTs to be listed
kswitch -p user.two@REALM.TWO
python -c "import gssapi; print(gssapi.Credentials(usage='initiate').name)"
python -c "import smbclient; smbclient.listdir(r'\\dc01.realm.one\netlogon')" # Will fail
@jborean93
Copy link
Owner

Ahh I see, gss_init_sec_context with an empty credential will take into account the realm when selecting the ticket to use whereas the logic in _get_gssapi_credential() is just getting the default principal and not taking into account the target SPN. Seems logical to swap the logic for it to return None instead of it getting the default principal.

@grawity
Copy link
Author

grawity commented Sep 7, 2021

Indeed, alhough it does probably make it harder (or impossible) to check for credential expiry upfront.

@jborean93
Copy link
Owner

I don't think that matters as much, the expiry check is mostly a historical thing where the original code checked if the cache was expired and had a fallback to the explicit credentials if passed in. Now it will always favour the explicit credentials so that's no longer relevant and if it's expired it will just fail when attempting the auth anyway.

@jborean93
Copy link
Owner

When you get a chance are you able to test out #16 to verify that it works as you expect?

@grawity
Copy link
Author

grawity commented Sep 14, 2021

Thanks, it seems to be working as expected (tested on top of main).

@jborean93
Copy link
Owner

Thanks for confirming!

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

Successfully merging a pull request may close this issue.

2 participants