Mercurial > notdcc
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/wlist.c Tue Mar 10 13:49:58 2009 +0100 @@ -0,0 +1,405 @@ +/* Distributed Checksum Clearinghouse + * + * whitelist lister + * + * 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.67 $Revision$ + */ + +#include "dcc_defs.h" +#include "dcc_ck.h" +#include <arpa/inet.h> + +static DCC_EMSG dcc_emsg; +static const char *homedir; + +static u_char quiet; + +static const char *ts2buf(time_t); + + +static void NRATTRIB +usage(void) +{ + dcc_logbad(EX_USAGE, "usage: [-VPQ] [-h homedir] [-t env_to] file"); +} + + + +int +main(int argc, char **argv) +{ + const char *to = 0; + u_char print_version = 0; + u_char first; + DCC_WHITE_INX inx, inx2; + const char *nm; + DCC_SUM sum; + struct stat ht_sb, ascii_sb, inc_sb; + char tgts_buf[20]; + int col; + u_char heading; + DCC_TGTS tgts; + DCC_WHITE_LISTING listing; + DCC_CK_TYPES type; + int i; + + dcc_syslog_init(0, argv[0], 0); + dcc_clnt_debug = 99; + + dup2(1, 2); /* put error messages in context */ + + dcc_wf_init(&cmn_wf, DCC_WF_WLIST | DCC_WF_EITHER); + + while ((i = getopt(argc, argv, "VPQqh:t:")) != EOF) { + switch (i) { + case 'V': + fprintf(stderr, DCC_VERSION"\n"); + print_version = 1; + break; + + case 'P': /* parse or rebuild hash table */ + cmn_wf.wf_flags &= ~DCC_WF_WLIST_RO; + cmn_wf.wf_flags |= DCC_WF_WLIST_RW; + break; + + case 'Q': /* query; don't rebuild hash table */ + cmn_wf.wf_flags &= ~DCC_WF_WLIST_RW; + cmn_wf.wf_flags |= DCC_WF_WLIST_RO; + break; + + case 'q': + quiet = 1; + break; + + case 'h': + homedir = optarg; + break; + + case 't': + to = optarg; + break; + + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc == 0) { + if (print_version) + exit(EX_OK); + usage(); + } + + dcc_cdhome(0, homedir, 1); + + first = 1; + while ((nm = *argv++) != 0) { + if (first) { + first = 0; + } else { + printf("\n\n--------------------------------\n"); + } + if (cmn_wf.wf_flags & DCC_WF_WLIST_RO) + cmn_wf.wf_flags |= DCC_WF_RO; + else + cmn_wf.wf_flags &= ~DCC_WF_RO; + if (!dcc_new_white_nm(dcc_emsg, &cmn_wf, nm)) { + dcc_error_msg("%s", dcc_emsg); + exit(EX_DATAERR); + } + printf("%s\n", cmn_wf.ascii_nm); + + switch (dcc_rdy_white(dcc_emsg, &cmn_wf, &cmn_tmp_wf)) { + case DCC_WHITE_OK: + break; + case DCC_WHITE_NOFILE: + dcc_error_msg("does %s exist?", nm); + exit(EX_DATAERR); + case DCC_WHITE_CONTINUE: + dcc_error_msg("%s", dcc_emsg); + break; + case DCC_WHITE_SILENT: + case DCC_WHITE_COMPLAIN: + dcc_error_msg("%s", dcc_emsg); + exit(EX_DATAERR); + break; + } + printf("%s\n", cmn_wf.wtbl->magic); + + if (to) { + dcc_str2ck(sum, 0, 0, to); + printf("%s\n%8s %s\t", + to, + dcc_type2str_err(DCC_CK_ENV_TO, 0, 0, 0), + dcc_ck2str_err(DCC_CK_ENV_TO, sum, 0)); + if (DCC_WHITE_OK != dcc_white_sum(dcc_emsg, &cmn_wf, + DCC_CK_ENV_TO, sum, + &tgts, &listing)) { + dcc_error_msg("%s", dcc_emsg); + } + if (listing == DCC_WHITE_UNLISTED) { + printf("unlisted\n"); + } else { + printf("%s\n", + dcc_tgts2str(tgts_buf, sizeof(tgts_buf), + tgts, 0)); + } + continue; + } + + printf(" %s whitelist %d entries\n", + (cmn_wf.wtbl_flags & DCC_WHITE_FG_PER_USER) + ? "per-user" : "global", + cmn_wf.wtbl->hdr.entries); + + if (0 > fstat(cmn_wf.ht_fd, &ht_sb)) { + dcc_error_msg("stat(%s): %s", + cmn_wf.ht_nm, ERROR_STR()); + exit(EX_DATAERR); + } + + if (0 > stat(cmn_wf.ascii_nm, &ascii_sb)) { + dcc_error_msg("stat(%s): %s", + cmn_wf.ascii_nm, ERROR_STR()); + } else if (ht_sb.st_mtime < ascii_sb.st_mtime) { + printf(" %s is older than %s\n", + cmn_wf.ht_nm, cmn_wf.ascii_nm); + } + + if (cmn_wf.wtbl->hdr.ascii_mtime == 0) { + printf(" %s broken\n", cmn_wf.ht_nm); + } else if (cmn_wf.wtbl->hdr.ascii_mtime != ascii_sb.st_mtime) { + printf(" %s has timestamp %s\n" + "\tfor %s which has mtime %s\n", + cmn_wf.ht_nm, + ts2buf(cmn_wf.wtbl->hdr.ascii_mtime), + cmn_wf.ascii_nm, + ts2buf(ascii_sb.st_mtime)); + } + + if (cmn_wf.wtbl->hdr.broken != 0) + printf(" %s broken until %s\n", + cmn_wf.ht_nm, + ts2buf(cmn_wf.wtbl->hdr.broken)); + if (cmn_wf.wtbl->hdr.reparse != 0) + printf(" re-parse %s for errors after %s\n", + cmn_wf.ascii_nm, + ts2buf(cmn_wf.wtbl->hdr.reparse)); + + if (cmn_wf.wtbl->hdr.flags & DCC_WHITE_FG_HOSTNAMES) { + printf(" resolve hostnames after %s\n", + ts2buf(ht_sb.st_mtime + DCC_WHITECLNT_RESOLVE)); + } else if (!(cmn_wf.wtbl->hdr.flags & DCC_WHITE_FG_PER_USER)) { + printf(" contains no hostnames\n"); + } + + for (i = 0; i < DIM(cmn_wf.wtbl->hdr.white_incs); ++i) { + if (cmn_wf.wtbl->hdr.white_incs[i].nm[0] == '\0') + break; + if (!i) + printf(" includes\n"); + printf(" %s\n", + fnm2abs_err(0, + cmn_wf.wtbl->hdr.white_incs[i].nm)); + if (0 > stat(cmn_wf.wtbl->hdr.white_incs[i].nm, + &inc_sb)) { + dcc_error_msg("stat(%s): %s", + cmn_wf.ascii_nm, ERROR_STR()); + } else if (ht_sb.st_mtime < inc_sb.st_mtime) { + printf(" %s is older than %s" + " and needs rebuilding\n", + cmn_wf.ht_nm, + path2fnm(cmn_wf.wtbl->hdr.white_incs[i + ].nm)); + } + } + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DCC_ON) + printf(" option DCC-on\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DCC_OFF) + printf(" option DCC-off\n"); + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_REP_ON) + printf(" option dcc-rep-on\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_REP_OFF) + printf(" option dcc-rep-off\n"); + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_ON) + printf(" option greylist-on\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_OFF) + printf(" option greylist-off\n"); + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_ALL) + printf(" option log-all\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_NORMAL) + printf(" option log-normal\n"); + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_D) + printf(" option log-subdirectory-day\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_H) + printf(" option log-subdirectory-hour\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_LOG_M) + printf(" option log-subdirectory-minute\n"); + + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_LOG_ON) + printf(" option greylist-log-on\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_GREY_LOG_OFF) + printf(" option greylist-log-off\n"); + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_MTA_FIRST) + printf(" option MTA-first\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_MTA_LAST) + printf(" option MTA-last\n"); + + for (i = 0; i < MAX_DNSBL_GROUPS; ++i) { + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DNSBL_ON(i)) + printf(" option DNSBL%d-on\n", i+1); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DNSBL_OFF(i)) + printf(" option DNSBL%d-off\n", i+1); + } + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_DISCARD_OK) + printf(" option forced-discard-ok\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_NO_DISCARD) + printf(" option no-forced-discard\n"); + + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_TRAP_ACC) + printf(" option spam-trap-accept\n"); + if (cmn_wf.wtbl_flags & DCC_WHITE_FG_TRAP_REJ) + printf(" option spam-trap_rej\n"); + + for (type = DCC_CK_TYPE_FIRST; + type <= DCC_CK_TYPE_LAST; + ++type) { + tgts = cmn_wf.wtbl->hdr.tholds_rej[type]; + if (tgts == DCC_THOLD_UNSET) + continue; + printf(" option threshold %s,%s\n", + dcc_type2str_err(type, 0, 0, 0), + dcc_thold2str(tgts_buf, sizeof(tgts_buf), + type, tgts)); + } + + printf("\n file checksum %s\n", + dcc_ck2str_err(0, cmn_wf.wtbl->hdr.ck_sum, 0)); + + if (quiet) + continue; + + heading = 0; + for (i = 0; i < cmn_wf.wtbl->hdr.cidr.len; ++i) { + struct in_addr addr4; + char cidr_buf[INET6_ADDRSTRLEN]; + + DCC_WHITE_CIDR_ENTRY *e=&cmn_wf.wtbl->hdr.cidr.e[i]; + if (!heading) { + heading = 1; + fputs("\n CIDR blocks\n", stdout); + } + printf("%6s %s/%d\n", + dcc_tgts2str(tgts_buf, sizeof(tgts_buf), + e->tgts,0), + dcc_ipv6tostr2(cidr_buf, sizeof(cidr_buf), + &e->addr), + dcc_ipv6toipv4(&addr4, &e->addr) + ? e->bits-96 : e->bits); + } + if (heading) + putchar('\n'); + + /* first the hash table */ + fputs("\n hash table\n", stdout); + col = 0; + for (inx = 0; inx < DIM(cmn_wf.wtbl->bins); ++inx) { + if (!cmn_wf.wtbl->bins[inx] + && col == 0 + && inx != 0) { + inx2 = inx; + while (inx2 < DIM(cmn_wf.wtbl->bins) + && !cmn_wf.wtbl->bins[inx2]) + ++inx2; + i = inx2 - inx; + i -= i % 4; + if (i != 0) { + printf(" ...\n"); + inx += i; + } + } + printf("%4d:", inx); + if (cmn_wf.wtbl->bins[inx]) { + printf("%-4d", cmn_wf.wtbl->bins[inx]); + } else { + printf(" "); + } + col = (col + 1) % 4; + putchar(col == 0 ? '\n' : '\t'); + } + + /* then the entries */ + printf("\n\n%4s->%-4s %12s %6s\n", + "slot", "next", "type", "count"); + for (inx = 0; inx < cmn_wf.wtbl_entries; ++inx) { + DCC_WHITE_ENTRY *e = &cmn_wf.wtbl->tbl[inx]; + if (e->type == DCC_CK_INVALID) + continue; + printf("%4d->%-4d %12s %6s %s\n", + inx, e->fwd, + dcc_type2str_err(e->type, 0, 0, 0), + dcc_tgts2str(tgts_buf, sizeof(tgts_buf), + e->tgts, 0), + dcc_ck2str_err(e->type, e->sum, 0)); + } + } + exit(EX_OK); +} + + + +static const char * +ts2buf(time_t ts) +{ + static struct { + char buf[26]; + } times[4]; + static int nbuf; + + nbuf = (nbuf+1) % DIM(times); + return dcc_time2str(times[nbuf].buf, sizeof(times[nbuf].buf), + "%b %d %X %Z", + ts); +}