diff options
-rw-r--r-- | usr.sbin/smtpd/lka_filter.c | 164 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd/Makefile | 3 |
2 files changed, 161 insertions, 6 deletions
diff --git a/usr.sbin/smtpd/lka_filter.c b/usr.sbin/smtpd/lka_filter.c index a4ac7fa3b39..52836fe8536 100644 --- a/usr.sbin/smtpd/lka_filter.c +++ b/usr.sbin/smtpd/lka_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka_filter.c,v 1.52 2019/12/12 20:47:39 gilles Exp $ */ +/* $OpenBSD: lka_filter.c,v 1.53 2019/12/13 12:43:56 gilles Exp $ */ /* * Copyright (c) 2018 Gilles Chehade <gilles@poolp.org> @@ -129,7 +129,7 @@ struct filter_chain { static struct dict filter_smtp_in; static struct tree sessions; -static int inited; +static int filters_inited; static struct dict filter_chains; @@ -170,6 +170,162 @@ static struct smtp_events { { "timeout" }, }; +static int processors_inited = 0; +static struct dict processors; + +struct processor_instance { + char *name; + struct io *io; + struct io *errfd; + int ready; + uint32_t subsystems; +}; + +static void processor_io(struct io *, int, void *); +static void processor_errfd(struct io *, int, void *); +void lka_filter_process_response(const char *, const char *); + +int +lka_proc_ready(void) +{ + void *iter; + struct processor_instance *pi; + + iter = NULL; + while (dict_iter(&processors, &iter, NULL, (void **)&pi)) + if (!pi->ready) + return 0; + return 1; +} + +static void +lka_proc_config(struct processor_instance *pi) +{ + io_printf(pi->io, "config|smtpd-version|%s\n", SMTPD_VERSION); + io_printf(pi->io, "config|smtp-session-timeout|%d\n", SMTPD_SESSION_TIMEOUT); + if (pi->subsystems & FILTER_SUBSYSTEM_SMTP_IN) + io_printf(pi->io, "config|subsystem|smtp-in\n"); + io_printf(pi->io, "config|ready\n"); +} + +void +lka_proc_forked(const char *name, uint32_t subsystems, int fd) +{ + struct processor_instance *processor; + + if (!processors_inited) { + dict_init(&processors); + processors_inited = 1; + } + + processor = xcalloc(1, sizeof *processor); + processor->name = xstrdup(name); + processor->io = io_new(); + processor->subsystems = subsystems; + + io_set_nonblocking(fd); + + io_set_fd(processor->io, fd); + io_set_callback(processor->io, processor_io, processor->name); + dict_xset(&processors, name, processor); +} + +void +lka_proc_errfd(const char *name, int fd) +{ + struct processor_instance *processor; + + processor = dict_xget(&processors, name); + + io_set_nonblocking(fd); + + processor->errfd = io_new(); + io_set_fd(processor->errfd, fd); + io_set_callback(processor->errfd, processor_errfd, processor->name); + + lka_proc_config(processor); +} + +struct io * +lka_proc_get_io(const char *name) +{ + struct processor_instance *processor; + + processor = dict_xget(&processors, name); + + return processor->io; +} + +static void +processor_register(const char *name, const char *line) +{ + struct processor_instance *processor; + + processor = dict_xget(&processors, name); + + if (strcmp(line, "register|ready") == 0) { + processor->ready = 1; + return; + } + + if (strncmp(line, "register|report|", 16) == 0) { + lka_report_register_hook(name, line+16); + return; + } + + if (strncmp(line, "register|filter|", 16) == 0) { + lka_filter_register_hook(name, line+16); + return; + } + + fatalx("Invalid register line received: %s", line); +} + +static void +processor_io(struct io *io, int evt, void *arg) +{ + struct processor_instance *processor; + const char *name = arg; + char *line = NULL; + ssize_t len; + + switch (evt) { + case IO_DATAIN: + while ((line = io_getline(io, &len)) != NULL) { + if (strncmp("register|", line, 9) == 0) { + processor_register(name, line); + continue; + } + + processor = dict_xget(&processors, name); + if (!processor->ready) + fatalx("Non-register message before register|" + "ready: %s", line); + else if (strncmp(line, "filter-result|", 14) == 0 || + strncmp(line, "filter-dataline|", 16) == 0) + lka_filter_process_response(name, line); + else if (strncmp(line, "report|", 7) == 0) + lka_report_proc(name, line); + else + fatalx("Invalid filter message type: %s", line); + } + } +} + +static void +processor_errfd(struct io *io, int evt, void *arg) +{ + const char *name = arg; + char *line = NULL; + ssize_t len; + + switch (evt) { + case IO_DATAIN: + while ((line = io_getline(io, &len)) != NULL) + log_warnx("%s: %s", name, line); + } +} + void lka_filter_init(void) { @@ -353,9 +509,9 @@ lka_filter_begin(uint64_t reqid, { struct filter_session *fs; - if (!inited) { + if (!filters_inited) { tree_init(&sessions); - inited = 1; + filters_inited = 1; } fs = xcalloc(1, sizeof (struct filter_session)); diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile index 8ff6ef3608a..b6f08933bc0 100644 --- a/usr.sbin/smtpd/smtpd/Makefile +++ b/usr.sbin/smtpd/smtpd/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.105 2019/12/12 20:47:39 gilles Exp $ +# $OpenBSD: Makefile,v 1.106 2019/12/13 12:43:56 gilles Exp $ .PATH: ${.CURDIR}/.. @@ -24,7 +24,6 @@ SRCS+= ioev.c SRCS+= limit.c SRCS+= lka.c SRCS+= lka_filter.c -SRCS+= lka_proc.c SRCS+= lka_session.c SRCS+= log.c SRCS+= mailaddr.c |