aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2019-11-26 08:20:06 +0100
committerGilles Chehade <gilles@poolp.org>2019-11-26 08:20:06 +0100
commit3ff8d6bc5376a8719dffa943e46f54dc46b93a84 (patch)
treedc0bd90642cc2dcea14b601b634ef4ad9eefd0e1
parentsync (diff)
downloadOpenSMTPD-3ff8d6bc5376a8719dffa943e46f54dc46b93a84.tar.xz
OpenSMTPD-3ff8d6bc5376a8719dffa943e46f54dc46b93a84.zip
sync
-rw-r--r--smtpd/bounce.c100
-rw-r--r--smtpd/envelope.c12
-rw-r--r--smtpd/parse.y98
-rw-r--r--smtpd/ruleset.c18
-rw-r--r--smtpd/smtp_session.c3
-rw-r--r--smtpd/smtpd.conf.548
-rw-r--r--smtpd/smtpd.h3
7 files changed, 217 insertions, 65 deletions
diff --git a/smtpd/bounce.c b/smtpd/bounce.c
index 02239988..4ce0ff71 100644
--- a/smtpd/bounce.c
+++ b/smtpd/bounce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bounce.c,v 1.80 2018/12/08 08:01:15 sunil Exp $ */
+/* $OpenBSD: bounce.c,v 1.81 2019/11/25 12:11:26 eric Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@poolp.org>
@@ -184,7 +184,7 @@ bounce_add(uint64_t evpid)
line = evp.errorline;
if (strlen(line) > 4 && (*line == '1' || *line == '6'))
line += 4;
- (void)snprintf(buf, sizeof(buf), "%s@%s: %s\n", evp.dest.user,
+ (void)snprintf(buf, sizeof(buf), "%s@%s: %s", evp.dest.user,
evp.dest.domain, line);
be = xmalloc(sizeof *be);
@@ -196,8 +196,7 @@ bounce_add(uint64_t evpid)
be->esc_class = evp.esc_class;
be->esc_code = evp.esc_code;
TAILQ_INSERT_TAIL(&msg->envelopes, be, entry);
- buf[strcspn(buf, "\n")] = '\0';
- log_debug("debug: bounce: adding report %16"PRIx64": %s", be->id, buf);
+ log_debug("debug: bounce: adding report %16"PRIx64": %s", be->id, be->report);
msg->timeout = time(NULL) + 1;
TAILQ_INSERT_TAIL(&pending, msg, entry);
@@ -311,7 +310,7 @@ bounce_send(struct bounce_session *s, const char *fmt, ...)
log_trace(TRACE_BOUNCE, "bounce: %p: >>> %s", s, p);
- io_xprintf(s->io, "%s\n", p);
+ io_xprintf(s->io, "%s\r\n", p);
free(p);
}
@@ -343,27 +342,27 @@ bounce_duration(long long int d)
}
#define NOTICE_INTRO \
- " Hi!\n\n" \
- " This is the MAILER-DAEMON, please DO NOT REPLY to this email.\n"
+ " Hi!\r\n\r\n" \
+ " This is the MAILER-DAEMON, please DO NOT REPLY to this email.\r\n"
const char *notice_error =
- " An error has occurred while attempting to deliver a message for\n"
- " the following list of recipients:\n\n";
+ " An error has occurred while attempting to deliver a message for\r\n"
+ " the following list of recipients:\r\n\r\n";
const char *notice_warning =
- " A message is delayed for more than %s for the following\n"
- " list of recipients:\n\n";
+ " A message is delayed for more than %s for the following\r\n"
+ " list of recipients:\r\n\r\n";
const char *notice_warning2 =
- " Please note that this is only a temporary failure report.\n"
- " The message is kept in the queue for up to %s.\n"
- " You DO NOT NEED to re-send the message to these recipients.\n\n";
+ " Please note that this is only a temporary failure report.\r\n"
+ " The message is kept in the queue for up to %s.\r\n"
+ " You DO NOT NEED to re-send the message to these recipients.\r\n\r\n";
const char *notice_success =
- " Your message was successfully delivered to these recipients.\n\n";
+ " Your message was successfully delivered to these recipients.\r\n\r\n";
const char *notice_relay =
- " Your message was relayed to these recipients.\n\n";
+ " Your message was relayed to these recipients.\r\n\r\n";
static int
bounce_next_message(struct bounce_session *s)
@@ -451,16 +450,16 @@ bounce_next(struct bounce_session *s)
/* Construct an appropriate notice. */
io_xprintf(s->io,
- "Subject: Delivery status notification: %s\n"
- "From: Mailer Daemon <MAILER-DAEMON@%s>\n"
- "To: %s\n"
- "Date: %s\n"
- "MIME-Version: 1.0\n"
+ "Subject: Delivery status notification: %s\r\n"
+ "From: Mailer Daemon <MAILER-DAEMON@%s>\r\n"
+ "To: %s\r\n"
+ "Date: %s\r\n"
+ "MIME-Version: 1.0\r\n"
"Content-Type: multipart/mixed;"
- "boundary=\"%16" PRIu64 "/%s\"\n"
- "\n"
- "This is a MIME-encapsulated message.\n"
- "\n",
+ "boundary=\"%16" PRIu64 "/%s\"\r\n"
+ "\r\n"
+ "This is a MIME-encapsulated message.\r\n"
+ "\r\n",
action_str(&s->msg->bounce),
s->smtpname,
s->msg->to,
@@ -469,12 +468,12 @@ bounce_next(struct bounce_session *s)
s->smtpname);
io_xprintf(s->io,
- "--%16" PRIu64 "/%s\n"
- "Content-Description: Notification\n"
- "Content-Type: text/plain; charset=us-ascii\n"
- "\n"
+ "--%16" PRIu64 "/%s\r\n"
+ "Content-Description: Notification\r\n"
+ "Content-Type: text/plain; charset=us-ascii\r\n"
+ "\r\n"
NOTICE_INTRO
- "\n",
+ "\r\n",
s->boundary, s->smtpname);
switch (s->msg->bounce.type) {
@@ -495,35 +494,36 @@ bounce_next(struct bounce_session *s)
TAILQ_FOREACH(evp, &s->msg->envelopes, entry) {
io_xprint(s->io, evp->report);
+ io_xprint(s->io, "\r\n");
}
- io_xprint(s->io, "\n");
+ io_xprint(s->io, "\r\n");
if (s->msg->bounce.type == B_DELAYED)
io_xprintf(s->io, notice_warning2,
bounce_duration(s->msg->bounce.ttl));
io_xprintf(s->io,
- " Below is a copy of the original message:\n"
- "\n");
+ " Below is a copy of the original message:\r\n"
+ "\r\n");
io_xprintf(s->io,
- "--%16" PRIu64 "/%s\n"
- "Content-Description: Delivery Report\n"
- "Content-Type: message/delivery-status\n"
- "\n",
+ "--%16" PRIu64 "/%s\r\n"
+ "Content-Description: Delivery Report\r\n"
+ "Content-Type: message/delivery-status\r\n"
+ "\r\n",
s->boundary, s->smtpname);
io_xprintf(s->io,
- "Reporting-MTA: dns; %s\n"
- "\n",
+ "Reporting-MTA: dns; %s\r\n"
+ "\r\n",
s->smtpname);
TAILQ_FOREACH(evp, &s->msg->envelopes, entry) {
io_xprintf(s->io,
- "Final-Recipient: rfc822; %s@%s\n"
- "Action: %s\n"
- "Status: %s\n"
- "\n",
+ "Final-Recipient: rfc822; %s@%s\r\n"
+ "Action: %s\r\n"
+ "Status: %s\r\n"
+ "\r\n",
evp->dest.user,
evp->dest.domain,
action_str(&s->msg->bounce),
@@ -538,10 +538,10 @@ bounce_next(struct bounce_session *s)
case BOUNCE_DATA_MESSAGE:
io_xprintf(s->io,
- "--%16" PRIu64 "/%s\n"
- "Content-Description: Message headers\n"
- "Content-Type: text/rfc822-headers\n"
- "\n",
+ "--%16" PRIu64 "/%s\r\n"
+ "Content-Description: Message headers\r\n"
+ "Content-Type: text/rfc822-headers\r\n"
+ "\r\n",
s->boundary, s->smtpname);
n = io_queued(s->io);
@@ -555,14 +555,14 @@ bounce_next(struct bounce_session *s)
fclose(s->msgfp);
s->msgfp = NULL;
io_xprintf(s->io,
- "\n--%16" PRIu64 "/%s--\n", s->boundary,
+ "\r\n--%16" PRIu64 "/%s--\r\n", s->boundary,
s->smtpname);
bounce_send(s, ".");
s->state = BOUNCE_DATA_END;
return (0);
}
line[len - 1] = '\0';
- io_xprintf(s->io, "%s%s\n",
+ io_xprintf(s->io, "%s%s\r\n",
(len == 2 && line[0] == '.') ? "." : "", line);
}
free(line);
@@ -577,7 +577,7 @@ bounce_next(struct bounce_session *s)
}
io_xprintf(s->io,
- "\n--%16" PRIu64 "/%s--\n", s->boundary, s->smtpname);
+ "\r\n--%16" PRIu64 "/%s--\r\n", s->boundary, s->smtpname);
log_trace(TRACE_BOUNCE, "bounce: %p: >>> [... %zu bytes ...]",
s, io_queued(s->io) - n);
diff --git a/smtpd/envelope.c b/smtpd/envelope.c
index 01957dc5..05a239e1 100644
--- a/smtpd/envelope.c
+++ b/smtpd/envelope.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: envelope.c,v 1.46 2019/09/19 16:00:59 gilles Exp $ */
+/* $OpenBSD: envelope.c,v 1.47 2019/11/25 14:18:32 gilles Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -177,6 +177,7 @@ envelope_dump_buffer(const struct envelope *ep, char *dest, size_t len)
envelope_ascii_dump(ep, &dest, &len, "smtpname");
envelope_ascii_dump(ep, &dest, &len, "helo");
envelope_ascii_dump(ep, &dest, &len, "hostname");
+ envelope_ascii_dump(ep, &dest, &len, "username");
envelope_ascii_dump(ep, &dest, &len, "errorline");
envelope_ascii_dump(ep, &dest, &len, "sockaddr");
envelope_ascii_dump(ep, &dest, &len, "sender");
@@ -400,6 +401,9 @@ ascii_load_field(const char *field, struct envelope *ep, char *buf)
if (strcasecmp("dest", field) == 0)
return ascii_load_mailaddr(&ep->dest, buf);
+ if (strcasecmp("username", field) == 0)
+ return ascii_load_string(ep->username, buf, sizeof(ep->username));
+
if (strcasecmp("errorline", field) == 0)
return ascii_load_string(ep->errorline, buf,
sizeof ep->errorline);
@@ -646,6 +650,12 @@ ascii_dump_field(const char *field, const struct envelope *ep,
if (strcasecmp(field, "dest") == 0)
return ascii_dump_mailaddr(&ep->dest, buf, len);
+ if (strcasecmp(field, "username") == 0) {
+ if (ep->username[0])
+ return ascii_dump_string(ep->username, buf, len);
+ return 1;
+ }
+
if (strcasecmp(field, "errorline") == 0)
return ascii_dump_string(ep->errorline, buf, len);
diff --git a/smtpd/parse.y b/smtpd/parse.y
index 2fff100e..f94b4685 100644
--- a/smtpd/parse.y
+++ b/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.263 2019/09/22 11:49:53 semarie Exp $ */
+/* $OpenBSD: parse.y,v 1.265 2019/11/26 06:10:20 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -1227,7 +1227,47 @@ negation TAG REGEX tables {
rule->flag_from_rdns = 1;
rule->table_from = strdup(t->t_name);
}
+| negation FROM MAIL_FROM tables {
+ struct table *anyhost = table_find(conf, "<anyhost>");
+ struct table *t = $4;
+ if (rule->flag_from) {
+ yyerror("from already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST, K_MAILADDR)) {
+ yyerror("table \"%s\" may not be used for from lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_from = 1;
+ rule->table_from = strdup(anyhost->t_name);
+ rule->flag_smtp_mail_from = $1 ? -1 : 1;
+ rule->table_smtp_mail_from = strdup(t->t_name);
+}
+| negation FROM MAIL_FROM REGEX tables {
+ struct table *anyhost = table_find(conf, "<anyhost>");
+ struct table *t = $5;
+
+ if (rule->flag_from) {
+ yyerror("from already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST, K_REGEX)) {
+ yyerror("table \"%s\" may not be used for from lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_from = 1;
+ rule->table_from = strdup(anyhost->t_name);
+ rule->flag_smtp_mail_from = $1 ? -1 : 1;
+ rule->flag_smtp_mail_from_regex = 1;
+ rule->table_smtp_mail_from = strdup(t->t_name);
+}
| negation FOR LOCAL {
struct table *t = table_find(conf, "<localnames>");
@@ -1284,6 +1324,47 @@ negation TAG REGEX tables {
rule->flag_for_regex = 1;
rule->table_for = strdup(t->t_name);
}
+| negation FOR RCPT_TO tables {
+ struct table *anyhost = table_find(conf, "<anydestination>");
+ struct table *t = $4;
+
+ if (rule->flag_for) {
+ yyerror("for already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST, K_MAILADDR)) {
+ yyerror("table \"%s\" may not be used for for lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_for = 1;
+ rule->table_for = strdup(anyhost->t_name);
+ rule->flag_smtp_rcpt_to = $1 ? -1 : 1;
+ rule->table_smtp_rcpt_to = strdup(t->t_name);
+}
+| negation FOR RCPT_TO REGEX tables {
+ struct table *anyhost = table_find(conf, "<anydestination>");
+ struct table *t = $5;
+
+ if (rule->flag_for) {
+ yyerror("for already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST, K_REGEX)) {
+ yyerror("table \"%s\" may not be used for for lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_for = 1;
+ rule->table_for = strdup(anyhost->t_name);
+ rule->flag_smtp_rcpt_to = $1 ? -1 : 1;
+ rule->flag_smtp_rcpt_to_regex = 1;
+ rule->table_smtp_rcpt_to = strdup(t->t_name);
+}
;
match_options:
@@ -1875,6 +1956,20 @@ opt_sock_listen : FILTER STRING {
YYERROR;
}
}
+ | TAG STRING {
+ if (listen_opts.options & LO_TAG) {
+ yyerror("tag already specified");
+ YYERROR;
+ }
+ listen_opts.options |= LO_TAG;
+
+ if (strlen($2) >= SMTPD_TAG_SIZE) {
+ yyerror("tag name too long");
+ free($2);
+ YYERROR;
+ }
+ listen_opts.tag = $2;
+ }
;
opt_if_listen : INET4 {
@@ -2915,7 +3010,6 @@ static void
create_sock_listener(struct listen_opts *lo)
{
struct listener *l = xcalloc(1, sizeof(*l));
- lo->tag = "local";
lo->hostname = conf->sc_hostname;
l->ss.ss_family = AF_LOCAL;
l->ss.ss_len = sizeof(struct sockaddr *);
diff --git a/smtpd/ruleset.c b/smtpd/ruleset.c
index db9d1aa5..869d8115 100644
--- a/smtpd/ruleset.c
+++ b/smtpd/ruleset.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ruleset.c,v 1.46 2019/11/12 20:21:46 gilles Exp $ */
+/* $OpenBSD: ruleset.c,v 1.47 2019/11/25 14:18:33 gilles Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@poolp.org>
@@ -152,6 +152,8 @@ static int
ruleset_match_smtp_auth(struct rule *r, const struct envelope *evp)
{
int ret;
+ struct table *table;
+ enum table_service service;
if (!r->flag_smtp_auth)
return 1;
@@ -159,14 +161,14 @@ ruleset_match_smtp_auth(struct rule *r, const struct envelope *evp)
if (!(evp->flags & EF_AUTHENTICATED))
ret = 0;
else if (r->table_smtp_auth) {
- /* XXX - not until smtp_session->username is added to envelope */
- /*
- * table = table_find(m->from_table);
- * key = evp->username;
- * return table_match(table, K_CREDENTIALS, key);
- */
- return -1;
+ if (r->flag_smtp_auth_regex)
+ service = K_REGEX;
+ else
+ service = strchr(evp->username, '@') ?
+ K_MAILADDR : K_STRING;
+ table = table_find(env, r->table_smtp_auth);
+ ret = table_match(table, service, evp->username);
}
else
ret = 1;
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index c6a6d52d..dfefdae9 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.415 2019/10/04 08:34:29 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.416 2019/11/25 14:18:33 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -2385,6 +2385,7 @@ smtp_tx(struct smtp_session *s)
(void)strlcpy(tx->evp.smtpname, s->smtpname, sizeof(tx->evp.smtpname));
(void)strlcpy(tx->evp.hostname, s->rdns, sizeof tx->evp.hostname);
(void)strlcpy(tx->evp.helo, s->helo, sizeof(tx->evp.helo));
+ (void)strlcpy(tx->evp.username, s->username, sizeof(tx->evp.username));
if (s->flags & SF_BOUNCE)
tx->evp.flags |= EF_BOUNCE;
diff --git a/smtpd/smtpd.conf.5 b/smtpd/smtpd.conf.5
index ca4087c3..f8a9f0e0 100644
--- a/smtpd/smtpd.conf.5
+++ b/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.228 2019/11/19 22:04:04 gilles Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.230 2019/11/26 06:10:20 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: November 19 2019 $
+.Dd $Mdocdate: November 26 2019 $
.Dt SMTPD.CONF 5
.Os
.Sh NAME
@@ -588,6 +588,20 @@ Specify that session may address the regex or regex table
.Ar domain .
.It Xo
.Op Ic \&!
+.Cm for rcpt-to
+.Ar recipient | Pf < Ar recipient Ns >
+.Xc
+Specify that session may address the string or list table
+.Ar recipient .
+.It Xo
+.Op Ic \&!
+.Cm for rcpt-to regex
+.Ar recipient | Pf < Ar recipient Ns >
+.Xc
+Specify that session may address the regex or regex table
+.Ar recipient .
+.It Xo
+.Op Ic \&!
.Cm from any
.Xc
Specify that session may originate from any source.
@@ -600,6 +614,22 @@ or from the local enqueuer.
This is the default, and may be omitted.
.It Xo
.Op Ic \&!
+.Cm from mail-from
+.Ar sender | Pf < Ar sender Ns >
+.Xc
+Specify that session may originate from sender or sender list
+.Ar sender ,
+no matter the source IP address.
+.It Xo
+.Op Ic \&!
+.Cm from mail-from regex
+.Ar sender | Pf < Ar sender Ns >
+.Xc
+Specify that session may originate from regex or regex list
+.Ar sender ,
+no matter the source IP address.
+.It Xo
+.Op Ic \&!
.Cm from rdns
.Xc
Specify that session may only originate from an IP address that
@@ -652,6 +682,20 @@ In addition, the following transaction options:
Matches transactions which have been authenticated.
.It Xo
.Op Ic \&!
+.Cm auth
+.Ar username | Pf < Ar username Ns >
+.Xc
+Matches transactions which have been authenticated for user or user list
+.Ar username .
+.It Xo
+.Op Ic \&!
+.Cm auth regex
+.Ar username | Pf < Ar username Ns >
+.Xc
+Matches transactions which have been authenticated for regex or regex list
+.Ar username .
+.It Xo
+.Op Ic \&!
.Cm helo
.Ar helo-name | Pf < Ar helo-name Ns >
.Xc
diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h
index b1c8fe37..39ca485a 100644
--- a/smtpd/smtpd.h
+++ b/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.642 2019/11/03 23:58:51 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.643 2019/11/25 14:18:33 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -489,6 +489,7 @@ struct envelope {
char smtpname[HOST_NAME_MAX+1];
char helo[HOST_NAME_MAX+1];
char hostname[HOST_NAME_MAX+1];
+ char username[SMTPD_MAXMAILADDRSIZE];
char errorline[LINE_MAX];
struct sockaddr_storage ss;