You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Enrique Rodriguez <en...@gmail.com> on 2007/03/02 01:24:15 UTC

[SASL] SASL questions

Hi, Directory developers,

I have time this weekend so I'm looking at adding SASL\GSSAPI\Kerberos
V5 to LDAP binds.  After reading some RFCs and ApacheDS internals, I
have a couple questions:

1)  The Authenticator.authenticate() method requires an LdapDN.
GSSAPI returns a Kerberos principal name.  What's the best way to map
this to a DN?  We could use a regex, like OpenLDAP, but since we have
access to the Kerberos attributes, we can also search directly for the
principal name by specifying a baseDN.  This means an extra lookup,
but it may mean easier config.  Do we want to require that the
principal name map to a DN with a regex?

For example:

GSSAPI returns:  hnelson@EXAMPLE.COM
Desired DN:      uid=hnelson,ou=users,dc=example,dc=com

With OpenLDAP you specify mappings using the format:

uid=<username>,cn=<realm>,cn=<mech>,cn=auth

A resulting regex for our typical example LDIF would be:

sasl-regexp
          uid=(.*),cn=example.com,cn=gssapi,cn=auth
          uid=$1,ou=users,dc=example,dc=com

The alternative would be to specify a baseDN, like we do for other
lookups.  We then search for the principal name and use the found DN.
Our configuration could be:

gssapiBaseDn = ou=users,dc=example,dc=com

2)  If the best way from #1 is a lookup on Kerberos principal name at
a baseDN, where is the best place to invoke that lookup?  I think I
have to do the lookup in the LDAP protocol provider, since the
Authenticator.authenticate() method requires an LdapDN.  If I set env
property Context.SECURITY_PRINCIPAL to the Kerberos principal name
from GSSAPI, is there any way to do a lookup and convert that prior to
calling Authenticator.authenticate(), but in the backend, not the
protocol provider?  Would we gain anything?  FWIW, the Kerberos
provider currently does lookups in the protocol provider.

BTW, the regex is sounding easier and probably more performant.

2)  Any opinion on the 'authenticatorType' to use?  Doco seems to
indicate that the choices are "none," "simple," and "strong."
However, it might be better (ie more modular) to have an authenticator
for each SASL type, eg "sasl-gssapi" and "sasl-digest-md5."  Even with
2 SASL mechanisms supported we could be looking at one large
Authenticator.  Would that be a pain for embedders, in which case we
could use "strong" and have a separate env property if we decide to
have multiple authenticators?

3)  I'm planning on adding GSSAPI.  What other SASL types are actually used?

Thanks,

Enrique

Re: [SASL] SASL questions

Posted by Enrique Rodriguez <en...@gmail.com>.
On 3/3/07, Alex Karasulu <ak...@apache.org> wrote:
> On 3/1/07, Enrique Rodriguez <en...@gmail.com> wrote:
> > ...
> > sasl-regexp
> >           uid=(.*),cn=example.com,cn=gssapi,cn=auth
> >           uid=$1,ou=users,dc=example,dc=com
>
> I'm having a bit of a problem understanding this.  It seems you're matching
> for some UID value in one DN (the first) and using that to map to another DN
> (2nd one in your example).
>
> I'm probably being a bit near sighted here and missing something.  Did we
> not want to use the regex to map a krb5 principal name to an LDAP DN?
>
> BTW is this example an OpenLDAP thing or a convention used to organize
> krb principal entries?

This is OpenLDAP config.  While we do, ultimately, want to map a
Kerberos principal to a DN, Kerberos (GSSAPI) is only one
authentication mechanism.  For example, users may also use DIGEST-MD5.
 The first DN is sort of a "virtual DN" where the root
"cn=gssapi,cn=auth" says the mechanism is GSSAPI.  It could also be
"cn=digest-md5,cn=auth", giving you a layer of indirection.  This
"virtual DN" format is:

uid=<username>,cn=<realm>,cn=<mech>,cn=auth

This allows you to have different mappings based on mechanism type.
For example, perhaps machine accounts must use GSSAPI while user
accounts can use GSSAPI or DIGEST-MD5 and machines and users are in
separate OU's?

