[Dovecot] [PATCH][RFC] LANMAN password scheme

Andrey Panin pazke at donpac.ru
Thu Jul 29 14:34:55 EEST 2004


On 211, 07 29, 2004 at 02:04:03PM +0400, Andrey Panin wrote:
> On 211, 07 29, 2004 at 08:31:19AM +0400, Andrey Panin wrote:
> > On 210, 07 28, 2004 at 11:33:40PM +1000, Joshua Goodall wrote:
> > > On Wed, Jul 28, 2004 at 12:36:30AM +0300, Timo Sirainen wrote:
> > > > On 27.7.2004, at 16:18, Andrey Panin wrote:
> > > > 
> > > > >It contains common code in src/lib-ntlm directory, Samba compatible
> > > > >NTLM password scheme and authentication mechanism itself.
> > > > 
> > > > So now Dovecot has md4, md5, sha1 and des code. Maybe there should be a 
> > > > lib-crypto or something similiar for those.
> > > 
> > > Yes.
> > > 
> > > Especially since I was thinking about doing a {BLOWFISH} for the
> > > $2$ MCF this weekend.
> > > 
> > > Also, Timo, do you think it would be worth have a compatability
> > > userdb/passdb for migrants from Courier's USERDB?
> > > 
> > > Andrey, how does the NTLM password scheme relate to OpenLDAP's
> > > {LANMAN} scheme?  As far as I can tell, {NTLM} uses md4 whilst
> > > {LANMAN} uses des.  Is that correct?
> > 
> > As i can guess from the {LANMAN} name, it probably uses older Lan
> > Manager password hash format which is DES based. We can get support
> > for it in ten minutes, all needed pieces are in place.
> 
> Well it taked a little more than ten minutes :)
> 
> If you are still interested attached patch adds OpenLDAP {LANMAN}
> compatible (I hope) password scheme.

s/taked/took/ :(

Better patch attached:
	- added missing safe_memset() in lm_hash() function;
	- modified mech-ntlm.c to use {LANMAN} scheme if {NTLM} isn't available.

-- 
Andrey Panin		| Linux and UNIX system administrator
pazke at donpac.ru		| PGP key: wwwkeys.pgp.net
-------------- next part --------------
Index: src/auth/mech-ntlm.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech-ntlm.c,v
retrieving revision 1.1
diff -u -r1.1 mech-ntlm.c
--- src/auth/mech-ntlm.c	28 Jul 2004 15:39:29 -0000	1.1
+++ src/auth/mech-ntlm.c	29 Jul 2004 11:01:41 -0000
@@ -32,6 +32,36 @@
 };
 
 static void
+lm_credentials_callback(const char *credentials,
+			struct auth_request *auth_request)
+{
+	struct ntlm_auth_request *auth =
+		(struct ntlm_auth_request *)auth_request;
+	const unsigned char *client_response;
+	unsigned char lm_response[LM_RESPONSE_SIZE];
+	unsigned char hash[LM_HASH_SIZE];
+	buffer_t *hash_buffer;
+	int ret;
+
+	if (credentials == NULL) {
+		mech_auth_finish(auth_request, NULL, 0, FALSE);
+		return;
+	}
+
+	hash_buffer = buffer_create_data(auth_request->pool,
+					 hash, sizeof(hash));
+	hex_to_binary(credentials, hash_buffer);
+
+	client_response = ntlmssp_buffer_data(auth->response, lm_response);
+
+	ntlmssp_v1_response(hash, auth->challenge, lm_response);
+
+	ret = memcmp(lm_response, client_response, LM_RESPONSE_SIZE) == 0;
+
+	mech_auth_finish(auth_request, NULL, 0, ret);
+}
+
+static void
 ntlm_credentials_callback(const char *credentials,
 			  struct auth_request *auth_request)
 {
@@ -44,7 +74,9 @@
 	int ret;
 
 	if (credentials == NULL) {
-		mech_auth_finish(auth_request, NULL, 0, FALSE);
+		passdb->lookup_credentials(auth_request,
+					   PASSDB_CREDENTIALS_LANMAN,
+					   lm_credentials_callback);
 		return;
 	}
 
Index: src/auth/passdb.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb.c,v
retrieving revision 1.20
diff -u -r1.20 passdb.c
--- src/auth/passdb.c	28 Jul 2004 15:39:29 -0000	1.20
+++ src/auth/passdb.c	29 Jul 2004 11:01:41 -0000
@@ -28,6 +28,8 @@
 		return "HMAC-MD5";
 	case PASSDB_CREDENTIALS_DIGEST_MD5:
 		return "DIGEST-MD5";
+	case PASSDB_CREDENTIALS_LANMAN:
+		return "LANMAN";
 	case PASSDB_CREDENTIALS_NTLM:
 		return "NTLM";
 	}
