[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#6826) Apache htpasswd MD5 support [patch]



Full_Name: Devin J. Pohly
Version: 2.4.23
OS: Linux
URL: http://openldap.pastebin.com/t4jWaUfe
Submission from: (NULL) (75.102.64.250)


== Proposed enhancement ==
When migrating an Apache .htpasswd-based system to LDAP authentication, it would
be nice if the password hashes would migrate cleanly.  .htpasswd uses three hash
formats: {SHA}, {CRYPT}, and "apr1", an MD5-based variant not supported by
OpenLDAP.

If OpenLDAP had a hash which was equivalent to (i.e. could be freely converted
to and from) Apache's apr1, conversion would be easy.

== Solution ==
If you're willing to have OpenLDAP depend on APR-Util, it would be trivial to
use the apr_md5_encode and apr_password_validate functions to support this
hash.

If not, I created a patch [1] which implements the apr1 hash.  The algorithm is
the same as PHK MD5 with a different magic number.  I derived the code from the
PHK source which is freely usable under the Beer-ware license (see patch).  This
patch adds an {APR1} hash type to OpenLDAP when configured with --enable-apr1.

[1] http://openldap.pastebin.com/t4jWaUfe

(Note: patch is against release, but passwd.c has not changed significantly in
HEAD.)

== Discussion ==
The patch has held up to my (limited) testing, but it could probably be written
better.  It might be useful to put the algorithm into its own function or file,
since it's fairly complex and used in both the chk_apr1 and hash_apr1 functions.
 It might also be useful to specify the magic number to the functions; then we
would get PHK $1$ hashes for free.

Apache selects salts with 48 bits of randomness but treats them as 64-bit salts.
 The lines referring to apr64[] replicate this behavior for backward
compatibility (so {APR1} hashes generated by slappasswd can be converted to
.htpasswd).  If you're not concerned about being able to convert in the opposite
direction, that code can be removed, and OpenLDAP can then use any size salt.

== Tools ==
The hashes are stored in OpenLDAP's base64(hash + salt) format for consistency. 
I put together a couple pipe-able scripts for converting between Apache's $apr1$
and OpenLDAP {APR1} formats:
Apache to OpenLDAP: http://openldap.pastebin.com/0SSbzjhH
OpenLDAP to Apache: http://openldap.pastebin.com/rfLBRASr