summaryrefslogtreecommitdiff
path: root/libexec/spamd/spamd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/spamd/spamd.c')
-rw-r--r--libexec/spamd/spamd.c111
1 files changed, 86 insertions, 25 deletions
diff --git a/libexec/spamd/spamd.c b/libexec/spamd/spamd.c
index b419ef34fe7..e96839ff8b2 100644
--- a/libexec/spamd/spamd.c
+++ b/libexec/spamd/spamd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spamd.c,v 1.118 2014/12/30 23:27:23 millert Exp $ */
+/* $OpenBSD: spamd.c,v 1.119 2015/01/13 21:42:59 millert Exp $ */
/*
* Copyright (c) 2002-2007 Bob Beck. All rights reserved.
@@ -29,6 +29,7 @@
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
+#include <limits.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -184,11 +185,12 @@ grow_obuf(struct con *cp, int off)
int
parse_configline(char *line)
{
- char *cp, prev, *name, *msg;
- static char **av = NULL;
- static size_t ac = 0;
- size_t au = 0;
+ char *cp, prev, *name, *msg, *tmp;
+ char **v4 = NULL, **v6 = NULL;
+ const char *errstr;
+ u_int nv4 = 0, nv6 = 0;
int mdone = 0;
+ sa_family_t af;
name = line;
@@ -219,11 +221,16 @@ parse_configline(char *line)
if (*cp == ';') {
mdone = 1;
*cp = '\0';
- } else
+ } else {
+ if (debug > 0)
+ printf("bad message: %s\n", msg);
goto parse_error;
+ }
}
break;
case '\0':
+ if (debug > 0)
+ printf("bad message: %s\n", msg);
goto parse_error;
default:
prev = '\0';
@@ -231,35 +238,89 @@ parse_configline(char *line)
}
}
- do {
- if (ac == au) {
- char **tmp;
+ while ((tmp = strsep(&cp, ";")) != NULL) {
+ char **av;
+ u_int au, ac;
- tmp = reallocarray(av, ac + 2048, sizeof(char *));
- if (tmp == NULL) {
- free(av);
- av = NULL;
- ac = 0;
- return (-1);
+ if (*tmp == '\0')
+ continue;
+
+ if (strncmp(tmp, "inet", 4) != 0)
+ goto parse_error;
+ switch (tmp[4]) {
+ case '\0':
+ af = AF_INET;
+ break;
+ case '6':
+ if (tmp[5] == '\0') {
+ af = AF_INET6;
+ break;
}
- av = tmp;
- ac += 2048;
+ /* FALLTHROUGH */
+ default:
+ if (debug > 0)
+ printf("unsupported address family: %s\n", tmp);
+ goto parse_error;
}
- } while ((av[au++] = strsep(&cp, ";")) != NULL);
- /* toss empty last entry to allow for trailing ; */
- while (au > 0 && (av[au - 1] == NULL || av[au - 1][0] == '\0'))
- au--;
+ tmp = strsep(&cp, ";");
+ if (tmp == NULL) {
+ if (debug > 0)
+ printf("missing address count\n");
+ goto parse_error;
+ }
+ ac = strtonum(tmp, 0, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ if (debug > 0)
+ printf("count \"%s\" is %s\n", tmp, errstr);
+ goto parse_error;
+ }
- if (au < 1)
+ av = reallocarray(NULL, ac, sizeof(char *));
+ for (au = 0; au < ac; au++) {
+ tmp = strsep(&cp, ";");
+ if (tmp == NULL) {
+ if (debug > 0)
+ printf("expected %u addrs, got %u\n",
+ ac, au + 1);
+ free(av);
+ goto parse_error;
+ }
+ if (*tmp == '\0')
+ continue;
+ av[au] = tmp;
+ }
+ if (af == AF_INET) {
+ if (debug > 0)
+ printf("duplicate inet\n");
+ if (v4 != NULL)
+ goto parse_error;
+ v4 = av;
+ nv4 = ac;
+ } else {
+ if (debug > 0)
+ printf("duplicate inet6\n");
+ if (v6 != NULL)
+ goto parse_error;
+ v6 = av;
+ nv6 = ac;
+ }
+ }
+ if (nv4 == 0 && nv6 == 0) {
+ if (debug > 0)
+ printf("no addresses\n");
goto parse_error;
- else
- sdl_add(name, msg, av, au);
+ }
+ sdl_add(name, msg, v4, nv4, v6, nv6);
+ free(v4);
+ free(v6);
return (0);
parse_error:
if (debug > 0)
- printf("bogus config line - need 'tag;message;a/m;a/m;a/m...'\n");
+ printf("bogus config line - need 'tag;message;af;count;a/m;a/m;a/m...'\n");
+ free(v4);
+ free(v6);
return (-1);
}