Mercurial > notdcc
comparison include/dcc_ck.h @ 0:c7f6b056b673
First import of vendor version
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 13:49:58 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7f6b056b673 |
---|---|
1 /* Distributed Checksum Clearinghouse | |
2 * | |
3 * checksum routines | |
4 * | |
5 * Copyright (c) 2008 by Rhyolite Software, LLC | |
6 * | |
7 * This agreement is not applicable to any entity which sells anti-spam | |
8 * solutions to others or provides an anti-spam solution as part of a | |
9 * security solution sold to other entities, or to a private network | |
10 * which employs the DCC or uses data provided by operation of the DCC | |
11 * but does not provide corresponding data to other users. | |
12 * | |
13 * Permission to use, copy, modify, and distribute this software without | |
14 * changes for any purpose with or without fee is hereby granted, provided | |
15 * that the above copyright notice and this permission notice appear in all | |
16 * copies and any distributed versions or copies are either unchanged | |
17 * or not called anything similar to "DCC" or "Distributed Checksum | |
18 * Clearinghouse". | |
19 * | |
20 * Parties not eligible to receive a license under this agreement can | |
21 * obtain a commercial license to use DCC by contacting Rhyolite Software | |
22 * at sales@rhyolite.com. | |
23 * | |
24 * A commercial license would be for Distributed Checksum and Reputation | |
25 * Clearinghouse software. That software includes additional features. This | |
26 * free license for Distributed ChecksumClearinghouse Software does not in any | |
27 * way grant permision to use Distributed Checksum and Reputation Clearinghouse | |
28 * software | |
29 * | |
30 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL | |
31 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | |
32 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC | |
33 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES | |
34 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
35 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
36 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
37 * SOFTWARE. | |
38 * | |
39 * Rhyolite Software DCC 1.3.103-1.182 $Revision$ | |
40 */ | |
41 | |
42 #ifndef DCC_CK_H | |
43 #define DCC_CK_H | |
44 | |
45 #include "dcc_clnt.h" | |
46 #include "dcc_md5.h" | |
47 | |
48 | |
49 typedef DCC_TGTS DCC_CKSUM_THOLDS[DCC_DIM_CKS]; | |
50 #define DCC_THOLD_NEVER (DCC_TGTS_TOO_MANY+1) | |
51 #define DCC_THOLD_UNSET (DCC_TGTS_INVALID) | |
52 | |
53 extern DCC_CKSUM_THOLDS dcc_tholds_rej; | |
54 | |
55 | |
56 /* MIME boundary | |
57 * RFC 1341 says boundaries can be 70 bytes, but handle non-conformant spam */ | |
58 #define DCC_CK_BND_MAX 94 | |
59 #define DCC_CK_BND_DIM (DCC_CK_BND_MAX+2) /* including leading -- */ | |
60 #define DCC_CK_BND_MISS (DCC_CK_BND_DIM+1) | |
61 typedef struct { | |
62 u_char bnd_len; /* length including leading "--" */ | |
63 u_char cmp_len; /* compared so far */ | |
64 char bnd[DCC_CK_BND_DIM]; /* "--"boundary */ | |
65 } DCC_CK_BND; | |
66 | |
67 | |
68 typedef u_char DCC_CK_FC[256]; | |
69 extern const DCC_CK_FC dcc_cset_1, dcc_cset_2; | |
70 | |
71 /* state machine for ignoring parts of URLs */ | |
72 typedef struct { | |
73 enum { | |
74 DCC_URL_ST_IDLE, /* waiting for H or = */ | |
75 DCC_URL_ST_QUOTE, /* " " '"' or 'H' after = */ | |
76 DCC_URL_ST_QH, /* " " H after quote */ | |
77 DCC_URL_ST_T1, /* " " T */ | |
78 DCC_URL_ST_T2, /* " " T */ | |
79 DCC_URL_ST_P, /* " " P */ | |
80 DCC_URL_ST_S, /* " " [S] */ | |
81 DCC_URL_ST_COLON, /* " " : */ | |
82 DCC_URL_ST_SLASH1, /* " " / */ | |
83 DCC_URL_ST_SLASH2, /* " " / */ | |
84 DCC_URL_ST_SLASH3_START, | |
85 DCC_URL_ST_SLASH3, /* " " third / */ | |
86 DCC_URL_ST_SKIP /* skipping rest of URL */ | |
87 } st; | |
88 char *start; /* start of hostname in URL */ | |
89 char *dot; /* last '.' in hostname */ | |
90 int total; /* length of URL */ | |
91 u_char flags; | |
92 # define DCC_URL_QUOTED 0x01 | |
93 # define DCC_URL_DEL_DOMAIN 0x02 /* waiting for domain to delete */ | |
94 # define DCC_URL_PERCENT1 0x04 /* waiting for 1st digit after % */ | |
95 # define DCC_URL_PERCENT2 0x08 /* waiting for 2nd digit after % */ | |
96 # define DCC_URL_SQUOTED 0x10 /* single quoted (') URL */ | |
97 # define DCC_URL_DQUOTED 0x20 /* double quoted (") URL */ | |
98 # define DCC_URL_QUOTES (DCC_URL_DQUOTED | DCC_URL_SQUOTED) | |
99 # define DCC_URL_SIMPLE (DCC_URL_DEL_DOMAIN \ | |
100 | DCC_URL_PERCENT1 \ | |
101 | DCC_URL_PERCENT2) | |
102 u_char percent; | |
103 } DCC_URL_SKIP; | |
104 #define DCC_URL_MAX 65 /* 63 is RFC 1034 limit on labels */ | |
105 #define DCC_URL_FAILSAFE 2000 /* big bogus "username:password@" */ | |
106 | |
107 | |
108 /* a template for generating a reply to an SMTP command */ | |
109 typedef enum { | |
110 REPLY_TPLT_NULL, | |
111 REPLY_TPLT_ID, /* queue ID for sendmail, fake for dccifd */ | |
112 REPLY_TPLT_CIP, /* SMTP client IP address */ | |
113 REPLY_TPLT_BTYPE, /* type of DNSBL hit */ | |
114 REPLY_TPLT_BTGT, /* DNSBL hit IP address or name */ | |
115 REPLY_TPLT_BPROBE, /* DNSBL probe domain name */ | |
116 REPLY_TPLT_BRESULT /* DNSBL probe result */ | |
117 } REPLY_TPLT_ARGS; | |
118 typedef struct { | |
119 const char *log_result; /* "reject" etc. for log */ | |
120 # define NUM_REPLY_TPLT_ARGS 6 | |
121 REPLY_TPLT_ARGS args[NUM_REPLY_TPLT_ARGS]; | |
122 char rcode[sizeof("5yz")]; | |
123 char xcode[sizeof("1.2.3")]; | |
124 u_char is_pat; /* template has %s references */ | |
125 # define REPLY_BUF_LEN 256 | |
126 char pat[REPLY_BUF_LEN]; /* pattern for SMTP message */ | |
127 } REPLY_TPLT; | |
128 | |
129 | |
130 /* specify a DNS blacklist */ | |
131 typedef struct { | |
132 char c[DCC_MAXDOMAINLEN]; /* null terminated */ | |
133 } DNSBL_DOM; | |
134 | |
135 typedef u_char DNSBL_FGS; | |
136 #define DNSBL_FG_DUP 0x01 /* duplicate blacklist */ | |
137 #define DNSBL_FG_TIMEO 0x02 /* suffered a timeout */ | |
138 #define DNSBL_FG_TFAIL 0x04 /* want SMTP failure on timeout */ | |
139 #define DNSBL_FG_CLIENT 0x08 /* check client IP address */ | |
140 #define DNSBL_FG_MAIL_HOST 0x10 /* check env_from domain */ | |
141 #define DNSBL_FG_URL 0x20 /* check URLs in message body */ | |
142 #define DNSBL_FG_MX 0x40 /* MX for _URL & _MAIL_HOST */ | |
143 #define DNSBL_FG_NS 0x80 /* NS for _URL & _MAIL_HOST */ | |
144 # define DNSBL_FG_HITS (DNSBL_FG_CLIENT | DNSBL_FG_MAIL_HOST | DNSBL_FG_URL) | |
145 # define DNSBL_FG_TYPES (DNSBL_FG_HITS | DNSBL_FG_MX | DNSBL_FG_NS) | |
146 # define DNSBL_FG_DEFAULT DNSBL_FG_TYPES | |
147 | |
148 typedef enum DNSBL_TYPE { | |
149 DNSBL_TYPE_IPV4, | |
150 DNSBL_TYPE_IPV6, | |
151 DNSBL_TYPE_NAME | |
152 } DNSBL_TYPE; | |
153 | |
154 #define MAX_DNSBL_GROUPS 3 | |
155 typedef u_char DNSBL_GBITS; | |
156 #define DNSBL_G2B(n) ((1<<(n)) & ((2<<MAX_DNSBL_GROUPS)-1)) | |
157 | |
158 typedef struct dnsbl { | |
159 struct dnsbl *fwd; | |
160 struct dnsbl *dup; /* same except result */ | |
161 u_char group; /* 1-indexed */ | |
162 struct in6_addr tgt; /* hit if DNSBL matches this block */ | |
163 struct in6_addr tgt_mask; | |
164 u_char tgt_use_ipv6; /* ipv4 vs. ipv6 result weighting */ | |
165 DNSBL_TYPE bl_type; | |
166 int bl_num; | |
167 int bl_dom_len; | |
168 DNSBL_DOM bl_dom; | |
169 const REPLY_TPLT *reply; | |
170 DNSBL_FGS fgs; | |
171 } DNSBL; | |
172 | |
173 /* working storage for one set of DNSBLs */ | |
174 typedef struct { | |
175 DNSBL_FGS fgs; /* kind of DNSBL hit */ | |
176 const char *btype; /* type of hit string */ | |
177 const DNSBL *dnsbl; /* hit DNSBL */ | |
178 char btype_buf[64]; | |
179 char result[DCC_SU2STR_SIZE]; /* IP address found in DNSBL */ | |
180 DNSBL_DOM tgt; /* IP address or name sought in DNSBL */ | |
181 DNSBL_DOM probe; /* what was actually looked up */ | |
182 } DNSBL_GROUP; | |
183 | |
184 /* working storage for all DNSBLs */ | |
185 typedef struct { | |
186 DNSBL_DOM dom; /* domain name */ | |
187 struct in6_addr addr; /* and/or IP address sought in DNSBL */ | |
188 } DNSBL_TGT; | |
189 typedef struct { | |
190 DNSBL_GBITS all; | |
191 DNSBL_GBITS client; | |
192 DNSBL_GBITS mail_host; | |
193 DNSBL_GBITS mail_host_ns; | |
194 DNSBL_GBITS mail_host_mx; | |
195 DNSBL_GBITS url; | |
196 DNSBL_GBITS url_ns; | |
197 DNSBL_GBITS url_mx; | |
198 } DNSBL_UNHIT; | |
199 typedef struct { | |
200 DCC_CLNT_CTXT *dcc_ctxt; | |
201 void *log_ctxt; | |
202 const char *id; | |
203 time_t msg_us; /* microseconds remaining for msg */ | |
204 struct timeval url_start; | |
205 time_t url_us; /* microseconds to look up URL */ | |
206 time_t url_us_used; | |
207 DNSBL_UNHIT unhit; /* groups of DNSBLs not yet hit */ | |
208 u_short tgt_dom_len; | |
209 DNSBL_TGT tgt; | |
210 struct { | |
211 DNSBL_DOM dom; | |
212 } tgt_cache[8]; | |
213 int tgt_cache_pos; | |
214 DNSBL_GROUP groups[MAX_DNSBL_GROUPS]; | |
215 } DNSBL_WORK; | |
216 | |
217 extern DNSBL *dnsbls; | |
218 extern u_char have_dnsbl_groups; | |
219 extern u_char have_helpers; | |
220 extern DCC_PATH dnsbl_progpath; | |
221 | |
222 | |
223 | |
224 /* accumulated checksums for an SMTP message */ | |
225 typedef struct { | |
226 const char *hdr_nm; /* name if substitute checksum */ | |
227 DCC_TGTS tgts; /* server's answer or previous total */ | |
228 DCC_CK_TYPE_B type; | |
229 u_char rpt2srvr; /* 1=report to server */ | |
230 DCC_SUM sum; | |
231 } DCC_GOT_SUM; | |
232 #define CLR_GOT_SUM(g) ((g)->hdr_nm = 0, (g)->tgts = DCC_TGTS_INVALID, \ | |
233 (g)->type = DCC_CK_INVALID, (g)->rpt2srvr = 0) | |
234 | |
235 typedef union { | |
236 u_int32_t w32[4]; | |
237 u_char b[16]; | |
238 } DCC_FUZ2_WORD; | |
239 #define DCC_FUZ2_WORD_CLEAR(_w) ((_w)->w32[0]=0, (_w)->w32[1]=0, \ | |
240 (_w)->w32[2]=0, (_w)->w32[3]=0) | |
241 | |
242 typedef struct { | |
243 DCC_URL_SKIP url; | |
244 u_int total; /* bytes */ | |
245 char *cp; /* end of data in buffer */ | |
246 char *eol; /* most recent eol */ | |
247 # define DCC_FUZ1_MAX_LINE 78 | |
248 # define DCC_HTTPS_STR "https" | |
249 # define DCC_HTTPS_LEN LITZ(DCC_HTTPS_STR) | |
250 char buf[DCC_FUZ1_MAX_LINE*4 | |
251 +DCC_HTTPS_LEN]; | |
252 MD5_CTX md5; | |
253 } DCC_CTX_FUZ1; | |
254 | |
255 | |
256 typedef struct { /* per-language counts */ | |
257 u_int wsummed; /* bytes of words summed */ | |
258 u_int wtotal; /* words summed */ | |
259 MD5_CTX md5; | |
260 } FUZ2_LANG; | |
261 | |
262 typedef struct { | |
263 u_int btotal; /* total non-whitespace bytes seen */ | |
264 u_int xsummed; /* non-word bytes checksummed */ | |
265 u_int wlen; /* length of current word */ | |
266 u_int cref_cnt; /* fancy character length */ | |
267 u_int tag_len; /* HTML tag length */ | |
268 DCC_FUZ2_WORD w; | |
269 DCC_FUZ2_WORD cref_w; | |
270 DCC_FUZ2_WORD tag; | |
271 int urls; /* # of URLs seen */ | |
272 char *url_cp; /* accumulated URLs */ | |
273 # define DCC_FUZ2_URL_MAX (1+DCC_URL_MAX) | |
274 char url_buf[DCC_FUZ2_URL_MAX*2]; | |
275 DCC_URL_SKIP url; /* state machine for skipping URLs */ | |
276 enum { | |
277 DCC_CREF_ST_IDLE = 0, | |
278 DCC_CREF_ST_START, /* get HTML character reference */ | |
279 DCC_CREF_ST_NUM, /* hex or decimal */ | |
280 DCC_CREF_ST_DEC, | |
281 DCC_CREF_ST_HEX, | |
282 DCC_CREF_ST_NAME | |
283 } cref_st; | |
284 enum { | |
285 DCC_FUZ2_ST_WORD = 0, /* gathering word */ | |
286 DCC_FUZ2_ST_START_TAG, /* gathering start of HTML tag */ | |
287 DCC_FUZ2_ST_SKIP_TAG, /* skipping HTML tag */ | |
288 DCC_FUZ2_ST_SKIP_COMMENT /* skipping HTML comment */ | |
289 } st; | |
290 # define FUZ2_LAN_NUM 3 | |
291 FUZ2_LANG lang[FUZ2_LAN_NUM]; | |
292 } DCC_CTX_FUZ2; | |
293 | |
294 /* The maximum length of a checksumed HELO value and the continuation string | |
295 * need to be the same for all users of the local white-/blacklist */ | |
296 #define DCC_HELO_MAX (DCC_MAXDOMAINLEN+8) | |
297 #define DCC_HELO_CONT "..." | |
298 | |
299 /* local-part maximum in RFC 2821 */ | |
300 #define DCC_LOCAL_PART_MAX 64 | |
301 #define DCC_ENV_FROM_MAX (DCC_LOCAL_PART_MAX+DCC_MAXDOMAINLEN) | |
302 | |
303 #define DCC_MSG_ID_LEN 24 | |
304 | |
305 /* do not checksum more than this much of a header line */ | |
306 #define DCC_HDR_CK_MAX 1024 | |
307 | |
308 /* substitute or locally configured checksums */ | |
309 #define DCC_MAX_SUB_CKS 6 | |
310 | |
311 #define DCC_WSUMS (DCC_DIM_CKS+DCC_MAX_SUB_CKS) /* max whitelist checksums */ | |
312 typedef struct { | |
313 DCC_GOT_SUM sums[DCC_WSUMS]; | |
314 struct in6_addr ip_addr; /* SMTP client IP address */ | |
315 struct { /* quoted-printable state machine */ | |
316 int x; | |
317 int y; | |
318 u_char n; | |
319 enum { | |
320 DCC_CK_QP_IDLE, /* waiting for '=' */ | |
321 DCC_CK_QP_EQ, /* seen "=" */ | |
322 DCC_CK_QP_1, /* seen "=X" of "=XY" */ | |
323 DCC_CK_QP_FAIL1, /* have output '=' after bad =X */ | |
324 DCC_CK_QP_FAIL2, /* have output '=' after bad =XY */ | |
325 DCC_CK_QP_FAIL3 /* have output 'X' after bad =XY */ | |
326 } state; | |
327 } qp; | |
328 struct { /* base64 state machine */ | |
329 u_int32_t quantum; | |
330 int quantum_cnt; | |
331 } b64; | |
332 enum { | |
333 CK_MP_ST_PREAMBLE, /* preamble before first boundary */ | |
334 CK_MP_ST_BND, /* MIME boundary */ | |
335 CK_MP_ST_HDRS, /* headers after a boundary */ | |
336 CK_MP_ST_TEXT, /* body or entity */ | |
337 CK_MP_ST_EPILOGUE /* text after last boundary */ | |
338 } mp_st; | |
339 enum CK_MHDR_ST { /* parse entity fields */ | |
340 CK_MHDR_ST_IDLE, | |
341 CK_MHDR_ST_CE_CT, /* matching "Content-T" */ | |
342 CK_MHDR_ST_CE, /* "ransfer-Encoding:" */ | |
343 CK_MHDR_ST_CE_WS, /* white space after "encoding:" */ | |
344 CK_MHDR_ST_CT, /* "ype:" */ | |
345 CK_MHDR_ST_CT_WS, /* white space after "type:" */ | |
346 CK_MHDR_ST_QP, /* "quoted-printable" */ | |
347 CK_MHDR_ST_B64, /* "base64" */ | |
348 CK_MHDR_ST_TEXT, /* "text" */ | |
349 CK_MHDR_ST_HTML, /* "/html" */ | |
350 CK_MHDR_ST_CSET_SKIP_PARAM, /* skip to ";" after "text" */ | |
351 CK_MHDR_ST_CSET_SPAN_WS, /* skip blanks before "charset" */ | |
352 CK_MHDR_ST_CSET, /* match "charset=" */ | |
353 CK_MHDR_ST_CSET_ISO_8859, /* "ISO-8859-" */ | |
354 CK_MHDR_ST_CSET_ISO_X, /* find the 8859 type number */ | |
355 CK_MHDR_ST_MULTIPART, /* match "multipart" */ | |
356 CK_MHDR_ST_BND_SKIP_PARAM, /* skip "/alternative;" or similar */ | |
357 CK_MHDR_ST_BND_SPAN_WS, /* skip whitespace before "boundary" */ | |
358 CK_MHDR_ST_BND, /* match "boundary=" */ | |
359 CK_MHDR_ST_BND_VALUE /* collecting boundary */ | |
360 } mhdr_st; | |
361 u_char mhdr_pos; | |
362 u_char mime_nest; /* # of nested MIME entities */ | |
363 u_char mime_bnd_matches; /* # of active boundary matches */ | |
364 DCC_CK_BND mime_bnd[3]; | |
365 enum { | |
366 DCC_CK_CT_TEXT = 0, | |
367 DCC_CK_CT_HTML, | |
368 DCC_CK_CT_BINARY | |
369 } mime_ct; | |
370 const u_char *mime_cset; | |
371 enum { | |
372 DCC_CK_CE_ASCII = 0, | |
373 DCC_CK_CE_QP, | |
374 DCC_CK_CE_B64 | |
375 } mime_ce; | |
376 struct { | |
377 u_int total; /* non-whitespace text */ | |
378 u_char flen; /* bytes of ">From" seen */ | |
379 MD5_CTX md5; | |
380 } ctx_body; | |
381 DCC_CTX_FUZ1 fuz1; | |
382 DCC_CTX_FUZ2 fuz2; | |
383 DNSBL_WORK *dnsbl; /* pointer to malloc()'ed state */ | |
384 DCC_CKSUM_THOLDS tholds_rej; | |
385 u_char flags; | |
386 # define DCC_CKS_MIME_BOL 0x01 /* header decoder is at BOL */ | |
387 # define DCC_CKS_MIME_QUOTED 0x02 /* quoted boundary */ | |
388 } DCC_GOT_CKS; | |
389 | |
390 typedef DCC_TGTS DCC_CKS_WTGTS[DCC_WSUMS]; | |
391 | |
392 | |
393 /* sscanf() a checksum */ | |
394 #define DCC_CKSUM_HEX_PAT "%8x %8x %8x %8x" | |
395 | |
396 | |
397 | |
398 | |
399 /* whiteclnt files */ | |
400 | |
401 #define DCC_WHITE_SUFFIX ".dccw" | |
402 #define DCC_WHITE_NEW_SUFFIX ".dccx" /* hash table under construction */ | |
403 | |
404 typedef char DCC_WHITE_MAGIC[128]; | |
405 #define WHITE_MAGIC_B_STR "DCC client whitelist hash table version " | |
406 #define WHITE_MAGIC_V_STR "23" | |
407 | |
408 typedef struct { | |
409 DCC_TGTS tgts; | |
410 int bits; | |
411 struct in6_addr addr; | |
412 struct in6_addr mask; | |
413 u_short lno; | |
414 u_char fno; | |
415 } DCC_WHITE_CIDR_ENTRY; | |
416 | |
417 typedef struct { | |
418 u_char len; | |
419 # define WHITE_CIDR_MAX_ENTRIES 64 | |
420 DCC_WHITE_CIDR_ENTRY e[WHITE_CIDR_MAX_ENTRIES]; | |
421 } DCC_WHITE_CIDR; | |
422 | |
423 typedef u_int DCC_WHITE_INX; /* 1-based index into hash table */ | |
424 | |
425 typedef struct { | |
426 DCC_WHITE_INX fwd; | |
427 DCC_TGTS tgts; | |
428 u_short lno; | |
429 u_char fno; | |
430 DCC_CK_TYPE_B type; | |
431 DCC_SUM sum; | |
432 } DCC_WHITE_ENTRY; | |
433 | |
434 #ifdef DCC_WIN32 | |
435 #define DCC_WHITE_TBL_BINS 521 /* should be prime */ | |
436 #else | |
437 #define DCC_WHITE_TBL_BINS 8209 /* should be prime */ | |
438 #endif | |
439 typedef u_int DCC_WHITE_FGS; | |
440 typedef struct { | |
441 DCC_WHITE_MAGIC magic; /* WHITE_MAGIC_* in ckwhite.c */ | |
442 struct { | |
443 DCC_WHITE_INX entries; /* # of entries in the file */ | |
444 DCC_WHITE_FGS flags; | |
445 # define DCC_WHITE_FG_PER_USER 0x00000001 | |
446 # define DCC_WHITE_FG_HOSTNAMES 0x00000002 /* have some */ | |
447 # define DCC_WHITE_FG_GREY_LOG_ON 0x00000004 | |
448 # define DCC_WHITE_FG_GREY_LOG_OFF 0x00000008 | |
449 # define DCC_WHITE_FG_GREY_ON 0x00000010 | |
450 # define DCC_WHITE_FG_GREY_OFF 0x00000020 | |
451 # define DCC_WHITE_FG_LOG_ALL 0x00000040 | |
452 # define DCC_WHITE_FG_LOG_NORMAL 0x00000080 | |
453 # define DCC_WHITE_FG_DISCARD_OK 0x00000100 | |
454 # define DCC_WHITE_FG_NO_DISCARD 0x00000200 | |
455 # define DCC_WHITE_FG_DCC_ON 0x00000400 | |
456 # define DCC_WHITE_FG_DCC_OFF 0x00000800 | |
457 # define DCC_WHITE_FG_REP_ON 0x00001000 | |
458 # define DCC_WHITE_FG_REP_OFF 0x00002000 | |
459 # define DCC_WHITE_FG_MTA_FIRST 0x00004000 | |
460 # define DCC_WHITE_FG_MTA_LAST 0x00008000 | |
461 # define DCC_WHITE_FG_LOG_D 0x00010000 | |
462 # define DCC_WHITE_FG_LOG_H 0x00020000 | |
463 # define DCC_WHITE_FG_LOG_M 0x00040000 | |
464 # define DCC_WHITE_FG_TRAP_ACC 0x00080000 /* spam trap */ | |
465 # define DCC_WHITE_FG_TRAP_REJ 0x00100000 /* spam trap */ | |
466 # define DCC_WHITE_FG_TRAPS (DCC_WHITE_FG_TRAP_ACC \ | |
467 | DCC_WHITE_FG_TRAP_REJ) | |
468 # define DCC_WHITE_FG_DNSBL_ON(n) (0x00200000*DNSBL_G2B(n)) | |
469 # define DCC_WHITE_FG_DNSBL_ON_M 0x00e00000 | |
470 # define DCC_WHITE_FG_DNSBL_OFF(n) (0x01000000*DNSBL_G2B(n)) | |
471 # define DCC_WHITE_FG_DNSBL_OFF_M 0x07000000 | |
472 time_t reparse; /* re-parse after this */ | |
473 time_t broken; /* serious broken until then */ | |
474 time_t ascii_mtime; /* ASCII file mtime at last parsing */ | |
475 struct { /* included files */ | |
476 time_t mtime; | |
477 DCC_PATH nm; | |
478 } white_incs[8]; | |
479 | |
480 DCC_CKSUM_THOLDS tholds_rej; | |
481 | |
482 DCC_SUM ck_sum; /* checksum of following contents */ | |
483 DCC_WHITE_CIDR cidr; | |
484 } hdr; | |
485 DCC_WHITE_INX bins[DCC_WHITE_TBL_BINS]; /* 1-based indeces or 0 for empty */ | |
486 DCC_WHITE_ENTRY tbl[1]; | |
487 } DCC_WHITE_TBL; | |
488 | |
489 | |
490 /* a ASCII whiteclnt file (including the files it includes) can be | |
491 * OK | |
492 * unreadable or otherwise badly broken | |
493 * missing | |
494 * if permanent, the hash table should be removed, but | |
495 * it might be temporary as an editor changes it | |
496 * a hash table can be | |
497 * OK | |
498 * out of date compared to the ASCII file(s) | |
499 * badly broken but not removable (e.g. bad directory permissions). | |
500 * | |
501 * Do not stat() the files iand so do not complain on every message by | |
502 * using wf->next_stat_time | |
503 * Avoid generating a complaint on every error message using wf->broken | |
504 * Reparse ASCII files with errors using wf->reparse or when their mtimes | |
505 * change, but not more often than we use stat() to check mtimes.. | |
506 * Reparse the main ASCII file if it contains host names by noticing the | |
507 * DCC_WHITE_FG_HOSTNAMES bit and that the mtime of the hash table is | |
508 * more than DCC_WHITECLNT_RESOLVE seconds old | |
509 */ | |
510 #define DCC_WHITE_REPARSE_DELAY (30*60) /* look for new DNS values */ | |
511 #define DCC_WHITE_BROKEN_DELAY (5*60) /* do not complain more often */ | |
512 #define DCC_WHITE_STAT_DELAY 10 /* don't stat() more often */ | |
513 | |
514 /* computed from DCC_WHITE_FGS */ | |
515 typedef u_int32_t FLTR_SWS; | |
516 #define FLTR_SW_SET 0x00000001 | |
517 #define FLTR_SW_NO_DISCARD 0x00000002 /* always reject spam */ | |
518 #define FLTR_SW_DCC_OFF 0x00000004 /* no DCC check */ | |
519 #define FLTR_SW_REP_ON 0x00000008 /* honor DCC reputation */ | |
520 #define FLTR_SW_LOG_ALL 0x00000010 | |
521 #define FLTR_SW_GREY_OFF 0x00000020 /* greylisting off */ | |
522 #define FLTR_SW_GREY_LOG_OFF 0x00000040 /* log greylist embargos */ | |
523 #define FLTR_SW_LOG_D 0x00000080 | |
524 #define FLTR_SW_LOG_H 0x00000100 | |
525 #define FLTR_SW_LOG_M 0x00000200 | |
526 #define FLTR_SW_MTA_FIRST 0x00000400 /* MTA IS/NOTSPAM checked first */ | |
527 #define FLTR_SW_TRAP_ACC 0x00000800 /* accepting spam trap */ | |
528 #define FLTR_SW_TRAP_REJ 0x00001000 /* rejecting spam trap */ | |
529 # define FLTR_SW_TRAPS (FLTR_SW_TRAP_ACC | FLTR_SW_TRAP_REJ) | |
530 #define FLTR_SW_DNSBL(n) (0x00002000*DNSBL_G2B(n)) /* check DNSBL */ | |
531 # define FLTR_SW_DNSBL_M 0x0000e000 | |
532 # define FLTR_SW_DNSBL_BITS(sws) (((sws)&FLTR_SW_DNSBL_M) \ | |
533 / FLTR_SW_DNSBL(0)) | |
534 | |
535 /* bits set to enable something */ | |
536 #define FLTR_SWS_SETTINGS_ON (FLTR_SW_REP_ON \ | |
537 | FLTR_SW_LOG_ALL \ | |
538 | FLTR_SW_MTA_FIRST \ | |
539 | FLTR_SW_DNSBL_M \ | |
540 | FLTR_SW_TRAPS) | |
541 /* bits set to disable something */ | |
542 #define FLTR_SWS_SETTINGS_OFF (FLTR_SW_DCC_OFF \ | |
543 | FLTR_SW_NO_DISCARD \ | |
544 | FLTR_SW_TRAP_REJ \ | |
545 | FLTR_SW_GREY_OFF \ | |
546 | FLTR_SW_GREY_LOG_OFF) | |
547 /* get bits of enabled FILTERS */ | |
548 #define FLTR_SWS_ON(sws) (((sws) ^ FLTR_SW_DCC_OFF) \ | |
549 & (FLTR_SW_DCC_OFF \ | |
550 | FLTR_SW_REP_ON \ | |
551 | FLTR_SW_DNSBL_M \ | |
552 | FLTR_SW_TRAP_REJ)) | |
553 | |
554 | |
555 /* everything there is to know about a currently active whitelist file */ | |
556 typedef struct { | |
557 DCC_WHITE_TBL *wtbl; | |
558 int ht_fd; /* hash table file */ | |
559 struct stat ht_sb; | |
560 DCC_WHITE_FGS wtbl_flags; | |
561 u_int wtbl_entries; /* # of entries mapped window */ | |
562 u_int wtbl_size; /* bytes in mapped window */ | |
563 time_t next_stat_time; | |
564 time_t reparse; /* when to re-parse file */ | |
565 time_t broken; /* something very sick until then */ | |
566 #ifdef DCC_WIN32 | |
567 HANDLE ht_map; /* WIN32 hash table map handle */ | |
568 #endif | |
569 u_int ascii_nm_len; | |
570 DCC_PATH ascii_nm; | |
571 DCC_PATH ht_nm; | |
572 int fno, lno; /* currently being parsed */ | |
573 u_char wf_flags; | |
574 # define DCC_WF_PER_USER 0x01 /* hostnames not allowed */ | |
575 # define DCC_WF_NOFILE 0x02 /* no whiteclnt file */ | |
576 # define DCC_WF_EITHER 0x04 /* either global or per-user ok */ | |
577 # define DCC_WF_RO 0x08 /* read only access */ | |
578 # define DCC_WF_WLIST 0x10 /* wlist command */ | |
579 # define DCC_WF_WLIST_RO 0x20 /* read-only wlist command */ | |
580 # define DCC_WF_WLIST_RW 0x40 /* read/write wlist command */ | |
581 u_char closed; | |
582 u_char need_reopen; /* lock-safe change flag */ | |
583 } DCC_WF; | |
584 | |
585 extern DCC_WF cmn_wf, cmn_tmp_wf; | |
586 | |
587 typedef enum { /* greylist result */ | |
588 ASK_GREY_FAIL, /* greylist server or other failure */ | |
589 ASK_GREY_OFF, /* client whitelist or blacklist */ | |
590 ASK_GREY_EMBARGO, | |
591 ASK_GREY_EMBARGO_END, /* first time server says ok */ | |
592 ASK_GREY_PASS, /* greylist server says ok */ | |
593 ASK_GREY_WHITE, /* greylist server says whitelisted */ | |
594 ASK_GREY_SPAM /* reported as spam to server */ | |
595 } ASK_GREY_RESULT; | |
596 | |
597 extern u_char grey_on; | |
598 extern u_char grey_query_only; | |
599 | |
600 extern u_int dcc_ck_qp_decode(DCC_GOT_CKS *, const char **, u_int *, | |
601 char *, u_int); | |
602 extern u_int dcc_ck_b64_decode(DCC_GOT_CKS *, const char **, u_int *, | |
603 char *, u_int); | |
604 | |
605 extern int dcc_ck_url(DCC_URL_SKIP *, char, char **); | |
606 #define DCC_CK_URL_MASK 0xff | |
607 #define DCC_CK_URL_SHIFT 8 | |
608 typedef enum { | |
609 DCC_CK_URL_CHAR, /* character in URL after host name */ | |
610 DCC_CK_URL_CK_LEN, /* 2nd slash */ | |
611 DCC_CK_URL_HOST, /* character in URL host name */ | |
612 DCC_CK_URL_DOT, /* dot in host name */ | |
613 DCC_CK_URL_HOST_END, /* end of host name */ | |
614 DCC_CK_URL_HOST_RESET, /* wasn't in host name after all */ | |
615 DCC_CK_URL_SKIP /* shipping URL or not in URL */ | |
616 } DCC_CK_URL; | |
617 | |
618 extern void dcc_ck_fuz1_init(DCC_GOT_CKS *); | |
619 extern void dcc_ck_fuz1(DCC_GOT_CKS *, const char *, u_int); | |
620 extern void dcc_ck_fuz1_fin(DCC_GOT_CKS *); | |
621 | |
622 extern void dcc_ck_fuz2_init(DCC_GOT_CKS *); | |
623 extern void dcc_ck_fuz2(DCC_GOT_CKS *, const char *, u_int); | |
624 extern void dcc_ck_fuz2_fin(DCC_GOT_CKS *); | |
625 | |
626 | |
627 extern void dcc_wf_init(DCC_WF *, u_int); | |
628 extern void dcc_wf_lock(DCC_WF *); | |
629 extern void dcc_wf_unlock(DCC_WF *); | |
630 | |
631 extern void dcc_str2ck(DCC_SUM, const char *, u_int, const char *); | |
632 extern u_char dcc_get_cks(DCC_GOT_CKS *, DCC_CK_TYPES, const char *, u_char); | |
633 extern u_char dcc_ck_get_sub(DCC_GOT_CKS *, const char *, const char *); | |
634 extern u_char dcc_add_sub_hdr(DCC_EMSG, const char *); | |
635 extern void dcc_ck_ipv6(DCC_SUM, const struct in6_addr *); | |
636 extern void dcc_get_ipv6_ck(DCC_GOT_CKS *, const struct in6_addr *); | |
637 extern void dcc_unget_ip_ck(DCC_GOT_CKS *); | |
638 extern u_char dcc_get_str_ip_ck(DCC_GOT_CKS *, const char *); | |
639 extern const char *parse_received(const char *, DCC_GOT_CKS *, | |
640 char *, int, char *, int, char *, int); | |
641 extern u_char parse_return_path(const char *, char *, int); | |
642 extern u_char parse_unix_from(const char *, char *, int); | |
643 extern u_char parse_mail_host(const char *, char *, int); | |
644 extern void dcc_print_cks(LOG_WRITE_FNC, void *, u_char, DCC_TGTS, | |
645 const DCC_GOT_CKS *, DCC_CKS_WTGTS, u_char); | |
646 #define PRINT_CK_TYPE_LEN 25 | |
647 #define PRINT_CK_SUM_LEN 35 | |
648 #define PRINT_CK_PAT_CK "%25s: %-35s" | |
649 #define PRINT_CK_PAT_LIM_CK "%25.*s%c %-35.*s" | |
650 #define PRINT_CK_PAT_SRVR " %7s" | |
651 #define PRINT_CK_PAT_SRVR_LEN 8 | |
652 #define PRINT_CK_PAT_WLIST " %5s" | |
653 #define PRINT_CK_PAT_WLIST_LEN 6 | |
654 #define PRINT_CK_PAT_THOLD PRINT_CK_PAT_WLIST | |
655 | |
656 extern void dcc_cks_init(DCC_GOT_CKS *); | |
657 extern void dcc_ck_mime_hdr(DCC_GOT_CKS *, const char *, const char *); | |
658 extern u_char parse_mime_hdr(DCC_GOT_CKS *, const char *, u_int, u_char); | |
659 extern void dcc_ck_body(DCC_GOT_CKS *, const void *, u_int); | |
660 extern void dcc_cks_fin(DCC_GOT_CKS *); | |
661 | |
662 extern u_char dcc_get_white(DCC_EMSG, DCC_WHITE_INX); | |
663 | |
664 typedef int (*DCC_PARSED_CK_FNC)(DCC_EMSG, DCC_WF *, | |
665 DCC_CK_TYPES, /* type of checksum */ | |
666 DCC_SUM, /* computed checksum */ | |
667 DCC_TGTS); /* "OK2" etc */ | |
668 typedef int (*DCC_PARSED_CK_CIDR_FNC)(DCC_EMSG, DCC_WF *, | |
669 int, | |
670 const struct in6_addr *, | |
671 const struct in6_addr *, | |
672 DCC_TGTS); | |
673 extern int dcc_parse_ck(DCC_EMSG, DCC_WF *wf, | |
674 const char *, DCC_CK_TYPES, const char *, DCC_TGTS, | |
675 DCC_PARSED_CK_FNC, DCC_PARSED_CK_CIDR_FNC); | |
676 extern int dcc_parse_hex_ck(DCC_EMSG, DCC_WF *wf, | |
677 const char *, DCC_CK_TYPES, const char *, DCC_TGTS, | |
678 DCC_PARSED_CK_FNC); | |
679 extern const char *wf_fnm(const DCC_WF *, int); | |
680 extern const char *wf_fnm_lno(DCC_FNM_LNO_BUF *, const DCC_WF *); | |
681 extern DCC_TGTS dcc_str2thold(DCC_CK_TYPES, const char *); | |
682 extern int dcc_parse_whitefile(DCC_EMSG, DCC_WF *, int, | |
683 DCC_PARSED_CK_FNC, DCC_PARSED_CK_CIDR_FNC); | |
684 | |
685 typedef enum { | |
686 DCC_WHITE_USE_DCC, | |
687 DCC_WHITE_LISTED, | |
688 DCC_WHITE_UNLISTED, | |
689 DCC_WHITE_BLACK | |
690 } DCC_WHITE_LISTING; | |
691 | |
692 typedef enum { | |
693 DCC_WHITE_OK, | |
694 DCC_WHITE_NOFILE, /* no ASCII file */ | |
695 DCC_WHITE_CONTINUE, /* modest error or bad host name */ | |
696 DCC_WHITE_COMPLAIN, /* bad hash table */ | |
697 DCC_WHITE_SILENT /* no more complaints */ | |
698 } DCC_WHITE_RESULT; | |
699 #define DCC_WHITE_RESULT_FAILURE DCC_WHITE_UNLISTED | |
700 | |
701 u_char dcc_new_white_nm(DCC_EMSG, DCC_WF *, const char *); | |
702 extern DCC_WHITE_RESULT dcc_rdy_white(DCC_EMSG, DCC_WF *, DCC_WF *); | |
703 extern DCC_WHITE_RESULT dcc_white_sum(DCC_EMSG, DCC_WF *, | |
704 DCC_CK_TYPES, const DCC_SUM, | |
705 DCC_TGTS *, DCC_WHITE_LISTING *); | |
706 extern u_char dcc_white_mx(DCC_EMSG, DCC_TGTS *, const DCC_GOT_CKS *); | |
707 extern DCC_WHITE_RESULT dcc_white_cks(DCC_EMSG, DCC_WF *, DCC_GOT_CKS *, | |
708 DCC_CKS_WTGTS, DCC_WHITE_LISTING *); | |
709 | |
710 | |
711 typedef u_int32_t ASK_ST; | |
712 #define ASK_ST_INVALID_MSG 0x00000001 /* incomplete SMTP transaction */ | |
713 #define ASK_ST_QUERY 0x00000002 /* ask but do not report */ | |
714 #define ASK_ST_QUERY_GREY 0x00000004 | |
715 #define ASK_ST_SRVR_OK2 0x00000008 /* have honored DCC_TGTS_OK2 */ | |
716 #define ASK_ST_SRVR_NOTSPAM 0x00000010 /* not spam by DCC server */ | |
717 #define ASK_ST_SRVR_ISSPAM 0x00000020 /* spam by DCC server & threshold */ | |
718 #define ASK_ST_REP_ISSPAM 0x00000040 /* spam by reputation & threshold */ | |
719 #define ASK_ST_MTA_NOTSPAM 0x00000080 /* MTA says it is not spam */ | |
720 #define ASK_ST_MTA_ISSPAM 0x00000100 /* MTA says it is spam */ | |
721 #define ASK_ST_WLIST_NOTSPAM 0x00000200 /* locally whitelisted message */ | |
722 #define ASK_ST_WLIST_ISSPAM 0x00000400 /* locally blacklisted message */ | |
723 #define ASK_ST_CLNT_ISSPAM 0x00000800 /* report to DCC server as spam */ | |
724 #define ASK_ST_GREY_EMBARGO 0x00001000 /* embargo this message */ | |
725 #define ASK_ST_GREY_LOGIT 0x00002000 /* greylist logging indicated */ | |
726 #define ASK_ST_LOGIT 0x00004000 /* log message for all recipients */ | |
727 #define ASK_ST_DNSBL_HIT(n) (0x00008000*DNSBL_G2B(n)) /* DNSBL hit */ | |
728 # define ASK_ST_DNSBL_HIT_M 0x00038000 | |
729 # define ASK_ST_DNSBL_HIT_BITS(st) (((st)&ASK_ST_DNSBL_HIT_M) \ | |
730 / ASK_ST_DNSBL_HIT(0)) | |
731 #define ASK_ST_DNSBL_TIMEO(n) (0x00040000*DNSBL_G2B(n)) /* DNSBL timeout */ | |
732 # define ASK_ST_DNSBL_TIMEO_M 0x001c0000 | |
733 # define ASK_ST_DNSBL_TIMEO_BITS(st) (((st)&ASK_ST_DNSBL_TIMEO_M) \ | |
734 / ASK_ST_DNSBL_TIMEO(0)) | |
735 #define ASK_ST_DNSBL_TFAIL(n) (0x00200000*DNSBL_G2B(n)) | |
736 # define ASK_ST_DNSBL_TFAIL_M 0x00e00000 | |
737 # define ASK_ST_DNSBL_TFAIL_BITS(st) (((st)&ASK_ST_DNSBL_TFAIL_M) \ | |
738 / ASK_ST_DNSBL_TFAIL(0)) | |
739 | |
740 | |
741 extern u_char dcc_ck_grey_answer(DCC_EMSG, const DCC_OP_RESP *); | |
742 extern int ask_dcc(DCC_EMSG, DCC_CLNT_CTXT *, u_char, | |
743 DCC_HEADER_BUF *, DCC_GOT_CKS *, ASK_ST *, u_char, | |
744 DCC_TGTS); | |
745 extern u_char unthr_ask_white(DCC_EMSG, ASK_ST *, FLTR_SWS *, const char *, | |
746 DCC_GOT_CKS *, DCC_CKS_WTGTS); | |
747 extern u_char unthr_ask_dcc(DCC_EMSG, DCC_CLNT_CTXT*, DCC_HEADER_BUF*, ASK_ST *, | |
748 DCC_GOT_CKS *, u_char, DCC_TGTS); | |
749 extern void dcc_clear_tholds(void); | |
750 extern u_char dcc_merge_tholds(DCC_CKSUM_THOLDS, | |
751 const DCC_CKSUM_THOLDS, const DCC_WHITE_TBL *); | |
752 extern void dcc_parse_honor(const char *); | |
753 extern u_char dcc_parse_tholds(const char *, const char *); | |
754 extern void dcc_honor_log_cnts(ASK_ST *, const DCC_GOT_CKS *, DCC_TGTS); | |
755 extern FLTR_SWS wf2sws(FLTR_SWS, const DCC_WF *); | |
756 extern void log_ask_st(LOG_WRITE_FNC, void *, ASK_ST, FLTR_SWS, u_char, | |
757 const DCC_HEADER_BUF *); | |
758 extern u_char dcc_parse_client_grey(const char *); | |
759 extern ASK_GREY_RESULT ask_grey(DCC_EMSG, DCC_CLNT_CTXT *, DCC_OPS, | |
760 DCC_SUM, DCC_SUM, | |
761 const DCC_GOT_CKS *, const DCC_SUM, | |
762 DCC_TGTS *, DCC_TGTS *, DCC_TGTS *); | |
763 | |
764 extern u_char dcc_parse_dnsbl(DCC_EMSG, const char *, const char *, u_char); | |
765 extern const REPLY_TPLT *dnsbl_parse_reply(const char *); | |
766 extern void helper_save_arg(const char *, const char *); | |
767 extern void helper_init(int); | |
768 extern void dcc_dnsbl_init(DCC_GOT_CKS *, | |
769 DCC_CLNT_CTXT *, void *, const char *); | |
770 extern void url_dnsbl(DNSBL_WORK *); | |
771 extern void dcc_mail_host_dnsbl(DNSBL_WORK *, const char *); | |
772 extern void dcc_client_dnsbl(DNSBL_WORK *, const struct in6_addr *, | |
773 const char *); | |
774 extern void dcc_dnsbl_result(ASK_ST *, DNSBL_WORK *); | |
775 extern int PATTRIB(3,4) thr_log_print(void *, u_char, const char *, ...); | |
776 extern int PATTRIB(2,3) thr_error_msg(void *, const char *, ...); | |
777 extern void PATTRIB(2,3) thr_trace_msg(void *, const char *, ...); | |
778 | |
779 #endif /* DCC_CK_H */ |