> > The alternative would be to specify a baseDN, like we do for other
> > lookups.  We then search for the principal name and use the found DN.
> > Our configuration could be:
> >
> > gssapiBaseDn = ou=users,dc=example,dc=com
>
> Do you think not using a regex for KRB5 principal to LDAP entry DN mappings
> will limit the flexibility of the server?  Might also be nice to support
> both mechanisms
> but that might be a little too much to grok for just getting something out
> the door.
>
> Sounds to me like the use of the base dn configuration parameter is much
> easier to implement, understand and convey to our users.

I do think the regex is important for flexibility.  1..n "base DN"s
would be easier, but we certainly can do regex.  Also, if
per-mechanism mapping is desirable then we need to figure out how to
allow that.

One thing I think we should be adamant about from the beginning with
this LDAP+Kerberos integration is that we must have multiple realm
support.  You must be able to have, for example, users under
ou=users,dc=apache,dc=org AND ou=users,dc=example,dc=com where the
realms are, respectively, APACHE.ORG and EXAMPLE.COM.  Plus, as Quanah
pointed out, you'll have user, machine, and service principals in
separate subtrees, as well.  I found it interesting that your
ApacheCon tutorial talks about how the core Partition Nexus performs
"call routing based on namespace."  Multi-realm is a no-brainer to
implement; in fact, the old OSGi build allowed this.  The limitation
today is only that there's no config support for it; we allow one base
DN.

I don't want to complicate the 1st round of this, but ... this
multi-base lookup applies to multiple zones for DNS and multiple
subnets for DHCP.  The DNS RFCs call this a "catalog."  Again, maybe a
core service (or two) will work for pre-processing everything for
everybody.

As you noted, it's best to get something out the door, but I wanted to
get some awareness going.

> > 2)  If the best way from #1 is a lookup on Kerberos principal name at
> > a baseDN, where is the best place to invoke that lookup?  I think I
> > have to do the lookup in the LDAP protocol provider, since the
> > Authenticator.authenticate () method requires an LdapDN.
>
> I guess you're going to have to add the work flow for managing the SASL bind
> within the PP.  The standard authentication pathway which uses these
> Authenticators
> may be useless to you.

Yeah, the PP will handle workflow, but it will also coordinate with a
MINA filter that handles wrapping and unwrapping data, once the Bind
has completed.

Inbound -> SaslFilter (off) -> decoder -> BindHandler <-> backend 1, 2
Outbound <- SaslFilter (off) <- encoder <--------'

All subsequent LDAP operations:
Inbound -> SaslFilter (on) -> decoder -> SearchHandler <-> backend
Outbound <- SaslFilter (on) <- encoder <-------'

#1 is a user lookup to authenticate.  Should be an Authenticator, once
we figure out how to derive a DN for the user based on principal w/
realm.
#2 is an LdapContext establishment for that user and stored in the session.

> It's been a while since I've been in this code so bear with me.  I guess I
> can give
> a better answer if I started fishing around in the code to get reacclimated.
>  If you
> need me to do that just let me know and I can make some time.

Cool, thanks.  I'll get some code committed and we can start to review
the more hairy integration issues.  BTW, where should I start putting
work?  I'm thinking the server-sasl module but I think longer term it
will just roll into the PP.  From the server-sasl or protocol-ldap
modules we can review the touchpoints with the core.  server-sasl
seemed to me to be an effort to segregate SASL since it was a JDK 1.5
thing.  Also, FYI, I don't think I'll be able to make this a drop-in
MINA subproject, like SSL, since there is a handler that must talk to
a user store.  Anyway, we can review it later.

> > If I set env
> > property Context.SECURITY_PRINCIPAL to the Kerberos principal name
> > from GSSAPI, is there any way to do a lookup and convert that prior to
> > calling Authenticator.authenticate(), but in the backend, not the
> > protocol provider?
>
> We could setup code withing the authentication service (interceptor) to
> detect
> sasl binds and automatically map the Krb5 principal name to an LDAP name.

Cool, makes sense.  As I mentioned above, a common way to map
zones/realms/subnets and handled in a common place would be very
powerful.