Index: src/auth/passdb.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb.h,v
retrieving revision 1.11
diff -u -r1.11 passdb.h
--- src/auth/passdb.h	28 Jul 2004 15:39:29 -0000	1.11
+++ src/auth/passdb.h	29 Jul 2004 11:01:41 -0000
@@ -13,6 +13,7 @@
 	PASSDB_CREDENTIALS_CRYPT,
 	PASSDB_CREDENTIALS_CRAM_MD5,
 	PASSDB_CREDENTIALS_DIGEST_MD5,
+	PASSDB_CREDENTIALS_LANMAN,
 	PASSDB_CREDENTIALS_NTLM
 };
 
Index: src/auth/password-scheme-ntlm.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/password-scheme-ntlm.c,v
retrieving revision 1.1
diff -u -r1.1 password-scheme-ntlm.c
--- src/auth/password-scheme-ntlm.c	28 Jul 2004 15:39:29 -0000	1.1
+++ src/auth/password-scheme-ntlm.c	29 Jul 2004 11:01:41 -0000
@@ -5,11 +5,20 @@
 
 #include "ntlm.h"
 
-const char *password_generate_ntlm(const char *plaintext)
+const char *password_generate_lm(const char *pw)
 {
-	unsigned char hash[16];
+	unsigned char hash[LM_HASH_SIZE];
 
-	ntlm_v1_hash(plaintext, hash);
+	lm_hash(pw, hash);
+
+	return binary_to_hex_ucase(hash, sizeof(hash));
+}
+
+const char *password_generate_ntlm(const char *pw)
+{
+	unsigned char hash[NTLMSSP_HASH_SIZE];
+
+	ntlm_v1_hash(pw, hash);
 
 	return binary_to_hex_ucase(hash, sizeof(hash));
 }
Index: src/auth/password-scheme.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/password-scheme.c,v
retrieving revision 1.11
diff -u -r1.11 password-scheme.c
--- src/auth/password-scheme.c	28 Jul 2004 15:39:29 -0000	1.11
+++ src/auth/password-scheme.c	29 Jul 2004 11:01:41 -0000
@@ -400,10 +400,22 @@
 	return memcmp(md5_digest, data, 16) == 0;
 }
 
+static int lm_verify(const char *plaintext, const char *password,
+		       const char *user __attr_unused__)
+{
+	return strcasecmp(password, password_generate_lm(plaintext)) == 0;
+}
+
+static const char *lm_generate(const char *plaintext,
+				 const char *user __attr_unused__)
+{
+	return password_generate_lm(plaintext);
+}
+
 static int ntlm_verify(const char *plaintext, const char *password,
 		       const char *user __attr_unused__)
 {
-	return strcmp(password, password_generate_ntlm(plaintext)) == 0;
+	return strcasecmp(password, password_generate_ntlm(plaintext)) == 0;
 }
 
 static const char *ntlm_generate(const char *plaintext,
@@ -425,6 +437,7 @@
 	{ "DIGEST-MD5", digest_md5_verify, digest_md5_generate },
 	{ "PLAIN-MD5", plain_md5_verify, plain_md5_generate },
 	{ "LDAP-MD5", ldap_md5_verify, ldap_md5_generate },
+	{ "LANMAN", lm_verify, lm_generate },
 	{ "NTLM", ntlm_verify, ntlm_generate },
 	{ NULL, NULL, NULL }
 };
