aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2019-09-20 19:56:25 +0200
committerGilles Chehade <gilles@poolp.org>2019-09-20 19:56:25 +0200
commitfe8dfb3fb3f31fe91555041d7412aaca71f501d3 (patch)
tree3d331dcd3748aee5960baa17ef6c2a24340fb6ef
parentsync (diff)
downloadOpenSMTPD-fe8dfb3fb3f31fe91555041d7412aaca71f501d3.tar.xz
OpenSMTPD-fe8dfb3fb3f31fe91555041d7412aaca71f501d3.zip
sync
-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 8b8b8570..cc53272a 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>
@@ -60,6 +60,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 ed17adcb..ed1fd36f 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>
@@ -267,7 +267,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;
@@ -287,12 +288,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 926b089a..6c817d00 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>
@@ -1735,6 +1735,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);
@@ -1782,6 +1783,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 {
@@ -2089,6 +2091,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 f5366623..72969e0a 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>
@@ -529,8 +529,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,
@@ -728,6 +729,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 e52077aa..4801d14f 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>
@@ -191,7 +191,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
@@ -217,6 +217,7 @@ grammar : /* empty */
| grammar queue '\n'
| grammar scheduler '\n'
| grammar smtp '\n'
+ | grammar srs '\n'
| grammar listen '\n'
| grammar table '\n'
| grammar dispatcher '\n'
@@ -537,6 +538,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 {
@@ -830,6 +856,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:
@@ -2377,6 +2415,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 e5a968e9..7ba6a472 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>
@@ -618,6 +618,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
@@ -804,6 +808,7 @@ struct mta_relay {
char *helotable;
char *heloname;
char *secret;
+ int srs;
int state;
size_t ntask;
@@ -1162,6 +1167,8 @@ struct dispatcher_remote {
int backup;
char *backupmx;
+
+ int srs;
};
struct dispatcher_bounce {
@@ -1587,6 +1594,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);