]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Login process: Log auth failure reasons better in disconnect message.
authorTimo Sirainen <tss@iki.fi>
Sun, 19 Oct 2008 11:00:57 +0000 (14:00 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 19 Oct 2008 11:00:57 +0000 (14:00 +0300)
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

12 files changed:
src/imap-login/client-authenticate.c
src/imap-login/client.c
src/login-common/client-common.c
src/login-common/client-common.h
src/login-common/common.h
src/login-common/main.c
src/login-common/ssl-proxy-openssl.c
src/login-common/ssl-proxy.c
src/login-common/ssl-proxy.h
src/master/login-process.c
src/pop3-login/client-authenticate.c
src/pop3-login/client.c

index 3f11587ad67f6d093e230b74cb3420261e1178ad..6b1ec3588efd467742d8f3c48ec36563329a38e5 100644 (file)
@@ -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. "
index 19e07ff67984922825bdab3f6561d85d4e833169..d379722de66865519e2dfd118f77ea2b9ba5f489 100644 (file)
@@ -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);
index ae1928064dbd9f64d82a2e41e2e5046d0d7da809..efb061b59bc5f304d3f2b425d2d521a4e8b4ca8f 100644 (file)
@@ -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);
+}
index dfda3fb2693e8b1ffe15d6c8a2b202d4880406a5..fc1cf558a1bdb1cb9331f9030945c7a48b9b5816 100644 (file)
@@ -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);
index 4956289dc58677f92bfad969a4744417d693df60..a9850cc36ef53ddd7212573ce723820f405978a4 100644 (file)
@@ -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;
index 2a7fee4415c9670a489cd3b198715ad1b121ad9c..76fc0fd6187b3b5bee33e3281d3b729e2bb896be 100644 (file)
@@ -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)
index 8948a3aec1fef797d0086f2c2ae9a4294c9510dd..91b29814512039642c4801f85430ff1daaa3c527 100644 (file)
@@ -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;
index 1c2c17d1abfd07633158ca174c358c4967178bc7..c02fcb577e0405dec84f2435504123a9d6403e43 100644 (file)
@@ -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;
index 40f8abd0140caa46a83aba55c0f7d15a89b3eb38..d8422d2b917f140ccee868a897d65981325ab872 100644 (file)
@@ -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;
index 94d231fbc731088965a0cc5f0bbb9cf8f78a88a1..bcdb290950076ec4731e48f50d0edc5af3dabac7 100644 (file)
@@ -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");
index d481452779c98ba66065dccac43259cdf5705178..82234d832ab045ad3cdeb67b0c101da177fb9dae 100644 (file)
@@ -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;
 }
 
index ec7980c75e4d8b48f57b8fd0e9f1599b44658057..00294a460d8a1140616ef3c780db4d853f3b609f 100644 (file)
@@ -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);