Mercurial > dnsbl
annotate src/context.h @ 194:688ec12a3c0c stable-6-0-14
delay autowhitelisting to avoid out of office reply bots
author | carl |
---|---|
date | Sun, 11 Nov 2007 13:21:48 -0800 |
parents | 8f4a9a37d4d9 |
children | 82886d4dd71f |
rev | line source |
---|---|
143 | 1 /* |
2 | |
152 | 3 Copyright (c) 2007 Carl Byington - 510 Software Group, released under |
4 the GPL version 3 or any later version at your choice available at | |
5 http://www.gnu.org/licenses/gpl-3.0.txt | |
143 | 6 |
7 */ | |
8 | |
94 | 9 #ifndef context_include |
10 #define context_include | |
11 | |
12 #include "tokenizer.h" | |
13 #include <map> | |
168 | 14 #include <regex.h> |
94 | 15 |
16 | |
17 enum status {oksofar, // not rejected yet | |
18 white, // whitelisted | |
19 black, // blacklisted | |
20 reject}; // rejected by a dns list | |
21 | |
22 class DNSBL; | |
23 class CONTEXT; | |
24 class VERIFY; | |
25 class SMTP; | |
153 | 26 class WHITELISTER; |
192
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
27 class DELAYWHITE; |
94 | 28 class recorder; |
29 | |
30 typedef map<char *, char *, ltstr> string_map; | |
31 typedef set<int> int_set; | |
32 typedef list<SMTP *> smtp_list; | |
33 typedef list<char *> string_list; | |
34 typedef DNSBL * DNSBLP; | |
35 typedef VERIFY * VERIFYP; | |
153 | 36 typedef WHITELISTER * WHITELISTERP; |
192
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
37 typedef DELAYWHITE * DELAYWHITEP; |
94 | 38 typedef list<DNSBLP> dnsblp_list; |
39 typedef map<char *, DNSBLP, ltstr> dnsblp_map; | |
40 typedef CONTEXT * CONTEXTP; | |
41 typedef list<CONTEXTP> context_list; | |
42 typedef map<char *, CONTEXTP, ltstr> context_map; | |
43 typedef map<char *, int, ltstr> ns_mapper; | |
136 | 44 typedef map<char *, int, ltstr> rcpt_rates; |
160 | 45 typedef map<char *, time_t, ltstr> autowhite_sent; |
94 | 46 typedef map<char *, VERIFYP, ltstr> verify_map; |
153 | 47 typedef map<char *, WHITELISTERP, ltstr> whitelister_map; |
192
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
48 typedef list<DELAYWHITEP> delay_whitelist; |
94 | 49 |
50 class SMTP { | |
51 static const int maxlen = 1000; | |
52 int fd; | |
53 bool error; | |
54 time_t stamp; | |
55 char efrom[maxlen]; // last envelope from sent on this socket | |
56 int pending; // unread bytes in buffer, not including the null terminator | |
57 char buffer[maxlen]; | |
58 public: | |
99 | 59 SMTP(int f) {fd = f; error = false; now(); efrom[0] = '\0'; init();}; |
94 | 60 ~SMTP() {if (!error) quit(); closefd();}; |
61 void init() {pending = 0; buffer[0] = '\0';}; | |
62 void append(char *c) {strncat(buffer, c, max(0, maxlen-1-(int)strlen(c)));}; | |
63 bool err() {return error;}; | |
64 void now() {stamp = time(NULL);}; | |
65 time_t get_stamp() {return stamp;}; | |
66 int get_fd() {return fd;}; | |
67 int writer(); | |
68 int reader(); | |
69 int read_line(); | |
70 int read_response(); | |
97 | 71 void flush_line(int r); |
94 | 72 int cmd(char *c); |
73 int helo(); | |
74 int rset(); | |
75 int from(char *f); | |
76 int rcpt(char *t); | |
77 int quit(); | |
78 void closefd(); | |
79 #ifdef VERIFY_DEBUG | |
80 static void log(char *m, int v); | |
81 static void log(char *m, char *v); | |
82 #endif | |
83 }; | |
84 | |
85 class VERIFY { | |
86 char *host; // host to be used to verify recipient addresses | |
87 time_t last_err; // time of last socket error | |
88 pthread_mutex_t mutex; // protect the lists of sockets and timestamps | |
89 smtp_list connections;// open sockets, ready to be used | |
90 public: | |
91 VERIFY(char *h); | |
153 | 92 void closer(); // if the oldest socket is ancient, close it |
94 | 93 SMTP *get_connection(); |
94 void put_connection(SMTP *conn); | |
95 bool ok(char *from, char *to); | |
96 }; | |
97 | |
153 | 98 class WHITELISTER { |
99 char *fn; // file to use | |
100 int days; // how long do we keep entries | |
101 pthread_mutex_t mutex; // protect the flag and map | |
160 | 102 time_t loaded; // when we loaded this file |
153 | 103 bool need; // force writing on new entries |
104 autowhite_sent rcpts; // recipient map to remember when we sent them mail | |
105 public: | |
106 WHITELISTER(char *f, int d); | |
160 | 107 void merge(); |
153 | 108 void writer(); // dump any changes back to the file |
109 void sent(char *to); | |
110 bool is_white(char *from); // should we white list this sender (did we send them anything recently) | |
156 | 111 int get_days() {return days;}; |
112 void set_days(int d) {days = d;}; | |
153 | 113 }; |
114 | |
192
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
115 class DELAYWHITE { |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
116 char* loto; |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
117 WHITELISTERP w; |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
118 CONTEXTP con; |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
119 public: |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
120 DELAYWHITE(char *loto_, WHITELISTERP w_, CONTEXTP con_); |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
121 char *get_loto() {return loto;}; |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
122 WHITELISTERP get_w() {return w;}; |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
123 CONTEXTP get_con() {return con;}; |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
124 }; |
8f4a9a37d4d9
delay autowhitelisting to avoid out of office reply bots
carl
parents:
179
diff
changeset
|
125 |
94 | 126 struct DNSBL { |
127 char *name; // nickname for this dns based list | |
128 char *suffix; // blacklist suffix like blackholes.five-ten-sg.com | |
129 char *message; // error message with one or two %s operators for the ip address replacement | |
130 DNSBL(char *n, char *s, char *m); | |
131 bool operator==(const DNSBL &rhs); | |
132 }; | |
133 | |
134 class CONTEXT { | |
135 CONTEXTP parent; | |
136 char * name; | |
137 context_map children; // map child context names to their contexts | |
138 string_set env_to; // this context applies to these envelope recipients | |
139 char * verify_host; // use this smtp host to verify email addresses | |
153 | 140 VERIFYP verifier; // pointer to the verifier structure |
168 | 141 char * generic_regx; // pointer to generic regular expression |
142 char * generic_message; // pointer to generic message with one %s | |
170 | 143 regex_t generic_pattern; // compiled regex pattern |
153 | 144 char * autowhite_file; // file to use for automatic whitelisting |
145 WHITELISTERP whitelister; // pointer to the auto whitelister structure | |
94 | 146 string_map env_from; // map senders to white/black/unknown |
147 context_map env_from_context; // map senders to a child context | |
148 char * env_from_default; // default value for senders that are not found in the map white/black/unknown/inherit | |
149 bool content_filtering; // | |
119 | 150 char * content_suffix; // for url body filtering based on ip addresses of hostnames in the body |
94 | 151 char * content_message; // "" |
119 | 152 char * uribl_suffix; // for uribl body filtering based on hostnames in the body |
153 char * uribl_message; // "" | |
94 | 154 string_set content_host_ignore;// hosts to ignore for content sbl checking |
155 string_set content_tlds; // | |
117 | 156 string_set content_cctlds; // |
94 | 157 string_set html_tags; // set of valid html tags |
158 int host_limit; // limit on host names | |
159 char * host_limit_message; // error message for excessive host names | |
160 bool host_random; // pick a random selection of host names rather than error for excessive hosts | |
161 int tag_limit; // limit on bad html tags | |
162 char * tag_limit_message; // error message for excessive bad html tags | |
163 | 163 int spamassassin_limit; // max score from spamassassin |
178 | 164 bool require_match; // require matching context filtering context |
165 bool dcc_greylist; // should we do dcc greylisting? | |
166 int dcc_bulk_threshold; // off = 0, many = 1000 | |
94 | 167 dnsblp_map dnsbl_names; // name to dnsbl mapping for lists that are available in this context and children |
168 dnsblp_list dnsbl_list; // list of dnsbls to be used in this context | |
140 | 169 int default_rcpt_rate; // if not specified per user |
136 | 170 rcpt_rates rcpt_per_hour; // per user limits on number of recipients per hour |
171 | |
94 | 172 |
173 public: | |
174 CONTEXT(CONTEXTP parent_, char *name_); | |
175 ~CONTEXT(); | |
176 CONTEXTP get_parent() {return parent;}; | |
177 bool is_parent(CONTEXTP p); // is p a parent of this? | |
178 char* get_full_name(char *buf, int size); | |
179 void add_context(CONTEXTP child) {children[child->name] = child;}; | |
180 bool allow_env_to(char *to) {return (parent) ? parent->cover_env_to(to) : true;}; | |
181 bool cover_env_to(char *to); | |
182 | |
153 | 183 void set_verifier(VERIFYP v) {verifier = v;}; |
94 | 184 void set_verify(char *host) {verify_host = host;}; |
185 char* get_verify() {return verify_host;}; | |
186 VERIFYP find_verify(char *to); | |
187 | |
168 | 188 |
153 | 189 void set_whitelister(WHITELISTERP v) {whitelister = v;}; |
190 void set_autowhite(char *fn) {autowhite_file = fn;}; | |
191 char* get_autowhite() {return autowhite_file;}; | |
162 | 192 WHITELISTERP find_autowhite(char *from, char *to); |
153 | 193 |
140 | 194 void set_default_rate(int limit) {default_rcpt_rate = limit;}; |
136 | 195 void add_rate(char *user, int limit) {rcpt_per_hour[user] = limit;}; |
196 int find_rate(char *user); | |
197 | |
94 | 198 void add_to(char *to) {env_to.insert(to);}; |
199 void add_from(char *from, char *status) {env_from[from] = status;}; | |
200 void add_from_context(char *from, CONTEXTP con) {env_from_context[from] = con;}; | |
201 void set_from_default(char *status) {env_from_default = status;}; | |
173
83fe0be032c1
fix leak, update timestamps when receiving auto-whitelisted sender
carl
parents:
170
diff
changeset
|
202 char* find_from(char *from, bool update_white = false); |
94 | 203 CONTEXTP find_context(char *from); |
204 CONTEXTP find_from_context_name(char *name); | |
205 | |
163 | 206 void set_content_filtering(bool filter) {content_filtering = filter; }; |
207 void set_content_suffix(char *suffix) {content_suffix = suffix; }; | |
208 void set_content_message(char *message) {content_message = message; }; | |
209 void set_uribl_suffix(char *suffix) {uribl_suffix = suffix; }; | |
210 void set_uribl_message(char *message) {uribl_message = message; }; | |
94 | 211 void add_ignore(char *host) {content_host_ignore.insert(host);}; |
163 | 212 void add_tld(char *tld) {content_tlds.insert(tld); }; |
213 void add_cctld(char *cctld) {content_cctlds.insert(cctld); }; | |
94 | 214 |
163 | 215 void set_host_limit(int limit) {host_limit = limit; }; |
94 | 216 void set_host_message(char *message) {host_limit_message = message;}; |
163 | 217 void set_host_random(bool random) {host_random = random; }; |
167
9b129ed78d7d
actually use spamassassin result, allow build without spam assassin, only call it if some recipient needs it.
carl
parents:
164
diff
changeset
|
218 void set_spamassassin_limit(int limit) {spamassassin_limit = limit; }; |
163 | 219 void set_tag_limit(int limit) {tag_limit = limit; }; |
94 | 220 void set_tag_message(char *message) {tag_limit_message = message;}; |
163 | 221 void add_tag(char *tag) {html_tags.insert(tag); }; |
94 | 222 |
163 | 223 void add_dnsbl(char *name, DNSBLP dns) {dnsbl_names[name] = dns; }; |
94 | 224 void add_dnsbl(DNSBLP dns) {dnsbl_list.push_back(dns);}; |
225 DNSBLP find_dnsbl(char *name); | |
226 | |
168 | 227 bool set_generic(char *regx, char *msg); |
228 char* generic_match(char *client); | |
229 | |
178 | 230 void set_require(bool r) {require_match = r; }; |
231 void set_grey(bool g) {dcc_greylist = g; }; | |
232 void set_bulk(int b) {dcc_bulk_threshold = b; }; | |
233 | |
163 | 234 bool get_content_filtering() {return content_filtering; }; |
179 | 235 bool get_require() {return content_filtering && require_match; }; |
236 bool get_grey() {return content_filtering && dcc_greylist; }; | |
237 int get_bulk() {return (content_filtering) ? dcc_bulk_threshold : 0;}; | |
238 int get_host_limit() {return (content_filtering) ? host_limit : 0;}; | |
239 bool get_host_random() {return (content_filtering) ? host_random : 0;}; | |
167
9b129ed78d7d
actually use spamassassin result, allow build without spam assassin, only call it if some recipient needs it.
carl
parents:
164
diff
changeset
|
240 int get_spamassassin_limit() {return (content_filtering) ? spamassassin_limit : 0;}; |
94 | 241 char* get_content_suffix(); |
242 char* get_content_message(); | |
119 | 243 char* get_uribl_suffix(); |
244 char* get_uribl_message(); | |
94 | 245 string_set& get_content_host_ignore(); |
246 string_set& get_content_tlds(); | |
117 | 247 string_set& get_content_cctlds(); |
94 | 248 string_set& get_html_tags(); |
249 dnsblp_list& get_dnsbl_list(); | |
250 | |
178 | 251 bool acceptable_content(recorder &memory, int score, int bulk, string& msg); |
94 | 252 bool ignore_host(char *host); |
253 | |
167
9b129ed78d7d
actually use spamassassin result, allow build without spam assassin, only call it if some recipient needs it.
carl
parents:
164
diff
changeset
|
254 void dump(bool isdefault, bool &spamass, int level = 0); |
94 | 255 }; |
256 | |
257 | |
258 struct CONFIG { | |
259 // the only mutable stuff once it has been loaded from the config file | |
260 int reference_count; // protected by the global config_mutex | |
261 // all the rest is constant after loading from the config file | |
262 int generation; | |
263 time_t load_time; | |
264 string_set config_files; | |
265 context_list contexts; // owns all the contexts, not just top level contexts | |
266 context_map env_to; // map recipient to a filtering context | |
267 CONTEXTP default_context;// for env_to values that don't have their own specific filtering context | |
268 // the default context is also used for some of the content filtering values | |
269 | |
270 CONFIG(); | |
271 ~CONFIG(); | |
272 void add_context(CONTEXTP con); | |
273 void add_to(char *to, CONTEXTP con); | |
274 CONTEXTP find_context(char *to); | |
275 void dump(); | |
276 }; | |
277 | |
136 | 278 |
153 | 279 extern char *token_autowhite; |
94 | 280 extern char *token_black; |
117 | 281 extern char *token_cctld; |
94 | 282 extern char *token_content; |
283 extern char *token_context; | |
178 | 284 extern char *token_dccbulk; |
94 | 285 extern char *token_dccfrom; |
178 | 286 extern char *token_dccgrey; |
94 | 287 extern char *token_dccto; |
288 extern char *token_default; | |
289 extern char *token_dnsbl; | |
290 extern char *token_dnsbll; | |
291 extern char *token_envfrom; | |
292 extern char *token_envto; | |
293 extern char *token_filter; | |
168 | 294 extern char *token_generic; |
94 | 295 extern char *token_host_limit; |
296 extern char *token_html_limit; | |
297 extern char *token_html_tags; | |
298 extern char *token_ignore; | |
299 extern char *token_include; | |
300 extern char *token_inherit; | |
301 extern char *token_lbrace; | |
302 extern char *token_mailhost; | |
303 extern char *token_many; | |
178 | 304 extern char *token_no; |
94 | 305 extern char *token_off; |
178 | 306 extern char *token_ok; |
117 | 307 extern char *token_ok2; |
94 | 308 extern char *token_on; |
136 | 309 extern char *token_rate; |
94 | 310 extern char *token_rbrace; |
178 | 311 extern char *token_require; |
94 | 312 extern char *token_semi; |
313 extern char *token_soft; | |
163 | 314 extern char *token_spamassassin; |
94 | 315 extern char *token_substitute; |
316 extern char *token_tld; | |
317 extern char *token_unknown; | |
119 | 318 extern char *token_uribl; |
178 | 319 extern char *token_verify; |
94 | 320 extern char *token_white; |
178 | 321 extern char *token_yes; |
94 | 322 |
153 | 323 extern pthread_mutex_t verifier_mutex; // protect the verifier map |
324 extern pthread_mutex_t whitelister_mutex; // protect the | |
94 | 325 |
326 void discard(string_set &s); | |
327 char* register_string(string_set &s, char *name); | |
328 char* register_string(char *name); | |
164 | 329 void clear_strings(); |
94 | 330 CONFIG *parse_config(char *fn); |
331 bool load_conf(CONFIG &dc, char *fn); | |
332 void* verify_closer(void *arg); | |
153 | 333 void* whitelister_writer(void *arg); |
94 | 334 void token_init(); |
335 | |
336 #endif |