aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2018-12-27 10:54:44 +0100
committerGilles Chehade <gilles@poolp.org>2018-12-27 10:54:44 +0100
commit995cc445c2dc0228ef8a31d88d2bc13d3c608311 (patch)
treef34c145f0219157938f7eb2738d43b3dec368c40
parentMerge branch 'master' into portable (diff)
parentsync (diff)
downloadOpenSMTPD-995cc445c2dc0228ef8a31d88d2bc13d3c608311.tar.xz
OpenSMTPD-995cc445c2dc0228ef8a31d88d2bc13d3c608311.zip
Merge branch 'master' into portable
-rw-r--r--smtpd/aliases.c18
-rw-r--r--smtpd/dict.c9
-rw-r--r--smtpd/dict.h48
-rw-r--r--smtpd/lka.c167
-rw-r--r--smtpd/lka_filter.c249
-rw-r--r--smtpd/lka_session.c4
-rw-r--r--smtpd/mta.c10
-rw-r--r--smtpd/mta_session.c209
-rw-r--r--smtpd/parse.y49
-rw-r--r--smtpd/pony.c6
-rw-r--r--smtpd/ruleset.c54
-rw-r--r--smtpd/smtp.c4
-rw-r--r--smtpd/smtp_session.c200
-rw-r--r--smtpd/smtpd-api.h52
-rw-r--r--smtpd/smtpd.c14
-rw-r--r--smtpd/smtpd.h57
-rw-r--r--smtpd/table.c204
-rw-r--r--smtpd/table_db.c73
-rw-r--r--smtpd/table_getpwnam.c41
-rw-r--r--smtpd/table_proc.c62
-rw-r--r--smtpd/table_static.c48
-rw-r--r--smtpd/tree.c9
-rw-r--r--smtpd/tree.h48
23 files changed, 528 insertions, 1107 deletions
diff --git a/smtpd/aliases.c b/smtpd/aliases.c
index be350897..0ce4c7ec 100644
--- a/smtpd/aliases.c
+++ b/smtpd/aliases.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aliases.c,v 1.73 2018/06/16 19:41:26 gilles Exp $ */
+/* $OpenBSD: aliases.c,v 1.75 2018/12/26 20:13:43 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -65,7 +65,7 @@ aliases_get(struct expand *expand, const char *username)
/* first, check if entry has a user-part tag */
pbuf = strchr(buf, *env->sc_subaddressing_delim);
if (pbuf) {
- ret = table_lookup(mapping, NULL, buf, K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, buf, &lk);
if (ret < 0)
return (-1);
if (ret)
@@ -74,7 +74,7 @@ aliases_get(struct expand *expand, const char *username)
}
/* no user-part tag, try looking up user */
- ret = table_lookup(mapping, NULL, buf, K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, buf, &lk);
if (ret <= 0)
return ret;
@@ -138,7 +138,7 @@ aliases_virtual_get(struct expand *expand, const struct mailaddr *maddr)
if (!bsnprintf(buf, sizeof(buf), "%s%c%s@%s",
user, *env->sc_subaddressing_delim, tag, domain))
return 0;
- ret = table_lookup(mapping, NULL, buf, K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, buf, &lk);
if (ret < 0)
return (-1);
if (ret)
@@ -148,7 +148,7 @@ aliases_virtual_get(struct expand *expand, const struct mailaddr *maddr)
/* then, check if entry exists without user-part tag */
if (!bsnprintf(buf, sizeof(buf), "%s@%s", user, domain))
return 0;
- ret = table_lookup(mapping, NULL, buf, K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, buf, &lk);
if (ret < 0)
return (-1);
if (ret)
@@ -159,7 +159,7 @@ aliases_virtual_get(struct expand *expand, const struct mailaddr *maddr)
if (!bsnprintf(buf, sizeof(buf), "%s%c%s",
user, *env->sc_subaddressing_delim, tag))
return 0;
- ret = table_lookup(mapping, NULL, buf, K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, buf, &lk);
if (ret < 0)
return (-1);
if (ret)
@@ -169,7 +169,7 @@ aliases_virtual_get(struct expand *expand, const struct mailaddr *maddr)
/* Failed ? We lookup for username only */
if (!bsnprintf(buf, sizeof(buf), "%s", user))
return 0;
- ret = table_lookup(mapping, NULL, buf, K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, buf, &lk);
if (ret < 0)
return (-1);
if (ret)
@@ -178,14 +178,14 @@ aliases_virtual_get(struct expand *expand, const struct mailaddr *maddr)
if (!bsnprintf(buf, sizeof(buf), "@%s", domain))
return 0;
/* Failed ? We lookup for catch all for virtual domain */
- ret = table_lookup(mapping, NULL, buf, K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, buf, &lk);
if (ret < 0)
return (-1);
if (ret)
goto expand;
/* Failed ? We lookup for a *global* catch all */
- ret = table_lookup(mapping, NULL, "@", K_ALIAS, &lk);
+ ret = table_lookup(mapping, K_ALIAS, "@", &lk);
if (ret <= 0)
return (ret);
diff --git a/smtpd/dict.c b/smtpd/dict.c
index d5998052..e660f0a5 100644
--- a/smtpd/dict.c
+++ b/smtpd/dict.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dict.c,v 1.5 2015/01/20 17:37:54 deraadt Exp $ */
+/* $OpenBSD: dict.c,v 1.6 2018/12/23 16:06:24 gilles Exp $ */
/*
* Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
@@ -22,17 +22,12 @@
#include <sys/types.h>
#include <sys/tree.h>
-#include <sys/socket.h> /* for smtpd.h */
-#include <sys/queue.h> /* for smtpd.h */
-#include <stdio.h> /* for smtpd.h */
-#include <imsg.h> /* for smtpd.h */
-
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-#include "smtpd.h"
+#include "dict.h"
struct dictentry {
SPLAY_ENTRY(dictentry) entry;
diff --git a/smtpd/dict.h b/smtpd/dict.h
new file mode 100644
index 00000000..c5d47e1a
--- /dev/null
+++ b/smtpd/dict.h
@@ -0,0 +1,48 @@
+/* $OpenBSD: dict.h,v 1.1 2018/12/23 16:06:24 gilles Exp $ */
+
+/*
+ * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
+ * Copyright (c) 2011 Gilles Chehade <gilles@poolp.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.
+ */
+
+#ifndef _DICT_H_
+#define _DICT_H_
+
+SPLAY_HEAD(_dict, dictentry);
+
+struct dict {
+ struct _dict dict;
+ size_t count;
+};
+
+
+/* dict.c */
+#define dict_init(d) do { SPLAY_INIT(&((d)->dict)); (d)->count = 0; } while(0)
+#define dict_empty(d) SPLAY_EMPTY(&((d)->dict))
+#define dict_count(d) ((d)->count)
+int dict_check(struct dict *, const char *);
+void *dict_set(struct dict *, const char *, void *);
+void dict_xset(struct dict *, const char *, void *);
+void *dict_get(struct dict *, const char *);
+void *dict_xget(struct dict *, const char *);
+void *dict_pop(struct dict *, const char *);
+void *dict_xpop(struct dict *, const char *);
+int dict_poproot(struct dict *, void **);
+int dict_root(struct dict *, const char **, void **);
+int dict_iter(struct dict *, void **, const char **, void **);
+int dict_iterfrom(struct dict *, void **, const char *, const char **, void **);
+void dict_merge(struct dict *, struct dict *);
+
+#endif
diff --git a/smtpd/lka.c b/smtpd/lka.c
index 519fb1d7..0291d49b 100644
--- a/smtpd/lka.c
+++ b/smtpd/lka.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka.c,v 1.228 2018/12/21 14:33:52 gilles Exp $ */
+/* $OpenBSD: lka.c,v 1.231 2018/12/26 20:13:43 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -60,9 +60,6 @@ static int lka_userinfo(const char *, const char *, struct userinfo *);
static int lka_addrname(const char *, const struct sockaddr *,
struct addrname *);
static int lka_mailaddrmap(const char *, const char *, const struct mailaddr *);
-static int lka_X509_verify(struct ca_vrfy_req_msg *, const char *, const char *);
-static void lka_certificate_verify(enum imsg_type, struct ca_vrfy_req_msg *);
-static void lka_certificate_verify_resume(enum imsg_type, struct ca_vrfy_req_msg *);
static void proc_timeout(int fd, short event, void *p);
@@ -73,12 +70,6 @@ lka_imsg(struct mproc *p, struct imsg *imsg)
{
struct table *table;
int ret;
- struct pki *pki;
- struct iovec iov[2];
- static struct ca_vrfy_req_msg *req_ca_vrfy = NULL;
- struct ca_vrfy_req_msg *req_ca_vrfy_chain;
- struct ca_cert_req_msg *req_ca_cert;
- struct ca_cert_resp_msg resp_ca_cert;
struct sockaddr_storage ss;
struct userinfo userinfo;
struct addrname addrname;
@@ -172,63 +163,6 @@ lka_imsg(struct mproc *p, struct imsg *imsg)
m_close(p);
return;
- case IMSG_SMTP_TLS_INIT:
- case IMSG_MTA_TLS_INIT:
- req_ca_cert = imsg->data;
- resp_ca_cert.reqid = req_ca_cert->reqid;
-
- xlowercase(buf, req_ca_cert->name, sizeof(buf));
- log_debug("debug: lka: looking up pki \"%s\"", buf);
- pki = dict_get(env->sc_pki_dict, buf);
- if (pki == NULL)
- if (req_ca_cert->fallback)
- pki = dict_get(env->sc_pki_dict, "*");
- if (pki == NULL) {
- resp_ca_cert.status = CA_FAIL;
- m_compose(p, imsg->hdr.type, 0, 0, -1, &resp_ca_cert,
- sizeof(resp_ca_cert));
- return;
- }
- resp_ca_cert.status = CA_OK;
- resp_ca_cert.cert_len = pki->pki_cert_len;
- (void)strlcpy(resp_ca_cert.name, pki->pki_name, sizeof resp_ca_cert.name);
- iov[0].iov_base = &resp_ca_cert;
- iov[0].iov_len = sizeof(resp_ca_cert);
- iov[1].iov_base = pki->pki_cert;
- iov[1].iov_len = pki->pki_cert_len;
- m_composev(p, imsg->hdr.type, 0, 0, -1, iov, nitems(iov));
- return;
-
- case IMSG_SMTP_TLS_VERIFY_CERT:
- case IMSG_MTA_TLS_VERIFY_CERT:
- req_ca_vrfy = xmemdup(imsg->data, sizeof *req_ca_vrfy);
- req_ca_vrfy->cert = xmemdup((char *)imsg->data +
- sizeof *req_ca_vrfy, req_ca_vrfy->cert_len);
- req_ca_vrfy->chain_cert = xcalloc(req_ca_vrfy->n_chain,
- sizeof (unsigned char *));
- req_ca_vrfy->chain_cert_len = xcalloc(req_ca_vrfy->n_chain,
- sizeof (off_t));
- return;
-
- case IMSG_SMTP_TLS_VERIFY_CHAIN:
- case IMSG_MTA_TLS_VERIFY_CHAIN:
- if (req_ca_vrfy == NULL)
- fatalx("lka:ca_vrfy: chain without a certificate");
- req_ca_vrfy_chain = imsg->data;
- req_ca_vrfy->chain_cert[req_ca_vrfy->chain_offset] = xmemdup((char *)imsg->data +
- sizeof *req_ca_vrfy_chain, req_ca_vrfy_chain->cert_len);
- req_ca_vrfy->chain_cert_len[req_ca_vrfy->chain_offset] = req_ca_vrfy_chain->cert_len;
- req_ca_vrfy->chain_offset++;
- return;
-
- case IMSG_SMTP_TLS_VERIFY:
- case IMSG_MTA_TLS_VERIFY:
- if (req_ca_vrfy == NULL)
- fatalx("lka:ca_vrfy: verify without a certificate");
- lka_certificate_verify(imsg->hdr.type, req_ca_vrfy);
- req_ca_vrfy = NULL;
- return;
-
case IMSG_SMTP_AUTHENTICATE:
m_msg(&m, imsg);
m_get_id(&m, &reqid);
@@ -304,7 +238,7 @@ lka_imsg(struct mproc *p, struct imsg *imsg)
m_add_int(p, LKA_TEMPFAIL);
}
else {
- ret = table_fetch(table, NULL, K_SOURCE, &lk);
+ ret = table_fetch(table, K_SOURCE, &lk);
if (ret == -1)
m_add_int(p, LKA_TEMPFAIL);
else if (ret == 0)
@@ -352,7 +286,7 @@ lka_imsg(struct mproc *p, struct imsg *imsg)
m_add_int(p, LKA_TEMPFAIL);
}
else {
- ret = table_fetch(table, NULL, K_RELAYHOST, &lk);
+ ret = table_fetch(table, K_RELAYHOST, &lk);
if (ret == -1)
m_add_int(p, LKA_TEMPFAIL);
else if (ret == 0)
@@ -759,7 +693,7 @@ lka_authenticate(const char *tablename, const char *user, const char *password)
return (LKA_TEMPFAIL);
}
- switch (table_lookup(table, NULL, user, K_CREDENTIALS, &lk)) {
+ switch (table_lookup(table, K_CREDENTIALS, user, &lk)) {
case -1:
log_warnx("warn: user credentials lookup fail for %s:%s",
tablename, user);
@@ -789,7 +723,7 @@ lka_credentials(const char *tablename, const char *label, char *dst, size_t sz)
dst[0] = '\0';
- switch (table_lookup(table, NULL, label, K_CREDENTIALS, &lk)) {
+ switch (table_lookup(table, K_CREDENTIALS, label, &lk)) {
case -1:
log_warnx("warn: credentials lookup fail for %s:%s",
tablename, label);
@@ -830,7 +764,7 @@ lka_userinfo(const char *tablename, const char *username, struct userinfo *res)
return (LKA_TEMPFAIL);
}
- switch (table_lookup(table, NULL, username, K_USERINFO, &lk)) {
+ switch (table_lookup(table, K_USERINFO, username, &lk)) {
case -1:
log_warnx("warn: failure during userinfo lookup %s:%s",
tablename, username);
@@ -860,7 +794,7 @@ lka_addrname(const char *tablename, const struct sockaddr *sa,
return (LKA_TEMPFAIL);
}
- switch (table_lookup(table, NULL, source, K_ADDRNAME, &lk)) {
+ switch (table_lookup(table, K_ADDRNAME, source, &lk)) {
case -1:
log_warnx("warn: failure during helo lookup %s:%s",
tablename, source);
@@ -888,7 +822,7 @@ lka_mailaddrmap(const char *tablename, const char *username, const struct mailad
return (LKA_TEMPFAIL);
}
- switch (table_lookup(table, NULL, username, K_MAILADDRMAP, &lk)) {
+ switch (table_lookup(table, K_MAILADDRMAP, username, &lk)) {
case -1:
log_warnx("warn: failure during mailaddrmap lookup %s:%s",
tablename, username);
@@ -910,88 +844,3 @@ lka_mailaddrmap(const char *tablename, const char *username, const struct mailad
}
return (LKA_OK);
}
-
-static int
-lka_X509_verify(struct ca_vrfy_req_msg *vrfy,
- const char *CAfile, const char *CRLfile)
-{
- X509 *x509;
- X509 *x509_tmp;
- STACK_OF(X509) *x509_chain;
- const unsigned char *d2i;
- size_t i;
- int ret = 0;
- const char *errstr;
-
- x509 = NULL;
- x509_tmp = NULL;
- x509_chain = NULL;
-
- d2i = vrfy->cert;
- if (d2i_X509(&x509, &d2i, vrfy->cert_len) == NULL) {
- x509 = NULL;
- goto end;
- }
-
- if (vrfy->n_chain) {
- x509_chain = sk_X509_new_null();
- for (i = 0; i < vrfy->n_chain; ++i) {
- d2i = vrfy->chain_cert[i];
- if (d2i_X509(&x509_tmp, &d2i, vrfy->chain_cert_len[i]) == NULL)
- goto end;
- sk_X509_insert(x509_chain, x509_tmp, i);
- x509_tmp = NULL;
- }
- }
- if (!ca_X509_verify(x509, x509_chain, CAfile, NULL, &errstr))
- log_debug("debug: lka: X509 verify: %s", errstr);
- else
- ret = 1;
-
-end:
- X509_free(x509);
- X509_free(x509_tmp);
- if (x509_chain)
- sk_X509_pop_free(x509_chain, X509_free);
-
- return ret;
-}
-
-static void
-lka_certificate_verify(enum imsg_type type, struct ca_vrfy_req_msg *req)
-{
- lka_certificate_verify_resume(type, req);
-}
-
-static void
-lka_certificate_verify_resume(enum imsg_type type, struct ca_vrfy_req_msg *req)
-{
- struct ca_vrfy_resp_msg resp;
- struct ca *sca;
- const char *cafile;
- size_t i;
-
- resp.reqid = req->reqid;
- sca = dict_get(env->sc_ca_dict, req->name);
- if (sca == NULL)
- if (req->fallback)
- sca = dict_get(env->sc_ca_dict, "*");
- cafile = sca ? sca->ca_cert_file : CA_FILE;
-
- if (sca == NULL && !req->fallback)
- resp.status = CA_FAIL;
- else if (!lka_X509_verify(req, cafile, NULL))
- resp.status = CA_FAIL;
- else
- resp.status = CA_OK;
-
- m_compose(p_pony, type, 0, 0, -1, &resp,
- sizeof resp);
-
- for (i = 0; i < req->n_chain; ++i)
- free(req->chain_cert[i]);
- free(req->chain_cert);
- free(req->chain_cert_len);
- free(req->cert);
- free(req);
-}
diff --git a/smtpd/lka_filter.c b/smtpd/lka_filter.c
index d6916e86..4135de19 100644
--- a/smtpd/lka_filter.c
+++ b/smtpd/lka_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka_filter.c,v 1.28 2018/12/22 13:09:05 gilles Exp $ */
+/* $OpenBSD: lka_filter.c,v 1.33 2018/12/26 15:55:09 eric Exp $ */
/*
* Copyright (c) 2018 Gilles Chehade <gilles@poolp.org>
@@ -140,6 +140,7 @@ lka_filter_init(void)
struct filter *filter;
struct filter_config *filter_config;
size_t i;
+ char buffer[LINE_MAX]; /* for traces */
dict_init(&filters);
dict_init(&filter_chains);
@@ -154,6 +155,8 @@ lka_filter_init(void)
filter->phases |= (1<<filter_config->phase);
filter->config = filter_config;
dict_set(&filters, name, filter);
+ log_trace(TRACE_FILTERS, "filters init type=builtin, name=%s, hooks=%08x",
+ name, filter->phases);
break;
case FILTER_TYPE_PROC:
@@ -162,6 +165,8 @@ lka_filter_init(void)
filter->proc = filter_config->proc;
filter->config = filter_config;
dict_set(&filters, name, filter);
+ log_trace(TRACE_FILTERS, "filters init type=proc, name=%s, proc=%s",
+ name, filter_config->proc);
break;
case FILTER_TYPE_CHAIN:
@@ -179,8 +184,16 @@ lka_filter_init(void)
filter->chain = xcalloc(filter_config->chain_size, sizeof(void **));
filter->chain_size = filter_config->chain_size;
filter->config = filter_config;
- for (i = 0; i < filter->chain_size; ++i)
+
+ buffer[0] = '\0';
+ for (i = 0; i < filter->chain_size; ++i) {
filter->chain[i] = dict_xget(&filters, filter_config->chain[i]);
+ if (i)
+ (void)strlcat(buffer, ", ", sizeof buffer);
+ (void)strlcat(buffer, filter->chain[i]->name, sizeof buffer);
+ }
+ log_trace(TRACE_FILTERS, "filters init type=chain, name=%s { %s }", name, buffer);
+
dict_set(&filters, name, filter);
break;
@@ -315,6 +328,8 @@ lka_filter_begin(uint64_t reqid,
fs->rdns = xstrdup(rdns);
fs->fcrdns = fcrdns;
tree_xset(&sessions, fs->id, fs);
+
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters session-begin", reqid);
}
void
@@ -325,6 +340,7 @@ lka_filter_end(uint64_t reqid)
fs = tree_xpop(&sessions, reqid);
free(fs->rdns);
free(fs);
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters session-end", reqid);
}
void
@@ -350,6 +366,7 @@ end:
m_add_id(p_pony, reqid);
m_add_int(p_pony, fd != -1 ? 1 : 0);
m_close(p_pony);
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters data-begin fd=%d", reqid, fd);
}
void
@@ -362,6 +379,7 @@ lka_filter_data_end(uint64_t reqid)
io_free(fs->io);
fs->io = NULL;
}
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters data-end", reqid);
}
static void
@@ -497,9 +515,13 @@ filter_protocol_internal(struct filter_session *fs, uint64_t *token, uint64_t re
struct filter_chain *filter_chain;
struct filter_entry *filter_entry;
struct filter *filter;
+ const char *phase_name = filter_execs[phase].phase_name;
+ int resume = 1;
- if (!*token)
+ if (!*token) {
fs->phase = phase;
+ resume = 0;
+ }
/* XXX - this sanity check requires a protocol change, stub for now */
phase = fs->phase;
@@ -520,6 +542,9 @@ filter_protocol_internal(struct filter_session *fs, uint64_t *token, uint64_t re
/* no filter_entry, we either had none or reached end of chain */
if (filter_entry == NULL) {
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters protocol phase=%s, resume=%s, "
+ "action=proceed",
+ fs->id, phase_name, resume ? "y" : "n");
filter_result_proceed(reqid);
return;
}
@@ -528,6 +553,10 @@ filter_protocol_internal(struct filter_session *fs, uint64_t *token, uint64_t re
*token = filter_entry->id;
filter = dict_get(&filters, filter_entry->name);
if (filter->proc) {
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters protocol phase=%s, "
+ "resume=%s, action=deferred, filter=%s",
+ fs->id, phase_name, resume ? "y" : "n",
+ filter->name);
filter_protocol_query(filter, filter_entry->id, reqid,
filter_execs[fs->phase].phase_name, param);
return; /* deferred response */
@@ -535,19 +564,43 @@ filter_protocol_internal(struct filter_session *fs, uint64_t *token, uint64_t re
if (filter_execs[fs->phase].func(fs, filter, reqid, param)) {
if (filter->config->rewrite) {
- filter_result_rewrite(reqid, filter->config->rewrite);
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters protocol phase=%s, "
+ "resume=%s, action=rewrite, filter=%s, query=%s, response=%s",
+ fs->id, phase_name, resume ? "y" : "n",
+ filter->name,
+ param,
+ filter->config->rewrite);
+ filter_result_rewrite(reqid, filter->config->rewrite);
return;
}
else if (filter->config->disconnect) {
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters protocol phase=%s, "
+ "resume=%s, action=disconnect, filter=%s, query=%s, response=%s",
+ fs->id, phase_name, resume ? "y" : "n",
+ filter->name,
+ param,
+ filter->config->disconnect);
filter_result_disconnect(reqid, filter->config->disconnect);
return;
}
else {
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters protocol phase=%s, "
+ "resume=%s, action=reject, filter=%s, query=%s, response=%s",
+ fs->id, phase_name, resume ? "y" : "n",
+ filter->name,
+ param,
+ filter->config->reject);
filter_result_reject(reqid, filter->config->reject);
return;
}
}
+ log_trace(TRACE_FILTERS, "%016"PRIx64" filters protocol phase=%s, "
+ "resume=%s, action=proceed, filter=%s, query=%s",
+ fs->id, phase_name, resume ? "y" : "n",
+ filter->name,
+ param);
+
/* filter_entry resulted in proceed, try next filter */
filter_protocol_internal(fs, token, reqid, phase, param);
return;
@@ -593,7 +646,8 @@ filter_protocol(uint64_t reqid, enum filter_phase phase, const char *param)
{
struct filter_session *fs;
uint64_t token = 0;
-
+ char *nparam = NULL;
+
fs = tree_xget(&sessions, reqid);
switch (phase) {
@@ -609,8 +663,14 @@ filter_protocol(uint64_t reqid, enum filter_phase phase, const char *param)
fs->mail_from = xstrdup(param + 1);
*strchr(fs->mail_from, '>') = '\0';
+ param = fs->mail_from;
break;
+ case FILTER_RCPT_TO:
+ nparam = xstrdup(param + 1);
+ *strchr(nparam, '>') = '\0';
+ param = nparam;
+ break;
case FILTER_STARTTLS:
case FILTER_AUTH:
/* TBD */
@@ -619,6 +679,8 @@ filter_protocol(uint64_t reqid, enum filter_phase phase, const char *param)
break;
}
filter_protocol_internal(fs, &token, reqid, phase, param);
+ if (nparam)
+ free(nparam);
}
static void
@@ -743,12 +805,13 @@ filter_check_rdns_table(struct filter *filter, enum table_service kind, const ch
{
int ret = 0;
- if (filter->config->rdns_table) {
- if (table_lookup(filter->config->rdns_table, NULL, key, kind, NULL) > 0)
- ret = 1;
- ret = filter->config->not_rdns_table < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->rdns_table == NULL)
+ return 0;
+
+ if (table_match(filter->config->rdns_table, kind, key) > 0)
+ ret = 1;
+
+ return filter->config->not_rdns_table < 0 ? !ret : ret;
}
static int
@@ -756,12 +819,12 @@ filter_check_rdns_regex(struct filter *filter, const char *key)
{
int ret = 0;
- if (filter->config->rdns_regex) {
- if (table_lookup(filter->config->rdns_regex, NULL, key, K_REGEX, NULL) > 0)
- ret = 1;
- ret = filter->config->not_rdns_regex < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->rdns_regex == NULL)
+ return 0;
+
+ if (table_match(filter->config->rdns_regex, K_REGEX, key) > 0)
+ ret = 1;
+ return filter->config->not_rdns_regex < 0 ? !ret : ret;
}
static int
@@ -769,12 +832,12 @@ filter_check_src_table(struct filter *filter, enum table_service kind, const cha
{
int ret = 0;
- if (filter->config->src_table) {
- if (table_lookup(filter->config->src_table, NULL, key, kind, NULL) > 0)
- ret = 1;
- ret = filter->config->not_src_table < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->src_table == NULL)
+ return 0;
+
+ if (table_match(filter->config->src_table, kind, key) > 0)
+ ret = 1;
+ return filter->config->not_src_table < 0 ? !ret : ret;
}
static int
@@ -782,12 +845,12 @@ filter_check_src_regex(struct filter *filter, const char *key)
{
int ret = 0;
- if (filter->config->src_regex) {
- if (table_lookup(filter->config->src_regex, NULL, key, K_REGEX, NULL) > 0)
- ret = 1;
- ret = filter->config->not_src_regex < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->src_regex == NULL)
+ return 0;
+
+ if (table_match(filter->config->src_regex, K_REGEX, key) > 0)
+ ret = 1;
+ return filter->config->not_src_regex < 0 ? !ret : ret;
}
static int
@@ -795,12 +858,12 @@ filter_check_helo_table(struct filter *filter, enum table_service kind, const ch
{
int ret = 0;
- if (filter->config->helo_table) {
- if (table_lookup(filter->config->helo_table, NULL, key, kind, NULL) > 0)
- ret = 1;
- ret = filter->config->not_helo_table < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->helo_table == NULL)
+ return 0;
+
+ if (table_match(filter->config->helo_table, kind, key) > 0)
+ ret = 1;
+ return filter->config->not_helo_table < 0 ? !ret : ret;
}
static int
@@ -808,12 +871,12 @@ filter_check_helo_regex(struct filter *filter, const char *key)
{
int ret = 0;
- if (filter->config->helo_regex) {
- if (table_lookup(filter->config->helo_regex, NULL, key, K_REGEX, NULL) > 0)
- ret = 1;
- ret = filter->config->not_helo_regex < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->helo_regex == NULL)
+ return 0;
+
+ if (table_match(filter->config->helo_regex, K_REGEX, key) > 0)
+ ret = 1;
+ return filter->config->not_helo_regex < 0 ? !ret : ret;
}
static int
@@ -821,12 +884,12 @@ filter_check_mail_from_table(struct filter *filter, enum table_service kind, con
{
int ret = 0;
- if (filter->config->mail_from_table) {
- if (table_lookup(filter->config->mail_from_table, NULL, key, kind, NULL) > 0)
- ret = 1;
- ret = filter->config->not_mail_from_table < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->mail_from_table == NULL)
+ return 0;
+
+ if (table_match(filter->config->mail_from_table, kind, key) > 0)
+ ret = 1;
+ return filter->config->not_mail_from_table < 0 ? !ret : ret;
}
static int
@@ -834,12 +897,12 @@ filter_check_mail_from_regex(struct filter *filter, const char *key)
{
int ret = 0;
- if (filter->config->mail_from_regex) {
- if (table_lookup(filter->config->mail_from_regex, NULL, key, K_REGEX, NULL) > 0)
- ret = 1;
- ret = filter->config->not_mail_from_regex < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->mail_from_regex == NULL)
+ return 0;
+
+ if (table_match(filter->config->mail_from_regex, K_REGEX, key) > 0)
+ ret = 1;
+ return filter->config->not_mail_from_regex < 0 ? !ret : ret;
}
static int
@@ -847,12 +910,12 @@ filter_check_rcpt_to_table(struct filter *filter, enum table_service kind, const
{
int ret = 0;
- if (filter->config->rcpt_to_table) {
- if (table_lookup(filter->config->rcpt_to_table, NULL, key, kind, NULL) > 0)
- ret = 1;
- ret = filter->config->not_rcpt_to_table < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->rcpt_to_table == NULL)
+ return 0;
+
+ if (table_match(filter->config->rcpt_to_table, kind, key) > 0)
+ ret = 1;
+ return filter->config->not_rcpt_to_table < 0 ? !ret : ret;
}
static int
@@ -860,12 +923,12 @@ filter_check_rcpt_to_regex(struct filter *filter, const char *key)
{
int ret = 0;
- if (filter->config->rcpt_to_regex) {
- if (table_lookup(filter->config->rcpt_to_regex, NULL, key, K_REGEX, NULL) > 0)
- ret = 1;
- ret = filter->config->not_rcpt_to_regex < 0 ? !ret : ret;
- }
- return ret;
+ if (filter->config->rcpt_to_regex == NULL)
+ return 0;
+
+ if (table_match(filter->config->rcpt_to_regex, K_REGEX, key) > 0)
+ ret = 1;
+ return filter->config->not_rcpt_to_regex < 0 ? !ret : ret;
}
static int
@@ -873,11 +936,11 @@ filter_check_fcrdns(struct filter *filter, int fcrdns)
{
int ret = 0;
- if (filter->config->fcrdns) {
- ret = fcrdns == 0;
- ret = filter->config->not_fcrdns < 0 ? !ret : ret;
- }
- return ret;
+ if (!filter->config->fcrdns)
+ return 0;
+
+ ret = fcrdns == 0;
+ return filter->config->not_fcrdns < 0 ? !ret : ret;
}
static int
@@ -886,14 +949,14 @@ filter_check_rdns(struct filter *filter, const char *hostname)
int ret = 0;
struct netaddr netaddr;
- if (filter->config->rdns) {
- /* if text_to_netaddress succeeds,
- * we don't have an rDNS so the filter should match
- */
- ret = text_to_netaddr(&netaddr, hostname);
- ret = filter->config->not_rdns < 0 ? !ret : ret;
- }
- return ret;
+ if (!filter->config->rdns)
+ return 0;
+
+ /* if text_to_netaddress succeeds,
+ * we don't have an rDNS so the filter should match
+ */
+ ret = text_to_netaddr(&netaddr, hostname);
+ return filter->config->not_rdns < 0 ? !ret : ret;
}
static int
@@ -903,9 +966,9 @@ filter_builtins_notimpl(struct filter_session *fs, struct filter *filter, uint64
}
static int
-filter_builtins_global(struct filter_session *fs, struct filter *filter, uint64_t reqid, const char *param)
+filter_builtins_global(struct filter_session *fs, struct filter *filter, uint64_t reqid)
{
- if (filter_check_fcrdns(filter, fs->fcrdns) ||
+ return filter_check_fcrdns(filter, fs->fcrdns) ||
filter_check_rdns(filter, fs->rdns) ||
filter_check_rdns_table(filter, K_DOMAIN, fs->rdns) ||
filter_check_rdns_regex(filter, fs->rdns) ||
@@ -914,43 +977,31 @@ filter_builtins_global(struct filter_session *fs, struct filter *filter, uint64_
filter_check_helo_table(filter, K_DOMAIN, fs->helo) ||
filter_check_helo_regex(filter, fs->helo) ||
filter_check_mail_from_table(filter, K_MAILADDR, fs->mail_from) ||
- filter_check_mail_from_regex(filter, fs->mail_from))
- return 1;
- return 0;
+ filter_check_mail_from_regex(filter, fs->mail_from);
}
static int
filter_builtins_connect(struct filter_session *fs, struct filter *filter, uint64_t reqid, const char *param)
{
- return filter_builtins_global(fs, filter, reqid, param);
+ return filter_builtins_global(fs, filter, reqid);
}
static int
filter_builtins_helo(struct filter_session *fs, struct filter *filter, uint64_t reqid, const char *param)
{
- return filter_builtins_global(fs, filter, reqid, param);
+ return filter_builtins_global(fs, filter, reqid);
}
static int
filter_builtins_mail_from(struct filter_session *fs, struct filter *filter, uint64_t reqid, const char *param)
{
- return filter_builtins_global(fs, filter, reqid, param);
+ return filter_builtins_global(fs, filter, reqid);
}
static int
filter_builtins_rcpt_to(struct filter_session *fs, struct filter *filter, uint64_t reqid, const char *param)
{
- int ret = 0;
- char *rcpt_to;
-
- rcpt_to = xstrdup(param + 1);
- *strchr(rcpt_to, '>') = '\0';
-
- if (filter_builtins_global(fs, filter, reqid, param) ||
- filter_check_rcpt_to_table(filter, K_MAILADDR, rcpt_to) ||
- filter_check_rcpt_to_regex(filter, rcpt_to))
- ret = 1;
-
- free(rcpt_to);
- return ret;
+ return filter_builtins_global(fs, filter, reqid) ||
+ filter_check_rcpt_to_table(filter, K_MAILADDR, param) ||
+ filter_check_rcpt_to_regex(filter, param);
}
diff --git a/smtpd/lka_session.c b/smtpd/lka_session.c
index bca6ad31..0ab78368 100644
--- a/smtpd/lka_session.c
+++ b/smtpd/lka_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka_session.c,v 1.88 2018/11/01 18:01:51 gilles Exp $ */
+/* $OpenBSD: lka_session.c,v 1.90 2018/12/26 20:13:43 eric Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
@@ -379,7 +379,7 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn)
*tag++ = '\0';
userbase = table_find(env, dsp->u.local.table_userbase, NULL);
- r = table_lookup(userbase, NULL, xn->u.user, K_USERINFO, &lk);
+ r = table_lookup(userbase, K_USERINFO, xn->u.user, &lk);
if (r == -1) {
log_trace(TRACE_EXPAND, "expand: lka_expand: "
"backend error while searching user");
diff --git a/smtpd/mta.c b/smtpd/mta.c
index a1e0c030..ec1be548 100644
--- a/smtpd/mta.c
+++ b/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.226 2018/09/24 16:14:34 eric Exp $ */
+/* $OpenBSD: mta.c,v 1.227 2018/12/23 16:37:53 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -315,14 +315,6 @@ mta_imsg(struct mproc *p, struct imsg *imsg)
mta_on_preference(relay, preference);
return;
- case IMSG_MTA_TLS_INIT:
- mta_session_imsg(p, imsg);
- return;
-
- case IMSG_MTA_TLS_VERIFY:
- mta_session_imsg(p, imsg);
- return;
-
case IMSG_CTL_RESUME_ROUTE:
u64 = *((uint64_t *)imsg->data);
if (u64)
diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c
index 655c205f..628b0ed1 100644
--- a/smtpd/mta_session.c
+++ b/smtpd/mta_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta_session.c,v 1.114 2018/12/17 11:14:56 eric Exp $ */
+/* $OpenBSD: mta_session.c,v 1.115 2018/12/23 16:37:53 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -150,8 +150,6 @@ static void mta_send(struct mta_session *, char *, ...);
static ssize_t mta_queue_data(struct mta_session *);
static void mta_response(struct mta_session *, char *);
static const char * mta_strstate(int);
-static void mta_start_tls(struct mta_session *);
-static int mta_verify_certificate(struct mta_session *);
static void mta_cert_init(struct mta_session *);
static void mta_cert_init_cb(void *, int, const char *, const void *, size_t);
static void mta_cert_verify(struct mta_session *);
@@ -244,13 +242,10 @@ mta_session(struct mta_relay *relay, struct mta_route *route)
void
mta_session_imsg(struct mproc *p, struct imsg *imsg)
{
- struct ca_vrfy_resp_msg *resp_ca_vrfy;
- struct ca_cert_resp_msg *resp_ca_cert;
struct mta_session *s;
struct msg m;
uint64_t reqid;
const char *name;
- void *ssl;
int status;
struct stat sb;
@@ -302,61 +297,6 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
mta_enter_state(s, MTA_MAIL);
return;
- case IMSG_MTA_TLS_INIT:
- resp_ca_cert = imsg->data;
- s = mta_tree_pop(&wait_ssl_init, resp_ca_cert->reqid);
- if (s == NULL)
- return;
-
- if (resp_ca_cert->status == CA_FAIL) {
- if (s->relay->pki_name) {
- log_info("%016"PRIx64" mta "
- "closing reason=ca-failure",
- s->id);
- mta_free(s);
- return;
- }
- else {
- ssl = ssl_mta_init(NULL, NULL, 0, env->sc_tls_ciphers);
- if (ssl == NULL)
- fatal("mta: ssl_mta_init");
- io_start_tls(s->io, ssl);
- return;
- }
- }
-
- resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert);
- resp_ca_cert->cert = xstrdup((char *)imsg->data +
- sizeof *resp_ca_cert);
- ssl = ssl_mta_init(resp_ca_cert->name,
- resp_ca_cert->cert, resp_ca_cert->cert_len, env->sc_tls_ciphers);
- if (ssl == NULL)
- fatal("mta: ssl_mta_init");
- io_start_tls(s->io, ssl);
-
- freezero(resp_ca_cert->cert, resp_ca_cert->cert_len);
- free(resp_ca_cert);
- return;
-
- case IMSG_MTA_TLS_VERIFY:
- resp_ca_vrfy = imsg->data;
- s = mta_tree_pop(&wait_ssl_verify, resp_ca_vrfy->reqid);
- if (s == NULL)
- return;
-
- if (resp_ca_vrfy->status == CA_OK)
- s->flags |= MTA_TLS_VERIFIED;
- else if (s->relay->flags & RELAY_TLS_VERIFY) {
- errno = 0;
- mta_error(s, "SSL certificate check failed");
- mta_free(s);
- return;
- }
-
- mta_tls_verified(s);
- io_resume(s->io, IO_IN);
- return;
-
case IMSG_MTA_LOOKUP_HELO:
m_msg(&m, imsg);
m_get_id(&m, &reqid);
@@ -1510,153 +1450,6 @@ mta_error(struct mta_session *s, const char *fmt, ...)
}
static void
-mta_start_tls(struct mta_session *s)
-{
- struct ca_cert_req_msg req_ca_cert;
- const char *certname;
-
- if (s->relay->pki_name) {
- certname = s->relay->pki_name;
- req_ca_cert.fallback = 0;
- }
- else {
- certname = s->helo;
- req_ca_cert.fallback = 1;
- }
-
- req_ca_cert.reqid = s->id;
- (void)strlcpy(req_ca_cert.name, certname, sizeof req_ca_cert.name);
- m_compose(p_lka, IMSG_MTA_TLS_INIT, 0, 0, -1,
- &req_ca_cert, sizeof(req_ca_cert));
- tree_xset(&wait_ssl_init, s->id, s);
- s->flags |= MTA_WAIT;
- return;
-}
-
-static int
-mta_verify_certificate(struct mta_session *s)
-{
-#define MAX_CERTS 16
-#define MAX_CERT_LEN (MAX_IMSGSIZE - (IMSG_HEADER_SIZE + sizeof(req_ca_vrfy)))
- struct ca_vrfy_req_msg req_ca_vrfy;
- struct iovec iov[2];
- X509 *x;
- STACK_OF(X509) *xchain;
- const char *name;
- unsigned char *cert_der[MAX_CERTS];
- int cert_len[MAX_CERTS];
- int i, cert_count, res;
-
- res = 0;
- memset(cert_der, 0, sizeof(cert_der));
- memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
-
- /* Send the client certificate */
- if (s->relay->ca_name) {
- name = s->relay->ca_name;
- req_ca_vrfy.fallback = 0;
- }
- else {
- name = s->helo;
- req_ca_vrfy.fallback = 1;
- }
- if (strlcpy(req_ca_vrfy.name, name, sizeof req_ca_vrfy.name)
- >= sizeof req_ca_vrfy.name)
- return 0;
-
- x = SSL_get_peer_certificate(io_ssl(s->io));
- if (x == NULL)
- return 0;
- xchain = SSL_get_peer_cert_chain(io_ssl(s->io));
-
- /*
- * Client provided a certificate and possibly a certificate chain.
- * SMTP can't verify because it does not have the information that
- * it needs, instead it will pass the certificate and chain to the
- * lookup process and wait for a reply.
- *
- */
-
- cert_len[0] = i2d_X509(x, &cert_der[0]);
- X509_free(x);
-
- if (cert_len[0] < 0) {
- log_warnx("warn: failed to encode certificate");
- goto end;
- }
- log_debug("debug: certificate 0: len=%d", cert_len[0]);
- if (cert_len[0] > (int)MAX_CERT_LEN) {
- log_warnx("warn: certificate too long");
- goto end;
- }
-
- if (xchain) {
- cert_count = sk_X509_num(xchain);
- log_debug("debug: certificate chain len: %d", cert_count);
- if (cert_count >= MAX_CERTS) {
- log_warnx("warn: certificate chain too long");
- goto end;
- }
- }
- else
- cert_count = 0;
-
- for (i = 0; i < cert_count; ++i) {
- x = sk_X509_value(xchain, i);
- cert_len[i+1] = i2d_X509(x, &cert_der[i+1]);
- if (cert_len[i+1] < 0) {
- log_warnx("warn: failed to encode certificate");
- goto end;
- }
- log_debug("debug: certificate %i: len=%d", i+1, cert_len[i+1]);
- if (cert_len[i+1] > (int)MAX_CERT_LEN) {
- log_warnx("warn: certificate too long");
- goto end;
- }
- }
-
- tree_xset(&wait_ssl_verify, s->id, s);
- s->flags |= MTA_WAIT;
-
- /* Send the client certificate */
- req_ca_vrfy.reqid = s->id;
- req_ca_vrfy.cert_len = cert_len[0];
- req_ca_vrfy.n_chain = cert_count;
- iov[0].iov_base = &req_ca_vrfy;
- iov[0].iov_len = sizeof(req_ca_vrfy);
- iov[1].iov_base = cert_der[0];
- iov[1].iov_len = cert_len[0];
- m_composev(p_lka, IMSG_MTA_TLS_VERIFY_CERT, 0, 0, -1,
- iov, nitems(iov));
-
- memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
- req_ca_vrfy.reqid = s->id;
-
- /* Send the chain, one cert at a time */
- for (i = 0; i < cert_count; ++i) {
- req_ca_vrfy.cert_len = cert_len[i+1];
- iov[1].iov_base = cert_der[i+1];
- iov[1].iov_len = cert_len[i+1];
- m_composev(p_lka, IMSG_MTA_TLS_VERIFY_CHAIN, 0, 0, -1,
- iov, nitems(iov));
- }
-
- /* Tell lookup process that it can start verifying, we're done */
- memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
- req_ca_vrfy.reqid = s->id;
- m_compose(p_lka, IMSG_MTA_TLS_VERIFY, 0, 0, -1,
- &req_ca_vrfy, sizeof req_ca_vrfy);
-
- res = 1;
-
- end:
- for (i = 0; i < MAX_CERTS; ++i)
- free(cert_der[i]);
-
- return res;
-}
-
-static void
mta_cert_init(struct mta_session *s)
{
const char *name;
diff --git a/smtpd/parse.y b/smtpd/parse.y
index 539faf6d..7424cd3c 100644
--- a/smtpd/parse.y
+++ b/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.246 2018/12/22 13:09:05 gilles Exp $ */
+/* $OpenBSD: parse.y,v 1.248 2018/12/23 15:49:04 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -113,7 +113,8 @@ struct dispatcher *dispatcher;
struct rule *rule;
struct processor *processor;
struct filter_config *filter_config;
-static uint64_t last_dynproc_id = 1;
+static uint32_t last_dynchain_id = 1;
+static uint32_t last_dynproc_id = 1;
enum listen_options {
LO_FAMILY = 0x000001,
@@ -1597,7 +1598,7 @@ FILTER STRING PROC_EXEC STRING {
char buffer[128];
do {
- (void)snprintf(buffer, sizeof buffer, "<dynproc:%016"PRIx64">", last_dynproc_id++);
+ (void)snprintf(buffer, sizeof buffer, "<dynproc:%08x>", last_dynproc_id++);
} while (dict_check(conf->sc_processors_dict, buffer));
if (dict_get(conf->sc_filters_dict, $2)) {
@@ -1804,6 +1805,27 @@ opt_sock_listen : FILTER STRING {
listen_opts.options |= LO_FILTER;
listen_opts.filtername = $2;
}
+ | FILTER {
+ char buffer[128];
+
+ if (listen_opts.options & LO_FILTER) {
+ yyerror("filter already specified");
+ YYERROR;
+ }
+
+ do {
+ (void)snprintf(buffer, sizeof buffer, "<dynchain:%08x>", last_dynchain_id++);
+ } while (dict_check(conf->sc_filters_dict, buffer));
+
+ listen_opts.options |= LO_FILTER;
+ listen_opts.filtername = xstrdup(buffer);
+ filter_config = xcalloc(1, sizeof *filter_config);
+ filter_config->filter_type = FILTER_TYPE_CHAIN;
+ dict_init(&filter_config->chain_procs);
+ } '{' filter_list '}' {
+ dict_set(conf->sc_filters_dict, listen_opts.filtername, filter_config);
+ filter_config = NULL;
+ }
| MASK_SRC {
if (config_lo_mask_source(&listen_opts)) {
YYERROR;
@@ -1871,6 +1893,27 @@ opt_if_listen : INET4 {
listen_opts.options |= LO_FILTER;
listen_opts.filtername = $2;
}
+ | FILTER {
+ char buffer[128];
+
+ if (listen_opts.options & LO_FILTER) {
+ yyerror("filter already specified");
+ YYERROR;
+ }
+
+ do {
+ (void)snprintf(buffer, sizeof buffer, "<dynchain:%08x>", last_dynchain_id++);
+ } while (dict_check(conf->sc_filters_dict, buffer));
+
+ listen_opts.options |= LO_FILTER;
+ listen_opts.filtername = xstrdup(buffer);
+ filter_config = xcalloc(1, sizeof *filter_config);
+ filter_config->filter_type = FILTER_TYPE_CHAIN;
+ dict_init(&filter_config->chain_procs);
+ } '{' filter_list '}' {
+ dict_set(conf->sc_filters_dict, listen_opts.filtername, filter_config);
+ filter_config = NULL;
+ }
| SMTPS {
if (listen_opts.options & LO_SSL) {
yyerror("TLS mode already specified");
diff --git a/smtpd/pony.c b/smtpd/pony.c
index 75742fa7..238f0244 100644
--- a/smtpd/pony.c
+++ b/smtpd/pony.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pony.c,v 1.25 2018/12/11 13:40:30 gilles Exp $ */
+/* $OpenBSD: pony.c,v 1.26 2018/12/23 16:37:53 eric Exp $ */
/*
* Copyright (c) 2014 Gilles Chehade <gilles@poolp.org>
@@ -93,8 +93,6 @@ pony_imsg(struct mproc *p, struct imsg *imsg)
case IMSG_SMTP_EXPAND_RCPT:
case IMSG_SMTP_LOOKUP_HELO:
case IMSG_SMTP_AUTHENTICATE:
- case IMSG_SMTP_TLS_INIT:
- case IMSG_SMTP_TLS_VERIFY:
case IMSG_SMTP_MESSAGE_COMMIT:
case IMSG_SMTP_MESSAGE_CREATE:
case IMSG_SMTP_MESSAGE_OPEN:
@@ -119,8 +117,6 @@ pony_imsg(struct mproc *p, struct imsg *imsg)
case IMSG_MTA_DNS_HOST:
case IMSG_MTA_DNS_HOST_END:
case IMSG_MTA_DNS_MX_PREFERENCE:
- case IMSG_MTA_TLS_INIT:
- case IMSG_MTA_TLS_VERIFY:
case IMSG_CTL_RESUME_ROUTE:
case IMSG_CTL_MTA_SHOW_HOSTS:
case IMSG_CTL_MTA_SHOW_RELAYS:
diff --git a/smtpd/ruleset.c b/smtpd/ruleset.c
index 8fbeec01..715cc8d8 100644
--- a/smtpd/ruleset.c
+++ b/smtpd/ruleset.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ruleset.c,v 1.38 2018/12/22 08:54:02 gilles Exp $ */
+/* $OpenBSD: ruleset.c,v 1.41 2018/12/26 17:37:15 eric Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@poolp.org>
@@ -35,22 +35,7 @@
#include "smtpd.h"
#include "log.h"
-
-static int
-ruleset_match_table_lookup(struct table *table, const char *key, enum table_service service)
-{
- switch (table_lookup(table, NULL, key, service, NULL)) {
- case 1:
- return 1;
- case -1:
- log_warnx("warn: failure to perform a table lookup on table %s",
- table->t_name);
- return -1;
- default:
- break;
- }
- return 0;
-}
+#define MATCH_RESULT(r, neg) ((r) == -1 ? -1 : ((neg) < 0 ? !(r) : (r)))
static int
ruleset_match_tag(struct rule *r, const struct envelope *evp)
@@ -66,10 +51,9 @@ ruleset_match_tag(struct rule *r, const struct envelope *evp)
service = K_REGEX;
table = table_find(env, r->table_tag, NULL);
- if ((ret = ruleset_match_table_lookup(table, evp->tag, service)) < 0)
- return ret;
+ ret = table_match(table, service, evp->tag);
- return r->flag_tag < 0 ? !ret : ret;
+ return MATCH_RESULT(ret, r->flag_tag);
}
static int
@@ -102,10 +86,9 @@ ruleset_match_from(struct rule *r, const struct envelope *evp)
service = K_REGEX;
table = table_find(env, r->table_from, NULL);
- if ((ret = ruleset_match_table_lookup(table, key, service)) < 0)
- return -1;
+ ret = table_match(table, service, key);
- return r->flag_from < 0 ? !ret : ret;
+ return MATCH_RESULT(ret, r->flag_from);
}
static int
@@ -122,11 +105,9 @@ ruleset_match_to(struct rule *r, const struct envelope *evp)
service = K_REGEX;
table = table_find(env, r->table_for, NULL);
- if ((ret = ruleset_match_table_lookup(table, evp->dest.domain,
- service)) < 0)
- return -1;
+ ret = table_match(table, service, evp->dest.domain);
- return r->flag_for < 0 ? !ret : ret;
+ return MATCH_RESULT(ret, r->flag_for);
}
static int
@@ -143,10 +124,9 @@ ruleset_match_smtp_helo(struct rule *r, const struct envelope *evp)
service = K_REGEX;
table = table_find(env, r->table_smtp_helo, NULL);
- if ((ret = ruleset_match_table_lookup(table, evp->helo, service)) < 0)
- return -1;
+ ret = table_match(table, service, evp->helo);
- return r->flag_smtp_helo < 0 ? !ret : ret;
+ return MATCH_RESULT(ret, r->flag_smtp_helo);
}
static int
@@ -174,7 +154,7 @@ ruleset_match_smtp_auth(struct rule *r, const struct envelope *evp)
/*
* table = table_find(m->from_table, NULL);
* key = evp->username;
- * return ruleset_match_table_lookup(table, key, K_CREDENTIALS);
+ * return table_match(table, K_CREDENTIALS, key);
*/
return -1;
@@ -182,7 +162,7 @@ ruleset_match_smtp_auth(struct rule *r, const struct envelope *evp)
else
ret = 1;
- return r->flag_smtp_auth < 0 ? !ret : ret;
+ return MATCH_RESULT(ret, r->flag_smtp_auth);
}
static int
@@ -203,10 +183,9 @@ ruleset_match_smtp_mail_from(struct rule *r, const struct envelope *evp)
return -1;
table = table_find(env, r->table_smtp_mail_from, NULL);
- if ((ret = ruleset_match_table_lookup(table, key, service)) < 0)
- return -1;
+ ret = table_match(table, service, key);
- return r->flag_smtp_mail_from < 0 ? !ret : ret;
+ return MATCH_RESULT(ret, r->flag_smtp_mail_from);
}
static int
@@ -227,10 +206,9 @@ ruleset_match_smtp_rcpt_to(struct rule *r, const struct envelope *evp)
return -1;
table = table_find(env, r->table_smtp_rcpt_to, NULL);
- if ((ret = ruleset_match_table_lookup(table, key, service)) < 0)
- return -1;
+ ret = table_match(table, service, key);
- return r->flag_smtp_rcpt_to < 0 ? !ret : ret;
+ return MATCH_RESULT(ret, r->flag_smtp_rcpt_to);
}
struct rule *
diff --git a/smtpd/smtp.c b/smtpd/smtp.c
index fc8253f3..a0ab898b 100644
--- a/smtpd/smtp.c
+++ b/smtpd/smtp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.c,v 1.163 2018/12/11 13:40:30 gilles Exp $ */
+/* $OpenBSD: smtp.c,v 1.164 2018/12/23 16:37:53 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -71,8 +71,6 @@ smtp_imsg(struct mproc *p, struct imsg *imsg)
case IMSG_SMTP_EXPAND_RCPT:
case IMSG_SMTP_LOOKUP_HELO:
case IMSG_SMTP_AUTHENTICATE:
- case IMSG_SMTP_TLS_INIT:
- case IMSG_SMTP_TLS_VERIFY:
case IMSG_FILTER_SMTP_PROTOCOL:
case IMSG_FILTER_SMTP_DATA_BEGIN:
smtp_session_imsg(p, imsg);
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index a166d8c9..2a258a65 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.379 2018/12/21 14:41:41 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.381 2018/12/26 11:29:13 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -195,8 +195,6 @@ static void smtp_rfc4954_auth_plain(struct smtp_session *, char *);
static void smtp_rfc4954_auth_login(struct smtp_session *, char *);
static void smtp_free(struct smtp_session *, const char *);
static const char *smtp_strstate(int);
-static void smtp_tls_init(struct smtp_session *);
-static int smtp_verify_certificate(struct smtp_session *);
static void smtp_cert_init(struct smtp_session *);
static void smtp_cert_init_cb(void *, int, const char *, const void *, size_t);
static void smtp_cert_verify(struct smtp_session *);
@@ -690,18 +688,14 @@ smtp_getaddrinfo_cb(void *arg, int gaierrno, struct addrinfo *ai0)
void
smtp_session_imsg(struct mproc *p, struct imsg *imsg)
{
- struct ca_cert_resp_msg *resp_ca_cert;
- struct ca_vrfy_resp_msg *resp_ca_vrfy;
struct smtp_session *s;
struct smtp_rcpt *rcpt;
- void *ssl;
char user[LOGIN_NAME_MAX];
struct msg m;
const char *line, *helo;
uint64_t reqid, evpid;
uint32_t msgid;
int status, success;
- void *ssl_ctx;
int filter_response;
const char *filter_param;
uint8_t i;
@@ -962,47 +956,6 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
smtp_enter_state(s, STATE_HELO);
return;
- case IMSG_SMTP_TLS_INIT:
- resp_ca_cert = imsg->data;
- s = tree_xpop(&wait_ssl_init, resp_ca_cert->reqid);
-
- if (resp_ca_cert->status == CA_FAIL) {
- log_info("%016"PRIx64" smtp disconnected "
- "reason=ca-failure",
- s->id);
- smtp_free(s, "CA failure");
- return;
- }
-
- resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert);
- resp_ca_cert->cert = xstrdup((char *)imsg->data +
- sizeof *resp_ca_cert);
- ssl_ctx = dict_get(env->sc_ssl_dict, resp_ca_cert->name);
- ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY);
- io_set_read(s->io);
- io_start_tls(s->io, ssl);
-
- freezero(resp_ca_cert->cert, resp_ca_cert->cert_len);
- free(resp_ca_cert);
- return;
-
- case IMSG_SMTP_TLS_VERIFY:
- resp_ca_vrfy = imsg->data;
- s = tree_xpop(&wait_ssl_verify, resp_ca_vrfy->reqid);
-
- if (resp_ca_vrfy->status == CA_OK)
- s->flags |= SF_VERIFIED;
- else if (s->listener->flags & F_TLS_VERIFY) {
- log_info("%016"PRIx64" smtp "
- "disconnected reason=cert-check-failed",
- s->id);
- smtp_free(s, "SSL certificate check failed");
- return;
- }
- smtp_tls_verified(s);
- io_resume(s->io, IO_IN);
- return;
-
case IMSG_FILTER_SMTP_PROTOCOL:
m_msg(&m, imsg);
m_get_id(&m, &reqid);
@@ -2181,150 +2134,6 @@ smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
}
static void
-smtp_tls_init(struct smtp_session *s)
-{
- struct ca_cert_req_msg req_ca_cert;
-
- req_ca_cert.reqid = s->id;
- if (s->listener->pki_name[0]) {
- (void)strlcpy(req_ca_cert.name, s->listener->pki_name,
- sizeof req_ca_cert.name);
- req_ca_cert.fallback = 0;
- }
- else {
- (void)strlcpy(req_ca_cert.name, s->smtpname,
- sizeof req_ca_cert.name);
- req_ca_cert.fallback = 1;
- }
- m_compose(p_lka, IMSG_SMTP_TLS_INIT, 0, 0, -1,
- &req_ca_cert, sizeof(req_ca_cert));
- tree_xset(&wait_ssl_init, s->id, s);
-}
-
-static int
-smtp_verify_certificate(struct smtp_session *s)
-{
-#define MAX_CERTS 16
-#define MAX_CERT_LEN (MAX_IMSGSIZE - (IMSG_HEADER_SIZE + sizeof(req_ca_vrfy)))
- struct ca_vrfy_req_msg req_ca_vrfy;
- struct iovec iov[2];
- X509 *x;
- STACK_OF(X509) *xchain;
- const char *name;
- unsigned char *cert_der[MAX_CERTS];
- int cert_len[MAX_CERTS];
- int i, cert_count, res;
-
- res = 0;
- memset(cert_der, 0, sizeof(cert_der));
- memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
-
- /* Send the client certificate */
- if (s->listener->ca_name[0]) {
- name = s->listener->ca_name;
- req_ca_vrfy.fallback = 0;
- }
- else {
- name = s->smtpname;
- req_ca_vrfy.fallback = 1;
- }
-
- if (strlcpy(req_ca_vrfy.name, name, sizeof req_ca_vrfy.name)
- >= sizeof req_ca_vrfy.name)
- return 0;
-
- x = SSL_get_peer_certificate(io_ssl(s->io));
- if (x == NULL)
- return 0;
- xchain = SSL_get_peer_cert_chain(io_ssl(s->io));
-
- /*
- * Client provided a certificate and possibly a certificate chain.
- * SMTP can't verify because it does not have the information that
- * it needs, instead it will pass the certificate and chain to the
- * lookup process and wait for a reply.
- *
- */
-
- cert_len[0] = i2d_X509(x, &cert_der[0]);
- X509_free(x);
-
- if (cert_len[0] < 0) {
- log_warnx("warn: failed to encode certificate");
- goto end;
- }
- log_debug("debug: certificate 0: len=%d", cert_len[0]);
- if (cert_len[0] > (int)MAX_CERT_LEN) {
- log_warnx("warn: certificate too long");
- goto end;
- }
-
- if (xchain) {
- cert_count = sk_X509_num(xchain);
- log_debug("debug: certificate chain len: %d", cert_count);
- if (cert_count >= MAX_CERTS) {
- log_warnx("warn: certificate chain too long");
- goto end;
- }
- }
- else
- cert_count = 0;
-
- for (i = 0; i < cert_count; ++i) {
- x = sk_X509_value(xchain, i);
- cert_len[i+1] = i2d_X509(x, &cert_der[i+1]);
- if (cert_len[i+1] < 0) {
- log_warnx("warn: failed to encode certificate");
- goto end;
- }
- log_debug("debug: certificate %i: len=%d", i+1, cert_len[i+1]);
- if (cert_len[i+1] > (int)MAX_CERT_LEN) {
- log_warnx("warn: certificate too long");
- goto end;
- }
- }
-
- tree_xset(&wait_ssl_verify, s->id, s);
-
- /* Send the client certificate */
- req_ca_vrfy.reqid = s->id;
- req_ca_vrfy.cert_len = cert_len[0];
- req_ca_vrfy.n_chain = cert_count;
- iov[0].iov_base = &req_ca_vrfy;
- iov[0].iov_len = sizeof(req_ca_vrfy);
- iov[1].iov_base = cert_der[0];
- iov[1].iov_len = cert_len[0];
- m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CERT, 0, 0, -1,
- iov, nitems(iov));
-
- memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
- req_ca_vrfy.reqid = s->id;
-
- /* Send the chain, one cert at a time */
- for (i = 0; i < cert_count; ++i) {
- req_ca_vrfy.cert_len = cert_len[i+1];
- iov[1].iov_base = cert_der[i+1];
- iov[1].iov_len = cert_len[i+1];
- m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CHAIN, 0, 0, -1,
- iov, nitems(iov));
- }
-
- /* Tell lookup process that it can start verifying, we're done */
- memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
- req_ca_vrfy.reqid = s->id;
- m_compose(p_lka, IMSG_SMTP_TLS_VERIFY, 0, 0, -1,
- &req_ca_vrfy, sizeof req_ca_vrfy);
-
- res = 1;
-
- end:
- for (i = 0; i < MAX_CERTS; ++i)
- free(cert_der[i]);
-
- return res;
-}
-
-static void
smtp_cert_init(struct smtp_session *s)
{
const char *name;
@@ -2827,8 +2636,11 @@ static int
smtp_tx_filtered_dataline(struct smtp_tx *tx, const char *line)
{
if (!strcmp(line, ".")) {
- if (tx->error)
- return 1;
+ /* XXX - this needs to be handled properly */
+ /*
+ * if (tx->error)
+ * return 1;
+ */
line = NULL;
}
else {
diff --git a/smtpd/smtpd-api.h b/smtpd/smtpd-api.h
index 00f62071..f83edd05 100644
--- a/smtpd/smtpd-api.h
+++ b/smtpd/smtpd-api.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd-api.h,v 1.35 2018/11/01 10:47:46 gilles Exp $ */
+/* $OpenBSD: smtpd-api.h,v 1.36 2018/12/23 16:06:24 gilles Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -20,24 +20,14 @@
#ifndef _SMTPD_API_H_
#define _SMTPD_API_H_
+#include "dict.h"
+#include "tree.h"
+
struct mailaddr {
char user[SMTPD_MAXLOCALPARTSIZE];
char domain[SMTPD_MAXDOMAINPARTSIZE];
};
-SPLAY_HEAD(_dict, dictentry);
-SPLAY_HEAD(_tree, treeentry);
-
-struct tree {
- struct _tree tree;
- size_t count;
-};
-
-struct dict {
- struct _dict dict;
- size_t count;
-};
-
#define PROC_QUEUE_API_VERSION 2
enum {
@@ -244,23 +234,6 @@ msgid_to_evpid(uint32_t msgid)
return ((uint64_t)msgid << 32);
}
-/* dict.c */
-#define dict_init(d) do { SPLAY_INIT(&((d)->dict)); (d)->count = 0; } while(0)
-#define dict_empty(d) SPLAY_EMPTY(&((d)->dict))
-#define dict_count(d) ((d)->count)
-int dict_check(struct dict *, const char *);
-void *dict_set(struct dict *, const char *, void *);
-void dict_xset(struct dict *, const char *, void *);
-void *dict_get(struct dict *, const char *);
-void *dict_xget(struct dict *, const char *);
-void *dict_pop(struct dict *, const char *);
-void *dict_xpop(struct dict *, const char *);
-int dict_poproot(struct dict *, void **);
-int dict_root(struct dict *, const char **, void **);
-int dict_iter(struct dict *, void **, const char **, void **);
-int dict_iterfrom(struct dict *, void **, const char *, const char **, void **);
-void dict_merge(struct dict *, struct dict *);
-
/* esc.c */
const char *esc_code(enum enhanced_status_class, enum enhanced_status_code);
@@ -314,21 +287,4 @@ void table_api_on_fetch(int(*)(int, struct dict *, char *, size_t));
int table_api_dispatch(void);
const char *table_api_get_name(void);
-/* tree.c */
-#define tree_init(t) do { SPLAY_INIT(&((t)->tree)); (t)->count = 0; } while(0)
-#define tree_empty(t) SPLAY_EMPTY(&((t)->tree))
-#define tree_count(t) ((t)->count)
-int tree_check(struct tree *, uint64_t);
-void *tree_set(struct tree *, uint64_t, void *);
-void tree_xset(struct tree *, uint64_t, void *);
-void *tree_get(struct tree *, uint64_t);
-void *tree_xget(struct tree *, uint64_t);
-void *tree_pop(struct tree *, uint64_t);
-void *tree_xpop(struct tree *, uint64_t);
-int tree_poproot(struct tree *, uint64_t *, void **);
-int tree_root(struct tree *, uint64_t *, void **);
-int tree_iter(struct tree *, void **, uint64_t *, void **);
-int tree_iterfrom(struct tree *, void **, uint64_t, uint64_t *, void **);
-void tree_merge(struct tree *, struct tree *);
-
#endif
diff --git a/smtpd/smtpd.c b/smtpd/smtpd.c
index 97f4742d..2347afa4 100644
--- a/smtpd/smtpd.c
+++ b/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.313 2018/12/13 17:07:13 gilles Exp $ */
+/* $OpenBSD: smtpd.c,v 1.315 2018/12/23 16:37:53 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -584,9 +584,7 @@ main(int argc, char *argv[])
tracing |= TRACE_IO;
else if (!strcmp(optarg, "smtp"))
tracing |= TRACE_SMTP;
- else if (!strcmp(optarg, "mfa") ||
- !strcmp(optarg, "filter") ||
- !strcmp(optarg, "filters"))
+ else if (!strcmp(optarg, "filters"))
tracing |= TRACE_FILTERS;
else if (!strcmp(optarg, "mta") ||
!strcmp(optarg, "transfer"))
@@ -2027,10 +2025,6 @@ imsg_to_str(int type)
CASE(IMSG_MTA_LOOKUP_SMARTHOST);
CASE(IMSG_MTA_OPEN_MESSAGE);
CASE(IMSG_MTA_SCHEDULE);
- CASE(IMSG_MTA_TLS_INIT);
- CASE(IMSG_MTA_TLS_VERIFY_CERT);
- CASE(IMSG_MTA_TLS_VERIFY_CHAIN);
- CASE(IMSG_MTA_TLS_VERIFY);
CASE(IMSG_SCHED_ENVELOPE_BOUNCE);
CASE(IMSG_SCHED_ENVELOPE_DELIVER);
@@ -2047,10 +2041,6 @@ imsg_to_str(int type)
CASE(IMSG_SMTP_CHECK_SENDER);
CASE(IMSG_SMTP_EXPAND_RCPT);
CASE(IMSG_SMTP_LOOKUP_HELO);
- CASE(IMSG_SMTP_TLS_INIT);
- CASE(IMSG_SMTP_TLS_VERIFY_CERT);
- CASE(IMSG_SMTP_TLS_VERIFY_CHAIN);
- CASE(IMSG_SMTP_TLS_VERIFY);
CASE(IMSG_SMTP_REQ_CONNECT);
CASE(IMSG_SMTP_REQ_HELO);
diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h
index 74a2c150..dc819276 100644
--- a/smtpd/smtpd.h
+++ b/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.601 2018/12/22 13:09:05 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.610 2018/12/27 09:30:29 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -301,10 +301,6 @@ enum imsg_type {
IMSG_MTA_LOOKUP_SMARTHOST,
IMSG_MTA_OPEN_MESSAGE,
IMSG_MTA_SCHEDULE,
- IMSG_MTA_TLS_INIT,
- IMSG_MTA_TLS_VERIFY_CERT,
- IMSG_MTA_TLS_VERIFY_CHAIN,
- IMSG_MTA_TLS_VERIFY,
IMSG_SCHED_ENVELOPE_BOUNCE,
IMSG_SCHED_ENVELOPE_DELIVER,
@@ -321,10 +317,6 @@ enum imsg_type {
IMSG_SMTP_CHECK_SENDER,
IMSG_SMTP_EXPAND_RCPT,
IMSG_SMTP_LOOKUP_HELO,
- IMSG_SMTP_TLS_INIT,
- IMSG_SMTP_TLS_VERIFY_CERT,
- IMSG_SMTP_TLS_VERIFY_CHAIN,
- IMSG_SMTP_TLS_VERIFY,
IMSG_SMTP_REQ_CONNECT,
IMSG_SMTP_REQ_HELO,
@@ -396,13 +388,14 @@ struct table {
};
struct table_backend {
+ const char *name;
const unsigned int services;
int (*config)(struct table *);
- void *(*open)(struct table *);
+ int (*open)(struct table *);
int (*update)(struct table *);
- void (*close)(void *);
- int (*lookup)(void *, struct dict *, const char *, enum table_service, union lookup *);
- int (*fetch)(void *, struct dict *, enum table_service, union lookup *);
+ void (*close)(struct table *);
+ int (*lookup)(struct table *, enum table_service, const char *, char **);
+ int (*fetch)(struct table *, enum table_service, char **);
};
@@ -1140,37 +1133,6 @@ enum mda_resp_status {
MDA_PERMFAIL
};
-struct ca_cert_req_msg {
- uint64_t reqid;
- char name[HOST_NAME_MAX+1];
- int fallback;
-};
-
-struct ca_cert_resp_msg {
- uint64_t reqid;
- enum ca_resp_status status;
- char name[HOST_NAME_MAX+1];
- char *cert;
- off_t cert_len;
-};
-
-struct ca_vrfy_req_msg {
- uint64_t reqid;
- char name[HOST_NAME_MAX+1];
- int fallback;
- unsigned char *cert;
- off_t cert_len;
- size_t n_chain;
- size_t chain_offset;
- unsigned char **chain_cert;
- off_t *chain_cert_len;
-};
-
-struct ca_vrfy_resp_msg {
- uint64_t reqid;
- enum ca_resp_status status;
-};
-
struct msg_walkinfo {
struct event ev;
uint32_t msgid;
@@ -1668,9 +1630,10 @@ void table_close(struct table *);
int table_check_use(struct table *, uint32_t, uint32_t);
int table_check_type(struct table *, uint32_t);
int table_check_service(struct table *, uint32_t);
-int table_lookup(struct table *, struct dict *, const char *, enum table_service,
+int table_match(struct table *, enum table_service, const char *);
+int table_lookup(struct table *, enum table_service, const char *,
union lookup *);
-int table_fetch(struct table *, struct dict *, enum table_service, union lookup *);
+int table_fetch(struct table *, enum table_service, union lookup *);
void table_destroy(struct smtpd *, struct table *);
void table_add(struct table *, const char *, const char *);
int table_domain_match(const char *, const char *);
@@ -1680,8 +1643,6 @@ int table_regex_match(const char *, const char *);
void table_open_all(struct smtpd *);
void table_dump_all(struct smtpd *);
void table_close_all(struct smtpd *);
-int table_parse_lookup(enum table_service, const char *, const char *,
- union lookup *);
/* to.c */
diff --git a/smtpd/table.c b/smtpd/table.c
index 37249abd..a5d4b272 100644
--- a/smtpd/table.c
+++ b/smtpd/table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table.c,v 1.33 2018/12/21 21:35:29 gilles Exp $ */
+/* $OpenBSD: table.c,v 1.41 2018/12/27 09:30:29 eric Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -55,42 +55,33 @@ extern struct table_backend table_backend_getpwnam;
extern struct table_backend table_backend_proc;
static const char * table_service_name(enum table_service);
-static const char * table_backend_name(struct table_backend *);
-static const char * table_dump_lookup(enum table_service, union lookup *);
+static int table_parse_lookup(enum table_service, const char *, const char *,
+ union lookup *);
static int parse_sockaddr(struct sockaddr *, int, const char *);
static unsigned int last_table_id = 0;
+static struct table_backend *backends[] = {
+ &table_backend_static,
+ &table_backend_db,
+ &table_backend_getpwnam,
+ &table_backend_proc,
+ NULL
+};
+
struct table_backend *
table_backend_lookup(const char *backend)
{
- if (!strcmp(backend, "static") || !strcmp(backend, "file"))
- return &table_backend_static;
-#ifdef HAVE_DB_API
- if (!strcmp(backend, "db"))
- return &table_backend_db;
-#endif
- if (!strcmp(backend, "getpwnam"))
- return &table_backend_getpwnam;
- if (!strcmp(backend, "proc"))
- return &table_backend_proc;
- return NULL;
-}
+ int i;
-static const char *
-table_backend_name(struct table_backend *backend)
-{
- if (backend == &table_backend_static)
- return "static";
-#ifdef HAVE_DB_API
- if (backend == &table_backend_db)
- return "db";
-#endif
- if (backend == &table_backend_getpwnam)
- return "getpwnam";
- if (backend == &table_backend_proc)
- return "proc";
- return "???";
+ if (!strcmp(backend, "file"))
+ backend = "static";
+
+ for (i = 0; backends[i]; i++)
+ if (!strcmp(backends[i]->name, backend))
+ return (backends[i]);
+
+ return NULL;
}
static const char *
@@ -129,11 +120,17 @@ table_find(struct smtpd *conf, const char *name, const char *tag)
}
int
-table_lookup(struct table *table, struct dict *params, const char *key, enum table_service kind,
+table_match(struct table *table, enum table_service kind, const char *key)
+{
+ return table_lookup(table, kind, key, NULL);
+}
+
+int
+table_lookup(struct table *table, enum table_service kind, const char *key,
union lookup *lk)
{
int r;
- char lkey[1024];
+ char lkey[1024], *buf = NULL;
if (table->t_backend->lookup == NULL)
return (-1);
@@ -143,55 +140,66 @@ table_lookup(struct table *table, struct dict *params, const char *key, enum tab
return -1;
}
- r = table->t_backend->lookup(table->t_handle, params, lkey, kind, lk);
+ r = table->t_backend->lookup(table, kind, lkey, lk ? &buf : NULL);
- if (r == 1)
+ if (r == 1) {
log_trace(TRACE_LOOKUP, "lookup: %s \"%s\" as %s in table %s:%s -> %s%s%s",
lk ? "lookup" : "check",
lkey,
table_service_name(kind),
- table_backend_name(table->t_backend),
+ table->t_backend->name,
table->t_name,
lk ? "\"" : "",
- (lk) ? table_dump_lookup(kind, lk): "found",
+ (lk) ? buf : "found",
lk ? "\"" : "");
+ if (buf)
+ r = table_parse_lookup(kind, lkey, buf, lk);
+ }
else
log_trace(TRACE_LOOKUP, "lookup: %s \"%s\" as %s in table %s:%s -> %d",
lk ? "lookup" : "check",
lkey,
table_service_name(kind),
- table_backend_name(table->t_backend),
+ table->t_backend->name,
table->t_name,
r);
+ free(buf);
+
return (r);
}
int
-table_fetch(struct table *table, struct dict *params, enum table_service kind, union lookup *lk)
+table_fetch(struct table *table, enum table_service kind, union lookup *lk)
{
int r;
+ char *buf = NULL;
if (table->t_backend->fetch == NULL)
return (-1);
- r = table->t_backend->fetch(table->t_handle, params, kind, lk);
+ r = table->t_backend->fetch(table, kind, lk ? &buf : NULL);
- if (r == 1)
+ if (r == 1) {
log_trace(TRACE_LOOKUP, "lookup: fetch %s from table %s:%s -> %s%s%s",
table_service_name(kind),
- table_backend_name(table->t_backend),
+ table->t_backend->name,
table->t_name,
lk ? "\"" : "",
- (lk) ? table_dump_lookup(kind, lk): "found",
+ (lk) ? buf : "found",
lk ? "\"" : "");
+ if (buf)
+ r = table_parse_lookup(kind, NULL, buf, lk);
+ }
else
log_trace(TRACE_LOOKUP, "lookup: fetch %s from table %s:%s -> %d",
table_service_name(kind),
- table_backend_name(table->t_backend),
+ table->t_backend->name,
table->t_name,
r);
+ free(buf);
+
return (r);
}
@@ -336,20 +344,16 @@ table_check_use(struct table *t, uint32_t tmask, uint32_t smask)
int
table_open(struct table *t)
{
- t->t_handle = NULL;
if (t->t_backend->open == NULL)
return (1);
- t->t_handle = t->t_backend->open(t);
- if (t->t_handle == NULL)
- return (0);
- return (1);
+ return (t->t_backend->open(t));
}
void
table_close(struct table *t)
{
if (t->t_backend->close)
- t->t_backend->close(t->t_handle);
+ t->t_backend->close(t);
}
int
@@ -549,7 +553,7 @@ table_close_all(struct smtpd *conf)
table_close(t);
}
-int
+static int
table_parse_lookup(enum table_service service, const char *key,
const char *line, union lookup *lk)
{
@@ -662,108 +666,6 @@ table_parse_lookup(enum table_service service, const char *key,
}
}
-static const char *
-table_dump_lookup(enum table_service s, union lookup *lk)
-{
- static char buf[LINE_MAX];
- struct maddrnode *mn;
- int ret;
-
- switch (s) {
- case K_NONE:
- break;
-
- case K_ALIAS:
- expand_to_text(lk->expand, buf, sizeof(buf));
- break;
-
- case K_DOMAIN:
- ret = snprintf(buf, sizeof(buf), "%s", lk->domain.name);
- if (ret == -1 || (size_t)ret >= sizeof (buf))
- goto err;
- break;
-
- case K_CREDENTIALS:
- ret = snprintf(buf, sizeof(buf), "%s:%s",
- lk->creds.username, lk->creds.password);
- if (ret == -1 || (size_t)ret >= sizeof (buf))
- goto err;
- break;
-
- case K_NETADDR:
- ret = snprintf(buf, sizeof(buf), "%s/%d",
- sockaddr_to_text((struct sockaddr *)&lk->netaddr.ss),
- lk->netaddr.bits);
- if (ret == -1 || (size_t)ret >= sizeof (buf))
- goto err;
- break;
-
- case K_USERINFO:
- ret = snprintf(buf, sizeof(buf), "%s:%d:%d:%s",
- lk->userinfo.username,
- lk->userinfo.uid,
- lk->userinfo.gid,
- lk->userinfo.directory);
- if (ret == -1 || (size_t)ret >= sizeof (buf))
- goto err;
- break;
-
- case K_SOURCE:
- ret = snprintf(buf, sizeof(buf), "%s",
- ss_to_text(&lk->source.addr));
- if (ret == -1 || (size_t)ret >= sizeof (buf))
- goto err;
- break;
-
- case K_MAILADDR:
- ret = snprintf(buf, sizeof(buf), "%s@%s",
- lk->mailaddr.user,
- lk->mailaddr.domain);
- if (ret == -1 || (size_t)ret >= sizeof (buf))
- goto err;
- break;
-
- case K_MAILADDRMAP:
- buf[0] = '\0';
- TAILQ_FOREACH(mn, &lk->maddrmap->queue, entries) {
- (void)strlcat(buf, mn->mailaddr.user, sizeof(buf));
- (void)strlcat(buf, "@", sizeof(buf));
- ret = strlcat(buf, mn->mailaddr.domain, sizeof(buf));
-
- if (mn != TAILQ_LAST(&lk->maddrmap->queue, xmaddr))
- ret = strlcat(buf, ", ", sizeof(buf));
-
- if (ret >= sizeof(buf)) {
- strlcpy(buf + sizeof(buf) - 4, "...", 4);
- break;
- }
- }
- break;
-
- case K_ADDRNAME:
- ret = snprintf(buf, sizeof(buf), "%s",
- lk->addrname.name);
- if (ret == -1 || (size_t)ret >= sizeof (buf))
- goto err;
- break;
-
- case K_RELAYHOST:
- if (strlcpy(buf, lk->relayhost, sizeof(buf)) >= sizeof(buf))
- goto err;
- break;
-
- default:
- (void)strlcpy(buf, "???", sizeof(buf));
- break;
- }
-
- return (buf);
-
-err:
- return (NULL);
-}
-
-
static int
parse_sockaddr(struct sockaddr *sa, int family, const char *str)
{
diff --git a/smtpd/table_db.c b/smtpd/table_db.c
index 4ef23f71..cd2263fe 100644
--- a/smtpd/table_db.c
+++ b/smtpd/table_db.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table_db.c,v 1.10 2018/05/31 21:06:12 gilles Exp $ */
+/* $OpenBSD: table_db.c,v 1.17 2018/12/27 09:30:29 eric Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
@@ -49,16 +49,19 @@
/* db(3) backend */
static int table_db_config(struct table *);
static int table_db_update(struct table *);
-static void *table_db_open(struct table *);
-static int table_db_lookup(void *, struct dict *, const char *, enum table_service, union lookup *);
-static int table_db_fetch(void *, struct dict *, enum table_service, union lookup *);
-static void table_db_close(void *);
+static int table_db_open(struct table *);
+static void *table_db_open2(struct table *);
+static int table_db_lookup(struct table *, enum table_service, const char *, char **);
+static int table_db_fetch(struct table *, enum table_service, char **);
+static void table_db_close(struct table *);
+static void table_db_close2(void *);
static char *table_db_get_entry(void *, const char *, size_t *);
static char *table_db_get_entry_match(void *, const char *, size_t *,
int(*)(const char *, const char *));
struct table_backend table_backend_db = {
+ "db",
K_ALIAS|K_CREDENTIALS|K_DOMAIN|K_NETADDR|K_USERINFO|K_SOURCE|K_MAILADDR|K_ADDRNAME|K_MAILADDRMAP,
table_db_config,
table_db_open,
@@ -81,7 +84,6 @@ struct dbhandle {
DB *db;
char pathname[PATH_MAX];
time_t mtime;
- struct table *table;
};
static int
@@ -89,11 +91,11 @@ table_db_config(struct table *table)
{
struct dbhandle *handle;
- handle = table_db_open(table);
+ handle = table_db_open2(table);
if (handle == NULL)
return 0;
- table_db_close(handle);
+ table_db_close2(handle);
return 1;
}
@@ -102,18 +104,34 @@ table_db_update(struct table *table)
{
struct dbhandle *handle;
- handle = table_db_open(table);
+ handle = table_db_open2(table);
if (handle == NULL)
return 0;
- table_db_close(table->t_handle);
+ table_db_close2(table->t_handle);
table->t_handle = handle;
return 1;
}
-static void *
+static int
table_db_open(struct table *table)
{
+ table->t_handle = table_db_open2(table);
+ if (table->t_handle == NULL)
+ return 0;
+ return 1;
+}
+
+static void
+table_db_close(struct table *table)
+{
+ table_db_close2(table->t_handle);
+ table->t_handle = NULL;
+}
+
+static void *
+table_db_open2(struct table *table)
+{
struct dbhandle *handle;
struct stat sb;
@@ -129,7 +147,6 @@ table_db_open(struct table *table)
handle->db = dbopen(table->t_config, O_RDONLY, 0600, DB_HASH, NULL);
if (handle->db == NULL)
goto error;
- handle->table = table;
return handle;
@@ -141,7 +158,7 @@ error:
}
static void
-table_db_close(void *hdl)
+table_db_close2(void *hdl)
{
struct dbhandle *handle = hdl;
handle->db->close(handle->db);
@@ -149,11 +166,10 @@ table_db_close(void *hdl)
}
static int
-table_db_lookup(void *hdl, struct dict *params, const char *key, enum table_service service,
- union lookup *lk)
+table_db_lookup(struct table *table, enum table_service service, const char *key,
+ char **dst)
{
- struct dbhandle *handle = hdl;
- struct table *table = NULL;
+ struct dbhandle *handle = table->t_handle;
char *line;
size_t len = 0;
int ret;
@@ -166,8 +182,7 @@ table_db_lookup(void *hdl, struct dict *params, const char *key, enum table_serv
/* DB has changed, close and reopen */
if (sb.st_mtime != handle->mtime) {
- table = handle->table;
- table_db_update(handle->table);
+ table_db_update(table);
handle = table->t_handle;
}
@@ -183,18 +198,18 @@ table_db_lookup(void *hdl, struct dict *params, const char *key, enum table_serv
return 0;
ret = 1;
- if (lk)
- ret = table_parse_lookup(service, key, line, lk);
- free(line);
+ if (dst)
+ *dst = line;
+ else
+ free(line);
return ret;
}
static int
-table_db_fetch(void *hdl, struct dict *params, enum table_service service, union lookup *lk)
+table_db_fetch(struct table *table, enum table_service service, char **dst)
{
- struct dbhandle *handle = hdl;
- struct table *table = handle->table;
+ struct dbhandle *handle = table->t_handle;
DBT dbk;
DBT dbd;
int r;
@@ -210,7 +225,13 @@ table_db_fetch(void *hdl, struct dict *params, enum table_service service, union
return 0;
}
- return table_parse_lookup(service, NULL, dbk.data, lk);
+ if (dst) {
+ *dst = strdup(dbk.data);
+ if (*dst == NULL)
+ return -1;
+ }
+
+ return 1;
}
diff --git a/smtpd/table_getpwnam.c b/smtpd/table_getpwnam.c
index 87b0a54c..b0a9e8cf 100644
--- a/smtpd/table_getpwnam.c
+++ b/smtpd/table_getpwnam.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table_getpwnam.c,v 1.4 2015/01/20 17:37:54 deraadt Exp $ */
+/* $OpenBSD: table_getpwnam.c,v 1.11 2018/12/27 09:30:29 eric Exp $ */
/*
* Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
@@ -42,12 +42,13 @@
/* getpwnam(3) backend */
static int table_getpwnam_config(struct table *);
static int table_getpwnam_update(struct table *);
-static void *table_getpwnam_open(struct table *);
-static int table_getpwnam_lookup(void *, struct dict *, const char *, enum table_service,
- union lookup *);
-static void table_getpwnam_close(void *);
+static int table_getpwnam_open(struct table *);
+static int table_getpwnam_lookup(struct table *, enum table_service, const char *,
+ char **);
+static void table_getpwnam_close(struct table *);
struct table_backend table_backend_getpwnam = {
+ "getpwnam",
K_USERINFO,
table_getpwnam_config,
table_getpwnam_open,
@@ -71,24 +72,23 @@ table_getpwnam_update(struct table *table)
return 1;
}
-static void *
+static int
table_getpwnam_open(struct table *table)
{
- return table;
+ return 1;
}
static void
-table_getpwnam_close(void *hdl)
+table_getpwnam_close(struct table *table)
{
return;
}
static int
-table_getpwnam_lookup(void *hdl, struct dict *params, const char *key, enum table_service kind,
- union lookup *lk)
+table_getpwnam_lookup(struct table *table, enum table_service kind, const char *key,
+ char **dst)
{
struct passwd *pw;
- size_t s;
if (kind != K_USERINFO)
return -1;
@@ -103,19 +103,16 @@ table_getpwnam_lookup(void *hdl, struct dict *params, const char *key, enum tabl
return -1;
return 0;
}
- if (lk == NULL)
+ if (dst == NULL)
return 1;
- lk->userinfo.uid = pw->pw_uid;
- lk->userinfo.gid = pw->pw_gid;
- s = strlcpy(lk->userinfo.username, pw->pw_name,
- sizeof(lk->userinfo.username));
- if (s >= sizeof(lk->userinfo.username))
- return (-1);
- s = strlcpy(lk->userinfo.directory, pw->pw_dir,
- sizeof(lk->userinfo.directory));
- if (s >= sizeof(lk->userinfo.directory))
- return (-1);
+ if (asprintf(dst, "%d:%d:%s",
+ pw->pw_uid,
+ pw->pw_gid,
+ pw->pw_dir) == -1) {
+ *dst = NULL;
+ return -1;
+ }
return (1);
}
diff --git a/smtpd/table_proc.c b/smtpd/table_proc.c
index fcf4ffcb..c29bcf86 100644
--- a/smtpd/table_proc.c
+++ b/smtpd/table_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table_proc.c,v 1.7 2018/05/31 21:06:12 gilles Exp $ */
+/* $OpenBSD: table_proc.c,v 1.14 2018/12/27 09:30:29 eric Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -120,7 +120,7 @@ table_proc_end(void)
* API
*/
-static void *
+static int
table_proc_open(struct table *table)
{
struct table_proc_priv *priv;
@@ -143,7 +143,9 @@ table_proc_open(struct table *table)
table_proc_call(priv);
table_proc_end();
- return (priv);
+ table->t_handle = priv;
+
+ return (1);
}
static int
@@ -162,60 +164,43 @@ table_proc_update(struct table *table)
}
static void
-table_proc_close(void *arg)
+table_proc_close(struct table *table)
{
- struct table_proc_priv *priv = arg;
+ struct table_proc_priv *priv = table->t_handle;
imsg_compose(&priv->ibuf, PROC_TABLE_CLOSE, 0, 0, -1, NULL, 0);
imsg_flush(&priv->ibuf);
+
+ table->t_handle = NULL;
}
static int
-imsg_add_params(struct ibuf *buf, struct dict *params)
+imsg_add_params(struct ibuf *buf)
{
- size_t count;
- const char *key;
- char *value;
- void *iter;
-
- count = 0;
- if (params)
- count = dict_count(params);
+ size_t count = 0;
if (imsg_add(buf, &count, sizeof(count)) == -1)
return (-1);
- if (count == 0)
- return (0);
-
- iter = NULL;
- while (dict_iter(params, &iter, &key, (void **)&value)) {
- if (imsg_add(buf, key, strlen(key) + 1) == -1)
- return (-1);
- if (imsg_add(buf, value, strlen(value) + 1) == -1)
- return (-1);
- }
-
return (0);
}
static int
-table_proc_lookup(void *arg, struct dict *params, const char *k, enum table_service s,
- union lookup *lk)
+table_proc_lookup(struct table *table, enum table_service s, const char *k, char **dst)
{
- struct table_proc_priv *priv = arg;
+ struct table_proc_priv *priv = table->t_handle;
struct ibuf *buf;
int r;
buf = imsg_create(&priv->ibuf,
- lk ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0,
+ dst ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0,
sizeof(s) + strlen(k) + 1);
if (buf == NULL)
return (-1);
if (imsg_add(buf, &s, sizeof(s)) == -1)
return (-1);
- if (imsg_add_params(buf, params) == -1)
+ if (imsg_add_params(buf) == -1)
return (-1);
if (imsg_add(buf, k, strlen(k) + 1) == -1)
return (-1);
@@ -224,7 +209,7 @@ table_proc_lookup(void *arg, struct dict *params, const char *k, enum table_serv
table_proc_call(priv);
table_proc_read(&r, sizeof(r));
- if (r == 1 && lk) {
+ if (r == 1 && dst) {
if (rlen == 0) {
log_warnx("warn: table-proc: empty response");
fatalx("table-proc: exiting");
@@ -233,7 +218,9 @@ table_proc_lookup(void *arg, struct dict *params, const char *k, enum table_serv
log_warnx("warn: table-proc: not NUL-terminated");
fatalx("table-proc: exiting");
}
- r = table_parse_lookup(s, k, rdata, lk);
+ *dst = strdup(rdata);
+ if (*dst == NULL)
+ r = -1;
table_proc_read(NULL, rlen);
}
@@ -243,9 +230,9 @@ table_proc_lookup(void *arg, struct dict *params, const char *k, enum table_serv
}
static int
-table_proc_fetch(void *arg, struct dict *params, enum table_service s, union lookup *lk)
+table_proc_fetch(struct table *table, enum table_service s, char **dst)
{
- struct table_proc_priv *priv = arg;
+ struct table_proc_priv *priv = table->t_handle;
struct ibuf *buf;
int r;
@@ -254,7 +241,7 @@ table_proc_fetch(void *arg, struct dict *params, enum table_service s, union loo
return (-1);
if (imsg_add(buf, &s, sizeof(s)) == -1)
return (-1);
- if (imsg_add_params(buf, params) == -1)
+ if (imsg_add_params(buf) == -1)
return (-1);
imsg_close(&priv->ibuf, buf);
@@ -270,7 +257,9 @@ table_proc_fetch(void *arg, struct dict *params, enum table_service s, union loo
log_warnx("warn: table-proc: not NUL-terminated");
fatalx("table-proc: exiting");
}
- r = table_parse_lookup(s, NULL, rdata, lk);
+ *dst = strdup(rdata);
+ if (*dst == NULL)
+ r = -1;
table_proc_read(NULL, rlen);
}
@@ -280,6 +269,7 @@ table_proc_fetch(void *arg, struct dict *params, enum table_service s, union loo
}
struct table_backend table_backend_proc = {
+ "proc",
K_ANY,
NULL,
table_proc_open,
diff --git a/smtpd/table_static.c b/smtpd/table_static.c
index 3a19e7e2..9f57f761 100644
--- a/smtpd/table_static.c
+++ b/smtpd/table_static.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table_static.c,v 1.20 2018/11/01 10:47:46 gilles Exp $ */
+/* $OpenBSD: table_static.c,v 1.27 2018/12/27 09:30:29 eric Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -43,14 +43,14 @@
/* static backend */
static int table_static_config(struct table *);
static int table_static_update(struct table *);
-static void *table_static_open(struct table *);
-static int table_static_lookup(void *, struct dict *, const char *,
- enum table_service, union lookup *);
-static int table_static_fetch(void *, struct dict *, enum table_service,
- union lookup *);
-static void table_static_close(void *);
+static int table_static_open(struct table *);
+static int table_static_lookup(struct table *, enum table_service, const char *,
+ char **);
+static int table_static_fetch(struct table *, enum table_service, char **);
+static void table_static_close(struct table *);
struct table_backend table_backend_static = {
+ "static",
K_ALIAS|K_CREDENTIALS|K_DOMAIN|K_NETADDR|K_USERINFO|
K_SOURCE|K_MAILADDR|K_ADDRNAME|K_MAILADDRMAP|K_RELAYHOST|
K_STRING|K_REGEX,
@@ -204,23 +204,23 @@ err:
return 0;
}
-static void *
+static int
table_static_open(struct table *table)
{
- return table;
+ table->t_handle = table;
+ return 1;
}
static void
-table_static_close(void *hdl)
+table_static_close(struct table *table)
{
- return;
+ table->t_handle = NULL;
}
static int
-table_static_lookup(void *hdl, struct dict *params, const char *key,
- enum table_service service, union lookup *lk)
+table_static_lookup(struct table *m, enum table_service service, const char *key,
+ char **dst)
{
- struct table *m = hdl;
char *line;
int ret;
int (*match)(const char *, const char *) = NULL;
@@ -253,20 +253,22 @@ table_static_lookup(void *hdl, struct dict *params, const char *key,
break;
}
- if (lk == NULL)
+ if (dst == NULL)
return ret ? 1 : 0;
if (ret == 0)
return 0;
- return table_parse_lookup(service, key, line, lk);
+ *dst = strdup(line);
+ if (*dst == NULL)
+ return -1;
+
+ return 1;
}
static int
-table_static_fetch(void *hdl, struct dict *params,
- enum table_service service, union lookup *lk)
+table_static_fetch(struct table *t, enum table_service service, char **dst)
{
- struct table *t = hdl;
const char *k;
if (!dict_iter(&t->t_dict, &t->t_iter, &k, (void **)NULL)) {
@@ -275,8 +277,12 @@ table_static_fetch(void *hdl, struct dict *params,
return 0;
}
- if (lk == NULL)
+ if (dst == NULL)
return 1;
- return table_parse_lookup(service, NULL, k, lk);
+ *dst = strdup(k);
+ if (*dst == NULL)
+ return -1;
+
+ return 1;
}
diff --git a/smtpd/tree.c b/smtpd/tree.c
index 03ba8d15..1d720a59 100644
--- a/smtpd/tree.c
+++ b/smtpd/tree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tree.c,v 1.5 2015/01/20 17:37:54 deraadt Exp $ */
+/* $OpenBSD: tree.c,v 1.6 2018/12/23 16:06:24 gilles Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
@@ -21,17 +21,12 @@
#include <sys/types.h>
#include <sys/tree.h>
-#include <sys/socket.h> /* for smtpd.h */
-#include <sys/queue.h> /* for smtpd.h */
-#include <stdio.h> /* for smtpd.h */
-#include <imsg.h> /* for smtpd.h */
-
#include <err.h>
#include <inttypes.h>
#include <stdlib.h>
#include <limits.h>
-#include "smtpd.h"
+#include "tree.h"
struct treeentry {
SPLAY_ENTRY(treeentry) entry;
diff --git a/smtpd/tree.h b/smtpd/tree.h
new file mode 100644
index 00000000..3d719f09
--- /dev/null
+++ b/smtpd/tree.h
@@ -0,0 +1,48 @@
+/* $OpenBSD: tree.h,v 1.1 2018/12/23 16:06:24 gilles Exp $ */
+
+/*
+ * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
+ * Copyright (c) 2011 Gilles Chehade <gilles@poolp.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.
+ */
+
+#ifndef _TREE_H_
+#define _TREE_H_
+
+SPLAY_HEAD(_tree, treeentry);
+
+struct tree {
+ struct _tree tree;
+ size_t count;
+};
+
+
+/* tree.c */
+#define tree_init(t) do { SPLAY_INIT(&((t)->tree)); (t)->count = 0; } while(0)
+#define tree_empty(t) SPLAY_EMPTY(&((t)->tree))
+#define tree_count(t) ((t)->count)
+int tree_check(struct tree *, uint64_t);
+void *tree_set(struct tree *, uint64_t, void *);
+void tree_xset(struct tree *, uint64_t, void *);
+void *tree_get(struct tree *, uint64_t);
+void *tree_xget(struct tree *, uint64_t);
+void *tree_pop(struct tree *, uint64_t);
+void *tree_xpop(struct tree *, uint64_t);
+int tree_poproot(struct tree *, uint64_t *, void **);
+int tree_root(struct tree *, uint64_t *, void **);
+int tree_iter(struct tree *, void **, uint64_t *, void **);
+int tree_iterfrom(struct tree *, void **, uint64_t, uint64_t *, void **);
+void tree_merge(struct tree *, struct tree *);
+
+#endif