From: Timo Sirainen Date: Sun, 19 Oct 2008 11:00:57 +0000 (+0300) Subject: Login process: Log auth failure reasons better in disconnect message. X-Git-Tag: 1.2.alpha3~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=38318f5e82662615cd88e99e398efe4a630ce020;p=thirdparty%2Fdovecot%2Fcore.git Login process: Log auth failure reasons better in disconnect message. For example if client certs are required it now logs if the cert wasn't sent or if the cert was invalid. --HG-- branch : HEAD --- diff --git a/src/imap-login/client-authenticate.c b/src/imap-login/client-authenticate.c index 3f11587ad6..6b1ec3588e 100644 --- a/src/imap-login/client-authenticate.c +++ b/src/imap-login/client-authenticate.c @@ -322,6 +322,7 @@ int cmd_login(struct imap_client *client, const struct imap_arg *args) "Plaintext authentication disabled"); } client->common.auth_tried_disabled_plaintext = TRUE; + client->common.auth_attempts++; client_send_line(client, "* BAD [ALERT] Plaintext authentication is disabled, " "but your client sent password in plaintext anyway. " diff --git a/src/imap-login/client.c b/src/imap-login/client.c index 19e07ff679..d379722de6 100644 --- a/src/imap-login/client.c +++ b/src/imap-login/client.c @@ -256,12 +256,7 @@ static int cmd_logout(struct imap_client *client) { client_send_line(client, "* BYE Logging out"); client_send_tagline(client, "OK Logout completed."); - if (client->common.auth_tried_disabled_plaintext) { - client_destroy(client, "Aborted login " - "(tried to use disabled plaintext authentication)"); - } else { - client_destroy(client, "Aborted login"); - } + client_destroy(client, "Aborted login"); return 1; } @@ -547,10 +542,9 @@ void client_destroy(struct imap_client *client, const char *reason) client->destroyed = TRUE; if (!client->login_success && reason != NULL) { - reason = client->common.auth_attempts == 0 ? - t_strdup_printf("%s (no auth attempts)", reason) : - t_strdup_printf("%s (auth failed, %u attempts)", - reason, client->common.auth_attempts); + reason = t_strconcat(reason, " ", + client_get_extra_disconnect_reason(&client->common), + NULL); } if (reason != NULL) client_syslog(&client->common, reason); diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index ae1928064d..efb061b59b 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -179,3 +179,25 @@ bool client_is_trusted(struct client *client) } return FALSE; } + +const char *client_get_extra_disconnect_reason(struct client *client) +{ + if (ssl_require_client_cert && client->proxy != NULL) { + if (ssl_proxy_has_broken_client_cert(client->proxy)) + return "(client sent an invalid cert)"; + if (!ssl_proxy_has_valid_client_cert(client->proxy)) + return "(client didn't send a cert)"; + } + + if (client->auth_attempts == 0) + return "(no auth attempts)"; + + /* some auth attempts without SSL/TLS */ + if (client->auth_tried_disabled_plaintext) + return "(tried to use disabled plaintext auth)"; + if (ssl_require_client_cert) + return "(cert required, client didn't start TLS)"; + + return t_strdup_printf("(auth failed, %u attempts)", + client->auth_attempts); +} diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index dfda3fb269..fc1cf558a1 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -54,6 +54,7 @@ void client_unlink(struct client *client); unsigned int clients_get_count(void) ATTR_PURE; void client_syslog(struct client *client, const char *msg); +const char *client_get_extra_disconnect_reason(struct client *client); bool client_is_trusted(struct client *client); void clients_notify_auth_connected(void); diff --git a/src/login-common/common.h b/src/login-common/common.h index 4956289dc5..a9850cc36e 100644 --- a/src/login-common/common.h +++ b/src/login-common/common.h @@ -15,6 +15,7 @@ extern const char *login_protocol; extern bool disable_plaintext_auth, process_per_connection; extern bool verbose_proctitle, verbose_ssl, verbose_auth; +extern bool ssl_require_client_cert; extern const char *greeting, *log_format; extern const char *const *log_format_elements; extern const char *capability_string; diff --git a/src/login-common/main.c b/src/login-common/main.c index 2a7fee4415..76fc0fd618 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -21,6 +21,7 @@ bool disable_plaintext_auth, process_per_connection; bool verbose_proctitle, verbose_ssl, verbose_auth; +bool ssl_require_client_cert; const char *greeting, *log_format; const char *const *log_format_elements; const char *trusted_networks; @@ -317,6 +318,7 @@ static void main_init(void) verbose_proctitle = getenv("VERBOSE_PROCTITLE") != NULL; verbose_ssl = getenv("VERBOSE_SSL") != NULL; verbose_auth = getenv("VERBOSE_AUTH") != NULL; + ssl_require_client_cert = getenv("SSL_REQUIRE_CLIENT_CERT") != NULL; greeting = getenv("GREETING"); if (greeting == NULL) diff --git a/src/login-common/ssl-proxy-openssl.c b/src/login-common/ssl-proxy-openssl.c index 8948a3aec1..91b2981451 100644 --- a/src/login-common/ssl-proxy-openssl.c +++ b/src/login-common/ssl-proxy-openssl.c @@ -517,6 +517,11 @@ bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy) return proxy->cert_received && !proxy->cert_broken; } +bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy) +{ + return proxy->cert_received && proxy->cert_broken; +} + const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy) { X509 *x509; diff --git a/src/login-common/ssl-proxy.c b/src/login-common/ssl-proxy.c index 1c2c17d1ab..c02fcb577e 100644 --- a/src/login-common/ssl-proxy.c +++ b/src/login-common/ssl-proxy.c @@ -21,6 +21,11 @@ bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy ATTR_UNUSED) return FALSE; } +bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy ATTR_UNUSED) +{ + return FALSE; +} + const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy ATTR_UNUSED) { return NULL; diff --git a/src/login-common/ssl-proxy.h b/src/login-common/ssl-proxy.h index 40f8abd014..d8422d2b91 100644 --- a/src/login-common/ssl-proxy.h +++ b/src/login-common/ssl-proxy.h @@ -11,6 +11,7 @@ extern bool ssl_initialized; the given fd must be simply forgotten. */ int ssl_proxy_new(int fd, struct ip_addr *ip, struct ssl_proxy **proxy_r); bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy) ATTR_PURE; +bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy); const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy); bool ssl_proxy_is_handshaked(const struct ssl_proxy *proxy) ATTR_PURE; const char *ssl_proxy_get_last_error(const struct ssl_proxy *proxy) ATTR_PURE; diff --git a/src/master/login-process.c b/src/master/login-process.c index 94d231fbc7..bcdb290950 100644 --- a/src/master/login-process.c +++ b/src/master/login-process.c @@ -530,6 +530,8 @@ static void login_process_unref(struct login_process *p) static void login_process_init_env(struct login_group *group, pid_t pid) { struct settings *set = group->set; + const struct auth_settings *auth; + bool require_cert; child_process_init_env(); @@ -579,6 +581,13 @@ static void login_process_init_env(struct login_group *group, pid_t pid) env_put("VERBOSE_SSL=1"); if (set->server->auths->verbose) env_put("VERBOSE_AUTH=1"); + require_cert = TRUE; + for (auth = set->server->auths; auth != NULL; auth = auth->next) { + if (!auth->ssl_require_client_cert) + require_cert = FALSE; + } + if (require_cert) + env_put("SSL_REQUIRE_CLIENT_CERT=1"); if (set->login_process_per_connection) { env_put("PROCESS_PER_CONNECTION=1"); diff --git a/src/pop3-login/client-authenticate.c b/src/pop3-login/client-authenticate.c index d481452779..82234d832a 100644 --- a/src/pop3-login/client-authenticate.c +++ b/src/pop3-login/client-authenticate.c @@ -276,6 +276,7 @@ static bool check_plaintext_auth(struct pop3_client *client) } client_send_line(client, "-ERR "AUTH_PLAINTEXT_DISABLED_MSG); client->common.auth_tried_disabled_plaintext = TRUE; + client->common.auth_attempts++; return FALSE; } diff --git a/src/pop3-login/client.c b/src/pop3-login/client.c index ec7980c75e..00294a460d 100644 --- a/src/pop3-login/client.c +++ b/src/pop3-login/client.c @@ -143,12 +143,7 @@ static bool cmd_stls(struct pop3_client *client) static bool cmd_quit(struct pop3_client *client) { client_send_line(client, "+OK Logging out"); - if (client->common.auth_tried_disabled_plaintext) { - client_destroy(client, "Aborted login " - "(tried to use disabled plaintext authentication)"); - } else { - client_destroy(client, "Aborted login"); - } + client_destroy(client, "Aborted login"); return TRUE; } @@ -352,10 +347,9 @@ void client_destroy(struct pop3_client *client, const char *reason) client->destroyed = TRUE; if (!client->login_success && reason != NULL) { - reason = client->common.auth_attempts == 0 ? - t_strdup_printf("%s (no auth attempts)", reason) : - t_strdup_printf("%s (auth failed, %u attempts)", - reason, client->common.auth_attempts); + reason = t_strconcat(reason, " ", + client_get_extra_disconnect_reason(&client->common), + NULL); } if (reason != NULL) client_syslog(&client->common, reason);