Subject: LDAP and DIGEST-MD5 SASL - rfc2829

From: [email-masked]
Date: Thu, 31 Aug 2000 17:44:07 -0500 (CDT)

Where do I store the credentials for DIGEST-MD5 in the directory?
(i.e. what attribute name)
Is READ access control needed for this attribute?

I'm trying to implement DIGEST-MD5 in an LDAP front-end to an X500 Directory.
I can't figure out what needs to be stored for credentials.  Thanks to
OpenLDAP, I have an ldapsearch that does the first part of the bind operation.
I have read RFC2829 and RFC2831 but find that I am at a loss to understand
how the very simple operation of authentication is performed.

From RFC2829 section 6.1:

   The server will respond with a bind response in which the resultCode
   is either success, or an error indication.

I have no idea how this operation is performed.  RFC2831 does not seem to
give a clue about this either.  As near as I can tell, the LDAP server
is required to either use a separate file for authentication information
that contains:

    username
    MD5hash( username-value ":" realm-value ":" passwd )

or store this information in the directory entry for the user that is
trying to authenticate.  It is not clear which attribute this information
needs to be stored in or what access control is needed for this attribute.

The catch-22 comes from what I see as a very serious security violation
with any of the methods that can be used to implement this operation.
Since the user needs only the MD5hash value to authenticate, The MD5hash
value can be considered as a plaintext password.  (3,9 in /rfc2831)
In order to do the DIGEST-MD5 calulation, this attribute needs to be able
to be read.  This means that any administrator that has access to the
directory can read this password hash and use it to authenticate to the
directory as that user.

In an X500 situation, this attribute must be able to be read between two
DSAs.  A snoop on the line will reveal this password hash, the same as
being able to read a cleartext password.  At least with simple authentication
the only thing passed between the DSAs is a compare operation.

I'm sure that I'm missing something very basic.  With all the complexity
of the DIGEST-MD5 operation, I can't believe that it is so simple to
break the authentication operation.

Kurt Zeilenga indicated that openldap allowed cyrus to handle the password and
the authentication.  This would seem to work fine for a single directory on
a single machine, but it does not work with replicated directories.

Can someone shed some likght on this problem?

Thanks
---
David Cahlander [email-masked] 651-415-3171

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Thu, 31 Aug 2000 18:20:56 -0700

>(i.e. what attribute name)

userPassword can be used to store the clear text password.
authPassword (draft-zeilenga-ldap-authpasswd-03.txt, a work
in progress) can be used to the DIGEST-MD5 specific secret.

>Is READ access control needed for this attribute?

Server specific as there is no standard track, mandatory to
implement LDAP access control model (yet).  However,  both
X.500 and LDAP access control models, IIRC, have recommendations
in this area... the current user (anonymous) requires no special
permission to authenticate.  Some servers, such as OpenLDAP 2.x,
actually require "anonymous" to have "auth"entication/"auth"orization
access to the entry and the attributes used for authentication.

>I can't figure out what needs to be stored for credentials.

You either need to store the username + cleartext password or
the username + H({ username-value, ":", realm-value, ":", passwd })
(see RFC 2831, 3.9).

One approach is to store the 'username@REALM' in 'uid' and
the password in 'userPassword' (or the hash in 'authPassword').
Then when the server gets a request to authenthicate
'username@REALM' it can search for (uid=username@REALM) and,
if unique, press on with userPassword (or authPassword).

Another variant of this is use REALM to select the base DN
for the search used to find the user.

Another approach is to REGEX the username/REALM into a DN
of an entry containing the secret.

Another approach is to store externally 'username/REALM' +
secret pairs (this is OpenLDAP 2.0 current approach).

There are other approaches.  (Including misguided
ones which use the bind DN or authzId to locate the
entry associated with the username/REALM).

>I'm sure that I'm missing something very basic.

The intent of DIGEST-MD5 is to offer relatively strong
authentication services between the client and the server
at low cost.

>With all the complexity of the DIGEST-MD5 operation,

DIGEST-MD5 is actually quite simple in comparison to
alternatives (such as StartTLS+simple).  It protects
the client/server authentication from a number of
common attacks, offers simple privacy/integrity protection,
proxy support, etc..

The problems associated with distributing (or providing read
access to) DIGEST-MD5 secrets is comparable to distributing
(or providing read/compare to) simple password secrets.

DIGEST-MD5 was not designed to address wide-scale distribute
of authentication secrets issues.

>I can't believe that it is so simple to

It's not DIGEST-MD5 that is broken....  use the mechanism
within its design constraints.... pay attention to documented
security considerations... and if your use doesn't fit
the mechanism, choose a more appropriate mechanism.

>a single machine, but it does not work with replicated directories.

We took this approach in OpenLDAP 2.0 as it was far more important
for our server to share DIGEST-MD5 secrets with other SASL-enabled
application servers (SMTP, IMAP, POP, HTTP, etc.) then it
was to support distributed LDAP-only services using THIS mechanism.

I believe other mechanisms, such as GSSAPI (w/ Kerberos V), are
much better suited to distributed, multiple application services.