commit 5468729e9a83aa7ec3136730765fdf855273f6f4 from: Martijn van Duren date: Fri Mar 29 09:46:14 2019 UTC Add -m flag, which only marks the mail as spam, but still passes it through commit - 02090eee90037052ff7d8ba498d53d511600a60d commit + 5468729e9a83aa7ec3136730765fdf855273f6f4 blob - 660a13669fd91ed4caf6f7b39c21d586ca4aa7c6 blob + d5d63b0a08909047713afd8a3992034535934660 --- main.c +++ main.c @@ -28,6 +28,7 @@ struct dnsbl_query { struct dnsbl_session { uint64_t reqid; uint64_t token; + int listed; struct dnsbl_query *query; RB_ENTRY(dnsbl_session) entry; }; @@ -37,13 +38,17 @@ RB_PROTOTYPE(dnsbl_sessions, dnsbl_session, entry, dns static char **blacklists = NULL; static size_t nblacklists = 0; +static int markspam = 0; void usage(void); void dnsbl_connect(char *, int, struct timespec *, char *, char *, uint64_t, uint64_t, char *, struct inx_addr *); +void dnsbl_dataline(char *, int, struct timespec *, char *, char *, uint64_t, + uint64_t, char *); void dnsbl_disconnect(char *, int, struct timespec *, char *, char *, uint64_t); void dnsbl_resolve(struct asr_result *, void *); void dnsbl_timeout(int, short, void *); +void dnsbl_session_query_done(struct dnsbl_session *); void dnsbl_session_free(struct dnsbl_session *); int dnsbl_session_cmp(struct dnsbl_session *, struct dnsbl_session *); @@ -62,7 +67,7 @@ main(int argc, char *argv[]) if (pledge("stdio dns", NULL) == -1) err(1, "pledge"); - while ((ch = getopt(argc, argv, "b:f:r:")) != -1) { + while ((ch = getopt(argc, argv, "b:m")) != -1) { switch (ch) { case 'b': blacklists = reallocarray(blacklists, nblacklists + 1, @@ -73,6 +78,9 @@ main(int argc, char *argv[]) err(1, NULL); nblacklists++; break; + case 'm': + markspam = 1; + break; default: usage(); } @@ -82,6 +90,7 @@ main(int argc, char *argv[]) errx(1, "No blacklist specified"); smtp_register_filter_connect(dnsbl_connect); + smtp_register_filter_dataline(dnsbl_dataline); smtp_in_register_report_disconnect(dnsbl_disconnect); smtp_run(); @@ -106,6 +115,7 @@ dnsbl_connect(char *type, int version, struct timespec err(1, NULL); session->reqid = reqid; session->token = token; + session->listed = -1; RB_INSERT(dnsbl_sessions, &dnsbl_sessions, session); if (xaddr->af == AF_INET) @@ -167,9 +177,15 @@ dnsbl_resolve(struct asr_result *result, void *arg) query->query = NULL; evtimer_del(&(query->timeout)); if (result->ar_hostent != NULL) { - smtp_filter_disconnect(session->reqid, session->token, - "Host listed at %s", blacklists[query->blacklist]); - dnsbl_session_free(session); + if (!markspam) { + smtp_filter_disconnect(session->reqid, session->token, + "Host listed at %s", blacklists[query->blacklist]); + dnsbl_session_free(session); + } else { + dnsbl_session_query_done(session); + session->listed = query->blacklist; + smtp_filter_proceed(session->reqid, session->token); + } return; } if (result->ar_h_errno != HOST_NOT_FOUND) { @@ -210,17 +226,41 @@ dnsbl_disconnect(char *type, int version, struct times } void -dnsbl_session_free(struct dnsbl_session *session) +dnsbl_dataline(char *type, int version, struct timespec *tm, char *direction, + char *phase, uint64_t reqid, uint64_t token, char *line) { + struct dnsbl_session *session, search; + + search.reqid = reqid; + session = RB_FIND(dnsbl_sessions, &dnsbl_sessions, &search); + + if (session->listed != -1) { + smtp_filter_dataline(reqid, token, "X-Spam: yes"); + smtp_filter_dataline(reqid, token, "X-Spam-DNSBL: Listed at %s", + blacklists[session->listed]); + session->listed = -1; + } + smtp_filter_dataline(reqid, token, "%s", line); +} + +void +dnsbl_session_query_done(struct dnsbl_session *session) +{ int i; - RB_REMOVE(dnsbl_sessions, &dnsbl_sessions, session); for (i = 0; i < nblacklists; i++) { if (!session->query[i].resolved) { event_asr_abort(session->query[i].event); evtimer_del(&(session->query[i].timeout)); } } +} + +void +dnsbl_session_free(struct dnsbl_session *session) +{ + RB_REMOVE(dnsbl_sessions, &dnsbl_sessions, session); + dnsbl_session_query_done(session); free(session->query); free(session); }