diff options
author | Gilles Chehade <gilles@poolp.org> | 2015-02-01 22:59:54 +0100 |
---|---|---|
committer | Gilles Chehade <gilles@poolp.org> | 2015-02-01 22:59:54 +0100 |
commit | e790330128f64deb4814272c86b55c60d9f2f543 (patch) | |
tree | c8ad39ddfdc4e96fe0a4280b89c15428d53e23bc | |
parent | make auth part of TLS line (diff) | |
download | OpenSMTPD-e790330128f64deb4814272c86b55c60d9f2f543.tar.xz OpenSMTPD-e790330128f64deb4814272c86b55c60d9f2f543.zip |
add support for multi-sender senders tableopensmtpd-201502012303
-rw-r--r-- | smtpd/lka.c | 21 | ||||
-rw-r--r-- | smtpd/mailaddr.c | 133 | ||||
-rw-r--r-- | smtpd/makemap/Makefile | 1 | ||||
-rw-r--r-- | smtpd/smtpd.h | 17 | ||||
-rw-r--r-- | smtpd/smtpd/Makefile | 1 | ||||
-rw-r--r-- | smtpd/table.c | 12 | ||||
-rw-r--r-- | smtpd/util.c | 4 |
7 files changed, 184 insertions, 5 deletions
diff --git a/smtpd/lka.c b/smtpd/lka.c index 126dc319..7b9e8359 100644 --- a/smtpd/lka.c +++ b/smtpd/lka.c @@ -668,8 +668,11 @@ lka_addrname(const char *tablename, const struct sockaddr *sa, static int lka_mailaddrmap(const char *tablename, const char *username, const struct mailaddr *maddr) { - struct table *table; - union lookup lk; + struct table *table; + struct maddrmap *mm; + struct maddrnode *mn; + union lookup lk; + int found; log_debug("debug: lka: mailaddrmap %s:%s", tablename, username); table = table_find(tablename, NULL); @@ -686,8 +689,18 @@ lka_mailaddrmap(const char *tablename, const char *username, const struct mailad case 0: return (LKA_PERMFAIL); default: - if (! mailaddr_match(maddr, &lk.mailaddr)) - return (LKA_PERMFAIL); + mm = lk.maddrmap; + found = 0; + TAILQ_FOREACH(mn, &lk.maddrmap->queue, entries) { + if (! mailaddr_match(maddr, &mn->mailaddr)) + continue; + found = 1; + break; + } + maddrmap_free(lk.maddrmap); + if (found) + return (LKA_OK); + return (LKA_PERMFAIL); } return (LKA_OK); } diff --git a/smtpd/mailaddr.c b/smtpd/mailaddr.c new file mode 100644 index 00000000..51dc061d --- /dev/null +++ b/smtpd/mailaddr.c @@ -0,0 +1,133 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2015 Gilles Chehade <gilles@poolp.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/tree.h> +#include <sys/socket.h> + +#include <ctype.h> +#include <event.h> +#include <imsg.h> +#include <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +#include "smtpd.h" +#include "log.h" + +static int +mailaddr_line_split(char **line, char **ret) +{ + static char buffer[LINE_MAX]; + int esc, dq, sq; + size_t i; + char *s; + + memset(buffer, 0, sizeof buffer); + esc = dq = sq = 0; + i = 0; + for (s = *line; (*s) && (i < sizeof(buffer)); ++s) { + if (esc) { + buffer[i++] = *s; + esc = 0; + continue; + } + if (*s == '\\') { + esc = 1; + continue; + } + if (*s == ',' && !dq && !sq) { + *ret = buffer; + *line = s+1; + return (1); + } + + buffer[i++] = *s; + esc = 0; + + if (*s == '"' && !sq) + dq ^= 1; + if (*s == '\'' && !dq) + sq ^= 1; + } + + if (esc || dq || sq || i == sizeof(buffer)) + return (-1); + + *ret = buffer; + *line = s; + return (i ? 1 : 0); +} + +int +mailaddr_line(struct maddrmap *maddrmap, const char *s) +{ + struct maddrnode mn; + char buffer[LINE_MAX]; + char *p, *subrcpt; + int ret; + + memset(buffer, 0, sizeof buffer); + if (strlcpy(buffer, s, sizeof buffer) >= sizeof buffer) + return 0; + + p = buffer; + while ((ret = mailaddr_line_split(&p, &subrcpt)) > 0) { + subrcpt = strip(subrcpt); + if (subrcpt[0] == '\0') + continue; + if (! text_to_mailaddr(&mn.mailaddr, subrcpt)) + return 0; + log_debug("subrcpt: [%s]", subrcpt); + maddrmap_insert(maddrmap, &mn); + } + + if (ret >= 0) + return 1; + /* expand_line_split() returned < 0 */ + return 0; +} + +void +maddrmap_init(struct maddrmap *maddrmap) +{ + TAILQ_INIT(&maddrmap->queue); +} + +void +maddrmap_insert(struct maddrmap *maddrmap, struct maddrnode *maddrnode) +{ + struct maddrnode *mn; + + mn = xmemdup(maddrnode, sizeof *maddrnode, "maddrmap_insert"); + TAILQ_INSERT_TAIL(&maddrmap->queue, mn, entries); +} + +void +maddrmap_free(struct maddrmap *maddrmap) +{ + struct maddrnode *mn; + + while ((mn = TAILQ_FIRST(&maddrmap->queue))) { + TAILQ_REMOVE(&maddrmap->queue, mn, entries); + free(mn); + } + free(maddrmap); +} diff --git a/smtpd/makemap/Makefile b/smtpd/makemap/Makefile index 904a89d8..a88d632f 100644 --- a/smtpd/makemap/Makefile +++ b/smtpd/makemap/Makefile @@ -27,6 +27,7 @@ SRCS+= expand.c SRCS+= limit.c SRCS+= log.c SRCS+= makemap.c +SRCS+= mailaddr.c SRCS+= parse.y SRCS+= table.c SRCS+= to.c diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h index 4a1032a2..ced2b5f5 100644 --- a/smtpd/smtpd.h +++ b/smtpd/smtpd.h @@ -147,6 +147,7 @@ union lookup { struct userinfo userinfo; struct mailaddr mailaddr; struct addrname addrname; + struct maddrmap *maddrmap; }; /* @@ -470,6 +471,15 @@ struct expand { struct expandnode *parent; }; +struct maddrnode { + TAILQ_ENTRY(maddrnode) entries; + struct mailaddr mailaddr; +}; + +struct maddrmap { + TAILQ_HEAD(xmaddr, maddrnode) queue; +}; + #define DSN_SUCCESS 0x01 #define DSN_FAILURE 0x02 #define DSN_DELAY 0x04 @@ -1205,6 +1215,13 @@ void filter_eom(uint64_t, int, size_t); void filter_event(uint64_t, int); void filter_build_fd_chain(uint64_t, int); + +/* mailaddr.c */ +int mailaddr_line(struct maddrmap *, const char *); +void maddrmap_init(struct maddrmap *); +void maddrmap_insert(struct maddrmap *, struct maddrnode *); +void maddrmap_free(struct maddrmap *); + /* mproc.c */ int mproc_fork(struct mproc *, const char*, char **); void mproc_init(struct mproc *, int); diff --git a/smtpd/smtpd/Makefile b/smtpd/smtpd/Makefile index 499c2285..b9474e33 100644 --- a/smtpd/smtpd/Makefile +++ b/smtpd/smtpd/Makefile @@ -33,6 +33,7 @@ SRCS+= limit.c SRCS+= lka.c SRCS+= lka_session.c SRCS+= log.c +SRCS+= mailaddr.c SRCS+= mda.c SRCS+= mproc.c SRCS+= mta.c diff --git a/smtpd/table.c b/smtpd/table.c index d6f2636e..ada019db 100644 --- a/smtpd/table.c +++ b/smtpd/table.c @@ -597,11 +597,21 @@ table_parse_lookup(enum table_service service, const char *key, return (1); case K_MAILADDR: - case K_MAILADDRMAP: if (!text_to_mailaddr(&lk->mailaddr, line)) return (-1); return (1); + case K_MAILADDRMAP: + lk->maddrmap = calloc(1, sizeof(*lk->maddrmap)); + if (lk->maddrmap == NULL) + return (-1); + maddrmap_init(lk->maddrmap); + if (! mailaddr_line(lk->maddrmap, line)) { + maddrmap_free(lk->maddrmap); + return (-1); + } + return (1); + case K_ADDRNAME: if (parse_sockaddr((struct sockaddr *)&lk->addrname.addr, PF_UNSPEC, key) == -1) diff --git a/smtpd/util.c b/smtpd/util.c index f7c9b1a2..092a93c5 100644 --- a/smtpd/util.c +++ b/smtpd/util.c @@ -449,6 +449,10 @@ mailaddr_match(const struct mailaddr *maddr1, const struct mailaddr *maddr2) struct mailaddr m2 = *maddr2; char *p; + /* catchall */ + if (m2.user[0] == '\0' && m2.domain[0] == '\0') + return 1; + if (! hostname_match(m1.domain, m2.domain)) return 0; |