Commit Diff


commit - 27541da87a2e82efb16eaac56bb5c10e12859b29
commit + 6840f1a1324e44cbaa373c963504b7b0eedeb569
blob - e621fb18c804aeddd0113a789eeeb8e34d0e7423
blob + 162410079b5787f759025db694c5a456932a50f6
--- Makefile
+++ Makefile
@@ -2,10 +2,14 @@
 
 PROG=	filter-dkim
 BINDIR=	/usr/libexec/smtpd/
-SRCS+=	main.c smtp_proc.c
+SRCS+=	main.c
 
-CFLAGS+= -g3 -O0
-LDADD+=	-levent -lcrypto
+CFLAGS+=-Wall -I${.CURDIR}
+CFLAGS+=-Wstrict-prototypes -Wmissing-prototypes
+CFLAGS+=-Wmissing-declarations
+CFLAGS+=-Wshadow -Wpointer-arith -Wcast-qual
+CFLAGS+=-Wsign-compare
+LDADD+=	-levent -lcrypto -lopensmtpd
 DPADD=	${LIBEVENT} ${LIBCRYPTO}
 
 .include <bsd.prog.mk>
blob - 114ca8bc90f950566cfe35bb43c14ae1b58834c9
blob + 18fee80d2299c7e4fff8667e6aba71006f622039
--- filter-dkim.1
+++ filter-dkim.1
@@ -22,13 +22,11 @@
 .Nd add dkim signature to messages
 .Sh SYNOPSIS
 .Nm
+.Op Fl tz
 .Op Fl a Ar algorithm
 .Op Fl c Ar canonicalization
 .Op Fl h Ar headers
-.Op Fl t
 .Op Fl x Ar seconds
-.Op Fl z
-.Op Fl Z
 .Fl d Ar domain
 .Fl k Ar file
 .Fl s Ar selector
@@ -71,10 +69,10 @@ Add the amount of
 the signature is valid to the dkim header.
 .It Fl z
 Add the mail headers used in the dkim signature to the dkim header.
+If a second
+.Fl z
+is specified all headers will be included in the dkim header.
 Useful for debugging purposes.
-.It Fl Z
-Add all the mail headers to the dkim header.
-Useful for debugging purposes.
 .El
 .Sh SEE ALSO
 .Xr smtpd 8
blob - 0d1c69f72c27f74d37a5e6d2083227dea8b7cf05
blob + 5a258366c31fcf1c07bdb19fc046fa0d549a4eea
--- main.c
+++ main.c
@@ -13,14 +13,11 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
-#include <sys/tree.h>
-
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/sha.h>
 
 #include <ctype.h>
-#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -30,7 +27,7 @@
 #include <time.h>
 #include <unistd.h>
 
