[dovecot-cvs] dovecot/src/auth password-verify.c,NONE,1.1 password-verify.h,NONE,1.1 Makefile.am,1.12,1.13 auth-login-interface.h,1.3,1.4 db-ldap.c,1.10,1.11 db-ldap.h,1.7,1.8 db-passwd-file.c,1.2,1.3 db-passwd-file.h,1.1,1.2 master-connection.c,1.4,1.5 mech-digest-md5.c,1.8,1.9 mech-plain.c,1.8,1.9 mech.c,1.7,1.8 mech.h,1.5,1.6 passdb-ldap.c,1.4,1.5 passdb-pam.c,1.4,1.5 passdb-passwd-file.c,1.4,1.5 passdb-passwd.c,1.3,1.4 passdb-shadow.c,1.4,1.5 passdb-vpopmail.c,1.3,1.4 passdb.c,1.5,1.6 passdb.h,1.4,1.5 userdb-ldap.c,1.8,1.9 userdb-passwd-file.c,1.3,1.4 userdb-passwd.c,1.3,1.4 userdb-static.c,1.3,1.4 userdb-vpopmail.c,1.3,1.4 userdb-vpopmail.h,1.1,1.2 userdb.h,1.4,1.5

cras at procontrol.fi cras at procontrol.fi
Tue Feb 18 21:11:29 EET 2003


Update of /home/cvs/dovecot/src/auth
In directory danu:/tmp/cvs-serv12828/src/auth

Modified Files:
	Makefile.am auth-login-interface.h db-ldap.c db-ldap.h 
	db-passwd-file.c db-passwd-file.h master-connection.c 
	mech-digest-md5.c mech-plain.c mech.c mech.h passdb-ldap.c 
	passdb-pam.c passdb-passwd-file.c passdb-passwd.c 
	passdb-shadow.c passdb-vpopmail.c passdb.c passdb.h 
	userdb-ldap.c userdb-passwd-file.c userdb-passwd.c 
	userdb-static.c userdb-vpopmail.c userdb-vpopmail.h userdb.h 
Added Files:
	password-verify.c password-verify.h 
Log Message:
Added default_pass_scheme to LDAP. Support for more password schemes. Merged
password checking code with LDAP and passwd-file, so both support the same
schemes now.



--- NEW FILE: password-verify.c ---
/* Copyright (C) 2003 Timo Sirainen */

#include "lib.h"
#include "hex-binary.h"
#include "md5.h"
#include "mycrypt.h"
#include "password-verify.h"

int password_verify(const char *plaintext, const char *password,
		    const char *scheme, const char *user)
{
	unsigned char digest[16];
	const char *realm, *str;

	if (password == NULL)
		return 0;

	if (strcasecmp(scheme, "CRYPT") == 0)
		return strcmp(mycrypt(password, plaintext), plaintext) == 0;

	if (strcasecmp(scheme, "PLAIN") == 0)
		return strcmp(password, plaintext) == 0;

	if (strcasecmp(scheme, "DIGEST-MD5") == 0) {
		/* user:realm:passwd */
		realm = strchr(user, '@');
		if (realm != NULL) realm++; else realm = "";

		str = t_strconcat(t_strcut(user, '@'), ":", realm,  ":",
				  plaintext, NULL);
		md5_get_digest(str, strlen(str), digest);
		str = binary_to_hex(digest, sizeof(digest));

		return strcasecmp(str, password) == 0;
	}

	if (strcasecmp(scheme, "PLAIN-MD5") == 0) {
		md5_get_digest(plaintext, strlen(plaintext), digest);
		str = binary_to_hex(digest, sizeof(digest));
		return strcasecmp(str, password) == 0;
	}

	return -1;
}

const char *password_get_scheme(const char **password)
{
	const char *p, *scheme;

	if (*password == NULL || **password != '{')
		return NULL;

	p = strchr(*password, '}');
	if (p == NULL)
		return NULL;

	scheme = t_strdup_until(*password + 1, p);
	*password = p + 1;
	return scheme;
}

--- NEW FILE: password-verify.h ---
#ifndef __PASSWORD_VERIFY_H
#define __PASSWORD_VERIFY_H

/* Returns 1 = matched, 0 = didn't match, -1 = unknown scheme */
int password_verify(const char *plaintext, const char *password,
		    const char *scheme, const char *user);

/* Extracts scheme from password, or returns NULL if it isn't found. */
const char *password_get_scheme(const char **password);

#endif

Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/auth/Makefile.am,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- Makefile.am	11 Feb 2003 18:01:39 -0000	1.12
+++ Makefile.am	18 Feb 2003 19:11:26 -0000	1.13
@@ -38,6 +38,7 @@
 	passdb-pam.c \
 	passdb-shadow.c \
 	passdb-vpopmail.c \
+	password-verify.c \
 	userdb.c \
 	userdb-ldap.c \
 	userdb-passwd.c \
@@ -58,5 +59,6 @@
 	mech.h \
 	mycrypt.h \
 	passdb.h \
