xref: /openbsd-src/usr.sbin/smtpd/mailaddr.c (revision d3140113bef2b86d3af61dd20c05a8630ff966c2)
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