[dovecot-cvs] dovecot/src/auth Makefile.am, 1.25, 1.26 main.c, 1.24, 1.25 password-scheme.c, 1.7, 1.8 password-scheme.h, 1.2, 1.3

cras at procontrol.fi cras at procontrol.fi
Sun May 30 06:57:17 EEST 2004


Update of /home/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv21174/auth

Modified Files:
	Makefile.am main.c password-scheme.c password-scheme.h 
Log Message:
Added support for password scheme plugins. auth module dir defaults under
module_dir now.



Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/auth/Makefile.am,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- a/Makefile.am	29 May 2004 21:40:30 -0000	1.25
+++ b/Makefile.am	30 May 2004 03:57:15 -0000	1.26
@@ -5,7 +5,7 @@
 INCLUDES = \
 	-I$(top_srcdir)/src/lib \
 	-I$(top_srcdir)/src/lib-settings \
-	-DAUTH_MODULE_DIR=\""$(libdir)/dovecot/auth"\" \
+	-DAUTH_MODULE_DIR=\""$(moduledir)/auth"\" \
 	$(AUTH_CFLAGS)
 
 dovecot_auth_LDADD = \

Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/main.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- a/main.c	29 May 2004 21:40:30 -0000	1.24
+++ b/main.c	30 May 2004 03:57:15 -0000	1.25
@@ -11,6 +11,7 @@
 #include "mech.h"
 #include "userdb.h"
 #include "passdb.h"
+#include "password-scheme.h"
 #include "auth-master-connection.h"
 #include "auth-client-connection.h"
 
@@ -93,6 +94,7 @@
 	mech_init();
 	userdb_init();
 	passdb_init();
+        password_schemes_init();
 
 	masters_buf = buffer_create_dynamic(default_pool, 64, (size_t)-1);
 
@@ -161,6 +163,7 @@
 		auth_master_connection_free(master[i]);
 	}
 
+        password_schemes_deinit();
 	passdb_deinit();
 	userdb_deinit();
 	mech_deinit();

Index: password-scheme.c
===================================================================
RCS file: /home/cvs/dovecot/src/auth/password-scheme.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- a/password-scheme.c	30 May 2004 02:21:53 -0000	1.7
+++ b/password-scheme.c	30 May 2004 03:57:15 -0000	1.8
@@ -1,9 +1,11 @@
 /* Copyright (C) 2003 Timo Sirainen */
 
 #include "lib.h"
+#include "buffer.h"
 #include "base64.h"
 #include "hex-binary.h"
 #include "md5.h"
+#include "module-dir.h"
 #include "mycrypt.h"
 #include "randgen.h"
 #include "str.h"
@@ -16,61 +18,23 @@
 static const char *salt_chars =
 	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
