From e4a215ca5005ed0fe0b4477d2ec1b1226dcb06c2 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 31 Dec 2013 19:00:26 +1100 Subject: [PATCH] BF: fix infinite recursion case in Action.substituteRecursiveTags --- fail2ban/server/action.py | 14 +++++++++++--- fail2ban/tests/actiontestcase.py | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/fail2ban/server/action.py b/fail2ban/server/action.py index 17f33a6f..7d107d9f 100644 --- a/fail2ban/server/action.py +++ b/fail2ban/server/action.py @@ -276,19 +276,27 @@ class Action: for tag, value in tags.iteritems(): value = str(value) m = t.search(value) + done = [] + #logSys.log(5, 'TAG: %s, value: %s' % (tag, value)) while m: - if m.group(1) == tag: + found_tag = m.group(1) + #logSys.log(5, 'found: %s' % found_tag) + if found_tag == tag or found_tag in done: # recursive definitions are bad + #logSys.log(5, 'recursion fail') return False else: - if tags.has_key(m.group(1)): - value = value[0:m.start()] + tags[m.group(1)] + value[m.end():] + if tags.has_key(found_tag): + value = value[0:m.start()] + tags[found_tag] + value[m.end():] + #logSys.log(5, 'value now: %s' % value) + done.append(found_tag) m = t.search(value, m.start()) else: # Missing tags are ok so we just continue on searching. # cInfo can contain aInfo elements like and valid shell # constructs like . m = t.search(value, m.start() + 1) + #logSys.log(5, 'TAG: %s, newvalue: %s' % (tag, value)) tags[tag] = value return tags substituteRecursiveTags = staticmethod(substituteRecursiveTags) diff --git a/fail2ban/tests/actiontestcase.py b/fail2ban/tests/actiontestcase.py index 36ecc3c9..c9364c07 100644 --- a/fail2ban/tests/actiontestcase.py +++ b/fail2ban/tests/actiontestcase.py @@ -58,6 +58,9 @@ class ExecuteAction(LogCaptureTestCase): self.assertFalse(Action.substituteRecursiveTags({'A': ''})) self.assertFalse(Action.substituteRecursiveTags({'A': '', 'B': ''})) self.assertFalse(Action.substituteRecursiveTags({'A': '', 'B': '', 'C': ''})) + # part recursion + self.assertFalse(Action.substituteRecursiveTags({'A': 'to= fromip=', 'C': '', 'B': '', 'D': ''})) + self.assertFalse(Action.substituteRecursiveTags({'failregex': 'to= fromip=', 'sweet': '', 'honeypot': '', 'ignoreregex': ''})) # missing tags are ok self.assertEqual(Action.substituteRecursiveTags({'A': ''}), {'A': ''}) self.assertEqual(Action.substituteRecursiveTags({'A': ' ','X':'fun'}), {'A': ' fun', 'X':'fun'})