From: Stephan Bosch Date: Mon, 3 Dec 2018 17:45:43 +0000 (+0100) Subject: lib-smtp: client: Make sending the XCLIENT command(s) always implicit and do it only... X-Git-Tag: 2.3.9~1009 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b65b580e2ab15d8bfab789cef108eae5164ce3f6;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: client: Make sending the XCLIENT command(s) always implicit and do it only once. 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. --- diff --git a/src/lib-smtp/smtp-client-connection.c b/src/lib-smtp/smtp-client-connection.c index 5e8a24af31..471ed21cc7 100644 --- a/src/lib-smtp/smtp-client-connection.c +++ b/src/lib-smtp/smtp-client-connection.c @@ -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); } diff --git a/src/lib-smtp/smtp-client-connection.h b/src/lib-smtp/smtp-client-connection.h index 5bda237c37..74f5a668dd 100644 --- a/src/lib-smtp/smtp-client-connection.h +++ b/src/lib-smtp/smtp-client-connection.h @@ -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); diff --git a/src/lib-smtp/smtp-client-private.h b/src/lib-smtp/smtp-client-private.h index 0bfe8b3f92..4ecc2e018e 100644 --- a/src/lib-smtp/smtp-client-private.h +++ b/src/lib-smtp/smtp-client-private.h @@ -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); diff --git a/src/submission/submission-backend-relay.c b/src/submission/submission-backend-relay.c index 6db7318453..0c4b9113bc 100644 --- a/src/submission/submission-backend-relay.c +++ b/src/submission/submission-backend-relay.c @@ -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;