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 }