Browse Source

fixed read of included config-files (`.local` overwrites options of `.conf` for config-files included with before/after)

pull/2306/head
sebres 6 years ago
parent
commit
c1ccabc1f9
  1. 2
      ChangeLog
  2. 12
      fail2ban/client/configparserinc.py
  3. 51
      fail2ban/tests/clientreadertestcase.py

2
ChangeLog

@ -35,6 +35,8 @@ ver. 0.10.5-dev-1 (20??/??/??) - development edition
-----------
### Fixes
* fixed read of included config-files (`.local` overwrites options of `.conf` for config-files
included with before/after)
* `filter.d/sshd.conf`:
- captures `Disconnecting ...: Change of username or service not allowed` (gh-2239, gh-2279)
- captures `Disconnected from ... [preauth]` (`extra`/`aggressive` mode and preauth phase only, gh-2239, gh-2279)

12
fail2ban/client/configparserinc.py

@ -73,6 +73,17 @@ else: # pragma: no cover
return self._cp_interpolate_some(option, accum, rest, section, map, *args, **kwargs)
SafeConfigParser._interpolate_some = _interpolate_some
def _expandConfFilesWithLocal(filenames):
"""Expands config files with local extension.
"""
newFilenames = []
for filename in filenames:
newFilenames.append(filename)
localname = os.path.splitext(filename)[0] + '.local'
if localname not in filenames and os.path.isfile(localname):
newFilenames.append(localname)
return newFilenames
# Gets the instance of the logger.
logSys = getLogger(__name__)
logLevel = 7
@ -245,6 +256,7 @@ after = 1.conf
def _getIncludes(self, filenames, seen=[]):
if not isinstance(filenames, list):
filenames = [ filenames ]
filenames = _expandConfFilesWithLocal(filenames)
# retrieve or cache include paths:
if self._cfg_share:
# cache/share include list:

51
fail2ban/tests/clientreadertestcase.py

@ -28,7 +28,8 @@ import re
import shutil
import tempfile
import unittest
from ..client.configreader import ConfigReader, ConfigReaderUnshared, NoSectionError
from ..client.configreader import ConfigReader, ConfigReaderUnshared, \
DefinitionInitConfigReader, NoSectionError
from ..client import configparserinc
from ..client.jailreader import JailReader, extractOptions
from ..client.filterreader import FilterReader
@ -125,6 +126,54 @@ option = %s
self._remove("c.d/90.conf")
self.assertEqual(self._getoption(), 2)
def testLocalInIncludes(self):
self._write("c.conf", value=None, content="""
[INCLUDES]
before = ib.conf
after = ia.conf
[Definition]
test = %(default/test)s
""")
self._write("ib.conf", value=None, content="""
[DEFAULT]
test = A
[Definition]
option = 1
""")
self._write("ib.local", value=None, content="""
[DEFAULT]
test = B
[Definition]
option = 2
""")
self._write("ia.conf", value=None, content="""
[DEFAULT]
test = C
[Definition]
oafter = 3
""")
self._write("ia.local", value=None, content="""
[DEFAULT]
test = D
[Definition]
oafter = 4
""")
class TestDefConfReader(DefinitionInitConfigReader):
_configOpts = {
"option": ["int", None],
"oafter": ["int", None],
"test": ["string", None],
}
self.c = TestDefConfReader('c', 'option', {})
self.c.setBaseDir(self.d)
self.assertTrue(self.c.read())
self.c.getOptions({}, all=True)
o = self.c.getCombined()
# test local wins (overwrite all options):
self.assertEqual(o.get('option'), 2)
self.assertEqual(o.get('oafter'), 4)
self.assertEqual(o.get('test'), 'D')
def testInterpolations(self):
self.assertFalse(self.c.read('i')) # nothing is there yet
self._write("i.conf", value=None, content="""

Loading…
Cancel
Save