diff options
Diffstat (limited to 'usr.sbin/smtpd/to.c')
-rw-r--r-- | usr.sbin/smtpd/to.c | 85 |
1 files changed, 50 insertions, 35 deletions
diff --git a/usr.sbin/smtpd/to.c b/usr.sbin/smtpd/to.c index 498783c3420..5b62dbdfcee 100644 --- a/usr.sbin/smtpd/to.c +++ b/usr.sbin/smtpd/to.c @@ -1,4 +1,4 @@ -/* $OpenBSD: to.c,v 1.21 2015/10/28 07:25:30 gilles Exp $ */ +/* $OpenBSD: to.c,v 1.22 2015/11/30 12:53:08 gilles Exp $ */ /* * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net> @@ -33,7 +33,6 @@ #include <errno.h> #include <event.h> #include <fcntl.h> -#include <fts.h> #include <imsg.h> #include <limits.h> #include <inttypes.h> @@ -338,14 +337,15 @@ text_to_relayhost(struct relayhost *relay, const char *s) { "tls+auth://", F_STARTTLS|F_AUTH }, { "secure://", F_SMTPS|F_STARTTLS }, { "secure+auth://", F_SMTPS|F_STARTTLS|F_AUTH }, - { "backup://", F_BACKUP } + { "backup://", F_BACKUP }, + { "tls+backup://", F_BACKUP|F_STARTTLS } }; const char *errstr = NULL; char *p, *q; char buffer[1024]; - char *sep; + char *beg, *end; size_t i; - int len; + size_t len; memset(buffer, 0, sizeof buffer); if (strlcpy(buffer, s, sizeof buffer) >= sizeof buffer) @@ -374,40 +374,53 @@ text_to_relayhost(struct relayhost *relay, const char *s) if (relay->flags & F_LMTP) relay->port = 0; - if ((sep = strrchr(p, ':')) != NULL) { - *sep = 0; - relay->port = strtonum(sep+1, 1, 0xffff, &errstr); + /* first, we extract the label if any */ + if ((q = strchr(p, '@')) != NULL) { + *q = 0; + if (strlcpy(relay->authlabel, p, sizeof (relay->authlabel)) + >= sizeof (relay->authlabel)) + return 0; + p = q + 1; + } + + /* then, we extract the mail exchanger */ + beg = end = p; + if (*beg == '[') { + if ((end = strchr(beg, ']')) == NULL) + return 0; + /* skip ']', it has to be included in the relay hostname */ + ++end; + len = end - beg; + } + else { + for (end = beg; *end; ++end) + if (! isalnum((unsigned char)*end) && + *end != '_' && *end != '.' && *end != '-') + break; + len = end - beg; + } + if (len >= sizeof relay->hostname) + return 0; + for (i = 0; i < len; ++i) + relay->hostname[i] = beg[i]; + relay->hostname[i] = 0; + + /* finally, we extract the port */ + p = beg + len; + if (*p == ':') { + relay->port = strtonum(p+1, 1, 0xffff, &errstr); if (errstr) return 0; - len = sep - p; } - else - len = strlen(p); + if (! valid_domainpart(relay->hostname)) + return 0; if ((relay->flags & F_LMTP) && (relay->port == 0)) return 0; - - relay->hostname[len] = 0; - - q = strchr(p, '@'); - if (q == NULL && relay->flags & F_AUTH) + if (relay->authlabel[0] == '\0' && relay->flags & F_AUTH) return 0; - if (q && !(relay->flags & F_AUTH)) + if (relay->authlabel[0] != '\0' && !(relay->flags & F_AUTH)) return 0; - - if (q == NULL) { - if (strlcpy(relay->hostname, p, sizeof (relay->hostname)) - >= sizeof (relay->hostname)) - return 0; - } else { - *q = 0; - if (strlcpy(relay->authlabel, p, sizeof (relay->authlabel)) - >= sizeof (relay->authlabel)) - return 0; - if (strlcpy(relay->hostname, q + 1, sizeof (relay->hostname)) - >= sizeof (relay->hostname)) - return 0; - } return 1; } @@ -438,6 +451,9 @@ relayhost_to_text(const struct relayhost *relay) case F_SMTPS: (void)strlcat(buf, "smtps://", sizeof buf); break; + case F_BACKUP|F_STARTTLS: + (void)strlcat(buf, "tls+backup://", sizeof buf); + break; case F_BACKUP: (void)strlcat(buf, "backup://", sizeof buf); break; @@ -706,8 +722,6 @@ expandnode_to_text(struct expandnode *expandnode) return NULL; } - -/******/ static int alias_is_maildir(struct expandnode *alias, const char *line, size_t len) { @@ -718,12 +732,13 @@ alias_is_maildir(struct expandnode *alias, const char *line, size_t len) memset(alias, 0, sizeof *alias); alias->type = EXPAND_MAILDIR; if (strlcpy(alias->u.buffer, line, - sizeof(alias->u.buffer)) >= sizeof(alias->u.buffer)) + sizeof(alias->u.buffer)) >= sizeof(alias->u.buffer)) return (0); return (1); } +/******/ static int alias_is_filter(struct expandnode *alias, const char *line, size_t len) { @@ -760,7 +775,7 @@ alias_is_username(struct expandnode *alias, const char *line, size_t len) while (*line) { if (!isalnum((unsigned char)*line) && - *line != '_' && *line != '.' && *line != '-') + *line != '_' && *line != '.' && *line != '-' && *line != '+') return 0; ++line; } |