comparison src/context.cpp @ 322:9f8411f3919c

add dkim white/black listing
author Carl Byington <carl@five-ten-sg.com>
date Sat, 17 Dec 2016 17:04:52 -0800
parents e172dc10fe24
children b6f173ac5209
comparison
equal deleted inserted replaced
321:e172dc10fe24 322:9f8411f3919c
72 const char *token_dkim_signer; 72 const char *token_dkim_signer;
73 const char *token_dkim_from; 73 const char *token_dkim_from;
74 const char *token_signed_white; 74 const char *token_signed_white;
75 const char *token_signed_black; 75 const char *token_signed_black;
76 const char *token_require_signed; 76 const char *token_require_signed;
77
78 const char *token_myhostname; 77 const char *token_myhostname;
78
79 #ifndef HOST_NAME_MAX 79 #ifndef HOST_NAME_MAX
80 #define HOST_NAME_MAX 255 80 #define HOST_NAME_MAX 255
81 #endif 81 #endif
82 char myhostname[HOST_NAME_MAX+1]; 82 char myhostname[HOST_NAME_MAX+1];
83 83
1097 if (!dnswl_list_parsed && parent) return parent->get_dnswl_list(); 1097 if (!dnswl_list_parsed && parent) return parent->get_dnswl_list();
1098 return dnswl_list; 1098 return dnswl_list;
1099 } 1099 }
1100 1100
1101 1101
1102 bool CONTEXT::acceptable_content(recorder &memory, int score, int bulk, string& msg) { 1102 bool CONTEXT::acceptable_content(recorder &memory, int score, int bulk, const char *signer, const char *from, string& msg) {
1103 char buf[maxlen];
1104 snprintf(buf, sizeof(buf), "acceptable content from %s signer %s", (signer) ? signer : token_asterisk, (from) ? from : token_asterisk);
1105 my_syslog(buf);
1106
1107 const char *st = find_dkim_signer(signer);
1108 if (st == token_white) return true;
1109 if (st == token_black) {
1110 char buf[maxlen];
1111 snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", signer);
1112 msg = string(buf);
1113 return false;
1114 }
1115
1116 DKIMP dk = find_dkim_from(from);
1117 if (dk) {
1118 st = dk->action;
1119 // signed by a white listed signer
1120 if ((st == token_signed_white) && (strcasecmp(signer,dk->signer) == 0)) return true;
1121 // not signed by the required signer
1122 if ((st == token_require_signed) && (strcasecmp(signer,dk->signer) != 0)) {
1123 char buf[maxlen];
1124 snprintf(buf, sizeof(buf), "Mail rejected - not dkim signed by %s", dk->signer);
1125 msg = string(buf);
1126 return false;
1127 }
1128 // signed by a black listed signer
1129 if ((st == token_signed_black) && (strcasecmp(signer,dk->signer) == 0)) {
1130 char buf[maxlen];
1131 snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", dk->signer);
1132 msg = string(buf);
1133 return false;
1134 }
1135 }
1136
1103 if (spamassassin_limit && (score > spamassassin_limit)) { 1137 if (spamassassin_limit && (score > spamassassin_limit)) {
1104 char buf[maxlen]; 1138 char buf[maxlen];
1105 snprintf(buf, sizeof(buf), "Mail rejected - spam assassin score %d", score); 1139 snprintf(buf, sizeof(buf), "Mail rejected - spam assassin score %d", score);
1106 msg = string(buf); 1140 msg = string(buf);
1107 return false; 1141 return false;
1166 printf("; \n"); 1200 printf("; \n");
1167 } 1201 }
1168 1202
1169 if (content_filtering) { 1203 if (content_filtering) {
1170 printf("%s content on { \n", indent); 1204 printf("%s content on { \n", indent);
1205 printf("%s dkim_signer { \n", indent);
1206 for (string_map::iterator i=dkim_signer_names.begin(); i!=dkim_signer_names.end(); i++) {
1207 const char *n = (*i).first;
1208 const char *a = (*i).second;
1209 printf("%s %s %s; \n", indent, n, a);
1210 }
1211 printf("%s } \n", indent);
1212 printf("%s dkim_from { \n", indent);
1213 for (dkimp_map::iterator i=dkim_from_names.begin(); i!=dkim_from_names.end(); i++) {
1214 const char *n = (*i).first;
1215 DKIM &d = *(*i).second;
1216 printf("%s %s %s %s; \n", indent, n, d.action, d.signer);
1217 }
1218 printf("%s } \n", indent);
1171 if (content_suffix) { 1219 if (content_suffix) {
1172 printf("%s filter %s \"%s\"; \n", indent, content_suffix, content_message); 1220 printf("%s filter %s \"%s\"; \n", indent, content_suffix, content_message);
1173 } 1221 }
1174 if (uribl_suffix) { 1222 if (uribl_suffix) {
1175 printf("%s uribl %s \"%s\"; \n", indent, uribl_suffix, uribl_message); 1223 printf("%s uribl %s \"%s\"; \n", indent, uribl_suffix, uribl_message);
1228 spamass |= (spamassassin_limit != 0); 1276 spamass |= (spamassassin_limit != 0);
1229 } 1277 }
1230 else { 1278 else {
1231 printf("%s content off {}; \n", indent); 1279 printf("%s content off {}; \n", indent);
1232 } 1280 }
1233
1234 printf("%s dkim_signer { \n", indent);
1235 for (string_map::iterator i=dkim_signer_names.begin(); i!=dkim_signer_names.end(); i++) {
1236 const char *n = (*i).first;
1237 const char *a = (*i).second;
1238 printf("%s %s %s; \n", indent, n, a);
1239 }
1240 printf("%s } \n", indent);
1241
1242 printf("%s dkim_from { \n", indent);
1243 for (dkimp_map::iterator i=dkim_from_names.begin(); i!=dkim_from_names.end(); i++) {
1244 const char *n = (*i).first;
1245 DKIM &d = *(*i).second;
1246 printf("%s %s %s %s; \n", indent, n, d.action, d.signer);
1247 }
1248
1249 printf("%s } \n", indent);
1250 1281
1251 printf("%s env_to { \t// %s\n", indent, fullname); 1282 printf("%s env_to { \t// %s\n", indent, fullname);
1252 for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) { 1283 for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) {
1253 printf("%s %s; \n", indent, *i); 1284 printf("%s %s; \n", indent, *i);
1254 } 1285 }
1456 tok.token_error("yes/no", have); 1487 tok.token_error("yes/no", have);
1457 return false; 1488 return false;
1458 } 1489 }
1459 if (!tsa(tok, token_semi)) return false; 1490 if (!tsa(tok, token_semi)) return false;
1460 return true; 1491 return true;
1492 }
1493
1494
1495 ////////////////////////////////////////////////
1496 //
1497 bool parse_dkim_signer(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1498 bool parse_dkim_signer(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1499 if (!tsa(tok, token_lbrace)) return false;
1500 while (true) {
1501 const char *have = tok.next();
1502 if (!have) break;
1503 if (have == token_rbrace) break;
1504 if (have == token_semi) {
1505 // optional separators
1506 }
1507 else {
1508 const char *signer = have;
1509 const char *action = tok.next();
1510 if ((action == token_white) || (action == token_black)) {
1511 me.add_dkim_signer(signer, action);
1512 }
1513 else {
1514 tok.token_error("white/black", action);
1515 }
1516 }
1517 }
1518 return tsa(tok, token_semi);
1519 }
1520
1521
1522 ////////////////////////////////////////////////
1523 //
1524 bool parse_dkim_from(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1525 bool parse_dkim_from(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1526 if (!tsa(tok, token_lbrace)) return false;
1527 while (true) {
1528 const char *have = tok.next();
1529 if (!have) break;
1530 if (have == token_rbrace) break;
1531 if (have == token_semi) {
1532 // optional separators
1533 }
1534 else {
1535 const char *from = have;
1536 const char *action = tok.next();
1537 if ((action == token_signed_white) || (action == token_signed_black) || (action == token_require_signed)) {
1538 const char *signer = tok.next();
1539 if (!signer) break;
1540 else me.add_dkim_from(from, action, signer);
1541 }
1542 else {
1543 tok.token_error("signed_white/signed_black/require_signed", action);
1544 }
1545 }
1546 }
1547 return tsa(tok, token_semi);
1461 } 1548 }
1462 1549
1463 1550
1464 //////////////////////////////////////////////// 1551 ////////////////////////////////////////////////
1465 // 1552 //
1625 return false; 1712 return false;
1626 } 1713 }
1627 me.set_bulk((int)i); 1714 me.set_bulk((int)i);
1628 } 1715 }
1629 if (!tsa(tok, token_semi)) return false; 1716 if (!tsa(tok, token_semi)) return false;
1717 }
1718 else if (have == token_dkim_signer) {
1719 if (!parse_dkim_signer(tok, dc, me)) return false;
1720 }
1721 else if (have == token_dkim_from) {
1722 if (!parse_dkim_from(tok, dc, me)) return false;
1630 } 1723 }
1631 else if (have == token_rbrace) { 1724 else if (have == token_rbrace) {
1632 break; // done 1725 break; // done
1633 } 1726 }
1634 else { 1727 else {
1850 if (!have) break; 1943 if (!have) break;
1851 if (have == token_rbrace) break; 1944 if (have == token_rbrace) break;
1852 me.add_rate_limit(have, tok.nextint()); 1945 me.add_rate_limit(have, tok.nextint());
1853 me.add_address_limit(have, tok.nextint()); 1946 me.add_address_limit(have, tok.nextint());
1854 if (!tsa(tok, token_semi)) return false; 1947 if (!tsa(tok, token_semi)) return false;
1855 }
1856 return tsa(tok, token_semi);
1857 }
1858
1859
1860 ////////////////////////////////////////////////
1861 //
1862 bool parse_dkim_signer(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1863 bool parse_dkim_signer(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1864 if (!tsa(tok, token_lbrace)) return false;
1865 while (true) {
1866 const char *have = tok.next();
1867 if (!have) break;
1868 if (have == token_rbrace) break;
1869 if (have == token_semi) {
1870 // optional separators
1871 }
1872 else {
1873 const char *signer = have;
1874 const char *action = tok.next();
1875 if ((action == token_white) || (action == token_black)) {
1876 me.add_dkim_signer(signer, action);
1877 }
1878 else {
1879 tok.token_error("white/black", action);
1880 }
1881 }
1882 }
1883 return tsa(tok, token_semi);
1884 }
1885
1886
1887 ////////////////////////////////////////////////
1888 //
1889 bool parse_dkim_from(TOKEN &tok, CONFIG &dc, CONTEXT &me);
1890 bool parse_dkim_from(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
1891 if (!tsa(tok, token_lbrace)) return false;
1892 while (true) {
1893 const char *have = tok.next();
1894 if (!have) break;
1895 if (have == token_rbrace) break;
1896 if (have == token_semi) {
1897 // optional separators
1898 }
1899 else {
1900 const char *from = have;
1901 const char *action = tok.next();
1902 if ((action == token_signed_white) || (action == token_signed_black) || (action == token_require_signed)) {
1903 const char *signer = tok.next();
1904 if (!signer) break;
1905 else me.add_dkim_from(from, action, signer);
1906 }
1907 else {
1908 tok.token_error("signed_white/signed_black/require_signed", action);
1909 }
1910 }
1911 } 1948 }
1912 return tsa(tok, token_semi); 1949 return tsa(tok, token_semi);
1913 } 1950 }
1914 1951
1915 1952