]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: smtp-client-connection - Explicitly specify which MAIL/RCPT parameters...
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 30 Mar 2021 19:06:58 +0000 (21:06 +0200)
committerMarkus Valentin <markus.valentin@open-xchange.com>
Tue, 20 Apr 2021 10:30:17 +0000 (12:30 +0200)
This is used in later commit to limit which custom parameters are actually sent
to the server based on the capabilities supported by said server.

src/lib-smtp/smtp-client-connection.c
src/lib-smtp/smtp-client-private.h
src/lib-smtp/smtp-client.h
src/lmtp/lmtp-proxy.c

index f273c0beee9fedbfaf1bf70aa4c80499ffd30ca1..ff07d628c54841120151b4ed435b424bb9b75a4f 100644 (file)
@@ -89,6 +89,15 @@ void smtp_client_connection_accept_extra_capability(
                .name = p_strdup(conn->pool, cap->name),
        };
 
+       if (cap->mail_param_extensions != NULL) {
+               cap_new.mail_param_extensions =
+                       p_strarray_dup(conn->pool, cap->mail_param_extensions);
+       }
+       if (cap->rcpt_param_extensions != NULL) {
+               cap_new.rcpt_param_extensions =
+                       p_strarray_dup(conn->pool, cap->rcpt_param_extensions);
+       }
+
        array_push_back(&conn->extra_capabilities, &cap_new);
 }
 
@@ -899,6 +908,41 @@ smtp_client_connection_starttls(struct smtp_client_connection *conn)
        return smtp_client_connection_authenticate(conn);
 }
 
+static void
+smtp_client_connection_record_param_extensions(
+       struct smtp_client_connection *conn, ARRAY_TYPE(const_string) *arr,
+       const char *const *extensions)
+{
+       pool_t pool = conn->cap_pool;
+
+       if (extensions == NULL || *extensions == NULL)
+               return;
+
+       if (!array_is_created(arr))
+               p_array_init(arr, pool, 4);
+       else {
+               const char *const *end;
+
+               /* Drop end marker */
+               i_assert(array_count(arr) > 0);
+               end = array_back(arr);
+               i_assert(*end == NULL);
+               array_pop_back(arr);
+       }
+
+       const char *const *new_p;
+       for (new_p = extensions; *new_p != NULL; new_p++) {
+               /* Drop duplicates */
+               if (array_lsearch(arr, new_p, i_strcasecmp_p) != NULL)
+                       continue;
+
+               array_push_back(arr, new_p);
+       }
+
+       /* Add new end marker */
+       array_append_zero(arr);
+}
+
 static void
 smtp_client_connection_record_extra_capability(
        struct smtp_client_connection *conn, const char *cap_name,
@@ -923,6 +967,13 @@ smtp_client_connection_record_extra_capability(
        cap_extra.params = p_strarray_dup(pool, params);
 
        array_push_back(&conn->caps.extra, &cap_extra);
+
+       smtp_client_connection_record_param_extensions(
+               conn, &conn->caps.mail_param_extensions,
+               ccap_extra->mail_param_extensions);
+       smtp_client_connection_record_param_extensions(
+               conn, &conn->caps.rcpt_param_extensions,
+               ccap_extra->rcpt_param_extensions);
 }
 
 static void
index 5292a9d7f5a466152c44d54384e2710d61204ad4..2cac23636ae7eb490d4cdbf8b84b7217db7e0734 100644 (file)
@@ -183,6 +183,11 @@ struct smtp_client_connection {
                const char **auth_mechanisms;
                const char **xclient_args;
                uoff_t size;
+
+               /* Lists of custom MAIL/RCPT parameters supported by peer. These
+                  arrays always end in NULL pointer once created. */
+               ARRAY_TYPE(const_string) mail_param_extensions;
+               ARRAY_TYPE(const_string) rcpt_param_extensions;
        } caps;
 
        struct smtp_reply_parser *reply_parser;
index 1717a221d9f9d73016edebb7cb447ab61fd14eb4..3fdc5c63fdd8193c9e50c5660239ede97837e605 100644 (file)
@@ -39,6 +39,11 @@ enum smtp_client_command_error {
 
 struct smtp_client_capability_extra {
        const char *name;
+
+       /* Send these additional custom MAIL parameters if available. */
+       const char *const *mail_param_extensions;
+       /* Send these additional custom RCPT parameters if available. */
+       const char *const *rcpt_param_extensions;
 };
 
 struct smtp_client_settings {
index 7074949a8c2deb8897ac52d6a733016436d2bb9d..11984b7f3a4fc9fb913994acc56c19e2edd27236 100644 (file)
@@ -222,8 +222,11 @@ static struct lmtp_proxy_connection *
 lmtp_proxy_get_connection(struct lmtp_proxy *proxy,
                          const struct lmtp_proxy_rcpt_settings *set)
 {
+       static const char *rcpt_param_extensions[] =
+               { LMTP_RCPT_FORWARD_PARAMETER, NULL };
        static const struct smtp_client_capability_extra cap_rcpt_forward = {
                .name = LMTP_RCPT_FORWARD_CAPABILITY,
+               .rcpt_param_extensions = rcpt_param_extensions,
        };
        struct smtp_client_settings lmtp_set;
        struct smtp_server_transaction *trans = proxy->trans;