-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 \
smtp-server-connection.c \
smtp-server.c \
smtp-submit-settings.c \
- smtp-submit.c
+ smtp-submit.c \
+ smtp-dovecot.c
headers = \
smtp-parser.h \
--- /dev/null
+/* 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));
+}
#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
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
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;
}
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;
}