From: Timo Sirainen Date: Thu, 22 Jul 2004 13:42:02 +0000 (+0300) Subject: Added LOGIN SASL mechanism. Patch by Andrey Panin X-Git-Tag: 1.1.alpha1~3760 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33c6d5807b449463e9b81db5ec99fe027cc1b984;p=thirdparty%2Fdovecot%2Fcore.git Added LOGIN SASL mechanism. Patch by Andrey Panin --HG-- branch : HEAD --- diff --git a/AUTHORS b/AUTHORS index 910784687f..369b6a9a0c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,7 +6,7 @@ Alex Howansky (src/auth/*-pgsql.c) Matthew Reimer (src/auth/*-mysql.c) -Andrey Panin (src/auth/mech-apop.c) +Andrey Panin (src/auth/mech-apop.c, src/auth/mech-login.c) This product includes software developed by Computing Services at Carnegie Mellon University (http://www.cmu.edu/computing/). diff --git a/src/auth/Makefile.am b/src/auth/Makefile.am index 1658bfe0ae..c3749ebd97 100644 --- a/src/auth/Makefile.am +++ b/src/auth/Makefile.am @@ -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 --git a/src/auth/mech-login.c b/src/auth/mech-login.c new file mode 100644 index 0000000000..afb897d550 --- /dev/null +++ b/src/auth/mech-login.c @@ -0,0 +1,116 @@ +/* + * 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) TRUE, + MEMBER(advertise) TRUE, + + MEMBER(passdb_need_plain) TRUE, + MEMBER(passdb_need_credentials) FALSE, + + mech_login_auth_new, +}; diff --git a/src/auth/mech.c b/src/auth/mech.c index 5a1d175e32..171f5c9dce 100644 --- a/src/auth/mech.c +++ b/src/auth/mech.c @@ -384,6 +384,7 @@ static void auth_failure_timeout(void *context __attr_unused__) } 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);