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

Proof of concept for SASL GSSAPI Client Authentication #50

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

schlenk
Copy link

@schlenk schlenk commented Feb 4, 2016

A proof of concept SASL / GSSAPI client authentication for ldaptor.

At the moment it is just ldaptor-search upgraded to do SASL-GSSAPI when asked to.

If you are in a Windows Domain with a domain user, you can use it as is, if you have kerberos_sspi installed.

python ldaptor-search --bind-sasl-mech GSSAPI 
   --service-location="CN=Users,DC=example,DC=com:dc.example.com" 
   --base "CN=Users,DC=example,DC=com" "(objectClass=*)" "cn"

Its not yet done or fully integrated (or doc'ed), but i wanted some feedback before going further, to not waste too much work.

I have a few questions about going forward with it:

  1. How to handle the optional dependencies to https://pypi.python.org/pypi/kerberos or (Windows) https://pypi.python.org/pypi/kerberos-sspi ?
  2. API thoughts on entry.bind() with SASL.
    The currently existing API is a bit clumsy when needing more than a single roundtrip. So i added a
    sasl_ctx parameter that does the repeated bind requests directly. Any different plans on how this
    should work?
  3. Should this be in ldaptor at all, or should it be external in some way?
  4. How about other SASL mechanisms?
  5. What other stuff (docs, tests, etc.) would be needed to land this?

This does too much still, due to bugs in pykerberos/kerberos_sspi (see may-day/kerberos-sspi#3 ).

@psi29a
Copy link
Contributor

psi29a commented Jun 7, 2016

Can you do a rebase against master?

@cwaldbieser
Copy link
Collaborator

I'm thinking it might be useful to use the Twisted plugin system[1] to add available authentication schemes to the utility. Not sure if we can use Twisted cred [2] with ldaptor, but it seems like if it wouldn't be too hard to move in that direction, we should try it, since it might mean we could leverage other existing authN mechanisms that have been written using cred.

For the optional depedndencies-- can you just try importing one module and if it fails fall back to the other, and then if that fails then don't include that authN option in the list of available command line options?

Also, I know Twisted has its own command line options abstraction, but it might be simpler to go with argparse from the standard library, which tends to give more of the default behaviors I expect for command line utilities without having to poke around as much.

SASL is a pretty common option in the LDAP world so I wouldn't be opposed to seeing it included in ldaptor. That said, if I understand correctly, the idea is that it separates authentication protocols from application protocols. So if we could get this to work with Twisted cred, it might be useful as a standalone release (txGSSAPI?). I quick google search did turn up some random code that purports to implement GSSAPI for Twisted cred [3], but I didn't test it out or look closely.

Docs are important. In fact, until you made this pull request, I didn't realize ldaptor had any built in command line tools, because the docs don't mention them! I'd suggest maybe a new sub-section in the "User's Guide" section for "Built in command line tools". I'd give some short examples on usage. Some pointers for adding additional authN plugins would be awesome. If it seems to cluttered in the User Guide, maybe it could go in the Cookbook section?

Thanks,
Carl

[1] https://twistedmatrix.com/documents/current/core/howto/tap.html
[2] https://twistedmatrix.com/documents/current/core/howto/cred.html
[3] http://www.ofchk.biz/server_source/calendar_server/src/twistedcaldav/authkerb.py

@schlenk
Copy link
Author

schlenk commented Jun 8, 2016

seems my git skills are a bit rusty... :-(, not sure if i messed up things.

@coveralls
Copy link

coveralls commented Jun 8, 2016

Coverage Status

Coverage decreased (-1.02%) to 86.028% when pulling e27d779 on schlenk:gssapi into 42ce859 on twisted:master.

@schlenk schlenk reopened this Jun 8, 2016
@coveralls
Copy link

coveralls commented Jun 8, 2016

Coverage Status

Coverage decreased (-1.0%) to 86.028% when pulling fec75d2 on schlenk:gssapi into 9380c55 on twisted:master.

@coveralls
Copy link

coveralls commented Jun 8, 2016

Coverage Status

Coverage decreased (-1.0%) to 86.028% when pulling fec75d2 on schlenk:gssapi into 9380c55 on twisted:master.

@psi29a
Copy link
Contributor

psi29a commented Jun 8, 2016

Awesome... all the builds work but pyflakes says:
ldaptor/usage.py:113: local variable 'MECHANISM' is assigned to but never used

Coverage is also not that great, it could use some test cases to see if anything is breaking.

@cwaldbieser: I agree with everything you've typed. I would like to see this PR using Twisted Cred if possible. I like the idea of making this plugable.

We can move to using argparse in another PR to keep this one to the point.

Same with documentation, it doesn't have to go in this PR but eventually the CLI tools should be covered.

@schlenk
Copy link
Author

schlenk commented Jun 8, 2016

@cwaldbieser: Agreed. Will have a look how cred fits into it and what to do about some docs. Docs might fit in well in an extra PR.

You are right that SASL is a way to decouple the auth protocol from the application protocol. But sadly it is more than just that. It also includes an negotiable extra layer to provide message integrity and privacy. So in the worst case one has the funny layering of LDAP inside TLS, secured by SASL message integrity handling Kerberos messages secured by GSSAPI. A little bit of overkill.

So having it pluggable isn't that hard (i know because it is pluggable in the Tcl stdlib SASL implementation [http://core.tcl.tk/tcllib/doc/trunk/embedded/www/tcllib/files/modules/sasl/sasl.html]). Just need to generalize the SASL_GSSAPIClientContext a bit to become a generic SASL_ClientContext and then plugin the specific mechanisms.

@cwaldbieser
Copy link
Collaborator

I did take a look at the bind() method in entry.BaseLDAPEntry. You are correct that it doesn't seem flexible for anything other than a simple BIND. In fact, it pre-supposes that you are BINDing with a DN, which could be a problem in some instances (e.g. a SASL "external" mechanism-- see python-ldap for an example[1]).

I would say to keep things flexible, it should probably have a parameter list like bind(**kwds) and the docstring would have to say what the valid parameter combos are, as they can vary pretty significantly from method to method. You might even need to just indicate that you need to refer to the authN provider docs for what parameters to pass outside of a simple BIND.

For BINDs that don't use DNs, one might have to do a more low-level request with the ldaptor.protocols.ldap.ldapclient.LDAPClient for now. Maybe someone can build a useful abstraction at a later time.

Thanks,
Carl

[1] https://www.python-ldap.org/doc/html/ldap-sasl.html#examples-for-ldap-sasl

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 this pull request may close these issues.

4 participants