Mercurial > notdcc
comparison misc/wlist.c @ 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 * whitelist lister | |
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.67 $Revision$ | |
40 */ | |
41 | |
42 #include "dcc_defs.h" | |
43 #include "dcc_ck.h" | |
44 #include <arpa/inet.h> | |
45 | |
46 static DCC_EMSG dcc_emsg; | |
47 static const char *homedir; | |
48 | |
49 static u_char quiet; | |
50 | |
51 static const char *ts2buf(time_t); | |
52 | |
53 | |
54 static void NRATTRIB | |
55 usage(void) | |
56 { | |
57 dcc_logbad(EX_USAGE, "usage: [-VPQ] [-h homedir] [-t env_to] file"); | |
58 } | |
59 | |
60 | |
61 | |
62 int | |
63 main(int argc, char **argv) | |
64 { | |
65 const char *to = 0; | |
66 u_char print_version = 0; | |
67 u_char first; | |
68 DCC_WHITE_INX inx, inx2; | |
69 const char *nm; | |
70 DCC_SUM sum; | |
71 struct stat ht_sb, ascii_sb, inc_sb; | |
72 char tgts_buf[20]; | |
73 int col; | |
74 u_char heading; | |
75 DCC_TGTS tgts; | |
76 DCC_WHITE_LISTING listing; | |
77 DCC_CK_TYPES type; | |
78 int i; | |
79 | |
80 dcc_syslog_init(0, argv[0], 0); | |
81 dcc_clnt_debug = 99; | |
82 | |
83 dup2(1, 2); /* put error messages in context */ | |
84 | |
85 dcc_wf_init(&cmn_wf, DCC_WF_WLIST | DCC_WF_EITHER); | |
86 | |
87 while ((i = getopt(argc, argv, "VPQqh:t:")) != EOF) { | |
88 switch (i) { | |
89 case 'V': | |
90 fprintf(stderr, DCC_VERSION"\n"); | |
91 print_version = 1; | |
92 break; | |
93 | |
94 case 'P': /* parse or rebuild hash table */ | |
95 cmn_wf.wf_flags &= ~DCC_WF_WLIST_RO; | |
96 cmn_wf.wf_flags |= DCC_WF_WLIST_RW; | |
97 break; | |
98 | |
99 case 'Q': /* query; don't rebuild hash table */ | |
100 cmn_wf.wf_flags &= ~DCC_WF_WLIST_RW; | |
101 cmn_wf.wf_flags |= DCC_WF_WLIST_RO; | |
102 break; | |
103 | |
104 case 'q': | |
105 quiet = 1; | |
106 break; | |
107 | |
108 case 'h': | |
109 homedir = optarg; | |
110 break; | |
111 | |
112 case 't': | |
113 to = optarg; | |
114 break; | |
115 | |
116 default: | |
117 usage(); | |
118 } | |
119 } | |
120 argc -= optind; | |
121 argv += optind; | |
122 if (argc == 0) { | |
123 if (print_version) | |
124 exit(EX_OK); | |
125 usage(); | |
126 } | |
127 | |
128 dcc_cdhome(0, homedir, 1); | |
129 | |
130 first = 1; | |
131 while ((nm = *argv++) != 0) { | |
132 if (first) { | |
133 first = 0; | |
134 } else { | |
135 printf("\n\n--------------------------------\n"); | |
136 } | |
137 if (cmn_wf.wf_flags & DCC_WF_WLIST_RO) | |
138 cmn_wf.wf_flags |= DCC_WF_RO; | |
139 else | |
140 cmn_wf.wf_flags &= ~DCC_WF_RO; | |
141 if (!dcc_new_white_nm(dcc_emsg, &cmn_wf, nm)) { | |
142 dcc_error_msg("%s", dcc_emsg); | |
143 exit(EX_DATAERR); | |
144 } | |
145 printf("%s\n", cmn_wf.ascii_nm); | |
146 | |
147 switch (dcc_rdy_white(dcc_emsg, &cmn_wf, &cmn_tmp_wf)) { | |
148 case DCC_WHITE_OK: | |
149 break; | |
150 case DCC_WHITE_NOFILE: | |
151 dcc_error_msg("does %s exist?", nm); | |
152 exit(EX_DATAERR); | |
153 case DCC_WHITE_CONTINUE: | |
154 dcc_error_msg("%s", dcc_emsg); | |
155 break; | |
156 case DCC_WHITE_SILENT: | |
157 case DCC_WHITE_COMPLAIN: | |
158 dcc_error_msg("%s", dcc_emsg); | |
159 exit(EX_DATAERR); | |
160 break; | |
161 } | |
162 printf("%s\n", cmn_wf.wtbl->magic); | |
163 | |
164 if (to) { | |
165 dcc_str2ck(sum, 0, 0, to); | |
166 printf("%s\n%8s %s\t", | |
167 to, | |
168 dcc_type2str_err(DCC_CK_ENV_TO, 0, 0, 0), | |
169 dcc_ck2str_err(DCC_CK_ENV_TO, sum, 0)); | |
170 if (DCC_WHITE_OK != dcc_white_sum(dcc_emsg, &cmn_wf, | |
171 DCC_CK_ENV_TO, sum, | |
172 &tgts, &listing)) { | |
173 dcc_error_msg("%s", dcc_emsg); | |
174 } | |
175 if (listing == DCC_WHITE_UNLISTED) { | |
176 printf("unlisted\n"); | |
177 } else { | |
178 printf("%s\n", | |
179 dcc_tgts2str(tgts_buf, sizeof(tgts_buf), | |
180 tgts, 0)); | |
181 } | |
182 continue; | |
183 } | |
184 | |
185 printf(" %s whitelist %d entries\n", | |
186 (cmn_wf.wtbl_flags & DCC_WHITE_FG_PER_USER) | |
187 ? "per-user" : "global", | |
188 cmn_wf.wtbl->hdr.entries); | |
189 | |
190 if (0 > fstat(cmn_wf.ht_fd, &ht_sb)) { | |
191 dcc_error_msg("stat(%s): %s", | |
192 cmn_wf.ht_nm, ERROR_STR()); | |
193 exit(EX_DATAERR); | |
194 } | |
195 | |
196 if (0 > stat(cmn_wf.ascii_nm, &ascii_sb)) { | |
197 dcc_error_msg("stat(%s): %s", | |
198 cmn_wf.ascii_nm, ERROR_STR()); | |
199 } else if (ht_sb.st_mtime < ascii_sb.st_mtime) { | |
200 printf(" %s is older than %s\n", | |
201 cmn_wf.ht_nm, cmn_wf.ascii_nm); | |
202 } | |
203 | |
204 if (cmn_wf.wtbl->hdr.ascii_mtime == 0) { | |
205 printf(" %s broken\n", cmn_wf.ht_nm); | |
206 } else if (cmn_wf.wtbl->hdr.ascii_mtime != ascii_sb.st_mtime) { | |
207 printf(" %s has timestamp %s\n" | |
208 "\tfor %s which has mtime %s\n", | |
209 cmn_wf.ht_nm, | |
210 ts2buf(cmn_wf.wtbl->hdr.ascii_mtime), | |
211 cmn_wf.ascii_nm, | |
212 ts2buf(ascii_sb.st_mtime)); | |
213 } | |
214 | |
215 if (cmn_wf.wtbl->hdr.broken != 0) | |
216 printf(" %s broken until %s\n", | |
217 cmn_wf.ht_nm, | |
218 ts2buf(cmn_wf.wtbl->hdr.broken)); | |
219 if (cmn_wf.wtbl->hdr.reparse != 0) | |
220 printf(" re-parse %s for errors after %s\n", | |
221 cmn_wf.ascii_nm, | |
222 ts2buf(cmn_wf.wtbl->hdr.reparse)); | |
223 | |
224 if (cmn_wf.wtbl->hdr.flags & DCC_WHITE_FG_HOSTNAMES) { | |
225 printf(" resolve hostnames after %s\n", | |
226 ts2buf(ht_sb.st_mtime + DCC_WHITECLNT_RESOLVE)); | |
227 } else if (!(cmn_wf.wtbl->hdr.flags & DCC_WHITE_FG_PER_USER)) { | |
228 printf(" contains no hostnames\n"); | |
229 } | |
230 | |
231 for (i = 0; i < DIM(cmn_wf.wtbl->hdr.white_incs); ++i) { | |
232 if (cmn_wf.wtbl->hdr.white_incs[i].nm[0] == '\0') | |
233 break; | |
234 if (!i) | |
235 printf(" includes\n"); | |
236 printf(" %s\n", | |
237 fnm2abs_err(0, | |
238 cmn_wf.wtbl->hdr.white_incs[i].nm)); | |
239 if (0 > stat(cmn_wf.wtbl->hdr.white_incs[i].nm, | |
240 &inc_sb)) { | |
241 dcc_error_msg("stat(%s): %s", | |
242 cmn_wf.ascii_nm, ERROR_STR()); | |
243 } else if (ht_sb.st_mtime < inc_sb.st_mtime) { | |
244 printf(" %s is older than %s" | |
245 " and needs rebuilding\n", | |
246 cmn_wf.ht_nm, | |
247 path2fnm(cmn_wf.wtbl->hdr.white_incs[i | |
248 ].nm)); | |
249 } | |
250 } | |
251 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DCC_ON) | |
252 printf(" option DCC-on\n"); | |
253 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DCC_OFF) | |
254 printf(" option DCC-off\n"); | |
255 | |
256 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_REP_ON) | |
257 printf(" option dcc-rep-on\n"); | |
258 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_REP_OFF) | |
259 printf(" option dcc-rep-off\n"); | |
260 | |
261 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_ON) | |
262 printf(" option greylist-on\n"); | |
263 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_OFF) | |
264 printf(" option greylist-off\n"); | |
265 | |
266 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_ALL) | |
267 printf(" option log-all\n"); | |
268 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_NORMAL) | |
269 printf(" option log-normal\n"); | |
270 | |
271 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_D) | |
272 printf(" option log-subdirectory-day\n"); | |
273 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_H) | |
274 printf(" option log-subdirectory-hour\n"); | |
275 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_M) | |
276 printf(" option log-subdirectory-minute\n"); | |
277 | |
278 | |
279 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_LOG_ON) | |
280 printf(" option greylist-log-on\n"); | |
281 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_LOG_OFF) | |
282 printf(" option greylist-log-off\n"); | |
283 | |
284 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_MTA_FIRST) | |
285 printf(" option MTA-first\n"); | |
286 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_MTA_LAST) | |
287 printf(" option MTA-last\n"); | |
288 | |
289 for (i = 0; i < MAX_DNSBL_GROUPS; ++i) { | |
290 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DNSBL_ON(i)) | |
291 printf(" option DNSBL%d-on\n", i+1); | |
292 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DNSBL_OFF(i)) | |
293 printf(" option DNSBL%d-off\n", i+1); | |
294 } | |
295 | |
296 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DISCARD_OK) | |
297 printf(" option forced-discard-ok\n"); | |
298 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_NO_DISCARD) | |
299 printf(" option no-forced-discard\n"); | |
300 | |
301 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_TRAP_ACC) | |
302 printf(" option spam-trap-accept\n"); | |
303 if (cmn_wf.wtbl_flags & DCC_WHITE_FG_TRAP_REJ) | |
304 printf(" option spam-trap_rej\n"); | |
305 | |
306 for (type = DCC_CK_TYPE_FIRST; | |
307 type <= DCC_CK_TYPE_LAST; | |
308 ++type) { | |
309 tgts = cmn_wf.wtbl->hdr.tholds_rej[type]; | |
310 if (tgts == DCC_THOLD_UNSET) | |
311 continue; | |
312 printf(" option threshold %s,%s\n", | |
313 dcc_type2str_err(type, 0, 0, 0), | |
314 dcc_thold2str(tgts_buf, sizeof(tgts_buf), | |
315 type, tgts)); | |
316 } | |
317 | |
318 printf("\n file checksum %s\n", | |
319 dcc_ck2str_err(0, cmn_wf.wtbl->hdr.ck_sum, 0)); | |
320 | |
321 if (quiet) | |
322 continue; | |
323 | |
324 heading = 0; | |
325 for (i = 0; i < cmn_wf.wtbl->hdr.cidr.len; ++i) { | |
326 struct in_addr addr4; | |
327 char cidr_buf[INET6_ADDRSTRLEN]; | |
328 | |
329 DCC_WHITE_CIDR_ENTRY *e=&cmn_wf.wtbl->hdr.cidr.e[i]; | |
330 if (!heading) { | |
331 heading = 1; | |
332 fputs("\n CIDR blocks\n", stdout); | |
333 } | |
334 printf("%6s %s/%d\n", | |
335 dcc_tgts2str(tgts_buf, sizeof(tgts_buf), | |
336 e->tgts,0), | |
337 dcc_ipv6tostr2(cidr_buf, sizeof(cidr_buf), | |
338 &e->addr), | |
339 dcc_ipv6toipv4(&addr4, &e->addr) | |
340 ? e->bits-96 : e->bits); | |
341 } | |
342 if (heading) | |
343 putchar('\n'); | |
344 | |
345 /* first the hash table */ | |
346 fputs("\n hash table\n", stdout); | |
347 col = 0; | |
348 for (inx = 0; inx < DIM(cmn_wf.wtbl->bins); ++inx) { | |
349 if (!cmn_wf.wtbl->bins[inx] | |
350 && col == 0 | |
351 && inx != 0) { | |
352 inx2 = inx; | |
353 while (inx2 < DIM(cmn_wf.wtbl->bins) | |
354 && !cmn_wf.wtbl->bins[inx2]) | |
355 ++inx2; | |
356 i = inx2 - inx; | |
357 i -= i % 4; | |
358 if (i != 0) { | |
359 printf(" ...\n"); | |
360 inx += i; | |
361 } | |
362 } | |
363 printf("%4d:", inx); | |
364 if (cmn_wf.wtbl->bins[inx]) { | |
365 printf("%-4d", cmn_wf.wtbl->bins[inx]); | |
366 } else { | |
367 printf(" "); | |
368 } | |
369 col = (col + 1) % 4; | |
370 putchar(col == 0 ? '\n' : '\t'); | |
371 } | |
372 | |
373 /* then the entries */ | |
374 printf("\n\n%4s->%-4s %12s %6s\n", | |
375 "slot", "next", "type", "count"); | |
376 for (inx = 0; inx < cmn_wf.wtbl_entries; ++inx) { | |
377 DCC_WHITE_ENTRY *e = &cmn_wf.wtbl->tbl[inx]; | |
378 if (e->type == DCC_CK_INVALID) | |
379 continue; | |
380 printf("%4d->%-4d %12s %6s %s\n", | |
381 inx, e->fwd, | |
382 dcc_type2str_err(e->type, 0, 0, 0), | |
383 dcc_tgts2str(tgts_buf, sizeof(tgts_buf), | |
384 e->tgts, 0), | |
385 dcc_ck2str_err(e->type, e->sum, 0)); | |
386 } | |
387 } | |
388 exit(EX_OK); | |
389 } | |
390 | |
391 | |
392 | |
393 static const char * | |
394 ts2buf(time_t ts) | |
395 { | |
396 static struct { | |
397 char buf[26]; | |
398 } times[4]; | |
399 static int nbuf; | |
400 | |
401 nbuf = (nbuf+1) % DIM(times); | |
402 return dcc_time2str(times[nbuf].buf, sizeof(times[nbuf].buf), | |
403 "%b %d %X %Z", | |
404 ts); | |
405 } |