aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2019-09-20 19:56:36 +0200
committerGilles Chehade <gilles@poolp.org>2019-09-20 19:56:36 +0200
commitdbf8d71b2c686598d8424dbd0e40da254e458665 (patch)
tree49420227396cf3fa6dabaf91420647ed80c6cfe3
parentfix build (diff)
parentsync (diff)
downloadOpenSMTPD-dbf8d71b2c686598d8424dbd0e40da254e458665.tar.xz
OpenSMTPD-dbf8d71b2c686598d8424dbd0e40da254e458665.zip
Merge branch 'master' into portable
-rw-r--r--smtpd/config.c3
-rw-r--r--smtpd/lka_session.c27
-rw-r--r--smtpd/mta.c9
-rw-r--r--smtpd/mta_session.c24
-rw-r--r--smtpd/parse.y43
-rw-r--r--smtpd/smtpd.conf.520
-rw-r--r--smtpd/smtpd.h14
7 files changed, 128 insertions, 12 deletions
diff --git a/smtpd/config.c b/smtpd/config.c
index 0d80f2e3..20743527 100644
--- a/smtpd/config.c
+++ b/smtpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.49 2018/12/28 14:21:02 eric Exp $ */
+/* $OpenBSD: config.c,v 1.50 2019/09/20 17:46:05 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -62,6 +62,7 @@ config_default(void)
conf->sc_maxsize = DEFAULT_MAX_BODY_SIZE;
conf->sc_subaddressing_delim = SUBADDRESSING_DELIMITER;
conf->sc_ttl = SMTPD_QUEUE_EXPIRY;
+ conf->sc_srs_ttl = SMTPD_QUEUE_EXPIRY / 86400;
conf->sc_mta_max_deferred = 100;
conf->sc_scheduler_max_inflight = 5000;
diff --git a/smtpd/lka_session.c b/smtpd/lka_session.c
index bbb06de7..999e01d6 100644
--- a/smtpd/lka_session.c
+++ b/smtpd/lka_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka_session.c,v 1.92 2018/12/28 11:40:29 eric Exp $ */
+/* $OpenBSD: lka_session.c,v 1.93 2019/09/20 17:46:05 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
@@ -269,7 +269,8 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn)
int r;
union lookup lk;
char *tag;
-
+ const char *srs_decoded;
+
if (xn->depth >= EXPAND_DEPTH) {
log_trace(TRACE_EXPAND, "expand: lka_expand: node too deep.");
lks->error = LKA_PERMFAIL;
@@ -289,12 +290,32 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn)
"[depth=%d]",
xn->u.mailaddr.user, xn->u.mailaddr.domain, xn->depth);
- /* Pass the node through the ruleset */
+
ep = lks->envelope;
ep.dest = xn->u.mailaddr;
if (xn->parent) /* nodes with parent are forward addresses */
ep.flags |= EF_INTERNAL;
+ /* handle SRS */
+ if (env->sc_srs_key != NULL &&
+ ep.sender.user[0] == '\0' &&
+ (strncasecmp(ep.rcpt.user, "SRS0=", 5) == 0 ||
+ strncasecmp(ep.rcpt.user, "SRS1=", 5) == 0)) {
+ srs_decoded = srs_decode(mailaddr_to_text(&ep.rcpt));
+ if (srs_decoded &&
+ text_to_mailaddr(&ep.rcpt, srs_decoded)) {
+ /* flag envelope internal and override rcpt */
+ ep.flags |= EF_INTERNAL;
+ xn->u.mailaddr = ep.rcpt;
+ lks->envelope = ep;
+ }
+ else {
+ log_warn("SRS failed to decode: %s",
+ mailaddr_to_text(&ep.rcpt));
+ }
+ }
+
+ /* Pass the node through the ruleset */
rule = ruleset_match(&ep);
if (rule == NULL || rule->reject) {
lks->error = (errno == EAGAIN) ?
diff --git a/smtpd/mta.c b/smtpd/mta.c
index 98284443..0908db25 100644
--- a/smtpd/mta.c
+++ b/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.231 2019/09/18 11:26:30 eric Exp $ */
+/* $OpenBSD: mta.c,v 1.232 2019/09/20 17:46:05 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -1738,6 +1738,7 @@ mta_relay(struct envelope *e, struct relayhost *relayh)
key.sourcetable = dispatcher->u.remote.source;
key.helotable = dispatcher->u.remote.helo_source;
key.heloname = dispatcher->u.remote.helo;
+ key.srs = dispatcher->u.remote.srs;
if (relayh->hostname[0]) {
key.domain = mta_domain(relayh->hostname, 1);
@@ -1785,6 +1786,7 @@ mta_relay(struct envelope *e, struct relayhost *relayh)
r->helotable = xstrdup(key.helotable);
if (key.heloname)
r->heloname = xstrdup(key.heloname);
+ r->srs = key.srs;
SPLAY_INSERT(mta_relay_tree, &relays, r);
stat_increment("mta.relay", 1);
} else {
@@ -2092,6 +2094,11 @@ mta_relay_cmp(const struct mta_relay *a, const struct mta_relay *b)
if (a->backupname && ((r = strcmp(a->backupname, b->backupname))))
return (r);
+ if (a->srs < b->srs)
+ return (-1);
+ if (a->srs > b->srs)
+ return (1);
+
return (0);
}
diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c
index 0c258b4a..fa5be18f 100644
--- a/smtpd/mta_session.c
+++ b/smtpd/mta_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta_session.c,v 1.121 2019/09/18 11:26:30 eric Exp $ */
+/* $OpenBSD: mta_session.c,v 1.122 2019/09/20 17:46:05 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -531,8 +531,9 @@ mta_enter_state(struct mta_session *s, int newstate)
char ibuf[LINE_MAX];
char obuf[LINE_MAX];
int offset;
+ const char *srs_sender;
- again:
+again:
oldstate = s->state;
log_trace(TRACE_MTA, "mta: %p: %s -> %s", s,
@@ -730,6 +731,25 @@ mta_enter_state(struct mta_session *s, int newstate)
s->hangon = 0;
s->msgtried++;
envid_sz = strlen(e->dsn_envid);
+
+ /* SRS-encode if requested for the relay action, AND we're not
+ * bouncing, AND we have an RCPT which means we are forwarded,
+ * AND the RCPT has a '@' just for sanity check (will always).
+ */
+ if (env->sc_srs_key != NULL &&
+ s->relay->srs &&
+ strchr(s->task->sender, '@') &&
+ e->rcpt &&
+ strchr(e->rcpt, '@')) {
+ /* encode and replace task sender with new SRS-sender */
+ srs_sender = srs_encode(s->task->sender,
+ strchr(e->rcpt, '@') + 1);
+ if (srs_sender) {
+ free(s->task->sender);
+ s->task->sender = xstrdup(srs_sender);
+ }
+ }
+
if (s->ext & MTA_EXT_DSN) {
mta_send(s, "MAIL FROM:<%s>%s%s%s%s",
s->task->sender,
diff --git a/smtpd/parse.y b/smtpd/parse.y
index f9cf0c46..76180938 100644
--- a/smtpd/parse.y
+++ b/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.261 2019/09/06 08:23:56 martijn Exp $ */
+/* $OpenBSD: parse.y,v 1.262 2019/09/20 17:46:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -197,7 +197,7 @@ typedef struct {
%token PHASE PKI PORT PROC PROC_EXEC PROXY_V2
%token QUEUE QUIT
%token RCPT_TO RDNS RECIPIENT RECEIVEDAUTH REGEX RELAY REJECT REPORT REWRITE RSET
-%token SCHEDULER SENDER SENDERS SMTP SMTP_IN SMTP_OUT SMTPS SOCKET SRC SUB_ADDR_DELIM
+%token SCHEDULER SENDER SENDERS SMTP SMTP_IN SMTP_OUT SMTPS SOCKET SRC SRS SUB_ADDR_DELIM
%token TABLE TAG TAGGED TLS TLS_REQUIRE TTL
%token USER USERBASE
%token VERIFY VIRTUAL
@@ -223,6 +223,7 @@ grammar : /* empty */
| grammar queue '\n'
| grammar scheduler '\n'
| grammar smtp '\n'
+ | grammar srs '\n'
| grammar listen '\n'
| grammar table '\n'
| grammar dispatcher '\n'
@@ -543,6 +544,31 @@ SMTP LIMIT limits_smtp
}
;
+srs:
+SRS KEY STRING {
+ conf->sc_srs_key = $3;
+}
+SRS KEY BACKUP STRING {
+ conf->sc_srs_key_backup = $3;
+}
+| SRS TTL STRING {
+ conf->sc_srs_ttl = delaytonum($3);
+ if (conf->sc_srs_ttl == -1) {
+ yyerror("ttl delay \"%s\" is invalid", $3);
+ free($3);
+ YYERROR;
+ }
+
+ conf->sc_srs_ttl /= 86400;
+ if (conf->sc_srs_ttl == 0) {
+ yyerror("ttl delay \"%s\" is too short", $3);
+ free($3);
+ YYERROR;
+ }
+ free($3);
+}
+;
+
dispatcher_local_option:
USER STRING {
@@ -836,6 +862,18 @@ HELO STRING {
dispatcher->u.remote.auth = strdup(t->t_name);
}
+| SRS {
+ if (conf->sc_srs_key == NULL) {
+ yyerror("an srs key is required for srs to be specified in an action");
+ YYERROR;
+ }
+ if (dispatcher->u.remote.srs == 1) {
+ yyerror("srs already specified for this dispatcher");
+ YYERROR;
+ }
+
+ dispatcher->u.remote.srs = 1;
+}
;
dispatcher_remote_options:
@@ -2383,6 +2421,7 @@ lookup(char *s)
{ "smtps", SMTPS },
{ "socket", SOCKET },
{ "src", SRC },
+ { "srs", SRS },
{ "sub-addr-delim", SUB_ADDR_DELIM },
{ "table", TABLE },
{ "tag", TAG },
diff --git a/smtpd/smtpd.conf.5 b/smtpd/smtpd.conf.5
index 4de04c95..1da4189c 100644
--- a/smtpd/smtpd.conf.5
+++ b/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.224 2019/09/06 08:23:56 martijn Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.225 2019/09/20 17:46:05 gilles Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -17,7 +17,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\"
-.Dd $Mdocdate: September 6 2019 $
+.Dd $Mdocdate: September 20 2019 $
.Dt SMTPD.CONF 5
.Os
.Sh NAME
@@ -270,6 +270,9 @@ and
.Dq smtps
protocols for authentication.
Server certificates for those protocols are verified by default.
+.It Cm srs
+When relaying a mail resulting from a forward,
+use the Sender Rewriting Scheme to rewrite sender address.
.It Cm tls Op Cm no-verify
Require TLS to be used when relaying, using mandatory STARTTLS by default.
When used with a smarthost, the protocol must not be
@@ -842,6 +845,19 @@ When resolving the local part of a local email address, ignore the ASCII
and all characters following it.
The default is
.Ql + .
+.It Ic srs Cm key Ar secret
+Set the secret key to use for SRS,
+the Sender Rewriting Scheme.
+.It Ic srs Cm key backup Ar secret
+Set a backup secret key to use as a fallback for SRS.
+This can be used to implementation SRS key rotation.
+.It Ic srs Cm ttl Ar delay
+Set the time-to-live delay for SRS envelopes.
+After this delay,
+a bounce reply to the SRS address will be discarded to limit risks of forged addresses.
+The default is four days
+.Pq 4d .
+The delay
.It Ic table Ar name Oo Ar type : Oc Ns Ar pathname
Tables provide additional configuration information for
.Xr smtpd 8
diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h
index a54da734..ab4eb839 100644
--- a/smtpd/smtpd.h
+++ b/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.638 2019/09/19 07:35:36 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.639 2019/09/20 17:46:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -644,6 +644,10 @@ struct smtpd {
char *sc_tls_ciphers;
char *sc_subaddressing_delim;
+
+ char *sc_srs_key;
+ char *sc_srs_key_backup;
+ int sc_srs_ttl;
};
#define TRACE_DEBUG 0x0001
@@ -830,6 +834,7 @@ struct mta_relay {
char *helotable;
char *heloname;
char *secret;
+ int srs;
int state;
size_t ntask;
@@ -1188,6 +1193,8 @@ struct dispatcher_remote {
int backup;
char *backupmx;
+
+ int srs;
};
struct dispatcher_bounce {
@@ -1613,6 +1620,11 @@ void log_imsg(int, int, struct imsg *);
int fork_proc_backend(const char *, const char *, const char *);
+/* srs.c */
+const char *srs_encode(const char *, const char *);
+const char *srs_decode(const char *);
+
+
/* ssl_smtpd.c */
void *ssl_mta_init(void *, char *, off_t, const char *);
void *ssl_smtp_init(void *, int);