Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2691:46f879c46b45 HEAD
auth_verbose now affects imap/pop3 login processes too. Every authentication
attempt by client is logged. Also fixed replies in AUTHENTICATE/AUTH
commands when it was aborted by client.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 05 Oct 2004 19:00:18 +0300 |
parents | 7b50711a168d |
children | 1065a557516b |
files | src/imap-login/client-authenticate.c src/imap-login/client.c src/imap-login/client.h src/login-common/common.h src/login-common/main.c src/master/login-process.c src/pop3-login/client-authenticate.c src/pop3-login/client.c src/pop3-login/client.h |
diffstat | 9 files changed, 140 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap-login/client-authenticate.c Tue Oct 05 18:30:03 2004 +0300 +++ b/src/imap-login/client-authenticate.c Tue Oct 05 19:00:18 2004 +0300 @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Timo Sirainen */ +/* Copyright (C) 2002-2004 Timo Sirainen */ #include "common.h" #include "base64.h" @@ -8,6 +8,7 @@ #include "ostream.h" #include "safe-memset.h" #include "str.h" +#include "str-sanitize.h" #include "imap-parser.h" #include "auth-client.h" #include "ssl-proxy.h" @@ -16,6 +17,9 @@ #include "auth-common.h" #include "master.h" +/* Used only for string sanitization while verbose_auth is set. */ +#define MAX_MECH_NAME 64 + const char *client_authenticate_get_capabilities(int secured) { const struct auth_mech_desc *mech; @@ -50,6 +54,9 @@ client->common.auth_request = NULL; } + if (msg != NULL && verbose_auth) + client_syslog(client, "Authentication failed: %s", msg); + client_send_tagline(client, msg != NULL ? t_strconcat("NO ", msg, NULL) : "NO Authentication failed."); @@ -161,6 +168,10 @@ pass = IMAP_ARG_STR(&args[1]); if (!client->secured && disable_plaintext_auth) { + if (verbose_auth) { + client_syslog(client, "Login failed: " + "Plaintext authentication disabled"); + } client_send_line(client, "* BAD [ALERT] Plaintext authentication is disabled, " "but your client sent password in plaintext anyway. " @@ -192,6 +203,8 @@ auth_client_request_new(auth_client, NULL, &info, login_callback, client, &error); if (client->common.auth_request == NULL) { + if (verbose_auth) + client_syslog(client, "Login failed: %s", error); client_send_tagline(client, t_strconcat( "NO Login failed: ", error, NULL)); client_unref(client); @@ -215,6 +228,12 @@ struct imap_client *client = context; const char *error; + if (!client->authenticating) { + /* client aborted */ + i_assert(reply == NULL); + return; + } + switch (auth_callback(request, reply, data, &client->common, master_callback, &error)) { case -1: @@ -301,12 +320,22 @@ mech = auth_client_find_mech(auth_client, mech_name); if (mech == NULL) { + if (verbose_auth) { + client_syslog(client, "Authenticate %s failed: " + "Unsupported mechanism", + str_sanitize(mech_name, MAX_MECH_NAME)); + } client_send_tagline(client, "NO Unsupported authentication mechanism."); return TRUE; } if (!client->secured && mech->plaintext && disable_plaintext_auth) { + if (verbose_auth) { + client_syslog(client, "Authenticate %s failed: " + "Plaintext authentication disabled", + str_sanitize(mech_name, MAX_MECH_NAME)); + } client_send_tagline(client, "NO Plaintext authentication disabled."); return TRUE; @@ -333,6 +362,11 @@ client_auth_input, client); client->authenticating = TRUE; } else { + if (verbose_auth) { + client_syslog(client, "Authenticate %s failed: %s", + str_sanitize(mech_name, MAX_MECH_NAME), + error); + } client_send_tagline(client, t_strconcat( "NO Authentication failed: ", error, NULL)); client_unref(client);
--- a/src/imap-login/client.c Tue Oct 05 18:30:03 2004 +0300 +++ b/src/imap-login/client.c Tue Oct 05 19:00:18 2004 +0300 @@ -434,7 +434,7 @@ client->destroyed = TRUE; if (reason != NULL) - client_syslog(client, reason); + client_syslog(client, "%s", reason); hash_remove(clients, client); @@ -507,15 +507,20 @@ client_send_line(client, t_strconcat(client->cmd_tag, " ", line, NULL)); } -void client_syslog(struct imap_client *client, const char *text) +void client_syslog(struct imap_client *client, const char *format, ...) { const char *addr; + va_list args; addr = net_ip2addr(&client->common.ip); if (addr == NULL) addr = "??"; - i_info("%s [%s]", text, addr); + t_push(); + va_start(args, format); + i_info("%s [%s]", t_strdup_vprintf(format, args), addr); + va_end(args); + t_pop(); } static void client_check_idle(struct imap_client *client)
--- a/src/imap-login/client.h Tue Oct 05 18:30:03 2004 +0300 +++ b/src/imap-login/client.h Tue Oct 05 19:00:18 2004 +0300 @@ -33,7 +33,8 @@ void client_send_line(struct imap_client *client, const char *line); void client_send_tagline(struct imap_client *client, const char *line); -void client_syslog(struct imap_client *client, const char *text); +void client_syslog(struct imap_client *client, const char *format, ...) + __attr_format__(2, 3); int client_read(struct imap_client *client); void client_input(void *context);
--- a/src/login-common/common.h Tue Oct 05 18:30:03 2004 +0300 +++ b/src/login-common/common.h Tue Oct 05 19:00:18 2004 +0300 @@ -3,8 +3,8 @@ #include "lib.h" -extern int disable_plaintext_auth, process_per_connection, verbose_proctitle; -extern int verbose_ssl, greeting_capability; +extern int disable_plaintext_auth, process_per_connection, greeting_capability; +extern int verbose_proctitle, verbose_ssl, verbose_auth; char *greeting; extern unsigned int max_logging_users; extern unsigned int login_process_uid;
--- a/src/login-common/main.c Tue Oct 05 18:30:03 2004 +0300 +++ b/src/login-common/main.c Tue Oct 05 19:00:18 2004 +0300 @@ -17,8 +17,8 @@ #include <unistd.h> #include <syslog.h> -int disable_plaintext_auth, process_per_connection, verbose_proctitle; -int verbose_ssl, greeting_capability; +int disable_plaintext_auth, process_per_connection, greeting_capability; +int verbose_proctitle, verbose_ssl, verbose_auth; char *greeting; unsigned int max_logging_users; unsigned int login_process_uid; @@ -159,6 +159,7 @@ process_per_connection = getenv("PROCESS_PER_CONNECTION") != NULL; verbose_proctitle = getenv("VERBOSE_PROCTITLE") != NULL; verbose_ssl = getenv("VERBOSE_SSL") != NULL; + verbose_auth = getenv("VERBOSE_AUTH") != NULL; value = getenv("MAX_LOGGING_USERS"); max_logging_users = value == NULL ? 0 : strtoul(value, NULL, 10);
--- a/src/master/login-process.c Tue Oct 05 18:30:03 2004 +0300 +++ b/src/master/login-process.c Tue Oct 05 19:00:18 2004 +0300 @@ -419,6 +419,8 @@ env_put("VERBOSE_PROCTITLE=1"); if (set->verbose_ssl) env_put("VERBOSE_SSL=1"); + if (set->server->auths->verbose) + env_put("VERBOSE_AUTH=1"); if (set->login_process_per_connection) { env_put("PROCESS_PER_CONNECTION=1");
--- a/src/pop3-login/client-authenticate.c Tue Oct 05 18:30:03 2004 +0300 +++ b/src/pop3-login/client-authenticate.c Tue Oct 05 19:00:18 2004 +0300 @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Timo Sirainen */ +/* Copyright (C) 2002-2004 Timo Sirainen */ #include "common.h" #include "base64.h" @@ -9,6 +9,7 @@ #include "ostream.h" #include "safe-memset.h" #include "str.h" +#include "str-sanitize.h" #include "auth-client.h" #include "../pop3/capability.h" #include "ssl-proxy.h" @@ -18,6 +19,9 @@ #include "client-authenticate.h" #include "ssl-proxy.h" +/* Used only for string sanitization while verbose_auth is set. */ +#define MAX_MECH_NAME 64 + int cmd_capa(struct pop3_client *client, const char *args __attr_unused__) { const struct auth_mech_desc *mech; @@ -51,11 +55,16 @@ static void client_auth_abort(struct pop3_client *client, const char *msg) { + client->authenticating = FALSE; + if (client->common.auth_request != NULL) { auth_client_request_abort(client->common.auth_request); client->common.auth_request = NULL; } + if (msg != NULL && verbose_auth) + client_syslog(client, "Authentication failed: %s", msg); + client_send_line(client, msg != NULL ? t_strconcat("-ERR ", msg, NULL) : "-ERR Authentication failed."); @@ -111,19 +120,6 @@ t_pop(); } -static enum auth_client_request_new_flags -client_get_auth_flags(struct pop3_client *client) -{ - enum auth_client_request_new_flags auth_flags = 0; - - if (client->common.proxy != NULL && - ssl_proxy_has_valid_client_cert(client->common.proxy)) - auth_flags |= AUTH_CLIENT_FLAG_SSL_VALID_CLIENT_CERT; - if (client->tls) - auth_flags |= AUTH_CLIENT_FLAG_SSL_ENABLED; - return auth_flags; -} - static void login_callback(struct auth_request *request, struct auth_client_request_reply *reply, const unsigned char *data, void *context) @@ -142,14 +138,32 @@ default: /* success, we should be able to log in. if we fail, just disconnect the client. */ + client->authenticating = FALSE; client_send_line(client, "+OK Logged in."); client_unref(client); } } +static enum auth_client_request_new_flags +client_get_auth_flags(struct pop3_client *client) +{ + enum auth_client_request_new_flags auth_flags = 0; + + if (client->common.proxy != NULL && + ssl_proxy_has_valid_client_cert(client->common.proxy)) + auth_flags |= AUTH_CLIENT_FLAG_SSL_VALID_CLIENT_CERT; + if (client->tls) + auth_flags |= AUTH_CLIENT_FLAG_SSL_ENABLED; + return auth_flags; +} + int cmd_user(struct pop3_client *client, const char *args) { if (!client->secured && disable_plaintext_auth) { + if (verbose_auth) { + client_syslog(client, "Login failed: " + "Plaintext authentication disabled"); + } client_send_line(client, "-ERR Plaintext authentication disabled."); return TRUE; @@ -190,23 +204,27 @@ info.initial_resp_size = str_len(plain_login); client_ref(client); + client->common.auth_request = auth_client_request_new(auth_client, NULL, &info, login_callback, client, &error); - - if (client->common.auth_request != NULL) { - /* don't read any input from client until login is finished */ - if (client->common.io != NULL) { - io_remove(client->common.io); - client->common.io = NULL; - } - return TRUE; - } else { + if (client->common.auth_request == NULL) { + if (verbose_auth) + client_syslog(client, "Login failed: %s", error); client_send_line(client, t_strconcat("-ERR Login failed: ", error, NULL)); client_unref(client); return TRUE; } + + /* don't read any input from client until login is finished */ + if (client->common.io != NULL) { + io_remove(client->common.io); + client->common.io = NULL; + } + + client->authenticating = TRUE; + return TRUE; } static void authenticate_callback(struct auth_request *request, @@ -216,6 +234,12 @@ struct pop3_client *client = context; const char *error; + if (!client->authenticating) { + /* client aborted */ + i_assert(reply == NULL); + return; + } + switch (auth_callback(request, reply, data, &client->common, master_callback, &error)) { case -1: @@ -230,6 +254,7 @@ default: /* success, we should be able to log in. if we fail, just disconnect the client. */ + client->authenticating = FALSE; client_send_line(client, "+OK Logged in."); client_unref(client); } @@ -307,12 +332,22 @@ mech = auth_client_find_mech(auth_client, mech_name); if (mech == NULL) { + if (verbose_auth) { + client_syslog(client, "Authenticate %s failed: " + "Unsupported mechanism", + str_sanitize(mech_name, MAX_MECH_NAME)); + } client_send_line(client, "-ERR Unsupported authentication mechanism."); return TRUE; } if (!client->secured && mech->plaintext && disable_plaintext_auth) { + if (verbose_auth) { + client_syslog(client, "Authenticate %s failed: " + "Plaintext authentication disabled", + str_sanitize(mech_name, MAX_MECH_NAME)); + } client_send_line(client, "-ERR Plaintext authentication disabled."); return TRUE; @@ -346,7 +381,13 @@ io_remove(client->common.io); client->common.io = io_add(client->common.fd, IO_READ, client_auth_input, client); + client->authenticating = TRUE; } else { + if (verbose_auth) { + client_syslog(client, "Authenticate %s failed: %s", + str_sanitize(mech_name, MAX_MECH_NAME), + error); + } client_send_line(client, t_strconcat( "-ERR Authentication failed: ", error, NULL)); client_unref(client); @@ -362,6 +403,8 @@ buffer_t *apop_data; if (client->apop_challenge == NULL) { + if (verbose_auth) + client_syslog(client, "APOP failed: APOP not enabled"); client_send_line(client, "-ERR APOP not enabled."); return TRUE; } @@ -369,6 +412,10 @@ /* <username> <md5 sum in hex> */ p = strchr(args, ' '); if (p == NULL || strlen(p+1) != 32) { + if (verbose_auth) { + client_syslog(client, "APOP failed: " + "Invalid parameters"); + } client_send_line(client, "-ERR Invalid parameters."); return TRUE; } @@ -382,6 +429,10 @@ buffer_append_c(apop_data, '\0'); if (hex_to_binary(p+1, apop_data) <= 0) { + if (verbose_auth) { + client_syslog(client, "APOP failed: " + "Invalid characters in MD5 response"); + } client_send_line(client, "-ERR Invalid characters in MD5 response."); return TRUE; @@ -409,6 +460,7 @@ io_remove(client->common.io); client->common.io = NULL; } + client->authenticating = TRUE; } else if (error == NULL) { /* the auth connection was lost. we have no choice but to fail the APOP logins completely since the @@ -416,6 +468,8 @@ client_destroy(client, "APOP auth connection lost"); client_unref(client); } else { + if (verbose_auth) + client_syslog(client, "APOP failed: %s", error); client_send_line(client, t_strconcat("-ERR Login failed: ", error, NULL)); client_unref(client);
--- a/src/pop3-login/client.c Tue Oct 05 18:30:03 2004 +0300 +++ b/src/pop3-login/client.c Tue Oct 05 19:00:18 2004 +0300 @@ -340,7 +340,7 @@ client->destroyed = TRUE; if (reason != NULL) - client_syslog(client, reason); + client_syslog(client, "%s", reason); hash_remove(clients, client); @@ -405,15 +405,20 @@ client_destroy(client, "Transmit buffer full"); } -void client_syslog(struct pop3_client *client, const char *text) +void client_syslog(struct pop3_client *client, const char *format, ...) { const char *addr; + va_list args; addr = net_ip2addr(&client->common.ip); if (addr == NULL) addr = "??"; - i_info("%s [%s]", text, addr); + t_push(); + va_start(args, format); + i_info("%s [%s]", t_strdup_vprintf(format, args), addr); + va_end(args); + t_pop(); } static void client_check_idle(struct pop3_client *client)
--- a/src/pop3-login/client.h Tue Oct 05 18:30:03 2004 +0300 +++ b/src/pop3-login/client.h Tue Oct 05 19:00:18 2004 +0300 @@ -25,6 +25,7 @@ unsigned int tls:1; unsigned int secured:1; + unsigned int authenticating:1; unsigned int auth_connected:1; unsigned int destroyed:1; }; @@ -32,7 +33,8 @@ void client_destroy(struct pop3_client *client, const char *reason); void client_send_line(struct pop3_client *client, const char *line); -void client_syslog(struct pop3_client *client, const char *text); +void client_syslog(struct pop3_client *client, const char *format, ...) + __attr_format__(2, 3); int client_read(struct pop3_client *client); void client_input(void *context);