From 28b44d2655abdf3768b30751a581def2f5f4b5a5 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 27 Apr 2011 22:54:03 -0400 Subject: [PATCH] NF: Mockup for handling complex additional Init parameters in actions So we could have substitutions tags chosen according to values of other tags, e.g. in this case ipv (IP version) tag would be added by fail2ban internally novo# grep -e '^[^#]' /etc/fail2ban/action.d/iptables-multiport.conf [Definition] actionstart = -N fail2ban- -A fail2ban- -j RETURN -I -p -m multiport --dports -j fail2ban- actionstop = -D -p -m multiport --dports -j fail2ban- -F fail2ban- -X fail2ban- actioncheck = -n -L | grep -q fail2ban- actionban = -I fail2ban- 1 -s -j DROP actionunban = -D fail2ban- -s -j DROP [Init] name = default port = ssh protocol = tcp chain = INPUT actioncmd/ipv = 4="iptables", 6="ip6tables" --- server/action.py | 33 ++++++++++++++++++++++++++++++++- server/actions.py | 3 +++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/server/action.py b/server/action.py index f55d9a6d..9a13ae21 100644 --- a/server/action.py +++ b/server/action.py @@ -81,6 +81,14 @@ class Action: # @param value the property value def setCInfo(self, key, value): + if '/' in value: + logSys.debug("Evaluating the value to dict") + try: + value = eval("dict(%s)" % value) + except Exception, e: + logSys.error("Failed to evaluate value %r for %s as dict" + % (value, key)) + logSys.debug("Set cinfo %s = %r" % (key, value)) self.__cInfo[key] = value ## @@ -237,7 +245,30 @@ class Action: """ string = query for tag in aInfo: - string = string.replace('<' + tag + '>', str(aInfo[tag])) + # simple replacement string or a dictionary + val = aInfo[tag] + if '/' in tag: + # dict Info and we should take after '/' as the key + # which would determine which actual tag to take from + # aInfo + tag_, key_tag = tag.split('/', 1) + if not key_tag in aInfo: + logSys.error( + "Failed to find information for key tag %s among %s. " + "Tag %s was ignored" % (key_tag, aInfo.keys(), tag)) + continue + if not isinstance(val, dict): + logSys.error("Tags defined as X/Y must contain dictionary " + "entries. Got %r. Tag %s was ignored" + % (val, tag)) + continue + if not aInfo[key_tag] in val: + logSys.error("There is no %s in %r. Tag %s was ignored" + % (aInfo[key_tag], val, tag)) + continue + tag = tag_ # TODO: pylint would scream here I guess + val = aInfo[tag][aInfo[key_tag]] + string = string.replace('<' + tag + '>', str(val)) # New line string = string.replace("
", '\n') return string diff --git a/server/actions.py b/server/actions.py index 06f15ec6..fc859811 100644 --- a/server/actions.py +++ b/server/actions.py @@ -156,6 +156,9 @@ class Actions(JailThread): aInfo = dict() bTicket = BanManager.createBanTicket(ticket) aInfo["ip"] = bTicket.getIP() + # TODO: adopt IPv6 handling from Rogerio + # and assign namespace here accordingly + aInfo["ipv"] = 4 # 4 for now aInfo["failures"] = bTicket.getAttempt() aInfo["time"] = bTicket.getTime() if self.__banManager.addBanTicket(bTicket):