Mercurial > dnsbl
diff 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 |
line wrap: on
line diff
--- a/src/context.cpp Sun Jul 10 14:19:00 2005 -0700 +++ b/src/context.cpp Wed Jul 13 23:04:14 2005 -0700 @@ -28,19 +28,22 @@ char *token_include; char *token_inherit; char *token_lbrace; +char *token_mailhost; char *token_many; char *token_off; +char *token_ok2; char *token_ok; -char *token_ok2; char *token_on; char *token_rbrace; char *token_semi; char *token_soft; +char *token_substitute; char *token_tld; char *token_unknown; char *token_white; string_set all_strings; // owns all the strings, only modified by the config loader thread +const int maxlen = 1000; DNSBL::DNSBL(char *n, char *s, char *m) { name = n; @@ -74,23 +77,39 @@ } -CONTEXTP CONFIG::find_context(char *to, char *from) { - CONTEXTP con = NULL; - context_map::iterator i = env_to.find(from); +void CONFIG::add_to(char *to, CONTEXTP con) { + context_map::iterator i = env_to.find(to); if (i != env_to.end()) { - con = (*i).second; - return con->find_from_context(from); + CONTEXTP c = (*i).second; + if ((c != con) && (c != con->get_parent())) { + char oldname[maxlen]; + char newname[maxlen]; + char *oldn = c->get_full_name(oldname, maxlen); + char *newn = con->get_full_name(newname, maxlen); + char buf[maxlen*3]; + snprintf(buf, maxlen*3, "both %s and %s claim envelope to %s, the second one wins", oldn, newn, to); + my_syslog(buf); } + } + env_to[to] = con; +} + + +CONTEXTP CONFIG::find_context(char *to) { + context_map::iterator i = env_to.find(to); + if (i != env_to.end()) return (*i).second; // found user@domain.tld key char *x = strchr(to, '@'); if (x) { x++; i = env_to.find(x); - if (i != env_to.end()) { - con = (*i).second; - return con->find_from_context(from); + if (i != env_to.end()) return (*i).second; // found domain.tld key + char y = *x; + *x = '\0'; + i = env_to.find(to); + *x = y; + if (i != env_to.end()) return (*i).second; // found user@ key } - } - return default_context->find_from_context(from); + return default_context; } @@ -101,6 +120,12 @@ CONTEXTP p = c->get_parent(); if (!p && (c != default_context)) c->dump(); } + char buf[maxlen]; + for (context_map::iterator i=env_to.begin(); i!=env_to.end(); i++) { + char *to = (*i).first; + CONTEXTP con = (*i).second; + printf("// envelope to %s \t-> context %s \n", to, con->get_full_name(buf,maxlen)); + } } @@ -111,10 +136,10 @@ content_filtering = (parent) ? parent->content_filtering : false; content_suffix = NULL; content_message = NULL; - host_limit = 0; + host_limit = (parent) ? parent->host_limit : 0; host_limit_message = NULL; - host_random = false; - tag_limit = 0; + host_random = (parent) ? parent->host_random : false; + tag_limit = (parent) ? parent->tag_limit : 0; tag_limit_message = NULL; } @@ -130,7 +155,6 @@ char *CONTEXT::get_full_name(char *buffer, int size) { if (!parent) return name; - const int maxlen = 1000; char buf[maxlen]; snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name); return buffer; @@ -138,51 +162,51 @@ bool CONTEXT::cover_env_to(char *to) { - const int maxlen = 1000; char buffer[maxlen]; char *x = strchr(to, '@'); if (x) x++; else x = to; + if (*x == '\0') return true; // always allow covering addresses with no domain name, eg abuse@ string_set::iterator i = env_to.find(x); if (i != env_to.end()) return true; - return (parent) ? parent->cover_env_to(to) : false; + return false; } char *CONTEXT::find_from(char *from) { - // do we have a white/black/unknown for this full from value? string_map::iterator i = env_from.find(from); - if (i != env_from.end()) return (*i).second; - // do we have a white/black/unknown for the source domain name? + if (i != env_from.end()) return (*i).second; // found user@domain.tld key char *x = strchr(from, '@'); if (x) { x++; i = env_from.find(x); - if (i != env_from.end()) return (*i).second; + if (i != env_from.end()) return (*i).second; // found domain.tld key + char y = *x; + *x = '\0'; + i = env_from.find(from); + *x = y; + if (i != env_from.end()) return (*i).second; // found user@ key } if ((env_from_default == token_inherit) && parent) { return parent->find_from(from); } - return env_from_default; + return (env_from_default == token_inherit) ? token_unknown : env_from_default; } -CONTEXTP CONTEXT::find_from_context(char *from) { - // do we have a special child context for this full from value? - context_map::iterator j = env_from_context.find(from); - if (j != env_from_context.end()) { - CONTEXTP con = (*j).second; - return con->find_from_context(from); - } +CONTEXTP CONTEXT::find_context(char *from) { + context_map::iterator i = env_from_context.find(from); + if (i != env_from_context.end()) return (*i).second; // found user@domain.tld key char *x = strchr(from, '@'); if (x) { x++; - // do we have a special context for the source domain name? - j = env_from_context.find(x); - if (j != env_from_context.end()) { - CONTEXTP con = (*j).second; - return con->find_from_context(from); - } + i = env_from_context.find(x); + if (i != env_from_context.end()) return (*i).second; // found domain.tld key + char y = *x; + *x = '\0'; + i = env_from_context.find(from); + *x = y; + if (i != env_from_context.end()) return (*i).second; // found user@ key } return this; } @@ -216,12 +240,13 @@ void CONTEXT::dump(int level) { - const int maxlen = 1000; char indent[maxlen]; int i = min(maxlen-1, level*4); memset(indent, ' ', i); indent[i] = '\0'; - printf("%s context %s { \n", indent, name); + char buf[maxlen]; + char *fullname = get_full_name(buf,maxlen); + printf("%s context %s { \t// %s\n", indent, name, fullname); for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) { char *n = (*i).first; @@ -276,10 +301,10 @@ printf("%s host_limit off; \n", indent); } if (tag_limit_message) { - printf("%s tag_limit on %d \"%s\"; \n", indent, tag_limit, tag_limit_message); + printf("%s html_limit on %d \"%s\"; \n", indent, tag_limit, tag_limit_message); } else { - printf("%s tag_limit off; \n", indent); + printf("%s html_limit off; \n", indent); } printf("%s }; \n", indent); } @@ -287,7 +312,7 @@ printf("%s content off {}; \n", indent, env_from_default); } - printf("%s env_to { \n", indent); + printf("%s env_to { \t// %s\n", indent, fullname); for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) { printf("%s %s; \n", indent, *i); } @@ -298,7 +323,7 @@ c->dump(level+1); } - printf("%s env_from %s { \n", indent, env_from_default); + printf("%s env_from %s { \t// %s\n", indent, env_from_default, fullname); if (!env_from.empty()) { printf("%s // white/black/unknown \n", indent); for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) { @@ -402,6 +427,7 @@ // bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me); bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me) { + bool topdefault = (!me.get_parent()) && (!dc.default_context); char *setting = tok.next(); if (setting == token_on) { me.set_content_filtering(true); @@ -418,9 +444,14 @@ char *have = tok.next(); if (!have) break; if (have == token_filter) { - me.set_content_suffix(tok.next()); - me.set_content_message(tok.next()); + char *suffix = tok.next(); + char *messag = tok.next(); + if (topdefault) { + me.set_content_suffix(suffix); + me.set_content_message(messag); + } if (!tsa(tok, token_semi)) return false; + if (!topdefault) tok.token_error("content filters may only be speciried in the top default context"); } else if (have == token_ignore) { if (!tsa(tok, token_lbrace)) return false; @@ -445,10 +476,11 @@ break; // done } else { - me.add_tld(have); + if (topdefault) me.add_tld(have); } } if (!tsa(tok, token_semi)) return false; + if (!topdefault) tok.token_error("tld values may only be specified in the top default context"); } else if (have == token_html_limit) { have = tok.next(); @@ -475,10 +507,11 @@ break; // done } else { - me.add_tag(have); + if (topdefault) me.add_tag(have); } } if (!tsa(tok, token_semi)) return false; + if (!topdefault) tok.token_error("html tags may only be specified in the top default context"); } else if (have == token_host_limit) { have = tok.next(); @@ -552,6 +585,17 @@ } } } + else if (have == token_substitute) { + if (tok.next() == token_mailhost) { + have = tok.next(); + if (keeping) { + if (me.allow_env_to(have)) { + me.add_to(have); + dc.add_to(have, &me); + } + } + } + } tok.skipeol(); } } @@ -560,7 +604,7 @@ dc.add_to(have, &me); } else { - tok.token_error("valid env_to address or domain name", have); + tok.token_error("user@ or user@domain.tld or domain.tld where domain.tld allowed by parent context", have); return false; } } @@ -573,7 +617,7 @@ bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me); bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me) { char *st = tok.next(); - if ((st == token_black) || (st == token_white) || (st == token_unknown)) { + if ((st == token_black) || (st == token_white) || (st == token_unknown) || (st == token_inherit)) { me.set_from_default(st); } else { @@ -615,6 +659,12 @@ me.add_from(have, (many) ? token_black : token_white); } } + else if (have == token_substitute) { + if (tok.next() == token_mailhost) { + have = tok.next(); + me.add_from(have, (many) ? token_black : token_white); + } + } tok.skipeol(); } } @@ -730,6 +780,7 @@ token_include = register_string("include"); token_inherit = register_string("inherit"); token_lbrace = register_string("{"); + token_mailhost = register_string("mail_host"); token_many = register_string("many"); token_off = register_string("off"); token_ok = register_string("ok"); @@ -738,6 +789,7 @@ token_rbrace = register_string("}"); token_semi = register_string(";"); token_soft = register_string("soft"); + token_substitute = register_string("substitute"); token_tld = register_string("tld"); token_unknown = register_string("unknown"); token_white = register_string("white");