+	password-verify.h \
 	userdb.h \
 	userdb-vpopmail.h

Index: auth-login-interface.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/auth-login-interface.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- auth-login-interface.h	2 Feb 2003 10:16:42 -0000	1.3
+++ auth-login-interface.h	18 Feb 2003 19:11:26 -0000	1.4
@@ -69,7 +69,6 @@
 	/* variable width data, indexes into data[].
 	   Ignore if it points outside data_size. */
 	size_t username_idx; /* NUL-terminated */
-	size_t realm_idx; /* NUL-terminated */
 	size_t reply_idx; /* last, non-NUL terminated */
 
 	size_t data_size;

Index: db-ldap.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/db-ldap.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- db-ldap.c	18 Feb 2003 17:18:31 -0000	1.10
+++ db-ldap.c	18 Feb 2003 19:11:26 -0000	1.11
@@ -34,6 +34,7 @@
 	DEF(SET_STR, user_filter),
 	DEF(SET_STR, pass_attrs),
 	DEF(SET_STR, pass_filter),
+	DEF(SET_STR, default_pass_scheme),
 	DEF(SET_STR, user_global_uid),
 	DEF(SET_STR, user_global_gid)
 };
@@ -49,6 +50,7 @@
 	MEMBER(user_filter) NULL,
 	MEMBER(pass_attrs) NULL,
 	MEMBER(pass_filter) NULL,
+	MEMBER(default_pass_scheme) "crypt",
 	MEMBER(user_global_uid) 0,
 	MEMBER(user_global_gid) 0
 };

Index: db-ldap.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/db-ldap.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- db-ldap.h	18 Feb 2003 17:18:31 -0000	1.7
+++ db-ldap.h	18 Feb 2003 19:11:26 -0000	1.8
@@ -22,6 +22,7 @@
 	const char *pass_attrs;
 	const char *pass_filter;
 
+	const char *default_pass_scheme;
 	unsigned int user_global_uid;
 	unsigned int user_global_gid;
 

Index: db-passwd-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/db-passwd-file.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- db-passwd-file.c	9 Feb 2003 17:23:20 -0000	1.2
+++ db-passwd-file.c	18 Feb 2003 19:11:26 -0000	1.3
@@ -41,25 +41,25 @@
 	p = pass == NULL ? NULL : strchr(pass, '[');
 	if (p == NULL) {
 		pu->password = p_strdup(pw->pool, pass);
-		pu->password_type = pass == NULL ? PASSWORD_NONE : PASSWORD_DES;
 	} else {
 		/* password[type] - we're being libpam-pwdfile compatible
-		   here. it uses 13 = DES and 34 = MD5. We add
-		   56 = Digest-MD5. */
-		pu->password = p_strdup_until(pw->pool, pass, p);
+		   here. it uses 13 = DES and 34 = MD5. For backwards
+		   comaptibility with ourself, we have also 56 = Digest-MD5. */
+		pass = t_strdup_until(pass, p);
 		if (p[1] == '3' && p[2] == '4') {
-			pu->password_type = PASSWORD_MD5;
-			str_lcase(pu->password);
+			pu->password = p_strconcat(pw->pool, "{PLAIN-MD5}",
+						   pass, NULL);
 		} else if (p[1] == '5' && p[2] == '6') {
-			pu->password_type = PASSWORD_DIGEST_MD5;
-			if (strlen(pu->password) != 32) {
+			pu->password = p_strconcat(pw->pool, "{DIGEST-MD5}",
+						   pass, NULL);
+			if (strlen(pu->password) != 32 + 12) {
 				i_error("User %s has invalid password in "
 					"file %s", username, pw->path);
 				return;
 			}
-			str_lcase(pu->password);
 		} else {
-			pu->password_type = PASSWORD_DES;
+			pu->password = p_strconcat(pw->pool, "{CRYPT}",
+						   pass, NULL);
 		}
 	}
 
@@ -208,13 +208,9 @@
 }
 
 struct passwd_user *