-#include "smtp_proc.h"
+#include "opensmtpd.h"
 
 struct dkim_signature {
 	char *signature;
@@ -38,9 +35,7 @@ struct dkim_signature {
 	size_t len;
 };
 
-struct dkim_session {
-	uint64_t reqid;
-	uint64_t token;
+struct dkim_message {
 	FILE *origf;
 	int parsing_headers;
 	char **headers;
@@ -51,12 +46,8 @@ struct dkim_session {
 	int err;
 	EVP_MD_CTX *b;
 	EVP_MD_CTX *bh;
-	RB_ENTRY(dkim_session) entry;
 };
 
-RB_HEAD(dkim_sessions, dkim_session) dkim_sessions = RB_INITIALIZER(NULL);
-RB_PROTOTYPE(dkim_sessions, dkim_session, entry, dkim_session_cmp);
-
 /* RFC 6376 section 5.4.1 */
 static char *dsign_headers[] = {
 	"from",
@@ -103,41 +94,35 @@ static const EVP_MD *hash_md;
 #define DKIM_SIGNATURE_LINELEN 78
 
 void usage(void);
-void dkim_err(struct dkim_session *, char *);
-void dkim_errx(struct dkim_session *, char *);
+void dkim_err(struct dkim_message *, char *);
+void dkim_errx(struct dkim_message *, char *);
 void dkim_headers_set(char *);
-void dkim_dataline(char *, int, struct timespec *, char *, char *, uint64_t,
-    uint64_t, char *);
-void dkim_commit(char *, int, struct timespec *, char *, char *, uint64_t,
-    uint64_t);
-void dkim_disconnect(char *, int, struct timespec *, char *, char *, uint64_t);
-struct dkim_session *dkim_session_new(uint64_t);
-void dkim_session_free(struct dkim_session *);
-int dkim_session_cmp(struct dkim_session *, struct dkim_session *);
-void dkim_parse_header(struct dkim_session *, char *, int);
-void dkim_parse_body(struct dkim_session *, char *);
-void dkim_sign(struct dkim_session *);
-int dkim_signature_printheader(struct dkim_session *, char *);
-int dkim_signature_printf(struct dkim_session *, char *, ...)
+void dkim_dataline(struct osmtpd_ctx *, const char *);
+void dkim_commit(struct osmtpd_ctx *);
+void *dkim_message_new(struct osmtpd_ctx *);
+void dkim_message_free(struct osmtpd_ctx *, void *);
+void dkim_parse_header(struct dkim_message *, char *, int);
+void dkim_parse_body(struct dkim_message *, char *);
+void dkim_sign(struct osmtpd_ctx *);
+int dkim_signature_printheader(struct dkim_message *, const char *);
+int dkim_signature_printf(struct dkim_message *, char *, ...)
 	__attribute__((__format__ (printf, 2, 3)));
-int dkim_signature_normalize(struct dkim_session *);
-int dkim_signature_need(struct dkim_session *, size_t);
-int dkim_sign_init(struct dkim_session *);
+int dkim_signature_normalize(struct dkim_message *);
+int dkim_signature_need(struct dkim_message *, size_t);
+int dkim_sign_init(struct dkim_message *);
 
 int
 main(int argc, char *argv[])
 {
 	int ch;
-	int i;
-	int debug = 0;
 	FILE *keyfile;
 	const char *errstr;
 
-	while ((ch = getopt(argc, argv, "a:c:Dd:h:k:s:tx:zZ")) != -1) {
+	while ((ch = getopt(argc, argv, "a:c:d:h:k:s:tx:z")) != -1) {
 		switch (ch) {
 		case 'a':
 			if (strncmp(optarg, "rsa-", 4) != 0)
-				err(1, "invalid algorithm");
+				osmtpd_err(1, "invalid algorithm");
 			hashalg = optarg + 4;
 			break;
 		case 'c':
@@ -148,18 +133,19 @@ main(int argc, char *argv[])
 				canonheader = CANON_RELAXED;
 				optarg += 7;
 			} else
-				err(1, "Invalid canonicalization");
+				osmtpd_err(1, "Invalid canonicalization");
 			if (optarg[0] == '/') {
 				if (strcmp(optarg + 1, "simple") == 0)
 					canonbody = CANON_SIMPLE;
 				else if (strcmp(optarg + 1, "relaxed") == 0)
 					canonbody = CANON_RELAXED;
 				else
-					err(1, "Invalid canonicalization");
+					osmtpd_err(1,
+					    "Invalid canonicalization");
 			} else if (optarg[0] == '\0')
 				canonbody = CANON_SIMPLE;
 			else
-				err(1, "Invalid canonicalization");
+				osmtpd_err(1, "Invalid canonicalization");
 			break;
 		case 'd':
 			domain = optarg;
@@ -169,12 +155,13 @@ main(int argc, char *argv[])
 			break;
 		case 'k':
 			if ((keyfile = fopen(optarg, "r")) == NULL)
-				err(1, "Can't open key file");
+				osmtpd_err(1, "Can't open key file (%s)",
+				    optarg);
 			pkey = PEM_read_PrivateKey(keyfile, NULL, NULL, NULL);
 			if (pkey == NULL)
-				errx(1, "Can't read key file");
+				osmtpd_errx(1, "Can't read key file");
 			if (EVP_PKEY_get0_RSA(pkey) == NULL)
-				err(1, "Key is not of type rsa");
+				osmtpd_err(1, "Key is not of type rsa");
 			fclose(keyfile);
 			break;
 		case 's':
@@ -186,17 +173,11 @@ main(int argc, char *argv[])
 		case 'x':
 			addexpire = strtonum(optarg, 1, INT64_MAX, &errstr);
 			if (addexpire == 0)
-				errx(1, "Expire offset is %s", errstr);
+				osmtpd_errx(1, "Expire offset is %s", errstr);
 			break;
 		case 'z':
-			addheaders = 1;
+			addheaders++;
 			break;
-		case 'Z':
-			addheaders = 2;
-			break;
-		case 'D':
-			debug = 1;
-			break;
 		default:
 			usage();
 		}
@@ -204,170 +185,135 @@ main(int argc, char *argv[])
 
 	OpenSSL_add_all_digests();
 	if ((hash_md = EVP_get_digestbyname(hashalg)) == NULL)
-		errx(1, "Can't find hash: %s", hashalg);
+		osmtpd_errx(1, "Can't find hash: %s", hashalg);
 
-	/*
-	 * fattr required for tmpfile.
-	 * Can hopefully be removed in the future
-	 */
-	if (pledge("fattr tmppath stdio", NULL) == -1)
-		err(1, "pledge");
+	if (pledge("tmppath stdio", NULL) == -1)
+		osmtpd_err(1, "pledge");
 
 	if (domain == NULL || selector == NULL || pkey == NULL)
 		usage();
 
-	smtp_register_filter_dataline(dkim_dataline);
-	smtp_register_filter_commit(dkim_commit);
-	smtp_in_register_report_disconnect(dkim_disconnect);
-	smtp_run(debug);
+	osmtpd_register_filter_dataline(dkim_dataline);
+	osmtpd_register_filter_commit(dkim_commit);
+	osmtpd_local_message(dkim_message_new, dkim_message_free);
+	osmtpd_run();
 
 	return 0;
 }
 
 void
-dkim_disconnect(char *type, int version, struct timespec *tm, char *direction,
-    char *phase, uint64_t reqid)
+dkim_dataline(struct osmtpd_ctx *ctx, const char *line)
 {
-	struct dkim_session *session, search;
-
-	search.reqid = reqid;
-	if ((session = RB_FIND(dkim_sessions, &dkim_sessions, &search)) != NULL)
-		dkim_session_free(session);
-}
-
-void
-dkim_dataline(char *type, int version, struct timespec *tm, char *direction,
-    char *phase, uint64_t reqid, uint64_t token, char *line)
-{
-	struct dkim_session *session, search;
+	struct dkim_message *message = ctx->local_message;
+	char *linedup;
 	size_t linelen;
 
-	search.reqid = reqid;
-	session = RB_FIND(dkim_sessions, &dkim_sessions, &search);
-	if (session == NULL) {
-		if ((session = dkim_session_new(reqid)) == NULL)
-			return;
-		session->token = token;
-	} else if (session->token != token)
-		errx(1, "Token incorrect");
-	if (session->err)
+	if (message->err)
 		return;
 
 	linelen = strlen(line);
-	if (fprintf(session->origf, "%s\n", line) < linelen)
-		dkim_err(session, "Couldn't write to tempfile");
+	if (fprintf(message->origf, "%s\n", line) < (int) linelen)
+		dkim_err(message, "Couldn't write to tempfile");
 
 	if (line[0] == '.' && line[1] =='\0') {
-		dkim_sign(session);
-	} else if (linelen !=  0 && session->parsing_headers) {
+		dkim_sign(ctx);
+	} else if (linelen !=  0 && message->parsing_headers) {
 		if (line[0] == '.')
 			line++;
-		dkim_parse_header(session, line, 0);
-	} else if (linelen == 0 && session->parsing_headers) {
-		if (addheaders > 0 && !dkim_signature_printf(session, "; "))
+		if ((linedup = strdup(line)) == NULL)
+			osmtpd_err(1, "strdup");
+		dkim_parse_header(message, linedup, 0);
+		free(linedup);
+	} else if (linelen == 0 && message->parsing_headers) {
+		if (addheaders > 0 && !dkim_signature_printf(message, "; "))
 			return;
-		session->parsing_headers = 0;
+		message->parsing_headers = 0;
 	} else {
 		if (line[0] == '.')
 			line++;
-		dkim_parse_body(session, line);
+		if ((linedup = strdup(line)) == NULL)
+			osmtpd_err(1, "strdup");
+		dkim_parse_body(message, linedup);
+		free(linedup);
 	}
 }
 
 void
-dkim_commit(char *type, int version, struct timespec *tm, char *direction,
-    char *phase, uint64_t reqid, uint64_t token)
+dkim_commit(struct osmtpd_ctx *ctx)
 {
-	struct dkim_session *session, search;
+	struct dkim_message *message = ctx->local_message;
 
-	search.reqid = reqid;
-	if ((session = RB_FIND(dkim_sessions, &dkim_sessions, &search)) == NULL)
-		errx(1, "Commit on undefined session");
-
-	if (session->err)
-		smtp_filter_disconnect(session->reqid, session->token,
-		    "Internal server error");
+	if (message->err)
+		osmtpd_filter_disconnect(ctx, "Internal server error");
 	else
-		smtp_filter_proceed(reqid, token);
-
-	dkim_session_free(session);
+		osmtpd_filter_proceed(ctx);
 }
 
-struct dkim_session *
-dkim_session_new(uint64_t reqid)
+void *
+dkim_message_new(struct osmtpd_ctx *ctx)
 {
-	struct dkim_session *session;
-	struct dkim_signature *signature;
+	struct dkim_message *message;
 
-	if ((session = calloc(1, sizeof(*session))) == NULL)
-		err(1, NULL);
+	if ((message = calloc(1, sizeof(*message))) == NULL)
+		osmtpd_err(1, NULL);
 
-	session->reqid = reqid;
-	if ((session->origf = tmpfile()) == NULL) {
-		dkim_err(session, "Can't open tempfile");
+	if ((message->origf = tmpfile()) == NULL) {
+		dkim_err(message, "Can't open tempfile");
 		return NULL;
 	}
-	session->parsing_headers = 1;
+	message->parsing_headers = 1;
 
-	session->body_whitelines = 0;
-	session->headers = calloc(1, sizeof(*(session->headers)));
-	if (session->headers == NULL) {
-		dkim_err(session, "Can't save headers");
+	message->body_whitelines = 0;
+	message->headers = calloc(1, sizeof(*(message->headers)));
+	if (message->headers == NULL) {
+		dkim_err(message, "Can't save headers");
 		return NULL;
 	}
-	session->lastheader = 0;
-	session->signature.signature = NULL;
-	session->signature.size = 0;
-	session->signature.len = 0;
-	session->err = 0;
+	message->lastheader = 0;
+	message->signature.signature = NULL;
+	message->signature.size = 0;
+	message->signature.len = 0;
+	message->err = 0;
 
-	if (!dkim_signature_printf(session,
+	if (!dkim_signature_printf(message,
 	    "DKIM-signature: v=%s; a=%s-%s; c=%s/%s; d=%s; s=%s; ", "1",
 	    cryptalg, hashalg,
 	    canonheader == CANON_SIMPLE ? "simple" : "relaxed",
 	    canonbody == CANON_SIMPLE ? "simple" : "relaxed",
 	    domain, selector))
 		return NULL;
-	if (addheaders > 0 && !dkim_signature_printf(session, "z="))
+	if (addheaders > 0 && !dkim_signature_printf(message, "z="))
 		return NULL;
 
-	if ((session->b = EVP_MD_CTX_new()) == NULL ||
-	    (session->bh = EVP_MD_CTX_new()) == NULL) {
-		dkim_errx(session, "Can't create hash context");
+	if ((message->b = EVP_MD_CTX_new()) == NULL ||
+	    (message->bh = EVP_MD_CTX_new()) == NULL) {
+		dkim_errx(message, "Can't create hash context");
 		return NULL;
 	}
-	if (EVP_DigestSignInit(session->b, NULL, hash_md, NULL, pkey) <= 0 ||
-	    EVP_DigestInit_ex(session->bh, hash_md, NULL) == 0) {
-		dkim_errx(session, "Failed to initialize hash context");
+	if (EVP_DigestSignInit(message->b, NULL, hash_md, NULL, pkey) <= 0 ||
+	    EVP_DigestInit_ex(message->bh, hash_md, NULL) == 0) {
+		dkim_errx(message, "Failed to initialize hash context");
 		return NULL;
 	}
-	if (RB_INSERT(dkim_sessions, &dkim_sessions, session) != NULL)
-		errx(1, "session already registered");
-	return session;
+	return message;
 }
 
 void
-dkim_session_free(struct dkim_session *session)
+dkim_message_free(struct osmtpd_ctx *ctx, void *data)
 {
+	struct dkim_message *message = data;
 	size_t i;
 
-	RB_REMOVE(dkim_sessions, &dkim_sessions, session);
-	fclose(session->origf);
-	EVP_MD_CTX_free(session->b);
-	EVP_MD_CTX_free(session->bh);
-	free(session->signature.signature);
-	for (i = 0; session->headers[i] != NULL; i++)
-		free(session->headers[i]);
-	free(session->headers);
-	free(session);
+	fclose(message->origf);
+	EVP_MD_CTX_free(message->b);
+	EVP_MD_CTX_free(message->bh);
+	free(message->signature.signature);
+	for (i = 0; message->headers[i] != NULL; i++)
+		free(message->headers[i]);
+	free(message->headers);
+	free(message);
 }
 
-int
-dkim_session_cmp(struct dkim_session *s1, struct dkim_session *s2)
-{
-	return (s1->reqid < s2->reqid ? -1 : s1->reqid > s2->reqid);
-}
-
 void
 dkim_headers_set(char *headers)
 {
@@ -379,21 +325,21 @@ dkim_headers_set(char *headers)
 	for (i = 0; headers[i] != '\0'; i++) {
 		/* RFC 5322 field-name */
 		if (!(headers[i] >= 33 && headers[i] <= 126))
-			errx(1, "-h: invalid character");
+			osmtpd_errx(1, "-h: invalid character");
 		if (headers[i] == ':') {
 			/* Test for empty headers */
 			if (i == 0 || headers[i - 1] == ':')
-				errx(1, "-h: header can't be empty");
+				osmtpd_errx(1, "-h: header can't be empty");
 			nsign_headers++;
 		}
 		headers[i] = tolower(headers[i]);
 	}
 	if (headers[i - 1] == ':')
-		errx(1, "-h: header can't be empty");
+		osmtpd_errx(1, "-h: header can't be empty");
 
-	sign_headers = reallocarray(NULL, nsign_headers + 1, sizeof(*sign_headers));
-	if (sign_headers == NULL)
-		errx(1, NULL);
+	if ((sign_headers = reallocarray(NULL, nsign_headers + 1,
+	    sizeof(*sign_headers))) == NULL)
+		osmtpd_errx(1, NULL);
 
 	for (i = 0; i < nsign_headers; i++) {
 		sign_headers[i] = headers;
@@ -405,25 +351,25 @@ dkim_headers_set(char *headers)
 			has_from = 1;
 	}
 	if (!has_from)
-		errx(1, "From header must be included");
+		osmtpd_errx(1, "From header must be included");
 }
 
 void
-dkim_err(struct dkim_session *session, char *msg)
+dkim_err(struct dkim_message *message, char *msg)
 {
-	session->err = 1;
-	warn("%s", msg);
+	message->err = 1;
+	fprintf(stderr, "%s\n", msg);
 }
 
 void
-dkim_errx(struct dkim_session *session, char *msg)
+dkim_errx(struct dkim_message *message, char *msg)
 {
-	session->err = 1;
-	warnx("%s", msg);
+	message->err = 1;
+	fprintf(stderr, "%s\n", msg);
 }
 
 void
-dkim_parse_header(struct dkim_session *session, char *line, int force)
+dkim_parse_header(struct dkim_message *message, char *line, int force)
 {
 	size_t i;
 	size_t r, w;
@@ -436,13 +382,13 @@ dkim_parse_header(struct dkim_session *session, char *
 	char *tmp;
 
 	if (addheaders == 2 && !force &&
-	    !dkim_signature_printheader(session, line))
+	    !dkim_signature_printheader(message, line))
 		return;
 
-	if ((line[0] == ' ' || line[0] == '\t') && !session->lastheader)
+	if ((line[0] == ' ' || line[0] == '\t') && !message->lastheader)
 		return;
 	if ((line[0] != ' ' && line[0] != '\t')) {
-		session->lastheader = 0;
+		message->lastheader = 0;
 		for (i = 0; i < nsign_headers; i++) {
 			hlen = strlen(sign_headers[i]);
 			if  (strncasecmp(line, sign_headers[i], hlen) == 0) {
@@ -458,11 +404,11 @@ dkim_parse_header(struct dkim_session *session, char *
 	}
 
 	if (addheaders == 1 && !force &&
-	    !dkim_signature_printheader(session, line))
+	    !dkim_signature_printheader(message, line))
 		return;
 
 	if (canonheader == CANON_RELAXED) {
-		if (!session->lastheader)
+		if (!message->lastheader)
 			fieldname = 1;
 		for (r = w = 0; line[r] != '\0'; r++) {
 			if (line[r] == ':' && fieldname) {
@@ -493,48 +439,48 @@ dkim_parse_header(struct dkim_session *session, char *
 	} else
 		linelen = strlen(line);
 
-	for (lastheader = 0; session->headers[lastheader] != NULL; lastheader++)
+	for (lastheader = 0; message->headers[lastheader] != NULL; lastheader++)
 		continue;
-	if (!session->lastheader) {
-		mtmp = recallocarray(session->headers, lastheader + 1,
+	if (!message->lastheader) {
+		mtmp = recallocarray(message->headers, lastheader + 1,
 		    lastheader + 2, sizeof(*mtmp));
 		if (mtmp == NULL) {
-			dkim_err(session, "Can't store header");
+			dkim_err(message, "Can't store header");
 			return;
 		}
-		session->headers = mtmp;
-		
-		session->headers[lastheader] = strdup(line);
-		session->headers[lastheader + 1 ] = NULL;
-		session->lastheader = 1;
+		message->headers = mtmp;
+
+		message->headers[lastheader] = strdup(line);
+		message->headers[lastheader + 1 ] = NULL;
+		message->lastheader = 1;
 	} else {
 		lastheader--;
-		linelen += strlen(session->headers[lastheader]);
+		linelen += strlen(message->headers[lastheader]);
 		if (canonheader == CANON_SIMPLE)
 			linelen += 2;
 		linelen++;
-		htmp = reallocarray(session->headers[lastheader], linelen,
+		htmp = reallocarray(message->headers[lastheader], linelen,
 		    sizeof(*htmp));
 		if (htmp == NULL) {
-			dkim_err(session, "Can't store header");
+			dkim_err(message, "Can't store header");
 			return;
 		}
-		session->headers[lastheader] = htmp;
+		message->headers[lastheader] = htmp;
 		if (canonheader == CANON_SIMPLE) {
 			if (strlcat(htmp, "\r\n", linelen) >= linelen)
-				errx(1, "Missized header");
+				osmtpd_errx(1, "Missized header");
 		} else if (canonheader == CANON_RELAXED &&
-		    (tmp = strchr(session->headers[lastheader], ':')) != NULL &&
+		    (tmp = strchr(message->headers[lastheader], ':')) != NULL &&
 		    tmp[1] == '\0')
 			line++;
 
 		if (strlcat(htmp, line, linelen) >= linelen)
-			errx(1, "Missized header");
+			osmtpd_errx(1, "Missized header");
 	}
 }
 
 void
-dkim_parse_body(struct dkim_session *session, char *line)
+dkim_parse_body(struct dkim_message *message, char *line)
 {
 	size_t r, w;
 	size_t linelen;
@@ -555,145 +501,143 @@ dkim_parse_body(struct dkim_session *session, char *li
 		linelen = strlen(line);
 
 	if (line[0] == '\0') {
-		session->body_whitelines++;
+		message->body_whitelines++;
 		return;
 	}
 
-	while (session->body_whitelines--) {
-		if (EVP_DigestUpdate(session->bh, "\r\n", 2) == 0) {
-			dkim_err(session, "Can't update hash context");
+	while (message->body_whitelines--) {
+		if (EVP_DigestUpdate(message->bh, "\r\n", 2) == 0) {
+			dkim_err(message, "Can't update hash context");
 			return;
 		}
 	}
-	session->body_whitelines = 0;
-	session->has_body = 1;
+	message->body_whitelines = 0;
+	message->has_body = 1;
 
-	if (EVP_DigestUpdate(session->bh, line, linelen) == 0 ||
-	    EVP_DigestUpdate(session->bh, "\r\n", 2) == 0) {
-		dkim_err(session, "Can't update hash context");
+	if (EVP_DigestUpdate(message->bh, line, linelen) == 0 ||
+	    EVP_DigestUpdate(message->bh, "\r\n", 2) == 0) {
+		dkim_err(message, "Can't update hash context");
 		return;
 	}
 }
 
 void
-dkim_sign(struct dkim_session *session)
+dkim_sign(struct osmtpd_ctx *ctx)
 {
+	struct dkim_message *message = ctx->local_message;
 	/* Use largest hash size here */
 	char bbh[EVP_MAX_MD_SIZE];
 	char bh[(((sizeof(bbh) + 2) / 3) * 4) + 1];
 	char *b;
 	time_t now;
-	ssize_t i, j;
+	ssize_t i;
 	size_t linelen;
 	char *tmp, *tmp2;
-	char tmpchar;
 
 	if (addtime || addexpire)
 		now = time(NULL);
-	if (addtime && !dkim_signature_printf(session, "t=%lld; ", now))
+	if (addtime && !dkim_signature_printf(message, "t=%lld; ", now))
 		return;
-	if (addexpire != 0 && !dkim_signature_printf(session, "x=%lld; ",
+	if (addexpire != 0 && !dkim_signature_printf(message, "x=%lld; ",
 	    now + addexpire < now ? INT64_MAX : now + addexpire))
 		return;
 
-	if (canonbody == CANON_SIMPLE && !session->has_body) {
-		if (EVP_DigestUpdate(session->bh, "\r\n", 2) <= 0) {
-			dkim_err(session, "Can't update hash context");
+	if (canonbody == CANON_SIMPLE && !message->has_body) {
+		if (EVP_DigestUpdate(message->bh, "\r\n", 2) <= 0) {
+			dkim_err(message, "Can't update hash context");
 			return;
 		}
 	}
-	if (EVP_DigestFinal_ex(session->bh, bbh, NULL) == 0) {
-		dkim_err(session, "Can't finalize hash context");
+	if (EVP_DigestFinal_ex(message->bh, bbh, NULL) == 0) {
+		dkim_err(message, "Can't finalize hash context");
 		return;
 	}
-	EVP_EncodeBlock(bh, bbh, EVP_MD_CTX_size(session->bh));
-	if (!dkim_signature_printf(session, "bh=%s; h=", bh))
+	EVP_EncodeBlock(bh, bbh, EVP_MD_CTX_size(message->bh));
+	if (!dkim_signature_printf(message, "bh=%s; h=", bh))
 		return;
 	/* Reverse order for ease of use of RFC6367 section 5.4.2 */
-	for (i = 0; session->headers[i] != NULL; i++)
+	for (i = 0; message->headers[i] != NULL; i++)
 		continue;
 	for (i--; i >= 0; i--) {
-		if (EVP_DigestSignUpdate(session->b,
-		    session->headers[i],
-		    strlen(session->headers[i])) <= 0 ||
-		    EVP_DigestSignUpdate(session->b, "\r\n", 2) <= 0) {
-			dkim_errx(session, "Failed to update digest context");
+		if (EVP_DigestSignUpdate(message->b,
+		    message->headers[i],
+		    strlen(message->headers[i])) <= 0 ||
+		    EVP_DigestSignUpdate(message->b, "\r\n", 2) <= 0) {
+			dkim_errx(message, "Failed to update digest context");
 			return;
 		}
 		/* We're done with the cached header after hashing */
-		for (tmp = session->headers[i]; tmp[0] != ':'; tmp++) {
+		for (tmp = message->headers[i]; tmp[0] != ':'; tmp++) {
 			if (tmp[0] == ' ' || tmp[0] == '\t')
 				break;
 			tmp[0] = tolower(tmp[0]);
 		}
 		tmp[0] = '\0';
-		if (!dkim_signature_printf(session, "%s%s",
-		    session->headers[i + 1] == NULL  ? "" : ":",
-		    session->headers[i]))
+		if (!dkim_signature_printf(message, "%s%s",
+		    message->headers[i + 1] == NULL  ? "" : ":",
+		    message->headers[i]))
 			return;
-		tmp[0] = tmpchar;
 	}
-	dkim_signature_printf(session, "; b=");
-	if (!dkim_signature_normalize(session))
+	dkim_signature_printf(message, "; b=");
+	if (!dkim_signature_normalize(message))
 		return;
-	if ((tmp = strdup(session->signature.signature)) == NULL) {
-		dkim_err(session, "Can't create DKIM signature");
+	if ((tmp = strdup(message->signature.signature)) == NULL) {
+		dkim_err(message, "Can't create DKIM signature");
 		return;
 	}
-	dkim_parse_header(session, tmp, 1);
-	if (EVP_DigestSignUpdate(session->b, tmp, strlen(tmp)) <= 0) {
-		dkim_err(session, "Failed to update digest context");
+	dkim_parse_header(message, tmp, 1);
+	if (EVP_DigestSignUpdate(message->b, tmp, strlen(tmp)) <= 0) {
+		dkim_err(message, "Failed to update digest context");
 		return;
 	}
 	free(tmp);
-	if (EVP_DigestSignFinal(session->b, NULL, &linelen) <= 0) {
-		dkim_err(session, "Failed to finalize digest");
+	if (EVP_DigestSignFinal(message->b, NULL, &linelen) <= 0) {
+		dkim_err(message, "Failed to finalize digest");
 		return;
 	}
 	if ((tmp = malloc(linelen)) == NULL) {
-		dkim_err(session, "Can't allocate space for digest");
+		dkim_err(message, "Can't allocate space for digest");
 		return;
 	}
-	if (EVP_DigestSignFinal(session->b, tmp, &linelen) <= 0) {
-		dkim_err(session, "Failed to finalize digest");
+	if (EVP_DigestSignFinal(message->b, tmp, &linelen) <= 0) {
+		dkim_err(message, "Failed to finalize digest");
 		return;
 	}
 	if ((b = malloc((((linelen + 2) / 3) * 4) + 1)) == NULL) {
-		dkim_err(session, "Can't create DKIM signature");
+		dkim_err(message, "Can't create DKIM signature");
 		return;
 	}
 	EVP_EncodeBlock(b, tmp, linelen);
 	free(tmp);
-	dkim_signature_printf(session, "%s\r\n", b);
+	dkim_signature_printf(message, "%s\r\n", b);
 	free(b);
-	dkim_signature_normalize(session);
-	tmp = session->signature.signature;
+	dkim_signature_normalize(message);
+	tmp = message->signature.signature;
 	while ((tmp2 = strchr(tmp, '\r')) != NULL) {
 		tmp2[0] = '\0';
-		smtp_filter_dataline(session->reqid, session->token,
-		    "%s", tmp);
+		osmtpd_filter_dataline(ctx, "%s", tmp);
 		tmp = tmp2 + 2;
 	}
 	tmp = NULL;
 	linelen = 0;
-	rewind(session->origf);
-	while ((i = getline(&tmp, &linelen, session->origf)) != -1) {
+	rewind(message->origf);
+	while ((i = getline(&tmp, &linelen, message->origf)) != -1) {
 		tmp[i - 1] = '\0';
-		smtp_filter_dataline(session->reqid, session->token, "%s", tmp);
+		osmtpd_filter_dataline(ctx, "%s", tmp);
 	}
 }
 
 int
-dkim_signature_normalize(struct dkim_session *session)
+dkim_signature_normalize(struct dkim_message *message)
 {
 	size_t i;
 	size_t linelen;
 	size_t checkpoint;
 	size_t skip;
-	size_t *headerlen = &(session->signature.len);
+	size_t *headerlen = &(message->signature.len);
 	int headername = 1;
 	char tag = '\0';
-	char *sig = session->signature.signature;
+	char *sig = message->signature.signature;
 
 	for (linelen = i = 0; sig[i] != '\0'; i++) {
 		if (sig[i] == '\r' && sig[i + 1] == '\n') {
@@ -719,11 +663,11 @@ dkim_signature_normalize(struct dkim_session *session)
 			    skip++)
 				continue;
 			skip -= checkpoint + 1;
-			if (!dkim_signature_need(session,
+			if (!dkim_signature_need(message,
 			    skip > 3 ? 0 : 3 - skip + 1))
 				return 0;
-			sig = session->signature.signature;
-			
+			sig = message->signature.signature;
+
 			memmove(sig + checkpoint + 3,
 			    sig + checkpoint + skip,
 			    *headerlen - skip - checkpoint + 1);
@@ -765,7 +709,7 @@ dkim_signature_normalize(struct dkim_session *session)
 }
 
 int
-dkim_signature_printheader(struct dkim_session *session, char *header)
+dkim_signature_printheader(struct dkim_message *message, const char *header)
 {
 	size_t i, j, len;
 	static char *fmtheader = NULL;
@@ -776,24 +720,24 @@ dkim_signature_printheader(struct dkim_session *sessio
 	len = strlen(header);
 	if ((len + 3) * 3 < len) {
 		errno = EOVERFLOW;
-		dkim_err(session, "Can't add z-component to header");
+		dkim_err(message, "Can't add z-component to header");
 		return 0;
 	}
 	if ((len + 3) * 3 > size) {
 		if ((tmp = reallocarray(fmtheader, 3, len + 3)) == NULL) {
-			dkim_err(session, "Can't add z-component to header");
+			dkim_err(message, "Can't add z-component to header");
 			return 0;
 		}
 		fmtheader = tmp;
 		size = (len + 1) * 3;
 	}
 
-	first = session->signature.signature[session->signature.len - 1] == '=';
+	first = message->signature.signature[message->signature.len - 1] == '=';
 	for (j = i = 0; header[i] != '\0'; i++, j++) {
 		if (i == 0 && header[i] != ' ' && header[i] != '\t' && !first)
 			fmtheader[j++] = '|';
 		if ((header[i] >= 0x21 && header[i] <= 0x3A) ||
-		     header[i] == 0x3C ||
+		    (header[i] == 0x3C) ||
 		    (header[i] >= 0x3E && header[i] <= 0x7B) ||
 		    (header[i] >= 0x7D && header[i] <= 0x7E))
 			fmtheader[j] = header[i];
@@ -806,28 +750,26 @@ dkim_signature_printheader(struct dkim_session *sessio
 	(void) sprintf(fmtheader + j, "=%02hhX=%02hhX", (unsigned char) '\r',
 	    (unsigned char) '\n');
 
-	return dkim_signature_printf(session, "%s", fmtheader);
+	return dkim_signature_printf(message, "%s", fmtheader);
 }
 
 int
-dkim_signature_printf(struct dkim_session *session, char *fmt, ...)
+dkim_signature_printf(struct dkim_message *message, char *fmt, ...)
 {
-	struct dkim_signature *sig = &(session->signature);
+	struct dkim_signature *sig = &(message->signature);
 	va_list ap;
-	size_t newlen;
-	char *tmp;
 	size_t len;
 
 	va_start(ap, fmt);
 	if ((len = vsnprintf(sig->signature + sig->len, sig->size - sig->len,
 	    fmt, ap)) >= sig->size - sig->len) {
 		va_end(ap);
-		if (!dkim_signature_need(session, len + 1))
+		if (!dkim_signature_need(message, len + 1))
 			return 0;
 		va_start(ap, fmt);
-		if ((len = vsnprintf(sig->signature + sig->len, sig->size - sig->len,
-		    fmt, ap)) >= sig->size - sig->len)
-			errx(1, "Miscalculated header size");
+		if ((len = vsnprintf(sig->signature + sig->len,
+		    sig->size - sig->len, fmt, ap)) >= sig->size - sig->len)
+			osmtpd_errx(1, "Miscalculated header size");
 	}
 	sig->len += len;
 	va_end(ap);
@@ -835,16 +777,16 @@ dkim_signature_printf(struct dkim_session *session, ch
 }
 
 int
-dkim_signature_need(struct dkim_session *session, size_t len)
+dkim_signature_need(struct dkim_message *message, size_t len)
 {
-	struct dkim_signature *sig = &(session->signature);
+	struct dkim_signature *sig = &(message->signature);
 	char *tmp;
 
 	if (sig->len + len < sig->size)
 		return 1;
 	sig->size = (((len + sig->len) / 512) + 1) * 512;
 	if ((tmp = realloc(sig->signature, sig->size)) == NULL) {
-		dkim_err(session, "No room for signature");
+		dkim_err(message, "No room for signature");
 		return 0;
 	}
 	sig->signature = tmp;
@@ -854,9 +796,8 @@ dkim_signature_need(struct dkim_session *session, size
 __dead void
 usage(void)
 {
-	fprintf(stderr, "usage: %s [-a signalg] [-c canonicalization] [-h headerfields] -d domain -k keyfile "
-	    "-s selector\n", getprogname());
+	fprintf(stderr, "usage: filter-dkim [-tz] [-a signalg] "
+	    "[-c canonicalization] [-h headerfields]\n    "
+	    "[-x seconds] -d domain -k keyfile -s selector\n");
 	exit(1);
 }
-
-RB_GENERATE(dkim_sessions, dkim_session, entry, dkim_session_cmp);
blob - e6708b1ce7cb46802b1c4c47df2df0f9dc92c4a7 (mode 644)
blob + /dev/null
--- smtp_proc.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (c) 2019 Martijn van Duren <martijn@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/time.h>
-#include <sys/socket.h>
-
-#include <arpa/inet.h>
-#include <err.h>
-#include <errno.h>
-#include <event.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "smtp_proc.h"
-
-#define NITEMS(x) (sizeof(x) / sizeof(*x))
-
-struct smtp_callback;
-struct smtp_request;
-
-extern struct event_base *current_base;
-
-static int smtp_register(char *, char *, char *, void *);
-static ssize_t smtp_getline(char ** restrict, size_t * restrict);
-static void smtp_newline(int, short, void *);
-static void smtp_connect(struct smtp_callback *, int, struct timespec *,
-    uint64_t, uint64_t, char *);
-static void smtp_noargs(struct smtp_callback *, int, struct timespec *,
-    uint64_t, uint64_t, char *);
-static void smtp_dataline(struct smtp_callback *, int, struct timespec *,
-    uint64_t, uint64_t, char *);
-static void smtp_in_link_disconnect(struct smtp_callback *, int, struct timespec *,
-    uint64_t, char *);
-static void smtp_printf(const char *, ...)
-	__attribute__((__format__ (printf, 1, 2)));
-static void smtp_vprintf(const char *, va_list);
-static void smtp_write(int, short, void *);
-
-struct smtp_writebuf {
-	char *buf;
-	size_t bufsize;
-	size_t buflen;
-};
-
-struct smtp_callback {
-	char *type;
-	char *phase;
-	char *direction;
-	union {
-		void (*smtp_filter)(struct smtp_callback *, int,
-		    struct timespec *, uint64_t, uint64_t, char *);
-		void (*smtp_report)(struct smtp_callback *, int,
-		    struct timespec *, uint64_t, char *);
-	};
-	void *cb;
-} smtp_callbacks[] = {
-        {"filter", "connect", "smtp-in", .smtp_filter = smtp_connect, NULL},
-        {"filter", "data", "smtp-in", .smtp_filter = smtp_noargs, NULL},
-        {"filter", "data-line", "smtp-in", .smtp_filter = smtp_dataline, NULL},
-        {"filter", "commit", "smtp-in", .smtp_filter = smtp_noargs, NULL},
-	{"report", "link-disconnect", "smtp-in",
-	    .smtp_report = smtp_in_link_disconnect, NULL}
-};
-
-static int ready = 0;
-
-int
-smtp_register_filter_connect(void (*cb)(char *, int, struct timespec *, char *,
-    char *, uint64_t, uint64_t, char *, struct inx_addr *))
-{
-	return smtp_register("filter", "connect", "smtp-in", (void *)cb);
-}
-
-int
-smtp_register_filter_data(void (*cb)(char *, int, struct timespec *, char *,
-    char *, uint64_t, uint64_t))
-{
-	return smtp_register("filter", "data", "smtp-in", (void *)cb);
-}
-
-int
-smtp_register_filter_dataline(void (*cb)(char *, int, struct timespec *, char *,
-    char *, uint64_t, uint64_t, char *))
-{
-	return smtp_register("filter", "data-line", "smtp-in", (void *)cb);
-}
-
-int
-smtp_register_filter_commit(void (*cb)(char *, int, struct timespec *, char *,
-    char *, uint64_t, uint64_t))
-{
-	return smtp_register("filter", "commit", "smtp-in", (void *)cb);
-}
-
-int
-smtp_in_register_report_disconnect(void (*cb)(char *, int, struct timespec *,
-    char *, char *, uint64_t))
-{
-	return smtp_register("report", "link-disconnect", "smtp-in", (void *)cb);
-}
-
-void
-smtp_run(int debug)
-{
-	struct event stdinev;
-
-	smtp_printf("register|ready\n");
-	ready = 1;
-
-	event_set(&stdinev, STDIN_FILENO, EV_READ | EV_PERSIST, smtp_newline,
-	    &stdinev);
-	event_add(&stdinev, NULL);
-
-	if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1)
-		err(1, "fcntl");
-	event_dispatch();
-}
-
-static ssize_t
-smtp_getline(char ** restrict buf, size_t * restrict size)
-{
-	static char *rbuf = NULL;
-	static size_t rsoff = 0, reoff = 0;
-	static size_t rbsize = 0;
-	char *sep;
-	size_t sepoff;
-	ssize_t strlen, nread;
-
-	do {
-		if (rsoff != reoff) {
-			if ((sep = memchr(rbuf + rsoff, '\n', reoff - rsoff))
-			    != NULL) {
-				sepoff = sep - rbuf;
-				if (*buf == NULL)
-					*size = 0;
-				if (*size < (sepoff - rsoff + 1)) {
-					*size = sepoff - rsoff + 1;
-					*buf = realloc(*buf, sepoff - rsoff + 1);
-					if (*buf == NULL)
-						err(1, NULL);
-				}
-				sep[0] = '\0';
-				strlen = strlcpy(*buf, rbuf + rsoff, *size);
-				if (strlen >= *size)
-					errx(1, "copy buffer too small");
-				rsoff = sepoff + 1;
-				return strlen;
-			}
-		}
-		/* If we can't fill at the end, move everything back. */
-		if (rbsize - reoff < 1500 && rsoff != 0) {
-			memmove(rbuf, rbuf + rsoff, reoff - rsoff);
-			reoff -= rsoff;
-			rsoff = 0;
-		}
-		/* If we still can't fill alloc some new memory. */
-		if (rbsize - reoff < 1500) {
-			if ((rbuf = realloc(rbuf, rbsize + 4096)) == NULL)
-				err(1, NULL);
-			rbsize += 4096;
-		}
-		nread = read(STDIN_FILENO, rbuf + reoff, rbsize - reoff);
-		if (nread <= 0)
-			return nread;
-		reoff += nread;
-	} while (1);
-}
-
-static void
-smtp_newline(int fd, short event, void *arg)
-{
-	struct event *stdinev = (struct event *)arg;
-	static char *line = NULL, *linedup = NULL;
-	static size_t linesize = 0;
-	static size_t dupsize = 0;
-	ssize_t linelen;
-	char *start, *end, *type, *direction, *phase, *params;
-	int version;
-	struct timespec tm;
-	uint64_t reqid, token;
-	int i;
-
-	while ((linelen = smtp_getline(&line, &linesize)) > 0) {
-		if (dupsize < linesize) {
-			if ((linedup = realloc(linedup, linesize)) == NULL)
-				err(1, NULL);
-			dupsize = linesize;
-		}
-		strlcpy(linedup, line, dupsize);
-		type = line;
-		if ((start = strchr(type, '|')) == NULL)
-			errx(1, "Invalid line received: missing version: %s", linedup);
-		start++[0] = '\0';
-		if ((end = strchr(start, '|')) == NULL)
-			errx(1, "Invalid line received: missing time: %s", linedup);
-		end++[0] = '\0';
-		if (strcmp(start, "1") != 0)
-			errx(1, "Unsupported protocol received: %s: %s", start, linedup);
-		version = 1;
-		start = end;
-		if ((direction = strchr(start, '|')) == NULL)
-			errx(1, "Invalid line received: missing direction: %s", linedup);
-		direction++[0] = '\0';
-		tm.tv_sec = (time_t) strtoull(start, &end, 10);
-		tm.tv_nsec = 0;
-		if (start[0] == '\0' || (end[0] != '\0' && end[0] != '.'))
-			errx(1, "Invalid line received: invalid timestamp: %s", linedup);
-		if (end[0] == '.') {
-			start = end + 1;
-			tm.tv_nsec = strtol(start, &end, 10);
-			if (start[0] == '\0' || end[0] != '\0')
-				errx(1, "Invalid line received: invalid "
-				    "timestamp: %s", linedup);
-			for (i = 9 - (end - start); i > 0; i--)
-				tm.tv_nsec *= 10;
-		}
-		if ((phase = strchr(direction, '|')) == NULL)
-			errx(1, "Invalid line receieved: missing phase: %s", linedup);
-		phase++[0] = '\0';
-		if ((start = strchr(phase, '|')) == NULL)
-			errx(1, "Invalid line received: missing reqid: %s", linedup);
-		start++[0] = '\0';
-		reqid = strtoull(start, &params, 16);
-		if (start[0] == '|' || (params[0] != '|' & params[0] != '\0'))
-			errx(1, "Invalid line received: invalid reqid: %s", linedup);
-		params++;
-
-		for (i = 0; i < NITEMS(smtp_callbacks); i++) {
-			if (strcmp(type, smtp_callbacks[i].type) == 0 &&
-			    strcmp(phase, smtp_callbacks[i].phase) == 0 &&
-			    strcmp(direction, smtp_callbacks[i].direction) == 0)
-				break;
-		}
-		if (i == NITEMS(smtp_callbacks)) {
-			errx(1, "Invalid line received: received unregistered "
-			    "%s: %s: %s", type, phase, linedup);
-		}
-		if (strcmp(type, "filter") == 0) {
-			start = params;
-			token = strtoull(start, &params, 16);
-			if (start[0] == '|' || params[0] != '|')
-				errx(1, "Invalid line received: invalid token: %s", linedup);
-			params++;
-			smtp_callbacks[i].smtp_filter(&(smtp_callbacks[i]),
-			    version, &tm, reqid, token, params);
-		} else
-			smtp_callbacks[i].smtp_report(&(smtp_callbacks[i]),
-			    version, &tm, reqid, params);
-	}
-	if (linelen == 0 || errno != EAGAIN)
-		event_del(stdinev);
-}
-
-static void
-smtp_connect(struct smtp_callback *cb, int version, struct timespec *tm,
-    uint64_t reqid, uint64_t token, char *params)
-{
-	struct inx_addr addrx;
-	char *hostname;
-	char *address;
-	int ret;
-	void (*f)(char *, int, struct timespec *,char *, char *, uint64_t,
-	    uint64_t, char *, struct inx_addr *);
-
-	hostname = params;
-	if ((address = strchr(params, '|')) == NULL)
-		errx(1, "Invalid line received: missing address: %s", params);
-	address++[0] = '\0';
-
-	addrx.af = AF_INET;
-	if (strncasecmp(address, "ipv6:", 5) == 0) {
-		addrx.af = AF_INET6;
-		address += 5;
-	}
-
-	ret = inet_pton(addrx.af, address, addrx.af == AF_INET ?
-	    (void *)&(addrx.addr) : (void *)&(addrx.addr6));
-	if (ret == 0)
-		errx(1, "Invalid line received: Couldn't parse address: %s", params);
-	if (ret == -1)
-		err(1, "Couldn't convert address: %s", params);
-
-	f = cb->cb;
-	f(cb->type, version, tm, cb->direction, cb->phase, reqid, token,
-	    hostname, &addrx);
-}
-
-static void
-smtp_noargs(struct smtp_callback *cb, int version, struct timespec *tm,
-    uint64_t reqid, uint64_t token, char *params)
-{
-	void (*f)(char *, int, struct timespec *, char *, char *, uint64_t,
-	    uint64_t);
-
-	f = cb->cb;
-	f(cb->type, version, tm, cb->direction, cb->phase, reqid, token);
-}
-
-static void
-smtp_dataline(struct smtp_callback *cb, int version, struct timespec *tm,
-    uint64_t reqid, uint64_t token, char *line)
-{
-	void (*f)(char *, int, struct timespec *, char *, char *, uint64_t,
-	    uint64_t, char *);
-
-	f = cb->cb;
-	f(cb->type, version, tm, cb->direction, cb->phase, reqid, token,
-	    line);
-}
-
-static void
-smtp_in_link_disconnect(struct smtp_callback *cb, int version,
-    struct timespec *tm, uint64_t reqid, char *params)
-{
-	void (*f)(char *, int, struct timespec *, char *, char *, uint64_t);
-
-	f = cb->cb;
-	f(cb->type, version, tm, cb->direction, cb->phase, reqid);
-}
-
-void
-smtp_filter_proceed(uint64_t reqid, uint64_t token)
-{
-	smtp_printf("filter-result|%016"PRIx64"|%016"PRIx64"|proceed\n", token,
-	    reqid);
-}
-
-static void
-smtp_printf(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	smtp_vprintf(fmt, ap);
-	va_end(ap);
-}
-
-static void
-smtp_vprintf(const char *fmt, va_list ap)
-{
-	va_list cap;
-	static struct smtp_writebuf buf = {NULL, 0, 0};
-	int fmtlen;
-
-	va_copy(cap, ap);
-	fmtlen = vsnprintf(buf.buf + buf.buflen, buf.bufsize - buf.buflen, fmt,
-	    ap);
-	if (fmtlen == -1)
-		err(1, "vsnprintf");
-	if (fmtlen >= buf.bufsize - buf.buflen) {
-		buf.bufsize = buf.buflen + fmtlen + 1;
-		buf.buf = reallocarray(buf.buf, buf.bufsize,
-		    sizeof(*(buf.buf)));
-		if (buf.buf == NULL)
-			err(1, NULL);
-		fmtlen = vsnprintf(buf.buf + buf.buflen,
-		    buf.bufsize - buf.buflen, fmt, cap);
-		if (fmtlen == -1)
-			err(1, "vsnprintf");
-	}
-	va_end(cap);
-	buf.buflen += fmtlen;
-
-	if (strchr(buf.buf, '\n') != NULL)
-		smtp_write(STDOUT_FILENO, EV_WRITE, &buf);
-}
-
-static void
-smtp_write(int fd, short event, void *arg)
-{
-	struct smtp_writebuf *buf = arg;
-	static struct event stdoutev;
-	static int evset = 0;
-	ssize_t wlen;
-
-	if (buf->buflen == 0)
-		return;
-	if (!evset) {
-		event_set(&stdoutev, fd, EV_WRITE, smtp_write, buf);
-		evset = 1;
-	}
-	wlen = write(fd, buf->buf, buf->buflen);
-	if (wlen == -1) {
-		if (errno != EAGAIN && errno != EINTR)
-			err(1, "Failed to write to smtpd");
-		event_add(&stdoutev, NULL);
-		return;
-	}
-	if (wlen < buf->buflen) {
-		memmove(buf->buf, buf->buf + wlen, buf->buflen - wlen);
-		event_add(&stdoutev, NULL);
-	}
-	buf->buflen -= wlen;
-	if (buf->buflen == 0 && event_pending(&stdoutev, EV_WRITE, NULL))
-		event_del(&stdoutev);
-}
-
-void
-smtp_filter_reject(uint64_t reqid, uint64_t token, int code,
-    const char *reason, ...)
-{
-	va_list ap;
-
-	if (code < 200 || code > 599)
-		errx(1, "Invalid reject code");
-
-	smtp_printf("filter-result|%016"PRIx64"|%016"PRIx64"|reject|%d ", token,
-	    reqid, code);
-	va_start(ap, reason);
-	smtp_vprintf(reason, ap);
-	va_end(ap);
-	smtp_printf("\n");
-}
-
-void
-smtp_filter_disconnect(uint64_t reqid, uint64_t token, const char *reason, ...)
-{
-	va_list ap;
-
-	smtp_printf("filter-result|%016"PRIx64"|%016"PRIx64"|disconnect|421 ",
-	    token, reqid);
-	va_start(ap, reason);
-	smtp_vprintf(reason, ap);
-	va_end(ap);
-	smtp_printf("\n");
-}
-
-void
-smtp_filter_dataline(uint64_t reqid, uint64_t token, const char *line, ...)
-{
-	va_list ap;
-
-	smtp_printf("filter-dataline|%016"PRIx64"|%016"PRIx64"|", token, reqid);
-	va_start(ap, line);
-	smtp_vprintf(line, ap);
-	va_end(ap);
-	smtp_printf("\n");
-}
-
-static int
-smtp_register(char *type, char *phase, char *direction, void *cb)
-{
-	int i;
-	static int evinit = 0;
-
-	if (ready)
-		errx(1, "Can't register when proc is running");
-
-	if (!evinit) {
-		event_init();
-		evinit = 1;
-	}
-
-	for (i = 0; i < NITEMS(smtp_callbacks); i++) {
-		if (strcmp(type, smtp_callbacks[i].type) == 0 &&
-		    strcmp(phase, smtp_callbacks[i].phase) == 0 &&
-		    strcmp(direction, smtp_callbacks[i].direction) == 0) {
-			if (smtp_callbacks[i].cb != NULL) {
-				errno = EALREADY;
-				return -1;
-			}
-			smtp_callbacks[i].cb = cb;
-			smtp_printf("register|%s|%s|%s\n", type, direction,
-			    phase);
-			return 0;
-		}
-	}
-	errno = EINVAL;
-	return -1;
-}
blob - ca27bcad53dea8412d4a2739f4b25ef203fe4d4f (mode 644)
blob + /dev/null
--- smtp_proc.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2019 Martijn van Duren <martijn@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 <netinet/in.h>
-
-#include <netinet/in.h>
-
-struct inx_addr {
-	int af;
-	union {
-		struct in_addr addr;
-		struct in6_addr addr6;
-	};
-};
-
-int smtp_register_filter_connect(void (*)(char *, int, struct timespec *,
-    char *, char *, uint64_t, uint64_t, char *, struct inx_addr *));
-int smtp_register_filter_data(void (*)(char *, int, struct timespec *, char *,
-    char *, uint64_t, uint64_t));
-int smtp_register_filter_dataline(void (*)(char *, int, struct timespec *, char *,
-    char *, uint64_t, uint64_t, char *));
-int smtp_register_filter_commit(void (*)(char *, int, struct timespec *, char *,
-    char *, uint64_t, uint64_t));
-int smtp_in_register_report_disconnect(void (*)(char *, int, struct timespec *,
-    char *, char *, uint64_t));
-void smtp_filter_proceed(uint64_t, uint64_t);
-void smtp_filter_reject(uint64_t, uint64_t, int, const char *, ...)
-	__attribute__((__format__ (printf, 4, 5)));
-void smtp_filter_disconnect(uint64_t, uint64_t, const char *, ...)
-	__attribute__((__format__ (printf, 3, 4)));
-void smtp_filter_dataline(uint64_t, uint64_t, const char *, ...)
-	__attribute__((__format__ (printf, 3, 4)));
-void smtp_run(int);