Mercurial > notdcc
view include/dcc_ck.h @ 3:b689077d4918
Ignore old patches
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 14:31:24 +0100 |
parents | c7f6b056b673 |
children |
line wrap: on
line source
/* Distributed Checksum Clearinghouse * * checksum routines * * Copyright (c) 2008 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 without * changes for any purpose with or without fee is hereby granted, provided * that the above copyright notice and this permission notice appear in all * copies and any distributed versions or copies are either unchanged * or not called anything similar to "DCC" or "Distributed Checksum * Clearinghouse". * * Parties not eligible to receive a license under this agreement can * obtain a commercial license to use DCC by contacting Rhyolite Software * at sales@rhyolite.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.103-1.182 $Revision$ */ #ifndef DCC_CK_H #define DCC_CK_H #include "dcc_clnt.h" #include "dcc_md5.h" typedef DCC_TGTS DCC_CKSUM_THOLDS[DCC_DIM_CKS]; #define DCC_THOLD_NEVER (DCC_TGTS_TOO_MANY+1) #define DCC_THOLD_UNSET (DCC_TGTS_INVALID) extern DCC_CKSUM_THOLDS dcc_tholds_rej; /* MIME boundary * RFC 1341 says boundaries can be 70 bytes, but handle non-conformant spam */ #define DCC_CK_BND_MAX 94 #define DCC_CK_BND_DIM (DCC_CK_BND_MAX+2) /* including leading -- */ #define DCC_CK_BND_MISS (DCC_CK_BND_DIM+1) typedef struct { u_char bnd_len; /* length including leading "--" */ u_char cmp_len; /* compared so far */ char bnd[DCC_CK_BND_DIM]; /* "--"boundary */ } DCC_CK_BND; typedef u_char DCC_CK_FC[256]; extern const DCC_CK_FC dcc_cset_1, dcc_cset_2; /* state machine for ignoring parts of URLs */ typedef struct { enum { DCC_URL_ST_IDLE, /* waiting for H or = */ DCC_URL_ST_QUOTE, /* " " '"' or 'H' after = */ DCC_URL_ST_QH, /* " " H after quote */ DCC_URL_ST_T1, /* " " T */ DCC_URL_ST_T2, /* " " T */ DCC_URL_ST_P, /* " " P */ DCC_URL_ST_S, /* " " [S] */ DCC_URL_ST_COLON, /* " " : */ DCC_URL_ST_SLASH1, /* " " / */ DCC_URL_ST_SLASH2, /* " " / */ DCC_URL_ST_SLASH3_START, DCC_URL_ST_SLASH3, /* " " third / */ DCC_URL_ST_SKIP /* skipping rest of URL */ } st; char *start; /* start of hostname in URL */ char *dot; /* last '.' in hostname */ int total; /* length of URL */ u_char flags; # define DCC_URL_QUOTED 0x01 # define DCC_URL_DEL_DOMAIN 0x02 /* waiting for domain to delete */ # define DCC_URL_PERCENT1 0x04 /* waiting for 1st digit after % */ # define DCC_URL_PERCENT2 0x08 /* waiting for 2nd digit after % */ # define DCC_URL_SQUOTED 0x10 /* single quoted (') URL */ # define DCC_URL_DQUOTED 0x20 /* double quoted (") URL */ # define DCC_URL_QUOTES (DCC_URL_DQUOTED | DCC_URL_SQUOTED) # define DCC_URL_SIMPLE (DCC_URL_DEL_DOMAIN \ | DCC_URL_PERCENT1 \ | DCC_URL_PERCENT2) u_char percent; } DCC_URL_SKIP; #define DCC_URL_MAX 65 /* 63 is RFC 1034 limit on labels */ #define DCC_URL_FAILSAFE 2000 /* big bogus "username:password@" */ /* a template for generating a reply to an SMTP command */ typedef enum { REPLY_TPLT_NULL, REPLY_TPLT_ID, /* queue ID for sendmail, fake for dccifd */ REPLY_TPLT_CIP, /* SMTP client IP address */ REPLY_TPLT_BTYPE, /* type of DNSBL hit */ REPLY_TPLT_BTGT, /* DNSBL hit IP address or name */ REPLY_TPLT_BPROBE, /* DNSBL probe domain name */ REPLY_TPLT_BRESULT /* DNSBL probe result */ } REPLY_TPLT_ARGS; typedef struct { const char *log_result; /* "reject" etc. for log */ # define NUM_REPLY_TPLT_ARGS 6 REPLY_TPLT_ARGS args[NUM_REPLY_TPLT_ARGS]; char rcode[sizeof("5yz")]; char xcode[sizeof("1.2.3")]; u_char is_pat; /* template has %s references */ # define REPLY_BUF_LEN 256 char pat[REPLY_BUF_LEN]; /* pattern for SMTP message */ } REPLY_TPLT; /* specify a DNS blacklist */ typedef struct { char c[DCC_MAXDOMAINLEN]; /* null terminated */ } DNSBL_DOM; typedef u_char DNSBL_FGS; #define DNSBL_FG_DUP 0x01 /* duplicate blacklist */ #define DNSBL_FG_TIMEO 0x02 /* suffered a timeout */ #define DNSBL_FG_TFAIL 0x04 /* want SMTP failure on timeout */ #define DNSBL_FG_CLIENT 0x08 /* check client IP address */ #define DNSBL_FG_MAIL_HOST 0x10 /* check env_from domain */ #define DNSBL_FG_URL 0x20 /* check URLs in message body */ #define DNSBL_FG_MX 0x40 /* MX for _URL & _MAIL_HOST */ #define DNSBL_FG_NS 0x80 /* NS for _URL & _MAIL_HOST */ # define DNSBL_FG_HITS (DNSBL_FG_CLIENT | DNSBL_FG_MAIL_HOST | DNSBL_FG_URL) # define DNSBL_FG_TYPES (DNSBL_FG_HITS | DNSBL_FG_MX | DNSBL_FG_NS) # define DNSBL_FG_DEFAULT DNSBL_FG_TYPES typedef enum DNSBL_TYPE { DNSBL_TYPE_IPV4, DNSBL_TYPE_IPV6, DNSBL_TYPE_NAME } DNSBL_TYPE; #define MAX_DNSBL_GROUPS 3 typedef u_char DNSBL_GBITS; #define DNSBL_G2B(n) ((1<<(n)) & ((2<<MAX_DNSBL_GROUPS)-1)) typedef struct dnsbl { struct dnsbl *fwd; struct dnsbl *dup; /* same except result */ u_char group; /* 1-indexed */ struct in6_addr tgt; /* hit if DNSBL matches this block */ struct in6_addr tgt_mask; u_char tgt_use_ipv6; /* ipv4 vs. ipv6 result weighting */ DNSBL_TYPE bl_type; int bl_num; int bl_dom_len; DNSBL_DOM bl_dom; const REPLY_TPLT *reply; DNSBL_FGS fgs; } DNSBL; /* working storage for one set of DNSBLs */ typedef struct { DNSBL_FGS fgs; /* kind of DNSBL hit */ const char *btype; /* type of hit string */ const DNSBL *dnsbl; /* hit DNSBL */ char btype_buf[64]; char result[DCC_SU2STR_SIZE]; /* IP address found in DNSBL */ DNSBL_DOM tgt; /* IP address or name sought in DNSBL */ DNSBL_DOM probe; /* what was actually looked up */ } DNSBL_GROUP; /* working storage for all DNSBLs */ typedef struct { DNSBL_DOM dom; /* domain name */ struct in6_addr addr; /* and/or IP address sought in DNSBL */ } DNSBL_TGT; typedef struct { DNSBL_GBITS all; DNSBL_GBITS client; DNSBL_GBITS mail_host; DNSBL_GBITS mail_host_ns; DNSBL_GBITS mail_host_mx; DNSBL_GBITS url; DNSBL_GBITS url_ns; DNSBL_GBITS url_mx; } DNSBL_UNHIT; typedef struct { DCC_CLNT_CTXT *dcc_ctxt; void *log_ctxt; const char *id; time_t msg_us; /* microseconds remaining for msg */ struct timeval url_start; time_t url_us; /* microseconds to look up URL */ time_t url_us_used; DNSBL_UNHIT unhit; /* groups of DNSBLs not yet hit */ u_short tgt_dom_len; DNSBL_TGT tgt; struct { DNSBL_DOM dom; } tgt_cache[8]; int tgt_cache_pos; DNSBL_GROUP groups[MAX_DNSBL_GROUPS]; } DNSBL_WORK; extern DNSBL *dnsbls; extern u_char have_dnsbl_groups; extern u_char have_helpers; extern DCC_PATH dnsbl_progpath; /* accumulated checksums for an SMTP message */ typedef struct { const char *hdr_nm; /* name if substitute checksum */ DCC_TGTS tgts; /* server's answer or previous total */ DCC_CK_TYPE_B type; u_char rpt2srvr; /* 1=report to server */ DCC_SUM sum; } DCC_GOT_SUM; #define CLR_GOT_SUM(g) ((g)->hdr_nm = 0, (g)->tgts = DCC_TGTS_INVALID, \ (g)->type = DCC_CK_INVALID, (g)->rpt2srvr = 0) typedef union { u_int32_t w32[4]; u_char b[16]; } DCC_FUZ2_WORD; #define DCC_FUZ2_WORD_CLEAR(_w) ((_w)->w32[0]=0, (_w)->w32[1]=0, \ (_w)->w32[2]=0, (_w)->w32[3]=0) typedef struct { DCC_URL_SKIP url; u_int total; /* bytes */ char *cp; /* end of data in buffer */ char *eol; /* most recent eol */ # define DCC_FUZ1_MAX_LINE 78 # define DCC_HTTPS_STR "https" # define DCC_HTTPS_LEN LITZ(DCC_HTTPS_STR) char buf[DCC_FUZ1_MAX_LINE*4 +DCC_HTTPS_LEN]; MD5_CTX md5; } DCC_CTX_FUZ1; typedef struct { /* per-language counts */ u_int wsummed; /* bytes of words summed */ u_int wtotal; /* words summed */ MD5_CTX md5; } FUZ2_LANG; typedef struct { u_int btotal; /* total non-whitespace bytes seen */ u_int xsummed; /* non-word bytes checksummed */ u_int wlen; /* length of current word */ u_int cref_cnt; /* fancy character length */ u_int tag_len; /* HTML tag length */ DCC_FUZ2_WORD w; DCC_FUZ2_WORD cref_w; DCC_FUZ2_WORD tag; int urls; /* # of URLs seen */ char *url_cp; /* accumulated URLs */ # define DCC_FUZ2_URL_MAX (1+DCC_URL_MAX) char url_buf[DCC_FUZ2_URL_MAX*2]; DCC_URL_SKIP url; /* state machine for skipping URLs */ enum { DCC_CREF_ST_IDLE = 0, DCC_CREF_ST_START, /* get HTML character reference */ DCC_CREF_ST_NUM, /* hex or decimal */ DCC_CREF_ST_DEC, DCC_CREF_ST_HEX, DCC_CREF_ST_NAME } cref_st; enum { DCC_FUZ2_ST_WORD = 0, /* gathering word */ DCC_FUZ2_ST_START_TAG, /* gathering start of HTML tag */ DCC_FUZ2_ST_SKIP_TAG, /* skipping HTML tag */ DCC_FUZ2_ST_SKIP_COMMENT /* skipping HTML comment */ } st; # define FUZ2_LAN_NUM 3 FUZ2_LANG lang[FUZ2_LAN_NUM]; } DCC_CTX_FUZ2; /* The maximum length of a checksumed HELO value and the continuation string * need to be the same for all users of the local white-/blacklist */ #define DCC_HELO_MAX (DCC_MAXDOMAINLEN+8) #define DCC_HELO_CONT "..." /* local-part maximum in RFC 2821 */ #define DCC_LOCAL_PART_MAX 64 #define DCC_ENV_FROM_MAX (DCC_LOCAL_PART_MAX+DCC_MAXDOMAINLEN) #define DCC_MSG_ID_LEN 24 /* do not checksum more than this much of a header line */ #define DCC_HDR_CK_MAX 1024 /* substitute or locally configured checksums */ #define DCC_MAX_SUB_CKS 6 #define DCC_WSUMS (DCC_DIM_CKS+DCC_MAX_SUB_CKS) /* max whitelist checksums */ typedef struct { DCC_GOT_SUM sums[DCC_WSUMS]; struct in6_addr ip_addr; /* SMTP client IP address */ struct { /* quoted-printable state machine */ int x; int y; u_char n; enum { DCC_CK_QP_IDLE, /* waiting for '=' */ DCC_CK_QP_EQ, /* seen "=" */ DCC_CK_QP_1, /* seen "=X" of "=XY" */ DCC_CK_QP_FAIL1, /* have output '=' after bad =X */ DCC_CK_QP_FAIL2, /* have output '=' after bad =XY */ DCC_CK_QP_FAIL3 /* have output 'X' after bad =XY */ } state; } qp; struct { /* base64 state machine */ u_int32_t quantum; int quantum_cnt; } b64; enum { CK_MP_ST_PREAMBLE, /* preamble before first boundary */ CK_MP_ST_BND, /* MIME boundary */ CK_MP_ST_HDRS, /* headers after a boundary */ CK_MP_ST_TEXT, /* body or entity */ CK_MP_ST_EPILOGUE /* text after last boundary */ } mp_st; enum CK_MHDR_ST { /* parse entity fields */ CK_MHDR_ST_IDLE, CK_MHDR_ST_CE_CT, /* matching "Content-T" */ CK_MHDR_ST_CE, /* "ransfer-Encoding:" */ CK_MHDR_ST_CE_WS, /* white space after "encoding:" */ CK_MHDR_ST_CT, /* "ype:" */ CK_MHDR_ST_CT_WS, /* white space after "type:" */ CK_MHDR_ST_QP, /* "quoted-printable" */ CK_MHDR_ST_B64, /* "base64" */ CK_MHDR_ST_TEXT, /* "text" */ CK_MHDR_ST_HTML, /* "/html" */ CK_MHDR_ST_CSET_SKIP_PARAM, /* skip to ";" after "text" */ CK_MHDR_ST_CSET_SPAN_WS, /* skip blanks before "charset" */ CK_MHDR_ST_CSET, /* match "charset=" */ CK_MHDR_ST_CSET_ISO_8859, /* "ISO-8859-" */ CK_MHDR_ST_CSET_ISO_X, /* find the 8859 type number */ CK_MHDR_ST_MULTIPART, /* match "multipart" */ CK_MHDR_ST_BND_SKIP_PARAM, /* skip "/alternative;" or similar */ CK_MHDR_ST_BND_SPAN_WS, /* skip whitespace before "boundary" */ CK_MHDR_ST_BND, /* match "boundary=" */ CK_MHDR_ST_BND_VALUE /* collecting boundary */ } mhdr_st; u_char mhdr_pos; u_char mime_nest; /* # of nested MIME entities */ u_char mime_bnd_matches; /* # of active boundary matches */ DCC_CK_BND mime_bnd[3]; enum { DCC_CK_CT_TEXT = 0, DCC_CK_CT_HTML, DCC_CK_CT_BINARY } mime_ct; const u_char *mime_cset; enum { DCC_CK_CE_ASCII = 0, DCC_CK_CE_QP, DCC_CK_CE_B64 } mime_ce; struct { u_int total; /* non-whitespace text */ u_char flen; /* bytes of ">From" seen */ MD5_CTX md5; } ctx_body; DCC_CTX_FUZ1 fuz1; DCC_CTX_FUZ2 fuz2; DNSBL_WORK *dnsbl; /* pointer to malloc()'ed state */ DCC_CKSUM_THOLDS tholds_rej; u_char flags; # define DCC_CKS_MIME_BOL 0x01 /* header decoder is at BOL */ # define DCC_CKS_MIME_QUOTED 0x02 /* quoted boundary */ } DCC_GOT_CKS; typedef DCC_TGTS DCC_CKS_WTGTS[DCC_WSUMS]; /* sscanf() a checksum */ #define DCC_CKSUM_HEX_PAT "%8x %8x %8x %8x" /* whiteclnt files */ #define DCC_WHITE_SUFFIX ".dccw" #define DCC_WHITE_NEW_SUFFIX ".dccx" /* hash table under construction */ typedef char DCC_WHITE_MAGIC[128]; #define WHITE_MAGIC_B_STR "DCC client whitelist hash table version " #define WHITE_MAGIC_V_STR "23" typedef struct { DCC_TGTS tgts; int bits; struct in6_addr addr; struct in6_addr mask; u_short lno; u_char fno; } DCC_WHITE_CIDR_ENTRY; typedef struct { u_char len; # define WHITE_CIDR_MAX_ENTRIES 64 DCC_WHITE_CIDR_ENTRY e[WHITE_CIDR_MAX_ENTRIES]; } DCC_WHITE_CIDR; typedef u_int DCC_WHITE_INX; /* 1-based index into hash table */ typedef struct { DCC_WHITE_INX fwd; DCC_TGTS tgts; u_short lno; u_char fno; DCC_CK_TYPE_B type; DCC_SUM sum; } DCC_WHITE_ENTRY; #ifdef DCC_WIN32 #define DCC_WHITE_TBL_BINS 521 /* should be prime */ #else #define DCC_WHITE_TBL_BINS 8209 /* should be prime */ #endif typedef u_int DCC_WHITE_FGS; typedef struct { DCC_WHITE_MAGIC magic; /* WHITE_MAGIC_* in ckwhite.c */ struct { DCC_WHITE_INX entries; /* # of entries in the file */ DCC_WHITE_FGS flags; # define DCC_WHITE_FG_PER_USER 0x00000001 # define DCC_WHITE_FG_HOSTNAMES 0x00000002 /* have some */ # define DCC_WHITE_FG_GREY_LOG_ON 0x00000004 # define DCC_WHITE_FG_GREY_LOG_OFF 0x00000008 # define DCC_WHITE_FG_GREY_ON 0x00000010 # define DCC_WHITE_FG_GREY_OFF 0x00000020 # define DCC_WHITE_FG_LOG_ALL 0x00000040 # define DCC_WHITE_FG_LOG_NORMAL 0x00000080 # define DCC_WHITE_FG_DISCARD_OK 0x00000100 # define DCC_WHITE_FG_NO_DISCARD 0x00000200 # define DCC_WHITE_FG_DCC_ON 0x00000400 # define DCC_WHITE_FG_DCC_OFF 0x00000800 # define DCC_WHITE_FG_REP_ON 0x00001000 # define DCC_WHITE_FG_REP_OFF 0x00002000 # define DCC_WHITE_FG_MTA_FIRST 0x00004000 # define DCC_WHITE_FG_MTA_LAST 0x00008000 # define DCC_WHITE_FG_LOG_D 0x00010000 # define DCC_WHITE_FG_LOG_H 0x00020000 # define DCC_WHITE_FG_LOG_M 0x00040000 # define DCC_WHITE_FG_TRAP_ACC 0x00080000 /* spam trap */ # define DCC_WHITE_FG_TRAP_REJ 0x00100000 /* spam trap */ # define DCC_WHITE_FG_TRAPS (DCC_WHITE_FG_TRAP_ACC \ | DCC_WHITE_FG_TRAP_REJ) # define DCC_WHITE_FG_DNSBL_ON(n) (0x00200000*DNSBL_G2B(n)) # define DCC_WHITE_FG_DNSBL_ON_M 0x00e00000 # define DCC_WHITE_FG_DNSBL_OFF(n) (0x01000000*DNSBL_G2B(n)) # define DCC_WHITE_FG_DNSBL_OFF_M 0x07000000 time_t reparse; /* re-parse after this */ time_t broken; /* serious broken until then */ time_t ascii_mtime; /* ASCII file mtime at last parsing */ struct { /* included files */ time_t mtime; DCC_PATH nm; } white_incs[8]; DCC_CKSUM_THOLDS tholds_rej; DCC_SUM ck_sum; /* checksum of following contents */ DCC_WHITE_CIDR cidr; } hdr; DCC_WHITE_INX bins[DCC_WHITE_TBL_BINS]; /* 1-based indeces or 0 for empty */ DCC_WHITE_ENTRY tbl[1]; } DCC_WHITE_TBL; /* a ASCII whiteclnt file (including the files it includes) can be * OK * unreadable or otherwise badly broken * missing * if permanent, the hash table should be removed, but * it might be temporary as an editor changes it * a hash table can be * OK * out of date compared to the ASCII file(s) * badly broken but not removable (e.g. bad directory permissions). * * Do not stat() the files iand so do not complain on every message by * using wf->next_stat_time * Avoid generating a complaint on every error message using wf->broken * Reparse ASCII files with errors using wf->reparse or when their mtimes * change, but not more often than we use stat() to check mtimes.. * Reparse the main ASCII file if it contains host names by noticing the * DCC_WHITE_FG_HOSTNAMES bit and that the mtime of the hash table is * more than DCC_WHITECLNT_RESOLVE seconds old */ #define DCC_WHITE_REPARSE_DELAY (30*60) /* look for new DNS values */ #define DCC_WHITE_BROKEN_DELAY (5*60) /* do not complain more often */ #define DCC_WHITE_STAT_DELAY 10 /* don't stat() more often */ /* computed from DCC_WHITE_FGS */ typedef u_int32_t FLTR_SWS; #define FLTR_SW_SET 0x00000001 #define FLTR_SW_NO_DISCARD 0x00000002 /* always reject spam */ #define FLTR_SW_DCC_OFF 0x00000004 /* no DCC check */ #define FLTR_SW_REP_ON 0x00000008 /* honor DCC reputation */ #define FLTR_SW_LOG_ALL 0x00000010 #define FLTR_SW_GREY_OFF 0x00000020 /* greylisting off */ #define FLTR_SW_GREY_LOG_OFF 0x00000040 /* log greylist embargos */ #define FLTR_SW_LOG_D 0x00000080 #define FLTR_SW_LOG_H 0x00000100 #define FLTR_SW_LOG_M 0x00000200 #define FLTR_SW_MTA_FIRST 0x00000400 /* MTA IS/NOTSPAM checked first */ #define FLTR_SW_TRAP_ACC 0x00000800 /* accepting spam trap */ #define FLTR_SW_TRAP_REJ 0x00001000 /* rejecting spam trap */ # define FLTR_SW_TRAPS (FLTR_SW_TRAP_ACC | FLTR_SW_TRAP_REJ) #define FLTR_SW_DNSBL(n) (0x00002000*DNSBL_G2B(n)) /* check DNSBL */ # define FLTR_SW_DNSBL_M 0x0000e000 # define FLTR_SW_DNSBL_BITS(sws) (((sws)&FLTR_SW_DNSBL_M) \ / FLTR_SW_DNSBL(0)) /* bits set to enable something */ #define FLTR_SWS_SETTINGS_ON (FLTR_SW_REP_ON \ | FLTR_SW_LOG_ALL \ | FLTR_SW_MTA_FIRST \ | FLTR_SW_DNSBL_M \ | FLTR_SW_TRAPS) /* bits set to disable something */ #define FLTR_SWS_SETTINGS_OFF (FLTR_SW_DCC_OFF \ | FLTR_SW_NO_DISCARD \ | FLTR_SW_TRAP_REJ \ | FLTR_SW_GREY_OFF \ | FLTR_SW_GREY_LOG_OFF) /* get bits of enabled FILTERS */ #define FLTR_SWS_ON(sws) (((sws) ^ FLTR_SW_DCC_OFF) \ & (FLTR_SW_DCC_OFF \ | FLTR_SW_REP_ON \ | FLTR_SW_DNSBL_M \ | FLTR_SW_TRAP_REJ)) /* everything there is to know about a currently active whitelist file */ typedef struct { DCC_WHITE_TBL *wtbl; int ht_fd; /* hash table file */ struct stat ht_sb; DCC_WHITE_FGS wtbl_flags; u_int wtbl_entries; /* # of entries mapped window */ u_int wtbl_size; /* bytes in mapped window */ time_t next_stat_time; time_t reparse; /* when to re-parse file */ time_t broken; /* something very sick until then */ #ifdef DCC_WIN32 HANDLE ht_map; /* WIN32 hash table map handle */ #endif u_int ascii_nm_len; DCC_PATH ascii_nm; DCC_PATH ht_nm; int fno, lno; /* currently being parsed */ u_char wf_flags; # define DCC_WF_PER_USER 0x01 /* hostnames not allowed */ # define DCC_WF_NOFILE 0x02 /* no whiteclnt file */ # define DCC_WF_EITHER 0x04 /* either global or per-user ok */ # define DCC_WF_RO 0x08 /* read only access */ # define DCC_WF_WLIST 0x10 /* wlist command */ # define DCC_WF_WLIST_RO 0x20 /* read-only wlist command */ # define DCC_WF_WLIST_RW 0x40 /* read/write wlist command */ u_char closed; u_char need_reopen; /* lock-safe change flag */ } DCC_WF; extern DCC_WF cmn_wf, cmn_tmp_wf; typedef enum { /* greylist result */ ASK_GREY_FAIL, /* greylist server or other failure */ ASK_GREY_OFF, /* client whitelist or blacklist */ ASK_GREY_EMBARGO, ASK_GREY_EMBARGO_END, /* first time server says ok */ ASK_GREY_PASS, /* greylist server says ok */ ASK_GREY_WHITE, /* greylist server says whitelisted */ ASK_GREY_SPAM /* reported as spam to server */ } ASK_GREY_RESULT; extern u_char grey_on; extern u_char grey_query_only; extern u_int dcc_ck_qp_decode(DCC_GOT_CKS *, const char **, u_int *, char *, u_int); extern u_int dcc_ck_b64_decode(DCC_GOT_CKS *, const char **, u_int *, char *, u_int); extern int dcc_ck_url(DCC_URL_SKIP *, char, char **); #define DCC_CK_URL_MASK 0xff #define DCC_CK_URL_SHIFT 8 typedef enum { DCC_CK_URL_CHAR, /* character in URL after host name */ DCC_CK_URL_CK_LEN, /* 2nd slash */ DCC_CK_URL_HOST, /* character in URL host name */ DCC_CK_URL_DOT, /* dot in host name */ DCC_CK_URL_HOST_END, /* end of host name */ DCC_CK_URL_HOST_RESET, /* wasn't in host name after all */ DCC_CK_URL_SKIP /* shipping URL or not in URL */ } DCC_CK_URL; extern void dcc_ck_fuz1_init(DCC_GOT_CKS *); extern void dcc_ck_fuz1(DCC_GOT_CKS *, const char *, u_int); extern void dcc_ck_fuz1_fin(DCC_GOT_CKS *); extern void dcc_ck_fuz2_init(DCC_GOT_CKS *); extern void dcc_ck_fuz2(DCC_GOT_CKS *, const char *, u_int); extern void dcc_ck_fuz2_fin(DCC_GOT_CKS *); extern void dcc_wf_init(DCC_WF *, u_int); extern void dcc_wf_lock(DCC_WF *); extern void dcc_wf_unlock(DCC_WF *); extern void dcc_str2ck(DCC_SUM, const char *, u_int, const char *); extern u_char dcc_get_cks(DCC_GOT_CKS *, DCC_CK_TYPES, const char *, u_char); extern u_char dcc_ck_get_sub(DCC_GOT_CKS *, const char *, const char *); extern u_char dcc_add_sub_hdr(DCC_EMSG, const char *); extern void dcc_ck_ipv6(DCC_SUM, const struct in6_addr *); extern void dcc_get_ipv6_ck(DCC_GOT_CKS *, const struct in6_addr *); extern void dcc_unget_ip_ck(DCC_GOT_CKS *); extern u_char dcc_get_str_ip_ck(DCC_GOT_CKS *, const char *); extern const char *parse_received(const char *, DCC_GOT_CKS *, char *, int, char *, int, char *, int); extern u_char parse_return_path(const char *, char *, int); extern u_char parse_unix_from(const char *, char *, int); extern u_char parse_mail_host(const char *, char *, int); extern void dcc_print_cks(LOG_WRITE_FNC, void *, u_char, DCC_TGTS, const DCC_GOT_CKS *, DCC_CKS_WTGTS, u_char); #define PRINT_CK_TYPE_LEN 25 #define PRINT_CK_SUM_LEN 35 #define PRINT_CK_PAT_CK "%25s: %-35s" #define PRINT_CK_PAT_LIM_CK "%25.*s%c %-35.*s" #define PRINT_CK_PAT_SRVR " %7s" #define PRINT_CK_PAT_SRVR_LEN 8 #define PRINT_CK_PAT_WLIST " %5s" #define PRINT_CK_PAT_WLIST_LEN 6 #define PRINT_CK_PAT_THOLD PRINT_CK_PAT_WLIST extern void dcc_cks_init(DCC_GOT_CKS *); extern void dcc_ck_mime_hdr(DCC_GOT_CKS *, const char *, const char *); extern u_char parse_mime_hdr(DCC_GOT_CKS *, const char *, u_int, u_char); extern void dcc_ck_body(DCC_GOT_CKS *, const void *, u_int); extern void dcc_cks_fin(DCC_GOT_CKS *); extern u_char dcc_get_white(DCC_EMSG, DCC_WHITE_INX); typedef int (*DCC_PARSED_CK_FNC)(DCC_EMSG, DCC_WF *, DCC_CK_TYPES, /* type of checksum */ DCC_SUM, /* computed checksum */ DCC_TGTS); /* "OK2" etc */ typedef int (*DCC_PARSED_CK_CIDR_FNC)(DCC_EMSG, DCC_WF *, int, const struct in6_addr *, const struct in6_addr *, DCC_TGTS); extern int dcc_parse_ck(DCC_EMSG, DCC_WF *wf, const char *, DCC_CK_TYPES, const char *, DCC_TGTS, DCC_PARSED_CK_FNC, DCC_PARSED_CK_CIDR_FNC); extern int dcc_parse_hex_ck(DCC_EMSG, DCC_WF *wf, const char *, DCC_CK_TYPES, const char *, DCC_TGTS, DCC_PARSED_CK_FNC); extern const char *wf_fnm(const DCC_WF *, int); extern const char *wf_fnm_lno(DCC_FNM_LNO_BUF *, const DCC_WF *); extern DCC_TGTS dcc_str2thold(DCC_CK_TYPES, const char *); extern int dcc_parse_whitefile(DCC_EMSG, DCC_WF *, int, DCC_PARSED_CK_FNC, DCC_PARSED_CK_CIDR_FNC); typedef enum { DCC_WHITE_USE_DCC, DCC_WHITE_LISTED, DCC_WHITE_UNLISTED, DCC_WHITE_BLACK } DCC_WHITE_LISTING; typedef enum { DCC_WHITE_OK, DCC_WHITE_NOFILE, /* no ASCII file */ DCC_WHITE_CONTINUE, /* modest error or bad host name */ DCC_WHITE_COMPLAIN, /* bad hash table */ DCC_WHITE_SILENT /* no more complaints */ } DCC_WHITE_RESULT; #define DCC_WHITE_RESULT_FAILURE DCC_WHITE_UNLISTED u_char dcc_new_white_nm(DCC_EMSG, DCC_WF *, const char *); extern DCC_WHITE_RESULT dcc_rdy_white(DCC_EMSG, DCC_WF *, DCC_WF *); extern DCC_WHITE_RESULT dcc_white_sum(DCC_EMSG, DCC_WF *, DCC_CK_TYPES, const DCC_SUM, DCC_TGTS *, DCC_WHITE_LISTING *); extern u_char dcc_white_mx(DCC_EMSG, DCC_TGTS *, const DCC_GOT_CKS *); extern DCC_WHITE_RESULT dcc_white_cks(DCC_EMSG, DCC_WF *, DCC_GOT_CKS *, DCC_CKS_WTGTS, DCC_WHITE_LISTING *); typedef u_int32_t ASK_ST; #define ASK_ST_INVALID_MSG 0x00000001 /* incomplete SMTP transaction */ #define ASK_ST_QUERY 0x00000002 /* ask but do not report */ #define ASK_ST_QUERY_GREY 0x00000004 #define ASK_ST_SRVR_OK2 0x00000008 /* have honored DCC_TGTS_OK2 */ #define ASK_ST_SRVR_NOTSPAM 0x00000010 /* not spam by DCC server */ #define ASK_ST_SRVR_ISSPAM 0x00000020 /* spam by DCC server & threshold */ #define ASK_ST_REP_ISSPAM 0x00000040 /* spam by reputation & threshold */ #define ASK_ST_MTA_NOTSPAM 0x00000080 /* MTA says it is not spam */ #define ASK_ST_MTA_ISSPAM 0x00000100 /* MTA says it is spam */ #define ASK_ST_WLIST_NOTSPAM 0x00000200 /* locally whitelisted message */ #define ASK_ST_WLIST_ISSPAM 0x00000400 /* locally blacklisted message */ #define ASK_ST_CLNT_ISSPAM 0x00000800 /* report to DCC server as spam */ #define ASK_ST_GREY_EMBARGO 0x00001000 /* embargo this message */ #define ASK_ST_GREY_LOGIT 0x00002000 /* greylist logging indicated */ #define ASK_ST_LOGIT 0x00004000 /* log message for all recipients */ #define ASK_ST_DNSBL_HIT(n) (0x00008000*DNSBL_G2B(n)) /* DNSBL hit */ # define ASK_ST_DNSBL_HIT_M 0x00038000 # define ASK_ST_DNSBL_HIT_BITS(st) (((st)&ASK_ST_DNSBL_HIT_M) \ / ASK_ST_DNSBL_HIT(0)) #define ASK_ST_DNSBL_TIMEO(n) (0x00040000*DNSBL_G2B(n)) /* DNSBL timeout */ # define ASK_ST_DNSBL_TIMEO_M 0x001c0000 # define ASK_ST_DNSBL_TIMEO_BITS(st) (((st)&ASK_ST_DNSBL_TIMEO_M) \ / ASK_ST_DNSBL_TIMEO(0)) #define ASK_ST_DNSBL_TFAIL(n) (0x00200000*DNSBL_G2B(n)) # define ASK_ST_DNSBL_TFAIL_M 0x00e00000 # define ASK_ST_DNSBL_TFAIL_BITS(st) (((st)&ASK_ST_DNSBL_TFAIL_M) \ / ASK_ST_DNSBL_TFAIL(0)) extern u_char dcc_ck_grey_answer(DCC_EMSG, const DCC_OP_RESP *); extern int ask_dcc(DCC_EMSG, DCC_CLNT_CTXT *, u_char, DCC_HEADER_BUF *, DCC_GOT_CKS *, ASK_ST *, u_char, DCC_TGTS); extern u_char unthr_ask_white(DCC_EMSG, ASK_ST *, FLTR_SWS *, const char *, DCC_GOT_CKS *, DCC_CKS_WTGTS); extern u_char unthr_ask_dcc(DCC_EMSG, DCC_CLNT_CTXT*, DCC_HEADER_BUF*, ASK_ST *, DCC_GOT_CKS *, u_char, DCC_TGTS); extern void dcc_clear_tholds(void); extern u_char dcc_merge_tholds(DCC_CKSUM_THOLDS, const DCC_CKSUM_THOLDS, const DCC_WHITE_TBL *); extern void dcc_parse_honor(const char *); extern u_char dcc_parse_tholds(const char *, const char *); extern void dcc_honor_log_cnts(ASK_ST *, const DCC_GOT_CKS *, DCC_TGTS); extern FLTR_SWS wf2sws(FLTR_SWS, const DCC_WF *); extern void log_ask_st(LOG_WRITE_FNC, void *, ASK_ST, FLTR_SWS, u_char, const DCC_HEADER_BUF *); extern u_char dcc_parse_client_grey(const char *); extern ASK_GREY_RESULT ask_grey(DCC_EMSG, DCC_CLNT_CTXT *, DCC_OPS, DCC_SUM, DCC_SUM, const DCC_GOT_CKS *, const DCC_SUM, DCC_TGTS *, DCC_TGTS *, DCC_TGTS *); extern u_char dcc_parse_dnsbl(DCC_EMSG, const char *, const char *, u_char); extern const REPLY_TPLT *dnsbl_parse_reply(const char *); extern void helper_save_arg(const char *, const char *); extern void helper_init(int); extern void dcc_dnsbl_init(DCC_GOT_CKS *, DCC_CLNT_CTXT *, void *, const char *); extern void url_dnsbl(DNSBL_WORK *); extern void dcc_mail_host_dnsbl(DNSBL_WORK *, const char *); extern void dcc_client_dnsbl(DNSBL_WORK *, const struct in6_addr *, const char *); extern void dcc_dnsbl_result(ASK_ST *, DNSBL_WORK *); extern int PATTRIB(3,4) thr_log_print(void *, u_char, const char *, ...); extern int PATTRIB(2,3) thr_error_msg(void *, const char *, ...); extern void PATTRIB(2,3) thr_trace_msg(void *, const char *, ...); #endif /* DCC_CK_H */