From b5c79dd713c2e444df9ba50b48718330ad936eb7 Mon Sep 17 00:00:00 2001 From: Florent Bruneau Date: Wed, 1 Oct 2008 00:16:59 +0200 Subject: [PATCH] Add greylist tests. Signed-off-by: Florent Bruneau --- postlicyd/data/greylist_q1 | 25 +++++++ postlicyd/data/greylist_q2 | 25 +++++++ postlicyd/data/greylist_q3 | 25 +++++++ postlicyd/data/test.conf | 15 ++++- postlicyd/greylist.c | 3 +- postlicyd/tst-filters.c | 130 +++++++++++++++++++++++++++++++------ 6 files changed, 201 insertions(+), 22 deletions(-) create mode 100644 postlicyd/data/greylist_q1 create mode 100644 postlicyd/data/greylist_q2 create mode 100644 postlicyd/data/greylist_q3 diff --git a/postlicyd/data/greylist_q1 b/postlicyd/data/greylist_q1 new file mode 100644 index 0000000..1925034 --- /dev/null +++ b/postlicyd/data/greylist_q1 @@ -0,0 +1,25 @@ +request=smtpd_access_policy +protocol_state=RCPT +protocol_name=SMTP +helo_name=some.domain.tld +queue_id=8045F2AB23 +sender=foo@bar.tld +recipient=bar@foo.tld +recipient_count=0 +client_address=1.2.3.4 +client_name=another.domain.tld +reverse_client_name=another.domain.tld +instance=123.456.7 +sasl_method=plain +sasl_username=you +sasl_sender= +size=12345 +ccert_subject=solaris9.porcupine.org +ccert_issuer=Wietse+20Venema +ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04 +encryption_protocol=TLSv1/SSLv3 +encryption_cipher=DHE-RSA-AES256-SHA +encryption_keysize=256 +etrn_domain= +stress= + diff --git a/postlicyd/data/greylist_q2 b/postlicyd/data/greylist_q2 new file mode 100644 index 0000000..46a45e7 --- /dev/null +++ b/postlicyd/data/greylist_q2 @@ -0,0 +1,25 @@ +request=smtpd_access_policy +protocol_state=RCPT +protocol_name=SMTP +helo_name=some.domain.tld +queue_id=8045F2AB23 +sender=foo2@bar.tld +recipient=bar2@foo.tld +recipient_count=0 +client_address=1.2.3.4 +client_name=another2.domain.tld +reverse_client_name=another2.domain.tld +instance=123.456.7 +sasl_method=plain +sasl_username=you +sasl_sender= +size=12345 +ccert_subject=solaris9.porcupine.org +ccert_issuer=Wietse+20Venema +ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04 +encryption_protocol=TLSv1/SSLv3 +encryption_cipher=DHE-RSA-AES256-SHA +encryption_keysize=256 +etrn_domain= +stress= + diff --git a/postlicyd/data/greylist_q3 b/postlicyd/data/greylist_q3 new file mode 100644 index 0000000..140ec18 --- /dev/null +++ b/postlicyd/data/greylist_q3 @@ -0,0 +1,25 @@ +request=smtpd_access_policy +protocol_state=RCPT +protocol_name=SMTP +helo_name=some.domain.tld +queue_id=8045F2AB23 +sender=foo@bar.tld +recipient=bar@foo.tld +recipient_count=0 +client_address=1.2.3.5 +client_name=another.domain.tld +reverse_client_name=another.domain.tld +instance=123.456.7 +sasl_method=plain +sasl_username=you +sasl_sender= +size=12345 +ccert_subject=solaris9.porcupine.org +ccert_issuer=Wietse+20Venema +ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04 +encryption_protocol=TLSv1/SSLv3 +encryption_cipher=DHE-RSA-AES256-SHA +encryption_keysize=256 +etrn_domain= +stress= + diff --git a/postlicyd/data/test.conf b/postlicyd/data/test.conf index 9825ce1..9901acc 100644 --- a/postlicyd/data/test.conf +++ b/postlicyd/data/test.conf @@ -3,7 +3,7 @@ match1 { match_all = false; condition = stress #=; - condtion = stress != yes; + condition = stress != yes; on_match = postfix:OK; on_fail = postfix:OK; } @@ -100,4 +100,17 @@ ips1 { on_soft_match = postfix:OK; } +greylist1 { + type = greylist; + + prefix = test1_; + path = data/; + delay = 1; + retry_window = 4; + client_awl = 2; + + on_greylist = postfix:OK; + on_whitelist = postfix:OK; +} + recipient_filter = match1; diff --git a/postlicyd/greylist.c b/postlicyd/greylist.c index 7d70875..e025045 100644 --- a/postlicyd/greylist.c +++ b/postlicyd/greylist.c @@ -209,7 +209,7 @@ static bool try_greylist(const greylist_config_t *config, /* Whitelist if count is enough. */ - if (aent.count > config->client_awl) { + if (aent.count >= config->client_awl) { if (now < aent.last + 3600) { INCR_AWL } @@ -311,6 +311,7 @@ static bool greylist_filter_constructor(filter_t *filter) FILTER_PARAM_PARSE_BOOLEAN(LOOKUP_BY_HOST, config->lookup_by_host); FILTER_PARAM_PARSE_INT(RETRY_WINDOW, config->retry_window); FILTER_PARAM_PARSE_INT(CLIENT_AWL, config->client_awl); + FILTER_PARAM_PARSE_INT(DELAY, config->delay); default: break; } diff --git a/postlicyd/tst-filters.c b/postlicyd/tst-filters.c index df17397..0c08f69 100644 --- a/postlicyd/tst-filters.c +++ b/postlicyd/tst-filters.c @@ -42,33 +42,49 @@ DECLARE_MAIN -static bool run_testcase(const config_t *config, const char *basepath, - const char *filename) +static char *read_query(const char *basepath, const char *filename, + char *buff, char **end, query_t *q) { - char buff[BUFSIZ]; char path[FILENAME_MAX]; - char *end; - snprintf(path, FILENAME_MAX, "%s%s", basepath, filename); { file_map_t map; if (!file_map_open(&map, path, false)) { - return false; + UNIXERR("open"); + return NULL; } if (map.end - map.map >= BUFSIZ) { syslog(LOG_ERR, "File too large for a testcase: %s", path); - return false; + file_map_close(&map); + return NULL; } memcpy(buff, map.map, map.end - map.map); - end = buff + (map.end - map.map); - *end = '\0'; + if (end != NULL) { + *end = buff + (map.end - map.map); + **end = '\0'; + } file_map_close(&map); } + char *eoq = strstr(buff, "\n\n"); + if (eoq == NULL) { + return NULL; + } + if (!query_parse(q, buff)) { + syslog(LOG_ERR, "Cannot parse query from file %s", filename); + return NULL; + } + return eoq + 2; +} + +static bool run_testcase(const config_t *config, const char *basepath, + const char *filename) +{ + char buff[BUFSIZ]; + char *end; query_t query; - const char *eol = strstr(buff, "\n\n") + 2; - if (!query_parse(&query, buff)) { - syslog(LOG_ERR, "Cannot parse query from file %s", path); + const char *eol = read_query(basepath, filename, buff, &end, &query); + if (eol == NULL) { return false; } @@ -102,14 +118,66 @@ static bool run_testcase(const config_t *config, const char *basepath, } filter_t *filter = array_ptr(config->filters, pos); - bool test = filter_test(filter, &query, result); - printf(" filter %s: %s\n", filter->name, test ? "SUCCESS" : "FAILED"); - ok = ok && test; +#define TEST(Name, Run) \ + do { \ + bool __test = (Run); \ + printf(" test %s: %s\n", Name, __test ? "SUCCESS" : "FAILED"); \ + ok = ok && __test; \ + } while (0) + TEST(filter->name, filter_test(filter, &query, result)); eol = neol + 1; } return ok; } +static bool run_greylisttest(const config_t *config, const char *basepath) +{ + char buff_q1[BUFSIZ]; + char buff_q2[BUFSIZ]; + char buff_q3[BUFSIZ]; + query_t q1; + query_t q2; + query_t q3; + bool ok = true; + + filter_t *greylist1; +// filter_t *greylist2; + +#define QUERY(Q) \ + printf("Reading greylist_" STR(Q) "\n"); \ + if (read_query(basepath, "greylist_" STR(Q), buff_##Q, NULL, &Q) == NULL) { \ + return false; \ + } + QUERY(q1); + QUERY(q2); + QUERY(q3); +#undef QUERY + +#define FILTER(F) \ + do { \ + int __p = filter_find_with_name(&config->filters, STR(F)); \ + if (__p < 0) { \ + return false; \ + } \ + F = array_ptr(config->filters, __p); \ + } while (0) + FILTER(greylist1); +// FILTER(greylist2); +#undef FILTER + + /* Test greylist */ + TEST("greylisted", filter_test(greylist1, &q1, HTK_GREYLIST)); + TEST("greylisted", filter_test(greylist1, &q1, HTK_GREYLIST)); + sleep(2); + TEST("whitelisted", filter_test(greylist1, &q1, HTK_WHITELIST)); + TEST("other_greylisted", filter_test(greylist1, &q2, HTK_GREYLIST)); + TEST("auto_whitelisted", filter_test(greylist1, &q1, HTK_WHITELIST)); + TEST("other_auto_whitelisted", filter_test(greylist1, &q2, HTK_WHITELIST)); + TEST("greylisted", filter_test(greylist1, &q3, HTK_GREYLIST)); + + return ok; +} + int main(int argc, char *argv[]) { char basepath[FILENAME_MAX]; @@ -122,8 +190,20 @@ int main(int argc, char *argv[]) } else { ++p; } - snprintf(basepath, FILENAME_MAX, "%.*sdata/", p - argv[0], argv[0]); + + /* Cleanup */ + { +#define RM(File) \ + snprintf(path, FILENAME_MAX, "%s/%s", basepath, File); \ + unlink(path); + RM("test1_greylist.db"); + RM("test1_whitelist.db"); + RM("test2_greylist.db"); + RM("test2_whitelist.db"); +#undef RM + } + snprintf(path, FILENAME_MAX, "%s/test.conf", basepath); config_t *config = config_read(path); @@ -131,21 +211,31 @@ int main(int argc, char *argv[]) return 1; } + +#define RUN(Name, Test, ...) \ + printf("Running %s:\n", Name); \ + printf("%s\n", run_##Test(config, basepath, ##__VA_ARGS__) ? "SUCCESS" \ + : "FAILED"); + + /* Test stateless filters */ DIR *dir = opendir(basepath); if (dir == NULL) { UNIXERR("opendir"); return 1; } - struct dirent *ent; while ((ent = readdir(dir)) != NULL) { if (strncmp("testcase_", ent->d_name, 9) == 0) { - printf("Running %s:\n", ent->d_name); - printf("%s\n", - run_testcase(config, basepath, ent->d_name) ? "SUCCESS" : "FAILED"); + RUN(ent->d_name, testcase, ent->d_name); } } closedir(dir); + /* Test greylist */ + RUN("greylist", greylisttest); + + +#undef RUN + config_delete(&config); return 0; } -- 2.20.1