Index: src/auth/password-scheme.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/password-scheme.h,v
retrieving revision 1.5
diff -u -r1.5 password-scheme.h
--- src/auth/password-scheme.h	28 Jul 2004 15:39:29 -0000	1.5
+++ src/auth/password-scheme.h	29 Jul 2004 11:01:41 -0000
@@ -30,6 +30,7 @@
 /* INTERNAL: */
 const char *password_generate_md5_crypt(const char *pw, const char *salt);
 const char *password_generate_cram_md5(const char *pw);
+const char *password_generate_lm(const char *pw);
 const char *password_generate_ntlm(const char *pw);
 
 #endif
Index: src/lib-ntlm/ntlm-encrypt.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-ntlm/ntlm-encrypt.c,v
retrieving revision 1.1
diff -u -r1.1 ntlm-encrypt.c
--- src/lib-ntlm/ntlm-encrypt.c	28 Jul 2004 15:39:30 -0000	1.1
+++ src/lib-ntlm/ntlm-encrypt.c	29 Jul 2004 11:01:41 -0000
@@ -46,6 +46,26 @@
 }
 
 const unsigned char *
+lm_hash(const char *passwd, unsigned char hash[LM_HASH_SIZE])
+{
+	static const unsigned char lm_magic[8] = "KGS!@#$%";
+	unsigned char buffer[14];
+	unsigned int i;
+
+	strncpy(buffer, passwd, sizeof(buffer));
+
+	for (i = 0; i < sizeof(buffer); i++)
+		buffer[i] = i_toupper(buffer[i]);
+
+	deshash(hash, buffer, lm_magic);
+	deshash(hash + 8, buffer + 7, lm_magic);
+
+	safe_memset(buffer, 0, sizeof(buffer));
+
+	return hash;
+}
+
+const unsigned char *
 ntlm_v1_hash(const char *passwd, unsigned char hash[NTLMSSP_HASH_SIZE])
 {
 	size_t len;
Index: src/lib-ntlm/ntlm-encrypt.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-ntlm/ntlm-encrypt.h,v
retrieving revision 1.1
diff -u -r1.1 ntlm-encrypt.h
--- src/lib-ntlm/ntlm-encrypt.h	28 Jul 2004 15:39:30 -0000	1.1
+++ src/lib-ntlm/ntlm-encrypt.h	29 Jul 2004 11:01:41 -0000
@@ -2,6 +2,9 @@
 #define __NTLM_ENCRYPT__
 
 const unsigned char *
+lm_hash(const char *passwd, unsigned char hash[LM_HASH_SIZE]);
+
+const unsigned char *
 ntlm_v1_hash(const char *passwd, unsigned char hash[NTLMSSP_HASH_SIZE]);
 
 void ntlmssp_v1_response(const unsigned char *hash,
Index: src/lib-ntlm/ntlm-types.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-ntlm/ntlm-types.h,v
retrieving revision 1.1
diff -u -r1.1 ntlm-types.h
--- src/lib-ntlm/ntlm-types.h	28 Jul 2004 15:39:30 -0000	1.1
+++ src/lib-ntlm/ntlm-types.h	29 Jul 2004 11:01:42 -0000
@@ -22,6 +22,9 @@
 
 #define NTLMSSP_CHALLENGE_SIZE		8
 
+#define LM_HASH_SIZE			16
+#define LM_RESPONSE_SIZE		24
+
 #define NTLMSSP_HASH_SIZE		16
 #define NTLMSSP_RESPONSE_SIZE		24
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://dovecot.org/pipermail/dovecot/attachments/20040729/b004b78c/attachment-0001.bin>


More information about the dovecot mailing list