Mercurial > dnsbl
view src/context.h @ 211:4db1457cd11a stable-6-0-18
Extend auto-whitelisting when receiving mail even if the auto whitelist is specified in a parent context.
Fixes for Solaris from sm-archive.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 22 Mar 2008 11:19:36 -0700 |
parents | 8f4a9a37d4d9 |
children | 82886d4dd71f |
line wrap: on
line source
/* Copyright (c) 2007 Carl Byington - 510 Software Group, released under the GPL version 3 or any later version at your choice available at http://www.gnu.org/licenses/gpl-3.0.txt */ #ifndef context_include #define context_include #include "tokenizer.h" #include <map> #include <regex.h> enum status {oksofar, // not rejected yet white, // whitelisted black, // blacklisted reject}; // rejected by a dns list class DNSBL; class CONTEXT; class VERIFY; class SMTP; class WHITELISTER; class DELAYWHITE; class recorder; typedef map<char *, char *, ltstr> string_map; typedef set<int> int_set; typedef list<SMTP *> smtp_list; typedef list<char *> string_list; typedef DNSBL * DNSBLP; typedef VERIFY * VERIFYP; typedef WHITELISTER * WHITELISTERP; typedef DELAYWHITE * DELAYWHITEP; typedef list<DNSBLP> dnsblp_list; typedef map<char *, DNSBLP, ltstr> dnsblp_map; typedef CONTEXT * CONTEXTP; typedef list<CONTEXTP> context_list; typedef map<char *, CONTEXTP, ltstr> context_map; typedef map<char *, int, ltstr> ns_mapper; typedef map<char *, int, ltstr> rcpt_rates; typedef map<char *, time_t, ltstr> autowhite_sent; typedef map<char *, VERIFYP, ltstr> verify_map; typedef map<char *, WHITELISTERP, ltstr> whitelister_map; typedef list<DELAYWHITEP> delay_whitelist; class SMTP { static const int maxlen = 1000; int fd; bool error; time_t stamp; char efrom[maxlen]; // last envelope from sent on this socket int pending; // unread bytes in buffer, not including the null terminator char buffer[maxlen]; public: SMTP(int f) {fd = f; error = false; now(); efrom[0] = '\0'; init();}; ~SMTP() {if (!error) quit(); closefd();}; void init() {pending = 0; buffer[0] = '\0';}; void append(char *c) {strncat(buffer, c, max(0, maxlen-1-(int)strlen(c)));}; bool err() {return error;}; void now() {stamp = time(NULL);}; time_t get_stamp() {return stamp;}; int get_fd() {return fd;}; int writer(); int reader(); int read_line(); int read_response(); void flush_line(int r); int cmd(char *c); int helo(); int rset(); int from(char *f); int rcpt(char *t); int quit(); void closefd(); #ifdef VERIFY_DEBUG static void log(char *m, int v); static void log(char *m, char *v); #endif }; class VERIFY { char *host; // host to be used to verify recipient addresses time_t last_err; // time of last socket error pthread_mutex_t mutex; // protect the lists of sockets and timestamps smtp_list connections;// open sockets, ready to be used public: VERIFY(char *h); void closer(); // if the oldest socket is ancient, close it SMTP *get_connection(); void put_connection(SMTP *conn); bool ok(char *from, char *to); }; class WHITELISTER { char *fn; // file to use int days; // how long do we keep entries pthread_mutex_t mutex; // protect the flag and map time_t loaded; // when we loaded this file bool need; // force writing on new entries autowhite_sent rcpts; // recipient map to remember when we sent them mail public: WHITELISTER(char *f, int d); void merge(); void writer(); // dump any changes back to the file void sent(char *to); bool is_white(char *from); // should we white list this sender (did we send them anything recently) int get_days() {return days;}; void set_days(int d) {days = d;}; }; class DELAYWHITE { char* loto; WHITELISTERP w; CONTEXTP con; public: DELAYWHITE(char *loto_, WHITELISTERP w_, CONTEXTP con_); char *get_loto() {return loto;}; WHITELISTERP get_w() {return w;}; CONTEXTP get_con() {return con;}; }; struct DNSBL { char *name; // nickname for this dns based list char *suffix; // blacklist suffix like blackholes.five-ten-sg.com char *message; // error message with one or two %s operators for the ip address replacement DNSBL(char *n, char *s, char *m); bool operator==(const DNSBL &rhs); }; class CONTEXT { CONTEXTP parent; char * name; context_map children; // map child context names to their contexts string_set env_to; // this context applies to these envelope recipients char * verify_host; // use this smtp host to verify email addresses VERIFYP verifier; // pointer to the verifier structure char * generic_regx; // pointer to generic regular expression char * generic_message; // pointer to generic message with one %s regex_t generic_pattern; // compiled regex pattern char * autowhite_file; // file to use for automatic whitelisting WHITELISTERP whitelister; // pointer to the auto whitelister structure string_map env_from; // map senders to white/black/unknown context_map env_from_context; // map senders to a child context char * env_from_default; // default value for senders that are not found in the map white/black/unknown/inherit bool content_filtering; // char * content_suffix; // for url body filtering based on ip addresses of hostnames in the body char * content_message; // "" char * uribl_suffix; // for uribl body filtering based on hostnames in the body char * uribl_message; // "" string_set content_host_ignore;// hosts to ignore for content sbl checking string_set content_tlds; // string_set content_cctlds; // string_set html_tags; // set of valid html tags int host_limit; // limit on host names char * host_limit_message; // error message for excessive host names bool host_random; // pick a random selection of host names rather than error for excessive hosts int tag_limit; // limit on bad html tags char * tag_limit_message; // error message for excessive bad html tags int spamassassin_limit; // max score from spamassassin bool require_match; // require matching context filtering context bool dcc_greylist; // should we do dcc greylisting? int dcc_bulk_threshold; // off = 0, many = 1000 dnsblp_map dnsbl_names; // name to dnsbl mapping for lists that are available in this context and children dnsblp_list dnsbl_list; // list of dnsbls to be used in this context int default_rcpt_rate; // if not specified per user rcpt_rates rcpt_per_hour; // per user limits on number of recipients per hour public: CONTEXT(CONTEXTP parent_, char *name_); ~CONTEXT(); CONTEXTP get_parent() {return parent;}; bool is_parent(CONTEXTP p); // is p a parent of this? char* get_full_name(char *buf, int size); void add_context(CONTEXTP child) {children[child->name] = child;}; bool allow_env_to(char *to) {return (parent) ? parent->cover_env_to(to) : true;}; bool cover_env_to(char *to); void set_verifier(VERIFYP v) {verifier = v;}; void set_verify(char *host) {verify_host = host;}; char* get_verify() {return verify_host;}; VERIFYP find_verify(char *to); void set_whitelister(WHITELISTERP v) {whitelister = v;}; void set_autowhite(char *fn) {autowhite_file = fn;}; char* get_autowhite() {return autowhite_file;}; WHITELISTERP find_autowhite(char *from, char *to); void set_default_rate(int limit) {default_rcpt_rate = limit;}; void add_rate(char *user, int limit) {rcpt_per_hour[user] = limit;}; int find_rate(char *user); void add_to(char *to) {env_to.insert(to);}; void add_from(char *from, char *status) {env_from[from] = status;}; void add_from_context(char *from, CONTEXTP con) {env_from_context[from] = con;}; void set_from_default(char *status) {env_from_default = status;}; char* find_from(char *from, bool update_white = false); CONTEXTP find_context(char *from); CONTEXTP find_from_context_name(char *name); void set_content_filtering(bool filter) {content_filtering = filter; }; void set_content_suffix(char *suffix) {content_suffix = suffix; }; void set_content_message(char *message) {content_message = message; }; void set_uribl_suffix(char *suffix) {uribl_suffix = suffix; }; void set_uribl_message(char *message) {uribl_message = message; }; void add_ignore(char *host) {content_host_ignore.insert(host);}; void add_tld(char *tld) {content_tlds.insert(tld); }; void add_cctld(char *cctld) {content_cctlds.insert(cctld); }; void set_host_limit(int limit) {host_limit = limit; }; void set_host_message(char *message) {host_limit_message = message;}; void set_host_random(bool random) {host_random = random; }; void set_spamassassin_limit(int limit) {spamassassin_limit = limit; }; void set_tag_limit(int limit) {tag_limit = limit; }; void set_tag_message(char *message) {tag_limit_message = message;}; void add_tag(char *tag) {html_tags.insert(tag); }; void add_dnsbl(char *name, DNSBLP dns) {dnsbl_names[name] = dns; }; void add_dnsbl(DNSBLP dns) {dnsbl_list.push_back(dns);}; DNSBLP find_dnsbl(char *name); bool set_generic(char *regx, char *msg); char* generic_match(char *client); void set_require(bool r) {require_match = r; }; void set_grey(bool g) {dcc_greylist = g; }; void set_bulk(int b) {dcc_bulk_threshold = b; }; bool get_content_filtering() {return content_filtering; }; bool get_require() {return content_filtering && require_match; }; bool get_grey() {return content_filtering && dcc_greylist; }; int get_bulk() {return (content_filtering) ? dcc_bulk_threshold : 0;}; int get_host_limit() {return (content_filtering) ? host_limit : 0;}; bool get_host_random() {return (content_filtering) ? host_random : 0;}; int get_spamassassin_limit() {return (content_filtering) ? spamassassin_limit : 0;}; char* get_content_suffix(); char* get_content_message(); char* get_uribl_suffix(); char* get_uribl_message(); string_set& get_content_host_ignore(); string_set& get_content_tlds(); string_set& get_content_cctlds(); string_set& get_html_tags(); dnsblp_list& get_dnsbl_list(); bool acceptable_content(recorder &memory, int score, int bulk, string& msg); bool ignore_host(char *host); void dump(bool isdefault, bool &spamass, int level = 0); }; struct CONFIG { // the only mutable stuff once it has been loaded from the config file int reference_count; // protected by the global config_mutex // all the rest is constant after loading from the config file int generation; time_t load_time; string_set config_files; context_list contexts; // owns all the contexts, not just top level contexts context_map env_to; // map recipient to a filtering context CONTEXTP default_context;// for env_to values that don't have their own specific filtering context // the default context is also used for some of the content filtering values CONFIG(); ~CONFIG(); void add_context(CONTEXTP con); void add_to(char *to, CONTEXTP con); CONTEXTP find_context(char *to); void dump(); }; extern char *token_autowhite; extern char *token_black; extern char *token_cctld; extern char *token_content; extern char *token_context; extern char *token_dccbulk; extern char *token_dccfrom; extern char *token_dccgrey; extern char *token_dccto; extern char *token_default; extern char *token_dnsbl; extern char *token_dnsbll; extern char *token_envfrom; extern char *token_envto; extern char *token_filter; extern char *token_generic; extern char *token_host_limit; extern char *token_html_limit; extern char *token_html_tags; extern char *token_ignore; extern char *token_include; extern char *token_inherit; extern char *token_lbrace; extern char *token_mailhost; extern char *token_many; extern char *token_no; extern char *token_off; extern char *token_ok; extern char *token_ok2; extern char *token_on; extern char *token_rate; extern char *token_rbrace; extern char *token_require; extern char *token_semi; extern char *token_soft; extern char *token_spamassassin; extern char *token_substitute; extern char *token_tld; extern char *token_unknown; extern char *token_uribl; extern char *token_verify; extern char *token_white; extern char *token_yes; extern pthread_mutex_t verifier_mutex; // protect the verifier map extern pthread_mutex_t whitelister_mutex; // protect the void discard(string_set &s); char* register_string(string_set &s, char *name); char* register_string(char *name); void clear_strings(); CONFIG *parse_config(char *fn); bool load_conf(CONFIG &dc, char *fn); void* verify_closer(void *arg); void* whitelister_writer(void *arg); void token_init(); #endif