From 39e8d6c59085ee82a05df18937053260556b395d Mon Sep 17 00:00:00 2001 From: gilles Date: Sat, 17 Oct 2015 13:35:45 +0000 Subject: [PATCH] this file is deprecated --- usr.sbin/smtpd/filter_api.c | 998 ------------------------------------ 1 file changed, 998 deletions(-) delete mode 100644 usr.sbin/smtpd/filter_api.c diff --git a/usr.sbin/smtpd/filter_api.c b/usr.sbin/smtpd/filter_api.c deleted file mode 100644 index 5b82f638608..00000000000 --- a/usr.sbin/smtpd/filter_api.c +++ /dev/null @@ -1,998 +0,0 @@ -/* $OpenBSD: filter_api.c,v 1.17 2015/10/14 22:01:43 gilles Exp $ */ - -/* - * Copyright (c) 2013 Eric Faurot - * Copyright (c) 2011 Gilles Chehade - * - * 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 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "smtpd.h" -#include "log.h" - -#define FILTER_HIWAT 65536 - -static struct tree queries; -static struct tree sessions; - -struct filter_session { - uint64_t id; - uint64_t qid; - int qtype; - size_t datalen; - - struct { - int eom_called; - - int error; - struct io iev; - struct iobuf ibuf; - size_t idatalen; - struct io oev; - struct iobuf obuf; - size_t odatalen; - } pipe; - - struct { - int ready; - int status; - int code; - char *line; - } response; -}; - -static int register_done; -static const char *filter_name; - -static struct filter_internals { - struct mproc p; - - uint32_t hooks; - uint32_t flags; - - uid_t uid; - gid_t gid; - const char *rootpath; - - struct { - int (*connect)(uint64_t, struct filter_connect *); - int (*helo)(uint64_t, const char *); - int (*mail)(uint64_t, struct mailaddr *); - int (*rcpt)(uint64_t, struct mailaddr *); - int (*data)(uint64_t); - void (*dataline)(uint64_t, const char *); - int (*eom)(uint64_t, size_t); - - void (*disconnect)(uint64_t); - void (*reset)(uint64_t); - void (*commit)(uint64_t); - void (*rollback)(uint64_t); - } cb; -} fi; - -static void filter_api_init(void); -static void filter_response(struct filter_session *, int, int, const char *); -static void filter_send_response(struct filter_session *); -static void filter_register_query(uint64_t, uint64_t, int); -static void filter_dispatch(struct mproc *, struct imsg *); -static void filter_dispatch_dataline(uint64_t, const char *); -static void filter_dispatch_data(uint64_t); -static void filter_dispatch_eom(uint64_t, size_t); -static void filter_dispatch_connect(uint64_t, struct filter_connect *); -static void filter_dispatch_helo(uint64_t, const char *); -static void filter_dispatch_mail(uint64_t, struct mailaddr *); -static void filter_dispatch_rcpt(uint64_t, struct mailaddr *); -static void filter_dispatch_reset(uint64_t); -static void filter_dispatch_commit(uint64_t); -static void filter_dispatch_rollback(uint64_t); -static void filter_dispatch_disconnect(uint64_t); - -static void filter_trigger_eom(struct filter_session *); -static void filter_io_in(struct io *, int); -static void filter_io_out(struct io *, int); -static const char *filterimsg_to_str(int); -static const char *hook_to_str(int); -static const char *query_to_str(int); -static const char *event_to_str(int); - - -static void -filter_response(struct filter_session *s, int status, int code, const char *line) -{ - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" %s filter_response(%d, %d, %s)", - filter_name, s->id, query_to_str(s->qtype), status, code, line); - - s->response.ready = 1; - s->response.status = status; - s->response.code = code; - if (line) - s->response.line = strdup(line); - else - s->response.line = NULL; - - /* eom is special, as the reponse has to be deferred until the pipe is all flushed */ - if (s->qtype == QUERY_EOM) - filter_trigger_eom(s); - else - filter_send_response(s); -} - -static void -filter_send_response(struct filter_session *s) -{ - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" %s filter_send_response() -> %d, %d, %s", - filter_name, s->id, query_to_str(s->qtype), - s->response.status, - s->response.code, - s->response.line); - - tree_xpop(&queries, s->qid); - - m_create(&fi.p, IMSG_FILTER_RESPONSE, 0, 0, -1); - m_add_id(&fi.p, s->qid); - m_add_int(&fi.p, s->qtype); - if (s->qtype == QUERY_EOM) - m_add_u32(&fi.p, s->datalen); - m_add_int(&fi.p, s->response.status); - m_add_int(&fi.p, s->response.code); - if (s->response.line) { - m_add_string(&fi.p, s->response.line); - free(s->response.line); - s->response.line = NULL; - } - m_close(&fi.p); - - s->qid = 0; - s->response.ready = 0; -} - -static void -filter_dispatch(struct mproc *p, struct imsg *imsg) -{ - struct filter_session *s; - struct filter_connect q_connect; - struct mailaddr maddr; - struct msg m; - const char *line, *name; - uint32_t v, datalen; - uint64_t id, qid; - int status, type; - int fds[2], fdin, fdout; - - log_trace(TRACE_FILTERS, "filter-api:%s imsg %s", filter_name, - filterimsg_to_str(imsg->hdr.type)); - - switch (imsg->hdr.type) { - case IMSG_FILTER_REGISTER: - m_msg(&m, imsg); - m_get_u32(&m, &v); - m_get_string(&m, &name); - filter_name = strdup(name); - m_end(&m); - if (v != FILTER_API_VERSION) { - log_warnx("warn: filter-api:%s API mismatch", filter_name); - fatalx("filter-api: exiting"); - } - m_create(p, IMSG_FILTER_REGISTER, 0, 0, -1); - m_add_int(p, fi.hooks); - m_add_int(p, fi.flags); - m_close(p); - break; - - case IMSG_FILTER_EVENT: - m_msg(&m, imsg); - m_get_id(&m, &id); - m_get_int(&m, &type); - m_end(&m); - switch (type) { - case EVENT_CONNECT: - s = xcalloc(1, sizeof(*s), "filter_dispatch"); - s->id = id; - s->pipe.iev.sock = -1; - s->pipe.oev.sock = -1; - tree_xset(&sessions, id, s); - break; - case EVENT_DISCONNECT: - filter_dispatch_disconnect(id); - s = tree_xpop(&sessions, id); - free(s); - break; - case EVENT_RESET: - filter_dispatch_reset(id); - break; - case EVENT_COMMIT: - filter_dispatch_commit(id); - break; - case EVENT_ROLLBACK: - filter_dispatch_rollback(id); - break; - default: - log_warnx("warn: filter-api:%s bad event %d", filter_name, type); - fatalx("filter-api: exiting"); - } - break; - - case IMSG_FILTER_QUERY: - m_msg(&m, imsg); - m_get_id(&m, &id); - m_get_id(&m, &qid); - m_get_int(&m, &type); - switch(type) { - case QUERY_CONNECT: - m_get_sockaddr(&m, (struct sockaddr*)&q_connect.local); - m_get_sockaddr(&m, (struct sockaddr*)&q_connect.remote); - m_get_string(&m, &q_connect.hostname); - m_end(&m); - filter_register_query(id, qid, type); - filter_dispatch_connect(id, &q_connect); - break; - case QUERY_HELO: - m_get_string(&m, &line); - m_end(&m); - filter_register_query(id, qid, type); - filter_dispatch_helo(id, line); - break; - case QUERY_MAIL: - m_get_mailaddr(&m, &maddr); - m_end(&m); - filter_register_query(id, qid, type); - filter_dispatch_mail(id, &maddr); - break; - case QUERY_RCPT: - m_get_mailaddr(&m, &maddr); - m_end(&m); - filter_register_query(id, qid, type); - filter_dispatch_rcpt(id, &maddr); - break; - case QUERY_DATA: - m_end(&m); - filter_register_query(id, qid, type); - filter_dispatch_data(id); - break; - case QUERY_EOM: - m_get_u32(&m, &datalen); - m_end(&m); - filter_register_query(id, qid, type); - filter_dispatch_eom(id, datalen); - break; - default: - log_warnx("warn: filter-api:%s bad query %d", filter_name, type); - fatalx("filter-api: exiting"); - } - break; - - case IMSG_FILTER_PIPE: - m_msg(&m, imsg); - m_get_id(&m, &id); - m_end(&m); - - fdout = imsg->fd; - fdin = -1; - - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) == -1) { - log_warn("warn: filter-api:%s socketpair", filter_name); - close(fdout); - } - else { - s = tree_xget(&sessions, id); - - s->pipe.eom_called = 0; - s->pipe.error = 0; - s->pipe.idatalen = 0; - s->pipe.odatalen = 0; - - iobuf_init(&s->pipe.obuf, 0, 0); - io_init(&s->pipe.oev, fdout, s, filter_io_out, &s->pipe.obuf); - io_set_write(&s->pipe.oev); - - iobuf_init(&s->pipe.ibuf, 0, 0); - io_init(&s->pipe.iev, fds[0], s, filter_io_in, &s->pipe.ibuf); - io_set_read(&s->pipe.iev); - - fdin = fds[1]; - } - - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" tx pipe %d -> %d", - filter_name, id, fdin, fdout); - - m_create(&fi.p, IMSG_FILTER_PIPE, 0, 0, fdin); - m_add_id(&fi.p, id); - m_close(&fi.p); - - break; - } -} - -static void -filter_register_query(uint64_t id, uint64_t qid, int type) -{ - struct filter_session *s; - - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" %s", filter_name, id, query_to_str(type)); - - s = tree_xget(&sessions, id); - if (s->qid) { - log_warnx("warn: filter-api:%s query already in progess", - filter_name); - fatalx("filter-api: exiting"); - } - s->qid = qid; - s->qtype = type; - s->response.ready = 0; - - tree_xset(&queries, qid, s); -} - -static void -filter_dispatch_connect(uint64_t id, struct filter_connect *conn) -{ - if (fi.cb.connect) - fi.cb.connect(id, conn); - else - filter_api_accept(id); -} - -static void -filter_dispatch_helo(uint64_t id, const char *helo) -{ - if (fi.cb.helo) - fi.cb.helo(id, helo); - else - filter_api_accept(id); -} - -static void -filter_dispatch_mail(uint64_t id, struct mailaddr *mail) -{ - if (fi.cb.mail) - fi.cb.mail(id, mail); - else - filter_api_accept(id); -} - -static void -filter_dispatch_rcpt(uint64_t id, struct mailaddr *rcpt) -{ - if (fi.cb.rcpt) - fi.cb.rcpt(id, rcpt); - else - filter_api_accept(id); -} - -static void -filter_dispatch_data(uint64_t id) -{ - if (fi.cb.data) - fi.cb.data(id); - else - filter_api_accept(id); -} - -static void -filter_dispatch_reset(uint64_t id) -{ - if (fi.cb.reset) - fi.cb.reset(id); -} - -static void -filter_dispatch_commit(uint64_t id) -{ - if (fi.cb.commit) - fi.cb.commit(id); -} - -static void -filter_dispatch_rollback(uint64_t id) -{ - if (fi.cb.rollback) - fi.cb.rollback(id); -} - -static void -filter_dispatch_disconnect(uint64_t id) -{ - if (fi.cb.disconnect) - fi.cb.disconnect(id); -} - -static void -filter_dispatch_dataline(uint64_t id, const char *data) -{ - if (fi.cb.dataline) - fi.cb.dataline(id, data); - else - filter_api_writeln(id, data); -} - -static void -filter_dispatch_eom(uint64_t id, size_t datalen) -{ - struct filter_session *s; - - s = tree_xget(&sessions, id); - s->datalen = datalen; - - filter_trigger_eom(s); -} - -static void -filter_trigger_eom(struct filter_session *s) -{ - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" filter_trigger_eom(%d, %d, %zu, %zu, %zu)", - filter_name, s->id, s->pipe.iev.sock, s->pipe.oev.sock, - s->datalen, s->pipe.idatalen, s->pipe.odatalen); - - /* This is called when - * - EOM query is first received - * - input data is closed - * - output has been written - */ - - /* input not done yet, or EOM query not received */ - if (s->pipe.iev.sock != -1 || s->qid == 0) - return; - - if (s->pipe.error) - goto fail; - - /* if size don't match, error out */ - if (s->pipe.idatalen != s->datalen) { - log_trace(TRACE_FILTERS, "filter-api:%s tx datalen mismatch: %zu/%zu", - filter_name, s->pipe.idatalen, s->datalen); - s->pipe.error = 1; - goto fail; - } - - /* if we didn't send the eom to the user do it now */ - if (!s->pipe.eom_called) { - s->pipe.eom_called = 1; - if (fi.cb.eom) - fi.cb.eom(s->id, s->datalen); - else - filter_api_accept(s->id); - return; - } - - if (s->pipe.error) - goto fail; - - /* wait for the output socket to be closed */ - if (s->pipe.oev.sock != -1) - return; - - s->datalen = s->pipe.odatalen; - filter_send_response(s); - - fail: - /* XXX */ - return; -} - -static void -filter_io_in(struct io *io, int evt) -{ - struct filter_session *s = io->arg; - char *line; - size_t len; - - log_trace(TRACE_FILTERS, "filter-api:%s filter_io_in(%p, %s)", - filter_name, s, io_strevent(evt)); - - switch (evt) { - case IO_DATAIN: - nextline: - line = iobuf_getline(&s->pipe.ibuf, &len); - if ((line == NULL && iobuf_len(&s->pipe.ibuf) >= LINE_MAX) || - (line && len >= LINE_MAX)) { - s->pipe.error = 1; - break; - } - /* No complete line received */ - if (line == NULL) { - iobuf_normalize(&s->pipe.ibuf); - /* flow control */ - if (iobuf_queued(&s->pipe.obuf) >= FILTER_HIWAT) - io_pause(&s->pipe.iev, IO_PAUSE_IN); - return; - } - - s->pipe.idatalen += len + 1; - /* XXX warning: do not clear io from this call! */ - filter_dispatch_dataline(s->id, line); - goto nextline; - - case IO_DISCONNECTED: - if (iobuf_len(&s->pipe.ibuf)) { - log_warn("warn: filter-api:%s %016"PRIx64" incomplete input", - filter_name, s->id); - } - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" input done (%zu bytes)", - filter_name, s->id, s->pipe.idatalen); - break; - - default: - log_warn("warn: filter-api:%s %016"PRIx64": unexpected io event %d on data pipe", - filter_name, s->id, evt); - s->pipe.error = 1; - - } - if (s->pipe.error) { - io_clear(&s->pipe.oev); - iobuf_clear(&s->pipe.obuf); - } - io_clear(&s->pipe.iev); - iobuf_clear(&s->pipe.ibuf); - filter_trigger_eom(s); -} - -static void -filter_io_out(struct io *io, int evt) -{ - struct filter_session *s = io->arg; - - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" filter_io_out(%s)", - filter_name, s->id, io_strevent(evt)); - - switch (evt) { - case IO_TIMEOUT: - case IO_DISCONNECTED: - case IO_ERROR: - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" io error on output pipe", - filter_name, s->id); - s->pipe.error = 1; - break; - - case IO_LOWAT: - /* flow control */ - if (s->pipe.iev.sock != -1 && s->pipe.iev.flags & IO_PAUSE_IN) { - io_resume(&s->pipe.iev, IO_PAUSE_IN); - return; - } - - /* if the input is done and there is a response we are done */ - if (s->pipe.iev.sock == -1 && s->response.ready) - break; - - /* just wait for more data to send */ - return; - - default: - fatalx("filter_io_out()"); - } - - io_clear(&s->pipe.oev); - iobuf_clear(&s->pipe.obuf); - if (s->pipe.error) { - io_clear(&s->pipe.iev); - iobuf_clear(&s->pipe.ibuf); - } - filter_trigger_eom(s); -} - -#define CASE(x) case x : return #x - -static const char * -filterimsg_to_str(int imsg) -{ - switch (imsg) { - CASE(IMSG_FILTER_REGISTER); - CASE(IMSG_FILTER_EVENT); - CASE(IMSG_FILTER_QUERY); - CASE(IMSG_FILTER_PIPE); - CASE(IMSG_FILTER_RESPONSE); - default: - return ("IMSG_FILTER_???"); - } -} - -static const char * -hook_to_str(int hook) -{ - switch (hook) { - CASE(HOOK_CONNECT); - CASE(HOOK_HELO); - CASE(HOOK_MAIL); - CASE(HOOK_RCPT); - CASE(HOOK_DATA); - CASE(HOOK_EOM); - CASE(HOOK_RESET); - CASE(HOOK_DISCONNECT); - CASE(HOOK_COMMIT); - CASE(HOOK_ROLLBACK); - CASE(HOOK_DATALINE); - default: - return ("HOOK_???"); - } -} - -static const char * -query_to_str(int query) -{ - switch (query) { - CASE(QUERY_CONNECT); - CASE(QUERY_HELO); - CASE(QUERY_MAIL); - CASE(QUERY_RCPT); - CASE(QUERY_DATA); - CASE(QUERY_EOM); - CASE(QUERY_DATALINE); - default: - return ("QUERY_???"); - } -} - -static const char * -event_to_str(int event) -{ - switch (event) { - CASE(EVENT_CONNECT); - CASE(EVENT_RESET); - CASE(EVENT_DISCONNECT); - CASE(EVENT_COMMIT); - CASE(EVENT_ROLLBACK); - default: - return ("EVENT_???"); - } -} - -/* - * These functions are called from mproc.c - */ - -enum smtp_proc_type smtpd_process; - -const char * -proc_name(enum smtp_proc_type proc) -{ - if (proc == PROC_FILTER) - return (filter_name); - return ("filter"); -} - -const char * -imsg_to_str(int imsg) -{ - static char buf[32]; - - snprintf(buf, sizeof(buf), "%d", imsg); - - return (buf); -} - - -/* - * These functions are callable by filters - */ - -void -filter_api_setugid(uid_t uid, gid_t gid) -{ - filter_api_init(); - - if (! uid) { - log_warn("warn: filter-api:%s can't set uid 0", filter_name); - fatalx("filter-api: exiting"); - } - if (! gid) { - log_warn("warn: filter-api:%s can't set gid 0", filter_name); - fatalx("filter-api: exiting"); - } - fi.uid = uid; - fi.gid = gid; -} - -void -filter_api_no_chroot(void) -{ - filter_api_init(); - - fi.rootpath = NULL; -} - -void -filter_api_set_chroot(const char *rootpath) -{ - filter_api_init(); - - fi.rootpath = rootpath; -} - -static void -filter_api_init(void) -{ - extern const char *__progname; - struct passwd *pw; - static int init = 0; - - if (init) - return; - - init = 1; - - log_init(-1); - log_verbose(1); - - pw = getpwnam(SMTPD_USER); - if (pw == NULL) { - log_warn("warn: filter-api:%s getpwnam", filter_name); - fatalx("filter-api: exiting"); - } - - smtpd_process = PROC_FILTER; - filter_name = __progname; - - tree_init(&queries); - tree_init(&sessions); - event_init(); - - memset(&fi, 0, sizeof(fi)); - fi.p.proc = PROC_PONY; - fi.p.name = "filter"; - fi.p.handler = filter_dispatch; - fi.uid = pw->pw_uid; - fi.gid = pw->pw_gid; - fi.rootpath = PATH_CHROOT; - - /* XXX just for now */ - fi.hooks = ~0; - - mproc_init(&fi.p, 0); -} - -void -filter_api_on_connect(int(*cb)(uint64_t, struct filter_connect *)) -{ - filter_api_init(); - - fi.hooks |= HOOK_CONNECT; - fi.cb.connect = cb; -} - -void -filter_api_on_helo(int(*cb)(uint64_t, const char *)) -{ - filter_api_init(); - - fi.hooks |= HOOK_HELO; - fi.cb.helo = cb; -} - -void -filter_api_on_mail(int(*cb)(uint64_t, struct mailaddr *)) -{ - filter_api_init(); - - fi.hooks |= HOOK_MAIL; - fi.cb.mail = cb; -} - -void -filter_api_on_rcpt(int(*cb)(uint64_t, struct mailaddr *)) -{ - filter_api_init(); - - fi.hooks |= HOOK_RCPT; - fi.cb.rcpt = cb; -} - -void -filter_api_on_data(int(*cb)(uint64_t)) -{ - filter_api_init(); - - fi.hooks |= HOOK_DATA; - fi.cb.data = cb; -} - -void -filter_api_on_dataline(void(*cb)(uint64_t, const char *)) -{ - filter_api_init(); - - fi.hooks |= HOOK_DATALINE | HOOK_EOM; - fi.cb.dataline = cb; -} - -void -filter_api_on_eom(int(*cb)(uint64_t, size_t)) -{ - filter_api_init(); - - fi.hooks |= HOOK_EOM; - fi.cb.eom = cb; -} - -void -filter_api_on_reset(void(*cb)(uint64_t)) -{ - filter_api_init(); - - fi.hooks |= HOOK_RESET; - fi.cb.reset = cb; -} - -void -filter_api_on_disconnect(void(*cb)(uint64_t)) -{ - filter_api_init(); - - fi.hooks |= HOOK_DISCONNECT; - fi.cb.disconnect = cb; -} - -void -filter_api_on_commit(void(*cb)(uint64_t)) -{ - filter_api_init(); - - fi.hooks |= HOOK_COMMIT; - fi.cb.commit = cb; -} - -void -filter_api_on_rollback(void(*cb)(uint64_t)) -{ - filter_api_init(); - - fi.hooks |= HOOK_ROLLBACK; - fi.cb.rollback = cb; -} - -void -filter_api_loop(void) -{ - if (register_done) { - log_warnx("warn: filter-api:%s filter_api_loop() already called", filter_name); - fatalx("filter-api: exiting"); - } - - filter_api_init(); - - register_done = 1; - - mproc_enable(&fi.p); - - if (fi.rootpath) { - if (chroot(fi.rootpath) == -1) { - log_warn("warn: filter-api:%s chroot", filter_name); - fatalx("filter-api: exiting"); - } - if (chdir("/") == -1) { - log_warn("warn: filter-api:%s chdir", filter_name); - fatalx("filter-api: exiting"); - } - } - - if (setgroups(1, &fi.gid) || - setresgid(fi.gid, fi.gid, fi.gid) || - setresuid(fi.uid, fi.uid, fi.uid)) { - log_warn("warn: filter-api:%s cannot drop privileges", filter_name); - fatalx("filter-api: exiting"); - } - - if (event_dispatch() < 0) { - log_warn("warn: filter-api:%s event_dispatch", filter_name); - fatalx("filter-api: exiting"); - } -} - -int -filter_api_accept(uint64_t id) -{ - struct filter_session *s; - - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" filter_api_accept()", filter_name, id); - - s = tree_xget(&sessions, id); - filter_response(s, FILTER_OK, 0, NULL); - - return (1); -} - -int -filter_api_reject(uint64_t id, enum filter_status status) -{ - struct filter_session *s; - - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" filter_api_reject(%d)", - filter_name, id, status); - - s = tree_xget(&sessions, id); - - /* This is NOT an acceptable status for a failure */ - if (status == FILTER_OK) - status = FILTER_FAIL; - - filter_response(s, status, 0, NULL); - - return (1); -} - -int -filter_api_reject_code(uint64_t id, enum filter_status status, uint32_t code, - const char *line) -{ - struct filter_session *s; - - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" filter_api_reject_code(%d, %u, %s)", - filter_name, id, status, code, line); - - s = tree_xget(&sessions, id); - - /* This is NOT an acceptable status for a failure */ - if (status == FILTER_OK) - status = FILTER_FAIL; - - filter_response(s, status, code, line); - - return (1); -} - -void -filter_api_writeln(uint64_t id, const char *line) -{ - struct filter_session *s; - - log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" filter_api_writeln(%s)", filter_name, id, line); - - s = tree_xget(&sessions, id); - - if (s->pipe.oev.sock == -1) { - log_warnx("warn: filter:%s: cannot write at this point", filter_name); - fatalx("exiting"); - } - - s->pipe.odatalen += strlen(line) + 1; - iobuf_fqueue(&s->pipe.obuf, "%s\n", line); - io_reload(&s->pipe.oev); -} - -const char * -filter_api_sockaddr_to_text(const struct sockaddr *sa) -{ - static char buf[NI_MAXHOST]; - - if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, - NI_NUMERICHOST)) - return ("(unknown)"); - else - return (buf); -} - -const char * -filter_api_mailaddr_to_text(const struct mailaddr *maddr) -{ - static char buffer[LINE_MAX]; - - strlcpy(buffer, maddr->user, sizeof buffer); - strlcat(buffer, "@", sizeof buffer); - if (strlcat(buffer, maddr->domain, sizeof buffer) >= sizeof buffer) - return (NULL); - - return (buffer); -} -- 2.20.1