From 1ec6a8f8952a91163cc26b66c15c8a55451ecff8 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sat, 20 Feb 2010 09:33:01 +0200 Subject: [PATCH] doveadm: Added penalty command to dump auth penalty state. --HG-- branch : HEAD --- src/doveadm/Makefile.am | 1 + src/doveadm/doveadm-penalty.c | 126 ++++++++++++++++++++++++++++++++++ src/doveadm/doveadm.c | 1 + src/doveadm/doveadm.h | 1 + 4 files changed, 129 insertions(+) create mode 100644 src/doveadm/doveadm-penalty.c diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am index 12f27e0ff1..92793d6c51 100644 --- a/src/doveadm/Makefile.am +++ b/src/doveadm/Makefile.am @@ -36,6 +36,7 @@ doveadm_SOURCES = \ doveadm-dump-mailboxlog.c \ doveadm-dump-thread.c \ doveadm-mail.c \ + doveadm-penalty.c \ doveadm-pw.c \ doveadm-who.c diff --git a/src/doveadm/doveadm-penalty.c b/src/doveadm/doveadm-penalty.c new file mode 100644 index 0000000000..c81cf6fda0 --- /dev/null +++ b/src/doveadm/doveadm-penalty.c @@ -0,0 +1,126 @@ +/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "network.h" +#include "istream.h" +#include "hash.h" +#include "doveadm.h" + +#include +#include +#include +#include + +struct penalty_line { + struct ip_addr ip; + unsigned int penalty; + time_t last_penalty, last_update; +}; + +struct penalty_context { + const char *anvil_path; + + struct ip_addr net_ip; + unsigned int net_bits; +}; + +static void penalty_parse_line(const char *line, struct penalty_line *line_r) +{ + const char *const *args = t_strsplit(line, "\t"); + const char *ident = args[0]; + const char *penalty_str = args[1]; + const char *last_penalty_str = args[2]; + const char *last_update_str = args[3]; + + memset(line_r, 0, sizeof(*line_r)); + + net_addr2ip(ident, &line_r->ip); + line_r->penalty = strtoul(penalty_str, NULL, 10); + line_r->last_penalty = strtoul(last_penalty_str, NULL, 10); + line_r->last_update = strtoul(last_update_str, NULL, 10); +} + +static void +penalty_print_line(struct penalty_context *ctx, + const struct penalty_line *line) +{ + const struct tm *tm; + char buf[10]; + + if (ctx->net_bits > 0) { + if (!net_is_in_network(&line->ip, &ctx->net_ip, ctx->net_bits)) + return; + } + + tm = localtime(&line->last_update); + strftime(buf, sizeof(buf), "%H:%M:%S", tm); + + printf("%-16s %7u %s %s\n", net_ip2addr(&line->ip), line->penalty, + unixdate2str(line->last_penalty), buf); +} + +static void penalty_lookup(struct penalty_context *ctx) +{ +#define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n" +#define ANVIL_CMD ANVIL_HANDSHAKE"PENALTY-DUMP\n" + struct istream *input; + const char *line; + int fd; + + fd = net_connect_unix(ctx->anvil_path); + if (fd == -1) + i_fatal("net_connect_unix(%s) failed: %m", ctx->anvil_path); + net_set_nonblock(fd, FALSE); + + input = i_stream_create_fd(fd, (size_t)-1, TRUE); + if (write(fd, ANVIL_CMD, strlen(ANVIL_CMD)) < 0) + i_fatal("write(%s) failed: %m", ctx->anvil_path); + while ((line = i_stream_read_next_line(input)) != NULL) { + if (*line == '\0') + break; + T_BEGIN { + struct penalty_line penalty_line; + + penalty_parse_line(line, &penalty_line); + penalty_print_line(ctx, &penalty_line); + } T_END; + } + if (input->stream_errno != 0) + i_fatal("read(%s) failed: %m", ctx->anvil_path); + + i_stream_destroy(&input); +} + +static void cmd_penalty(int argc, char *argv[]) +{ + struct penalty_context ctx; + int c; + + memset(&ctx, 0, sizeof(ctx)); + ctx.anvil_path = PKG_RUNDIR"/anvil"; + while ((c = getopt(argc, argv, "a:")) > 0) { + switch (c) { + case 'a': + ctx.anvil_path = optarg; + break; + default: + help(&doveadm_cmd_penalty); + } + } + + if (argv[1] != NULL) { + if (net_parse_range(argv[1], &ctx.net_ip, &ctx.net_bits) == 0) + argv++; + } + if (argv[1] != NULL) + help(&doveadm_cmd_penalty); + + fprintf(stderr, "%-16s penalty last_penalty last_update\n", "IP"); + penalty_lookup(&ctx); +} + +struct doveadm_cmd doveadm_cmd_penalty = { + cmd_penalty, "penalty", + "[-a ] []", NULL +}; diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c index 5bac41aa6b..fc3b0bad41 100644 --- a/src/doveadm/doveadm.c +++ b/src/doveadm/doveadm.c @@ -101,6 +101,7 @@ int main(int argc, char *argv[]) doveadm_register_cmd(&doveadm_cmd_dump); doveadm_register_cmd(&doveadm_cmd_pw); doveadm_register_cmd(&doveadm_cmd_who); + doveadm_register_cmd(&doveadm_cmd_penalty); while ((c = master_getopt(master_service)) > 0) { switch (c) { diff --git a/src/doveadm/doveadm.h b/src/doveadm/doveadm.h index 4ee48f7ccd..21c4e60c5f 100644 --- a/src/doveadm/doveadm.h +++ b/src/doveadm/doveadm.h @@ -17,6 +17,7 @@ extern struct doveadm_cmd doveadm_cmd_user; extern struct doveadm_cmd doveadm_cmd_dump; extern struct doveadm_cmd doveadm_cmd_pw; extern struct doveadm_cmd doveadm_cmd_who; +extern struct doveadm_cmd doveadm_cmd_penalty; extern bool doveadm_verbose, doveadm_debug; -- 2.47.3