]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: Move Dovecot-specific redirect reply parsing and generation to smtp-dovecot.h.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Fri, 8 Oct 2021 22:58:13 +0000 (00:58 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 17 Jan 2022 11:52:09 +0000 (13:52 +0200)
src/lib-smtp/Makefile.am
src/lib-smtp/smtp-dovecot.c [new file with mode: 0644]
src/lib-smtp/smtp-dovecot.h
src/lmtp/lmtp-proxy.c

index 5b86281a8cae1ff46f40cb86179b570a535b515b..870654c20858531bf697db65cb2062813572c621 100644 (file)
@@ -6,6 +6,7 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-master \
        -I$(top_srcdir)/src/lib-sasl \
+       -I$(top_srcdir)/src/lib-auth \
        -I$(top_srcdir)/src/lib-ssl-iostream \
        -I$(top_srcdir)/src/lib-dns \
        -I$(top_srcdir)/src/lib-program-client \
@@ -46,7 +47,8 @@ libsmtp_la_SOURCES = \
        smtp-server-connection.c \
        smtp-server.c \
        smtp-submit-settings.c \
-       smtp-submit.c
+       smtp-submit.c \
+       smtp-dovecot.c
 
 headers = \
        smtp-parser.h \
diff --git a/src/lib-smtp/smtp-dovecot.c b/src/lib-smtp/smtp-dovecot.c
new file mode 100644 (file)
index 0000000..beb4b88
--- /dev/null
@@ -0,0 +1,77 @@
+/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "auth-proxy.h"
+#include "smtp-common.h"
+#include "smtp-reply.h"
+#include "smtp-server.h"
+#include "smtp-dovecot.h"
+
+bool smtp_reply_code_is_proxy_redirect(unsigned int code, const char *enh_code)
+{
+       return (code == 550 && enh_code != NULL &&
+               strcmp(enh_code, SMTP_PROXY_REDIRECT_ENH_CODE_STR) == 0);
+}
+
+bool smtp_reply_is_proxy_redirect(const struct smtp_reply *reply)
+{
+       return smtp_reply_code_equals(reply, SMTP_PROXY_REDIRECT_CODE,
+                                     SMTP_PROXY_REDIRECT_ENH_CODE);
+}
+
+int smtp_proxy_redirect_parse(const char *target, const char **destuser_r,
+                             const char **host_r, struct ip_addr *ip_r,
+                             in_port_t *port_r)
+{
+       const char *pend;
+
+       /* Skip <address> part of the reply if present (RCPT reply) */
+       pend = strchr(target, ' ');
+       if (*target == '<') {
+               if (pend == NULL)
+                       return -1;
+               target = pend + 1;
+               pend = strchr(target, ' ');
+       }
+       if (pend != NULL)
+               target = t_strdup_until(target, pend);
+
+       return (auth_proxy_parse_redirect(target, destuser_r, host_r,
+                                         ip_r, port_r) ? 0 : -1);
+}
+
+static const char *
+smtp_create_redirect_reply(const struct smtp_proxy_redirect *predir,
+                          in_port_t default_port)
+{
+       string_t *referral = t_str_new(128);
+
+       if (predir->username != NULL)
+               str_printfa(referral, "%s@", predir->username);
+       if (predir->port == default_port)
+               str_append(referral, predir->host);
+       else
+               str_printfa(referral, "%s:%u", predir->host, predir->port);
+       return str_c(referral);
+}
+
+void smtp_server_reply_redirect(struct smtp_server_cmd_ctx *cmd,
+                               in_port_t default_port,
+                               const struct smtp_proxy_redirect *predir)
+{
+       smtp_server_reply(cmd, SMTP_PROXY_REDIRECT_CODE,
+                         SMTP_PROXY_REDIRECT_ENH_CODE_STR,
+                         "%s Referral",
+                         smtp_create_redirect_reply(predir, default_port));
+}
+
+void smtp_server_recipient_reply_redirect(
+       struct smtp_server_recipient *rcpt, in_port_t default_port,
+       const struct smtp_proxy_redirect *predir)
+{
+       smtp_server_recipient_reply(
+               rcpt, SMTP_PROXY_REDIRECT_CODE,
+               SMTP_PROXY_REDIRECT_ENH_CODE_STR, "%s Referral",
+               smtp_create_redirect_reply(predir, default_port));
+}
index 4aacdeebba40e98189e5a2ca7b0cbebb91f427de..8d2dace993ed343780c384347f225ac63f14b4b9 100644 (file)
@@ -3,7 +3,32 @@
 
 #include "smtp-reply.h"
 
+#define SMTP_PROXY_REDIRECT_CODE         550
 #define SMTP_PROXY_REDIRECT_ENH_CODE     SMTP_REPLY_ENH_CODE(5, 2, 900)
 #define SMTP_PROXY_REDIRECT_ENH_CODE_STR "5.2.900"
 
+struct smtp_reply;
+struct smtp_server_cmd_ctx;
+struct smtp_server_recipient;
+
+struct smtp_proxy_redirect {
+       const char *username;
+       const char *host;
+       in_port_t port;
+};
+
+bool smtp_reply_code_is_proxy_redirect(unsigned int code, const char *enh_code);
+bool smtp_reply_is_proxy_redirect(const struct smtp_reply *reply);
+
+int smtp_proxy_redirect_parse(const char *target, const char **destuser_r,
+                             const char **host_r, struct ip_addr *ip_r,
+                             in_port_t *port_r);
+
+void smtp_server_reply_redirect(struct smtp_server_cmd_ctx *cmd,
+                               in_port_t default_port,
+                               const struct smtp_proxy_redirect *predir);
+void smtp_server_recipient_reply_redirect(
+       struct smtp_server_recipient *rcpt, in_port_t default_port,
+       const struct smtp_proxy_redirect *predir);
+
 #endif
index 9edc4d30bc354edec9e191189b9cf43a442fc0e4..dfc6a0fa517b844d8421fcc07cb1c250381827ee 100644 (file)
@@ -559,23 +559,10 @@ lmtp_proxy_rcpt_parse_redirect(const struct smtp_reply *proxy_reply,
                               const char **host_r, struct ip_addr *ip_r,
                               in_port_t *port_r)
 {
-       const char *target, *pend;
-
        if (proxy_reply->text_lines == NULL)
                return -1;
-       target = *proxy_reply->text_lines;
-       pend = strchr(target, ' ');
-       if (*target == '<') {
-               if (pend == NULL)
-                       return -1;
-               target = pend + 1;
-               pend = strchr(target, ' ');
-       }
-       if (pend != NULL)
-               target = t_strdup_until(target, pend);
-
-       return auth_proxy_parse_redirect(target, destuser_r, host_r,
-                                        ip_r, port_r) ? 0 : -1;
+       return smtp_proxy_redirect_parse(*proxy_reply->text_lines, destuser_r,
+                                        host_r, ip_r, port_r);
 }
 
 static void
@@ -757,8 +744,7 @@ lmtp_proxy_rcpt_cb(const struct smtp_reply *proxy_reply,
        if (!lmtp_proxy_handle_reply(lprcpt, proxy_reply, &reply))
                return;
 
-       if (smtp_reply_code_equals(proxy_reply, 550,
-                                  SMTP_PROXY_REDIRECT_ENH_CODE)) {
+       if (smtp_reply_is_proxy_redirect(proxy_reply)) {
                lmtp_proxy_rcpt_redirect(lprcpt, proxy_reply);
                return;
        }
@@ -857,13 +843,12 @@ lmtp_proxy_rcpt_handle_not_proxied(struct lmtp_proxy_recipient *lprcpt,
                return -1;
        }
 
-       string_t *referral = t_str_new(128);
-       if (destuser != NULL)
-               str_printfa(referral, "%s@", destuser);
-       str_printfa(referral, "%s:%u", set->set.host, set->set.port);
-       smtp_server_recipient_reply(
-               rcpt, 550, SMTP_PROXY_REDIRECT_ENH_CODE_STR,
-               "%s Referral", str_c(referral));
+       const struct smtp_proxy_redirect predir = {
+               .username = destuser,
+               .host = set->set.host,
+               .port = set->set.port,
+       };
+       smtp_server_recipient_reply_redirect(rcpt, 0, &predir);
        return -1;
 }