]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added LOGIN SASL mechanism. Patch by Andrey Panin
authorTimo Sirainen <tss@iki.fi>
Thu, 22 Jul 2004 13:42:02 +0000 (16:42 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 22 Jul 2004 13:42:02 +0000 (16:42 +0300)
--HG--
branch : HEAD

AUTHORS
src/auth/Makefile.am
src/auth/mech-login.c [new file with mode: 0644]
src/auth/mech.c

diff --git a/AUTHORS b/AUTHORS
index 910784687fff95e8a7dfd1638e7bf113486db7c3..369b6a9a0c7381aacca07158b72f912aef5acc25 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,7 +6,7 @@ Alex Howansky <alex@wankwood.com> (src/auth/*-pgsql.c)
 
 Matthew Reimer <mreimer@vpop.net> (src/auth/*-mysql.c)
 
-Andrey Panin <pazke@donpac.ru> (src/auth/mech-apop.c)
+Andrey Panin <pazke@donpac.ru> (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/).
index 1658bfe0aefcd198457c1ec8cb8363201890dd88..c3749ebd97b9d6bae4b4e21ab0910e60c9568280 100644 (file)
@@ -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 (file)
index 0000000..afb897d
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * LOGIN authentication mechanism.
+ *
+ * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru>
+ *
+ * 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,
+};
index 5a1d175e32e023fb435af4561038a0e0890f64e9..171f5c9dcee2ad94cd8e094b155923e368300028 100644 (file)
@@ -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);