Mercurial > dnsbl
comparison src/context.cpp @ 75:1142e46be550
start coding on new config syntax
author | carl |
---|---|
date | Wed, 13 Jul 2005 23:04:14 -0700 |
parents | b7449114ebb0 |
children | 81f1e400e8ab |
comparison
equal
deleted
inserted
replaced
74:b7449114ebb0 | 75:1142e46be550 |
---|---|
26 char *token_html_tags; | 26 char *token_html_tags; |
27 char *token_ignore; | 27 char *token_ignore; |
28 char *token_include; | 28 char *token_include; |
29 char *token_inherit; | 29 char *token_inherit; |
30 char *token_lbrace; | 30 char *token_lbrace; |
31 char *token_mailhost; | |
31 char *token_many; | 32 char *token_many; |
32 char *token_off; | 33 char *token_off; |
34 char *token_ok2; | |
33 char *token_ok; | 35 char *token_ok; |
34 char *token_ok2; | |
35 char *token_on; | 36 char *token_on; |
36 char *token_rbrace; | 37 char *token_rbrace; |
37 char *token_semi; | 38 char *token_semi; |
38 char *token_soft; | 39 char *token_soft; |
40 char *token_substitute; | |
39 char *token_tld; | 41 char *token_tld; |
40 char *token_unknown; | 42 char *token_unknown; |
41 char *token_white; | 43 char *token_white; |
42 | 44 |
43 string_set all_strings; // owns all the strings, only modified by the config loader thread | 45 string_set all_strings; // owns all the strings, only modified by the config loader thread |
46 const int maxlen = 1000; | |
44 | 47 |
45 DNSBL::DNSBL(char *n, char *s, char *m) { | 48 DNSBL::DNSBL(char *n, char *s, char *m) { |
46 name = n; | 49 name = n; |
47 suffix = s; | 50 suffix = s; |
48 message = m; | 51 message = m; |
72 default_context = con; | 75 default_context = con; |
73 } | 76 } |
74 } | 77 } |
75 | 78 |
76 | 79 |
77 CONTEXTP CONFIG::find_context(char *to, char *from) { | 80 void CONFIG::add_to(char *to, CONTEXTP con) { |
78 CONTEXTP con = NULL; | 81 context_map::iterator i = env_to.find(to); |
79 context_map::iterator i = env_to.find(from); | |
80 if (i != env_to.end()) { | 82 if (i != env_to.end()) { |
81 con = (*i).second; | 83 CONTEXTP c = (*i).second; |
82 return con->find_from_context(from); | 84 if ((c != con) && (c != con->get_parent())) { |
83 } | 85 char oldname[maxlen]; |
86 char newname[maxlen]; | |
87 char *oldn = c->get_full_name(oldname, maxlen); | |
88 char *newn = con->get_full_name(newname, maxlen); | |
89 char buf[maxlen*3]; | |
90 snprintf(buf, maxlen*3, "both %s and %s claim envelope to %s, the second one wins", oldn, newn, to); | |
91 my_syslog(buf); | |
92 } | |
93 } | |
94 env_to[to] = con; | |
95 } | |
96 | |
97 | |
98 CONTEXTP CONFIG::find_context(char *to) { | |
99 context_map::iterator i = env_to.find(to); | |
100 if (i != env_to.end()) return (*i).second; // found user@domain.tld key | |
84 char *x = strchr(to, '@'); | 101 char *x = strchr(to, '@'); |
85 if (x) { | 102 if (x) { |
86 x++; | 103 x++; |
87 i = env_to.find(x); | 104 i = env_to.find(x); |
88 if (i != env_to.end()) { | 105 if (i != env_to.end()) return (*i).second; // found domain.tld key |
89 con = (*i).second; | 106 char y = *x; |
90 return con->find_from_context(from); | 107 *x = '\0'; |
91 } | 108 i = env_to.find(to); |
92 } | 109 *x = y; |
93 return default_context->find_from_context(from); | 110 if (i != env_to.end()) return (*i).second; // found user@ key |
111 } | |
112 return default_context; | |
94 } | 113 } |
95 | 114 |
96 | 115 |
97 void CONFIG::dump() { | 116 void CONFIG::dump() { |
98 if (default_context) default_context->dump(); | 117 if (default_context) default_context->dump(); |
99 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { | 118 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
100 CONTEXTP c = *i; | 119 CONTEXTP c = *i; |
101 CONTEXTP p = c->get_parent(); | 120 CONTEXTP p = c->get_parent(); |
102 if (!p && (c != default_context)) c->dump(); | 121 if (!p && (c != default_context)) c->dump(); |
122 } | |
123 char buf[maxlen]; | |
124 for (context_map::iterator i=env_to.begin(); i!=env_to.end(); i++) { | |
125 char *to = (*i).first; | |
126 CONTEXTP con = (*i).second; | |
127 printf("// envelope to %s \t-> context %s \n", to, con->get_full_name(buf,maxlen)); | |
103 } | 128 } |
104 } | 129 } |
105 | 130 |
106 | 131 |
107 CONTEXT::CONTEXT(CONTEXTP parent_, char *name_) { | 132 CONTEXT::CONTEXT(CONTEXTP parent_, char *name_) { |
109 name = name_; | 134 name = name_; |
110 env_from_default = (parent) ? token_inherit : token_unknown; | 135 env_from_default = (parent) ? token_inherit : token_unknown; |
111 content_filtering = (parent) ? parent->content_filtering : false; | 136 content_filtering = (parent) ? parent->content_filtering : false; |
112 content_suffix = NULL; | 137 content_suffix = NULL; |
113 content_message = NULL; | 138 content_message = NULL; |
114 host_limit = 0; | 139 host_limit = (parent) ? parent->host_limit : 0; |
115 host_limit_message = NULL; | 140 host_limit_message = NULL; |
116 host_random = false; | 141 host_random = (parent) ? parent->host_random : false; |
117 tag_limit = 0; | 142 tag_limit = (parent) ? parent->tag_limit : 0; |
118 tag_limit_message = NULL; | 143 tag_limit_message = NULL; |
119 } | 144 } |
120 | 145 |
121 | 146 |
122 CONTEXT::~CONTEXT() { | 147 CONTEXT::~CONTEXT() { |
128 } | 153 } |
129 | 154 |
130 | 155 |
131 char *CONTEXT::get_full_name(char *buffer, int size) { | 156 char *CONTEXT::get_full_name(char *buffer, int size) { |
132 if (!parent) return name; | 157 if (!parent) return name; |
133 const int maxlen = 1000; | |
134 char buf[maxlen]; | 158 char buf[maxlen]; |
135 snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name); | 159 snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name); |
136 return buffer; | 160 return buffer; |
137 } | 161 } |
138 | 162 |
139 | 163 |
140 bool CONTEXT::cover_env_to(char *to) { | 164 bool CONTEXT::cover_env_to(char *to) { |
141 const int maxlen = 1000; | |
142 char buffer[maxlen]; | 165 char buffer[maxlen]; |
143 char *x = strchr(to, '@'); | 166 char *x = strchr(to, '@'); |
144 if (x) x++; | 167 if (x) x++; |
145 else x = to; | 168 else x = to; |
169 if (*x == '\0') return true; // always allow covering addresses with no domain name, eg abuse@ | |
146 string_set::iterator i = env_to.find(x); | 170 string_set::iterator i = env_to.find(x); |
147 if (i != env_to.end()) return true; | 171 if (i != env_to.end()) return true; |
148 return (parent) ? parent->cover_env_to(to) : false; | 172 return false; |
149 } | 173 } |
150 | 174 |
151 | 175 |
152 char *CONTEXT::find_from(char *from) { | 176 char *CONTEXT::find_from(char *from) { |
153 // do we have a white/black/unknown for this full from value? | |
154 string_map::iterator i = env_from.find(from); | 177 string_map::iterator i = env_from.find(from); |
155 if (i != env_from.end()) return (*i).second; | 178 if (i != env_from.end()) return (*i).second; // found user@domain.tld key |
156 // do we have a white/black/unknown for the source domain name? | |
157 char *x = strchr(from, '@'); | 179 char *x = strchr(from, '@'); |
158 if (x) { | 180 if (x) { |
159 x++; | 181 x++; |
160 i = env_from.find(x); | 182 i = env_from.find(x); |
161 if (i != env_from.end()) return (*i).second; | 183 if (i != env_from.end()) return (*i).second; // found domain.tld key |
184 char y = *x; | |
185 *x = '\0'; | |
186 i = env_from.find(from); | |
187 *x = y; | |
188 if (i != env_from.end()) return (*i).second; // found user@ key | |
162 } | 189 } |
163 if ((env_from_default == token_inherit) && parent) { | 190 if ((env_from_default == token_inherit) && parent) { |
164 return parent->find_from(from); | 191 return parent->find_from(from); |
165 } | 192 } |
166 return env_from_default; | 193 return (env_from_default == token_inherit) ? token_unknown : env_from_default; |
167 } | 194 } |
168 | 195 |
169 | 196 |
170 CONTEXTP CONTEXT::find_from_context(char *from) { | 197 CONTEXTP CONTEXT::find_context(char *from) { |
171 // do we have a special child context for this full from value? | 198 context_map::iterator i = env_from_context.find(from); |
172 context_map::iterator j = env_from_context.find(from); | 199 if (i != env_from_context.end()) return (*i).second; // found user@domain.tld key |
173 if (j != env_from_context.end()) { | |
174 CONTEXTP con = (*j).second; | |
175 return con->find_from_context(from); | |
176 } | |
177 char *x = strchr(from, '@'); | 200 char *x = strchr(from, '@'); |
178 if (x) { | 201 if (x) { |
179 x++; | 202 x++; |
180 // do we have a special context for the source domain name? | 203 i = env_from_context.find(x); |
181 j = env_from_context.find(x); | 204 if (i != env_from_context.end()) return (*i).second; // found domain.tld key |
182 if (j != env_from_context.end()) { | 205 char y = *x; |
183 CONTEXTP con = (*j).second; | 206 *x = '\0'; |
184 return con->find_from_context(from); | 207 i = env_from_context.find(from); |
185 } | 208 *x = y; |
209 if (i != env_from_context.end()) return (*i).second; // found user@ key | |
186 } | 210 } |
187 return this; | 211 return this; |
188 } | 212 } |
189 | 213 |
190 | 214 |
214 } | 238 } |
215 } | 239 } |
216 | 240 |
217 | 241 |
218 void CONTEXT::dump(int level) { | 242 void CONTEXT::dump(int level) { |
219 const int maxlen = 1000; | |
220 char indent[maxlen]; | 243 char indent[maxlen]; |
221 int i = min(maxlen-1, level*4); | 244 int i = min(maxlen-1, level*4); |
222 memset(indent, ' ', i); | 245 memset(indent, ' ', i); |
223 indent[i] = '\0'; | 246 indent[i] = '\0'; |
224 printf("%s context %s { \n", indent, name); | 247 char buf[maxlen]; |
248 char *fullname = get_full_name(buf,maxlen); | |
249 printf("%s context %s { \t// %s\n", indent, name, fullname); | |
225 | 250 |
226 for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) { | 251 for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) { |
227 char *n = (*i).first; | 252 char *n = (*i).first; |
228 DNSBL &d = *(*i).second; | 253 DNSBL &d = *(*i).second; |
229 printf("%s dnsbl %s %s \"%s\"; \n", indent, n, d.suffix, d.message); | 254 printf("%s dnsbl %s %s \"%s\"; \n", indent, n, d.suffix, d.message); |
274 } | 299 } |
275 else { | 300 else { |
276 printf("%s host_limit off; \n", indent); | 301 printf("%s host_limit off; \n", indent); |
277 } | 302 } |
278 if (tag_limit_message) { | 303 if (tag_limit_message) { |
279 printf("%s tag_limit on %d \"%s\"; \n", indent, tag_limit, tag_limit_message); | 304 printf("%s html_limit on %d \"%s\"; \n", indent, tag_limit, tag_limit_message); |
280 } | 305 } |
281 else { | 306 else { |
282 printf("%s tag_limit off; \n", indent); | 307 printf("%s html_limit off; \n", indent); |
283 } | 308 } |
284 printf("%s }; \n", indent); | 309 printf("%s }; \n", indent); |
285 } | 310 } |
286 else { | 311 else { |
287 printf("%s content off {}; \n", indent, env_from_default); | 312 printf("%s content off {}; \n", indent, env_from_default); |
288 } | 313 } |
289 | 314 |
290 printf("%s env_to { \n", indent); | 315 printf("%s env_to { \t// %s\n", indent, fullname); |
291 for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) { | 316 for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) { |
292 printf("%s %s; \n", indent, *i); | 317 printf("%s %s; \n", indent, *i); |
293 } | 318 } |
294 printf("%s }; \n", indent); | 319 printf("%s }; \n", indent); |
295 | 320 |
296 for (context_map::iterator i=children.begin(); i!=children.end(); i++) { | 321 for (context_map::iterator i=children.begin(); i!=children.end(); i++) { |
297 CONTEXTP c = (*i).second; | 322 CONTEXTP c = (*i).second; |
298 c->dump(level+1); | 323 c->dump(level+1); |
299 } | 324 } |
300 | 325 |
301 printf("%s env_from %s { \n", indent, env_from_default); | 326 printf("%s env_from %s { \t// %s\n", indent, env_from_default, fullname); |
302 if (!env_from.empty()) { | 327 if (!env_from.empty()) { |
303 printf("%s // white/black/unknown \n", indent); | 328 printf("%s // white/black/unknown \n", indent); |
304 for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) { | 329 for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) { |
305 char *f = (*i).first; | 330 char *f = (*i).first; |
306 char *t = (*i).second; | 331 char *t = (*i).second; |
307 printf("%s %s \t %s; \n", indent, f, t); | 332 printf("%s %s \t%s; \n", indent, f, t); |
308 } | 333 } |
309 } | 334 } |
310 if (!env_from_context.empty()) { | 335 if (!env_from_context.empty()) { |
311 printf("%s // child contexts \n", indent); | 336 printf("%s // child contexts \n", indent); |
312 for (context_map::iterator j=env_from_context.begin(); j!=env_from_context.end(); j++) { | 337 for (context_map::iterator j=env_from_context.begin(); j!=env_from_context.end(); j++) { |
313 char *f = (*j).first; | 338 char *f = (*j).first; |
314 CONTEXTP t = (*j).second; | 339 CONTEXTP t = (*j).second; |
315 printf("%s %s \t %s; \n", indent, f, t->name); | 340 printf("%s %s \t%s; \n", indent, f, t->name); |
316 } | 341 } |
317 } | 342 } |
318 printf("%s }; \n", indent); | 343 printf("%s }; \n", indent); |
319 | 344 |
320 printf("%s }; \n", indent); | 345 printf("%s }; \n", indent); |
400 | 425 |
401 //////////////////////////////////////////////// | 426 //////////////////////////////////////////////// |
402 // | 427 // |
403 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me); | 428 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
404 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me) { | 429 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
430 bool topdefault = (!me.get_parent()) && (!dc.default_context); | |
405 char *setting = tok.next(); | 431 char *setting = tok.next(); |
406 if (setting == token_on) { | 432 if (setting == token_on) { |
407 me.set_content_filtering(true); | 433 me.set_content_filtering(true); |
408 } | 434 } |
409 else if (setting == token_off) { | 435 else if (setting == token_off) { |
416 if (!tsa(tok, token_lbrace)) return false; | 442 if (!tsa(tok, token_lbrace)) return false; |
417 while (true) { | 443 while (true) { |
418 char *have = tok.next(); | 444 char *have = tok.next(); |
419 if (!have) break; | 445 if (!have) break; |
420 if (have == token_filter) { | 446 if (have == token_filter) { |
421 me.set_content_suffix(tok.next()); | 447 char *suffix = tok.next(); |
422 me.set_content_message(tok.next()); | 448 char *messag = tok.next(); |
449 if (topdefault) { | |
450 me.set_content_suffix(suffix); | |
451 me.set_content_message(messag); | |
452 } | |
423 if (!tsa(tok, token_semi)) return false; | 453 if (!tsa(tok, token_semi)) return false; |
454 if (!topdefault) tok.token_error("content filters may only be speciried in the top default context"); | |
424 } | 455 } |
425 else if (have == token_ignore) { | 456 else if (have == token_ignore) { |
426 if (!tsa(tok, token_lbrace)) return false; | 457 if (!tsa(tok, token_lbrace)) return false; |
427 while (true) { | 458 while (true) { |
428 if (!have) break; | 459 if (!have) break; |
443 if (!have) break; | 474 if (!have) break; |
444 if (have == token_rbrace) { | 475 if (have == token_rbrace) { |
445 break; // done | 476 break; // done |
446 } | 477 } |
447 else { | 478 else { |
448 me.add_tld(have); | 479 if (topdefault) me.add_tld(have); |
449 } | 480 } |
450 } | 481 } |
451 if (!tsa(tok, token_semi)) return false; | 482 if (!tsa(tok, token_semi)) return false; |
483 if (!topdefault) tok.token_error("tld values may only be specified in the top default context"); | |
452 } | 484 } |
453 else if (have == token_html_limit) { | 485 else if (have == token_html_limit) { |
454 have = tok.next(); | 486 have = tok.next(); |
455 if (have == token_on) { | 487 if (have == token_on) { |
456 me.set_tag_limit(tok.nextint()); | 488 me.set_tag_limit(tok.nextint()); |
473 if (!have) break; | 505 if (!have) break; |
474 if (have == token_rbrace) { | 506 if (have == token_rbrace) { |
475 break; // done | 507 break; // done |
476 } | 508 } |
477 else { | 509 else { |
478 me.add_tag(have); | 510 if (topdefault) me.add_tag(have); |
479 } | 511 } |
480 } | 512 } |
481 if (!tsa(tok, token_semi)) return false; | 513 if (!tsa(tok, token_semi)) return false; |
514 if (!topdefault) tok.token_error("html tags may only be specified in the top default context"); | |
482 } | 515 } |
483 else if (have == token_host_limit) { | 516 else if (have == token_host_limit) { |
484 have = tok.next(); | 517 have = tok.next(); |
485 if (have == token_on) { | 518 if (have == token_on) { |
486 me.set_host_limit(tok.nextint()); | 519 me.set_host_limit(tok.nextint()); |
550 me.add_to(have); | 583 me.add_to(have); |
551 dc.add_to(have, &me); | 584 dc.add_to(have, &me); |
552 } | 585 } |
553 } | 586 } |
554 } | 587 } |
588 else if (have == token_substitute) { | |
589 if (tok.next() == token_mailhost) { | |
590 have = tok.next(); | |
591 if (keeping) { | |
592 if (me.allow_env_to(have)) { | |
593 me.add_to(have); | |
594 dc.add_to(have, &me); | |
595 } | |
596 } | |
597 } | |
598 } | |
555 tok.skipeol(); | 599 tok.skipeol(); |
556 } | 600 } |
557 } | 601 } |
558 else if (me.allow_env_to(have)) { | 602 else if (me.allow_env_to(have)) { |
559 me.add_to(have); | 603 me.add_to(have); |
560 dc.add_to(have, &me); | 604 dc.add_to(have, &me); |
561 } | 605 } |
562 else { | 606 else { |
563 tok.token_error("valid env_to address or domain name", have); | 607 tok.token_error("user@ or user@domain.tld or domain.tld where domain.tld allowed by parent context", have); |
564 return false; | 608 return false; |
565 } | 609 } |
566 } | 610 } |
567 return tsa(tok, token_semi); | 611 return tsa(tok, token_semi); |
568 } | 612 } |
571 //////////////////////////////////////////////// | 615 //////////////////////////////////////////////// |
572 // | 616 // |
573 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me); | 617 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
574 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me) { | 618 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
575 char *st = tok.next(); | 619 char *st = tok.next(); |
576 if ((st == token_black) || (st == token_white) || (st == token_unknown)) { | 620 if ((st == token_black) || (st == token_white) || (st == token_unknown) || (st == token_inherit)) { |
577 me.set_from_default(st); | 621 me.set_from_default(st); |
578 } | 622 } |
579 else { | 623 else { |
580 tok.push(st); | 624 tok.push(st); |
581 } | 625 } |
610 continue; | 654 continue; |
611 } | 655 } |
612 if (have == token_envfrom) { | 656 if (have == token_envfrom) { |
613 have = tok.next(); | 657 have = tok.next(); |
614 if (keeping) { | 658 if (keeping) { |
659 me.add_from(have, (many) ? token_black : token_white); | |
660 } | |
661 } | |
662 else if (have == token_substitute) { | |
663 if (tok.next() == token_mailhost) { | |
664 have = tok.next(); | |
615 me.add_from(have, (many) ? token_black : token_white); | 665 me.add_from(have, (many) ? token_black : token_white); |
616 } | 666 } |
617 } | 667 } |
618 tok.skipeol(); | 668 tok.skipeol(); |
619 } | 669 } |
728 token_html_tags = register_string("html_tags"); | 778 token_html_tags = register_string("html_tags"); |
729 token_ignore = register_string("ignore"); | 779 token_ignore = register_string("ignore"); |
730 token_include = register_string("include"); | 780 token_include = register_string("include"); |
731 token_inherit = register_string("inherit"); | 781 token_inherit = register_string("inherit"); |
732 token_lbrace = register_string("{"); | 782 token_lbrace = register_string("{"); |
783 token_mailhost = register_string("mail_host"); | |
733 token_many = register_string("many"); | 784 token_many = register_string("many"); |
734 token_off = register_string("off"); | 785 token_off = register_string("off"); |
735 token_ok = register_string("ok"); | 786 token_ok = register_string("ok"); |
736 token_ok2 = register_string("ok2"); | 787 token_ok2 = register_string("ok2"); |
737 token_on = register_string("on"); | 788 token_on = register_string("on"); |
738 token_rbrace = register_string("}"); | 789 token_rbrace = register_string("}"); |
739 token_semi = register_string(";"); | 790 token_semi = register_string(";"); |
740 token_soft = register_string("soft"); | 791 token_soft = register_string("soft"); |
792 token_substitute = register_string("substitute"); | |
741 token_tld = register_string("tld"); | 793 token_tld = register_string("tld"); |
742 token_unknown = register_string("unknown"); | 794 token_unknown = register_string("unknown"); |
743 token_white = register_string("white"); | 795 token_white = register_string("white"); |
744 } | 796 } |