commit - 43613b9ec24600ac3faa951256f3bb6b2ee4e261
commit + 2d73ea73b1a5ad46925c2c9ec38b4ba984b6c2db
blob - 7bae5abbdcb0556f822c31364031109be9f2c88a
blob + 98ffc1487d67e4c65090f149a46d103b5b2801c9
--- Makefile
+++ Makefile
LOCALBASE?= /usr/local/
-PROG= filter-dkimverify
-MAN= filter-dkimverify.8
+PROG= filter-auth
+MAN= filter-auth.8
BINDIR= ${LOCALBASE}/libexec/smtpd/
MANDIR= ${LOCALBASE}/man/man
blob - b49771b61776484246483a4eb8e34bf5287f2f58 (mode 644)
blob + /dev/null
--- filter-dkimverify.8
+++ /dev/null
-.\" $OpenBSD$
-.\"
-.\" 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.
-.\"
-.Dd $Mdocdate$
-.Dt FILTER-DKIMVERIFY 8
-.Os
-.Sh NAME
-.Nm filter-dkimverify
-.Nd verifies dkim signature of messages
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-.Nm
-verifies the dkim signatures of messages and adds an Authentication-Results
-header to the message.
-.Sh SEE ALSO
-.Xr filter-admdscrub 8
-.Xr filter-dkimsign 8
-.Xr smtpd 8
blob - /dev/null
blob + e032c9d28e7f4b33bfa138564c4c8e1f9af047bb (mode 644)
--- /dev/null
+++ filter-auth.8
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2024 Kirill A. Korinsky <kirill@korins.ky>>
+.\" 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.
+.\"
+.Dd $Mdocdate$
+.Dt FILTER-AUTH 8
+.Os
+.Sh NAME
+.Nm filter-auth
+.Nd authenticate email via verification of dkim signature
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm
+verifies the dkim signatures of messages and adds an Authentication-Results
+header to the message.
+.Sh SEE ALSO
+.Xr filter-admdscrub 8
+.Xr filter-dkimsign 8
+.Xr smtpd 8
blob - 9bf3a4b3cdc1fbc115cdffe68a5a06f64d7d2c3e
blob + 783c649bf34969be621d58a681bbf239da82c7cb
--- main.c
+++ main.c
* Use RFC8601 (Authentication-Results) codes instead of RFC6376 codes,
* since they're more expressive.
*/
-enum state {
+enum dkim_state {
DKIM_UNKNOWN,
DKIM_PASS,
DKIM_FAIL,
DKIM_PERMERROR
};
-struct signature {
+struct dkim_signature {
struct header *header;
- enum state state;
+ enum dkim_state state;
const char *state_reason;
int v;
const char *a;
uint8_t parsed;
char *buf;
size_t buflen;
- struct signature *sig;
+ struct dkim_signature *sig;
};
#define AUTHENTICATION_RESULTS_LINELEN 78
};
void usage(void);
-void dkim_conf(const char *, const char *);
-void dkim_dataline(struct osmtpd_ctx *, const char *);
-void *dkim_message_new(struct osmtpd_ctx *);
-void dkim_message_free(struct osmtpd_ctx *, void *);
+void auth_conf(const char *, const char *);
+void auth_dataline(struct osmtpd_ctx *, const char *);
+void *auth_message_new(struct osmtpd_ctx *);
+void auth_message_free(struct osmtpd_ctx *, void *);
void dkim_header_add(struct osmtpd_ctx *, const char *);
void dkim_signature_parse(struct header *);
-void dkim_signature_parse_v(struct signature *, const char *, const char *);
-void dkim_signature_parse_a(struct signature *, const char *, const char *);
-void dkim_signature_parse_b(struct signature *, const char *, const char *);
-void dkim_signature_parse_bh(struct signature *, const char *, const char *);
-void dkim_signature_parse_c(struct signature *, const char *, const char *);
-void dkim_signature_parse_d(struct signature *, const char *, const char *);
-void dkim_signature_parse_h(struct signature *, const char *, const char *);
-void dkim_signature_parse_i(struct signature *, const char *, const char *);
-void dkim_signature_parse_l(struct signature *, const char *, const char *);
-void dkim_signature_parse_q(struct signature *, const char *, const char *);
-void dkim_signature_parse_s(struct signature *, const char *, const char *);
-void dkim_signature_parse_t(struct signature *, const char *, const char *);
-void dkim_signature_parse_x(struct signature *, const char *, const char *);
-void dkim_signature_parse_z(struct signature *, const char *, const char *);
-void dkim_lookup_record(struct signature *sig, const char *domain);
-void dkim_signature_verify(struct signature *);
-void dkim_signature_header(EVP_MD_CTX *, struct signature *, struct header *);
-void dkim_signature_state(struct signature *, enum state, const char *);
-const char *dkim_state2str(enum state);
+void dkim_signature_parse_v(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_a(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_b(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_bh(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_c(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_d(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_h(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_i(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_l(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_q(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_s(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_t(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_x(struct dkim_signature *, const char *, const char *);
+void dkim_signature_parse_z(struct dkim_signature *, const char *, const char *);
+void dkim_lookup_record(struct dkim_signature *sig, const char *domain);
+void dkim_signature_verify(struct dkim_signature *);
+void dkim_signature_header(EVP_MD_CTX *, struct dkim_signature *, struct header *);
+void dkim_signature_state(struct dkim_signature *, enum dkim_state, const char *);
+const char *dkim_state2str(enum dkim_state);
void dkim_header_cat(struct osmtpd_ctx *, const char *);
void dkim_body_parse(struct message *, const char *);
-void dkim_body_verify(struct signature *);
+void dkim_body_verify(struct dkim_signature *);
void dkim_rr_resolve(struct asr_result *, void *);
-void dkim_message_verify(struct message *);
-ssize_t dkim_ar_cat(char **ar, size_t *n, size_t aroff, const char *fmt, ...)
+void auth_message_verify(struct message *);
+ssize_t auth_ar_cat(char **ar, size_t *n, size_t aroff, const char *fmt, ...)
__attribute__((__format__ (printf, 4, 5)));
-int dkim_ar_print(struct osmtpd_ctx *, const char *);
-int dkim_key_text_parse(struct signature *, const char *);
+int auth_ar_print(struct osmtpd_ctx *, const char *);
+int dkim_key_text_parse(struct dkim_signature *, const char *);
char *authservid;
EVP_ENCODE_CTX *ectx = NULL;
if ((ectx = EVP_ENCODE_CTX_new()) == NULL)
osmtpd_err(1, "EVP_ENCODE_CTX_new");
- osmtpd_register_conf(dkim_conf);
- osmtpd_register_filter_dataline(dkim_dataline);
- osmtpd_local_message(dkim_message_new, dkim_message_free);
+ osmtpd_register_conf(auth_conf);
+ osmtpd_register_filter_dataline(auth_dataline);
+ osmtpd_local_message(auth_message_new, auth_message_free);
osmtpd_run();
return 0;
}
void
-dkim_conf(const char *key, const char *value)
+auth_conf(const char *key, const char *value)
{
const char *end;
}
void
-dkim_dataline(struct osmtpd_ctx *ctx, const char *line)
+auth_dataline(struct osmtpd_ctx *ctx, const char *line)
{
struct message *msg = ctx->local_message;
size_t i;
continue;
dkim_body_verify(msg->header[i].sig);
}
- dkim_message_verify(msg);
+ auth_message_verify(msg);
return;
}
}
}
void *
-dkim_message_new(struct osmtpd_ctx *ctx)
+auth_message_new(struct osmtpd_ctx *ctx)
{
struct message *msg;
}
void
-dkim_message_free(struct osmtpd_ctx *ctx, void *data)
+auth_message_free(struct osmtpd_ctx *ctx, void *data)
{
struct message *msg = data;
size_t i, j;
void
dkim_signature_parse(struct header *header)
{
- struct signature *sig;
+ struct dkim_signature *sig;
const char *buf, *i, *end;
char tagname[3];
char subdomain[HOST_NAME_MAX + 1];
}
void
-dkim_lookup_record(struct signature *sig, const char *domain)
+dkim_lookup_record(struct dkim_signature *sig, const char *domain)
{
struct asr_query *query;
}
void
-dkim_signature_parse_v(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_v(struct dkim_signature *sig, const char *start, const char *end)
{
if (sig->v != 0) { /* Duplicate tag */
dkim_signature_state(sig, DKIM_PERMERROR, "Duplicate v tag");
}
void
-dkim_signature_parse_a(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_a(struct dkim_signature *sig, const char *start, const char *end)
{
char ah[sizeof("sha256")];
}
void
-dkim_signature_parse_b(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_b(struct dkim_signature *sig, const char *start, const char *end)
{
int decodesz;
size_t i, j;
}
void
-dkim_signature_parse_bh(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_bh(struct dkim_signature *sig, const char *start, const char *end)
{
const char *b64;
size_t n;
}
void
-dkim_signature_parse_c(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_c(struct dkim_signature *sig, const char *start, const char *end)
{
if (sig->c != 0) {
dkim_signature_state(sig, DKIM_PERMERROR, "Duplicate c tag");
}
void
-dkim_signature_parse_d(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_d(struct dkim_signature *sig, const char *start, const char *end)
{
if (sig->d[0] != '\0') {
dkim_signature_state(sig, DKIM_PERMERROR, "Duplicate d tag");
}
void
-dkim_signature_parse_h(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_h(struct dkim_signature *sig, const char *start, const char *end)
{
const char *h;
size_t n = 0;
}
void
-dkim_signature_parse_i(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_i(struct dkim_signature *sig, const char *start, const char *end)
{
if (sig->i != NULL) {
dkim_signature_state(sig, DKIM_PERMERROR, "Duplicate i tag");
}
void
-dkim_signature_parse_l(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_l(struct dkim_signature *sig, const char *start, const char *end)
{
long long l;
char *lend;
}
void
-dkim_signature_parse_q(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_q(struct dkim_signature *sig, const char *start, const char *end)
{
const char *qend;
}
void
-dkim_signature_parse_s(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_s(struct dkim_signature *sig, const char *start, const char *end)
{
if (sig->s[0] != '\0') {
dkim_signature_state(sig, DKIM_PERMERROR, "Duplicate s tag");
}
void
-dkim_signature_parse_t(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_t(struct dkim_signature *sig, const char *start, const char *end)
{
char *tend;
}
void
-dkim_signature_parse_x(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_x(struct dkim_signature *sig, const char *start, const char *end)
{
char *xend;
}
void
-dkim_signature_parse_z(struct signature *sig, const char *start, const char *end)
+dkim_signature_parse_z(struct dkim_signature *sig, const char *start, const char *end)
{
if (sig->z != 0) {
dkim_signature_state(sig, DKIM_PERMERROR, "Duplicate z tag");
}
void
-dkim_signature_verify(struct signature *sig)
+dkim_signature_verify(struct dkim_signature *sig)
{
struct message *msg = sig->header->msg;
static EVP_MD_CTX *bctx = NULL;
EVP_DigestVerifyUpdate((a), (b), (c)))
void
-dkim_signature_header(EVP_MD_CTX *bctx, struct signature *sig,
+dkim_signature_header(EVP_MD_CTX *bctx, struct dkim_signature *sig,
struct header *header)
{
char c;
}
void
-dkim_signature_state(struct signature *sig, enum state state,
+dkim_signature_state(struct dkim_signature *sig, enum dkim_state state,
const char *reason)
{
if (sig->query != NULL) {
}
const char *
-dkim_state2str(enum state state)
+dkim_state2str(enum dkim_state state)
{
switch (state)
{
void
dkim_rr_resolve(struct asr_result *ar, void *arg)
{
- struct signature *sig = arg;
+ struct dkim_signature *sig = arg;
char key[UINT16_MAX + 1];
const char *rr_txt;
size_t keylen, cstrlen;
}
verify:
free(ar->ar_data);
- dkim_message_verify(sig->header->msg);
+ auth_message_verify(sig->header->msg);
}
int
-dkim_key_text_parse(struct signature *sig, const char *key)
+dkim_key_text_parse(struct dkim_signature *sig, const char *key)
{
char tagname, *hashname;
const char *end, *tagvend;
void
dkim_body_parse(struct message *msg, const char *line)
{
- struct signature *sig;
+ struct dkim_signature *sig;
const char *end = line, *hash, *prev;
size_t hashn, len, i;
int wsp, ret;
}
void
-dkim_body_verify(struct signature *sig)
+dkim_body_verify(struct dkim_signature *sig)
{
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int digestsz;
}
void
-dkim_message_verify(struct message *msg)
+auth_message_verify(struct message *msg)
{
- struct signature *sig;
+ struct dkim_signature *sig;
size_t i;
ssize_t n, aroff = 0;
int found = 0;
dkim_signature_state(msg->header[i].sig, DKIM_PASS, NULL);
}
- if ((aroff = dkim_ar_cat(&line, &linelen, aroff,
+ if ((aroff = auth_ar_cat(&line, &linelen, aroff,
"Authentication-Results: %s", authservid)) == -1)
osmtpd_err(1, "%s: malloc", __func__);
for (i = 0; i < msg->nheaders; i++) {
if (sig == NULL)
continue;
found = 1;
- if ((aroff = dkim_ar_cat(&line, &linelen, aroff, "; dkim=%s",
+ if ((aroff = auth_ar_cat(&line, &linelen, aroff, "; dkim=%s",
dkim_state2str(sig->state))) == -1)
osmtpd_err(1, "%s: malloc", __func__);
if (sig->state_reason != NULL) {
- if ((aroff = dkim_ar_cat(&line, &linelen, aroff,
+ if ((aroff = auth_ar_cat(&line, &linelen, aroff,
" reason=\"%s\"", sig->state_reason)) == -1)
osmtpd_err(1, "%s: malloc", __func__);
}
if (sig->s[0] != '\0') {
- if ((aroff = dkim_ar_cat(&line, &linelen, aroff,
+ if ((aroff = auth_ar_cat(&line, &linelen, aroff,
" header.s=%s", sig->s)) == -1)
osmtpd_err(1, "%s: malloc", __func__);
}
if (sig->d[0] != '\0') {
- if ((aroff = dkim_ar_cat(&line, &linelen, aroff,
+ if ((aroff = auth_ar_cat(&line, &linelen, aroff,
" header.d=%s", sig->d)) == -1)
osmtpd_err(1, "%s: malloc", __func__);
}
* which can contain FWS and CFWS.
*/
if (sig->a != NULL) {
- if ((aroff = dkim_ar_cat(&line, &linelen, aroff,
+ if ((aroff = auth_ar_cat(&line, &linelen, aroff,
" header.a=%.*s", (int)sig->asz, sig->a)) == -1)
osmtpd_err(1, "%s: malloc", __func__);
}
if (sig->bheaderclean[0] != '\0') {
- if ((aroff = dkim_ar_cat(&line, &linelen, aroff,
+ if ((aroff = auth_ar_cat(&line, &linelen, aroff,
" header.b=%s", sig->bheaderclean)) == -1)
osmtpd_err(1, "%s: malloc", __func__);
}
}
if (!found) {
- aroff = dkim_ar_cat(&line, &linelen, aroff, "; dkim=none");
+ aroff = auth_ar_cat(&line, &linelen, aroff, "; dkim=none");
if (aroff == -1)
osmtpd_err(1, "%s: malloc", __func__);
}
- if (dkim_ar_print(msg->ctx, line) != 0) {
+ if (auth_ar_print(msg->ctx, line) != 0) {
osmtpd_warnx(msg->ctx, "Mallformed AR header");
goto fail;
}
}
int
-dkim_ar_print(struct osmtpd_ctx *ctx, const char *start)
+auth_ar_print(struct osmtpd_ctx *ctx, const char *start)
{
const char *scan, *checkpoint, *ncheckpoint;
int arlen = 0, first = 1, arid = 1;
}
ssize_t
-dkim_ar_cat(char **ar, size_t *n, size_t aroff, const char *fmt, ...)
+auth_ar_cat(char **ar, size_t *n, size_t aroff, const char *fmt, ...)
{
va_list ap;
char *artmp;
__dead void
usage(void)
{
- fprintf(stderr, "usage: filter-dkimverify\n");
+ fprintf(stderr, "usage: filter-auth\n");
exit(1);
}