comparison src/context.cpp @ 178:d6531c702be3

embedded dcc filtering
author carl
date Thu, 04 Oct 2007 22:45:21 -0700
parents e726e1a61ef9
children 7a722f482bfb
comparison
equal deleted inserted replaced
177:a4d313c2460b 178:d6531c702be3
21 21
22 static char* context_version="$Id$"; 22 static char* context_version="$Id$";
23 23
24 char *token_autowhite; 24 char *token_autowhite;
25 char *token_black; 25 char *token_black;
26 char *token_cctld;
26 char *token_content; 27 char *token_content;
27 char *token_context; 28 char *token_context;
29 char *token_dccbulk;
28 char *token_dccfrom; 30 char *token_dccfrom;
31 char *token_dccgrey;
29 char *token_dccto; 32 char *token_dccto;
30 char *token_default; 33 char *token_default;
31 char *token_dnsbl; 34 char *token_dnsbl;
32 char *token_dnsbll; 35 char *token_dnsbll;
33 char *token_envfrom; 36 char *token_envfrom;
41 char *token_include; 44 char *token_include;
42 char *token_inherit; 45 char *token_inherit;
43 char *token_lbrace; 46 char *token_lbrace;
44 char *token_mailhost; 47 char *token_mailhost;
45 char *token_many; 48 char *token_many;
49 char *token_no;
46 char *token_off; 50 char *token_off;
51 char *token_ok;
47 char *token_ok2; 52 char *token_ok2;
48 char *token_ok;
49 char *token_on; 53 char *token_on;
50 char *token_rate; 54 char *token_rate;
51 char *token_rbrace; 55 char *token_rbrace;
56 char *token_require;
52 char *token_semi; 57 char *token_semi;
53 char *token_soft; 58 char *token_soft;
54 char *token_spamassassin; 59 char *token_spamassassin;
55 char *token_substitute; 60 char *token_substitute;
56 char *token_tld; 61 char *token_tld;
57 char *token_cctld;
58 char *token_unknown; 62 char *token_unknown;
59 char *token_uribl; 63 char *token_uribl;
60 char *token_verify; 64 char *token_verify;
61 char *token_white; 65 char *token_white;
66 char *token_yes;
62 67
63 char *token_myhostname; 68 char *token_myhostname;
64 #ifndef HOST_NAME_MAX 69 #ifndef HOST_NAME_MAX
65 #define HOST_NAME_MAX 255 70 #define HOST_NAME_MAX 255
66 #endif 71 #endif
72 pthread_mutex_t whitelister_mutex; // protect the whitelisters map 77 pthread_mutex_t whitelister_mutex; // protect the whitelisters map
73 whitelister_map whitelisters; 78 whitelister_map whitelisters;
74 79
75 string_set all_strings; // owns all the strings, only modified by the config loader thread 80 string_set all_strings; // owns all the strings, only modified by the config loader thread
76 const int maxlen = 1000; // used for snprintf buffers 81 const int maxlen = 1000; // used for snprintf buffers
77 const int maxsmtp_age = 120;// smtp verify sockets older than this are ancient 82 const int maxsmtp_age = 60;// smtp verify sockets older than this are ancient
78 const int maxauto_age = 600;// auto whitelister delay before flushing to file 83 const int maxauto_age = 600;// auto whitelister delay before flushing to file
79 extern int NULL_SOCKET; 84 extern int NULL_SOCKET;
80 const time_t ERROR_SMTP_SOCKET_TIME = 600; // number of seconds between attempts to open a socket to an smtp server 85 const time_t ERROR_SMTP_SOCKET_TIME = 600; // number of seconds between attempts to open a socket to an smtp server
81 86
82 87
695 host_limit_message = NULL; 700 host_limit_message = NULL;
696 host_random = (parent) ? parent->host_random : false; 701 host_random = (parent) ? parent->host_random : false;
697 tag_limit = (parent) ? parent->tag_limit : 0; 702 tag_limit = (parent) ? parent->tag_limit : 0;
698 tag_limit_message = NULL; 703 tag_limit_message = NULL;
699 spamassassin_limit = (parent) ? parent->spamassassin_limit : 0; 704 spamassassin_limit = (parent) ? parent->spamassassin_limit : 0;
705 require_match = (parent) ? parent->require_match : false;
706 dcc_greylist = (parent) ? parent->dcc_greylist : false;
707 dcc_bulk_threshold = (parent) ? parent->dcc_bulk_threshold : 0;
700 default_rcpt_rate = INT_MAX; 708 default_rcpt_rate = INT_MAX;
701 } 709 }
702 710
703 711
704 CONTEXT::~CONTEXT() { 712 CONTEXT::~CONTEXT() {
915 if (dnsbl_list.empty() && parent) return parent->get_dnsbl_list(); 923 if (dnsbl_list.empty() && parent) return parent->get_dnsbl_list();
916 return dnsbl_list; 924 return dnsbl_list;
917 } 925 }
918 926
919 927
920 bool CONTEXT::acceptable_content(recorder &memory, int score, string& msg) { 928 bool CONTEXT::acceptable_content(recorder &memory, int score, int bulk, string& msg) {
921 if (spamassassin_limit && (score > spamassassin_limit)) { 929 if (spamassassin_limit && (score > spamassassin_limit)) {
922 char buf[maxlen]; 930 char buf[maxlen];
923 snprintf(buf, sizeof(buf), "Mail rejected - spam assassin score %d", score); 931 snprintf(buf, sizeof(buf), "Mail rejected - spam assassin score %d", score);
932 msg = string(buf);
933 return false;
934 }
935 if (dcc_bulk_threshold && (bulk > dcc_bulk_threshold)) {
936 char buf[maxlen];
937 snprintf(buf, sizeof(buf), "Mail rejected - dcc score %d", bulk);
924 msg = string(buf); 938 msg = string(buf);
925 return false; 939 return false;
926 } 940 }
927 if (memory.excessive_bad_tags(tag_limit)) { 941 if (memory.excessive_bad_tags(tag_limit)) {
928 msg = string(tag_limit_message); 942 msg = string(tag_limit_message);
1014 } 1028 }
1015 else { 1029 else {
1016 printf("%s html_limit off; \n", indent); 1030 printf("%s html_limit off; \n", indent);
1017 } 1031 }
1018 printf("%s spamassassin %d; \n", indent, spamassassin_limit); 1032 printf("%s spamassassin %d; \n", indent, spamassassin_limit);
1033 printf("%s require_match %s; \n", indent, (require_match) ? "yes" : "no");
1034 printf("%s dcc_greylist %s; \n", indent, (dcc_greylist) ? "yes" : "no");
1035 if (dcc_bulk_threshold == 0) printf("%s dcc_bulk_threshold off; \n", indent);
1036 else if (dcc_bulk_threshold == 1000) printf("%s dcc_bulk_threshold many; \n", indent);
1037 else printf("%s dcc_bulk_threshold %d; \n", indent, dcc_bulk_threshold);
1019 printf("%s }; \n", indent); 1038 printf("%s }; \n", indent);
1020 spamass |= (spamassassin_limit != 0); 1039 spamass |= (spamassassin_limit != 0);
1021 } 1040 }
1022 else { 1041 else {
1023 printf("%s content off {}; \n", indent, env_from_default); 1042 printf("%s content off {}; \n", indent, env_from_default);
1212 if (have == token_rbrace) break; // done 1231 if (have == token_rbrace) break; // done
1213 me.add_ignore(have); 1232 me.add_ignore(have);
1214 } 1233 }
1215 if (!tsa(tok, token_semi)) return false; 1234 if (!tsa(tok, token_semi)) return false;
1216 } 1235 }
1236 else if (have == token_tld) {
1237 if (!tsa(tok, token_lbrace)) return false;
1238 while (true) {
1239 char *have = tok.next();
1240 if (!have) break;
1241 if (have == token_rbrace) break; // done
1242 me.add_tld(have);
1243 }
1244 if (!tsa(tok, token_semi)) return false;
1245 }
1217 else if (have == token_cctld) { 1246 else if (have == token_cctld) {
1218 if (!tsa(tok, token_lbrace)) return false; 1247 if (!tsa(tok, token_lbrace)) return false;
1219 while (true) { 1248 while (true) {
1220 char *have = tok.next(); 1249 char *have = tok.next();
1221 if (!have) break; 1250 if (!have) break;
1222 if (have == token_rbrace) break; // done 1251 if (have == token_rbrace) break; // done
1223 me.add_cctld(have); 1252 me.add_cctld(have);
1224 } 1253 }
1225 if (!tsa(tok, token_semi)) return false; 1254 if (!tsa(tok, token_semi)) return false;
1226 } 1255 }
1227 else if (have == token_tld) {
1228 if (!tsa(tok, token_lbrace)) return false;
1229 while (true) {
1230 char *have = tok.next();
1231 if (!have) break;
1232 if (have == token_rbrace) break; // done
1233 me.add_tld(have);
1234 }
1235 if (!tsa(tok, token_semi)) return false;
1236 }
1237 else if (have == token_html_limit) {
1238 have = tok.next();
1239 if (have == token_on) {
1240 me.set_tag_limit(tok.nextint());
1241 me.set_tag_message(tok.next());
1242 }
1243 else if (have == token_off) {
1244 me.set_tag_limit(0);
1245 me.set_tag_message(NULL);
1246 }
1247 else {
1248 tok.token_error("on/off", have);
1249 return false;
1250 }
1251 if (!tsa(tok, token_semi)) return false;
1252 }
1253 else if (have == token_html_tags) { 1256 else if (have == token_html_tags) {
1254 if (!tsa(tok, token_lbrace)) return false; 1257 if (!tsa(tok, token_lbrace)) return false;
1255 while (true) { 1258 while (true) {
1256 char *have = tok.next(); 1259 char *have = tok.next();
1257 if (!have) break; 1260 if (!have) break;
1267 me.add_tag(register_string(buf)); // trailing / 1270 me.add_tag(register_string(buf)); // trailing /
1268 } 1271 }
1269 } 1272 }
1270 if (!tsa(tok, token_semi)) return false; 1273 if (!tsa(tok, token_semi)) return false;
1271 } 1274 }
1275 else if (have == token_html_limit) {
1276 have = tok.next();
1277 if (have == token_on) {
1278 me.set_tag_limit(tok.nextint());
1279 me.set_tag_message(tok.next());
1280 }
1281 else if (have == token_off) {
1282 me.set_tag_limit(0);
1283 me.set_tag_message(NULL);
1284 }
1285 else {
1286 tok.token_error("on/off", have);
1287 return false;
1288 }
1289 if (!tsa(tok, token_semi)) return false;
1290 }
1272 else if (have == token_host_limit) { 1291 else if (have == token_host_limit) {
1273 have = tok.next(); 1292 have = tok.next();
1274 if (have == token_on) { 1293 if (have == token_on) {
1275 me.set_host_limit(tok.nextint()); 1294 me.set_host_limit(tok.nextint());
1276 me.set_host_message(tok.next()); 1295 me.set_host_message(tok.next());
1292 } 1311 }
1293 if (!tsa(tok, token_semi)) return false; 1312 if (!tsa(tok, token_semi)) return false;
1294 } 1313 }
1295 else if (have == token_spamassassin) { 1314 else if (have == token_spamassassin) {
1296 me.set_spamassassin_limit(tok.nextint()); 1315 me.set_spamassassin_limit(tok.nextint());
1316 if (!tsa(tok, token_semi)) return false;
1317 }
1318 else if (have == token_require) {
1319 have = tok.next();
1320 if (have == token_yes) me.set_require(true);
1321 else if (have == token_no) me.set_require(false);
1322 else {
1323 tok.token_error("yes/no", have);
1324 return false;
1325 }
1326 if (!tsa(tok, token_semi)) return false;
1327 }
1328 else if (have == token_dccgrey) {
1329 have = tok.next();
1330 if (have == token_yes) me.set_grey(true);
1331 else if (have == token_no) me.set_grey(false);
1332 else {
1333 tok.token_error("yes/no", have);
1334 return false;
1335 }
1336 if (!tsa(tok, token_semi)) return false;
1337 }
1338 else if (have == token_dccbulk) {
1339 have = tok.next();
1340 if (have == token_off) me.set_bulk(0);
1341 else if (have == token_many) me.set_bulk(1000);
1342 else {
1343 char *e;
1344 long i = strtol(have, &e, 10);
1345 if (*e != '\0') {
1346 tok.token_error("integer", have);
1347 return false;
1348 }
1349 me.set_bulk((int)i);
1350 }
1297 if (!tsa(tok, token_semi)) return false; 1351 if (!tsa(tok, token_semi)) return false;
1298 } 1352 }
1299 else if (have == token_rbrace) { 1353 else if (have == token_rbrace) {
1300 break; // done 1354 break; // done
1301 } 1355 }
1600 1654
1601 //////////////////////////////////////////////// 1655 ////////////////////////////////////////////////
1602 // init the tokens 1656 // init the tokens
1603 // 1657 //
1604 void token_init() { 1658 void token_init() {
1605 token_autowhite = register_string("autowhite"); 1659 token_autowhite = register_string("autowhite");
1606 token_black = register_string("black"); 1660 token_black = register_string("black");
1607 token_cctld = register_string("cctld"); 1661 token_cctld = register_string("cctld");
1608 token_content = register_string("content"); 1662 token_content = register_string("content");
1609 token_context = register_string("context"); 1663 token_context = register_string("context");
1610 token_dccfrom = register_string("dcc_from"); 1664 token_dccbulk = register_string("dcc_bulk_threshold");
1611 token_dccto = register_string("dcc_to"); 1665 token_dccfrom = register_string("dcc_from");
1612 token_default = register_string("default"); 1666 token_dccgrey = register_string("dcc_greylist");
1613 token_dnsbl = register_string("dnsbl"); 1667 token_dccto = register_string("dcc_to");
1614 token_dnsbll = register_string("dnsbl_list"); 1668 token_default = register_string("default");
1615 token_envfrom = register_string("env_from"); 1669 token_dnsbl = register_string("dnsbl");
1616 token_envto = register_string("env_to"); 1670 token_dnsbll = register_string("dnsbl_list");
1617 token_filter = register_string("filter"); 1671 token_envfrom = register_string("env_from");
1618 token_generic = register_string("generic"); 1672 token_envto = register_string("env_to");
1619 token_host_limit = register_string("host_limit"); 1673 token_filter = register_string("filter");
1620 token_html_limit = register_string("html_limit"); 1674 token_generic = register_string("generic");
1621 token_html_tags = register_string("html_tags"); 1675 token_host_limit = register_string("host_limit");
1622 token_ignore = register_string("ignore"); 1676 token_html_limit = register_string("html_limit");
1623 token_include = register_string("include"); 1677 token_html_tags = register_string("html_tags");
1624 token_inherit = register_string("inherit"); 1678 token_ignore = register_string("ignore");
1625 token_lbrace = register_string("{"); 1679 token_include = register_string("include");
1626 token_mailhost = register_string("mail_host"); 1680 token_inherit = register_string("inherit");
1627 token_many = register_string("many"); 1681 token_lbrace = register_string("{");
1628 token_off = register_string("off"); 1682 token_mailhost = register_string("mail_host");
1629 token_ok = register_string("ok"); 1683 token_many = register_string("many");
1630 token_ok2 = register_string("ok2"); 1684 token_no = register_string("no");
1631 token_on = register_string("on"); 1685 token_off = register_string("off");
1632 token_rate = register_string("rate_limit"); 1686 token_ok = register_string("ok");
1633 token_rbrace = register_string("}"); 1687 token_ok2 = register_string("ok2");
1634 token_semi = register_string(";"); 1688 token_on = register_string("on");
1635 token_soft = register_string("soft"); 1689 token_rate = register_string("rate_limit");
1636 token_spamassassin = register_string("spamassassin"); 1690 token_rbrace = register_string("}");
1637 token_substitute = register_string("substitute"); 1691 token_require = register_string("require_match");
1638 token_tld = register_string("tld"); 1692 token_semi = register_string(";");
1639 token_unknown = register_string("unknown"); 1693 token_soft = register_string("soft");
1640 token_uribl = register_string("uribl"); 1694 token_spamassassin = register_string("spamassassin");
1641 token_verify = register_string("verify"); 1695 token_substitute = register_string("substitute");
1642 token_white = register_string("white"); 1696 token_tld = register_string("tld");
1697 token_unknown = register_string("unknown");
1698 token_uribl = register_string("uribl");
1699 token_verify = register_string("verify");
1700 token_white = register_string("white");
1701 token_yes = register_string("yes");
1643 1702
1644 if (gethostname(myhostname, HOST_NAME_MAX+1) != 0) { 1703 if (gethostname(myhostname, HOST_NAME_MAX+1) != 0) {
1645 strncpy(myhostname, "localhost", HOST_NAME_MAX+1); 1704 strncpy(myhostname, "localhost", HOST_NAME_MAX+1);
1646 } 1705 }
1647 myhostname[HOST_NAME_MAX] = '\0'; // ensure null termination 1706 myhostname[HOST_NAME_MAX] = '\0'; // ensure null termination