aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Faurot <eric@faurot.net>2014-05-07 17:19:21 +0200
committerEric Faurot <eric@faurot.net>2014-05-07 17:19:21 +0200
commit87dbcbaa1639df923f41b09ebde199bde529af4e (patch)
tree54608fa28f5597210a4b2828eff2d7b2de805e67
parentfix prototype (diff)
downloadOpenSMTPD-87dbcbaa1639df923f41b09ebde199bde529af4e.tar.xz
OpenSMTPD-87dbcbaa1639df923f41b09ebde199bde529af4e.zip
replace mfa.c and mfa_session.c with filter.c
-rw-r--r--smtpd/filter.c (renamed from smtpd/mfa_session.c)275
-rw-r--r--smtpd/filter_api.c4
-rw-r--r--smtpd/mfa.c426
-rw-r--r--smtpd/mproc.c2
-rw-r--r--smtpd/parse.y22
-rw-r--r--smtpd/pony.c3
-rw-r--r--smtpd/smtp.c29
-rw-r--r--smtpd/smtp_session.c67
-rw-r--r--smtpd/smtpd-api.h6
-rw-r--r--smtpd/smtpd.h35
-rw-r--r--smtpd/smtpd/Makefile3
11 files changed, 208 insertions, 664 deletions
diff --git a/smtpd/mfa_session.c b/smtpd/filter.c
index 115f346f..58ebab0b 100644
--- a/smtpd/mfa_session.c
+++ b/smtpd/filter.c
@@ -53,38 +53,38 @@ enum {
};
-struct mfa_filterproc {
- TAILQ_ENTRY(mfa_filterproc) entry;
+struct filter_proc {
+ TAILQ_ENTRY(filter_proc) entry;
struct mproc mproc;
int hooks;
int flags;
int ready;
};
-struct mfa_filter {
- TAILQ_ENTRY(mfa_filter) entry;
- struct mfa_filterproc *proc;
+struct filter {
+ TAILQ_ENTRY(filter) entry;
+ struct filter_proc *proc;
};
-TAILQ_HEAD(mfa_filters, mfa_filter);
+TAILQ_HEAD(filter_lst, filter);
-struct mfa_session {
+struct filter_session {
uint64_t id;
int terminate;
- TAILQ_HEAD(mfa_queries, mfa_query) queries;
- struct mfa_filters *filters;
- struct mfa_filter *fcurr;
+ TAILQ_HEAD(filter_queries, filter_query) queries;
+ struct filter_lst *filters;
+ struct filter *fcurr;
};
-struct mfa_query {
- uint64_t qid;
- int type;
- int hook;
- struct mfa_session *session;
- TAILQ_ENTRY(mfa_query) entry;
+struct filter_query {
+ uint64_t qid;
+ int type;
+ int hook;
+ struct filter_session *session;
+ TAILQ_ENTRY(filter_query) entry;
- int state;
- int hasrun;
- struct mfa_filter *current;
+ int state;
+ int hasrun;
+ struct filter *current;
/* current data */
union {
@@ -106,18 +106,18 @@ struct mfa_query {
} smtp;
};
-static void mfa_filter_imsg(struct mproc *, struct imsg *);
-static struct mfa_query *mfa_query(struct mfa_session *, int, int);
-static void mfa_drain_query(struct mfa_query *);
-static void mfa_run_query(struct mfa_filter *, struct mfa_query *);
-static void mfa_set_fdout(struct mfa_session *, int);
+static void filter_imsg(struct mproc *, struct imsg *);
+static struct filter_query *filter_query(struct filter_session *, int, int);
+static void filter_drain_query(struct filter_query *);
+static void filter_run_query(struct filter *, struct filter_query *);
+static void filter_set_fdout(struct filter_session *, int);
-static TAILQ_HEAD(, mfa_filterproc) procs;
+static TAILQ_HEAD(, filter_proc) procs;
struct dict chains;
-static const char * mfa_query_to_text(struct mfa_query *);
-static const char * mfa_filter_to_text(struct mfa_filter *);
-static const char * mfa_filterproc_to_text(struct mfa_filterproc *);
+static const char * filter_query_to_text(struct filter_query *);
+static const char * filter_to_text(struct filter *);
+static const char * filter_proc_to_text(struct filter_proc *);
static const char * type_to_str(int);
static const char * query_to_str(int);
static const char * event_to_str(int);
@@ -129,11 +129,11 @@ struct tree queries;
static void
-mfa_extend_chain(struct mfa_filters *chain, const char *name)
+filter_extend_chain(struct filter_lst *chain, const char *name)
{
- struct mfa_filter *n;
- struct mfa_filters *fchain;
- struct filter *fconf;
+ struct filter *n;
+ struct filter_lst *fchain;
+ struct filter_conf *fconf;
int i;
fconf = dict_xget(&env->sc_filters, name);
@@ -142,12 +142,12 @@ mfa_extend_chain(struct mfa_filters *chain, const char *name)
for (i = 0; i < MAX_FILTER_PER_CHAIN; i++) {
if (!fconf->filters[i][0])
break;
- mfa_extend_chain(chain, fconf->filters[i]);
+ filter_extend_chain(chain, fconf->filters[i]);
}
}
else {
log_debug("mfa: adding filter \"%s\"", name);
- n = xcalloc(1, sizeof(*n), "mfa_extend_chain");
+ n = xcalloc(1, sizeof(*n), "filter_extend_chain");
fchain = dict_get(&chains, name);
n->proc = TAILQ_FIRST(fchain)->proc;
TAILQ_INSERT_TAIL(chain, n, entry);
@@ -155,14 +155,14 @@ mfa_extend_chain(struct mfa_filters *chain, const char *name)
}
void
-mfa_filter_prepare(void)
+filter_postfork(void)
{
static int prepare = 0;
- struct filter *filter;
+ struct filter_conf *filter;
void *iter;
- struct mfa_filterproc *proc;
- struct mfa_filters *fchain;
- struct mfa_filter *f;
+ struct filter_proc *proc;
+ struct filter_lst *fchain;
+ struct filter *f;
struct mproc *p;
int done, i;
@@ -183,22 +183,22 @@ mfa_filter_prepare(void)
log_debug("mfa: building simple chain \"%s\"", filter->name);
- proc = xcalloc(1, sizeof(*proc), "mfa_filter_init");
+ proc = xcalloc(1, sizeof(*proc), "filter_postfork");
p = &proc->mproc;
- p->handler = mfa_filter_imsg;
+ p->handler = filter_imsg;
p->proc = PROC_FILTER;
- p->name = xstrdup(filter->name, "mfa_filter_init");
+ p->name = xstrdup(filter->name, "filter_postfork");
p->data = proc;
if (mproc_fork(p, filter->path, filter->name) < 0)
- fatalx("mfa_filter_init");
+ fatalx("filter_postfork");
log_debug("mfa: registering proc \"%s\"", filter->name);
- f = xcalloc(1, sizeof(*f), "mfa_filter_init");
+ f = xcalloc(1, sizeof(*f), "filter_postfork");
f->proc = proc;
TAILQ_INSERT_TAIL(&procs, proc, entry);
- fchain = xcalloc(1, sizeof(*fchain), "mfa_filter_prepare");
+ fchain = xcalloc(1, sizeof(*fchain), "filter_postfork");
TAILQ_INIT(fchain);
TAILQ_INSERT_TAIL(fchain, f, entry);
dict_xset(&chains, filter->name, fchain);
@@ -227,13 +227,13 @@ mfa_filter_prepare(void)
}
if (filter->done == 0)
continue;
- fchain = xcalloc(1, sizeof(*fchain), "mfa_filter_prepare");
+ fchain = xcalloc(1, sizeof(*fchain), "filter_postfork");
TAILQ_INIT(fchain);
log_debug("mfa: building chain \"%s\"...", filter->name);
for (i = 0; i < MAX_FILTER_PER_CHAIN; i++) {
if (!filter->filters[i][0])
break;
- mfa_extend_chain(fchain, filter->filters[i]);
+ filter_extend_chain(fchain, filter->filters[i]);
}
log_debug("mfa: done building chain \"%s\"", filter->name);
dict_xset(&chains, filter->name, fchain);
@@ -243,17 +243,17 @@ mfa_filter_prepare(void)
if (dict_get(&chains, "default") == NULL) {
log_debug("mfa: done building default chain");
- fchain = xcalloc(1, sizeof(*fchain), "mfa_filter_prepare");
+ fchain = xcalloc(1, sizeof(*fchain), "filter_postfork");
TAILQ_INIT(fchain);
dict_xset(&chains, "default", fchain);
}
}
void
-mfa_filter_init(void)
+filter_configure(void)
{
static int init = 0;
- struct mfa_filterproc *p;
+ struct filter_proc *p;
if (init)
return;
@@ -271,17 +271,17 @@ mfa_filter_init(void)
}
if (TAILQ_FIRST(&procs) == NULL)
- mfa_ready();
+ smtp_configure();
}
void
-mfa_filter_event(uint64_t id, int event)
+filter_event(uint64_t id, int event)
{
- struct mfa_session *s;
- struct mfa_query *q;
+ struct filter_session *s;
+ struct filter_query *q;
if (event == EVENT_CONNECT) {
- s = xcalloc(1, sizeof(*s), "mfa_filter_event");
+ s = xcalloc(1, sizeof(*s), "filter_event");
s->id = id;
s->filters = dict_xget(&chains, "default");
TAILQ_INIT(&s->queries);
@@ -292,128 +292,122 @@ mfa_filter_event(uint64_t id, int event)
s = tree_xpop(&sessions, id);
else
s = tree_xget(&sessions, id);
- q = mfa_query(s, QT_EVENT, event);
+ q = filter_query(s, QT_EVENT, event);
- mfa_drain_query(q);
+ filter_drain_query(q);
}
void
-mfa_filter_connect(uint64_t id, const struct sockaddr *local,
+filter_connect(uint64_t id, const struct sockaddr *local,
const struct sockaddr *remote, const char *host)
{
- struct mfa_session *s;
- struct mfa_query *q;
+ struct filter_session *s;
+ struct filter_query *q;
s = tree_xget(&sessions, id);
- q = mfa_query(s, QT_QUERY, QUERY_CONNECT);
+ q = filter_query(s, QT_QUERY, QUERY_CONNECT);
memmove(&q->u.connect.local, local, local->sa_len);
memmove(&q->u.connect.remote, remote, remote->sa_len);
strlcpy(q->u.connect.hostname, host, sizeof(q->u.connect.hostname));
- q->smtp.status = MFA_OK;
+ q->smtp.status = FILTER_OK;
q->smtp.code = 0;
q->smtp.response = NULL;
- mfa_drain_query(q);
+ filter_drain_query(q);
}
void
-mfa_filter_mailaddr(uint64_t id, int qhook, const struct mailaddr *maddr)
+filter_mailaddr(uint64_t id, int qhook, const struct mailaddr *maddr)
{
- struct mfa_session *s;
- struct mfa_query *q;
+ struct filter_session *s;
+ struct filter_query *q;
s = tree_xget(&sessions, id);
- q = mfa_query(s, QT_QUERY, qhook);
+ q = filter_query(s, QT_QUERY, qhook);
strlcpy(q->u.maddr.user, maddr->user, sizeof(q->u.maddr.user));
strlcpy(q->u.maddr.domain, maddr->domain, sizeof(q->u.maddr.domain));
- mfa_drain_query(q);
+ filter_drain_query(q);
}
void
-mfa_filter_line(uint64_t id, int qhook, const char *line)
+filter_line(uint64_t id, int qhook, const char *line)
{
- struct mfa_session *s;
- struct mfa_query *q;
+ struct filter_session *s;
+ struct filter_query *q;
s = tree_xget(&sessions, id);
- q = mfa_query(s, QT_QUERY, qhook);
+ q = filter_query(s, QT_QUERY, qhook);
- strlcpy(q->u.line, line, sizeof(q->u.line));
+ if (line)
+ strlcpy(q->u.line, line, sizeof(q->u.line));
- mfa_drain_query(q);
+ filter_drain_query(q);
}
void
-mfa_filter_eom(uint64_t id, int qhook, size_t datalen)
+filter_eom(uint64_t id, int qhook, size_t datalen)
{
- struct mfa_session *s;
- struct mfa_query *q;
+ struct filter_session *s;
+ struct filter_query *q;
s = tree_xget(&sessions, id);
- q = mfa_query(s, QT_QUERY, qhook);
+ q = filter_query(s, QT_QUERY, qhook);
q->u.datalen = datalen;
- mfa_drain_query(q);
-}
-
-void
-mfa_filter(uint64_t id, int qhook)
-{
- struct mfa_session *s;
- struct mfa_query *q;
-
- s = tree_xget(&sessions, id);
- q = mfa_query(s, QT_QUERY, qhook);
-
- mfa_drain_query(q);
+ filter_drain_query(q);
}
static void
-mfa_set_fdout(struct mfa_session *s, int fdout)
+filter_set_fdout(struct filter_session *s, int fdout)
{
struct mproc *p;
while(s->fcurr) {
if (s->fcurr->proc->hooks & HOOK_DATALINE) {
- log_trace(TRACE_MFA, "mfa: sending fd %d to %s", fdout, mfa_filter_to_text(s->fcurr));
+ log_trace(TRACE_MFA, "mfa: sending fd %d to %s", fdout, filter_to_text(s->fcurr));
p = &s->fcurr->proc->mproc;
m_create(p, IMSG_FILTER_PIPE_SETUP, 0, 0, fdout);
m_add_id(p, s->id);
m_close(p);
return;
}
- s->fcurr = TAILQ_PREV(s->fcurr, mfa_filters, entry);
+ s->fcurr = TAILQ_PREV(s->fcurr, filter_lst, entry);
}
log_trace(TRACE_MFA, "mfa: chain input is %d", fdout);
+
+#if 0
+ XXX finish
+
m_create(p_smtp, IMSG_QUEUE_MESSAGE_FILE, 0, 0, fdout);
m_add_id(p_smtp, s->id);
m_add_int(p_smtp, 1);
m_close(p_smtp);
return;
+#endif
}
void
-mfa_build_fd_chain(uint64_t id, int fdout)
+filter_build_fd_chain(uint64_t id, int fdout)
{
- struct mfa_session *s;
+ struct filter_session *s;
s = tree_xget(&sessions, id);
- s->fcurr = TAILQ_LAST(s->filters, mfa_filters);
- mfa_set_fdout(s, fdout);
+ s->fcurr = TAILQ_LAST(s->filters, filter_lst);
+ filter_set_fdout(s, fdout);
}
-static struct mfa_query *
-mfa_query(struct mfa_session *s, int type, int qhook)
+static struct filter_query *
+filter_query(struct filter_session *s, int type, int qhook)
{
- struct mfa_query *q;
+ struct filter_query *q;
- q = xcalloc(1, sizeof *q, "mfa_query");
+ q = xcalloc(1, sizeof *q, "filter_query");
q->qid = generate_uid();
q->session = s;
q->type = type;
@@ -435,11 +429,11 @@ mfa_query(struct mfa_session *s, int type, int qhook)
}
static void
-mfa_drain_query(struct mfa_query *q)
+filter_drain_query(struct filter_query *q)
{
- struct mfa_query *prev;
+ struct filter_query *prev;
- log_trace(TRACE_MFA, "filter: draining query %s", mfa_query_to_text(q));
+ log_trace(TRACE_MFA, "filter: draining query %s", filter_query_to_text(q));
/*
* The query must be passed through all filters that registered
@@ -452,13 +446,13 @@ mfa_drain_query(struct mfa_query *q)
/* Trigger the current filter if not done yet. */
if (!q->hasrun) {
- mfa_run_query(q->current, q);
+ filter_run_query(q->current, q);
q->hasrun = 1;
}
if (q->state == QUERY_RUNNING) {
log_trace(TRACE_MFA,
"filter: waiting for running query %s",
- mfa_query_to_text(q));
+ filter_query_to_text(q));
return;
}
@@ -466,12 +460,12 @@ mfa_drain_query(struct mfa_query *q)
* Do not move forward if the query ahead of us is
* waiting on this filter.
*/
- prev = TAILQ_PREV(q, mfa_queries, entry);
+ prev = TAILQ_PREV(q, filter_queries, entry);
if (prev && prev->current == q->current) {
q->state = QUERY_WAITING;
log_trace(TRACE_MFA,
"filter: query blocked by previous query %s",
- mfa_query_to_text(prev));
+ filter_query_to_text(prev));
return;
}
@@ -481,6 +475,8 @@ mfa_drain_query(struct mfa_query *q)
q->state = QUERY_DONE;
}
+ TAILQ_REMOVE(&q->session->queries, q, entry);
+
if (q->type == QT_QUERY) {
log_trace(TRACE_MFA,
"filter: query %016"PRIx64" done: "
@@ -492,32 +488,30 @@ mfa_drain_query(struct mfa_query *q)
/* ...and send the SMTP response */
if (q->hook == QUERY_EOM) {
- mfa_report_eom(q->session->id, q->u.datalen);
+/*
+ smtp_filter_eom(q->session->id, q->u.datalen);
+*/
+ smtp_filter_response(q->session->id, q->hook,
+ q->smtp.status, q->smtp.code, q->smtp.response);
}
else {
- m_create(p_smtp, IMSG_MFA_SMTP_RESPONSE, 0, 0, -1);
- m_add_id(p_smtp, q->session->id);
- m_add_int(p_smtp, q->smtp.status);
- m_add_u32(p_smtp, q->smtp.code);
- if (q->smtp.response)
- m_add_string(p_smtp, q->smtp.response);
- m_close(p_smtp);
+ smtp_filter_response(q->session->id, q->hook,
+ q->smtp.status, q->smtp.code, q->smtp.response);
}
free(q->smtp.response);
}
- TAILQ_REMOVE(&q->session->queries, q, entry);
log_trace(TRACE_MFA, "filter: freeing query %016" PRIx64, q->qid);
free(q);
}
static void
-mfa_run_query(struct mfa_filter *f, struct mfa_query *q)
+filter_run_query(struct filter *f, struct filter_query *q)
{
if (q->type == QT_QUERY) {
log_trace(TRACE_MFA, "filter: running filter %s for query %s",
- mfa_filter_to_text(f), mfa_query_to_text(q));
+ filter_to_text(f), filter_query_to_text(q));
m_create(&f->proc->mproc, IMSG_FILTER_QUERY, 0, 0, -1);
m_add_id(&f->proc->mproc, q->session->id);
@@ -552,7 +546,7 @@ mfa_run_query(struct mfa_filter *f, struct mfa_query *q)
}
else {
log_trace(TRACE_MFA, "filter: running filter %s for query %s",
- mfa_filter_to_text(f), mfa_query_to_text(q));
+ filter_to_text(f), filter_query_to_text(q));
m_create(&f->proc->mproc, IMSG_FILTER_EVENT, 0, 0, -1);
m_add_id(&f->proc->mproc, q->session->id);
@@ -562,11 +556,11 @@ mfa_run_query(struct mfa_filter *f, struct mfa_query *q)
}
static void
-mfa_filter_imsg(struct mproc *p, struct imsg *imsg)
+filter_imsg(struct mproc *p, struct imsg *imsg)
{
- struct mfa_filterproc *proc = p->data;
- struct mfa_session *s;
- struct mfa_query *q, *next;
+ struct filter_proc *proc = p->data;
+ struct filter_session *s;
+ struct filter_query *q, *next;
struct msg m;
const char *line;
uint64_t qid;
@@ -580,7 +574,7 @@ mfa_filter_imsg(struct mproc *p, struct imsg *imsg)
log_trace(TRACE_MFA, "filter: imsg %s from procfilter %s",
filterimsg_to_str(imsg->hdr.type),
- mfa_filterproc_to_text(proc));
+ filter_proc_to_text(proc));
switch (imsg->hdr.type) {
@@ -603,7 +597,8 @@ mfa_filter_imsg(struct mproc *p, struct imsg *imsg)
TAILQ_FOREACH(proc, &procs, entry)
if (!proc->ready)
return;
- mfa_ready();
+
+ smtp_configure();
break;
case IMSG_FILTER_RESPONSE:
@@ -630,21 +625,21 @@ mfa_filter_imsg(struct mproc *p, struct imsg *imsg)
q->smtp.code = code;
if (line) {
free(q->smtp.response);
- q->smtp.response = xstrdup(line, "mfa_filter_imsg");
+ q->smtp.response = xstrdup(line, "filter_imsg");
}
q->state = (status == FILTER_OK) ? QUERY_READY : QUERY_DONE;
if (qhook == QUERY_EOM)
q->u.datalen = datalen;
next = TAILQ_NEXT(q, entry);
- mfa_drain_query(q);
+ filter_drain_query(q);
/*
* If there is another query after this one which is waiting,
* make it move forward.
*/
if (next && next->state == QUERY_WAITING)
- mfa_drain_query(next);
+ filter_drain_query(next);
break;
case IMSG_FILTER_PIPE_SETUP:
@@ -653,8 +648,8 @@ mfa_filter_imsg(struct mproc *p, struct imsg *imsg)
m_end(&m);
s = tree_xget(&sessions, qid);
- s->fcurr = TAILQ_PREV(s->fcurr, mfa_filters, entry);
- mfa_set_fdout(s, imsg->fd);
+ s->fcurr = TAILQ_PREV(s->fcurr, filter_lst, entry);
+ filter_set_fdout(s, imsg->fd);
break;
default:
@@ -664,7 +659,7 @@ mfa_filter_imsg(struct mproc *p, struct imsg *imsg)
}
static const char *
-mfa_query_to_text(struct mfa_query *q)
+filter_query_to_text(struct filter_query *q)
{
static char buf[1024];
char tmp[1024];
@@ -705,17 +700,17 @@ mfa_query_to_text(struct mfa_query *q)
}
static const char *
-mfa_filter_to_text(struct mfa_filter *f)
+filter_to_text(struct filter *f)
{
static char buf[1024];
- snprintf(buf, sizeof buf, "filter:%s", mfa_filterproc_to_text(f->proc));
+ snprintf(buf, sizeof buf, "filter:%s", filter_proc_to_text(f->proc));
return (buf);
}
static const char *
-mfa_filterproc_to_text(struct mfa_filterproc *proc)
+filter_proc_to_text(struct filter_proc *proc)
{
static char buf[1024];
@@ -788,10 +783,10 @@ static const char *
status_to_str(int status)
{
switch (status) {
- CASE(MFA_OK);
- CASE(MFA_FAIL);
- CASE(MFA_CLOSE);
+ CASE(FILTER_OK);
+ CASE(FILTER_FAIL);
+ CASE(FILTER_CLOSE);
default:
- return "MFA_???";
+ return "FILTER_???";
}
}
diff --git a/smtpd/filter_api.c b/smtpd/filter_api.c
index c62631ec..b40a709a 100644
--- a/smtpd/filter_api.c
+++ b/smtpd/filter_api.c
@@ -95,7 +95,7 @@ static struct filter_internals {
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, enum filter_hook);
+static void filter_register_query(uint64_t, uint64_t, enum filter_hook_type);
static void filter_dispatch(struct mproc *, struct imsg *);
static void filter_dispatch_dataline(uint64_t, const char *);
static void filter_dispatch_data(uint64_t);
@@ -338,7 +338,7 @@ filter_dispatch(struct mproc *p, struct imsg *imsg)
}
static void
-filter_register_query(uint64_t id, uint64_t qid, enum filter_hook hook)
+filter_register_query(uint64_t id, uint64_t qid, enum filter_hook_type hook)
{
struct filter_session *s;
diff --git a/smtpd/mfa.c b/smtpd/mfa.c
deleted file mode 100644
index ce27f7ee..00000000
--- a/smtpd/mfa.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/* $OpenBSD$ */
-
-/*
- * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
- * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
- *
- * 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 <sys/types.h>
-#include <sys/wait.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/socket.h>
-
-#include <err.h>
-#include <errno.h>
-#include <event.h>
-#include <imsg.h>
-#include <inttypes.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "smtpd.h"
-#include "log.h"
-
-struct mfa_tx {
- uint64_t reqid;
- struct io io;
- struct iobuf iobuf;
- FILE *ofile;
- size_t datain;
- size_t datalen;
- int eom;
- int error;
-};
-
-static void mfa_imsg(struct mproc *, struct imsg *);
-static void mfa_shutdown(void);
-static void mfa_sig_handler(int, short, void *);
-static void mfa_tx_io(struct io *, int);
-static int mfa_tx(uint64_t, int);
-static void mfa_tx_done(struct mfa_tx *);
-
-struct tree tx_tree;
-
-static void
-mfa_imsg(struct mproc *p, struct imsg *imsg)
-{
- struct sockaddr_storage local, remote;
- struct mailaddr maddr;
- struct msg m;
- const char *line, *hostname;
- uint64_t reqid;
- uint32_t datalen; /* XXX make it off_t? */
- int v, success, fdout;
-
- if (p->proc == PROC_PONY) {
- switch (imsg->hdr.type) {
- case IMSG_SMTP_REQ_CONNECT:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_sockaddr(&m, (struct sockaddr *)&local);
- m_get_sockaddr(&m, (struct sockaddr *)&remote);
- m_get_string(&m, &hostname);
- m_end(&m);
- mfa_filter_event(reqid, EVENT_CONNECT);
- mfa_filter_connect(reqid, (struct sockaddr *)&local,
- (struct sockaddr *)&remote, hostname);
- return;
-
- case IMSG_SMTP_REQ_HELO:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_string(&m, &line);
- m_end(&m);
- mfa_filter_line(reqid, QUERY_HELO, line);
- return;
-
- case IMSG_SMTP_REQ_MAIL:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_mailaddr(&m, &maddr);
- m_end(&m);
- mfa_filter_mailaddr(reqid, QUERY_MAIL, &maddr);
- return;
-
- case IMSG_SMTP_REQ_RCPT:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_mailaddr(&m, &maddr);
- m_end(&m);
- mfa_filter_mailaddr(reqid, QUERY_RCPT, &maddr);
- return;
-
- case IMSG_SMTP_REQ_DATA:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_end(&m);
- mfa_filter(reqid, QUERY_DATA);
- return;
-
- case IMSG_SMTP_REQ_EOM:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_u32(&m, &datalen);
- m_end(&m);
- mfa_filter_eom(reqid, QUERY_EOM, datalen);
- return;
-
- case IMSG_SMTP_EVENT_RSET:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_end(&m);
- mfa_filter_event(reqid, EVENT_RESET);
- return;
-
- case IMSG_SMTP_EVENT_COMMIT:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_end(&m);
- mfa_filter_event(reqid, EVENT_COMMIT);
- return;
-
- case IMSG_SMTP_EVENT_ROLLBACK:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_end(&m);
- mfa_filter_event(reqid, EVENT_ROLLBACK);
- return;
-
- case IMSG_SMTP_EVENT_DISCONNECT:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_end(&m);
- mfa_filter_event(reqid, EVENT_DISCONNECT);
- return;
- }
- }
-
- if (p->proc == PROC_QUEUE) {
- switch (imsg->hdr.type) {
- case IMSG_QUEUE_MESSAGE_FILE:
- m_msg(&m, imsg);
- m_get_id(&m, &reqid);
- m_get_int(&m, &success);
- m_end(&m);
-
- fdout = mfa_tx(reqid, imsg->fd);
- mfa_build_fd_chain(reqid, fdout);
- return;
- }
- }
-
- if (p->proc == PROC_PARENT) {
- switch (imsg->hdr.type) {
- case IMSG_CONF_START:
- return;
-
- case IMSG_CONF_FILTER:
- return;
-
- case IMSG_CONF_END:
- mfa_filter_init();
- return;
-
- case IMSG_CTL_VERBOSE:
- m_msg(&m, imsg);
- m_get_int(&m, &v);
- m_end(&m);
- log_verbose(v);
- return;
-
- case IMSG_CTL_PROFILE:
- m_msg(&m, imsg);
- m_get_int(&m, &v);
- m_end(&m);
- profiling = v;
- return;
- }
- }
-
- errx(1, "mfa_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
-}
-
-static void
-mfa_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- mfa_shutdown();
- break;
-
- case SIGCHLD:
- fatalx("unexpected SIGCHLD");
- break;
-
- default:
- fatalx("mfa_sig_handler: unexpected signal");
- }
-}
-
-static void
-mfa_shutdown(void)
-{
- pid_t pid;
-
- do {
- pid = waitpid(WAIT_MYPGRP, NULL, 0);
- } while (pid != -1 || (pid == -1 && errno == EINTR));
-
- log_info("info: mail filter exiting");
- _exit(0);
-}
-
-pid_t
-mfa(void)
-{
- pid_t pid;
- struct passwd *pw;
- struct event ev_sigint;
- struct event ev_sigterm;
- struct event ev_sigchld;
-
- switch (pid = fork()) {
- case -1:
- fatal("filter: cannot fork");
- case 0:
- post_fork(PROC_MFA);
- break;
- default:
- return (pid);
- }
-
- mfa_filter_prepare();
-
- purge_config(PURGE_EVERYTHING);
-
- if ((pw = getpwnam(SMTPD_USER)) == NULL)
- fatalx("unknown user " SMTPD_USER);
-
- config_process(PROC_MFA);
-
- if (chroot(PATH_CHROOT) == -1)
- fatal("scheduler: chroot");
- if (chdir("/") == -1)
- fatal("scheduler: chdir(\"/\")");
-
- if (setgroups(1, &pw->pw_gid) ||
- setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
- setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
- fatal("filter: cannot drop privileges");
-
- imsg_callback = mfa_imsg;
- event_init();
-
- tree_init(&tx_tree);
-
- signal_set(&ev_sigint, SIGINT, mfa_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, mfa_sig_handler, NULL);
- signal_set(&ev_sigchld, SIGCHLD, mfa_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
- signal_add(&ev_sigchld, NULL);
- signal(SIGPIPE, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
-
- config_peer(PROC_PARENT);
- config_peer(PROC_QUEUE);
- config_peer(PROC_CONTROL);
- config_peer(PROC_PONY);
- config_done();
-
- mproc_disable(p_pony);
-
- if (event_dispatch() < 0)
- fatal("event_dispatch");
- mfa_shutdown();
-
- return (0);
-}
-
-void
-mfa_ready(void)
-{
- log_debug("debug: mfa ready");
- mproc_enable(p_pony);
-}
-
-static int
-mfa_tx(uint64_t reqid, int fdout)
-{
- struct mfa_tx *tx;
- int sp[2];
-
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) {
- log_warn("warn: mfa: socketpair");
- return (-1);
- }
-
- tx = xcalloc(1, sizeof(*tx), "mfa_tx");
-
- if ((tx->ofile = fdopen(fdout, "w")) == NULL) {
- log_warn("warn: mfa: fdopen");
- free(tx);
- close(sp[0]);
- close(sp[1]);
- return (-1);
- }
-
- iobuf_init(&tx->iobuf, 0, 0);
- io_init(&tx->io, sp[0], tx, mfa_tx_io, &tx->iobuf);
- io_set_read(&tx->io);
- tx->reqid = reqid;
- tree_xset(&tx_tree, reqid, tx);
-
- return (sp[1]);
-}
-
-static void
-mfa_tx_io(struct io *io, int evt)
-{
- struct mfa_tx *tx = io->arg;
- size_t len, n;
- char *data;
-
- switch (evt) {
- case IO_DATAIN:
- data = iobuf_data(&tx->iobuf);
- len = iobuf_len(&tx->iobuf);
- log_debug("debug: mfa: tx data (%zu) for req %016"PRIx64,
- len, tx->reqid);
- n = fwrite(data, 1, len, tx->ofile);
- if (n != len) {
- tx->error = 1;
- break;
- }
- tx->datain += n;
- iobuf_drop(&tx->iobuf, n);
- iobuf_normalize(&tx->iobuf);
- return;
-
- case IO_DISCONNECTED:
- log_debug("debug: mfa: tx done for req %016"PRIx64,
- tx->reqid);
- break;
-
- default:
- log_debug("debug: mfa: tx error for req %016"PRIx64,
- tx->reqid);
- tx->error = 1;
- break;
- }
-
- io_clear(&tx->io);
- iobuf_clear(&tx->iobuf);
- fclose(tx->ofile);
- tx->ofile = NULL;
- if (tx->eom)
- mfa_tx_done(tx);
-}
-
-static void
-mfa_tx_done(struct mfa_tx *tx)
-{
- log_debug("debug: mfa: tx done for %016"PRIx64, tx->reqid);
-
- tree_xpop(&tx_tree, tx->reqid);
-
- if (!tx->error && tx->datain != tx->datalen) {
- log_debug("debug: mfa: tx datalen mismatch: %zu/%zu",
- tx->datain, tx->datalen);
- tx->error = 1;
- }
-
- if (tx->error) {
- log_debug("debug: mfa: tx error");
-
- m_create(p_pony, IMSG_MFA_SMTP_RESPONSE, 0, 0, -1);
- m_add_id(p_pony, tx->reqid);
- m_add_int(p_pony, MFA_FAIL);
- m_add_u32(p_pony, 0);
- m_add_string(p_pony, "Internal server error");
- m_close(p_pony);
- }
- else {
- /* XXX we could send the commit message here directly */
- m_create(p_pony, IMSG_MFA_SMTP_RESPONSE, 0, 0, -1);
- m_add_id(p_pony, tx->reqid);
- m_add_int(p_pony, MFA_OK);
- m_add_u32(p_pony, 300);
- m_add_string(p_pony, "This is not to be sent to the client");
- m_close(p_pony);
- }
-
- free(tx);
-}
-
-void
-mfa_report_eom(uint64_t reqid, size_t size)
-{
- struct mfa_tx *tx;
-
- tx = tree_xget(&tx_tree, reqid);
-
- tx->datalen = size;
- tx->eom = 1;
-
- if (tx->ofile == NULL)
- mfa_tx_done(tx);
-}
diff --git a/smtpd/mproc.c b/smtpd/mproc.c
index 9e5b33e2..dbcf5713 100644
--- a/smtpd/mproc.c
+++ b/smtpd/mproc.c
@@ -63,7 +63,7 @@ mproc_fork(struct mproc *p, const char *path, const char *arg)
exit(1);
execl(path, arg, NULL);
- err(1, "execl");
+ err(1, "execl: %s", path);
}
/* parent process */
diff --git a/smtpd/parse.y b/smtpd/parse.y
index 0c55245b..ed938b62 100644
--- a/smtpd/parse.y
+++ b/smtpd/parse.y
@@ -91,7 +91,7 @@ char *symget(const char *);
struct smtpd *conf = NULL;
static int errors = 0;
-struct filter *filter = NULL;
+struct filter_conf *filter = NULL;
struct table *table = NULL;
struct rule *rule = NULL;
struct listener l;
@@ -125,9 +125,9 @@ void set_localaddrs(struct table *);
int delaytonum(char *);
int is_if_in_group(const char *, const char *);
-static struct filter *create_filter(const char *, const char *);
-static struct filter *create_filter_chain(const char *);
-static int extend_filter_chain(struct filter *, const char *);
+static struct filter_conf *create_filter(const char *, const char *);
+static struct filter_conf *create_filter_chain(const char *);
+static int extend_filter_chain(struct filter_conf *, const char *);
typedef struct {
union {
@@ -2125,10 +2125,10 @@ end:
return ret;
}
-struct filter *
+struct filter_conf *
create_filter(const char *name, const char *path)
{
- struct filter *f;
+ struct filter_conf *f;
if (dict_get(&conf->sc_filters, name)) {
yyerror("filter \"%s\" already defined", name);
@@ -2137,17 +2137,19 @@ create_filter(const char *name, const char *path)
f = xcalloc(1, sizeof(*f), "create_filter");
strlcpy(f->name, name, sizeof(f->name));
- strlcpy(f->path, path, sizeof(f->path));
+ strlcpy(f->path, PATH_FILTERS, sizeof(f->path));
+ strlcat(f->path, "/filter-", sizeof(f->path));
+ strlcat(f->path, path, sizeof(f->path));
dict_xset(&conf->sc_filters, name, f);
return (f);
}
-static struct filter *
+static struct filter_conf *
create_filter_chain(const char *name)
{
- struct filter *f;
+ struct filter_conf *f;
if (dict_get(&conf->sc_filters, name)) {
yyerror("filter \"%s\" already defined", name);
@@ -2163,7 +2165,7 @@ create_filter_chain(const char *name)
}
static int
-extend_filter_chain(struct filter *f, const char *name)
+extend_filter_chain(struct filter_conf *f, const char *name)
{
int i;
diff --git a/smtpd/pony.c b/smtpd/pony.c
index 4a5bcd1d..a6121223 100644
--- a/smtpd/pony.c
+++ b/smtpd/pony.c
@@ -56,7 +56,7 @@ pony_imsg(struct mproc *p, struct imsg *imsg)
case IMSG_CONF_START:
return;
case IMSG_CONF_END:
- smtp_configure();
+ filter_configure();
return;
case IMSG_CTL_VERBOSE:
m_msg(&m, imsg);
@@ -170,6 +170,7 @@ pony(void)
mda_postfork();
mta_postfork();
smtp_postfork();
+ filter_postfork();
/* do not purge listeners and pki, they are purged
* in smtp_configure()
diff --git a/smtpd/smtp.c b/smtpd/smtp.c
index fb4799d3..2f0cc29f 100644
--- a/smtpd/smtp.c
+++ b/smtpd/smtp.c
@@ -55,9 +55,6 @@ static size_t sessions;
void
smtp_imsg(struct mproc *p, struct imsg *imsg)
{
- struct msg m;
- int v;
-
if (p->proc == PROC_LKA) {
switch (imsg->hdr.type) {
case IMSG_SMTP_DNS_PTR:
@@ -89,32 +86,6 @@ smtp_imsg(struct mproc *p, struct imsg *imsg)
}
}
- if (p->proc == PROC_PARENT) {
- switch (imsg->hdr.type) {
-
- case IMSG_CONF_START:
- return;
-
- case IMSG_CONF_END:
- smtp_setup_events();
- return;
-
- case IMSG_CTL_VERBOSE:
- m_msg(&m, imsg);
- m_get_int(&m, &v);
- m_end(&m);
- log_verbose(v);
- return;
-
- case IMSG_CTL_PROFILE:
- m_msg(&m, imsg);
- m_get_int(&m, &v);
- m_end(&m);
- profiling = v;
- return;
- }
- }
-
if (p->proc == PROC_CONTROL) {
switch (imsg->hdr.type) {
case IMSG_CTL_SMTP_SESSION:
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index 0708f273..f5865b53 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -158,8 +158,6 @@ static void smtp_session_init(void);
static int smtp_lookup_servername(struct smtp_session *);
static void smtp_connected(struct smtp_session *);
static void smtp_send_banner(struct smtp_session *);
-static void smtp_mfa_response(struct smtp_session *, int, int, uint32_t,
- const char *);
static void smtp_io(struct io *, int);
static void smtp_enter_state(struct smtp_session *, int);
static void smtp_reply(struct smtp_session *, char *, ...);
@@ -209,6 +207,7 @@ static struct { int code; const char *cmd; } commands[] = {
static struct tree wait_lka_ptr;
static struct tree wait_lka_helo;
static struct tree wait_lka_rcpt;
+static struct tree wait_mfa;
static struct tree wait_mfa_data;
static struct tree wait_parent_auth;
static struct tree wait_queue_msg;
@@ -226,6 +225,7 @@ smtp_session_init(void)
tree_init(&wait_lka_ptr);
tree_init(&wait_lka_helo);
tree_init(&wait_lka_rcpt);
+ tree_init(&wait_mfa);
tree_init(&wait_mfa_data);
tree_init(&wait_parent_auth);
tree_init(&wait_queue_msg);
@@ -622,13 +622,16 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
fatalx(NULL);
}
-static void
-smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
+void
+smtp_filter_response(uint64_t id, int query, int status, uint32_t code,
const char *line)
{
- struct ca_cert_req_msg req_ca_cert;
+ struct smtp_session *s;
+ struct ca_cert_req_msg req_ca_cert;
- if (status == MFA_CLOSE) {
+ s = tree_xpop(&wait_mfa, id);
+
+ if (status == FILTER_CLOSE) {
code = code ? code : 421;
line = line ? line : "Temporary failure";
smtp_reply(s, "%d %s", code, line);
@@ -637,10 +640,10 @@ smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
return;
}
- switch (msg) {
+ switch (query) {
- case IMSG_SMTP_REQ_CONNECT:
- if (status != MFA_OK) {
+ case QUERY_CONNECT:
+ if (status != FILTER_OK) {
log_info("smtp-in: Disconnecting session %016" PRIx64
": rejected by filter", s->id);
smtp_free(s, "rejected by filter");
@@ -663,8 +666,8 @@ smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
smtp_send_banner(s);
return;
- case IMSG_SMTP_REQ_HELO:
- if (status != MFA_OK) {
+ case QUERY_HELO:
+ if (status != FILTER_OK) {
code = code ? code : 530;
line = line ? line : "Hello rejected";
smtp_reply(s, "%d %s", code, line);
@@ -695,8 +698,8 @@ smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
io_reload(&s->io);
return;
- case IMSG_SMTP_REQ_MAIL:
- if (status != MFA_OK) {
+ case QUERY_MAIL:
+ if (status != FILTER_OK) {
code = code ? code : 530;
line = line ? line : "Sender rejected";
smtp_reply(s, "%d %s", code, line);
@@ -710,8 +713,8 @@ smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
tree_xset(&wait_queue_msg, s->id, s);
return;
- case IMSG_SMTP_REQ_RCPT:
- if (status != MFA_OK) {
+ case QUERY_RCPT:
+ if (status != FILTER_OK) {
code = code ? code : 530;
line = line ? line : "Recipient rejected";
smtp_reply(s, "%d %s", code, line);
@@ -733,8 +736,8 @@ smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
tree_xset(&wait_lka_rcpt, s->id, s);
return;
- case IMSG_SMTP_REQ_DATA:
- if (status != MFA_OK) {
+ case QUERY_DATA:
+ if (status != FILTER_OK) {
code = code ? code : 530;
line = line ? line : "Message rejected";
smtp_reply(s, "%d %s", code, line);
@@ -748,8 +751,8 @@ smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
tree_xset(&wait_queue_fd, s->id, s);
return;
- case IMSG_SMTP_REQ_EOM:
- if (status != MFA_OK) {
+ case QUERY_EOM:
+ if (status != FILTER_OK) {
code = code ? code : 530;
line = line ? line : "Message rejected";
smtp_reply(s, "%d %s", code, line);
@@ -760,7 +763,7 @@ smtp_mfa_response(struct smtp_session *s, int msg, int status, uint32_t code,
return;
default:
- fatal("bad mfa_imsg");
+ log_warn("smtp: bad mfa query type %d", query);
}
}
@@ -1851,57 +1854,69 @@ smtp_sni_callback(SSL *ssl, int *ad, void *arg)
static void
smtp_filter_rset(struct smtp_session *s)
{
+ filter_event(s->id, EVENT_RESET);
}
static void
smtp_filter_commit(struct smtp_session *s)
{
+ filter_event(s->id, EVENT_COMMIT);
}
static void
smtp_filter_rollback(struct smtp_session *s)
{
+ filter_event(s->id, EVENT_ROLLBACK);
}
static void
smtp_filter_disconnect(struct smtp_session *s)
{
+ filter_event(s->id, EVENT_DISCONNECT);
}
static void
smtp_filter_connect(struct smtp_session *s, struct sockaddr *sa)
{
- smtp_mfa_response(s, IMSG_SMTP_REQ_CONNECT, MFA_OK, 0, NULL);
+ filter_event(s->id, EVENT_CONNECT);
+
+ tree_xset(&wait_mfa, s->id, s);
+ filter_connect(s->id, sa, (struct sockaddr *)&s->ss, s->hostname);
}
static void
smtp_filter_eom(struct smtp_session *s)
{
- smtp_mfa_response(s, IMSG_SMTP_REQ_EOM, MFA_OK, 0, NULL);
+ tree_xset(&wait_mfa, s->id, s);
+ filter_eom(s->id, QUERY_EOM, s->datalen);
}
static void
smtp_filter_helo(struct smtp_session *s)
{
- smtp_mfa_response(s, IMSG_SMTP_REQ_HELO, MFA_OK, 0, NULL);
+ tree_xset(&wait_mfa, s->id, s);
+ filter_line(s->id, QUERY_HELO, s->helo);
}
static void
smtp_filter_mail(struct smtp_session *s)
{
- smtp_mfa_response(s, IMSG_SMTP_REQ_MAIL, MFA_OK, 0, NULL);
+ tree_xset(&wait_mfa, s->id, s);
+ filter_mailaddr(s->id, QUERY_MAIL, &s->evp.sender);
}
static void
smtp_filter_rcpt(struct smtp_session *s)
{
- smtp_mfa_response(s, IMSG_SMTP_REQ_RCPT, MFA_OK, 0, NULL);
+ tree_xset(&wait_mfa, s->id, s);
+ filter_mailaddr(s->id, QUERY_RCPT, &s->evp.rcpt);
}
static void
smtp_filter_data(struct smtp_session *s)
{
- smtp_mfa_response(s, IMSG_SMTP_REQ_DATA, MFA_OK, 0, NULL);
+ tree_xset(&wait_mfa, s->id, s);
+ filter_line(s->id, QUERY_DATA, NULL);
}
static void
diff --git a/smtpd/smtpd-api.h b/smtpd/smtpd-api.h
index 0cc637e8..98e83570 100644
--- a/smtpd/smtpd-api.h
+++ b/smtpd/smtpd-api.h
@@ -64,7 +64,7 @@ enum filter_imsg {
};
/* XXX - server side requires mfa_session.c update on filter_event */
-enum filter_event {
+enum filter_event_type {
EVENT_CONNECT,
EVENT_RESET,
EVENT_DISCONNECT,
@@ -73,7 +73,7 @@ enum filter_event {
};
/* XXX - server side requires mfa_session.c update on filter_hook changes */
-enum filter_query {
+enum filter_query_type {
QUERY_CONNECT,
QUERY_HELO,
QUERY_MAIL,
@@ -84,7 +84,7 @@ enum filter_query {
};
/* XXX - server side requires mfa_session.c update on filter_hook changes */
-enum filter_hook {
+enum filter_hook_type {
HOOK_CONNECT = 1 << 0,
HOOK_HELO = 1 << 1,
HOOK_MAIL = 1 << 2,
diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h
index d848b5f4..9a5e47b9 100644
--- a/smtpd/smtpd.h
+++ b/smtpd/smtpd.h
@@ -632,7 +632,7 @@ struct deliver {
};
#define MAX_FILTER_PER_CHAIN 16
-struct filter {
+struct filter_conf {
int chain;
int done;
char name[MAX_FILTER_NAME];
@@ -1005,12 +1005,6 @@ struct bounce_req_msg {
struct delivery_bounce bounce;
};
-enum mfa_resp_status {
- MFA_OK,
- MFA_FAIL,
- MFA_CLOSE,
-};
-
enum dns_error {
DNS_OK = 0,
DNS_RETRY,
@@ -1183,23 +1177,16 @@ void mda_postprivdrop(void);
void mda_imsg(struct mproc *, struct imsg *);
-/* mfa.c */
-pid_t mfa(void);
-void mfa_ready(void);
-
-
-/* mfa_session.c */
-void mfa_filter_prepare(void);
-void mfa_filter_init(void);
-void mfa_filter_connect(uint64_t, const struct sockaddr *,
+/* filter.c */
+void filter_postfork(void);
+void filter_configure(void);
+void filter_connect(uint64_t, const struct sockaddr *,
const struct sockaddr *, const char *);
-void mfa_filter_mailaddr(uint64_t, int, const struct mailaddr *);
-void mfa_filter_line(uint64_t, int, const char *);
-void mfa_filter_eom(uint64_t, int, size_t);
-void mfa_filter(uint64_t, int);
-void mfa_filter_event(uint64_t, int);
-void mfa_build_fd_chain(uint64_t, int);
-
+void filter_mailaddr(uint64_t, int, const struct mailaddr *);
+void filter_line(uint64_t, int, const char *);
+void filter_eom(uint64_t, int, size_t);
+void filter_event(uint64_t, int);
+void filter_build_fd_chain(uint64_t, int);
/* mproc.c */
int mproc_fork(struct mproc *, const char*, const char *);
@@ -1324,7 +1311,7 @@ void smtp_collect(void);
int smtp_session(struct listener *, int, const struct sockaddr_storage *,
const char *);
void smtp_session_imsg(struct mproc *, struct imsg *);
-
+void smtp_filter_response(uint64_t, int, int, uint32_t, const char *);
/* smtpd.c */
void imsg_dispatch(struct mproc *, struct imsg *);
diff --git a/smtpd/smtpd/Makefile b/smtpd/smtpd/Makefile
index fe560443..203737a4 100644
--- a/smtpd/smtpd/Makefile
+++ b/smtpd/smtpd/Makefile
@@ -20,6 +20,7 @@ SRCS+= dns.c
SRCS+= envelope.c
SRCS+= esc.c
SRCS+= expand.c
+SRCS+= filter.c
SRCS+= forward.c
SRCS+= iobuf.c
SRCS+= ioev.c
@@ -28,8 +29,6 @@ SRCS+= lka.c
SRCS+= lka_session.c
SRCS+= log.c
SRCS+= mda.c
-#SRCS+= mfa.c
-#SRCS+= mfa_session.c
SRCS+= mproc.c
SRCS+= mta.c
SRCS+= mta_session.c