From 78f0cf35e3f1cd312b36867ee44c0368aa9a7d34 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 5 Nov 2016 13:04:13 +0100 Subject: [PATCH] Parse "N more authentication failures" messages --- bouncer.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/bouncer.c b/bouncer.c index 526b7d6..e5edf9e 100644 --- a/bouncer.c +++ b/bouncer.c @@ -7,7 +7,6 @@ * FIXME: ipset create bouncer6 hash:ip family inet6 * FIXME: sshd_config: UseDNS no * FIXME: PAM module names should be made configurable - * FIXME: Parse "N more failures" messages */ #undef LOCAL_DEBUG @@ -299,7 +298,7 @@ static void culprit_cleanup(void) timer_add(&cleanup_timer, next_cleanup); } -static void handle_failed_login(struct addr addr) +static void handle_failed_login(struct addr addr, int cnt) { int is_new; timestamp_t now = main_get_now(); @@ -308,16 +307,16 @@ static void handle_failed_login(struct addr addr) if (is_new) { c->last_fail = now; - c->fail_count = 1; + c->fail_count = cnt; c->banned = 0; clist_add_tail(&suspect_list, &c->n); num_suspects++; - msg(L_DEBUG, "Suspect %s: new", AFMT(addr)); + msg(L_DEBUG, "Suspect %s: new, failures=%u", AFMT(addr), c->fail_count); } else if (!c->banned) { c->last_fail = now; - c->fail_count++; + c->fail_count += cnt; clist_remove(&c->n); clist_add_tail(&suspect_list, &c->n); msg(L_DEBUG, "Suspect %s: failures=%u", AFMT(addr), c->fail_count); @@ -371,6 +370,7 @@ static void process_msg(char *line) char *p = line; int c; // 2016-11-04T17:18:54.825821+01:00 sshd[6733]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=1.2.3.4 + // 2016-11-05T12:49:52.418880+01:00 sshd[16271]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=116.31.116.26 user=root // We shall start with 32 non-spaces for (int i=0; i<32; i++) @@ -405,9 +405,21 @@ static void process_msg(char *line) DBG("Parse 3: <%s>", p); // "authentication failure;" + int cnt = 1; if (!check_next(&p, "authentication failure; ")) - return; - DBG("Parse 4: <%s>", p); + { + // "PAM more authentication failures;" + if (!check_next(&p, "PAM ")) + return; + if (!(*p >= '0' && *p <= '9')) + return; + cnt = atoi(p); + while (*p >= '0' && *p <= '9') + p++; + if (!check_next(&p, " more authentication failures; ")) + return; + } + DBG("Parse 4: <%s> cnt=%d", p, cnt); // Decode attributes bool done = 0; @@ -442,7 +454,7 @@ static void process_msg(char *line) // Act on the message struct addr addr; if (addr_parse(&addr, rhost)) - handle_failed_login(addr); + handle_failed_login(addr, cnt); else msg(L_WARN, "Unable to parse address %s", rhost); } -- 2.39.2