]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: client: Make sending the XCLIENT command(s) always implicit and do it only...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 3 Dec 2018 17:45:43 +0000 (18:45 +0100)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Tue, 12 Feb 2019 13:42:07 +0000 (15:42 +0200)
For most servers, XCLIENT changes the ip:port identity of the client, causing it
to lose privileges to send more XCLIENT commands. For long XCLIENT commands
split in a series of XCLIENT commands, the ip:port parameters were sent last
already, so that did not cause problems even before this change. However, the
old code assumed it could update XCLIENT fields later on, which is often not
possible.

src/lib-smtp/smtp-client-connection.c
src/lib-smtp/smtp-client-connection.h
src/lib-smtp/smtp-client-private.h
src/submission/submission-backend-relay.c

index 0c2d217463dc63fbad756dfbb688625aa53a6ade..a37aa38d1f374f386546dc1eee68344814df11c3 100644 (file)
@@ -498,6 +498,8 @@ void smtp_client_connection_send_xclient(struct smtp_client_connection *conn)
 
        if (!conn->set.peer_trusted)
                return;
+       if (conn->xclient_sent)
+               return;
        if ((conn->caps.standard & SMTP_CAPABILITY_XCLIENT) == 0 ||
            conn->caps.xclient_args == NULL)
                return;
@@ -748,20 +750,14 @@ smtp_client_connection_authenticate(struct smtp_client_connection *conn)
        const char *init_resp, *error;
 
        if (set->username == NULL && set->sasl_mech == NULL) {
-               if (!conn->initial_xclient_sent && !conn->set.xclient_defer) {
-                       conn->initial_xclient_sent = TRUE;
+               if (!conn->set.xclient_defer)
                        smtp_client_connection_send_xclient(conn);
-               }
                return (conn->xclient_replies_expected == 0);
        }
 
-       if (!conn->initial_xclient_sent) {
-               conn->initial_xclient_sent = TRUE;
-               smtp_client_connection_send_xclient(conn);
-               if (conn->xclient_replies_expected > 0)
-                       return FALSE;
-       }
-
+       smtp_client_connection_send_xclient(conn);
+       if (conn->xclient_replies_expected > 0)
+               return FALSE;
        if (conn->authenticated)
                return TRUE;
 
@@ -2035,6 +2031,9 @@ void smtp_client_connection_update_proxy_data(
        struct smtp_client_connection *conn,
        const struct smtp_proxy_data *proxy_data)
 {
+       if (conn->xclient_sent)
+               return;
+
        smtp_proxy_data_merge(conn->pool, &conn->set.proxy_data, proxy_data);
 }
 
index 5bda237c375ea2319b5a576b3e7f8dfe62651310..74f5a668dd90c5ca2eafa136636ef6dbe1a1ad99 100644 (file)
@@ -68,7 +68,6 @@ void smtp_client_connection_uncork(struct smtp_client_connection *conn);
 void smtp_client_connection_connect(struct smtp_client_connection *conn,
        smtp_client_command_callback_t login_callback, void *login_context);
 void smtp_client_connection_disconnect(struct smtp_client_connection *conn);
-void smtp_client_connection_send_xclient(struct smtp_client_connection *conn);
 
 void smtp_client_connection_switch_ioloop(struct smtp_client_connection *conn);
 
index 0bfe8b3f924793cb16135c5bbc477f58bf74645e..4ecc2e018e862608e7430fd91db0af5d1bc210d1 100644 (file)
@@ -198,7 +198,7 @@ struct smtp_client_connection {
 
        bool old_smtp:1;
        bool authenticated:1;
-       bool initial_xclient_sent:1;
+       bool xclient_sent:1;
        bool connect_failed:1;
        bool connect_succeeded:1;
        bool handshake_failed:1;
@@ -263,6 +263,8 @@ struct connection_list *smtp_client_connection_list_init(void);
 const char *
 smpt_client_connection_label(struct smtp_client_connection *conn);
 
+void smtp_client_connection_send_xclient(struct smtp_client_connection *conn);
+
 void smtp_client_connection_fail(struct smtp_client_connection *conn,
                                 unsigned int status, const char *error);
 
index 6db7318453cc0dc77a92a1bb53979ff07a67b2b1..0c4b9113bc440064bda5dde00502c1627a0760af 100644 (file)
@@ -19,7 +19,6 @@ struct submission_backend_relay {
        struct smtp_client_connection *conn;
        struct smtp_client_transaction *trans;
 
-       bool xclient_sent:1;
        bool trans_started:1;
        bool trusted:1;
 };
@@ -240,9 +239,6 @@ relay_cmd_helo_update_xclient(struct submission_backend_relay *backend,
        i_zero(&proxy_data);
        proxy_data.helo = data->helo.domain;
        smtp_client_connection_update_proxy_data(backend->conn, &proxy_data);
-
-       smtp_client_connection_send_xclient(backend->conn);
-       backend->xclient_sent = TRUE;
 }
 
 static void
@@ -251,7 +247,6 @@ relay_cmd_helo_reply(struct smtp_server_cmd_ctx *cmd,
 {
        struct submission_backend_relay *backend = helo->backend;
 
-       /* relay an XCLIENT command */
        if (helo->data->changed)
                relay_cmd_helo_update_xclient(backend, helo->data);
 
@@ -293,7 +288,6 @@ relay_cmd_helo_start(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
 {
        struct submission_backend_relay *backend = helo->backend;
 
-       /* relay an XCLIENT command */
        if (helo->data->changed)
                relay_cmd_helo_update_xclient(backend, helo->data);
 }
@@ -334,31 +328,6 @@ struct relay_cmd_mail_context {
        struct smtp_client_transaction_mail *relay_mail;
 };
 
-static void
-relay_cmd_mail_update_xclient(struct submission_backend_relay *backend)
-{
-       struct client *client = backend->backend.client;
-       struct smtp_proxy_data proxy_data;
-       struct smtp_server_helo_data *helo_data =
-               smtp_server_connection_get_helo_data(client->conn);
-
-       if (backend->xclient_sent)
-               return;
-       if (!backend->trusted)
-               return;
-       if (helo_data->domain == NULL)
-               return;
-
-       i_zero(&proxy_data);
-       proxy_data.helo = helo_data->domain;
-       proxy_data.proto = SMTP_PROXY_PROTOCOL_ESMTP;
-       smtp_client_connection_update_proxy_data(backend->conn, &proxy_data);
-       
-       smtp_client_connection_send_xclient(backend->conn);
-       backend->xclient_sent = TRUE;
-}
-
-
 static void
 relay_cmd_mail_replied(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
                       struct relay_cmd_mail_context *mail_cmd)
@@ -464,8 +433,6 @@ backend_relay_cmd_mail(struct submission_backend *_backend,
        if (relay_cmd_mail_parameter_size(backend, cmd, relay_caps, data) < 0)
                return -1;
 
-       relay_cmd_mail_update_xclient(backend);
-
        /* queue command (pipeline) */
        mail_cmd = p_new(cmd->pool, struct relay_cmd_mail_context, 1);
        mail_cmd->backend = backend;
@@ -1059,6 +1026,7 @@ submission_backend_relay_create(
                                user->conn.remote_port;
                }
                smtp_set.proxy_data.login = user->username;
+               smtp_set.xclient_defer = TRUE;
        }
 
        smtp_set.username = set->user;