/* Distributed Checksum Clearinghouse * * checksum routines * * 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.148 $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@" */ /* specify a DNS blacklist */ typedef char DNSBL_DOM[MAXHOSTNAMELEN]; typedef struct dnsbl { struct dnsbl *fwd; DCC_SOCKU result_su; /* usually 127.0.0.2 */ u_char result_use_ipv6; /* how to lookup result */ enum DNSBL_TYPE { DNSBL_TYPE_IPV4, DNSBL_TYPE_IPV6, DNSBL_TYPE_NAME } bl_type; int bl_num; int bl_dom_len; DNSBL_DOM bl_dom; const void *reply; u_char flags; # define DNSBL_FG_ENVELOPE 0x01 # define DNSBL_FG_BODY 0x02 # define DNSBL_FG_MX 0x04 # define DNSBL_FG_NS 0x08 } DNSBL; extern DNSBL *dnsbls; extern u_char have_helpers; extern DCC_PATH dnsbl_progpath; /* working storage for DNS blacklisting */ typedef enum { /* what part of a message got a hit */ DNSBL_HIT_NONE, DNSBL_HIT_CLIENT, /* SMTP client */ DNSBL_HIT_MAIL_HOST, /* SMTP envelope mail_from domain */ DNSBL_HIT_URL /* URL in body */ } DNSBL_HIT; typedef enum { /* secondary hit type */ DNSBL_HTYPE_STD, DNSBL_HTYPE_MX, DNSBL_HTYPE_NS } DNSBL_HTYPE; typedef struct reply REPLY; typedef struct cmn_work CMN_WORK; typedef struct { DCC_CLNT_CTXT *dcc_ctxt; void *log_ctxt; time_t msg_us; /* microseconds remaining for msg */ struct timeval url_start; time_t url_us; const char *id; DNSBL_HIT hit; DNSBL_HTYPE htype; /* hit was on an MX or NS address */ int bl_num; u_char timeouts; /* # of timed out lookups */ u_short tgt_dom_len; DNSBL_DOM tgt_dom; /* body URL or envelope sender domain */ DNSBL_DOM probe; /* what was actually looked up */ } DNSBL_WORK; /* 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; 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 (sizeof(DCC_HTTPS_STR)-1) 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 (MAXHOSTNAMELEN+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+MAXHOSTNAMELEN) #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 */ # define DCC_CKS_WHITECLNT_THOLD 0x04 /* using whiteclnt thresholds */ } 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 "21" 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_DISCARD_NOK 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_DNSBL_ON 0x00004000 # define DCC_WHITE_FG_DNSBL_OFF 0x00008000 # define DCC_WHITE_FG_MTA_FIRST 0x00010000 # define DCC_WHITE_FG_MTA_LAST 0x00020000 # define DCC_WHITE_FG_LOG_D 0x00040000 # define DCC_WHITE_FG_LOG_H 0x00080000 # define DCC_WHITE_FG_LOG_M 0x00100000 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_RE_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_short FLTR_SWS; #define FLTR_SW_SET 0x0001 #define FLTR_SW_DISCARD_NOK 0x0002 /* forced discard of spam not ok */ #define FLTR_SW_DCC_OFF 0x0004 /* no DCC check */ #define FLTR_SW_REP_ON 0x0008 /* honor DCC reputation */ #define FLTR_SW_LOG_ALL 0x0010 #define FLTR_SW_GREY_OFF 0x0020 /* greylisting off */ #define FLTR_SW_GREY_LOG_OFF 0x0040 /* log greylist embargos */ #define FLTR_SW_LOG_D 0x0080 #define FLTR_SW_LOG_H 0x0100 #define FLTR_SW_LOG_M 0x0200 #define FLTR_SW_MTA_FIRST 0x0400 /* MTA IS/NOTSPAM checked first */ #define FLTR_SW_DNSBL_ON 0x0800 /* check DNS blacklists */ /* bits set to enable a filter */ #define FLTR_SWS_SETTINGS_ON (FLTR_SW_REP_ON | FLTR_SW_LOG_ALL \ | FLTR_SW_MTA_FIRST | FLTR_SW_DNSBL_ON) /* bits set to disable a filter */ #define FLTR_SWS_SETTINGS_OFF (FLTR_SW_DCC_OFF \ | FLTR_SW_DISCARD_NOK \ | FLTR_SW_GREY_OFF | FLTR_SW_GREY_LOG_OFF) /* enabled filters */ #define FLTR_SWS_ON(sws) (((sws) ^ FLTR_SW_DCC_OFF) \ & (FLTR_SW_DCC_OFF | FLTR_SW_REP_ON \ | FLTR_SW_DNSBL_ON)) /* everything there is to know about a currently active whitelist file */ typedef struct { u_int changed; /* lock-safe change flag */ DCC_WHITE_TBL *info; int ht_fd; /* hash table file */ struct stat ht_sb; DCC_WHITE_FGS info_flags; u_int info_entries; /* # of entries mapped window */ u_int info_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_WLIST_CMD 0x04 /* wlist command */ # define DCC_WF_RO 0x08 /* read-only wlist command */ } 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 *, u_char); 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 *, u_char); 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_ipv6_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 *, DCC_GOT_CKS *, char[DCC_HDR_CK_MAX+1]); 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 u_char dcc_grey_spam(DCC_EMSG, DCC_CLNT_CTXT *, const DCC_GOT_CKS *, const DCC_SUM, const DCC_SUM); extern void dcc_cks_init(DCC_GOT_CKS *, DCC_CLNT_CTXT *, CMN_WORK *, const char *); 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 *, u_char); 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, /* minor error e.g. bad host name */ DCC_WHITE_COMPLAIN, /* bad hash table */ DCC_WHITE_SILENT /* no complaints about bad hash table */ } 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_int ASK_ST; #define ASK_ST_INVALID_MSG 0x0001 /* incomplete SMTP transaction */ #define ASK_ST_SRVR_OK2 0x0002 /* have honored DCC_TGTS_OK2 */ #define ASK_ST_SRVR_NOTSPAM 0x0004 /* known not spam by DCC server */ #define ASK_ST_SRVR_ISSPAM 0x0008 /* spam by DCC server */ #define ASK_ST_REP_ISSPAM 0x0010 /* spam by reputation */ #define ASK_ST_DNSBL_ISSPAM 0x0020 /* DNS blacklist hit */ #define ASK_ST_MTA_NOTSPAM 0x0040 /* MTA says it is not spam */ #define ASK_ST_MTA_ISSPAM 0x0080 /* MTA says it is spam */ #define ASK_ST_WLIST_NOTSPAM 0x0100 /* locally whitelisted message */ #define ASK_ST_WLIST_ISSPAM 0x0200 /* locally whitelisted message */ #define ASK_ST_CLNT_ISSPAM 0x0400 /* report to DCC server as spam */ #define ASK_ST_GREY_EMBARGO 0x0800 /* embargo this message */ #define ASK_ST_GREY_LOGIT 0x1000 /* greylist logging indicated */ #define ASK_ST_LOGIT 0x2000 /* log message for all recipients */ typedef union { DCC_HDR hdr; DCC_ANSWER a; #ifdef DCC_PKT_VERSION5 DCC_ANSWERv5 a5; #endif DCC_GREY_ANSWER g; DCC_ERROR error; } ASK_RESP; extern u_char dcc_ck_grey_answer(DCC_EMSG, const ASK_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, const char *, int, const DCC_HEADER_BUF *); extern u_char dcc_parse_client_grey(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 *); extern const REPLY *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 *, CMN_WORK *, const char *); extern void dcc_dnsbl_url(DNSBL_WORK *); extern void dcc_mail_host_dnsbl(DNSBL_WORK *, const char *); extern void dcc_sender_dnsbl(DNSBL_WORK *, const struct in6_addr *); extern void dcc_dnsbl_result(ASK_ST *, const REPLY **, const DNSBL_WORK *); extern int PATTRIB(3,4) thr_log_print(void *, u_char, const char *, ...); extern void PATTRIB(2,3) thr_error_msg(void *, const char *, ...); extern void PATTRIB(2,3) thr_trace_msg(void *, const char *, ...); #endif /* DCC_CK_H */