Mercurial > dnsbl
comparison src/context.cpp @ 233:5c3e9bf45bb5 stable-6-0-23
Add whitelisting by regex expression filtering.
Add queueid to whitelist extension log message.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Mon, 25 May 2009 11:14:32 -0700 |
parents | 82886d4dd71f |
children | ef97c7cd4a6e |
comparison
equal
deleted
inserted
replaced
232:768ce0f23149 | 233:5c3e9bf45bb5 |
---|---|
60 const char *token_tld; | 60 const char *token_tld; |
61 const char *token_unknown; | 61 const char *token_unknown; |
62 const char *token_uribl; | 62 const char *token_uribl; |
63 const char *token_verify; | 63 const char *token_verify; |
64 const char *token_white; | 64 const char *token_white; |
65 const char *token_white_regex; | |
65 const char *token_yes; | 66 const char *token_yes; |
66 | 67 |
67 const char *token_myhostname; | 68 const char *token_myhostname; |
68 #ifndef HOST_NAME_MAX | 69 #ifndef HOST_NAME_MAX |
69 #define HOST_NAME_MAX 255 | 70 #define HOST_NAME_MAX 255 |
690 name = name_; | 691 name = name_; |
691 verify_host = NULL; | 692 verify_host = NULL; |
692 verifier = NULL; | 693 verifier = NULL; |
693 generic_regx = NULL; | 694 generic_regx = NULL; |
694 generic_message = NULL; | 695 generic_message = NULL; |
696 white_regx = NULL; | |
695 autowhite_file = NULL; | 697 autowhite_file = NULL; |
696 whitelister = NULL; | 698 whitelister = NULL; |
697 env_from_default = (parent) ? token_inherit : token_unknown; | 699 env_from_default = (parent) ? token_inherit : token_unknown; |
698 content_filtering = (parent) ? parent->content_filtering : false; | 700 content_filtering = (parent) ? parent->content_filtering : false; |
699 content_suffix = NULL; | 701 content_suffix = NULL; |
718 DNSBLP d = (*i).second; | 720 DNSBLP d = (*i).second; |
719 // delete the underlying DNSBL objects. | 721 // delete the underlying DNSBL objects. |
720 delete d; | 722 delete d; |
721 } | 723 } |
722 if (generic_regx) regfree(&generic_pattern); | 724 if (generic_regx) regfree(&generic_pattern); |
725 if (white_regx) regfree(&white_pattern); | |
723 } | 726 } |
724 | 727 |
725 | 728 |
726 bool CONTEXT::is_parent(CONTEXTP p) { | 729 bool CONTEXT::is_parent(CONTEXTP p) { |
727 if (p == parent) return true; | 730 if (p == parent) return true; |
733 const char *CONTEXT::get_full_name(char *buffer, int size) { | 736 const char *CONTEXT::get_full_name(char *buffer, int size) { |
734 if (!parent) return name; | 737 if (!parent) return name; |
735 char buf[maxlen]; | 738 char buf[maxlen]; |
736 snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name); | 739 snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name); |
737 return buffer; | 740 return buffer; |
741 } | |
742 | |
743 | |
744 bool CONTEXT::set_white(const char *regx) | |
745 { | |
746 int rc = 0; | |
747 if (white_regx) regfree(&white_pattern); | |
748 white_regx = regx; | |
749 if (white_regx) { | |
750 rc = regcomp(&white_pattern, regx, REG_NOSUB | REG_ICASE | REG_EXTENDED); | |
751 } | |
752 return rc; // true iff bad pattern | |
753 } | |
754 | |
755 | |
756 bool CONTEXT::white_match(const char *from) | |
757 { | |
758 return (from && | |
759 white_regx && | |
760 (0 == regexec(&white_pattern, from, 0, NULL, 0))); | |
738 } | 761 } |
739 | 762 |
740 | 763 |
741 bool CONTEXT::set_generic(const char *regx, const char *msg) | 764 bool CONTEXT::set_generic(const char *regx, const char *msg) |
742 { | 765 { |
804 rcpt_rates::iterator i = rcpt_per_hour.find(user); | 827 rcpt_rates::iterator i = rcpt_per_hour.find(user); |
805 return (i == rcpt_per_hour.end()) ? default_rcpt_rate : (*i).second; | 828 return (i == rcpt_per_hour.end()) ? default_rcpt_rate : (*i).second; |
806 } | 829 } |
807 | 830 |
808 | 831 |
809 const char *CONTEXT::find_from(const char *from, bool update_white) { | 832 const char *CONTEXT::find_from(const char *from, bool update_white, const char *queueid) { |
810 WHITELISTERP w = whitelister; | 833 WHITELISTERP w = whitelister; |
811 CONTEXTP p = parent; | 834 CONTEXTP p = parent; |
812 while (!w && p) { | 835 while (!w && p) { |
813 w = p->whitelister; | 836 w = p->whitelister; |
814 p = p->parent; | 837 p = p->parent; |
815 } | 838 } |
816 if (w && w->is_white(from)) { | 839 if (w && w->is_white(from)) { |
817 if (update_white) { | 840 if (update_white && queueid) { |
818 // update senders timestamp to extend the whitelisting period | 841 // update senders timestamp to extend the whitelisting period |
819 if (debug_syslog > 1) { | 842 if (debug_syslog > 1) { |
820 char buf[maxlen]; | 843 char buf[maxlen]; |
821 char msg[maxlen]; | 844 char msg[maxlen]; |
822 snprintf(msg, sizeof(msg), "extend whitelist reply from <%s> in context %s", from, get_full_name(buf,maxlen)); | 845 snprintf(msg, sizeof(msg), "%s: extend whitelist reply from <%s> in context %s", queueid, from, get_full_name(buf,maxlen)); |
823 my_syslog(msg); | 846 my_syslog(msg); |
824 } | 847 } |
825 w->sent(strdup(from)); | 848 w->sent(strdup(from)); |
826 } | 849 } |
827 return token_white; | 850 return token_white; |
842 *x = y; | 865 *x = y; |
843 if (i != env_from.end()) rc = (*i).second; // found user@ key | 866 if (i != env_from.end()) rc = (*i).second; // found user@ key |
844 } | 867 } |
845 } | 868 } |
846 } | 869 } |
870 if ((rc == token_inherit) || (rc == token_unknown)) { | |
871 bool ok = white_match(from); | |
872 if (ok) rc = token_white; | |
873 } | |
847 if ((rc == token_inherit) && parent) return parent->find_from(from); | 874 if ((rc == token_inherit) && parent) return parent->find_from(from); |
848 return (rc == token_inherit) ? token_unknown : rc; | 875 return (rc == token_inherit) ? token_unknown : rc; |
849 } | 876 } |
850 | 877 |
851 | 878 |
1065 if (generic_regx) { | 1092 if (generic_regx) { |
1066 printf("%s generic \"%s\" \n", indent, generic_regx); | 1093 printf("%s generic \"%s\" \n", indent, generic_regx); |
1067 printf("%s \"%s\"; \n", indent, generic_message); | 1094 printf("%s \"%s\"; \n", indent, generic_message); |
1068 } | 1095 } |
1069 | 1096 |
1097 if (white_regx) { | |
1098 printf("%s white_regex \"%s\"; \n", indent, white_regx); | |
1099 } | |
1100 | |
1070 if (autowhite_file && whitelister) { | 1101 if (autowhite_file && whitelister) { |
1071 printf("%s autowhite %d %s; \n", indent, whitelister->get_days(), autowhite_file); | 1102 printf("%s autowhite %d %s; \n", indent, whitelister->get_days(), autowhite_file); |
1072 } | 1103 } |
1073 | 1104 |
1074 for (context_map::iterator i=children.begin(); i!=children.end(); i++) { | 1105 for (context_map::iterator i=children.begin(); i!=children.end(); i++) { |
1463 } | 1494 } |
1464 | 1495 |
1465 | 1496 |
1466 //////////////////////////////////////////////// | 1497 //////////////////////////////////////////////// |
1467 // | 1498 // |
1499 bool parse_white(TOKEN &tok, CONFIG &dc, CONTEXT &me); | |
1500 bool parse_white(TOKEN &tok, CONFIG &dc, CONTEXT &me) { | |
1501 const char *regx = tok.next(); | |
1502 if (!tsa(tok, token_semi)) return false; | |
1503 if (me.set_white(regx)) { | |
1504 tok.token_error("invalid regular expression %s", regx, regx); | |
1505 return false; | |
1506 } | |
1507 return true; | |
1508 } | |
1509 | |
1510 | |
1511 //////////////////////////////////////////////// | |
1512 // | |
1468 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me); | 1513 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
1469 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me) { | 1514 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
1470 int days = tok.nextint(); | 1515 int days = tok.nextint(); |
1471 const char *fn = tok.next(); | 1516 const char *fn = tok.next(); |
1472 if (!tsa(tok, token_semi)) return false; | 1517 if (!tsa(tok, token_semi)) return false; |
1604 else if (have == token_verify) { | 1649 else if (have == token_verify) { |
1605 if (!parse_verify(tok, dc, *con)) return false; | 1650 if (!parse_verify(tok, dc, *con)) return false; |
1606 } | 1651 } |
1607 else if (have == token_generic) { | 1652 else if (have == token_generic) { |
1608 if (!parse_generic(tok, dc, *con)) return false; | 1653 if (!parse_generic(tok, dc, *con)) return false; |
1654 } | |
1655 else if (have == token_white_regex) { | |
1656 if (!parse_white(tok, dc, *con)) return false; | |
1609 } | 1657 } |
1610 else if (have == token_autowhite) { | 1658 else if (have == token_autowhite) { |
1611 if (!parse_autowhite(tok, dc, *con)) return false; | 1659 if (!parse_autowhite(tok, dc, *con)) return false; |
1612 } | 1660 } |
1613 else if (have == token_envfrom) { | 1661 else if (have == token_envfrom) { |
1706 token_tld = register_string("tld"); | 1754 token_tld = register_string("tld"); |
1707 token_unknown = register_string("unknown"); | 1755 token_unknown = register_string("unknown"); |
1708 token_uribl = register_string("uribl"); | 1756 token_uribl = register_string("uribl"); |
1709 token_verify = register_string("verify"); | 1757 token_verify = register_string("verify"); |
1710 token_white = register_string("white"); | 1758 token_white = register_string("white"); |
1759 token_white_regex = register_string("white_regex"); | |
1711 token_yes = register_string("yes"); | 1760 token_yes = register_string("yes"); |
1712 | 1761 |
1713 if (gethostname(myhostname, HOST_NAME_MAX+1) != 0) { | 1762 if (gethostname(myhostname, HOST_NAME_MAX+1) != 0) { |
1714 strncpy(myhostname, "localhost", HOST_NAME_MAX+1); | 1763 strncpy(myhostname, "localhost", HOST_NAME_MAX+1); |
1715 } | 1764 } |