diff -urpNX /usr/share/dontdiff dovecot-1.0-test29.vanilla/src/auth/mech-login.c dovecot-1.0-test29/src/auth/mech-login.c --- dovecot-1.0-test29.vanilla/src/auth/mech-login.c 1970-01-01 03:00:00.000000000 +0300 +++ dovecot-1.0-test29/src/auth/mech-login.c 2004-07-21 22:34:06.000000000 +0400 @@ -0,0 +1,115 @@ +/* + * LOGIN authentication mechanism. + * + * Copyright (c) 2004 Andrey Panin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "common.h" +#include "mech.h" +#include "passdb.h" +#include "safe-memset.h" + +static void verify_callback(enum passdb_result result, + struct auth_request *request) +{ + mech_auth_finish(request, NULL, 0, result == PASSDB_RESULT_OK); +} + +static int +mech_login_auth_continue(struct auth_request *auth_request, + const unsigned char *data, size_t data_size, + mech_callback_t *callback) +{ + struct auth_client_request_reply reply; + static const char prompt2[] = "Password:"; + + auth_request->callback = callback; + + if (!auth_request->user) { + auth_request->user = p_strndup(auth_request->pool, data, data_size); + + if (!mech_is_valid_username(auth_request->user)) { + if (verbose) { + i_info("login(%s): invalid username", + get_log_prefix(auth_request)); + } + mech_auth_finish(auth_request, NULL, 0, FALSE); + return TRUE; + } + + mech_init_auth_client_reply(&reply); + reply.id = auth_request->id; + reply.result = AUTH_CLIENT_RESULT_CONTINUE; + + reply.reply_idx = 0; + reply.data_size = strlen(prompt2); + callback(&reply, prompt2, auth_request->conn); + } else { + char *pass = p_strndup(unsafe_data_stack_pool, data, data_size); + + passdb->verify_plain(auth_request, pass, verify_callback); + + safe_memset(pass, 0, strlen(pass)); + } + + return TRUE; +} + +static int +mech_login_auth_initial(struct auth_request *auth_request, + struct auth_client_request_new *request, + const unsigned char *data __attr_unused__, + mech_callback_t *callback) +{ + struct auth_client_request_reply reply; + static const char prompt1[] = "Username:"; + + mech_init_auth_client_reply(&reply); + reply.id = request->id; + reply.result = AUTH_CLIENT_RESULT_CONTINUE; + + reply.reply_idx = 0; + reply.data_size = strlen(prompt1); + callback(&reply, prompt1, auth_request->conn); + + return TRUE; +} + +static void mech_login_auth_free(struct auth_request *auth_request) +{ + pool_unref(auth_request->pool); +} + +static struct auth_request *mech_login_auth_new(void) +{ + struct auth_request *auth; + pool_t pool; + + pool = pool_alloconly_create("login_auth_request", 256); + auth = p_new(pool, struct auth_request, 1); + + auth->refcount = 1; + auth->pool = pool; + auth->auth_initial = mech_login_auth_initial; + auth->auth_continue = mech_login_auth_continue; + auth->auth_free = mech_login_auth_free; + + return auth; +} + +const struct mech_module mech_login = { + "LOGIN", + + MEMBER(plaintext) FALSE, + MEMBER(advertise) TRUE, + + MEMBER(passdb_need_plain) FALSE, + MEMBER(passdb_need_credentials) TRUE, + + mech_login_auth_new, +}; diff -urpNX /usr/share/dontdiff dovecot-1.0-test29.vanilla/src/auth/Makefile.am dovecot-1.0-test29/src/auth/Makefile.am --- dovecot-1.0-test29.vanilla/src/auth/Makefile.am 2004-07-21 15:32:16.000000000 +0400 +++ dovecot-1.0-test29/src/auth/Makefile.am 2004-07-22 10:36:56.000000000 +0400 @@ -29,6 +29,7 @@ dovecot_auth_SOURCES = \ mech-anonymous.c \ mech-cyrus-sasl2.c \ mech-plain.c \ + mech-login.c \ mech-cram-md5.c \ mech-digest-md5.c \ mech-apop.c \ diff -urpNX /usr/share/dontdiff dovecot-1.0-test29.vanilla/src/auth/mech.c dovecot-1.0-test29/src/auth/mech.c --- dovecot-1.0-test29.vanilla/src/auth/mech.c 2004-07-03 00:07:31.000000000 +0400 +++ dovecot-1.0-test29/src/auth/mech.c 2004-07-22 10:36:26.000000000 +0400 @@ -384,6 +384,7 @@ static void auth_failure_timeout(void *c } extern struct mech_module mech_plain; +extern struct mech_module mech_login; extern struct mech_module mech_apop; extern struct mech_module mech_cram_md5; extern struct mech_module mech_digest_md5; @@ -412,6 +413,8 @@ void mech_init(void) while (*mechanisms != NULL) { if (strcasecmp(*mechanisms, "PLAIN") == 0) mech_register_module(&mech_plain); + else if (strcasecmp(*mechanisms, "LOGIN") == 0) + mech_register_module(&mech_login); else if (strcasecmp(*mechanisms, "APOP") == 0) mech_register_module(&mech_apop); else if (strcasecmp(*mechanisms, "CRAM-MD5") == 0) @@ -474,6 +477,7 @@ void mech_deinit(void) timeout_remove(to_auth_failures); mech_unregister_module(&mech_plain); + mech_unregister_module(&mech_login); mech_unregister_module(&mech_apop); mech_unregister_module(&mech_cram_md5); mech_unregister_module(&mech_digest_md5);