commit - 02090eee90037052ff7d8ba498d53d511600a60d
commit + 5468729e9a83aa7ec3136730765fdf855273f6f4
blob - 660a13669fd91ed4caf6f7b39c21d586ca4aa7c6
blob + d5d63b0a08909047713afd8a3992034535934660
--- main.c
+++ main.c
struct dnsbl_session {
uint64_t reqid;
uint64_t token;
+ int listed;
struct dnsbl_query *query;
RB_ENTRY(dnsbl_session) entry;
};
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 *);
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,
err(1, NULL);
nblacklists++;
break;
+ case 'm':
+ markspam = 1;
+ break;
default:
usage();
}
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();
err(1, NULL);
session->reqid = reqid;
session->token = token;
+ session->listed = -1;
RB_INSERT(dnsbl_sessions, &dnsbl_sessions, session);
if (xaddr->af == AF_INET)
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) {
}
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);
}