-db_passwd_file_lookup(struct passwd_file *pw,
-		      const char *user, const char *realm)
+db_passwd_file_lookup(struct passwd_file *pw, const char *user)
 {
 	struct passwd_user *pu;
-
-	if (realm != NULL)
-		user = t_strconcat(user, "@", realm, NULL);
 
 	passwd_file_sync(pw);
 

Index: db-passwd-file.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/db-passwd-file.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- db-passwd-file.h	31 Jan 2003 06:56:58 -0000	1.1
+++ db-passwd-file.h	18 Feb 2003 19:11:26 -0000	1.2
@@ -1,13 +1,6 @@
 #ifndef __DB_PASSWD_FILE_H
 #define __DB_PASSWD_FILE_H
 
-enum password_type {
-	PASSWORD_NONE,
-	PASSWORD_DES,
-	PASSWORD_MD5,
-	PASSWORD_DIGEST_MD5
-};
-
 struct passwd_user {
 	char *user_realm; /* user at realm */
 	const char *realm; /* NULL or points to user_realm */
@@ -18,7 +11,6 @@
 	char *home;
 	char *mail;
 
-	enum password_type password_type;
 	char *password;
 
 	unsigned int chroot:1;
@@ -39,8 +31,7 @@
 extern struct passwd_file *passdb_pwf;
 
 struct passwd_user *
-db_passwd_file_lookup(struct passwd_file *pw,
-		      const char *user, const char *realm);
+db_passwd_file_lookup(struct passwd_file *pw, const char *user);
 
 struct passwd_file *db_passwd_file_parse(const char *path);
 void db_passwd_file_unref(struct passwd_file *pw);

Index: master-connection.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/master-connection.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- master-connection.c	9 Feb 2003 20:12:56 -0000	1.4
+++ master-connection.c	18 Feb 2003 19:11:26 -0000	1.5
@@ -114,8 +114,8 @@
 	if (request == NULL)
 		send_reply(&failure_reply, sizeof(failure_reply), request->tag);
 	else {
-		userdb->lookup(auth_request->user, auth_request->realm,
-			       userdb_callback, POINTER_CAST(request->tag));
+		userdb->lookup(auth_request->user, userdb_callback,
+			       POINTER_CAST(request->tag));
 		mech_request_free(login_conn, auth_request, request->id);
 	}
 }

Index: mech-digest-md5.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech-digest-md5.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mech-digest-md5.c	2 Feb 2003 10:16:42 -0000	1.8
+++ mech-digest-md5.c	18 Feb 2003 19:11:26 -0000	1.9
@@ -568,10 +568,14 @@
 				  request->data_size, &error)) {
 		auth_request->callback = callback;
 
-		auth_request->user = p_strdup(auth_request->pool,
-					      auth->username);
-		auth_request->realm =
-			p_strdup_empty(auth_request->pool, auth->realm);
+		if (auth->realm == NULL) {
+			auth_request->user = p_strdup(auth_request->pool,
+						      auth->username);
+		} else {
+			auth_request->user = p_strconcat(auth_request->pool,
+							 auth->username, "@",
+							 auth->realm, NULL);
+		}
 
 		passdb->lookup_credentials(&auth->auth_request,
 					   PASSDB_CREDENTIALS_DIGEST_MD5,

Index: mech-plain.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech-plain.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mech-plain.c	9 Feb 2003 17:10:19 -0000	1.8
+++ mech-plain.c	18 Feb 2003 19:11:26 -0000	1.9
@@ -44,10 +44,6 @@
 
 	/* split and save user/realm */
 	auth_request->user = p_strdup(auth_request->pool, authenid);
-	auth_request->realm = strchr(auth_request->user, '@');
-	if (auth_request->realm != NULL)
-		*auth_request->realm++ = '\0';
-
 	passdb->verify_plain(auth_request, pass, verify_callback);
 
 	/* make sure it's cleared */

Index: mech.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mech.c	2 Feb 2003 10:16:42 -0000	1.7
+++ mech.c	18 Feb 2003 19:11:26 -0000	1.8
@@ -133,7 +133,6 @@
 	memset(reply, 0, sizeof(*reply));
 
 	reply->username_idx = (unsigned int)-1;
-	reply->realm_idx = (unsigned int)-1;
 	reply->reply_idx = (unsigned int)-1;
 }
 
@@ -147,14 +146,6 @@
 
 	reply->username_idx = 0;
 	buffer_append(buf, auth_request->user, strlen(auth_request->user)+1);
-
-	if (auth_request->realm == NULL)
-		reply->realm_idx = (size_t)-1;
-	else {
-		reply->realm_idx = buffer_get_used_size(buf);
-		buffer_append(buf, auth_request->realm,
-			      strlen(auth_request->realm)+1);
-	}
 
 	if (data_size == 0)
 		reply->reply_idx = (size_t)-1;

Index: mech.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/mech.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- mech.h	2 Feb 2003 10:16:42 -0000	1.5
+++ mech.h	18 Feb 2003 19:11:26 -0000	1.6
@@ -10,7 +10,7 @@
 
 struct auth_request {
 	pool_t pool;
-	char *user, *realm;
+	char *user;
 
 	struct login_connection *conn;
 	unsigned int id;

Index: passdb-ldap.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-ldap.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- passdb-ldap.c	18 Feb 2003 17:18:31 -0000	1.4
+++ passdb-ldap.c	18 Feb 2003 19:11:26 -0000	1.5
@@ -8,7 +8,7 @@
 #include "common.h"
 #include "str.h"
 #include "var-expand.h"
-#include "mycrypt.h"
+#include "password-verify.h"
 #include "db-ldap.h"
 #include "passdb.h"
 
@@ -55,15 +55,10 @@
 	LDAPMessage *entry;
 	BerElement *ber;
 	char *attr, **vals;
-	const char *user, *password;
-
-	if (auth_request->realm == NULL)
-		user = auth_request->user;
-	else {
-		user = t_strconcat(auth_request->user, "@",
-				   auth_request->realm, NULL);
-	}
+	const char *user, *password, *scheme;
+	int ret;
 
+	user = auth_request->user;
 	password = NULL;
 
 	entry = res == NULL ? NULL : ldap_first_entry(conn->ld, res);
@@ -73,7 +68,6 @@
 	} else {
 		attr = ldap_first_attribute(conn->ld, entry, &ber);
 		while (attr != NULL) {
-			i_warning("attr: %s", attr);
 			vals = ldap_get_values(conn->ld, entry, attr);
 			if (vals != NULL && vals[0] != NULL &&
 			    vals[1] == NULL) {
@@ -95,56 +89,38 @@
 		}
 	}
 
-	switch (ldap_request->credentials) {
-	case -1:
-		/* verify_plain */
-		if (password == NULL) {
-			ldap_request->callback.
-				verify_plain(PASSDB_RESULT_USER_UNKNOWN,
-					     auth_request);
-			break;
-		}
-
-		if (strncasecmp(password, "{crypt}", 7) == 0)
-			password += 7;
+	scheme = password_get_scheme(&password);
+	if (scheme == NULL) {
+		scheme = conn->set.default_pass_scheme;
+		i_assert(scheme != NULL);
+	}
 
-		if (strcmp(mycrypt(password, ldap_request->password),
-			   ldap_request->password) != 0) {
-			if (verbose)
-				i_info("ldap(%s): password mismatch", user);
-			ldap_request->callback.
-				verify_plain(PASSDB_RESULT_PASSWORD_MISMATCH,
-					     auth_request);
-		} else {
-			ldap_request->callback.verify_plain(PASSDB_RESULT_OK,
-							    auth_request);
-		}
-		break;
-	case PASSDB_CREDENTIALS_PLAINTEXT:
-		if (password != NULL &&
-		    strncasecmp(password, "{plain}", 7) == 0)
-			password += 7;
-		else
-			password = NULL;
+	if (ldap_request->credentials != -1) {
+		passdb_handle_credentials(ldap_request->credentials,
+			user, password, scheme,
+			ldap_request->callback.lookup_credentials,
+			auth_request);
+		return;
+	}
 
-		ldap_request->callback.lookup_credentials(password,
-							  auth_request);
-		break;
-	case PASSDB_CREDENTIALS_CRYPT:
-		ldap_request->callback.lookup_credentials(password,
-							  auth_request);
-		break;
-	case PASSDB_CREDENTIALS_DIGEST_MD5:
-		if (password != NULL &&
-		    strncasecmp(password, "{digest-md5}", 12) == 0)
-			password += 12;
-		else
-			password = NULL;
+	/* verify plain */
+	if (password == NULL) {
+		ldap_request->callback.verify_plain(PASSDB_RESULT_USER_UNKNOWN,
+						    auth_request);
+		return;
+	}
 
-		ldap_request->callback.lookup_credentials(password,
-							  auth_request);
-		break;
+	ret = password_verify(ldap_request->password, password, scheme, user);
+	if (ret < 0)
+		i_error("ldap(%s): Unknown password scheme %s", user, scheme);
+	else if (ret == 0) {
+		if (verbose)
+			i_info("ldap(%s): password mismatch", user);
 	}
+
+	ldap_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
+					    PASSDB_RESULT_PASSWORD_MISMATCH,
+					    auth_request);
 }
 
 static void ldap_lookup_pass(struct auth_request *auth_request,
@@ -154,14 +130,7 @@
 	const char *user, *filter;
 	string_t *str;
 
-	if (auth_request->realm == NULL)
-		user = auth_request->user;
-	else {
-		user = t_strconcat(auth_request->user, "@",
-				   auth_request->realm, NULL);
-	}
-
-	user = ldap_escape(user);
+	user = ldap_escape(auth_request->user);
 	if (conn->set.pass_filter == NULL) {
 		filter = t_strdup_printf("(&(objectClass=posixAccount)(%s=%s))",
 			passdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], user);

Index: passdb-pam.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-pam.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- passdb-pam.c	8 Feb 2003 15:00:35 -0000	1.4
+++ passdb-pam.c	18 Feb 2003 19:11:26 -0000	1.5
@@ -199,36 +199,30 @@
 		 verify_plain_callback_t *callback)
 {
 	pam_handle_t *pamh;
-	const char *user;
 	struct pam_userpass userpass;
 	struct pam_conv conv;
 	int status, status2;
 
-	if (request->realm == NULL)
-		user = request->user;
-	else
-		user = t_strconcat(request->user, "@", request->realm, NULL);
-
 	conv.conv = pam_userpass_conv;
 	conv.appdata_ptr = &userpass;
 
-	userpass.user = user;
+	userpass.user = request->user;
 	userpass.pass = password;
 
-	status = pam_start(service_name, user, &conv, &pamh);
+	status = pam_start(service_name, request->user, &conv, &pamh);
 	if (status != PAM_SUCCESS) {
 		if (verbose) {
 			i_info("PAM: pam_start(%s) failed: %s",
-			       user, pam_strerror(pamh, status));
+			       request->user, pam_strerror(pamh, status));
 		}
 		callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
 		return;
 	}
 
-	status = pam_auth(pamh, user);
+	status = pam_auth(pamh, request->user);
 	if ((status2 = pam_end(pamh, status)) != PAM_SUCCESS) {
 		i_error("pam_end(%s) failed: %s",
-			user, pam_strerror(pamh, status2));
+			request->user, pam_strerror(pamh, status2));
 		callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
 		return;
 	}

