Mercurial > dnsbl
comparison src/context.cpp @ 278:368572c57013
add limits on unique ip addresses per hour per authenticated user
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 17 Dec 2013 15:35:23 -0800 |
parents | bdcf203e3f7b |
children | 802e2b779ed1 |
comparison
equal
deleted
inserted
replaced
277:7163e9b04bdb | 278:368572c57013 |
---|---|
704 } | 704 } |
705 } | 705 } |
706 | 706 |
707 | 707 |
708 CONTEXT::CONTEXT(CONTEXTP parent_, const char *name_) { | 708 CONTEXT::CONTEXT(CONTEXTP parent_, const char *name_) { |
709 parent = parent_; | 709 parent = parent_; |
710 name = name_; | 710 name = name_; |
711 verify_host = NULL; | 711 verify_host = NULL; |
712 verifier = NULL; | 712 verifier = NULL; |
713 generic_regx = NULL; | 713 generic_regx = NULL; |
714 generic_message = NULL; | 714 generic_message = NULL; |
715 white_regx = NULL; | 715 white_regx = NULL; |
716 autowhite_file = NULL; | 716 autowhite_file = NULL; |
717 whitelister = NULL; | 717 whitelister = NULL; |
718 env_from_default = (parent) ? token_inherit : token_unknown; | 718 env_from_default = (parent) ? token_inherit : token_unknown; |
719 content_filtering = (parent) ? parent->content_filtering : false; | 719 content_filtering = (parent) ? parent->content_filtering : false; |
720 content_suffix = NULL; | 720 content_suffix = NULL; |
721 content_message = NULL; | 721 content_message = NULL; |
722 uribl_suffix = NULL; | 722 uribl_suffix = NULL; |
723 uribl_message = NULL; | 723 uribl_message = NULL; |
724 host_limit = (parent) ? parent->host_limit : 0; | 724 host_limit = (parent) ? parent->host_limit : 0; |
725 host_limit_message = NULL; | 725 host_limit_message = NULL; |
726 host_random = (parent) ? parent->host_random : false; | 726 host_random = (parent) ? parent->host_random : false; |
727 tag_limit = (parent) ? parent->tag_limit : 0; | 727 tag_limit = (parent) ? parent->tag_limit : 0; |
728 tag_limit_message = NULL; | 728 tag_limit_message = NULL; |
729 spamassassin_limit = (parent) ? parent->spamassassin_limit : 0; | 729 spamassassin_limit = (parent) ? parent->spamassassin_limit : 0; |
730 require_match = (parent) ? parent->require_match : false; | 730 require_match = (parent) ? parent->require_match : false; |
731 require_rdns = (parent) ? parent->require_rdns : false; | 731 require_rdns = (parent) ? parent->require_rdns : false; |
732 dcc_greylist = (parent) ? parent->dcc_greylist : false; | 732 dcc_greylist = (parent) ? parent->dcc_greylist : false; |
733 dcc_bulk_threshold = (parent) ? parent->dcc_bulk_threshold : 0; | 733 dcc_bulk_threshold = (parent) ? parent->dcc_bulk_threshold : 0; |
734 dnsbl_list_parsed = false; | 734 dnsbl_list_parsed = false; |
735 dnswl_list_parsed = false; | 735 dnswl_list_parsed = false; |
736 default_rcpt_rate = 36000; // 10 per second | 736 default_rate_limit = 36000; // 10 per second |
737 rcpt_daily_multiple = 3; | 737 default_address_limit = 10; |
738 daily_rate_multiple = 3; | |
739 daily_address_multiple = 3; | |
738 } | 740 } |
739 | 741 |
740 | 742 |
741 CONTEXT::~CONTEXT() { | 743 CONTEXT::~CONTEXT() { |
742 for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) { | 744 for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) { |
843 else | 845 else |
844 return NULL; | 846 return NULL; |
845 } | 847 } |
846 | 848 |
847 | 849 |
848 int CONTEXT::find_rate(const char *user) { | 850 int CONTEXT::find_rate_limit(const char *user) { |
849 if (rcpt_per_hour.empty()) return default_rcpt_rate; | 851 if (rcpt_per_hour.empty()) return default_rate_limit; |
850 rcpt_rates::iterator i = rcpt_per_hour.find(user); // look for authen id, or sender user@email limiting | 852 rates::iterator i = rcpt_per_hour.find(user); // look for authen id, or sender user@email limiting |
851 if (i != rcpt_per_hour.end()) return (*i).second; // found authen id, or user@email limiting | 853 if (i != rcpt_per_hour.end()) return (*i).second; // found authen id, or user@email limiting |
852 const char *f = strchr(user, '@'); | 854 const char *f = strchr(user, '@'); |
853 if (!f) return default_rcpt_rate; | 855 if (!f) return default_rate_limit; |
854 i = rcpt_per_hour.find(f); // look for @domain limiting | 856 i = rcpt_per_hour.find(f); // look for @domain limiting |
855 if (i != rcpt_per_hour.end()) return (*i).second; // found @domain limiting | 857 if (i != rcpt_per_hour.end()) return (*i).second; // found @domain limiting |
856 return default_rcpt_rate; | 858 return default_rate_limit; |
859 } | |
860 | |
861 | |
862 int CONTEXT::find_address_limit(const char *user) { | |
863 if (addresses_per_hour.empty()) return default_address_limit; | |
864 rates::iterator i = addresses_per_hour.find(user); // look for authen id, or sender user@email limiting | |
865 if (i != addresses_per_hour.end()) return (*i).second; // found authen id, or user@email limiting | |
866 const char *f = strchr(user, '@'); | |
867 if (!f) return default_address_limit; | |
868 i = addresses_per_hour.find(f); // look for @domain limiting | |
869 if (i != addresses_per_hour.end()) return (*i).second; // found @domain limiting | |
870 return default_address_limit; | |
857 } | 871 } |
858 | 872 |
859 | 873 |
860 bool CONTEXT::is_unauthenticated_limited(const char *user) { | 874 bool CONTEXT::is_unauthenticated_limited(const char *user) { |
861 rcpt_rates::iterator i = rcpt_per_hour.find(user); // look for sender user@email limiting | 875 rates::iterator i = rcpt_per_hour.find(user); // look for sender user@email limiting |
862 if (i != rcpt_per_hour.end()) return true; // found user@email limiting | 876 if (i != rcpt_per_hour.end()) return true; // found user@email limiting |
863 const char *f = strchr(user, '@'); | 877 const char *f = strchr(user, '@'); |
864 if (!f) return false; | 878 if (!f) return false; |
865 i = rcpt_per_hour.find(f); // look for sender @domain limiting | 879 i = rcpt_per_hour.find(f); // look for sender @domain limiting |
866 return (i != rcpt_per_hour.end()); // found @domain limiting | 880 return (i != rcpt_per_hour.end()); // found @domain limiting |
1209 } | 1223 } |
1210 } | 1224 } |
1211 printf("%s }; \n", indent); | 1225 printf("%s }; \n", indent); |
1212 | 1226 |
1213 if (isdefault) { | 1227 if (isdefault) { |
1214 printf("%s rate_limit %d %d { \n", indent, default_rcpt_rate, rcpt_daily_multiple); | 1228 printf("%s rate_limit %d %d %d %d { \n", indent, default_rate_limit, daily_rate_multiple, default_address_limit, daily_address_multiple); |
1215 for (rcpt_rates::iterator j=rcpt_per_hour.begin(); j!=rcpt_per_hour.end(); j++) { | 1229 for (rates::iterator j=rcpt_per_hour.begin(); j!=rcpt_per_hour.end(); j++) { |
1216 const char *u = (*j).first; | 1230 const char *u = (*j).first; |
1217 int l = (*j).second; | 1231 int l = (*j).second; |
1218 printf("%s \"%s\" \t%d; \n", indent, u, l); | 1232 rates::iterator k = addresses_per_hour.find(u); |
1233 int a = (k==addresses_per_hour.end()) ? default_address_limit : (*k).second; | |
1234 printf("%s \"%s\" \t%d %d; \n", indent, u, l, a); | |
1219 } | 1235 } |
1220 printf("%s }; \n", indent); | 1236 printf("%s }; \n", indent); |
1221 } | 1237 } |
1222 | 1238 |
1223 printf("%s }; \n", indent); | 1239 printf("%s }; \n", indent); |
1751 | 1767 |
1752 //////////////////////////////////////////////// | 1768 //////////////////////////////////////////////// |
1753 // | 1769 // |
1754 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me); | 1770 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
1755 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me) { | 1771 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
1756 const char *def = tok.next(); | 1772 me.set_default_rate_limit(tok.nextint()); |
1757 tok.push(def); | 1773 me.set_daily_rate_multiple(tok.nextint()); |
1758 if (def != token_lbrace) me.set_default_rate(tok.nextint()); | 1774 me.set_default_address_limit(tok.nextint()); |
1759 | 1775 me.set_daily_address_multiple(tok.nextint()); |
1760 def = tok.next(); | |
1761 tok.push(def); | |
1762 if (def != token_lbrace) me.set_daily_multiple(tok.nextint()); | |
1763 | |
1764 if (!tsa(tok, token_lbrace)) return false; | 1776 if (!tsa(tok, token_lbrace)) return false; |
1765 while (true) { | 1777 while (true) { |
1766 const char *have = tok.next(); | 1778 const char *have = tok.next(); |
1767 if (!have) break; | 1779 if (!have) break; |
1768 if (have == token_rbrace) break; | 1780 if (have == token_rbrace) break; |
1769 if (have == token_semi) { | 1781 me.add_rate_limit(have, tok.nextint()); |
1770 // optional separators | 1782 me.add_address_limit(have, tok.nextint()); |
1771 } | 1783 if (!tsa(tok, token_semi)) return false; |
1772 else { | |
1773 me.add_rate(have, tok.nextint()); | |
1774 } | |
1775 } | 1784 } |
1776 return tsa(tok, token_semi); | 1785 return tsa(tok, token_semi); |
1777 } | 1786 } |
1778 | 1787 |
1779 | 1788 |