diff options
author | Gilles Chehade <gilles@poolp.org> | 2019-11-26 08:20:29 +0100 |
---|---|---|
committer | Gilles Chehade <gilles@poolp.org> | 2019-11-26 08:20:29 +0100 |
commit | 7693069bd466757ccf2f019c5c3c18ffd85a7945 (patch) | |
tree | 6cdba9a32f10aea571df9e3538248a11a943a2a4 | |
parent | Merge branch 'master' into portable (diff) | |
parent | sync (diff) | |
download | OpenSMTPD-7693069bd466757ccf2f019c5c3c18ffd85a7945.tar.xz OpenSMTPD-7693069bd466757ccf2f019c5c3c18ffd85a7945.zip |
Merge branch 'master' into portable
-rw-r--r-- | smtpd/bounce.c | 100 | ||||
-rw-r--r-- | smtpd/envelope.c | 12 | ||||
-rw-r--r-- | smtpd/parse.y | 98 | ||||
-rw-r--r-- | smtpd/ruleset.c | 18 | ||||
-rw-r--r-- | smtpd/smtp_session.c | 3 | ||||
-rw-r--r-- | smtpd/smtpd.conf.5 | 48 | ||||
-rw-r--r-- | smtpd/smtpd.h | 3 |
7 files changed, 217 insertions, 65 deletions
diff --git a/smtpd/bounce.c b/smtpd/bounce.c index 41526d8d..86555cad 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> @@ -186,7 +186,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); @@ -198,8 +198,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); @@ -313,7 +312,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); } @@ -345,27 +344,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) @@ -453,16 +452,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, @@ -471,12 +470,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) { @@ -497,35 +496,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), @@ -540,10 +540,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); @@ -557,14 +557,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); @@ -579,7 +579,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 c02a0e75..35d98b79 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> @@ -179,6 +179,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"); @@ -408,6 +409,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); @@ -654,6 +658,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 e7ee2c8c..ea894b89 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> @@ -1233,7 +1233,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>"); @@ -1290,6 +1330,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: @@ -1881,6 +1962,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 { @@ -2921,7 +3016,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; #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN diff --git a/smtpd/ruleset.c b/smtpd/ruleset.c index 2eae58c0..719a2913 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> @@ -154,6 +154,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; @@ -161,14 +163,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 d2487807..9b6e2d27 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> @@ -2394,6 +2394,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 e81da539..86481f94 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> @@ -515,6 +515,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; |