> > Would we gain anything?  FWIW, the Kerberos
> > provider currently does lookups in the protocol provider.
>
> You could do that or alter the LDAP infrastructure between the pp and the
> partition (the interceptors) to handle sasl binds.
>
> > BTW, the regex is sounding easier and probably more performant.
>
> Oh? Why do you think?

Hmm, a misstatement on my part.  I was thinking the regex would be
more performant as you would build a DN and look directly for it,
while a lookup at a baseDN would mean a broader search.  And I have
lookup code from Kerberos but nothing for regex's so regex support
would be a new effort, and thus "harder."  Mostly my own lack of
experience with regex's.

> > 2)  Any opinion on the 'authenticatorType' to use?  Doco seems to
> > indicate that the choices are "none," "simple," and "strong."
> > However, it might be better (ie more modular) to have an authenticator
> > for each SASL type, eg "sasl-gssapi" and "sasl-digest-md5."  Even with
> > 2 SASL mechanisms supported we could be looking at one large
> > Authenticator.  Would that be a pain for embedders, in which case we
> > could use "strong" and have a separate env property if we decide to
> > have multiple authenticators?
>
> Hmmm I think adding strong type specifiers for specific SASL mechanisms
> might require a little refactoring in how Authenticators work.  I just need
> to take a better look at the code again.

OK, I'll wait.

> > 3)  I'm planning on adding GSSAPI.  What other SASL types are actually
> used?
>
> I think that's the most useful and most expected of mechanisms.  However md5
> is also popular.
>
> <dreaming>
> It would be cool would be to at some point implement the SASL mechanism for
> utilizing OTPs.
> </dreaming>

I looked at that while reviewing SASL doco.  IIUC, it isn't a generic
mechanism for any type of OTP, but rather a specific OTP algorithm.
We couldn't reuse it for HOTP, if that's what you're thinking.  HOTP
or HOTP+PIN would be great to add with Binds, though.

> I think I need to dive back into this code to be more useful to you.
> Furthermore it's not
> in the best shape it could be in.

It's been a great exercise for getting familiar with the core.

Enrique

Re: [SASL] SASL questions

Posted by Alex Karasulu <ak...@apache.org>.
Hi Enrique,

On 3/1/07, Enrique Rodriguez <en...@gmail.com> wrote:
>
> Hi, Directory developers,
>
> I have time this weekend so I'm looking at adding SASL\GSSAPI\Kerberos
> V5 to LDAP binds.


Excellent!

After reading some RFCs and ApacheDS internals, I
> have a couple questions:
>
> 1)  The Authenticator.authenticate() method requires an LdapDN.


Yep.

GSSAPI returns a Kerberos principal name.  What's the best way to map
> this to a DN?  We could use a regex, like OpenLDAP, but since we have
> access to the Kerberos attributes, we can also search directly for the
> principal name by specifying a baseDN.  This means an extra lookup,
> but it may mean easier config.  Do we want to require that the
> principal name map to a DN with a regex?
>
> For example:
>
> GSSAPI returns:  hnelson@EXAMPLE.COM
> Desired DN:      uid=hnelson,ou=users,dc=example,dc=com
>
> With OpenLDAP you specify mappings using the format:
>
> uid=<username>,cn=<realm>,cn=<mech>,cn=auth
>
> A resulting regex for our typical example LDIF would be:
>
> sasl-regexp
>           uid=(.*),cn=example.com,cn=gssapi,cn=auth
>           uid=$1,ou=users,dc=example,dc=com


I'm having a bit of a problem understanding this.  It seems you're matching
for some UID value in one DN (the first) and using that to map to another DN
(2nd one in your example).

I'm probably being a bit near sighted here and missing something.  Did we
not want to use the regex to map a krb5 principal name to an LDAP DN?

BTW is this example an OpenLDAP thing or a convention used to organize
krb principal entries?

The alternative would be to specify a baseDN, like we do for other
> lookups.  We then search for the principal name and use the found DN.
> Our configuration could be:
>
> gssapiBaseDn = ou=users,dc=example,dc=com


