]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
submission-login: Halt the handling of the AUTH commmand while the auth service is...
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 4 Nov 2025 23:04:09 +0000 (00:04 +0100)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Nov 2025 20:22:55 +0000 (20:22 +0000)
src/submission-login/client-authenticate.c
src/submission-login/client-authenticate.h
src/submission-login/client.c
src/submission-login/client.h

index 39a63f891647408a87b58c093e835f699bcc4a3d..89e7f872b5f0b7c398acd5bed7c925b742659ec2 100644 (file)
@@ -287,6 +287,7 @@ void submission_client_auth_send_challenge(struct client *client,
                container_of(client, struct submission_client, common);
        struct smtp_server_cmd_ctx *cmd = subm_client->auth_cmd;
 
+       i_assert(!subm_client->auth_cmd_implicit);
        i_assert(cmd != NULL);
 
        smtp_server_cmd_auth_send_challenge(cmd, data);
@@ -329,18 +330,49 @@ cmd_auth_set_master_data_prefix(struct submission_client *subm_client,
        client->master_data_prefix = buffer_free_without_data(&buf);
 }
 
+void cmd_auth_begin(struct submission_client *subm_client)
+{
+       subm_client->auth_cmd_deferred = FALSE;
+
+       if (subm_client->auth_cmd == NULL)
+               return;
+
+       struct client *client = &subm_client->common;
+
+       if (subm_client->auth_cmd_implicit) {
+               (void)client_auth_begin_implicit(client,
+                                                SASL_MECH_NAME_EXTERNAL, "=");
+       } else {
+               struct smtp_server_cmd_auth *data = subm_client->auth_cmd_data;
+
+               i_assert(data != NULL);
+               (void)client_auth_begin(client, data->sasl_mech,
+                                       data->initial_response);
+       }
+}
+
 int cmd_auth(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
             struct smtp_server_cmd_auth *data)
 {
        struct submission_client *subm_client = conn_ctx;
        struct client *client = &subm_client->common;
 
+       i_assert(!client->authenticating);
+
        cmd_auth_set_master_data_prefix(subm_client, NULL);
+       subm_client->auth_cmd_deferred = FALSE;
 
        i_assert(subm_client->auth_cmd == NULL);
        subm_client->auth_cmd = cmd;
+       subm_client->auth_cmd_data = data; /* allocated on cmd pool */
+       subm_client->auth_cmd_implicit = FALSE;
+
+       if (!auth_client_is_connected(auth_client)) {
+               subm_client->auth_cmd_deferred = TRUE;
+               return 0;
+       }
 
-       (void)client_auth_begin(client, data->sasl_mech, data->initial_response);
+       cmd_auth_begin(subm_client);
        return 0;
 }
 
@@ -362,15 +394,24 @@ void cmd_mail(struct smtp_server_cmd_ctx *cmd, const char *params)
                return;
        }
 
+       i_assert(!client->authenticating);
+
        e_debug(cmd->event,
                "Performing implicit EXTERNAL authentication");
 
        smtp_server_command_input_lock(cmd);
 
        cmd_auth_set_master_data_prefix(subm_client, params);
+       subm_client->auth_cmd_deferred = FALSE;
 
        i_assert(subm_client->auth_cmd == NULL);
        subm_client->auth_cmd = cmd;
+       subm_client->auth_cmd_implicit = TRUE;
+
+       if (!auth_client_is_connected(auth_client)) {
+               subm_client->auth_cmd_deferred = TRUE;
+               return;
+       }
 
-       (void)client_auth_begin_implicit(client, SASL_MECH_NAME_EXTERNAL, "=");
+       cmd_auth_begin(subm_client);
 }
index 8353b49f31b9afcfc770e8dba26f80bf9384c2d3..4f7ea6d0772d30becbbbc48a249734bfc43bf2fe 100644 (file)
@@ -13,6 +13,7 @@ int cmd_helo(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
             struct smtp_server_cmd_helo *data);
 int cmd_auth_continue(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
                      const char *response);
+void cmd_auth_begin(struct submission_client *subm_client);
 int cmd_auth(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
             struct smtp_server_cmd_auth *data);
 
index 1d920d1524a2ddbad411a14b0d81aeb78cc899c7..a42ab261ab8e7bed65c3503c09f8fdebc35e21e7 100644 (file)
@@ -168,6 +168,15 @@ static void submission_client_notify_auth_ready(struct client *client)
                smtp_server_connection_start(subm_client->conn);
 }
 
+static void submission_client_notify_auth_connected(struct client *client)
+{
+       struct submission_client *subm_client =
+               container_of(client, struct submission_client, common);
+
+       if (subm_client->auth_cmd_deferred)
+               cmd_auth_begin(subm_client);
+}
+
 static void
 submission_client_notify_disconnect(struct client *_client,
                                    enum client_disconnect_reason reason,
@@ -243,6 +252,7 @@ static void client_connection_disconnect(void *context, const char *reason)
        struct submission_client *client = context;
 
        client->auth_cmd = NULL;
+       client->auth_cmd_data = NULL;
        client_disconnect(&client->common, reason);
 }
 
@@ -323,6 +333,7 @@ static struct client_vfuncs submission_client_vfuncs = {
        .destroy = submission_client_destroy,
        .reload_config = submission_client_reload_config,
        .notify_auth_ready = submission_client_notify_auth_ready,
+       .notify_auth_connected = submission_client_notify_auth_connected,
        .notify_disconnect = submission_client_notify_disconnect,
        .auth_send_challenge = submission_client_auth_send_challenge,
        .auth_result = submission_client_auth_result,
index 731d912d95f3ab27c52e660853be334b7540d821..34f948f55f1860cea3a1a4de9d675f5cf1fe6316 100644 (file)
@@ -25,7 +25,9 @@ struct submission_client {
        enum smtp_capability backend_capabilities;
 
        struct smtp_server_connection *conn;
+
        struct smtp_server_cmd_ctx *auth_cmd;
+       struct smtp_server_cmd_auth *auth_cmd_data;
 
        enum submission_proxy_state proxy_state;
        enum smtp_capability proxy_capability;
@@ -34,6 +36,9 @@ struct submission_client {
        struct smtp_server_reply *proxy_reply;
        const char **proxy_xclient;
        unsigned int proxy_xclient_replies_expected;
+
+       bool auth_cmd_implicit:1;
+       bool auth_cmd_deferred:1;
 };
 
 #endif