mech-login.c revision 1e3a608d8d0e08cb7d549718fbfbcc148fdb236f
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen/*
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen * LOGIN authentication mechanism.
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen *
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru>
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen *
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen * This program is free software; you can redistribute it and/or modify
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen * it under the terms of the GNU Lesser General Public License as published
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen * by the Free Software Foundation; either version 2 of the License, or
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen * (at your option) any later version.
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen */
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen#include "common.h"
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen#include "mech.h"
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen#include "passdb.h"
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen#include "safe-memset.h"
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainenstatic void verify_callback(enum passdb_result result,
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen struct auth_request *request)
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen{
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen switch (result) {
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen case PASSDB_RESULT_OK:
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen auth_request_success(request, NULL, 0);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen break;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen case PASSDB_RESULT_INTERNAL_FAILURE:
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen auth_request_internal_failure(request);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen break;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen default:
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen auth_request_fail(request);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen break;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen }
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen}
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenstatic void
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenmech_login_auth_continue(struct auth_request *request,
78ed6a99e980228a75fa59cff84327dc0ea82857Timo Sirainen const unsigned char *data, size_t data_size)
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen{
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen static const char prompt2[] = "Password:";
97c339398f1aba6f315b55a9b6ee6b020e33bea4Timo Sirainen const char *username, *error;
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen if (request->user == NULL) {
97c339398f1aba6f315b55a9b6ee6b020e33bea4Timo Sirainen username = t_strndup(data, data_size);
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
97c339398f1aba6f315b55a9b6ee6b020e33bea4Timo Sirainen if (!auth_request_set_username(request, username, &error)) {
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen auth_request_log_info(request, "login", "%s", error);
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen auth_request_fail(request);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen return;
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen }
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
78ed6a99e980228a75fa59cff84327dc0ea82857Timo Sirainen request->callback(request, AUTH_CLIENT_RESULT_CONTINUE,
78ed6a99e980228a75fa59cff84327dc0ea82857Timo Sirainen prompt2, strlen(prompt2));
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen } else {
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen char *pass = p_strndup(unsafe_data_stack_pool, data, data_size);
1e21e6be70994b1aa9e52ca0e2f51afefca6d0dfTimo Sirainen auth_request_verify_plain(request, pass, verify_callback);
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen safe_memset(pass, 0, strlen(pass));
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen }
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen}
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenstatic void
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenmech_login_auth_initial(struct auth_request *request,
1e3a608d8d0e08cb7d549718fbfbcc148fdb236fTimo Sirainen const unsigned char *data, size_t data_size)
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen{
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen static const char prompt1[] = "Username:";
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
1e3a608d8d0e08cb7d549718fbfbcc148fdb236fTimo Sirainen if (data_size == 0) {
1e3a608d8d0e08cb7d549718fbfbcc148fdb236fTimo Sirainen request->callback(request, AUTH_CLIENT_RESULT_CONTINUE,
1e3a608d8d0e08cb7d549718fbfbcc148fdb236fTimo Sirainen prompt1, strlen(prompt1));
1e3a608d8d0e08cb7d549718fbfbcc148fdb236fTimo Sirainen } else {
1e3a608d8d0e08cb7d549718fbfbcc148fdb236fTimo Sirainen mech_login_auth_continue(request, data, data_size);
1e3a608d8d0e08cb7d549718fbfbcc148fdb236fTimo Sirainen }
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen}
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenstatic void mech_login_auth_free(struct auth_request *request)
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen{
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen pool_unref(request->pool);
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen}
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
4ac5448461b63de9637de839fbc611a3d503287cTimo Sirainenstatic struct auth_request *mech_login_auth_new(void)
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen{
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen struct auth_request *request;
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen pool_t pool;
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
e03ec0b7b9d92551331bc509bcd86920544171d1Timo Sirainen pool = pool_alloconly_create("login_auth_request", 1024);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen request = p_new(pool, struct auth_request, 1);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen request->pool = pool;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen return request;
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen}
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainenconst struct mech_module mech_login = {
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen "LOGIN",
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen MEMBER(flags) MECH_SEC_PLAINTEXT,
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen MEMBER(passdb_need_plain) TRUE,
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen MEMBER(passdb_need_credentials) FALSE,
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen mech_login_auth_new,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen mech_login_auth_initial,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen mech_login_auth_continue,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen mech_login_auth_free
33c6d5807b449463e9b81db5ec99fe027cc1b984Timo Sirainen};