[Dovecot] MD5 ldap password schemes

Joshua Goodall joshua at roughtrade.net
Tue Feb 3 03:51:19 EET 2004


On Mon, Feb 02, 2004 at 08:02:53PM +0200, Timo Sirainen wrote:
> On Sat, 2004-01-31 at 01:21, SAiello at Jentoo.com wrote:
> > Looking at the possible LDAP passwords Schemes, if I wanted to use PLAIN-MD5 
> > or DIGEST-MD5, what would format would I use in LDAP for the userPassword 
> > field ? I have done SHA, SSHA, and MD5 before, but not sure what is 
> > acceptable for the above mentioned, that dovecot can use.
> 
> PLAIN-MD5 means the field contains just the MD5 sum of the password in
> hex. DIGEST-MD5 is MD5 sum of user:realm:password string. They don't
> have any special format in there..

There is a certain impedence mismatch between RFC2307's idea of {MD5}
and Dovecot's.  I tinkered a while ago with this quirk and the resulting
patch is attached. (also available from http://www.roughtrade.net/dovecot/)

Caveat emptor: it is totally untested beyond my workstation, it is
unchanged from months ago, has not been reviewed by Timo and is not in
the CVS tree.  I've only just confirmed that it compiles with 0.99.10.4.
Let me know if it's of any use.

Regards
Joshua.


-- 
Joshua Goodall                           "as modern as tomorrow afternoon"
joshua at roughtrade.net                                       - FW109
-------------- next part --------------
--- dovecot-0.99.10.4/src/auth/passdb-ldap.c.orig	Fri Mar 21 02:55:57 2003
+++ dovecot-0.99.10.4/src/auth/passdb-ldap.c	Tue Feb  3 12:19:17 2004
@@ -11,6 +11,9 @@
 #include "password-scheme.h"
 #include "db-ldap.h"
 #include "passdb.h"
+#include "base64.h"
+#include "buffer.h"
+#include "hex-binary.h"
 
 #include <ldap.h>
 #include <stdlib.h>
@@ -54,6 +57,7 @@
         struct auth_request *auth_request = request->context;
 	LDAPMessage *entry;
 	BerElement *ber;
+	buffer_t *buf;
 	char *attr, **vals;
 	const char *user, *password, *scheme;
 	int ret;
@@ -102,6 +106,16 @@
 	if (scheme == NULL) {
 		scheme = conn->set.default_pass_scheme;
 		i_assert(scheme != NULL);
+	}
+
+	/* Special case for OpenLDAP's MD5 type */
+	if (strcasecmp(scheme, "MD5") == 0) {
+		buf = buffer_create_static(data_stack_pool, 16);
+		if (base64_decode(password, strlen(password), NULL, buf) == 1
+				&& buffer_get_used_size(buf) == 16) {
+			password = binary_to_hex(buffer_get_data(buf, NULL), 16);
+			scheme = "PLAIN-MD5";
+		}
 	}
 
 	if (ldap_request->credentials != -1) {
--- dovecot-0.99.10.4/src/auth/password-scheme.c.orig	Sun May  4 04:32:59 2003
+++ dovecot-0.99.10.4/src/auth/password-scheme.c	Tue Feb  3 12:20:57 2004
@@ -2,6 +2,8 @@
 
 #include "lib.h"
 #include "hex-binary.h"
+#include "base64.h"
+#include "buffer.h"
 #include "md5.h"
 #include "md5crypt.h"
 #include "mycrypt.h"
@@ -16,6 +18,10 @@
 {
 	unsigned char digest[16];
 	const char *realm, *str;
+	buffer_t *buf;
+	size_t size;
+	const void *data;
+	struct md5_context ctx;
 
 	if (password == NULL)
 		return 0;
@@ -48,6 +54,29 @@
 		return strcasecmp(str, password) == 0;
 	}
 
+	/* format: base64-encoded MD5 hash and salt */
+	if (strcasecmp(scheme, "SMD5") == 0) {
+		buf = buffer_create_static(data_stack_pool,
+				MAX_BASE64_DECODED_SIZE(strlen(password)+1));
+
+		if (base64_decode(password, strlen(password), NULL, buf) == 1) {
+			data = buffer_get_data(buf, &size);
+			if (size <= 16) {
+				i_error("password-verify(%s): invalid SMD5", user);
+				return -1;
+			}
+
+			md5_init(&ctx);
+			md5_update(&ctx, plaintext, strlen(plaintext));
+			md5_update(&ctx, &data[16], size-16);
+			md5_final(&ctx, digest);
+			return memcmp(digest, data, 16) == 0;
+                } else {
+			i_error("password-verify(%s): couldn't decode SMD5", user);
+			return -1;
+		}
+	}
+
 	return -1;
 }
 
@@ -79,6 +108,14 @@
 
 	scheme = t_strdup_until(*password + 1, p);
 	*password = p + 1;
+
+	/* LDAP's RFC2307 specifies the MD5 scheme for what we call PLAIN-MD5.
+	 * Implementations use base64 encoding for the hash, so we can
+	 * detect the genuine {MD5}'s MCF format - base64 doesn't use '$'. */
+	if (strncasecmp(scheme, "MD5", 3) == 0 &&
+		strncmp(*password, "$1$", 3) != 0) {
+		scheme = "PLAIN-MD5";
+	}
 	return scheme;
 }
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
URL: <http://dovecot.org/pipermail/dovecot/attachments/20040203/1a01b1e3/attachment-0001.bin>


More information about the dovecot mailing list