/* Distributed Checksum Clearinghouse * * common threaded client definitions * * Copyright (c) 2006 by Rhyolite Software, LLC * * This agreement is not applicable to any entity which sells anti-spam * solutions to others or provides an anti-spam solution as part of a * security solution sold to other entities, or to a private network * which employs the DCC or uses data provided by operation of the DCC * but does not provide corresponding data to other users. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * Parties not eligible to receive a license under this agreement can * obtain a commercial license to use DCC and permission to use * U.S. Patent 6,330,590 by contacting Commtouch at http://www.commtouch.com/ * or by email to nospam@commtouch.com. * * A commercial license would be for Distributed Checksum and Reputation * Clearinghouse software. That software includes additional features. This * free license for Distributed ChecksumClearinghouse Software does not in any * way grant permision to use Distributed Checksum and Reputation Clearinghouse * software * * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * * Rhyolite Software DCC 1.3.50-1.67 $Revision$ */ #ifndef CLNT_DEFS_H #define CLNT_DEFS_H #include "dcc_ck.h" #include "dcc_xhdr.h" #include "dcc_heap_debug.h" #ifdef HAVE_PTHREAD_H #include #else #include #endif #include #include #include #include /* what to do about checksums whose counts say "spam" */ typedef enum { CMN_REJECT = 0, /* tell sendmail to reject spam */ CMN_DISCARD, /* discard spam */ CMN_IGNORE, /* ignore spam reports */ } CMN_ACTION; extern CMN_ACTION action; typedef enum { SETHDR, ADDHDR, NOHDR } CHGHDR; extern CHGHDR chghdr; struct reply { const char *log_result; /* "reject" etc. for log */ char rcode[sizeof("5yz")]; char xcode[sizeof("1.2.3")]; # define REPLY_BUF_LEN 256 char buf[REPLY_BUF_LEN]; /* pattern or generated SMTP message */ }; extern REPLY reject_reply; #define DCC_RCODE "550" #define DCC_XCODE "5.7.1" extern REPLY grey_reply; extern REPLY reputation_reply; extern REPLY dcc_fail_reply; typedef struct { int msgs; /* total messages */ int tgts; /* total addressees */ int tgts_discarded; /* discarded for this many addressess */ int tgts_rejected; int tgts_ignored; int tgts_embargoed; int msgs_embargoed; int msgs_spam; time_t msg_prev, msg_next; } TOTALS; extern TOTALS totals; /* This is a wild guess of open files hidden in libraries and elsewhere. * Some systems such as Solaris seem to have an amazing number of them * Each whitelist context involves an open hash table file */ #define EXTRA_FILES (32 + NUM_CWFS) /* Some of these flags are computed for all recipients (e.g. white- or * blacklisting from the main whiteclnt file) in the common flags and * then copied to individual recipient flags words. * Others are kept only in the common word. */ typedef u_short RCPT_FGS; # define RCPT_FG_NULL_WHITECLNT 0x0001 /* no entries in it */ # define RCPT_FG_REJ_FILTER 0x0002 /* rejected by dccifd or dccm */ # define RCPT_FG_BAD_USERNAME 0x0004 /* user bad & rejected by MTA */ # define RCPT_FG_WLIST_ISSPAM 0x0008 /* whiteclnt blacklisted */ # define RCPT_FG_WLIST_NOTSPAM 0x0010 /* whiteclnt whitelisted */ # define RCPT_FG_WHITE 0x0020 # define RCPT_FG_BLACK 0x0040 # define RCPT_FG_ISSPAM 0x0080 /* result for this target */ # define RCPT_FG_GREY_END 0x0100 /* end of greylist embargo */ # define RCPT_FG_GREY_WHITE 0x0200 /* whitelisted for greylist */ /* per-recipient state */ typedef struct rcpt_st { struct rcpt_st *fwd; struct cmn_work *cwp; off_t log_pos_to; /* env_To line in main log file */ off_t log_pos_white; DCC_CKS_WTGTS wtgts; DCC_TGTS env_to_tgts, user_tgts; ASK_GREY_RESULT grey_result; u_int embargo_num; DCC_SUM wf_sum; DCC_CKSUM_THOLDS tholds_rej; FLTR_SWS sws; RCPT_FGS fgs; RCPT_FGS global_env_to_fgs; RCPT_FGS env_to_fgs; # define RCTP_MAXNAME 257 /* sendmail MAXNAME limit */ char env_to[RCTP_MAXNAME]; /* env_to */ char user[RCTP_MAXNAME]; /* mailbox */ char rej_msg[REPLY_BUF_LEN]; const char *rej_result; DCC_SUM env_to_sum; DCC_SUM user_sum; DCC_SUM msg_sum; DCC_SUM triple_sum; DCC_PATH dir; /* recipient's whitelist and logdir */ DCC_PATH user_log_nm; } RCPT_ST; /* per message state common to threaded DCC clients */ struct cmn_work { struct work *wp; DCC_CLNT_CTXT *dcc_ctxt; DNSBL_WORK *dnsbl_work; u_int dcc_ctxt_sn; struct timeval ldate; CMN_ACTION action; u_int xhdr_len; char xhdr[sizeof(DCC_XHDR_START)+sizeof(DCC_BRAND)+1]; char clnt_name[MAXHOSTNAMELEN]; /* SMTP client */ char clnt_str[INET6_ADDRSTRLEN+1]; struct in6_addr clnt_addr; char sender_name[MAXHOSTNAMELEN]; /* source of mail message */ char sender_str[INET6_ADDRSTRLEN+1]; struct in6_addr sender_addr; char helo[DCC_HELO_MAX]; char env_from[DCC_ENV_FROM_MAX+1]; char mail_host[MAXHOSTNAMELEN]; /* Mail_From host name */ char id[DCC_MSG_ID_LEN+1]; DCC_EMSG emsg; DCC_PATH tmp_nm; DCC_PATH log_nm; /* log file for this message */ int num_rcpts; # define MAX_RCPTS 1024 RCPT_ST *rcpt_st_first, *rcpt_st_last; int log_fd; /* -1=none */ int tmp_fd; /* copy of entire message */ DCC_HEADER_BUF header; EARLY_LOG early_log; u_short cmn_fgs; # define CMN_FG_ENV_LOGGED 0x0001 /* have logged the envelope */ # define CMN_FG_LOG_EARLY 0x0002 /* too early to write to log file */ # define CMN_FG_CHECK_REP 0x0004 /* check DCC reputations */ # define CMN_FG_FROM_MX 0x0008 /* don't reject MX secondary */ # define CMN_FG_FROM_SUBMIT 0x0010 /* SMTP submission clients */ # define CMN_FG_MTA_QUERY 0x0020 # define CMN_FG_LOCAL_SPAM 0x0040 # define CMN_FG_LOG_ENV_TO 0x0080 /* >=1 env_to checksum to log */ # define CMN_FG_THOLDS_SET 0x0100 DCC_GOT_CKS cks; #define CMN_WORK_ZERO log_ip_pos /* here down cleared for each msg */ off_t log_ip_pos; /* position and length of IP: line */ int log_ip_len; off_t log_pos_to_first; /* first env_To line in log file */ off_t log_pos_to_end; /* end of env_To lines in log file */ off_t log_pos_white_first; /* first white-list result */ off_t log_pos_white_last; /* last white-list result */ REPLY reply; const REPLY *dnsbl_reply; DCC_TGTS tgts; /* total accepted Mail_From values */ DCC_TGTS white_tgts; /* # ->tgts whitelisting message */ DCC_TGTS reject_tgts; /* # ->tgts rejecting message */ DCC_TGTS deliver_tgts; /* # ->tgts wanting the message */ DCC_TGTS mta_rej_tgts; /* not accepted by order of MTA */ DCC_TGTS early_grey_tgts; /* report to DCC if embargoed */ DCC_TGTS late_grey_tgts; /* don't report to DCC if delivered */ DCC_TGTS local_tgts; /* what we told the DCC server */ #if MAX_LOG_SIZE > 0 int log_size; #endif DCC_CKS_WTGTS wtgts; FLTR_SWS init_sws; /* initial value for rcpt_st->sws */ FLTR_SWS rcpts_sws; /* common among recipients */ RCPT_FGS rcpt_fgs; ASK_ST ask_st; /* ASK_ST_* */ }; extern const char *tmpdir; extern u_int dcc_ctxt_sn; /* change X-DCC header server name */ extern RCPT_ST *rcpt_st_free; const char *userdirs; extern u_char dcc_query_only; extern u_char discard_nok_def; /* 0=discard on whitelist conflicts */ extern u_char per_user_tholds_ok; /* 1=DCC thresholds in whiteclnt */ extern u_char try_extra_hard; /* 1=don't quit if DCC server dead */ extern u_char to_white_only; extern const char *mapfile_nm; extern const char *main_white_nm; extern pthread_mutex_t user_log_mutex; extern pthread_t user_log_owner; extern void clnt_sigs_off(sigset_t *); extern void parse_userdirs(const char *); extern u_char get_user_dir(RCPT_ST *, const char *, int, const char *, int); extern void parse_reply(REPLY *, u_char, const char *, const char *, const char *, const char *); extern void parse_reply_arg(const char *); extern void make_reply(REPLY *, const REPLY *, const CMN_WORK *); extern void finish_replies(void); extern void cmn_init(DCC_EMSG); extern void cmn_create(CMN_WORK *); extern u_char cmn_open_tmp(CMN_WORK *); extern void cmn_close_tmp(CMN_WORK *); extern u_char cmn_write_tmp(CMN_WORK *cwp, const void *, int); extern u_char check_mx_listing(CMN_WORK *); extern void cmn_clear(CMN_WORK *, struct work *, u_char); extern void create_rcpt_sts(int); extern void free_rcpt_sts(CMN_WORK *, u_char); extern RCPT_ST *alloc_rcpt_st(CMN_WORK *, u_char); extern void log_start(CMN_WORK *); extern void log_stop(CMN_WORK *); extern void log_write(CMN_WORK *, const void *, u_int); extern void log_body_write(CMN_WORK *, const char *, u_int); #define LOG_CMN_CAPTION(cwp, s) log_write(cwp, s, STRZ(s)) #define LOG_CMN_EOL(cwp) LOG_CMN_CAPTION(cwp, "\n") #define LOG_CAPTION(wp, s) LOG_CMN_CAPTION(&(wp)->cw, s) #define LOG_EOL(wp) LOG_CAPTION(wp, "\n") extern off_t log_lseek_get(CMN_WORK *); extern void thr_log_late(CMN_WORK *); extern void thr_log_envelope(CMN_WORK *, u_char); extern u_char ck_dcc_ctxt(CMN_WORK *); extern u_char cmn_compat_whitelist(CMN_WORK *, RCPT_ST *); extern void cmn_ask_white(CMN_WORK *, u_char); extern int cmn_ask_dcc(CMN_WORK *); extern void users_process(CMN_WORK *); extern void users_log_result(CMN_WORK *, const char *); extern void user_reject_discard(CMN_WORK *, RCPT_ST *); extern void log_smtp_reply(CMN_WORK *); extern void totals_init(void); extern void totals_stop(void); extern void totals_msg(void); #endif /* CLNT_DEFS_H */