Do you think not using a regex for KRB5 principal to LDAP entry DN mappings
will limit the flexibility of the server?  Might also be nice to support
both mechanisms
but that might be a little too much to grok for just getting something out
the door.

Sounds to me like the use of the base dn configuration parameter is much
easier to implement, understand and convey to our users.

2)  If the best way from #1 is a lookup on Kerberos principal name at
> a baseDN, where is the best place to invoke that lookup?  I think I
> have to do the lookup in the LDAP protocol provider, since the
> Authenticator.authenticate() method requires an LdapDN.


I guess you're going to have to add the work flow for managing the SASL bind

within the PP.  The standard authentication pathway which uses these
Authenticators
may be useless to you.

It's been a while since I've been in this code so bear with me.  I guess I
can give
a better answer if I started fishing around in the code to get
reacclimated.  If you
need me to do that just let me know and I can make some time.

If I set env
> property Context.SECURITY_PRINCIPAL to the Kerberos principal name
> from GSSAPI, is there any way to do a lookup and convert that prior to
> calling Authenticator.authenticate(), but in the backend, not the
> protocol provider?


We could setup code withing the authentication service (interceptor) to
detect
sasl binds and automatically map the Krb5 principal name to an LDAP name.

Would we gain anything?  FWIW, the Kerberos
> provider currently does lookups in the protocol provider.


You could do that or alter the LDAP infrastructure between the pp and the
partition (the interceptors) to handle sasl binds.

BTW, the regex is sounding easier and probably more performant.


Oh? Why do you think?

2)  Any opinion on the 'authenticatorType' to use?  Doco seems to
> indicate that the choices are "none," "simple," and "strong."
> However, it might be better (ie more modular) to have an authenticator
> for each SASL type, eg "sasl-gssapi" and "sasl-digest-md5."  Even with
> 2 SASL mechanisms supported we could be looking at one large
> Authenticator.  Would that be a pain for embedders, in which case we
> could use "strong" and have a separate env property if we decide to
> have multiple authenticators?


Hmmm I think adding strong type specifiers for specific SASL mechanisms
might require a little refactoring in how Authenticators work.  I just need
to take a better look at the code again.

3)  I'm planning on adding GSSAPI.  What other SASL types are actually used?


I think that's the most useful and most expected of mechanisms.  However md5

is also popular.

<dreaming>
It would be cool would be to at some point implement the SASL mechanism for
utilizing OTPs.
</dreaming>

I think I need to dive back into this code to be more useful to you.
Furthermore it's not
in the best shape it could be in.

Alex

Re: [SASL] SASL questions

Posted by Quanah Gibson-Mount <qu...@stanford.edu>.

--On Friday, March 02, 2007 1:57 PM -0800 Enrique Rodriguez 
<en...@gmail.com> wrote:

> On 3/1/07, Quanah Gibson-Mount <qu...@stanford.edu> wrote:
>> ...
>> ldap:///cn=Webauth,cn=Applications,dc=stanford,dc=edu??sub?krb5Principal
>> Name=webauth/$1@stanford.edu sasl-regexp
>> uid=(.*),cn=stanford.edu,cn=gssapi,cn=auth
>> ldap:///uid=$1,cn=Accounts,dc=stanford,dc=edu??sub?suSeasStatus=active
>>
>> In particular, if you look at the last one, this is dealing with
>> Accounts. Rather than looking at their Kerberos krb5Name at all, I do a
>> direct mapping if they have an active "full" account.  All users have
>> kerberos principals, but not all users have "full" accounts.  So in the
>> case that they don't have "full" accounts, I don't want them to just
>> automatically be able to search the directory with an authenticated view.
>
> Thanks, this is really great feedback.
>
> Can you clarify "full" user vs. "non-full"?  Is the deal here that a
> non-full user is one who is coming in from outside Stanford via
> Shibboleth credentials, and who is then mapped to Kerberos credentials
> for access to intra-enterprise services?

Well, no, we support Shibboleth separately from full vs base (non-full). 
It has more to do with say, contractors or other outside people who may 
need access to specific resources.

<http://sunetid.stanford.edu/>

has a chart part way down describing the differences between base & full.

