mirror of https://github.com/fail2ban/fail2ban
RF+BF+ENH: Rewrite extract options, and now allow "=" char in options
parent
970291867b
commit
33a7763cfc
|
@ -36,6 +36,8 @@ logSys = logging.getLogger(__name__)
|
||||||
class JailReader(ConfigReader):
|
class JailReader(ConfigReader):
|
||||||
|
|
||||||
optionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
|
optionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
|
||||||
|
optionExtractRE = re.compile(
|
||||||
|
r'([\w\-_\.]+)=(?:"([^"]*)"|\'([^\']*)\'|([^,]*))(?:,|$)')
|
||||||
|
|
||||||
def __init__(self, name, force_enable=False, **kwargs):
|
def __init__(self, name, force_enable=False, **kwargs):
|
||||||
ConfigReader.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
|
@ -155,46 +157,13 @@ class JailReader(ConfigReader):
|
||||||
|
|
||||||
#@staticmethod
|
#@staticmethod
|
||||||
def extractOptions(option):
|
def extractOptions(option):
|
||||||
m = JailReader.optionCRE.match(option)
|
option_name, optstr = JailReader.optionCRE.match(option).groups()
|
||||||
d = dict()
|
option_opts = dict()
|
||||||
mgroups = m.groups()
|
if optstr:
|
||||||
if len(mgroups) == 2:
|
for optmatch in JailReader.optionExtractRE.finditer(optstr):
|
||||||
option_name, option_opts = mgroups
|
opt = optmatch.group(1)
|
||||||
elif len(mgroups) == 1:
|
value = [
|
||||||
option_name, option_opts = mgroups[0], None
|
val for val in optmatch.group(2,3,4) if val is not None][0]
|
||||||
else:
|
option_opts[opt.strip()] = value.strip()
|
||||||
raise ValueError("While reading option %s we should have got up to "
|
return option_name, option_opts
|
||||||
"2 groups. Got: %r" % (option, mgroups))
|
|
||||||
if not option_opts is None:
|
|
||||||
# Huge bad hack :( This method really sucks. TODO Reimplement it.
|
|
||||||
options = ""
|
|
||||||
escapeChar = None
|
|
||||||
allowComma = False
|
|
||||||
for c in option_opts:
|
|
||||||
if c in ('"', "'") and not allowComma:
|
|
||||||
# Start
|
|
||||||
escapeChar = c
|
|
||||||
allowComma = True
|
|
||||||
elif c == escapeChar:
|
|
||||||
# End
|
|
||||||
escapeChar = None
|
|
||||||
allowComma = False
|
|
||||||
else:
|
|
||||||
if c == ',' and allowComma:
|
|
||||||
options += "<COMMA>"
|
|
||||||
else:
|
|
||||||
options += c
|
|
||||||
|
|
||||||
# Split using ,
|
|
||||||
optionsSplit = options.split(',')
|
|
||||||
# Replace the tag <COMMA> with ,
|
|
||||||
optionsSplit = [n.replace("<COMMA>", ',') for n in optionsSplit]
|
|
||||||
|
|
||||||
for param in optionsSplit:
|
|
||||||
p = param.split('=')
|
|
||||||
try:
|
|
||||||
d[p[0].strip()] = p[1].strip()
|
|
||||||
except IndexError:
|
|
||||||
logSys.error("Invalid argument %s in '%s'" % (p, option_opts))
|
|
||||||
return [option_name, d]
|
|
||||||
extractOptions = staticmethod(extractOptions)
|
extractOptions = staticmethod(extractOptions)
|
||||||
|
|
|
@ -147,19 +147,19 @@ class JailReaderTest(unittest.TestCase):
|
||||||
def testSplitOption(self):
|
def testSplitOption(self):
|
||||||
# Simple example
|
# Simple example
|
||||||
option = "mail-whois[name=SSH]"
|
option = "mail-whois[name=SSH]"
|
||||||
expected = ['mail-whois', {'name': 'SSH'}]
|
expected = ('mail-whois', {'name': 'SSH'})
|
||||||
result = JailReader.extractOptions(option)
|
result = JailReader.extractOptions(option)
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
# Empty option
|
# Empty option
|
||||||
option = "abc[]"
|
option = "abc[]"
|
||||||
expected = ['abc', {}]
|
expected = ('abc', {})
|
||||||
result = JailReader.extractOptions(option)
|
result = JailReader.extractOptions(option)
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
# More complex examples
|
# More complex examples
|
||||||
option = 'option[opt01=abc,opt02="123",opt03="with=okay?",opt04="andwith,okay...",opt05="how about spaces",opt06="single\'in\'double",opt07=\'double"in"single\', opt08= leave some space, opt09=one for luck, opt10=, opt11=]'
|
option = 'option[opt01=abc,opt02="123",opt03="with=okay?",opt04="andwith,okay...",opt05="how about spaces",opt06="single\'in\'double",opt07=\'double"in"single\', opt08= leave some space, opt09=one for luck, opt10=, opt11=]'
|
||||||
expected = ['option', {
|
expected = ('option', {
|
||||||
'opt01': "abc",
|
'opt01': "abc",
|
||||||
'opt02': "123",
|
'opt02': "123",
|
||||||
'opt03': "with=okay?",
|
'opt03': "with=okay?",
|
||||||
|
@ -171,7 +171,7 @@ class JailReaderTest(unittest.TestCase):
|
||||||
'opt09': "one for luck",
|
'opt09': "one for luck",
|
||||||
'opt10': "",
|
'opt10': "",
|
||||||
'opt11': "",
|
'opt11': "",
|
||||||
}]
|
})
|
||||||
result = JailReader.extractOptions(option)
|
result = JailReader.extractOptions(option)
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue