[Dovecot] [PATCH, RFC 3/13] OTP: parity table
Add OTP parity table.
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-parity.c dovecot/src/lib-otp/otp-parity.c
--- dovecot.vanilla/src/lib-otp/otp-parity.c 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/lib-otp/otp-parity.c 2006-06-23 13:44:31.161891112 +0400
@@ -0,0 +1,29 @@
+/*
+ * OTP parity table.
+ *
+ * Copyright (c) 2006 Andrey Panin
Parser for OTP extended response as defined by RFC 2243.
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-parse.c dovecot/src/lib-otp/otp-parse.c
--- dovecot.vanilla/src/lib-otp/otp-parse.c 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/lib-otp/otp-parse.c 2006-06-23 13:44:31.213883208 +0400
@@ -0,0 +1,254 @@
+/*
+ * OTP extended response parser.
+ *
+ * Copyright (c) 2006 Andrey Panin
Finally add lib-otp to the build process. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/configure.in dovecot/configure.in --- dovecot.vanilla/configure.in 2006-06-23 13:42:22.158502608 +0400 +++ dovecot/configure.in 2006-06-23 13:44:31.276873632 +0400 @@ -1742,6 +1742,7 @@ src/lib-imap/Makefile src/lib-index/Makefile src/lib-mail/Makefile src/lib-ntlm/Makefile +src/lib-otp/Makefile src/lib-settings/Makefile src/lib-storage/Makefile src/lib-storage/index/Makefile diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/Makefile.am dovecot/src/lib-otp/Makefile.am --- dovecot.vanilla/src/lib-otp/Makefile.am 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/Makefile.am 2006-06-23 13:44:31.276873632 +0400 @@ -0,0 +1,16 @@ +noinst_LIBRARIES = libotp.a + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib + +libotp_a_SOURCES = \ + otp-dictionary.c \ + otp-hash.c \ + otp-parity.c \ + otp-parse.c + +noinst_HEADERS = \ + otp-dictionary.h \ + otp-hash.h \ + otp-parity.h \ + otp-parse.h diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp.h dovecot/src/lib-otp/otp.h --- dovecot.vanilla/src/lib-otp/otp.h 1970-01-01 03:00:00.000000000 +0300 +++ dovecot/src/lib-otp/otp.h 2006-06-23 13:44:31.277873480 +0400 @@ -0,0 +1,22 @@ +#ifndef __OTP_H__ +#define __OTP_H__ + +#define OTP_MAX_SEED_LEN 16 +#define OTP_MAX_WORD_LEN 4 +#define OTP_WORDS_NUMBER 6 + +#define OTP_HASH_SIZE 8 + +struct otp_state { + int algo; + int seq; + unsigned char hash[OTP_HASH_SIZE]; + char seed[OTP_MAX_SEED_LEN + 1]; +}; + +#include "otp-hash.h" +#include "otp-dictionary.h" +#include "otp-parity.h" +#include "otp-parse.h" + +#endif /* __OTP_H__ */ diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/Makefile.am dovecot/src/Makefile.am --- dovecot.vanilla/src/Makefile.am 2006-06-23 13:42:22.126507472 +0400 +++ dovecot/src/Makefile.am 2006-06-23 13:44:31.277873480 +0400 @@ -11,6 +11,7 @@ SUBDIRS = \ lib-dict \ lib-sql \ lib-ntlm \ + lib-otp \ lib-settings \ lib-charset \ lib-mail \
Add OTP and SKEY password schemes. SKEY is the same as OTP but uses
MD4 algorithm always.
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/Makefile.am dovecot/src/auth/Makefile.am
--- dovecot.vanilla/src/auth/Makefile.am 2006-06-23 13:42:22.122508080 +0400
+++ dovecot/src/auth/Makefile.am 2006-06-23 13:44:31.340863904 +0400
@@ -9,6 +9,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib-sql \
-I$(top_srcdir)/src/lib-settings \
-I$(top_srcdir)/src/lib-ntlm \
+ -I$(top_srcdir)/src/lib-otp \
-DAUTH_MODULE_DIR=\""$(moduledir)/auth"\" \
-DPKG_LIBEXECDIR=\""$(pkglibexecdir)"\" \
$(AUTH_CFLAGS)
@@ -21,12 +22,14 @@ libpassword_a_SOURCES = \
password-scheme-md5crypt.c \
password-scheme-cram-md5.c \
password-scheme-ntlm.c \
+ password-scheme-otp.c \
password-scheme-rpa.c
dovecot_auth_LDADD = \
libpassword.a \
../lib-settings/libsettings.a \
../lib-ntlm/libntlm.a \
+ ../lib-otp/libotp.a \
../lib-sql/libsql.a \
../lib/liblib.a \
$(AUTH_LIBS) \
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/passdb.c dovecot/src/auth/passdb.c
--- dovecot.vanilla/src/auth/passdb.c 2006-06-23 13:42:22.124507776 +0400
+++ dovecot/src/auth/passdb.c 2006-06-23 13:44:31.340863904 +0400
@@ -67,6 +67,10 @@ passdb_credentials_to_str(enum passdb_cr
return "LANMAN";
case PASSDB_CREDENTIALS_NTLM:
return "NTLM";
+ case PASSDB_CREDENTIALS_OTP:
+ return "OTP";
+ case PASSDB_CREDENTIALS_SKEY:
+ return "SKEY";
case PASSDB_CREDENTIALS_RPA:
return "RPA";
}
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/passdb.h dovecot/src/auth/passdb.h
--- dovecot.vanilla/src/auth/passdb.h 2006-06-23 13:42:22.124507776 +0400
+++ dovecot/src/auth/passdb.h 2006-06-23 13:44:31.340863904 +0400
@@ -15,6 +15,8 @@ enum passdb_credentials {
PASSDB_CREDENTIALS_DIGEST_MD5,
PASSDB_CREDENTIALS_LANMAN,
PASSDB_CREDENTIALS_NTLM,
+ PASSDB_CREDENTIALS_OTP,
+ PASSDB_CREDENTIALS_SKEY,
PASSDB_CREDENTIALS_RPA
};
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/password-scheme.c dovecot/src/auth/password-scheme.c
--- dovecot.vanilla/src/auth/password-scheme.c 2006-06-23 13:42:22.125507624 +0400
+++ dovecot/src/auth/password-scheme.c 2006-06-23 13:44:31.340863904 +0400
@@ -10,6 +10,7 @@
#include "mycrypt.h"
#include "randgen.h"
#include "sha1.h"
+#include "otp.h"
#include "str.h"
#include "password-scheme.h"
@@ -450,6 +451,25 @@ static const char *ntlm_generate(const c
return password_generate_ntlm(plaintext);
}
+static bool otp_verify(const char *plaintext, const char *password,
+ const char *user __attr_unused__)
+{
+ return strcasecmp(password,
+ password_generate_otp(plaintext, password, -1)) == 0;
+}
+
+static const char *otp_generate(const char *plaintext,
+ const char *user __attr_unused__)
+{
+ return password_generate_otp(plaintext, NULL, OTP_HASH_SHA1);
+}
+
+static const char *skey_generate(const char *plaintext,
+ const char *user __attr_unused__)
+{
+ return password_generate_otp(plaintext, NULL, OTP_HASH_MD4);
+}
+
static bool rpa_verify(const char *plaintext, const char *password,
const char *user __attr_unused__)
{
@@ -478,6 +498,8 @@ static const struct password_scheme defa
{ "LDAP-MD5", ldap_md5_verify, ldap_md5_generate },
{ "LANMAN", lm_verify, lm_generate },
{ "NTLM", ntlm_verify, ntlm_generate },
+ { "OTP", otp_verify, otp_generate },
+ { "SKEY", otp_verify, skey_generate },
{ "RPA", rpa_verify, rpa_generate },
{ NULL, NULL, NULL }
};
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/password-scheme.h dovecot/src/auth/password-scheme.h
--- dovecot.vanilla/src/auth/password-scheme.h 2006-06-23 13:42:22.125507624 +0400
+++ dovecot/src/auth/password-scheme.h 2006-06-23 13:44:31.340863904 +0400
@@ -32,6 +32,7 @@ const char *password_generate_md5_crypt(
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);
+const char *password_generate_otp(const char *pw, const char *state, int algo);
const char *password_generate_rpa(const char *pw);
#endif
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/password-scheme-otp.c dovecot/src/auth/password-scheme-otp.c
--- dovecot.vanilla/src/auth/password-scheme-otp.c 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/auth/password-scheme-otp.c 2006-06-23 13:44:31.341863752 +0400
@@ -0,0 +1,39 @@
+/*
+ * OTP password scheme.
+ *
+ * Copyright (c) 2006 Andrey Panin
Add auth_request_set_credentials() function. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/auth-request.c dovecot/src/auth/auth-request.c --- dovecot.vanilla/src/auth/auth-request.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/auth-request.c 2006-06-23 13:44:31.427850680 +0400 @@ -508,6 +508,37 @@ void auth_request_lookup_credentials(str } } +void auth_request_set_credentials(struct auth_request *request, + enum passdb_credentials credentials, + const char *data, + set_credentials_callback_t *callback) +{ + struct passdb_module *passdb = request->passdb->passdb; + const char *cache_key, *new_credentials; + + i_assert(credentials == PASSDB_CREDENTIALS_OTP); + + cache_key = passdb_cache == NULL ? NULL : passdb->cache_key; + if (cache_key != NULL) { + auth_cache_remove(passdb_cache, request, cache_key); + } + + request->private_callback.set_credentials = callback; + + new_credentials = t_strconcat("{", + passdb_credentials_to_str(credentials), "}", data, NULL); + + if (passdb->blocking) { + passdb_blocking_set_credentials(request, new_credentials); + } else if (passdb->iface.set_credentials != NULL) { + passdb->iface.set_credentials(request, new_credentials, + callback); + } else { + /* this passdb doesn't support credentials update */ + callback(PASSDB_RESULT_INTERNAL_FAILURE, request); + } +} + void auth_request_userdb_callback(struct auth_stream_reply *reply, struct auth_request *request) { diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/auth-request.h dovecot/src/auth/auth-request.h --- dovecot.vanilla/src/auth/auth-request.h 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/auth-request.h 2006-06-23 13:44:31.427850680 +0400 @@ -59,6 +59,7 @@ struct auth_request { union { verify_plain_callback_t *verify_plain; lookup_credentials_callback_t *lookup_credentials; + set_credentials_callback_t *set_credentials; userdb_callback_t *userdb; } private_callback; enum passdb_credentials credentials; @@ -149,6 +150,10 @@ void auth_request_verify_plain_callback( void auth_request_lookup_credentials_callback(enum passdb_result result, const char *credentials, struct auth_request *request); +void auth_request_set_credentials(struct auth_request *request, + enum passdb_credentials credentials, + const char *data, + set_credentials_callback_t *callback); void auth_request_userdb_callback(struct auth_stream_reply *reply, struct auth_request *request); diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/passdb.h dovecot/src/auth/passdb.h --- dovecot.vanilla/src/auth/passdb.h 2006-06-23 13:44:31.413852808 +0400 +++ dovecot/src/auth/passdb.h 2006-06-23 13:44:31.427850680 +0400 @@ -37,6 +37,8 @@ typedef void verify_plain_callback_t(enu typedef void lookup_credentials_callback_t(enum passdb_result result, const char *password, struct auth_request *request); +typedef void set_credentials_callback_t(enum passdb_result result, + struct auth_request *request); struct passdb_module_interface { const char *name; @@ -54,6 +56,11 @@ struct passdb_module_interface { auth_request->credentials. */ void (*lookup_credentials)(struct auth_request *request, lookup_credentials_callback_t *callback); + + /* Update credentials */ + int (*set_credentials)(struct auth_request *request, + const char *new_credentials, + set_credentials_callback_t *callback); }; struct passdb_module {
Add set_credentials method to sql passdb. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/db-sql.c dovecot/src/auth/db-sql.c --- dovecot.vanilla/src/auth/db-sql.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/db-sql.c 2006-06-23 13:44:31.480842624 +0400 @@ -18,6 +18,7 @@ static struct setting_def setting_defs[] DEF(SET_STR, connect), DEF(SET_STR, password_query), DEF(SET_STR, user_query), + DEF(SET_STR, update_query), DEF(SET_STR, default_pass_scheme), { 0, NULL, 0 } @@ -28,6 +29,7 @@ struct sql_settings default_sql_settings MEMBER(connect) NULL, MEMBER(password_query) "SELECT password FROM users WHERE userid = '%u'", MEMBER(user_query) "SELECT home, uid, gid FROM users WHERE userid = '%u'", + MEMBER(update_query) "UPDATE users SET password = '%c' WHERE userid = '%u'", MEMBER(default_pass_scheme) "PLAIN-MD5" }; diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/db-sql.h dovecot/src/auth/db-sql.h --- dovecot.vanilla/src/auth/db-sql.h 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/db-sql.h 2006-06-23 13:44:31.481842472 +0400 @@ -8,6 +8,7 @@ struct sql_settings { const char *connect; const char *password_query; const char *user_query; + const char *update_query; const char *default_pass_scheme; }; diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/passdb-sql.c dovecot/src/auth/passdb-sql.c --- dovecot.vanilla/src/auth/passdb-sql.c 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/passdb-sql.c 2006-06-23 13:44:31.481842472 +0400 @@ -6,7 +6,9 @@ #include "str.h" #include "strescape.h" +#include "buffer.h" #include "var-expand.h" +#include "safe-memset.h" #include "password-scheme.h" #include "auth-cache.h" #include "db-sql.h" @@ -26,6 +28,7 @@ struct passdb_sql_request { union { verify_plain_callback_t *verify_plain; lookup_credentials_callback_t *lookup_credentials; + set_credentials_callback_t *set_credentials; } callback; }; @@ -175,6 +178,57 @@ static void sql_lookup_credentials(struc sql_lookup_pass(sql_request); } +static int sql_set_credentials(struct auth_request *request, + const char *new_credentials, + set_credentials_callback_t *callback) +{ + struct sql_passdb_module *module = + (struct sql_passdb_module *) request->passdb->passdb; + struct sql_transaction_context *transaction; + const struct var_expand_table *tab; + struct var_expand_table tmp; + const char *error; + string_t *query; + buffer_t *buf; + int ret; + + t_push(); + + buf = buffer_create_dynamic(unsafe_data_stack_pool, 128); + + tmp.key = 'c'; + tmp.value = new_credentials; + buffer_append(buf, &tmp, sizeof(tmp)); + + tab = auth_request_get_var_expand_table(request, passdb_sql_escape); + do { + buffer_append(buf, tab++, sizeof(*tab)); + } while (tab->key != '\0'); + + tab = buffer_free_without_data(buf); + + query = t_str_new(512); + var_expand(query, module->conn->set.update_query, tab); + + transaction = sql_transaction_begin(module->conn->db); + + sql_update(transaction, str_c(query)); + + ret = sql_transaction_commit_s(&transaction, &error); + + callback(ret == 0 ? PASSDB_RESULT_OK : PASSDB_RESULT_INTERNAL_FAILURE, + request); + + if (ret < 0) + i_info("SQL error: %s", error); + + safe_memset(str_c_modifyable(query), 0, str_len(query)); + + t_pop(); + + return 0; +} + static struct passdb_module * passdb_sql_preinit(struct auth_passdb *auth_passdb, const char *args) { @@ -221,7 +275,8 @@ struct passdb_module_interface passdb_sq passdb_sql_deinit, sql_verify_plain, - sql_lookup_credentials + sql_lookup_credentials, + sql_set_credentials, }; #endif
Add set_credentials support to blocking passdb support code. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/auth-worker-client.c dovecot/src/auth/auth-worker-client.c --- dovecot.vanilla/src/auth/auth-worker-client.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/auth-worker-client.c 2006-06-23 13:44:31.543833048 +0400 @@ -228,6 +228,72 @@ auth_worker_handle_passl(struct auth_wor } static void +set_credentials_callback(enum passdb_result result, + struct auth_request *request) +{ + struct auth_worker_client *client = request->context; + + string_t *str; + + str = t_str_new(64); + str_printfa(str, "%u\t", request->id); + + if (result != PASSDB_RESULT_OK) + str_printfa(str, "FAIL\t%d\t", result); + else { + str_printfa(str, "OK\t%s\t", request->user); + } + str_append_c(str, '\n'); + o_stream_send(client->output, str_data(str), str_len(str)); + + auth_request_unref(&request); + auth_worker_client_check_throttle(client); + auth_worker_client_unref(&client); +} + +static void +auth_worker_handle_passs(struct auth_worker_client *client, + unsigned int id, const char *args) +{ + struct auth_request *auth_request; + unsigned int passdb_id; + const char *data; + + passdb_id = atoi(t_strcut(args, '\t')); + args = strchr(args, '\t'); + if (args == NULL) { + i_error("BUG: Auth worker server sent us invalid PASSS"); + return; + } + args++; + + data = t_strcut(args, '\t'); + args = strchr(args, '\t'); + if (args != NULL) args++; + + auth_request = worker_auth_request_new(client, id, args); + + if (auth_request->user == NULL || auth_request->service == NULL) { + i_error("BUG: PASSS had missing parameters"); + auth_request_unref(&auth_request); + return; + } + + while (auth_request->passdb->id != passdb_id) { + auth_request->passdb = auth_request->passdb->next; + if (auth_request->passdb == NULL) { + i_error("BUG: PASSS had invalid passdb ID"); + auth_request_unref(&auth_request); + return; + } + } + + auth_request->passdb->passdb->iface. + set_credentials(auth_request, + data, set_credentials_callback); +} + +static void lookup_user_callback(struct auth_stream_reply *reply, struct auth_request *auth_request) { @@ -297,6 +363,8 @@ auth_worker_handle_line(struct auth_work auth_worker_handle_passv(client, id, line + 6); else if (strncmp(line, "PASSL\t", 6) == 0) auth_worker_handle_passl(client, id, line + 6); + else if (strncmp(line, "PASSS\t", 6) == 0) + auth_worker_handle_passs(client, id, line + 6); else if (strncmp(line, "USER\t", 5) == 0) auth_worker_handle_user(client, id, line + 5); diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/passdb-blocking.c dovecot/src/auth/passdb-blocking.c --- dovecot.vanilla/src/auth/passdb-blocking.c 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/passdb-blocking.c 2006-06-23 13:44:31.543833048 +0400 @@ -157,3 +157,24 @@ void passdb_blocking_lookup_credentials( auth_worker_call(request, str_c(str), lookup_credentials_callback); } + +static void +set_credentials_callback(struct auth_request *request, const char *reply) +{ + enum passdb_result result = check_failure(request, &reply); + + request->private_callback.set_credentials(result, request); +} + +void passdb_blocking_set_credentials(struct auth_request *request, + const char *new_credentials) +{ + string_t *str; + + str = t_str_new(64); + str_printfa(str, "PASSS\t%u\t%s\t", + request->passdb->id, new_credentials); + auth_request_export(request, str); + + auth_worker_call(request, str_c(str), set_credentials_callback); +} diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/passdb-blocking.h dovecot/src/auth/passdb-blocking.h --- dovecot.vanilla/src/auth/passdb-blocking.h 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/passdb-blocking.h 2006-06-23 13:44:31.544832896 +0400 @@ -3,5 +3,7 @@ void passdb_blocking_verify_plain(struct auth_request *request); void passdb_blocking_lookup_credentials(struct auth_request *request); +void passdb_blocking_set_credentials(struct auth_request *request, + const char *new_credentials); #endif
Add passdb_need_set_credentials flag into mech_module structure to mark authentication mechanisms which need credentials update to work properly. diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/auth.c dovecot/src/auth/auth.c --- dovecot.vanilla/src/auth/auth.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/auth.c 2006-06-23 13:44:31.606823472 +0400 @@ -143,6 +143,17 @@ static bool auth_passdb_list_have_creden return FALSE; } +static int auth_passdb_list_have_set_credentials(struct auth *auth) +{ + struct auth_passdb *passdb; + + for (passdb = auth->passdbs; passdb != NULL; passdb = passdb->next) { + if (passdb->passdb->iface.set_credentials != NULL) + return TRUE; + } + return FALSE; +} + static void auth_mech_list_verify_passdb(struct auth *auth) { struct mech_module_list *list; @@ -154,6 +165,9 @@ static void auth_mech_list_verify_passdb if (list->module.passdb_need_credentials && !auth_passdb_list_have_credentials(auth)) break; + if (list->module.passdb_need_set_credentials && + !auth_passdb_list_have_set_credentials(auth)) + break; } if (list != NULL) { diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-anonymous.c dovecot/src/auth/mech-anonymous.c --- dovecot.vanilla/src/auth/mech-anonymous.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/mech-anonymous.c 2006-06-23 13:44:31.606823472 +0400 @@ -41,6 +41,7 @@ struct mech_module mech_anonymous = { MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_anonymous_auth_new, mech_generic_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-apop.c dovecot/src/auth/mech-apop.c --- dovecot.vanilla/src/auth/mech-apop.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/mech-apop.c 2006-06-23 13:44:31.607823320 +0400 @@ -156,6 +156,7 @@ const struct mech_module mech_apop = { MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_apop_auth_new, mech_apop_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-cram-md5.c dovecot/src/auth/mech-cram-md5.c --- dovecot.vanilla/src/auth/mech-cram-md5.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/mech-cram-md5.c 2006-06-23 13:44:31.607823320 +0400 @@ -188,6 +188,7 @@ struct mech_module mech_cram_md5 = { MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_cram_md5_auth_new, mech_cram_md5_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-digest-md5.c dovecot/src/auth/mech-digest-md5.c --- dovecot.vanilla/src/auth/mech-digest-md5.c 2006-06-23 13:42:22.123507928 +0400 +++ dovecot/src/auth/mech-digest-md5.c 2006-06-23 13:44:31.607823320 +0400 @@ -618,6 +618,7 @@ struct mech_module mech_digest_md5 = { MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_digest_md5_auth_new, mech_digest_md5_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-gssapi.c dovecot/src/auth/mech-gssapi.c --- dovecot.vanilla/src/auth/mech-gssapi.c 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/mech-gssapi.c 2006-06-23 13:44:31.607823320 +0400 @@ -393,6 +393,7 @@ const struct mech_module mech_gssapi = { MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_gssapi_auth_new, mech_gssapi_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech.h dovecot/src/auth/mech.h --- dovecot.vanilla/src/auth/mech.h 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/mech.h 2006-06-23 13:44:31.608823168 +0400 @@ -26,6 +26,7 @@ struct mech_module { enum mech_security_flags flags; unsigned int passdb_need_plain:1; unsigned int passdb_need_credentials:1; + unsigned int passdb_need_set_credentials:1; struct auth_request *(*auth_new)(void); void (*auth_initial)(struct auth_request *request, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-login.c dovecot/src/auth/mech-login.c --- dovecot.vanilla/src/auth/mech-login.c 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/mech-login.c 2006-06-23 13:44:31.608823168 +0400 @@ -84,6 +84,7 @@ const struct mech_module mech_login = { MEMBER(passdb_need_plain) TRUE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_login_auth_new, mech_login_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-ntlm.c dovecot/src/auth/mech-ntlm.c --- dovecot.vanilla/src/auth/mech-ntlm.c 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/mech-ntlm.c 2006-06-23 13:44:31.608823168 +0400 @@ -262,6 +262,7 @@ const struct mech_module mech_ntlm = { MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_ntlm_auth_new, mech_generic_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-plain.c dovecot/src/auth/mech-plain.c --- dovecot.vanilla/src/auth/mech-plain.c 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/mech-plain.c 2006-06-23 13:44:31.608823168 +0400 @@ -91,6 +91,7 @@ struct mech_module mech_plain = { MEMBER(passdb_need_plain) TRUE, MEMBER(passdb_need_credentials) FALSE, + MEMBER(passdb_need_set_credentials) FALSE, mech_plain_auth_new, mech_generic_auth_initial, diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-rpa.c dovecot/src/auth/mech-rpa.c --- dovecot.vanilla/src/auth/mech-rpa.c 2006-06-23 13:42:22.124507776 +0400 +++ dovecot/src/auth/mech-rpa.c 2006-06-23 13:44:31.608823168 +0400 @@ -601,6 +601,7 @@ const struct mech_module mech_rpa = { MEMBER(passdb_need_plain) FALSE, MEMBER(passdb_need_credentials) TRUE, + MEMBER(passdb_need_set_credentials) FALSE, mech_rpa_auth_new, mech_generic_auth_initial,
Add common code shared by both OTP and SKEY authentication mechanism.
otp_try_lock() and otp_unlock() functions are used to implement race
attack protection which is required by RFC 2289.
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/Makefile.am dovecot/src/auth/Makefile.am
--- dovecot.vanilla/src/auth/Makefile.am 2006-06-23 13:44:31.401854632 +0400
+++ dovecot/src/auth/Makefile.am 2006-06-23 13:44:31.711807512 +0400
@@ -62,6 +62,7 @@ dovecot_auth_SOURCES = \
mech-gssapi.c \
mech-rpa.c \
mech-apop.c \
+ otp-skey-common.c \
passdb.c \
passdb-blocking.c \
passdb-bsdauth.c \
@@ -104,6 +105,7 @@ noinst_HEADERS = \
common.h \
mech.h \
mycrypt.h \
+ otp-skey-common.h \
passdb.h \
passdb-blocking.h \
passdb-cache.h \
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/otp-skey-common.c dovecot/src/auth/otp-skey-common.c
--- dovecot.vanilla/src/auth/otp-skey-common.c 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/auth/otp-skey-common.c 2006-06-23 13:44:31.711807512 +0400
@@ -0,0 +1,64 @@
+/*
+ * Common code for OTP and SKEY authentication mechanisms.
+ *
+ * Copyright (c) 2006 Andrey Panin
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/Makefile.am dovecot/src/auth/Makefile.am
--- dovecot.vanilla/src/auth/Makefile.am 2006-06-23 13:44:31.762799760 +0400
+++ dovecot/src/auth/Makefile.am 2006-06-23 13:44:31.763799608 +0400
@@ -59,6 +59,7 @@ dovecot_auth_SOURCES = \
mech-cram-md5.c \
mech-digest-md5.c \
mech-ntlm.c \
+ mech-otp.c \
mech-gssapi.c \
mech-rpa.c \
mech-apop.c \
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech.c dovecot/src/auth/mech.c
--- dovecot.vanilla/src/auth/mech.c 2006-06-23 13:42:22.124507776 +0400
+++ dovecot/src/auth/mech.c 2006-06-23 13:44:31.764799456 +0400
@@ -68,6 +68,7 @@ extern struct mech_module mech_apop;
extern struct mech_module mech_cram_md5;
extern struct mech_module mech_digest_md5;
extern struct mech_module mech_ntlm;
+extern struct mech_module mech_otp;
extern struct mech_module mech_rpa;
extern struct mech_module mech_anonymous;
#ifdef HAVE_GSSAPI
@@ -82,6 +83,7 @@ void mech_init(void)
mech_register_module(&mech_cram_md5);
mech_register_module(&mech_digest_md5);
mech_register_module(&mech_ntlm);
+ mech_register_module(&mech_otp);
mech_register_module(&mech_rpa);
mech_register_module(&mech_anonymous);
#ifdef HAVE_GSSAPI
@@ -97,6 +99,7 @@ void mech_deinit(void)
mech_unregister_module(&mech_cram_md5);
mech_unregister_module(&mech_digest_md5);
mech_unregister_module(&mech_ntlm);
+ mech_unregister_module(&mech_otp);
mech_unregister_module(&mech_rpa);
mech_unregister_module(&mech_anonymous);
#ifdef HAVE_GSSAPI
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-otp.c dovecot/src/auth/mech-otp.c
--- dovecot.vanilla/src/auth/mech-otp.c 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/auth/mech-otp.c 2006-06-23 13:44:31.764799456 +0400
@@ -0,0 +1,295 @@
+/*
+ * One-Time-Password (RFC 2444) authentication mechanism.
+ *
+ * Copyright (c) 2006 Andrey Panin
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/Makefile.am dovecot/src/auth/Makefile.am
--- dovecot.vanilla/src/auth/Makefile.am 2006-06-23 13:44:31.820790944 +0400
+++ dovecot/src/auth/Makefile.am 2006-06-23 13:44:31.822790640 +0400
@@ -60,6 +60,7 @@ dovecot_auth_SOURCES = \
mech-digest-md5.c \
mech-ntlm.c \
mech-otp.c \
+ mech-skey.c \
mech-gssapi.c \
mech-rpa.c \
mech-apop.c \
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech.c dovecot/src/auth/mech.c
--- dovecot.vanilla/src/auth/mech.c 2006-06-23 13:44:31.821790792 +0400
+++ dovecot/src/auth/mech.c 2006-06-23 13:44:31.822790640 +0400
@@ -69,6 +69,7 @@ extern struct mech_module mech_cram_md5;
extern struct mech_module mech_digest_md5;
extern struct mech_module mech_ntlm;
extern struct mech_module mech_otp;
+extern struct mech_module mech_skey;
extern struct mech_module mech_rpa;
extern struct mech_module mech_anonymous;
#ifdef HAVE_GSSAPI
@@ -84,6 +85,7 @@ void mech_init(void)
mech_register_module(&mech_digest_md5);
mech_register_module(&mech_ntlm);
mech_register_module(&mech_otp);
+ mech_register_module(&mech_skey);
mech_register_module(&mech_rpa);
mech_register_module(&mech_anonymous);
#ifdef HAVE_GSSAPI
@@ -100,6 +102,7 @@ void mech_deinit(void)
mech_unregister_module(&mech_digest_md5);
mech_unregister_module(&mech_ntlm);
mech_unregister_module(&mech_otp);
+ mech_unregister_module(&mech_skey);
mech_unregister_module(&mech_rpa);
mech_unregister_module(&mech_anonymous);
#ifdef HAVE_GSSAPI
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/auth/mech-skey.c dovecot/src/auth/mech-skey.c
--- dovecot.vanilla/src/auth/mech-skey.c 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/auth/mech-skey.c 2006-06-23 13:44:31.823790488 +0400
@@ -0,0 +1,224 @@
+/*
+ * S/Key (RFC 1731) authentication mechanism.
+ *
+ * Copyright (c) 2006 Andrey Panin
On 183, 07 02, 2006 at 02:25:43PM +0300, Timo Sirainen wrote:
On Mon, 2006-06-26 at 16:58 +0400, Andrey Panin wrote:
/* OTP credentials not found, try S/KEY */
auth_request_lookup_credentials(auth_request,
I guess here should be PASSDB_CREDENTIALS_SKEY
Yes, it should. Cut and paste error :(
-- Andrey Panin | Linux and UNIX system administrator pazke@donpac.ru | PGP key: wwwkeys.pgp.net
On Mon, 2006-06-26 at 16:58 +0400, Andrey Panin wrote:
- MEMBER(update_query) "UPDATE users SET password = '%c' WHERE userid = '%u'", ..
- buf = buffer_create_dynamic(unsafe_data_stack_pool, 128);
- tmp.key = 'c';
- tmp.value = new_credentials;
- buffer_append(buf, &tmp, sizeof(tmp));
- tab = auth_request_get_var_expand_table(request, passdb_sql_escape);
- do {
buffer_append(buf, tab++, sizeof(*tab));
- } while (tab->key != '\0');
I haven't looked at the patches too closely yet, but how about using the existing %w instead of adding a new %c?
Otherwise looks good. Well, except PASSS could be changed to something else :) SETCRED maybe.
On 177, 06 26, 2006 at 04:26:23PM +0300, Timo Sirainen wrote:
On Mon, 2006-06-26 at 16:58 +0400, Andrey Panin wrote:
- MEMBER(update_query) "UPDATE users SET password = '%c' WHERE userid = '%u'", ..
- buf = buffer_create_dynamic(unsafe_data_stack_pool, 128);
- tmp.key = 'c';
- tmp.value = new_credentials;
- buffer_append(buf, &tmp, sizeof(tmp));
- tab = auth_request_get_var_expand_table(request, passdb_sql_escape);
- do {
buffer_append(buf, tab++, sizeof(*tab));
- } while (tab->key != '\0');
I haven't looked at the patches too closely yet, but how about using the existing %w instead of adding a new %c?
Good idea, but needs documentation update since %w is defined as "plaintext password from plaintext authentication mechanism" now.
Otherwise looks good. Well, except PASSS could be changed to something else :) SETCRED maybe.
As you wish :) I'll send an updated patches soon.
-- Andrey Panin | Linux and UNIX system administrator pazke@donpac.ru | PGP key: wwwkeys.pgp.net
On 178, 06 27, 2006 at 11:07:51 +0400, Andrey Panin wrote:
On 177, 06 26, 2006 at 04:26:23PM +0300, Timo Sirainen wrote:
On Mon, 2006-06-26 at 16:58 +0400, Andrey Panin wrote:
- MEMBER(update_query) "UPDATE users SET password = '%c' WHERE userid = '%u'", ..
- buf = buffer_create_dynamic(unsafe_data_stack_pool, 128);
- tmp.key = 'c';
- tmp.value = new_credentials;
- buffer_append(buf, &tmp, sizeof(tmp));
- tab = auth_request_get_var_expand_table(request, passdb_sql_escape);
- do {
buffer_append(buf, tab++, sizeof(*tab));
- } while (tab->key != '\0');
I haven't looked at the patches too closely yet, but how about using the existing %w instead of adding a new %c?
Good idea, but needs documentation update since %w is defined as "plaintext password from plaintext authentication mechanism" now.
Otherwise looks good. Well, except PASSS could be changed to something else :) SETCRED maybe.
As you wish :) I'll send an updated patches soon.
Updated patches attached, s/%c/%w/ and s/PASSS/SETCRED/
-- Andrey Panin | Linux and UNIX system administrator pazke@donpac.ru | PGP key: wwwkeys.pgp.net
participants (2)
-
Andrey Panin
-
Timo Sirainen