+static buffer_t *schemes_buf;
+static const struct password_scheme *schemes;
+#ifdef HAVE_MODULES
+static struct module *scheme_modules;
+#endif
+
 int password_verify(const char *plaintext, const char *password,
 		    const char *scheme, const char *user)
 {
-	unsigned char md5_digest[16];
-	const char *realm, *str;
+	const struct password_scheme *s;
 
 	if (password == NULL)
 		return 0;
 
-	if (strcasecmp(scheme, "CRYPT") == 0)
-		return strcmp(mycrypt(plaintext, password), password) == 0;
-
-	if (strcasecmp(scheme, "MD5") == 0) {
-                str = password_generate_md5_crypt(plaintext, password);
-		return strcmp(str, password) == 0;
-	}
-#ifdef HAVE_OPENSSL_SHA1
-	if (strcasecmp(scheme, "SHA") == 0 ||
-	    strcasecmp(scheme, "SHA1") == 0) {
-		unsigned char sha1_digest[SHA_DIGEST_LENGTH];
-		string_t *str;
-
-		SHA1(plaintext, strlen(plaintext), sha1_digest);
-
-		str = t_str_new(64);
-		base64_encode(sha1_digest, sizeof(sha1_digest), str);
-		return strcasecmp(str_c(str), password) == 0;
-	}
-#endif
-
-	if (strcasecmp(scheme, "PLAIN") == 0)
-		return strcmp(password, plaintext) == 0;
-
-	if (strcasecmp(scheme, "HMAC-MD5") == 0) {
-		str = password_generate_cram_md5(plaintext);
-		return strcmp(str, password) == 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), md5_digest);
-		str = binary_to_hex(md5_digest, sizeof(md5_digest));
-
-		return strcasecmp(str, password) == 0;
-	}
-
-	if (strcasecmp(scheme, "PLAIN-MD5") == 0) {
-		md5_get_digest(plaintext, strlen(plaintext), md5_digest);
-		str = binary_to_hex(md5_digest, sizeof(md5_digest));
-		return strcasecmp(str, password) == 0;
+	for (s = schemes; s->name != NULL; s++) {
+		if (strcasecmp(s->name, scheme) == 0)
+			return s->password_verify(plaintext, password, user);
 	}
 
 	return -1;
@@ -110,48 +74,197 @@
 const char *password_generate(const char *plaintext, const char *user,
 			      const char *scheme)
 {
-	const char *realm, *str;
-	unsigned char digest[16];
+	const struct password_scheme *s;
+
+	for (s = schemes; s->name != NULL; s++) {
+		if (strcasecmp(s->name, scheme) == 0)
+			return s->password_generate(plaintext, user);
+	}
+
+	return NULL;
+}
+
+static int crypt_verify(const char *plaintext, const char *password,
+			const char *user __attr_unused__)
+{
+	return strcmp(mycrypt(plaintext, password), password) == 0;
+}
+
+static const char *crypt_generate(const char *plaintext,
+				  const char *user __attr_unused__)
+{
+	char salt[9];
+
+	random_fill(salt, 2);
+	salt[0] = salt_chars[salt[0] % (sizeof(salt_chars)-1)];
+	salt[1] = salt_chars[salt[1] % (sizeof(salt_chars)-1)];
+	salt[2] = '\0';
+	return t_strdup(mycrypt(plaintext, salt));
+}
+
+static int md5_verify(const char *plaintext, const char *password,
+		      const char *user __attr_unused__)
+{
+	const char *str;
+
+	str = password_generate_md5_crypt(plaintext, password);
+	return strcmp(str, password) == 0;
+}
+
+static const char *md5_generate(const char *plaintext,
+				const char *user __attr_unused__)
+{
 	char salt[9];
 	int i;
 
-	if (strcasecmp(scheme, "CRYPT") == 0) {
-		random_fill(salt, 2);
-		salt[0] = salt_chars[salt[0] % (sizeof(salt_chars)-1)];
-		salt[1] = salt_chars[salt[1] % (sizeof(salt_chars)-1)];
-		salt[2] = '\0';
-		return t_strdup(mycrypt(plaintext, salt));
-	}
+	random_fill(salt, 8);
+	for (i = 0; i < 8; i++)
+		salt[i] = salt_chars[salt[i] % (sizeof(salt_chars)-1)];
+	salt[8] = '\0';
+	return password_generate_md5_crypt(plaintext, salt);
+}
 
-	if (strcasecmp(scheme, "MD5") == 0) {
-		random_fill(salt, 8);
-		for (i = 0; i < 8; i++)
-			salt[i] = salt_chars[salt[i] % (sizeof(salt_chars)-1)];
-		salt[8] = '\0';
-		return password_generate_md5_crypt(plaintext, salt);
-	}
+#ifdef HAVE_OPENSSL_SHA1
+static int sha_verify(const char *plaintext, const char *password,
+		      const char *user __attr_unused__)
+{
+	unsigned char digest[SHA_DIGEST_LENGTH];
+	string_t *str;
 
-	if (strcasecmp(scheme, "PLAIN") == 0)
-		return plaintext;
+	SHA1(plaintext, strlen(plaintext), digest);
 
-	if (strcasecmp(scheme, "HMAC-MD5") == 0)
-		return password_generate_cram_md5(plaintext);
+	str = t_str_new(64);
+	base64_encode(digest, sizeof(digest), str);
+	return strcasecmp(str_c(str), password) == 0;
+}
+#endif
 
-	if (strcasecmp(scheme, "DIGEST-MD5") == 0) {
-		/* user:realm:passwd */
-		realm = strchr(user, '@');
-		if (realm != NULL) realm++; else realm = "";
+static int plain_verify(const char *plaintext, const char *password,
+			const char *user __attr_unused__)
+{
+	return strcmp(password, plaintext) == 0;
+}
 
-		str = t_strconcat(t_strcut(user, '@'), ":", realm,  ":",
-				  plaintext, NULL);
-		md5_get_digest(str, strlen(str), digest);
-		return binary_to_hex(digest, sizeof(digest));
-	}
+static const char *plain_generate(const char *plaintext,
+				  const char *user __attr_unused__)
+{
+	return plaintext;
+}
 
-	if (strcasecmp(scheme, "PLAIN-MD5") == 0) {
-		md5_get_digest(plaintext, strlen(plaintext), digest);
-		return binary_to_hex(digest, sizeof(digest));
+static int hmac_md5_verify(const char *plaintext, const char *password,
+			   const char *user __attr_unused__)
+{
+	return strcmp(password_generate_cram_md5(plaintext), password) == 0;
+}
+
+static const char *hmac_md5_generate(const char *plaintext,
+				     const char *user __attr_unused__)
+{
+	return password_generate_cram_md5(plaintext);
+}
+
+static int digest_md5_verify(const char *plaintext, const char *password,
+			     const char *user)
+{
+	unsigned char digest[16];
+	const char *realm, *str;
+
+	/* 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;
+}
+
+static const char *digest_md5_generate(const char *plaintext, const char *user)
+{
+	const char *realm, *str;
+	unsigned char digest[16];
+
+	/* 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);
+	return binary_to_hex(digest, sizeof(digest));
+}
+
+static int plain_md5_verify(const char *plaintext, const char *password,
+			    const char *user __attr_unused__)
+{
+	unsigned char digest[16];
+	const char *str;
+
+	md5_get_digest(plaintext, strlen(plaintext), digest);
+	str = binary_to_hex(digest, sizeof(digest));
+	return strcasecmp(str, password) == 0;
+}
+
+static const char *plain_md5_generate(const char *plaintext,
+				      const char *user __attr_unused__)
+{
+	unsigned char digest[16];
+
+	md5_get_digest(plaintext, strlen(plaintext), digest);
+	return binary_to_hex(digest, sizeof(digest));
+}
+
+static const struct password_scheme default_schemes[] = {
+	{ "CRYPT", crypt_verify, crypt_generate },
+	{ "MD5", md5_verify, md5_generate },
+#ifdef HAVE_OPENSSL_SHA1
+	{ "SHA", sha_verify, NULL },
+	{ "SHA1", sha_verify, NULL },
+#endif
+	{ "PLAIN", plain_verify, plain_generate },
+	{ "HMAC-MD5", hmac_md5_verify, hmac_md5_generate },
+	{ "DIGEST-MD5", digest_md5_verify, digest_md5_generate },
+	{ "PLAIN-MD5", plain_md5_verify, plain_md5_generate },
+	{ NULL, NULL, NULL }
+};
+
+void password_schemes_init(void)
+{
+	static const struct password_scheme null_scheme = { NULL, NULL, NULL };
+	const struct password_scheme *s;
+#ifdef HAVE_MODULES
+	struct module *mod;
+	const char *symbol;
+#endif
+
+	schemes_buf = buffer_create_dynamic(default_pool, 128, (size_t)-1);
+	for (s = default_schemes; s->name != NULL; s++)
+		buffer_append(schemes_buf, s, sizeof(*s));
+
+#ifdef HAVE_MODULES
+	scheme_modules = module_dir_load(AUTH_MODULE_DIR"/password", FALSE);
+	for (mod = scheme_modules; mod != NULL; mod = mod->next) {
+		t_push();
+		symbol = t_strconcat(mod->name, "_scheme", NULL);
+		s = module_get_symbol(mod, symbol);
+		if (s != NULL)
+			buffer_append(schemes_buf, s, sizeof(*s));
+		t_pop();
 	}
+#endif
 
-	return NULL;
+	buffer_append(schemes_buf, &null_scheme, sizeof(null_scheme));
+	schemes = buffer_get_data(schemes_buf, NULL);
+}
+
+void password_schemes_deinit(void)
+{
+#ifdef HAVE_MODULES
+	module_dir_unload(scheme_modules);
+#endif
+
+	buffer_free(schemes_buf);
+	schemes = NULL;
 }

Index: password-scheme.h
===================================================================
RCS file: /home/cvs/dovecot/src/auth/password-scheme.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/password-scheme.h	10 Nov 2003 20:36:02 -0000	1.2
+++ b/password-scheme.h	30 May 2004 03:57:15 -0000	1.3
@@ -1,6 +1,15 @@
 #ifndef __PASSWORD_SCHEME_H
 #define __PASSWORD_SCHEME_H
 
+struct password_scheme {
+	const char *name;
+
+	int (*password_verify)(const char *plaintext, const char *password,
+			       const char *user);
+	const char *(*password_generate)(const char *plaintext,
+					 const char *user);
+};
+
 /* 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);
@@ -12,6 +21,9 @@
 const char *password_generate(const char *plaintext, const char *user,
 			      const char *scheme);
 
+void password_schemes_init(void);
+void password_schemes_deinit(void);
+
 /* INTERNAL: */
 const char *password_generate_md5_crypt(const char *pw, const char *salt);
 const char *password_generate_cram_md5(const char *pw);



More information about the dovecot-cvs mailing list