Index: passdb-passwd-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-passwd-file.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- passdb-passwd-file.c	2 Feb 2003 00:08:28 -0000	1.4
+++ passdb-passwd-file.c	18 Feb 2003 19:11:26 -0000	1.5
@@ -7,12 +7,9 @@
 
 #include "common.h"
 #include "passdb.h"
+#include "password-verify.h"
 #include "db-passwd-file.h"
 
-#include "hex-binary.h"
-#include "md5.h"
-#include "mycrypt.h"
-
 struct passwd_file *passdb_pwf = NULL;
 
 static void
@@ -20,74 +17,33 @@
 			 verify_plain_callback_t *callback)
 {
 	struct passwd_user *pu;
-	unsigned char digest[16];
-	const char *str;
+	const char *scheme, *crypted_pass;
+	int ret;
 
-	pu = db_passwd_file_lookup(passdb_pwf, request->user, request->realm);
+	pu = db_passwd_file_lookup(passdb_pwf, request->user);
 	if (pu == NULL) {
 		callback(PASSDB_RESULT_USER_UNKNOWN, request);
 		return;
 	}
 
-	switch (pu->password_type) {
-	case PASSWORD_NONE:
-		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
-		return;
-
-	case PASSWORD_DES:
-		if (strcmp(mycrypt(password, pu->password),
-			   pu->password) == 0) {
-			callback(PASSDB_RESULT_OK, request);
-			return;
-		}
-
-		if (verbose) {
-			i_info("passwd-file(%s): DES password mismatch",
-			       pu->user_realm);
-		}
-		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
-		return;
-
-	case PASSWORD_MD5:
-		md5_get_digest(password, strlen(password), digest);
-		str = binary_to_hex(digest, sizeof(digest));
-
-		if (strcmp(str, pu->password) == 0) {
-			callback(PASSDB_RESULT_OK, request);
-			return;
-		}
-
-		if (verbose) {
-			i_info("passwd-file(%s): MD5 password mismatch",
-			       pu->user_realm);
-		}
-		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
-		return;
-
-	case PASSWORD_DIGEST_MD5:
-		/* user:realm:passwd */
-		str = t_strconcat(t_strcut(pu->user_realm, '@'), ":",
-				  pu->realm == NULL ? "" : pu->realm,  ":",
-				  password, NULL);
-
-		md5_get_digest(str, strlen(str), digest);
-		str = binary_to_hex(digest, sizeof(digest));
-
-		if (strcmp(str, pu->password) == 0) {
-			callback(PASSDB_RESULT_OK, request);
-			return;
-		}
+	crypted_pass = pu->password;
+	scheme = password_get_scheme(&crypted_pass);
+	if (scheme == NULL) scheme = "DES";
 
-		if (verbose) {
-			i_info("passwd-file(%s): DIGEST-MD5 password mismatch",
-			       pu->user_realm);
+	ret = password_verify(password, crypted_pass, scheme,
+			      request->user);
+	if (ret > 0)
+		callback(PASSDB_RESULT_OK, request);
+	else {
+		if (ret < 0) {
+			i_error("passwd-file(%s): Unknown password scheme %s",
+				pu->user_realm, scheme);
+		} else if (verbose) {
+			i_info("passwd-file(%s): %s password mismatch",
+			       pu->user_realm, scheme);
 		}
-
 		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
-		return;
 	}
-
-	i_unreached();
 }
 
 static void
@@ -96,41 +52,19 @@
 			       lookup_credentials_callback_t *callback)
 {
 	struct passwd_user *pu;
+	const char *crypted_pass, *scheme;
 
-	pu = db_passwd_file_lookup(passdb_pwf, request->user, request->realm);
+	pu = db_passwd_file_lookup(passdb_pwf, request->user);
 	if (pu == NULL) {
 		callback(NULL, request);
 		return;
 	}
 
-	if (pu->password_type == PASSWORD_NONE) {
-		if (verbose)
-			i_info("passwd-file(%s): No password", pu->user_realm);
-		callback(NULL, request);
-		return;
-	}
-
-	switch (credentials) {
-	case PASSDB_CREDENTIALS_DIGEST_MD5:
-		if (pu->password_type == PASSWORD_DIGEST_MD5) {
-			callback(pu->password, request);
-			return;
-		}
+	crypted_pass = pu->password;
+	scheme = password_get_scheme(&crypted_pass);
 
-		if (verbose) {
-			i_info("passwd-file(%s): No DIGEST-MD5 password",
-			       pu->user_realm);
-		}
-		callback(NULL, request);
-		return;
-	default:
-		if (verbose) {
-			i_info("passwd-file(%s): Unsupported credentials %u",
-			       pu->user_realm, (unsigned int)credentials);
-		}
-		callback(NULL, request);
-		return;
-	}
+	passdb_handle_credentials(credentials, request->user, crypted_pass,
+				  scheme, callback, request);
 }
 
 static void passwd_file_init(const char *args)

Index: passdb-passwd.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-passwd.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- passdb-passwd.c	2 Feb 2003 00:08:28 -0000	1.3
+++ passdb-passwd.c	18 Feb 2003 19:11:26 -0000	1.4
@@ -16,21 +16,15 @@
 passwd_verify_plain(struct auth_request *request, const char *password,
 		    verify_plain_callback_t *callback)
 {
-	const char *user;
 	struct passwd *pw;
 	int result;
 
-	if (request->realm == NULL)
-		user = request->user;
-	else
-		user = t_strconcat(request->user, "@", request->realm, NULL);
-
-	pw = getpwnam(user);
+	pw = getpwnam(request->user);
 	if (pw == NULL) {
 		if (errno != 0)
-			i_error("getpwnam(%s) failed: %m", user);
+			i_error("getpwnam(%s) failed: %m", request->user);
 		else if (verbose)
-			i_info("passwd(%s): unknown user", user);
+			i_info("passwd(%s): unknown user", request->user);
 		callback(PASSDB_RESULT_USER_UNKNOWN, request);
 		return;
 	}
@@ -38,7 +32,7 @@
 	if (!IS_VALID_PASSWD(pw->pw_passwd)) {
 		if (verbose) {
 			i_info("passwd(%s): invalid password field '%s'",
-			       user, pw->pw_passwd);
+			       request->user, pw->pw_passwd);
 		}
 		callback(PASSDB_RESULT_USER_DISABLED, request);
 		return;
@@ -52,7 +46,7 @@
 
 	if (!result) {
 		if (verbose)
-			i_info("passwd(%s): password mismatch", user);
+			i_info("passwd(%s): password mismatch", request->user);
 		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
 		return;
 	}

Index: passdb-shadow.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-shadow.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- passdb-shadow.c	4 Feb 2003 00:34:54 -0000	1.4
+++ passdb-shadow.c	18 Feb 2003 19:11:26 -0000	1.5
@@ -16,21 +16,15 @@
 shadow_verify_plain(struct auth_request *request, const char *password,
 		    verify_plain_callback_t *callback)
 {
-	const char *user;
 	struct spwd *spw;
 	int result;
 
-	if (request->realm == NULL)
-		user = request->user;
-	else
-		user = t_strconcat(request->user, "@", request->realm, NULL);
-
-	spw = getspnam(user);
+	spw = getspnam(request->user);
 	if (spw == NULL) {
 		if (errno != 0)
-			i_error("getspnam(%s) failed: %m", user);
+			i_error("getspnam(%s) failed: %m", request->user);
 		else if (verbose)
-			i_info("shadow(%s): unknown user", user);
+			i_info("shadow(%s): unknown user", request->user);
 		callback(PASSDB_RESULT_USER_UNKNOWN, request);
 		return;
 	}
@@ -38,7 +32,7 @@
 	if (!IS_VALID_PASSWD(spw->sp_pwdp)) {
 		if (verbose) {
 			i_info("shadow(%s): invalid password field '%s'",
-			       user, spw->sp_pwdp);
+			       request->user, spw->sp_pwdp);
 		}
 		callback(PASSDB_RESULT_USER_DISABLED, request);
 		return;
@@ -52,7 +46,7 @@
 
 	if (!result) {
 		if (verbose)
-			i_info("shadow(%s): password mismatch", user);
+			i_info("shadow(%s): password mismatch", request->user);
 		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
 		return;
 	}

Index: passdb-vpopmail.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb-vpopmail.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- passdb-vpopmail.c	2 Feb 2003 00:08:28 -0000	1.3
+++ passdb-vpopmail.c	18 Feb 2003 19:11:26 -0000	1.4
@@ -22,7 +22,7 @@
 	struct vqpasswd *vpw;
 	int result;
 
-	vpw = vpopmail_lookup_vqp(request->user, request->realm,
+	vpw = vpopmail_lookup_vqp(request->user,
 				  vpop_user, vpop_domain);
 	if (vpw == NULL) {
 		callback(PASSDB_RESULT_USER_UNKNOWN, request);

Index: passdb.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- passdb.c	11 Feb 2003 20:25:35 -0000	1.5
+++ passdb.c	18 Feb 2003 19:11:26 -0000	1.6
@@ -13,20 +13,52 @@
 
 struct passdb_module *passdb;
 
-const char *passdb_credentials_to_str(enum passdb_credentials credentials)
+static const char *
+passdb_credentials_to_str(enum passdb_credentials credentials)
 {
 	switch (credentials) {
 	case _PASSDB_CREDENTIALS_INTERNAL:
 		break;
 	case PASSDB_CREDENTIALS_PLAINTEXT:
-		return "plaintext";
+		return "PLAIN";
 	case PASSDB_CREDENTIALS_CRYPT:
-		return "crypt";
+		return "CRYPT";
 	case PASSDB_CREDENTIALS_DIGEST_MD5:
-		return "digest-md5";
+		return "DIGEST-MD5";
 	}
 
 	return "??";
+}
+
+void passdb_handle_credentials(enum passdb_credentials credentials,
+			       const char *user, const char *password,
+			       const char *scheme,
+			       lookup_credentials_callback_t *callback,
+                               struct auth_request *auth_request)
+{
+	const char *wanted_scheme;
+
+	if (credentials == PASSDB_CREDENTIALS_CRYPT) {
+		/* anything goes */
+		if (password != NULL)
+			password = t_strdup_printf("{%s}%s", scheme, password);
+		callback(password, auth_request);
+		return;
+	}
+
+	if (password != NULL) {
+		wanted_scheme = passdb_credentials_to_str(credentials);
+		if (strcasecmp(scheme, wanted_scheme) != 0) {
+			if (verbose) {
+				i_info("password(%s): Requested %s scheme, "
+				       "but we have only %s", user,
+				       wanted_scheme, scheme);
+			}
+			password = NULL;
+		}
+	}
+
+	callback(password, auth_request);
 }
 
 void passdb_init(void)

Index: passdb.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/passdb.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- passdb.h	11 Feb 2003 09:55:58 -0000	1.4
+++ passdb.h	18 Feb 2003 19:11:26 -0000	1.5
@@ -43,7 +43,11 @@
 				   lookup_credentials_callback_t *callback);
 };
 
-const char *passdb_credentials_to_str(enum passdb_credentials credentials);
+void passdb_handle_credentials(enum passdb_credentials credentials,
+			       const char *user, const char *password,
+			       const char *scheme,
+			       lookup_credentials_callback_t *callback,
+                               struct auth_request *auth_request);
 
 extern struct passdb_module *passdb;
 

Index: userdb-ldap.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-ldap.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- userdb-ldap.c	18 Feb 2003 17:18:31 -0000	1.8
+++ userdb-ldap.c	18 Feb 2003 19:11:26 -0000	1.9
@@ -137,16 +137,13 @@
 	t_pop();
 }
 
-static void userdb_ldap_lookup(const char *user, const char *realm,
-			       userdb_callback_t *callback, void *context)
+static void userdb_ldap_lookup(const char *user, userdb_callback_t *callback,
+			       void *context)
 {
 	struct ldap_connection *conn = userdb_ldap_conn->conn;
 	struct userdb_ldap_request *request;
 	const char *filter;
 	string_t *str;
-
-	if (realm != NULL)
-		user = t_strconcat(user, "@", realm, NULL);
 
 	user = ldap_escape(user);
 	if (conn->set.user_filter == NULL) {

Index: userdb-passwd-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-passwd-file.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- userdb-passwd-file.c	31 Jan 2003 06:56:58 -0000	1.3
+++ userdb-passwd-file.c	18 Feb 2003 19:11:26 -0000	1.4
@@ -11,13 +11,13 @@
 
 struct passwd_file *userdb_pwf = NULL;
 
-static void passwd_file_lookup(const char *user, const char *realm,
-			       userdb_callback_t *callback, void *context)
+static void passwd_file_lookup(const char *user, userdb_callback_t *callback,
+			       void *context)
 {
 	struct user_data data;
 	struct passwd_user *pu;
 
-	pu = db_passwd_file_lookup(userdb_pwf, user, realm);
+	pu = db_passwd_file_lookup(userdb_pwf, user);
 	if (pu == NULL) {
 		callback(NULL, context);
 		return;
@@ -27,8 +27,7 @@
 	data.uid = pu->uid;
 	data.gid = pu->gid;
 
-	data.virtual_user = realm == NULL ? user :
-		t_strconcat(user, "@", realm, NULL);
+	data.virtual_user = user;
 	data.home = pu->home;
 	data.mail = pu->mail;
 

Index: userdb-passwd.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-passwd.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- userdb-passwd.c	31 Jan 2003 06:56:58 -0000	1.3
+++ userdb-passwd.c	18 Feb 2003 19:11:26 -0000	1.4
@@ -10,14 +10,12 @@
 
 #include <pwd.h>
 
-static void passwd_lookup(const char *user, const char *realm,
-			  userdb_callback_t *callback, void *context)
+static void passwd_lookup(const char *user, userdb_callback_t *callback,
+			  void *context)
 {
 	struct user_data data;
 	struct passwd *pw;
 
-	if (realm != NULL)
-		user = t_strconcat(user, "@", realm, NULL);
 	pw = getpwnam(user);
 	if (pw == NULL) {
 		if (errno != 0)

Index: userdb-static.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-static.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- userdb-static.c	31 Jan 2003 06:56:58 -0000	1.3
+++ userdb-static.c	18 Feb 2003 19:11:26 -0000	1.4
@@ -16,14 +16,11 @@
 static gid_t static_gid;
 static char *static_home_template;
 
-static void static_lookup(const char *user, const char *realm,
-			  userdb_callback_t *callback, void *context)
+static void static_lookup(const char *user, userdb_callback_t *callback,
+			  void *context)
 {
 	struct user_data data;
 	string_t *str;
-
-	if (realm != NULL)
-		user = t_strconcat(user, "@", realm, NULL);
 
 	memset(&data, 0, sizeof(data));
 	data.uid = static_uid;

Index: userdb-vpopmail.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-vpopmail.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- userdb-vpopmail.c	11 Feb 2003 17:42:31 -0000	1.3
+++ userdb-vpopmail.c	18 Feb 2003 19:11:26 -0000	1.4
@@ -11,31 +11,25 @@
 #include "userdb.h"
 #include "userdb-vpopmail.h"
 
-struct vqpasswd *vpopmail_lookup_vqp(const char *user, const char *realm,
+struct vqpasswd *vpopmail_lookup_vqp(const char *user,
 				     char vpop_user[VPOPMAIL_LIMIT],
 				     char vpop_domain[VPOPMAIL_LIMIT])
 {
 	struct vqpasswd *vpw;
 
-	if (realm != NULL) {
-		if (strlen(user) >= VPOPMAIL_LIMIT ||
-		    strlen(realm) >= VPOPMAIL_LIMIT)
-			return NULL;
-	} else {
-		/* vpop_user must be zero-filled or parse_email() leaves an
-		   extra character after the user name. we'll fill vpop_domain
-		   as well just to be sure... */
-		memset(vpop_user, '\0', VPOPMAIL_LIMIT);
-		memset(vpop_domain, '\0', VPOPMAIL_LIMIT);
+	/* vpop_user must be zero-filled or parse_email() leaves an
+	   extra character after the user name. we'll fill vpop_domain
+	   as well just to be sure... */
+	memset(vpop_user, '\0', VPOPMAIL_LIMIT);
+	memset(vpop_domain, '\0', VPOPMAIL_LIMIT);
 
-		if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain,
-				VPOPMAIL_LIMIT-1) < 0) {
-			if (verbose) {
-				i_info("vpopmail(%s): parse_email() failed",
-				       user);
-			}
-			return NULL;
+	if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain,
+			VPOPMAIL_LIMIT-1) < 0) {
+		if (verbose) {
+			i_info("vpopmail(%s): parse_email() failed",
+			       user);
 		}
+		return NULL;
 	}
 
 	vpw = vauth_getpw(vpop_user, vpop_domain);
@@ -50,8 +44,8 @@
 
 #ifdef USERDB_VPOPMAIL
 
-static void vpopmail_lookup(const char *user, const char *realm,
-			    userdb_callback_t *callback, void *context)
+static void vpopmail_lookup(const char *user, userdb_callback_t *callback,
+			    void *context)
 {
 	char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
 	struct vqpasswd *vpw;
@@ -60,10 +54,7 @@
 	gid_t gid;
 	pool_t pool;
 
-	if (realm != NULL)
-		user = t_strconcat(user, "@", realm, NULL);
-
-	vpw = vpopmail_lookup_vqp(user, realm, vpop_user, vpop_domain);
+	vpw = vpopmail_lookup_vqp(user, vpop_user, vpop_domain);
 	if (vpw == NULL) {
 		callback(NULL, context);
 		return;

Index: userdb-vpopmail.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb-vpopmail.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- userdb-vpopmail.h	27 Jan 2003 01:33:40 -0000	1.1
+++ userdb-vpopmail.h	18 Feb 2003 19:11:26 -0000	1.2
@@ -10,7 +10,7 @@
    overflows. */
 #define VPOPMAIL_LIMIT 81
 
-struct vqpasswd *vpopmail_lookup_vqp(const char *user, const char *realm,
+struct vqpasswd *vpopmail_lookup_vqp(const char *user,
 				     char vpop_user[VPOPMAIL_LIMIT],
 				     char vpop_domain[VPOPMAIL_LIMIT]);
 

Index: userdb.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/userdb.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- userdb.h	2 Feb 2003 00:08:28 -0000	1.4
+++ userdb.h	18 Feb 2003 19:11:26 -0000	1.5
@@ -19,8 +19,8 @@
 	void (*init)(const char *args);
 	void (*deinit)(void);
 
-	void (*lookup)(const char *user, const char *realm,
-		       userdb_callback_t *callback, void *context);
+	void (*lookup)(const char *user, userdb_callback_t *callback,
+		       void *context);
 };
 
 extern struct userdb_module *userdb;




More information about the dovecot-cvs mailing list