diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/mailaddr.c | 133 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 18 |
2 files changed, 150 insertions, 1 deletions
diff --git a/usr.sbin/smtpd/mailaddr.c b/usr.sbin/smtpd/mailaddr.c new file mode 100644 index 00000000000..98a3436b83e --- /dev/null +++ b/usr.sbin/smtpd/mailaddr.c @@ -0,0 +1,133 @@ +/* $OpenBSD: mailaddr.c,v 1.1 2015/10/28 14:30:03 gilles Exp $ */ + +/* + * 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/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index a7711d2f0e6..6a4b99acf74 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.481 2015/10/28 07:25:30 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.482 2015/10/28 14:30:03 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> @@ -466,6 +466,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 @@ -1184,6 +1193,13 @@ void mda_postprivdrop(void); void mda_imsg(struct mproc *, struct imsg *); +/* 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); |