[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