mirror of https://github.com/fail2ban/fail2ban
commit
7ba8f437f1
|
@ -22,7 +22,7 @@ jobs:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11.0-alpha.1', pypy2, pypy3]
|
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11.0-beta.3', pypy2, pypy3]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||||
steps:
|
steps:
|
||||||
|
@ -61,6 +61,8 @@ jobs:
|
||||||
#sudo apt-get -y install python${F2B_PY/2/}-systemd || echo 'systemd not available'
|
#sudo apt-get -y install python${F2B_PY/2/}-systemd || echo 'systemd not available'
|
||||||
sudo apt-get -y install libsystemd-dev || echo 'systemd dependencies seems to be unavailable'
|
sudo apt-get -y install libsystemd-dev || echo 'systemd dependencies seems to be unavailable'
|
||||||
python -m pip install systemd-python || echo 'systemd not available'
|
python -m pip install systemd-python || echo 'systemd not available'
|
||||||
|
#readline if available as module:
|
||||||
|
python -c 'import readline' 2> /dev/null || python -m pip install readline || echo 'readline not available'
|
||||||
|
|
||||||
- name: Before scripts
|
- name: Before scripts
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -334,7 +334,7 @@ class Fail2banRegex(object):
|
||||||
fltFile = None
|
fltFile = None
|
||||||
fltOpt = {}
|
fltOpt = {}
|
||||||
if regextype == 'fail':
|
if regextype == 'fail':
|
||||||
if re.search(r'^(?ms)/{0,3}[\w/_\-.]+(?:\[.*\])?$', value):
|
if re.search(r'(?ms)^/{0,3}[\w/_\-.]+(?:\[.*\])?$', value):
|
||||||
try:
|
try:
|
||||||
fltName, fltOpt = extractOptions(value)
|
fltName, fltOpt = extractOptions(value)
|
||||||
if "." in fltName[~5:]:
|
if "." in fltName[~5:]:
|
||||||
|
|
|
@ -35,6 +35,7 @@ logSys = getLogger(__name__)
|
||||||
# check already grouped contains "(", but ignores char "\(" and conditional "(?(id)...)":
|
# check already grouped contains "(", but ignores char "\(" and conditional "(?(id)...)":
|
||||||
RE_GROUPED = re.compile(r'(?<!(?:\(\?))(?<!\\)\((?!\?)')
|
RE_GROUPED = re.compile(r'(?<!(?:\(\?))(?<!\\)\((?!\?)')
|
||||||
RE_GROUP = ( re.compile(r'^((?:\(\?\w+\))?\^?(?:\(\?\w+\))?)(.*?)(\$?)$'), r"\1(\2)\3" )
|
RE_GROUP = ( re.compile(r'^((?:\(\?\w+\))?\^?(?:\(\?\w+\))?)(.*?)(\$?)$'), r"\1(\2)\3" )
|
||||||
|
RE_GLOBALFLAGS = re.compile(r'((?:^|(?!<\\))\(\?[a-z]+\))')
|
||||||
|
|
||||||
RE_EXLINE_NO_BOUNDS = re.compile(r'^\{UNB\}')
|
RE_EXLINE_NO_BOUNDS = re.compile(r'^\{UNB\}')
|
||||||
RE_EXLINE_BOUND_BEG = re.compile(r'^\{\^LN-BEG\}')
|
RE_EXLINE_BOUND_BEG = re.compile(r'^\{\^LN-BEG\}')
|
||||||
|
@ -110,6 +111,11 @@ class DateTemplate(object):
|
||||||
# because it may be very slow in negative case (by long log-lines not matching pattern)
|
# because it may be very slow in negative case (by long log-lines not matching pattern)
|
||||||
|
|
||||||
regex = regex.strip()
|
regex = regex.strip()
|
||||||
|
# cut global flags like (?iu) from RE in order to pre-set it after processing:
|
||||||
|
gf = RE_GLOBALFLAGS.search(regex)
|
||||||
|
if gf:
|
||||||
|
regex = RE_GLOBALFLAGS.sub('', regex, count=1)
|
||||||
|
# check word boundaries needed:
|
||||||
boundBegin = wordBegin and not RE_NO_WRD_BOUND_BEG.search(regex)
|
boundBegin = wordBegin and not RE_NO_WRD_BOUND_BEG.search(regex)
|
||||||
boundEnd = wordEnd and not RE_NO_WRD_BOUND_END.search(regex)
|
boundEnd = wordEnd and not RE_NO_WRD_BOUND_END.search(regex)
|
||||||
# if no group add it now, should always have a group(1):
|
# if no group add it now, should always have a group(1):
|
||||||
|
@ -135,6 +141,8 @@ class DateTemplate(object):
|
||||||
self.flags |= DateTemplate.LINE_END
|
self.flags |= DateTemplate.LINE_END
|
||||||
# remove possible special pattern "**" in front and end of regex:
|
# remove possible special pattern "**" in front and end of regex:
|
||||||
regex = RE_DEL_WRD_BOUNDS[0].sub(RE_DEL_WRD_BOUNDS[1], regex)
|
regex = RE_DEL_WRD_BOUNDS[0].sub(RE_DEL_WRD_BOUNDS[1], regex)
|
||||||
|
if gf: # restore global flags:
|
||||||
|
regex = gf.group(1) + regex
|
||||||
self._regex = regex
|
self._regex = regex
|
||||||
logSys.log(4, ' constructed regex %s', regex)
|
logSys.log(4, ' constructed regex %s', regex)
|
||||||
self._cRegex = None
|
self._cRegex = None
|
||||||
|
|
|
@ -91,6 +91,13 @@ R_MAP = {
|
||||||
"PORT": "fport",
|
"PORT": "fport",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# map global flags like ((?i)xxx) or (?:(?i)xxx) to local flags (?i:xxx) if supported by RE-engine in this python version:
|
||||||
|
try:
|
||||||
|
re.search("^re(?i:val)$", "reVAL")
|
||||||
|
R_GLOB2LOCFLAGS = ( re.compile(r"(?<!\\)\((?:\?:)?(\(\?[a-z]+)\)"), r"\1:" )
|
||||||
|
except:
|
||||||
|
R_GLOB2LOCFLAGS = ()
|
||||||
|
|
||||||
def mapTag2Opt(tag):
|
def mapTag2Opt(tag):
|
||||||
try: # if should be mapped:
|
try: # if should be mapped:
|
||||||
return R_MAP[tag]
|
return R_MAP[tag]
|
||||||
|
@ -124,6 +131,9 @@ class Regex:
|
||||||
#
|
#
|
||||||
if regex.lstrip() == '':
|
if regex.lstrip() == '':
|
||||||
raise RegexException("Cannot add empty regex")
|
raise RegexException("Cannot add empty regex")
|
||||||
|
# special handling wrapping global flags to local flags:
|
||||||
|
if R_GLOB2LOCFLAGS:
|
||||||
|
regex = R_GLOB2LOCFLAGS[0].sub(R_GLOB2LOCFLAGS[1], regex)
|
||||||
try:
|
try:
|
||||||
self._regexObj = re.compile(regex, re.MULTILINE if multiline else 0)
|
self._regexObj = re.compile(regex, re.MULTILINE if multiline else 0)
|
||||||
self._regex = regex
|
self._regex = regex
|
||||||
|
|
|
@ -568,6 +568,11 @@ class Fail2banClientTest(Fail2banClientServerBase):
|
||||||
os.kill(pid, signal.SIGCONT)
|
os.kill(pid, signal.SIGCONT)
|
||||||
self.assertLogged("timed out")
|
self.assertLogged("timed out")
|
||||||
self.pruneLog()
|
self.pruneLog()
|
||||||
|
# check readline module available (expected by interactive client)
|
||||||
|
try:
|
||||||
|
import readline
|
||||||
|
except ImportError as e:
|
||||||
|
raise unittest.SkipTest('Skip test because of import error: %s' % e)
|
||||||
# interactive client chat with started server:
|
# interactive client chat with started server:
|
||||||
INTERACT += [
|
INTERACT += [
|
||||||
"echo INTERACT-ECHO",
|
"echo INTERACT-ECHO",
|
||||||
|
|
Loading…
Reference in New Issue