changeset 7984:399b81cc6189 HEAD

MD5 scheme can now autodetect between MD5-CRYPT and PLAIN-MD5.
author Timo Sirainen <tss@iki.fi>
date Wed, 09 Jul 2008 17:50:29 +0530
parents ba581bed8cc7
children a6d187abaa5a
files src/auth/password-scheme.c
diffstat 1 files changed, 39 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/password-scheme.c	Wed Jul 09 14:51:08 2008 +0530
+++ b/src/auth/password-scheme.c	Wed Jul 09 17:50:29 2008 +0530
@@ -141,8 +141,10 @@
 	len = strlen(password);
 	if (encoding != PW_ENCODING_NONE && s->raw_password_len != 0 &&
 	    strchr(scheme, '.') == NULL) {
-		/* encoding not specified. we can autodetect between
-		   base64 and hex encodings. */
+		/* encoding not specified. we can guess quite well between
+		   base64 and hex encodings. the only problem is distinguishing
+		   2 character strings, but there shouldn't be any that short
+		   raw_password_lens. */
 		encoding = len == s->raw_password_len * 2 ? PW_ENCODING_HEX :
 			PW_ENCODING_BASE64;
 	}
@@ -152,6 +154,17 @@
 		*raw_password_r = (const unsigned char *)password;
 		*size_r = len;
 		break;
+	case PW_ENCODING_HEX:
+		buf = buffer_create_static_hard(pool_datastack_create(),
+						len / 2 + 1);
+		if (hex_to_binary(password, buf) == 0) {
+			*raw_password_r = buf->data;
+			*size_r = buf->used;
+			break;
+		}
+		/* fall through, just in case it was base64-encoded after
+		   all. some input lengths produce matching hex and base64
+		   encoded lengths. */
 	case PW_ENCODING_BASE64:
 		buf = buffer_create_static_hard(pool_datastack_create(),
 						MAX_BASE64_DECODED_SIZE(len));
@@ -161,15 +174,6 @@
 		*raw_password_r = buf->data;
 		*size_r = buf->used;
 		break;
-	case PW_ENCODING_HEX:
-		buf = buffer_create_static_hard(pool_datastack_create(),
-						len / 2 + 1);
-		if (hex_to_binary(password, buf) < 0)
-			return -1;
-
-		*raw_password_r = buf->data;
-		*size_r = buf->used;
-		break;
 	}
 	if (s->raw_password_len != *size_r && s->raw_password_len != 0) {
 		/* password has invalid length */
@@ -280,6 +284,29 @@
 }
 
 static bool
+md5_verify(const char *plaintext, const char *user,
+	   const unsigned char *raw_password, size_t size)
+{
+	const char *password, *str;
+	const unsigned char *md5_password;
+	size_t md5_size;
+
+	password = t_strndup(raw_password, size);
+	if (strncmp(password, "$1$", 3) == 0) {
+		/* MD5-CRYPT */
+		str = password_generate_md5_crypt(plaintext, password);
+		return strcmp(str, password) == 0;
+	} else {
+		if (password_decode(password, "PLAIN-MD5",
+				    &md5_password, &md5_size) < 0)
+			return FALSE;
+
+		return password_verify(plaintext, user, "PLAIN-MD5",
+				       md5_password, md5_size) > 0;
+	}
+}
+
+static bool
 md5_crypt_verify(const char *plaintext, const char *user ATTR_UNUSED,
 		 const unsigned char *raw_password, size_t size)
 {
@@ -560,7 +587,7 @@
 
 static const struct password_scheme builtin_schemes[] = {
 	{ "CRYPT", PW_ENCODING_NONE, 0, crypt_verify, crypt_generate },
-	{ "MD5", PW_ENCODING_NONE, 0, md5_crypt_verify, md5_crypt_generate },
+	{ "MD5", PW_ENCODING_NONE, 0, md5_verify, md5_crypt_generate },
 	{ "MD5-CRYPT", PW_ENCODING_NONE, 0,
 	  md5_crypt_verify, md5_crypt_generate },
  	{ "SHA", PW_ENCODING_BASE64, SHA1_RESULTLEN, NULL, sha1_generate },