<http://www.stanford.edu/dept/as/mais/applications/sunetid/index.html>

has more charts, and a broader description of base vs full.


>> My only question here is if this is a reference to the strength of the
>> connection, but I'm guessing it isn't.  One of the things OpenLDAP lets
>> me do is enforce encryption strength of connections.  For example, in my
>> ACL files, I have:
>> ...
>> which means the SASL SSF must be at least strength 56.  Java and other
>> applications will by default connect via SASL/GSSAPI with *no* encryption
>> (yuck!).
>
> JNDI uses an env property Context.SECURITY_AUTHENTICATION.  The
> javadoc states this can be "none", "simple", or "strong".  In the
> current BindHandler, this property is set to "simple" which then
> AFAICK maps to the SimpleAuthenticator.  Likely this is just another
> mismatch between the client-side JNDI API and our needs as a server.

Yeah, we have a number of Java apps using SASL/GSSAPI.  It was through them 
that we discovered Java's default behavior. ;)

One of my co-workers actually has a document on accessing LDAP with 
SASL/GSSAPI up:

<http://www.stanford.edu/~kam/ldap.html>


> I'll note as a separate feature the need to specify the connection
> strength for access control and open a JIRA issue.


Sounds good. :)

--Quanah

--
Quanah Gibson-Mount
Principal Software Developer
ITS/Shared Application Services
Stanford University
GnuPG Public Key: http://www.stanford.edu/~quanah/pgp.html

Re: [SASL] SASL questions

Posted by Enrique Rodriguez <en...@gmail.com>.
On 3/1/07, Quanah Gibson-Mount <qu...@stanford.edu> wrote:
> ... ldap:///cn=Webauth,cn=Applications,dc=stanford,dc=edu??sub?krb5PrincipalName=webauth/$1@stanford.edu
> sasl-regexp uid=(.*),cn=stanford.edu,cn=gssapi,cn=auth
> ldap:///uid=$1,cn=Accounts,dc=stanford,dc=edu??sub?suSeasStatus=active
>
> In particular, if you look at the last one, this is dealing with Accounts.
> Rather than looking at their Kerberos krb5Name at all, I do a direct
> mapping if they have an active "full" account.  All users have kerberos
> principals, but not all users have "full" accounts.  So in the case that
> they don't have "full" accounts, I don't want them to just automatically be
> able to search the directory with an authenticated view.

Thanks, this is really great feedback.

Can you clarify "full" user vs. "non-full"?  Is the deal here that a
non-full user is one who is coming in from outside Stanford via
Shibboleth credentials, and who is then mapped to Kerberos credentials
for access to intra-enterprise services?

> My only question here is if this is a reference to the strength of the
> connection, but I'm guessing it isn't.  One of the things OpenLDAP lets me
> do is enforce encryption strength of connections.  For example, in my ACL
> files, I have:
> ...
> which means the SASL SSF must be at least strength 56.  Java and other
> applications will by default connect via SASL/GSSAPI with *no* encryption
> (yuck!).

JNDI uses an env property Context.SECURITY_AUTHENTICATION.  The
javadoc states this can be "none", "simple", or "strong".  In the
current BindHandler, this property is set to "simple" which then
AFAICK maps to the SimpleAuthenticator.  Likely this is just another
mismatch between the client-side JNDI API and our needs as a server.

I'll note as a separate feature the need to specify the connection
strength for access control and open a JIRA issue.

Thanks again.

Enrique

Re: [SASL] SASL questions

Posted by Quanah Gibson-Mount <qu...@stanford.edu>.

--On Thursday, March 01, 2007 4:24 PM -0800 Enrique Rodriguez 
<en...@gmail.com> wrote:

