]> mj.ucw.cz Git - bouncer.git/commitdiff
Parse "N more authentication failures" messages
authorMartin Mares <mj@ucw.cz>
Sat, 5 Nov 2016 12:04:13 +0000 (13:04 +0100)
committerMartin Mares <mj@ucw.cz>
Sat, 5 Nov 2016 12:04:13 +0000 (13:04 +0100)
bouncer.c

index 526b7d689cef49e47ed284d2a7741ab36e53f857..e5edf9e1150fee491e46fc4f1e9a090f13572120 100644 (file)
--- 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 <n> 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);
 }