From be60518218cc859af4e7ee57e4d22beab27205d5 Mon Sep 17 00:00:00 2001
From: Daniel Black <grooverdan@users.sourceforge.net>
Date: Tue, 12 Nov 2013 18:57:01 +1100
Subject: [PATCH] BF/ENH: DoS resistant roundcube-auth with test cases and more
 variation in IMAP error given

---
 config/filter.d/roundcube-auth.conf | 19 ++++++++++++++++---
 testcases/files/logs/roundcube-auth | 18 ++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/config/filter.d/roundcube-auth.conf b/config/filter.d/roundcube-auth.conf
index 279c5edd..b093f69c 100644
--- a/config/filter.d/roundcube-auth.conf
+++ b/config/filter.d/roundcube-auth.conf
@@ -9,8 +9,21 @@ before = common.conf
 
 [Definition]
 
-failregex = ^\s*(\[(\s[+-][0-9]{4})?\])?(%(__hostname)s roundcube: IMAP Error)?: (FAILED login|Login failed) for .*? from <HOST>(\. AUTHENTICATE .*)?\s*$
+failregex = ^\s*(\[(\s[+-][0-9]{4})?\])?(%(__hostname)s roundcube: IMAP Error)?: (FAILED login|Login failed) for .*? from <HOST>(\. .* in .*?/rcube_imap\.php on line \d+ \(\S+ \S+\))?$
 
 ignoreregex = 
-
-# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge
+# DEV Notes:
+#
+# Source: https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_imap.php#L180
+#
+# Part after <HOST> comes straight from IMAP server up until the " in ....."
+# Earlier versions didn't log the IMAP response hence optional.
+#
+# DoS resistance:
+#
+# Assume that the user can inject "from <HOST>" into the imap response
+# somehow. Write test cases around this to ensure that the combination of 
+# arbitary user input and IMAP response doesn't inject the wrong IP for 
+# fail2ban
+#
+# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge & Daniel Black
diff --git a/testcases/files/logs/roundcube-auth b/testcases/files/logs/roundcube-auth
index 7c16efbd..43a42192 100644
--- a/testcases/files/logs/roundcube-auth
+++ b/testcases/files/logs/roundcube-auth
@@ -4,3 +4,21 @@
 May 26 07:12:40 hamster roundcube: IMAP Error: Login failed for sales@example.com from 10.1.1.47
 # failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" }
 Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login)
+
+# Made up to attempts to inject a DoS on the server. Assume the user can manipulate the IMAP error response
+#
+# user = admin from 127.0.0.1
+# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" }
+Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login)
+#
+# IMAP server logs user=${username}
+# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" }
+Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. user=admin from 127.0.0.1 in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login)
+#
+# Old roundcube version - no IMAP response
+# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" }
+Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 from 1.2.3.4
+#
+# user = admin from 127.0.0.1 in 
+# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" }
+Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 in from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. user=admin from 127.0.0.1 in in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login)