> Hi, Directory developers,
>
> I have time this weekend so I'm looking at adding SASL\GSSAPI\Kerberos
> V5 to LDAP binds.  After reading some RFCs and ApacheDS internals, I
> have a couple questions:
>
> 1)  The Authenticator.authenticate() method requires an LdapDN.
> GSSAPI returns a Kerberos principal name.  What's the best way to map
> this to a DN?  We could use a regex, like OpenLDAP, but since we have
> access to the Kerberos attributes, we can also search directly for the
> principal name by specifying a baseDN.  This means an extra lookup,
> but it may mean easier config.  Do we want to require that the
> principal name map to a DN with a regex?
>
> For example:
>
> GSSAPI returns:  hnelson@EXAMPLE.COM
> Desired DN:      uid=hnelson,ou=users,dc=example,dc=com
>
> With OpenLDAP you specify mappings using the format:
>
> uid=<username>,cn=<realm>,cn=<mech>,cn=auth
>
> A resulting regex for our typical example LDIF would be:
>
> sasl-regexp
>           uid=(.*),cn=example.com,cn=gssapi,cn=auth
>           uid=$1,ou=users,dc=example,dc=com
>
> The alternative would be to specify a baseDN, like we do for other
> lookups.  We then search for the principal name and use the found DN.
> Our configuration could be:
>
> gssapiBaseDn = ou=users,dc=example,dc=com

My only comment here is that in my environment, I have more than just users 
that use Kerberos to bind to the server.  For example, I have cgi, service, 
webauth, and ldap principles.  They are all in their own trees, like:

cn=web,cn=service,cn=applications,dc=stanford,dc=edu
cn=www,cn=webauth,cn=applications,dc=stanford,dc=edu
cn=quanah,cn=cgi,cn=applications,dc=stanford,dc=edu

etc.

So I have multiple regex's in my slapd.conf:

sasl-regexp uid=(.*)/cgi,cn=stanford.edu,cn=gssapi,cn=auth 
ldap:///cn=cgi,cn=applications,dc=stanford,dc=edu??sub?krb5PrincipalName=$1/cgi@stanford.edu
sasl-regexp uid=service/(.*),cn=stanford.edu,cn=gssapi,cn=auth 
ldap:///cn=Service,cn=Applications,dc=stanford,dc=edu??sub?krb5PrincipalName=service/$1@stanford.edu
sasl-regexp uid=webauth/(.*),cn=stanford.edu,cn=gssapi,cn=auth 
ldap:///cn=Webauth,cn=Applications,dc=stanford,dc=edu??sub?krb5PrincipalName=webauth/$1@stanford.edu
sasl-regexp uid=(.*),cn=stanford.edu,cn=gssapi,cn=auth 
ldap:///uid=$1,cn=Accounts,dc=stanford,dc=edu??sub?suSeasStatus=active


In particular, if you look at the last one, this is dealing with Accounts. 
Rather than looking at their Kerberos krb5Name at all, I do a direct 
mapping if they have an active "full" account.  All users have kerberos 
principals, but not all users have "full" accounts.  So in the case that 
they don't have "full" accounts, I don't want them to just automatically be 
able to search the directory with an authenticated view.

> 2)  Any opinion on the 'authenticatorType' to use?  Doco seems to
> indicate that the choices are "none," "simple," and "strong."
> However, it might be better (ie more modular) to have an authenticator
> for each SASL type, eg "sasl-gssapi" and "sasl-digest-md5."  Even with
> 2 SASL mechanisms supported we could be looking at one large
> Authenticator.  Would that be a pain for embedders, in which case we
> could use "strong" and have a separate env property if we decide to
> have multiple authenticators?

My only question here is if this is a reference to the strength of the 
connection, but I'm guessing it isn't.  One of the things OpenLDAP lets me 
do is enforce encryption strength of connections.  For example, in my ACL 
files, I have:

    by dn.base="cn=lsdb,cn=Service,cn=Applications,dc=stanford,dc=edu" 
sasl_ssf=56 read


which means the SASL SSF must be at least strength 56.  Java and other 
applications will by default connect via SASL/GSSAPI with *no* encryption 
(yuck!).

> 3)  I'm planning on adding GSSAPI.  What other SASL types are actually
> used?

SASL/EXTERNAL is used a lot (Cert authentication)
SASL/DIGEST-MD5 is used a lot

--Quanah


--
Quanah Gibson-Mount
Principal Software Developer
ITS/Shared Application Services
Stanford University
GnuPG Public Key: http://www.stanford.edu/~quanah/pgp.html