commit 57cbfccc70a86c36f9d4eb2a34af40008446f119 from: Martijn van Duren date: Wed Mar 27 11:39:48 2019 UTC New level of tweaking commit - ba153e30ab30865884e14f8d96ec0d3e7a633386 commit + 57cbfccc70a86c36f9d4eb2a34af40008446f119 blob - 4f77a04cf6f65653b40d1dcc2354aab472a27900 blob + b3485b1bfa8478c7739de10ae713686503cd2173 --- main.c +++ main.c @@ -13,7 +13,7 @@ static char **blacklists = NULL; static size_t nblacklists = 0; int retries = 0; -enum filter_decision onfailure = FILTER_PROCEED; +int reject_onfailure = 0; void usage(void); enum filter_decision dnsbl_connect(char *, int, time_t, char *, char *, @@ -46,16 +46,7 @@ main(int argc, char *argv[]) nblacklists++; break; case 'f': - if (strcasecmp(optarg, "proceed") == 0) - onfailure = FILTER_PROCEED; - else if (strcasecmp(optarg, "reject") == 0) - onfailure = FILTER_REJECT; - else if (strcasecmp(optarg, "disconnect") == 0) - onfailure = FILTER_DISCONNECT; - else if (strcasecmp(optarg, "rewrite") == 0) - onfailure = FILTER_REWRITE; - else - errx(1, "Invalid on failure case"); + reject_onfailure = 1; case 'r': if ((retries = strtonum(optarg, 0, 10, &errstr)) == 0 && errstr != NULL) @@ -83,7 +74,7 @@ dnsbl_connect(char *type, int version, time_t tm, char char reply[1500]; struct hostent *hent; u_char *addr; - int i; + int i, try; addr = (u_char *)&(params->addr); for (i = 0; i < nblacklists; i++) { @@ -117,17 +108,28 @@ dnsbl_connect(char *type, int version, time_t tm, char errx(1, "Can't create query, domain too long"); } else errx(1, "Invalid address family received"); - } - for (i = -1; i < retries; i++) { - if ((hent = gethostbyname(query)) == NULL) { - if (h_errno == HOST_NOT_FOUND) - return FILTER_PROCEED; - if (h_errno != TRY_AGAIN) - return onfailure; + for (try = -1; try < retries; try++) { + if ((hent = gethostbyname(query)) == NULL) { + if (h_errno == HOST_NOT_FOUND) + break; + if (h_errno != TRY_AGAIN) { + if (!reject_onfailure) + break; + else + smtp_filter_disconnect(reqid, + token, + "Blacklist check failed"); + return FILTER_DISCONNECT; + } + } else { + smtp_filter_disconnect(reqid, token, + "Listed at %s", blacklists[i]); + return FILTER_DISCONNECT; + } } } - return FILTER_REJECT; + return FILTER_PROCEED; } void blob - 468875bd2912e308bd8e68deb977ec893466a3c0 blob + 4000129f96cc995befbc2ff68e0ad978b7feb60b --- smtp_proc.c +++ smtp_proc.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ struct smtp_callback { }; static int ready = 0; +static int resolved = 1; int smtp_register_filter_connect(enum filter_decision (*cb)(char *, int, time_t, @@ -216,27 +218,80 @@ static void smtp_handle(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid, uint64_t token, void *params) { - int ret; + enum filter_decision fdes; - switch (cb->cb(cb->type, version, tm, cb->direction, cb->phase, reqid, - token, params)) { - case FILTER_PROCEED: - printf("filter-result|%016"PRIx64"|%016"PRIx64"|proceed\n", - token, reqid); - break; - case FILTER_REJECT: - printf("filter-result|%016"PRIx64"|%016"PRIx64"|reject|%s\n", - token, reqid, "451 Proper message later"); - break; - case FILTER_DISCONNECT: - printf("filter-result|%016"PRIx64"|%016"PRIx64"|disconnect|" - "%s\n", token, reqid, "421 Proper message later"); - break; - case FILTER_REWRITE: - errx(1, "Not sure what is intended here yet"); + if (!resolved) + errx(1, "Handling unexpected second request"); + resolved = 0; + fdes = cb->cb(cb->type, version, tm, cb->direction, cb->phase, reqid, + token, params); + if (!resolved) { + switch (fdes) { + case FILTER_PROCEED: + smtp_filter_proceed(reqid, token); + break; + case FILTER_REJECT: + smtp_filter_reject(reqid, token, 451, + "Rejected by filter"); + break; + case FILTER_DISCONNECT: + smtp_filter_disconnect(reqid, token, + "Rejected by filter"); + break; + case FILTER_REWRITE: + errx(1, "Not sure what is intended here yet"); + } } } +void +smtp_filter_proceed(uint64_t reqid, uint64_t token) +{ + if (resolved) + errx(1, "reqid: %016"PRIx64" token: %016"PRIx64" already " + "resolved", reqid, token); + printf("filter-result|%016"PRIx64"|%016"PRIx64"|proceed\n", token, reqid); + resolved = 1; +} + +void +smtp_filter_reject(uint64_t reqid, uint64_t token, int code, + const char *reason, ...) +{ + va_list ap; + + if (resolved) + errx(1, "reqid: %016"PRIx64" token: %016"PRIx64" already " + "resolved", reqid, token); + if (code < 200 || code > 599) + errx(1, "Invalid reject code"); + + printf("filter-result|%016"PRIx64"|%016"PRIx64"|reject|%d ", token, + reqid, code); + va_start(ap, reason); + vprintf(reason, ap); + va_end(ap); + putchar('\n'); + resolved = 1; +} + +void +smtp_filter_disconnect(uint64_t reqid, uint64_t token, const char *reason, ...) +{ + va_list ap; + + if (resolved) + errx(1, "reqid: %016"PRIx64" token: %016"PRIx64" already " + "resolved", reqid, token); + printf("filter-result|%016"PRIx64"|%016"PRIx64"|disconnect|421 ", + token, reqid); + va_start(ap, reason); + vprintf(reason, ap); + va_end(ap); + putchar('\n'); + resolved = 1; +} + static int smtp_register(char *type, char *phase, char *direction, smtp_cb cb) { blob - e190c1c0fa454eb54f08eb9c220e6d24132495f3 blob + 32f5edae76536f943271a670f009dbabaca1ed72 --- smtp_proc.h +++ smtp_proc.h @@ -18,4 +18,9 @@ enum filter_decision { int smtp_register_filter_connect(enum filter_decision (*cb)(char *, int, time_t, char *, char *, uint64_t, uint64_t, struct smtp_filter_connect *)); +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_run(void);