1*d3140113Seric /* $OpenBSD: mailaddr.c,v 1.5 2021/06/14 17:58:15 eric Exp $ */
212618d23Sgilles
312618d23Sgilles /*
412618d23Sgilles * Copyright (c) 2015 Gilles Chehade <gilles@poolp.org>
512618d23Sgilles *
612618d23Sgilles * Permission to use, copy, modify, and distribute this software for any
712618d23Sgilles * purpose with or without fee is hereby granted, provided that the above
812618d23Sgilles * copyright notice and this permission notice appear in all copies.
912618d23Sgilles *
1012618d23Sgilles * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1112618d23Sgilles * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1212618d23Sgilles * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1312618d23Sgilles * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1412618d23Sgilles * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1512618d23Sgilles * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1612618d23Sgilles * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1712618d23Sgilles */
1812618d23Sgilles
1912618d23Sgilles #include <stdlib.h>
2012618d23Sgilles #include <string.h>
2112618d23Sgilles
2212618d23Sgilles #include "smtpd.h"
2312618d23Sgilles #include "log.h"
2412618d23Sgilles
2512618d23Sgilles static int
mailaddr_line_split(char ** line,char ** ret)2612618d23Sgilles mailaddr_line_split(char **line, char **ret)
2712618d23Sgilles {
2812618d23Sgilles static char buffer[LINE_MAX];
2912618d23Sgilles int esc, dq, sq;
3012618d23Sgilles size_t i;
3112618d23Sgilles char *s;
3212618d23Sgilles
3312618d23Sgilles memset(buffer, 0, sizeof buffer);
3412618d23Sgilles esc = dq = sq = 0;
3512618d23Sgilles i = 0;
3612618d23Sgilles for (s = *line; (*s) && (i < sizeof(buffer)); ++s) {
3712618d23Sgilles if (esc) {
3812618d23Sgilles buffer[i++] = *s;
3912618d23Sgilles esc = 0;
4012618d23Sgilles continue;
4112618d23Sgilles }
4212618d23Sgilles if (*s == '\\') {
4312618d23Sgilles esc = 1;
4412618d23Sgilles continue;
4512618d23Sgilles }
4612618d23Sgilles if (*s == ',' && !dq && !sq) {
4712618d23Sgilles *ret = buffer;
4812618d23Sgilles *line = s+1;
4912618d23Sgilles return (1);
5012618d23Sgilles }
5112618d23Sgilles
5212618d23Sgilles buffer[i++] = *s;
5312618d23Sgilles esc = 0;
5412618d23Sgilles
5512618d23Sgilles if (*s == '"' && !sq)
5612618d23Sgilles dq ^= 1;
5712618d23Sgilles if (*s == '\'' && !dq)
5812618d23Sgilles sq ^= 1;
5912618d23Sgilles }
6012618d23Sgilles
6112618d23Sgilles if (esc || dq || sq || i == sizeof(buffer))
6212618d23Sgilles return (-1);
6312618d23Sgilles
6412618d23Sgilles *ret = buffer;
6512618d23Sgilles *line = s;
6612618d23Sgilles return (i ? 1 : 0);
6712618d23Sgilles }
6812618d23Sgilles
6912618d23Sgilles int
mailaddr_line(struct maddrmap * maddrmap,const char * s)7012618d23Sgilles mailaddr_line(struct maddrmap *maddrmap, const char *s)
7112618d23Sgilles {
7212618d23Sgilles struct maddrnode mn;
73bbd7ab91Smartijn char *p, *subrcpt, *buffer;
7412618d23Sgilles int ret;
7512618d23Sgilles
76bbd7ab91Smartijn if ((buffer = strdup(s)) == NULL)
7712618d23Sgilles return 0;
7812618d23Sgilles
7912618d23Sgilles p = buffer;
8012618d23Sgilles while ((ret = mailaddr_line_split(&p, &subrcpt)) > 0) {
8112618d23Sgilles subrcpt = strip(subrcpt);
8212618d23Sgilles if (subrcpt[0] == '\0')
8312618d23Sgilles continue;
84bbd7ab91Smartijn if (!text_to_mailaddr(&mn.mailaddr, subrcpt)) {
85bbd7ab91Smartijn free(buffer);
8612618d23Sgilles return 0;
87bbd7ab91Smartijn }
8812618d23Sgilles log_debug("subrcpt: [%s]", subrcpt);
8912618d23Sgilles maddrmap_insert(maddrmap, &mn);
9012618d23Sgilles }
9112618d23Sgilles
92bbd7ab91Smartijn free(buffer);
93bbd7ab91Smartijn
9412618d23Sgilles if (ret >= 0)
9512618d23Sgilles return 1;
9612618d23Sgilles /* expand_line_split() returned < 0 */
9712618d23Sgilles return 0;
9812618d23Sgilles }
9912618d23Sgilles
10012618d23Sgilles void
maddrmap_init(struct maddrmap * maddrmap)10112618d23Sgilles maddrmap_init(struct maddrmap *maddrmap)
10212618d23Sgilles {
10312618d23Sgilles TAILQ_INIT(&maddrmap->queue);
10412618d23Sgilles }
10512618d23Sgilles
10612618d23Sgilles void
maddrmap_insert(struct maddrmap * maddrmap,struct maddrnode * maddrnode)10712618d23Sgilles maddrmap_insert(struct maddrmap *maddrmap, struct maddrnode *maddrnode)
10812618d23Sgilles {
10912618d23Sgilles struct maddrnode *mn;
11012618d23Sgilles
111118c16f3Sgilles mn = xmemdup(maddrnode, sizeof *maddrnode);
11212618d23Sgilles TAILQ_INSERT_TAIL(&maddrmap->queue, mn, entries);
11312618d23Sgilles }
11412618d23Sgilles
11512618d23Sgilles void
maddrmap_free(struct maddrmap * maddrmap)11612618d23Sgilles maddrmap_free(struct maddrmap *maddrmap)
11712618d23Sgilles {
11812618d23Sgilles struct maddrnode *mn;
11912618d23Sgilles
12012618d23Sgilles while ((mn = TAILQ_FIRST(&maddrmap->queue))) {
12112618d23Sgilles TAILQ_REMOVE(&maddrmap->queue, mn, entries);
12212618d23Sgilles free(mn);
12312618d23Sgilles }
12412618d23Sgilles free(maddrmap);
12512618d23Sgilles }
126