blob: ee872ec41739207824220ff01d4c393114f54bd9 [file] [log] [blame]
Andrew Geissler1fe918a2020-05-15 14:16:47 -05001From abaa20435bac7decffa69e6f965aac9ce29aff6a Mon Sep 17 00:00:00 2001
2From: Armin Kuster <akuster808@gmail.com>
3Date: Wed, 12 Feb 2020 17:19:15 +0000
4Subject: [PATCH] python3-fail2ban: 2-3 conversion
5
6Upstream-Status: OE specific.
7
8fail2ban handles py3 via a 2-3 conversion utility.
9
10Signed-off-by: Armin Kuster <akuster808@gmail.com>
11---
12 fail2ban/client/actionreader.py | 4 +-
13 fail2ban/client/configparserinc.py | 10 +-
14 fail2ban/client/configreader.py | 4 +-
15 fail2ban/client/csocket.py | 4 +-
16 fail2ban/client/fail2banclient.py | 4 +-
17 fail2ban/client/fail2banregex.py | 20 +-
18 fail2ban/client/filterreader.py | 2 +-
19 fail2ban/client/jailreader.py | 4 +-
20 fail2ban/helpers.py | 15 +-
21 fail2ban/server/action.py | 19 +-
22 fail2ban/server/actions.py | 24 +-
23 fail2ban/server/asyncserver.py | 4 +-
24 fail2ban/server/banmanager.py | 18 +-
25 fail2ban/server/database.py | 6 +-
26 fail2ban/server/failmanager.py | 8 +-
27 fail2ban/server/failregex.py | 9 +-
28 fail2ban/server/filter.py | 12 +-
29 fail2ban/server/filterpoll.py | 2 +-
30 fail2ban/server/filterpyinotify.py | 6 +-
31 fail2ban/server/ipdns.py | 16 +-
32 fail2ban/server/jail.py | 14 +-
33 fail2ban/server/mytime.py | 2 +-
34 fail2ban/server/server.py | 18 +-
35 fail2ban/server/strptime.py | 6 +-
36 fail2ban/server/ticket.py | 14 +-
37 fail2ban/server/transmitter.py | 2 +-
38 fail2ban/server/utils.py | 6 +-
39 fail2ban/tests/action_d/test_badips.py | 2 +-
40 fail2ban/tests/actiontestcase.py | 4 +-
41 fail2ban/tests/clientreadertestcase.py | 4 +-
42 fail2ban/tests/databasetestcase.py | 16 +-
43 fail2ban/tests/datedetectortestcase.py | 6 +-
44 fail2ban/tests/fail2banclienttestcase.py | 8 +-
45 fail2ban/tests/failmanagertestcase.py | 10 +-
46 .../tests/files/config/apache-auth/digest.py | 20 +-
47 fail2ban/tests/filtertestcase.py | 92 ++---
48 fail2ban/tests/misctestcase.py | 22 +-
49 fail2ban/tests/observertestcase.py | 34 +-
50 fail2ban/tests/samplestestcase.py | 8 +-
51 fail2ban/tests/servertestcase.py | 28 +-
52 fail2ban/tests/sockettestcase.py | 2 +-
53 fail2ban/tests/utils.py | 22 +-
54 setup.py | 326 ------------------
55 43 files changed, 264 insertions(+), 593 deletions(-)
56 delete mode 100755 setup.py
57
58diff --git a/fail2ban/client/actionreader.py b/fail2ban/client/actionreader.py
59index 80617a50..ecf323c5 100644
60--- a/fail2ban/client/actionreader.py
61+++ b/fail2ban/client/actionreader.py
62@@ -90,11 +90,11 @@ class ActionReader(DefinitionInitConfigReader):
63 stream = list()
64 stream.append(head + ["addaction", self._name])
65 multi = []
66- for opt, optval in opts.iteritems():
67+ for opt, optval in opts.items():
68 if opt in self._configOpts and not opt.startswith('known/'):
69 multi.append([opt, optval])
70 if self._initOpts:
71- for opt, optval in self._initOpts.iteritems():
72+ for opt, optval in self._initOpts.items():
73 if opt not in self._configOpts and not opt.startswith('known/'):
74 multi.append([opt, optval])
75 if len(multi) > 1:
76diff --git a/fail2ban/client/configparserinc.py b/fail2ban/client/configparserinc.py
77index e0f39579..45c77437 100644
78--- a/fail2ban/client/configparserinc.py
79+++ b/fail2ban/client/configparserinc.py
80@@ -62,7 +62,7 @@ if sys.version_info >= (3,2):
81 parser, option, accum, rest, section, map, *args, **kwargs)
82
83 else: # pragma: no cover
84- from ConfigParser import SafeConfigParser, \
85+ from configparser import SafeConfigParser, \
86 InterpolationMissingOptionError, NoOptionError, NoSectionError
87
88 # Interpolate missing known/option as option from default section
89@@ -327,7 +327,7 @@ after = 1.conf
90 # mix it with defaults:
91 return set(opts.keys()) | set(self._defaults)
92 # only own option names:
93- return opts.keys()
94+ return list(opts.keys())
95
96 def read(self, filenames, get_includes=True):
97 if not isinstance(filenames, list):
98@@ -356,7 +356,7 @@ after = 1.conf
99 ret += i
100 # merge defaults and all sections to self:
101 alld.update(cfg.get_defaults())
102- for n, s in cfg.get_sections().iteritems():
103+ for n, s in cfg.get_sections().items():
104 # conditional sections
105 cond = SafeConfigParserWithIncludes.CONDITIONAL_RE.match(n)
106 if cond:
107@@ -366,7 +366,7 @@ after = 1.conf
108 del(s['__name__'])
109 except KeyError:
110 pass
111- for k in s.keys():
112+ for k in list(s.keys()):
113 v = s.pop(k)
114 s[k + cond] = v
115 s2 = alls.get(n)
116@@ -399,7 +399,7 @@ after = 1.conf
117 sec.update(options)
118 return
119 sk = {}
120- for k, v in options.iteritems():
121+ for k, v in options.items():
122 if not k.startswith(pref) and k != '__name__':
123 sk[pref+k] = v
124 sec.update(sk)
125diff --git a/fail2ban/client/configreader.py b/fail2ban/client/configreader.py
126index 20709b72..b5167409 100644
127--- a/fail2ban/client/configreader.py
128+++ b/fail2ban/client/configreader.py
129@@ -26,7 +26,7 @@ __license__ = "GPL"
130
131 import glob
132 import os
133-from ConfigParser import NoOptionError, NoSectionError
134+from configparser import NoOptionError, NoSectionError
135
136 from .configparserinc import sys, SafeConfigParserWithIncludes, logLevel
137 from ..helpers import getLogger, _as_bool, _merge_dicts, substituteRecursiveTags
138@@ -197,7 +197,7 @@ class ConfigReaderUnshared(SafeConfigParserWithIncludes):
139 config_files += sorted(glob.glob('%s/*.local' % config_dir))
140
141 # choose only existing ones
142- config_files = filter(os.path.exists, config_files)
143+ config_files = list(filter(os.path.exists, config_files))
144
145 if len(config_files):
146 # at least one config exists and accessible
147diff --git a/fail2ban/client/csocket.py b/fail2ban/client/csocket.py
148index ab3e294b..9417cde9 100644
149--- a/fail2ban/client/csocket.py
150+++ b/fail2ban/client/csocket.py
151@@ -47,7 +47,7 @@ class CSocket:
152
153 def send(self, msg, nonblocking=False, timeout=None):
154 # Convert every list member to string
155- obj = dumps(map(CSocket.convert, msg), HIGHEST_PROTOCOL)
156+ obj = dumps(list(map(CSocket.convert, msg)), HIGHEST_PROTOCOL)
157 self.__csock.send(obj + CSPROTO.END)
158 return self.receive(self.__csock, nonblocking, timeout)
159
160@@ -71,7 +71,7 @@ class CSocket:
161 @staticmethod
162 def convert(m):
163 """Convert every "unexpected" member of message to string"""
164- if isinstance(m, (basestring, bool, int, float, list, dict, set)):
165+ if isinstance(m, (str, bool, int, float, list, dict, set)):
166 return m
167 else: # pragma: no cover
168 return str(m)
169diff --git a/fail2ban/client/fail2banclient.py b/fail2ban/client/fail2banclient.py
170index 7c90ca40..7eb11684 100755
171--- a/fail2ban/client/fail2banclient.py
172+++ b/fail2ban/client/fail2banclient.py
173@@ -45,7 +45,7 @@ def _thread_name():
174 return threading.current_thread().__class__.__name__
175
176 def input_command(): # pragma: no cover
177- return raw_input(PROMPT)
178+ return input(PROMPT)
179
180 ##
181 #
182@@ -444,7 +444,7 @@ class Fail2banClient(Fail2banCmdLine, Thread):
183 return False
184 finally:
185 self._alive = False
186- for s, sh in _prev_signals.iteritems():
187+ for s, sh in _prev_signals.items():
188 signal.signal(s, sh)
189
190
191diff --git a/fail2ban/client/fail2banregex.py b/fail2ban/client/fail2banregex.py
192index 513b765d..4a71b3c0 100644
193--- a/fail2ban/client/fail2banregex.py
194+++ b/fail2ban/client/fail2banregex.py
195@@ -41,10 +41,10 @@ import shlex
196 import sys
197 import time
198 import time
199-import urllib
200+import urllib.request, urllib.parse, urllib.error
201 from optparse import OptionParser, Option
202
203-from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError
204+from configparser import NoOptionError, NoSectionError, MissingSectionHeaderError
205
206 try: # pragma: no cover
207 from ..server.filtersystemd import FilterSystemd
208@@ -68,7 +68,7 @@ def debuggexURL(sample, regex, multiline=False, useDns="yes"):
209 'flavor': 'python'
210 }
211 if multiline: args['flags'] = 'm'
212- return 'https://www.debuggex.com/?' + urllib.urlencode(args)
213+ return 'https://www.debuggex.com/?' + urllib.parse.urlencode(args)
214
215 def output(args): # pragma: no cover (overriden in test-cases)
216 print(args)
217@@ -244,7 +244,7 @@ class Fail2banRegex(object):
218
219 def __init__(self, opts):
220 # set local protected members from given options:
221- self.__dict__.update(dict(('_'+o,v) for o,v in opts.__dict__.iteritems()))
222+ self.__dict__.update(dict(('_'+o,v) for o,v in opts.__dict__.items()))
223 self._opts = opts
224 self._maxlines_set = False # so we allow to override maxlines in cmdline
225 self._datepattern_set = False
226@@ -304,7 +304,7 @@ class Fail2banRegex(object):
227 realopts = {}
228 combopts = reader.getCombined()
229 # output all options that are specified in filter-argument as well as some special (mostly interested):
230- for k in ['logtype', 'datepattern'] + fltOpt.keys():
231+ for k in ['logtype', 'datepattern'] + list(fltOpt.keys()):
232 # combined options win, but they contain only a sub-set in filter expected keys,
233 # so get the rest from definition section:
234 try:
235@@ -424,7 +424,7 @@ class Fail2banRegex(object):
236 self.output( "Use %11s line : %s" % (regex, shortstr(value)) )
237 regex_values = {regextype: [RegexStat(value)]}
238
239- for regextype, regex_values in regex_values.iteritems():
240+ for regextype, regex_values in regex_values.items():
241 regex = regextype + 'regex'
242 setattr(self, "_" + regex, regex_values)
243 for regex in regex_values:
244@@ -523,10 +523,10 @@ class Fail2banRegex(object):
245 output(ret[1])
246 elif self._opts.out == 'msg':
247 for ret in ret:
248- output('\n'.join(map(lambda v:''.join(v for v in v), ret[3].get('matches'))))
249+ output('\n'.join([''.join(v for v in v) for v in ret[3].get('matches')]))
250 elif self._opts.out == 'row':
251 for ret in ret:
252- output('[%r,\t%r,\t%r],' % (ret[1],ret[2],dict((k,v) for k, v in ret[3].iteritems() if k != 'matches')))
253+ output('[%r,\t%r,\t%r],' % (ret[1],ret[2],dict((k,v) for k, v in ret[3].items() if k != 'matches')))
254 else:
255 for ret in ret:
256 output(ret[3].get(self._opts.out))
257@@ -565,9 +565,9 @@ class Fail2banRegex(object):
258 ans = [[]]
259 for arg in [l, regexlist]:
260 ans = [ x + [y] for x in ans for y in arg ]
261- b = map(lambda a: a[0] + ' | ' + a[1].getFailRegex() + ' | ' +
262+ b = [a[0] + ' | ' + a[1].getFailRegex() + ' | ' +
263 debuggexURL(self.encode_line(a[0]), a[1].getFailRegex(),
264- multiline, self._opts.usedns), ans)
265+ multiline, self._opts.usedns) for a in ans]
266 pprint_list([x.rstrip() for x in b], header)
267 else:
268 output( "%s too many to print. Use --print-all-%s " \
269diff --git a/fail2ban/client/filterreader.py b/fail2ban/client/filterreader.py
270index 413f125e..4f0cc4cf 100644
271--- a/fail2ban/client/filterreader.py
272+++ b/fail2ban/client/filterreader.py
273@@ -71,7 +71,7 @@ class FilterReader(DefinitionInitConfigReader):
274 @staticmethod
275 def _fillStream(stream, opts, jailName):
276 prio0idx = 0
277- for opt, value in opts.iteritems():
278+ for opt, value in opts.items():
279 if opt in ("failregex", "ignoreregex"):
280 if value is None: continue
281 multi = []
282diff --git a/fail2ban/client/jailreader.py b/fail2ban/client/jailreader.py
283index 50c1d047..969d0bc0 100644
284--- a/fail2ban/client/jailreader.py
285+++ b/fail2ban/client/jailreader.py
286@@ -117,7 +117,7 @@ class JailReader(ConfigReader):
287 }
288 _configOpts.update(FilterReader._configOpts)
289
290- _ignoreOpts = set(['action', 'filter', 'enabled'] + FilterReader._configOpts.keys())
291+ _ignoreOpts = set(['action', 'filter', 'enabled'] + list(FilterReader._configOpts.keys()))
292
293 def getOptions(self):
294
295@@ -236,7 +236,7 @@ class JailReader(ConfigReader):
296 stream.extend(self.__filter.convert())
297 # and using options from jail:
298 FilterReader._fillStream(stream, self.__opts, self.__name)
299- for opt, value in self.__opts.iteritems():
300+ for opt, value in self.__opts.items():
301 if opt == "logpath":
302 if self.__opts.get('backend', '').startswith("systemd"): continue
303 found_files = 0
304diff --git a/fail2ban/helpers.py b/fail2ban/helpers.py
305index 6f2bcdd7..7e563696 100644
306--- a/fail2ban/helpers.py
307+++ b/fail2ban/helpers.py
308@@ -31,6 +31,7 @@ import traceback
309 from threading import Lock
310
311 from .server.mytime import MyTime
312+import importlib
313
314 try:
315 import ctypes
316@@ -63,7 +64,7 @@ if sys.version_info < (3,): # pragma: 3.x no cover
317 from imp import load_dynamic as __ldm
318 _sys = __ldm('_sys', 'sys')
319 except ImportError: # pragma: no cover - only if load_dynamic fails
320- reload(sys)
321+ importlib.reload(sys)
322 _sys = sys
323 if hasattr(_sys, "setdefaultencoding"):
324 _sys.setdefaultencoding(encoding)
325@@ -101,7 +102,7 @@ if sys.version_info >= (3,): # pragma: 2.x no cover
326 else: # pragma: 3.x no cover
327 def uni_decode(x, enc=PREFER_ENC, errors='strict'):
328 try:
329- if isinstance(x, unicode):
330+ if isinstance(x, str):
331 return x.encode(enc, errors)
332 return x
333 except (UnicodeDecodeError, UnicodeEncodeError): # pragma: no cover - unsure if reachable
334@@ -110,7 +111,7 @@ else: # pragma: 3.x no cover
335 return x.encode(enc, 'replace')
336 if sys.getdefaultencoding().upper() != 'UTF-8': # pragma: no cover - utf-8 is default encoding now
337 def uni_string(x):
338- if not isinstance(x, unicode):
339+ if not isinstance(x, str):
340 return str(x)
341 return x.encode(PREFER_ENC, 'replace')
342 else:
343@@ -118,7 +119,7 @@ else: # pragma: 3.x no cover
344
345
346 def _as_bool(val):
347- return bool(val) if not isinstance(val, basestring) \
348+ return bool(val) if not isinstance(val, str) \
349 else val.lower() in ('1', 'on', 'true', 'yes')
350
351
352@@ -326,7 +327,7 @@ def splitwords(s):
353 """
354 if not s:
355 return []
356- return filter(bool, map(lambda v: v.strip(), re.split('[ ,\n]+', s)))
357+ return list(filter(bool, [v.strip() for v in re.split('[ ,\n]+', s)]))
358
359 if sys.version_info >= (3,5):
360 eval(compile(r'''if 1:
361@@ -436,7 +437,7 @@ def substituteRecursiveTags(inptags, conditional='',
362 while True:
363 repFlag = False
364 # substitute each value:
365- for tag in tags.iterkeys():
366+ for tag in tags.keys():
367 # ignore escaped or already done (or in ignore list):
368 if tag in ignore or tag in done: continue
369 # ignore replacing callable items from calling map - should be converted on demand only (by get):
370@@ -476,7 +477,7 @@ def substituteRecursiveTags(inptags, conditional='',
371 m = tre_search(value, m.end())
372 continue
373 # if calling map - be sure we've string:
374- if not isinstance(repl, basestring): repl = uni_string(repl)
375+ if not isinstance(repl, str): repl = uni_string(repl)
376 value = value.replace('<%s>' % rtag, repl)
377 #logSys.log(5, 'value now: %s' % value)
378 # increment reference count:
379diff --git a/fail2ban/server/action.py b/fail2ban/server/action.py
380index 5c817fc0..81d50689 100644
381--- a/fail2ban/server/action.py
382+++ b/fail2ban/server/action.py
383@@ -111,9 +111,9 @@ class CallingMap(MutableMapping, object):
384 def _asdict(self, calculated=False, checker=None):
385 d = dict(self.data, **self.storage)
386 if not calculated:
387- return dict((n,v) for n,v in d.iteritems() \
388+ return dict((n,v) for n,v in d.items() \
389 if not callable(v) or n in self.CM_REPR_ITEMS)
390- for n,v in d.items():
391+ for n,v in list(d.items()):
392 if callable(v):
393 try:
394 # calculate:
395@@ -179,7 +179,7 @@ class CallingMap(MutableMapping, object):
396 return self.__class__(_merge_copy_dicts(self.data, self.storage))
397
398
399-class ActionBase(object):
400+class ActionBase(object, metaclass=ABCMeta):
401 """An abstract base class for actions in Fail2Ban.
402
403 Action Base is a base definition of what methods need to be in
404@@ -209,7 +209,6 @@ class ActionBase(object):
405 Any additional arguments specified in `jail.conf` or passed
406 via `fail2ban-client` will be passed as keyword arguments.
407 """
408- __metaclass__ = ABCMeta
409
410 @classmethod
411 def __subclasshook__(cls, C):
412@@ -420,7 +419,7 @@ class CommandAction(ActionBase):
413 if not callable(family): # pragma: no cover
414 return self.__substCache.get(key, {}).get(family)
415 # family as expression - use it to filter values:
416- return [v for f, v in self.__substCache.get(key, {}).iteritems() if family(f)]
417+ return [v for f, v in self.__substCache.get(key, {}).items() if family(f)]
418 cmd = args[0]
419 if cmd: # set:
420 try:
421@@ -432,7 +431,7 @@ class CommandAction(ActionBase):
422 try:
423 famd = self.__substCache[key]
424 cmd = famd.pop(family)
425- for family, v in famd.items():
426+ for family, v in list(famd.items()):
427 if v == cmd:
428 del famd[family]
429 except KeyError: # pragma: no cover
430@@ -448,7 +447,7 @@ class CommandAction(ActionBase):
431 res = True
432 err = 'Script error'
433 if not family: # all started:
434- family = [famoper for (famoper,v) in self.__started.iteritems() if v]
435+ family = [famoper for (famoper,v) in self.__started.items() if v]
436 for famoper in family:
437 try:
438 cmd = self._getOperation(tag, famoper)
439@@ -617,7 +616,7 @@ class CommandAction(ActionBase):
440 and executes the resulting command.
441 """
442 # collect started families, may be started on demand (conditional):
443- family = [f for (f,v) in self.__started.iteritems() if v & 3 == 3]; # started and contains items
444+ family = [f for (f,v) in self.__started.items() if v & 3 == 3]; # started and contains items
445 # if nothing contains items:
446 if not family: return True
447 # flush:
448@@ -642,7 +641,7 @@ class CommandAction(ActionBase):
449 """
450 # collect started families, if started on demand (conditional):
451 if family is None:
452- family = [f for (f,v) in self.__started.iteritems() if v]
453+ family = [f for (f,v) in self.__started.items() if v]
454 # if no started (on demand) actions:
455 if not family: return True
456 self.__started = {}
457@@ -676,7 +675,7 @@ class CommandAction(ActionBase):
458 ret = True
459 # for each started family:
460 if self.actioncheck:
461- for (family, started) in self.__started.items():
462+ for (family, started) in list(self.__started.items()):
463 if started and not self._invariantCheck(family, beforeRepair):
464 # reset started flag and command of executed operation:
465 self.__started[family] = 0
466diff --git a/fail2ban/server/actions.py b/fail2ban/server/actions.py
467index 24fea838..94b9c3ed 100644
468--- a/fail2ban/server/actions.py
469+++ b/fail2ban/server/actions.py
470@@ -156,11 +156,11 @@ class Actions(JailThread, Mapping):
471 else:
472 if hasattr(self, '_reload_actions'):
473 # reload actions after all parameters set via stream:
474- for name, initOpts in self._reload_actions.iteritems():
475+ for name, initOpts in self._reload_actions.items():
476 if name in self._actions:
477 self._actions[name].reload(**(initOpts if initOpts else {}))
478 # remove obsolete actions (untouched by reload process):
479- delacts = OrderedDict((name, action) for name, action in self._actions.iteritems()
480+ delacts = OrderedDict((name, action) for name, action in self._actions.items()
481 if name not in self._reload_actions)
482 if len(delacts):
483 # unban all tickets using removed actions only:
484@@ -289,7 +289,7 @@ class Actions(JailThread, Mapping):
485 """
486 if actions is None:
487 actions = self._actions
488- revactions = actions.items()
489+ revactions = list(actions.items())
490 revactions.reverse()
491 for name, action in revactions:
492 try:
493@@ -314,7 +314,7 @@ class Actions(JailThread, Mapping):
494 True when the thread exits nicely.
495 """
496 cnt = 0
497- for name, action in self._actions.iteritems():
498+ for name, action in self._actions.items():
499 try:
500 action.start()
501 except Exception as e:
502@@ -474,7 +474,7 @@ class Actions(JailThread, Mapping):
503 Observers.Main.add('banFound', bTicket, self._jail, btime)
504 logSys.notice("[%s] %sBan %s", self._jail.name, ('' if not bTicket.restored else 'Restore '), ip)
505 # do actions :
506- for name, action in self._actions.iteritems():
507+ for name, action in self._actions.items():
508 try:
509 if ticket.restored and getattr(action, 'norestored', False):
510 continue
511@@ -511,13 +511,13 @@ class Actions(JailThread, Mapping):
512 if bTicket.banEpoch == self.banEpoch and diftm > 3:
513 # avoid too often checks:
514 if not rebanacts and MyTime.time() > self.__lastConsistencyCheckTM + 3:
515- for action in self._actions.itervalues():
516+ for action in self._actions.values():
517 action.consistencyCheck()
518 self.__lastConsistencyCheckTM = MyTime.time()
519 # check epoch in order to reban it:
520 if bTicket.banEpoch < self.banEpoch:
521 if not rebanacts: rebanacts = dict(
522- (name, action) for name, action in self._actions.iteritems()
523+ (name, action) for name, action in self._actions.items()
524 if action.banEpoch > bTicket.banEpoch)
525 cnt += self.__reBan(bTicket, actions=rebanacts)
526 else: # pragma: no cover - unexpected: ticket is not banned for some reasons - reban using all actions:
527@@ -542,8 +542,8 @@ class Actions(JailThread, Mapping):
528 ip = ticket.getIP()
529 aInfo = self.__getActionInfo(ticket)
530 if log:
531- logSys.notice("[%s] Reban %s%s", self._jail.name, aInfo["ip"], (', action %r' % actions.keys()[0] if len(actions) == 1 else ''))
532- for name, action in actions.iteritems():
533+ logSys.notice("[%s] Reban %s%s", self._jail.name, aInfo["ip"], (', action %r' % list(actions.keys())[0] if len(actions) == 1 else ''))
534+ for name, action in actions.items():
535 try:
536 logSys.debug("[%s] action %r: reban %s", self._jail.name, name, ip)
537 if not aInfo.immutable: aInfo.reset()
538@@ -567,7 +567,7 @@ class Actions(JailThread, Mapping):
539 if not self.__banManager._inBanList(ticket): return
540 # do actions :
541 aInfo = None
542- for name, action in self._actions.iteritems():
543+ for name, action in self._actions.items():
544 try:
545 if ticket.restored and getattr(action, 'norestored', False):
546 continue
547@@ -616,7 +616,7 @@ class Actions(JailThread, Mapping):
548 cnt = 0
549 # first we'll execute flush for actions supporting this operation:
550 unbactions = {}
551- for name, action in (actions if actions is not None else self._actions).iteritems():
552+ for name, action in (actions if actions is not None else self._actions).items():
553 try:
554 if hasattr(action, 'flush') and (not isinstance(action, CommandAction) or action.actionflush):
555 logSys.notice("[%s] Flush ticket(s) with %s", self._jail.name, name)
556@@ -671,7 +671,7 @@ class Actions(JailThread, Mapping):
557 aInfo = self.__getActionInfo(ticket)
558 if log:
559 logSys.notice("[%s] Unban %s", self._jail.name, aInfo["ip"])
560- for name, action in unbactions.iteritems():
561+ for name, action in unbactions.items():
562 try:
563 logSys.debug("[%s] action %r: unban %s", self._jail.name, name, ip)
564 if not aInfo.immutable: aInfo.reset()
565diff --git a/fail2ban/server/asyncserver.py b/fail2ban/server/asyncserver.py
566index e3400737..f5f9740b 100644
567--- a/fail2ban/server/asyncserver.py
568+++ b/fail2ban/server/asyncserver.py
569@@ -178,7 +178,7 @@ def loop(active, timeout=None, use_poll=False, err_count=None):
570 elif err_count['listen'] > 100: # pragma: no cover - normally unreachable
571 if (
572 e.args[0] == errno.EMFILE # [Errno 24] Too many open files
573- or sum(err_count.itervalues()) > 1000
574+ or sum(err_count.values()) > 1000
575 ):
576 logSys.critical("Too many errors - critical count reached %r", err_count)
577 break
578@@ -220,7 +220,7 @@ class AsyncServer(asyncore.dispatcher):
579 elif self.__errCount['accept'] > 100:
580 if (
581 (isinstance(e, socket.error) and e.args[0] == errno.EMFILE) # [Errno 24] Too many open files
582- or sum(self.__errCount.itervalues()) > 1000
583+ or sum(self.__errCount.values()) > 1000
584 ):
585 logSys.critical("Too many errors - critical count reached %r", self.__errCount)
586 self.stop()
587diff --git a/fail2ban/server/banmanager.py b/fail2ban/server/banmanager.py
588index 5770bfd7..9bb44971 100644
589--- a/fail2ban/server/banmanager.py
590+++ b/fail2ban/server/banmanager.py
591@@ -105,9 +105,9 @@ class BanManager:
592 def getBanList(self, ordered=False, withTime=False):
593 with self.__lock:
594 if not ordered:
595- return self.__banList.keys()
596+ return list(self.__banList.keys())
597 lst = []
598- for ticket in self.__banList.itervalues():
599+ for ticket in self.__banList.values():
600 eob = ticket.getEndOfBanTime(self.__banTime)
601 lst.append((ticket,eob))
602 lst.sort(key=lambda t: t[1])
603@@ -126,7 +126,7 @@ class BanManager:
604
605 def __iter__(self):
606 with self.__lock:
607- return self.__banList.itervalues()
608+ return iter(self.__banList.values())
609
610 ##
611 # Returns normalized value
612@@ -165,7 +165,7 @@ class BanManager:
613 return return_dict
614 # get ips in lock:
615 with self.__lock:
616- banIPs = [banData.getIP() for banData in self.__banList.values()]
617+ banIPs = [banData.getIP() for banData in list(self.__banList.values())]
618 # get cymru info:
619 try:
620 for ip in banIPs:
621@@ -341,7 +341,7 @@ class BanManager:
622 # Gets the list of ticket to remove (thereby correct next unban time).
623 unBanList = {}
624 nextUnbanTime = BanTicket.MAX_TIME
625- for fid,ticket in self.__banList.iteritems():
626+ for fid,ticket in self.__banList.items():
627 # current time greater as end of ban - timed out:
628 eob = ticket.getEndOfBanTime(self.__banTime)
629 if time > eob:
630@@ -357,15 +357,15 @@ class BanManager:
631 if len(unBanList):
632 if len(unBanList) / 2.0 <= len(self.__banList) / 3.0:
633 # few as 2/3 should be removed - remove particular items:
634- for fid in unBanList.iterkeys():
635+ for fid in unBanList.keys():
636 del self.__banList[fid]
637 else:
638 # create new dictionary without items to be deleted:
639- self.__banList = dict((fid,ticket) for fid,ticket in self.__banList.iteritems() \
640+ self.__banList = dict((fid,ticket) for fid,ticket in self.__banList.items() \
641 if fid not in unBanList)
642
643 # return list of tickets:
644- return unBanList.values()
645+ return list(unBanList.values())
646
647 ##
648 # Flush the ban list.
649@@ -375,7 +375,7 @@ class BanManager:
650
651 def flushBanList(self):
652 with self.__lock:
653- uBList = self.__banList.values()
654+ uBList = list(self.__banList.values())
655 self.__banList = dict()
656 return uBList
657
658diff --git a/fail2ban/server/database.py b/fail2ban/server/database.py
659index ed736a7a..0e8c9aec 100644
660--- a/fail2ban/server/database.py
661+++ b/fail2ban/server/database.py
662@@ -67,13 +67,13 @@ if sys.version_info >= (3,): # pragma: 2.x no cover
663 else: # pragma: 3.x no cover
664 def _normalize(x):
665 if isinstance(x, dict):
666- return dict((_normalize(k), _normalize(v)) for k, v in x.iteritems())
667+ return dict((_normalize(k), _normalize(v)) for k, v in x.items())
668 elif isinstance(x, (list, set)):
669 return [_normalize(element) for element in x]
670- elif isinstance(x, unicode):
671+ elif isinstance(x, str):
672 # in 2.x default text_factory is unicode - so return proper unicode here:
673 return x.encode(PREFER_ENC, 'replace').decode(PREFER_ENC)
674- elif isinstance(x, basestring):
675+ elif isinstance(x, str):
676 return x.decode(PREFER_ENC, 'replace')
677 return x
678
679diff --git a/fail2ban/server/failmanager.py b/fail2ban/server/failmanager.py
680index 93c028fb..a9c6b5f6 100644
681--- a/fail2ban/server/failmanager.py
682+++ b/fail2ban/server/failmanager.py
683@@ -57,7 +57,7 @@ class FailManager:
684 def getFailCount(self):
685 # may be slow on large list of failures, should be used for test purposes only...
686 with self.__lock:
687- return len(self.__failList), sum([f.getRetry() for f in self.__failList.values()])
688+ return len(self.__failList), sum([f.getRetry() for f in list(self.__failList.values())])
689
690 def getFailTotal(self):
691 with self.__lock:
692@@ -125,7 +125,7 @@ class FailManager:
693 # in case of having many active failures, it should be ran only
694 # if debug level is "low" enough
695 failures_summary = ', '.join(['%s:%d' % (k, v.getRetry())
696- for k,v in self.__failList.iteritems()])
697+ for k,v in self.__failList.items()])
698 logSys.log(logLevel, "Total # of detected failures: %d. Current failures from %d IPs (IP:count): %s"
699 % (self.__failTotal, len(self.__failList), failures_summary))
700
701@@ -138,7 +138,7 @@ class FailManager:
702
703 def cleanup(self, time):
704 with self.__lock:
705- todelete = [fid for fid,item in self.__failList.iteritems() \
706+ todelete = [fid for fid,item in self.__failList.items() \
707 if item.getLastTime() + self.__maxTime <= time]
708 if len(todelete) == len(self.__failList):
709 # remove all:
710@@ -152,7 +152,7 @@ class FailManager:
711 del self.__failList[fid]
712 else:
713 # create new dictionary without items to be deleted:
714- self.__failList = dict((fid,item) for fid,item in self.__failList.iteritems() \
715+ self.__failList = dict((fid,item) for fid,item in self.__failList.items() \
716 if item.getLastTime() + self.__maxTime > time)
717 self.__bgSvc.service()
718
719diff --git a/fail2ban/server/failregex.py b/fail2ban/server/failregex.py
720index f7dafbef..fb75187d 100644
721--- a/fail2ban/server/failregex.py
722+++ b/fail2ban/server/failregex.py
723@@ -128,10 +128,7 @@ class Regex:
724 self._regexObj = re.compile(regex, re.MULTILINE if multiline else 0)
725 self._regex = regex
726 self._altValues = {}
727- for k in filter(
728- lambda k: len(k) > len(ALTNAME_PRE) and k.startswith(ALTNAME_PRE),
729- self._regexObj.groupindex
730- ):
731+ for k in [k for k in self._regexObj.groupindex if len(k) > len(ALTNAME_PRE) and k.startswith(ALTNAME_PRE)]:
732 n = ALTNAME_CRE.match(k).group(1)
733 self._altValues[k] = n
734 self._altValues = list(self._altValues.items()) if len(self._altValues) else None
735@@ -211,7 +208,7 @@ class Regex:
736 #
737 @staticmethod
738 def _tupleLinesBuf(tupleLines):
739- return "\n".join(map(lambda v: "".join(v[::2]), tupleLines)) + "\n"
740+ return "\n".join(["".join(v[::2]) for v in tupleLines]) + "\n"
741
742 ##
743 # Searches the regular expression.
744@@ -223,7 +220,7 @@ class Regex:
745
746 def search(self, tupleLines, orgLines=None):
747 buf = tupleLines
748- if not isinstance(tupleLines, basestring):
749+ if not isinstance(tupleLines, str):
750 buf = Regex._tupleLinesBuf(tupleLines)
751 self._matchCache = self._regexObj.search(buf)
752 if self._matchCache:
753diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py
754index 998fe298..d181fd38 100644
755--- a/fail2ban/server/filter.py
756+++ b/fail2ban/server/filter.py
757@@ -292,7 +292,7 @@ class Filter(JailThread):
758 dd = DateDetector()
759 dd.default_tz = self.__logtimezone
760 if not isinstance(pattern, (list, tuple)):
761- pattern = filter(bool, map(str.strip, re.split('\n+', pattern)))
762+ pattern = list(filter(bool, list(map(str.strip, re.split('\n+', pattern)))))
763 for pattern in pattern:
764 dd.appendTemplate(pattern)
765 self.dateDetector = dd
766@@ -987,7 +987,7 @@ class FileFilter(Filter):
767 # @return log paths
768
769 def getLogPaths(self):
770- return self.__logs.keys()
771+ return list(self.__logs.keys())
772
773 ##
774 # Get the log containers
775@@ -995,7 +995,7 @@ class FileFilter(Filter):
776 # @return log containers
777
778 def getLogs(self):
779- return self.__logs.values()
780+ return list(self.__logs.values())
781
782 ##
783 # Get the count of log containers
784@@ -1021,7 +1021,7 @@ class FileFilter(Filter):
785
786 def setLogEncoding(self, encoding):
787 encoding = super(FileFilter, self).setLogEncoding(encoding)
788- for log in self.__logs.itervalues():
789+ for log in self.__logs.values():
790 log.setEncoding(encoding)
791
792 def getLog(self, path):
793@@ -1183,7 +1183,7 @@ class FileFilter(Filter):
794 """Status of Filter plus files being monitored.
795 """
796 ret = super(FileFilter, self).status(flavor=flavor)
797- path = self.__logs.keys()
798+ path = list(self.__logs.keys())
799 ret.append(("File list", path))
800 return ret
801
802@@ -1191,7 +1191,7 @@ class FileFilter(Filter):
803 """Stop monitoring of log-file(s)
804 """
805 # stop files monitoring:
806- for path in self.__logs.keys():
807+ for path in list(self.__logs.keys()):
808 self.delLogPath(path)
809 # stop thread:
810 super(Filter, self).stop()
811diff --git a/fail2ban/server/filterpoll.py b/fail2ban/server/filterpoll.py
812index 228a2c8b..d49315cc 100644
813--- a/fail2ban/server/filterpoll.py
814+++ b/fail2ban/server/filterpoll.py
815@@ -176,4 +176,4 @@ class FilterPoll(FileFilter):
816 return False
817
818 def getPendingPaths(self):
819- return self.__file404Cnt.keys()
820+ return list(self.__file404Cnt.keys())
821diff --git a/fail2ban/server/filterpyinotify.py b/fail2ban/server/filterpyinotify.py
822index ca6b253f..b683b860 100644
823--- a/fail2ban/server/filterpyinotify.py
824+++ b/fail2ban/server/filterpyinotify.py
825@@ -158,7 +158,7 @@ class FilterPyinotify(FileFilter):
826 except KeyError: pass
827
828 def getPendingPaths(self):
829- return self.__pending.keys()
830+ return list(self.__pending.keys())
831
832 def _checkPending(self):
833 if not self.__pending:
834@@ -168,7 +168,7 @@ class FilterPyinotify(FileFilter):
835 return
836 found = {}
837 minTime = 60
838- for path, (retardTM, isDir) in self.__pending.iteritems():
839+ for path, (retardTM, isDir) in self.__pending.items():
840 if ntm - self.__pendingChkTime < retardTM:
841 if minTime > retardTM: minTime = retardTM
842 continue
843@@ -184,7 +184,7 @@ class FilterPyinotify(FileFilter):
844 self.__pendingChkTime = time.time()
845 self.__pendingMinTime = minTime
846 # process now because we've missed it in monitoring:
847- for path, isDir in found.iteritems():
848+ for path, isDir in found.items():
849 self._delPending(path)
850 # refresh monitoring of this:
851 self._refreshWatcher(path, isDir=isDir)
852diff --git a/fail2ban/server/ipdns.py b/fail2ban/server/ipdns.py
853index 6648dac6..fe8f8db8 100644
854--- a/fail2ban/server/ipdns.py
855+++ b/fail2ban/server/ipdns.py
856@@ -275,7 +275,7 @@ class IPAddr(object):
857 raise ValueError("invalid ipstr %r, too many plen representation" % (ipstr,))
858 if "." in s[1] or ":" in s[1]: # 255.255.255.0 resp. ffff:: style mask
859 s[1] = IPAddr.masktoplen(s[1])
860- s[1] = long(s[1])
861+ s[1] = int(s[1])
862 return s
863
864 def __init(self, ipstr, cidr=CIDR_UNSPEC):
865@@ -309,7 +309,7 @@ class IPAddr(object):
866
867 # mask out host portion if prefix length is supplied
868 if cidr is not None and cidr >= 0:
869- mask = ~(0xFFFFFFFFL >> cidr)
870+ mask = ~(0xFFFFFFFF >> cidr)
871 self._addr &= mask
872 self._plen = cidr
873
874@@ -321,13 +321,13 @@ class IPAddr(object):
875
876 # mask out host portion if prefix length is supplied
877 if cidr is not None and cidr >= 0:
878- mask = ~(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL >> cidr)
879+ mask = ~(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF >> cidr)
880 self._addr &= mask
881 self._plen = cidr
882
883 # if IPv6 address is a IPv4-compatible, make instance a IPv4
884 elif self.isInNet(IPAddr.IP6_4COMPAT):
885- self._addr = lo & 0xFFFFFFFFL
886+ self._addr = lo & 0xFFFFFFFF
887 self._family = socket.AF_INET
888 self._plen = 32
889 else:
890@@ -445,7 +445,7 @@ class IPAddr(object):
891 elif self.isIPv6:
892 # convert network to host byte order
893 hi = self._addr >> 64
894- lo = self._addr & 0xFFFFFFFFFFFFFFFFL
895+ lo = self._addr & 0xFFFFFFFFFFFFFFFF
896 binary = struct.pack("!QQ", hi, lo)
897 if self._plen and self._plen < 128:
898 add = "/%d" % self._plen
899@@ -503,9 +503,9 @@ class IPAddr(object):
900 if self.family != net.family:
901 return False
902 if self.isIPv4:
903- mask = ~(0xFFFFFFFFL >> net.plen)
904+ mask = ~(0xFFFFFFFF >> net.plen)
905 elif self.isIPv6:
906- mask = ~(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL >> net.plen)
907+ mask = ~(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF >> net.plen)
908 else:
909 return False
910
911@@ -517,7 +517,7 @@ class IPAddr(object):
912 m4 = (1 << 32)-1
913 mmap = {m6: 128, m4: 32, 0: 0}
914 m = 0
915- for i in xrange(0, 128):
916+ for i in range(0, 128):
917 m |= 1 << i
918 if i < 32:
919 mmap[m ^ m4] = 32-1-i
920diff --git a/fail2ban/server/jail.py b/fail2ban/server/jail.py
921index ce9968a8..5fa5ef10 100644
922--- a/fail2ban/server/jail.py
923+++ b/fail2ban/server/jail.py
924@@ -26,7 +26,7 @@ __license__ = "GPL"
925 import logging
926 import math
927 import random
928-import Queue
929+import queue
930
931 from .actions import Actions
932 from ..helpers import getLogger, _as_bool, extractOptions, MyTime
933@@ -76,7 +76,7 @@ class Jail(object):
934 "might not function correctly. Please shorten"
935 % name)
936 self.__name = name
937- self.__queue = Queue.Queue()
938+ self.__queue = queue.Queue()
939 self.__filter = None
940 # Extra parameters for increase ban time
941 self._banExtra = {};
942@@ -127,25 +127,25 @@ class Jail(object):
943 "Failed to initialize any backend for Jail %r" % self.name)
944
945 def _initPolling(self, **kwargs):
946- from filterpoll import FilterPoll
947+ from .filterpoll import FilterPoll
948 logSys.info("Jail '%s' uses poller %r" % (self.name, kwargs))
949 self.__filter = FilterPoll(self, **kwargs)
950
951 def _initGamin(self, **kwargs):
952 # Try to import gamin
953- from filtergamin import FilterGamin
954+ from .filtergamin import FilterGamin
955 logSys.info("Jail '%s' uses Gamin %r" % (self.name, kwargs))
956 self.__filter = FilterGamin(self, **kwargs)
957
958 def _initPyinotify(self, **kwargs):
959 # Try to import pyinotify
960- from filterpyinotify import FilterPyinotify
961+ from .filterpyinotify import FilterPyinotify
962 logSys.info("Jail '%s' uses pyinotify %r" % (self.name, kwargs))
963 self.__filter = FilterPyinotify(self, **kwargs)
964
965 def _initSystemd(self, **kwargs): # pragma: systemd no cover
966 # Try to import systemd
967- from filtersystemd import FilterSystemd
968+ from .filtersystemd import FilterSystemd
969 logSys.info("Jail '%s' uses systemd %r" % (self.name, kwargs))
970 self.__filter = FilterSystemd(self, **kwargs)
971
972@@ -213,7 +213,7 @@ class Jail(object):
973 try:
974 ticket = self.__queue.get(False)
975 return ticket
976- except Queue.Empty:
977+ except queue.Empty:
978 return False
979
980 def setBanTimeExtra(self, opt, value):
981diff --git a/fail2ban/server/mytime.py b/fail2ban/server/mytime.py
982index 98b69bd4..24bba5cf 100644
983--- a/fail2ban/server/mytime.py
984+++ b/fail2ban/server/mytime.py
985@@ -162,7 +162,7 @@ class MyTime:
986
987 @returns number (calculated seconds from expression "val")
988 """
989- if isinstance(val, (int, long, float, complex)):
990+ if isinstance(val, (int, float, complex)):
991 return val
992 # replace together standing abbreviations, example '1d12h' -> '1d 12h':
993 val = MyTime._str2sec_prep.sub(r" \1", val)
994diff --git a/fail2ban/server/server.py b/fail2ban/server/server.py
995index 159f6506..fc948e8c 100644
996--- a/fail2ban/server/server.py
997+++ b/fail2ban/server/server.py
998@@ -97,7 +97,7 @@ class Server:
999
1000 def start(self, sock, pidfile, force=False, observer=True, conf={}):
1001 # First set the mask to only allow access to owner
1002- os.umask(0077)
1003+ os.umask(0o077)
1004 # Second daemonize before logging etc, because it will close all handles:
1005 if self.__daemon: # pragma: no cover
1006 logSys.info("Starting in daemon mode")
1007@@ -190,7 +190,7 @@ class Server:
1008
1009 # Restore default signal handlers:
1010 if _thread_name() == '_MainThread':
1011- for s, sh in self.__prev_signals.iteritems():
1012+ for s, sh in self.__prev_signals.items():
1013 signal.signal(s, sh)
1014
1015 # Give observer a small chance to complete its work before exit
1016@@ -268,10 +268,10 @@ class Server:
1017 logSys.info("Stopping all jails")
1018 with self.__lock:
1019 # 1st stop all jails (signal and stop actions/filter thread):
1020- for name in self.__jails.keys():
1021+ for name in list(self.__jails.keys()):
1022 self.delJail(name, stop=True, join=False)
1023 # 2nd wait for end and delete jails:
1024- for name in self.__jails.keys():
1025+ for name in list(self.__jails.keys()):
1026 self.delJail(name, stop=False, join=True)
1027
1028 def reloadJails(self, name, opts, begin):
1029@@ -302,7 +302,7 @@ class Server:
1030 if "--restart" in opts:
1031 self.stopAllJail()
1032 # first set all affected jail(s) to idle and reset filter regex and other lists/dicts:
1033- for jn, jail in self.__jails.iteritems():
1034+ for jn, jail in self.__jails.items():
1035 if name == '--all' or jn == name:
1036 jail.idle = True
1037 self.__reload_state[jn] = jail
1038@@ -313,7 +313,7 @@ class Server:
1039 # end reload, all affected (or new) jails have already all new parameters (via stream) and (re)started:
1040 with self.__lock:
1041 deljails = []
1042- for jn, jail in self.__jails.iteritems():
1043+ for jn, jail in self.__jails.items():
1044 # still in reload state:
1045 if jn in self.__reload_state:
1046 # remove jails that are not reloaded (untouched, so not in new configuration)
1047@@ -513,7 +513,7 @@ class Server:
1048 jails = [self.__jails[name]]
1049 else:
1050 # in all jails:
1051- jails = self.__jails.values()
1052+ jails = list(self.__jails.values())
1053 # unban given or all (if value is None):
1054 cnt = 0
1055 ifexists |= (name is None)
1056@@ -551,7 +551,7 @@ class Server:
1057 def isAlive(self, jailnum=None):
1058 if jailnum is not None and len(self.__jails) != jailnum:
1059 return 0
1060- for jail in self.__jails.values():
1061+ for jail in list(self.__jails.values()):
1062 if not jail.isAlive():
1063 return 0
1064 return 1
1065@@ -759,7 +759,7 @@ class Server:
1066 return "flushed"
1067
1068 def setThreadOptions(self, value):
1069- for o, v in value.iteritems():
1070+ for o, v in value.items():
1071 if o == 'stacksize':
1072 threading.stack_size(int(v)*1024)
1073 else: # pragma: no cover
1074diff --git a/fail2ban/server/strptime.py b/fail2ban/server/strptime.py
1075index 498d284b..a5579fdc 100644
1076--- a/fail2ban/server/strptime.py
1077+++ b/fail2ban/server/strptime.py
1078@@ -79,7 +79,7 @@ timeRE['ExY'] = r"(?P<Y>%s\d)" % _getYearCentRE(cent=(0,3), distance=3)
1079 timeRE['Exy'] = r"(?P<y>%s\d)" % _getYearCentRE(cent=(2,3), distance=3)
1080
1081 def getTimePatternRE():
1082- keys = timeRE.keys()
1083+ keys = list(timeRE.keys())
1084 patt = (r"%%(%%|%s|[%s])" % (
1085 "|".join([k for k in keys if len(k) > 1]),
1086 "".join([k for k in keys if len(k) == 1]),
1087@@ -134,7 +134,7 @@ def zone2offset(tz, dt):
1088 """
1089 if isinstance(tz, int):
1090 return tz
1091- if isinstance(tz, basestring):
1092+ if isinstance(tz, str):
1093 return validateTimeZone(tz)
1094 tz, tzo = tz
1095 if tzo is None or tzo == '': # without offset
1096@@ -171,7 +171,7 @@ def reGroupDictStrptime(found_dict, msec=False, default_tz=None):
1097 year = month = day = hour = minute = tzoffset = \
1098 weekday = julian = week_of_year = None
1099 second = fraction = 0
1100- for key, val in found_dict.iteritems():
1101+ for key, val in found_dict.items():
1102 if val is None: continue
1103 # Directives not explicitly handled below:
1104 # c, x, X
1105diff --git a/fail2ban/server/ticket.py b/fail2ban/server/ticket.py
1106index f67e0d23..f0b727c2 100644
1107--- a/fail2ban/server/ticket.py
1108+++ b/fail2ban/server/ticket.py
1109@@ -55,7 +55,7 @@ class Ticket(object):
1110 self._time = time if time is not None else MyTime.time()
1111 self._data = {'matches': matches or [], 'failures': 0}
1112 if data is not None:
1113- for k,v in data.iteritems():
1114+ for k,v in data.items():
1115 if v is not None:
1116 self._data[k] = v
1117 if ticket:
1118@@ -89,7 +89,7 @@ class Ticket(object):
1119
1120 def setIP(self, value):
1121 # guarantee using IPAddr instead of unicode, str for the IP
1122- if isinstance(value, basestring):
1123+ if isinstance(value, str):
1124 value = IPAddr(value)
1125 self._ip = value
1126
1127@@ -181,7 +181,7 @@ class Ticket(object):
1128 if len(args) == 1:
1129 # todo: if support >= 2.7 only:
1130 # self._data = {k:v for k,v in args[0].iteritems() if v is not None}
1131- self._data = dict([(k,v) for k,v in args[0].iteritems() if v is not None])
1132+ self._data = dict([(k,v) for k,v in args[0].items() if v is not None])
1133 # add k,v list or dict (merge):
1134 elif len(args) == 2:
1135 self._data.update((args,))
1136@@ -192,7 +192,7 @@ class Ticket(object):
1137 # filter (delete) None values:
1138 # todo: if support >= 2.7 only:
1139 # self._data = {k:v for k,v in self._data.iteritems() if v is not None}
1140- self._data = dict([(k,v) for k,v in self._data.iteritems() if v is not None])
1141+ self._data = dict([(k,v) for k,v in self._data.items() if v is not None])
1142
1143 def getData(self, key=None, default=None):
1144 # return whole data dict:
1145@@ -201,17 +201,17 @@ class Ticket(object):
1146 # return default if not exists:
1147 if not self._data:
1148 return default
1149- if not isinstance(key,(str,unicode,type(None),int,float,bool,complex)):
1150+ if not isinstance(key,(str,type(None),int,float,bool,complex)):
1151 # return filtered by lambda/function:
1152 if callable(key):
1153 # todo: if support >= 2.7 only:
1154 # return {k:v for k,v in self._data.iteritems() if key(k)}
1155- return dict([(k,v) for k,v in self._data.iteritems() if key(k)])
1156+ return dict([(k,v) for k,v in self._data.items() if key(k)])
1157 # return filtered by keys:
1158 if hasattr(key, '__iter__'):
1159 # todo: if support >= 2.7 only:
1160 # return {k:v for k,v in self._data.iteritems() if k in key}
1161- return dict([(k,v) for k,v in self._data.iteritems() if k in key])
1162+ return dict([(k,v) for k,v in self._data.items() if k in key])
1163 # return single value of data:
1164 return self._data.get(key, default)
1165
1166diff --git a/fail2ban/server/transmitter.py b/fail2ban/server/transmitter.py
1167index f83e9d5f..80726cb4 100644
1168--- a/fail2ban/server/transmitter.py
1169+++ b/fail2ban/server/transmitter.py
1170@@ -475,7 +475,7 @@ class Transmitter:
1171 opt = command[1][len("bantime."):]
1172 return self.__server.getBanTimeExtra(name, opt)
1173 elif command[1] == "actions":
1174- return self.__server.getActions(name).keys()
1175+ return list(self.__server.getActions(name).keys())
1176 elif command[1] == "action":
1177 actionname = command[2]
1178 actionvalue = command[3]
1179diff --git a/fail2ban/server/utils.py b/fail2ban/server/utils.py
1180index d4461a7d..13c24e76 100644
1181--- a/fail2ban/server/utils.py
1182+++ b/fail2ban/server/utils.py
1183@@ -57,7 +57,7 @@ _RETCODE_HINTS = {
1184
1185 # Dictionary to lookup signal name from number
1186 signame = dict((num, name)
1187- for name, num in signal.__dict__.iteritems() if name.startswith("SIG"))
1188+ for name, num in signal.__dict__.items() if name.startswith("SIG"))
1189
1190 class Utils():
1191 """Utilities provide diverse static methods like executes OS shell commands, etc.
1192@@ -109,7 +109,7 @@ class Utils():
1193 break
1194 else: # pragma: 3.x no cover (dict is in 2.6 only)
1195 remlst = []
1196- for (ck, cv) in cache.iteritems():
1197+ for (ck, cv) in cache.items():
1198 # if expired:
1199 if cv[1] <= t:
1200 remlst.append(ck)
1201@@ -152,7 +152,7 @@ class Utils():
1202 if not isinstance(realCmd, list):
1203 realCmd = [realCmd]
1204 i = len(realCmd)-1
1205- for k, v in varsDict.iteritems():
1206+ for k, v in varsDict.items():
1207 varsStat += "%s=$%s " % (k, i)
1208 realCmd.append(v)
1209 i += 1
1210diff --git a/fail2ban/tests/action_d/test_badips.py b/fail2ban/tests/action_d/test_badips.py
1211index 013c0fdb..3c35e4d7 100644
1212--- a/fail2ban/tests/action_d/test_badips.py
1213+++ b/fail2ban/tests/action_d/test_badips.py
1214@@ -32,7 +32,7 @@ from ..utils import LogCaptureTestCase, CONFIG_DIR
1215 if sys.version_info >= (3, ): # pragma: 2.x no cover
1216 from urllib.error import HTTPError, URLError
1217 else: # pragma: 3.x no cover
1218- from urllib2 import HTTPError, URLError
1219+ from urllib.error import HTTPError, URLError
1220
1221 def skip_if_not_available(f):
1222 """Helper to decorate tests to skip in case of timeout/http-errors like "502 bad gateway".
1223diff --git a/fail2ban/tests/actiontestcase.py b/fail2ban/tests/actiontestcase.py
1224index 1a00c040..ecd09246 100644
1225--- a/fail2ban/tests/actiontestcase.py
1226+++ b/fail2ban/tests/actiontestcase.py
1227@@ -244,14 +244,14 @@ class CommandActionTest(LogCaptureTestCase):
1228 setattr(self.__action, 'ab', "<ac>")
1229 setattr(self.__action, 'x?family=inet6', "")
1230 # produce self-referencing properties except:
1231- self.assertRaisesRegexp(ValueError, r"properties contain self referencing definitions",
1232+ self.assertRaisesRegex(ValueError, r"properties contain self referencing definitions",
1233 lambda: self.__action.replaceTag("<a><b>",
1234 self.__action._properties, conditional="family=inet4")
1235 )
1236 # remore self-referencing in props:
1237 delattr(self.__action, 'ac')
1238 # produce self-referencing query except:
1239- self.assertRaisesRegexp(ValueError, r"possible self referencing definitions in query",
1240+ self.assertRaisesRegex(ValueError, r"possible self referencing definitions in query",
1241 lambda: self.__action.replaceTag("<x<x<x<x<x<x<x<x<x<x<x<x<x<x<x<x<x<x<x<x<x>>>>>>>>>>>>>>>>>>>>>",
1242 self.__action._properties, conditional="family=inet6")
1243 )
1244diff --git a/fail2ban/tests/clientreadertestcase.py b/fail2ban/tests/clientreadertestcase.py
1245index 2c1d0a0e..aa7908c4 100644
1246--- a/fail2ban/tests/clientreadertestcase.py
1247+++ b/fail2ban/tests/clientreadertestcase.py
1248@@ -390,7 +390,7 @@ class JailReaderTest(LogCaptureTestCase):
1249 # And multiple groups (`][` instead of `,`)
1250 result = extractOptions(option.replace(',', ']['))
1251 expected2 = (expected[0],
1252- dict((k, v.replace(',', '][')) for k, v in expected[1].iteritems())
1253+ dict((k, v.replace(',', '][')) for k, v in expected[1].items())
1254 )
1255 self.assertEqual(expected2, result)
1256
1257@@ -975,7 +975,7 @@ filter = testfilter1
1258 self.assertEqual(add_actions[-1][-1], "{}")
1259
1260 def testLogPathFileFilterBackend(self):
1261- self.assertRaisesRegexp(ValueError, r"Have not found any log file for .* jail",
1262+ self.assertRaisesRegex(ValueError, r"Have not found any log file for .* jail",
1263 self._testLogPath, backend='polling')
1264
1265 def testLogPathSystemdBackend(self):
1266diff --git a/fail2ban/tests/databasetestcase.py b/fail2ban/tests/databasetestcase.py
1267index 9a5e9fa1..562461a6 100644
1268--- a/fail2ban/tests/databasetestcase.py
1269+++ b/fail2ban/tests/databasetestcase.py
1270@@ -67,7 +67,7 @@ class DatabaseTest(LogCaptureTestCase):
1271
1272 @property
1273 def db(self):
1274- if isinstance(self._db, basestring) and self._db == ':auto-create-in-memory:':
1275+ if isinstance(self._db, str) and self._db == ':auto-create-in-memory:':
1276 self._db = getFail2BanDb(self.dbFilename)
1277 return self._db
1278 @db.setter
1279@@ -159,7 +159,7 @@ class DatabaseTest(LogCaptureTestCase):
1280 self.db = Fail2BanDb(self.dbFilename)
1281 self.assertEqual(self.db.getJailNames(), set(['DummyJail #29162448 with 0 tickets']))
1282 self.assertEqual(self.db.getLogPaths(), set(['/tmp/Fail2BanDb_pUlZJh.log']))
1283- ticket = FailTicket("127.0.0.1", 1388009242.26, [u"abc\n"])
1284+ ticket = FailTicket("127.0.0.1", 1388009242.26, ["abc\n"])
1285 self.assertEqual(self.db.getBans()[0], ticket)
1286
1287 self.assertEqual(self.db.updateDb(Fail2BanDb.__version__), Fail2BanDb.__version__)
1288@@ -185,9 +185,9 @@ class DatabaseTest(LogCaptureTestCase):
1289 self.assertEqual(len(bans), 2)
1290 # compare first ticket completely:
1291 ticket = FailTicket("1.2.3.7", 1417595494, [
1292- u'Dec 3 09:31:08 f2btest test:auth[27658]: pam_unix(test:auth): authentication failure; logname= uid=0 euid=0 tty=test ruser= rhost=1.2.3.7',
1293- u'Dec 3 09:31:32 f2btest test:auth[27671]: pam_unix(test:auth): authentication failure; logname= uid=0 euid=0 tty=test ruser= rhost=1.2.3.7',
1294- u'Dec 3 09:31:34 f2btest test:auth[27673]: pam_unix(test:auth): authentication failure; logname= uid=0 euid=0 tty=test ruser= rhost=1.2.3.7'
1295+ 'Dec 3 09:31:08 f2btest test:auth[27658]: pam_unix(test:auth): authentication failure; logname= uid=0 euid=0 tty=test ruser= rhost=1.2.3.7',
1296+ 'Dec 3 09:31:32 f2btest test:auth[27671]: pam_unix(test:auth): authentication failure; logname= uid=0 euid=0 tty=test ruser= rhost=1.2.3.7',
1297+ 'Dec 3 09:31:34 f2btest test:auth[27673]: pam_unix(test:auth): authentication failure; logname= uid=0 euid=0 tty=test ruser= rhost=1.2.3.7'
1298 ])
1299 ticket.setAttempt(3)
1300 self.assertEqual(bans[0], ticket)
1301@@ -286,11 +286,11 @@ class DatabaseTest(LogCaptureTestCase):
1302 # invalid + valid, invalid + valid unicode, invalid + valid dual converted (like in filter:readline by fallback) ...
1303 tickets = [
1304 FailTicket("127.0.0.1", 0, ['user "test"', 'user "\xd1\xe2\xe5\xf2\xe0"', 'user "\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f"']),
1305- FailTicket("127.0.0.2", 0, ['user "test"', u'user "\xd1\xe2\xe5\xf2\xe0"', u'user "\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f"']),
1306+ FailTicket("127.0.0.2", 0, ['user "test"', 'user "\xd1\xe2\xe5\xf2\xe0"', 'user "\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f"']),
1307 FailTicket("127.0.0.3", 0, ['user "test"', b'user "\xd1\xe2\xe5\xf2\xe0"', b'user "\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f"']),
1308- FailTicket("127.0.0.4", 0, ['user "test"', 'user "\xd1\xe2\xe5\xf2\xe0"', u'user "\xe4\xf6\xfc\xdf"']),
1309+ FailTicket("127.0.0.4", 0, ['user "test"', 'user "\xd1\xe2\xe5\xf2\xe0"', 'user "\xe4\xf6\xfc\xdf"']),
1310 FailTicket("127.0.0.5", 0, ['user "test"', 'unterminated \xcf']),
1311- FailTicket("127.0.0.6", 0, ['user "test"', u'unterminated \xcf']),
1312+ FailTicket("127.0.0.6", 0, ['user "test"', 'unterminated \xcf']),
1313 FailTicket("127.0.0.7", 0, ['user "test"', b'unterminated \xcf'])
1314 ]
1315 for ticket in tickets:
1316diff --git a/fail2ban/tests/datedetectortestcase.py b/fail2ban/tests/datedetectortestcase.py
1317index 458f76ef..49ada60d 100644
1318--- a/fail2ban/tests/datedetectortestcase.py
1319+++ b/fail2ban/tests/datedetectortestcase.py
1320@@ -279,7 +279,7 @@ class DateDetectorTest(LogCaptureTestCase):
1321 self.assertEqual(logTime, mu)
1322 self.assertEqual(logMatch.group(1), '2012/10/11 02:37:17')
1323 # confuse it with year being at the end
1324- for i in xrange(10):
1325+ for i in range(10):
1326 ( logTime, logMatch ) = self.datedetector.getTime('11/10/2012 02:37:17 [error] 18434#0')
1327 self.assertEqual(logTime, mu)
1328 self.assertEqual(logMatch.group(1), '11/10/2012 02:37:17')
1329@@ -505,7 +505,7 @@ class CustomDateFormatsTest(unittest.TestCase):
1330 date = dd.getTime(line)
1331 if matched:
1332 self.assertTrue(date)
1333- if isinstance(matched, basestring):
1334+ if isinstance(matched, str):
1335 self.assertEqual(matched, date[1].group(1))
1336 else:
1337 self.assertEqual(matched, date[0])
1338@@ -537,7 +537,7 @@ class CustomDateFormatsTest(unittest.TestCase):
1339 date = dd.getTime(line)
1340 if matched:
1341 self.assertTrue(date)
1342- if isinstance(matched, basestring): # pragma: no cover
1343+ if isinstance(matched, str): # pragma: no cover
1344 self.assertEqual(matched, date[1].group(1))
1345 else:
1346 self.assertEqual(matched, date[0])
1347diff --git a/fail2ban/tests/fail2banclienttestcase.py b/fail2ban/tests/fail2banclienttestcase.py
1348index 95f73ed3..bba354fa 100644
1349--- a/fail2ban/tests/fail2banclienttestcase.py
1350+++ b/fail2ban/tests/fail2banclienttestcase.py
1351@@ -367,10 +367,10 @@ def with_foreground_server_thread(startextra={}):
1352 # several commands to server in body of decorated function:
1353 return f(self, tmp, startparams, *args, **kwargs)
1354 except Exception as e: # pragma: no cover
1355- print('=== Catch an exception: %s' % e)
1356+ print(('=== Catch an exception: %s' % e))
1357 log = self.getLog()
1358 if log:
1359- print('=== Error of server, log: ===\n%s===' % log)
1360+ print(('=== Error of server, log: ===\n%s===' % log))
1361 self.pruneLog()
1362 raise
1363 finally:
1364@@ -440,7 +440,7 @@ class Fail2banClientServerBase(LogCaptureTestCase):
1365 )
1366 except: # pragma: no cover
1367 if _inherited_log(startparams):
1368- print('=== Error by wait fot server, log: ===\n%s===' % self.getLog())
1369+ print(('=== Error by wait fot server, log: ===\n%s===' % self.getLog()))
1370 self.pruneLog()
1371 log = pjoin(tmp, "f2b.log")
1372 if isfile(log):
1373@@ -1610,6 +1610,6 @@ class Fail2banServerTest(Fail2banClientServerBase):
1374 self.stopAndWaitForServerEnd(SUCCESS)
1375
1376 def testServerStartStop(self):
1377- for i in xrange(2000):
1378+ for i in range(2000):
1379 self._testServerStartStop()
1380
1381diff --git a/fail2ban/tests/failmanagertestcase.py b/fail2ban/tests/failmanagertestcase.py
1382index a5425286..2a94cc82 100644
1383--- a/fail2ban/tests/failmanagertestcase.py
1384+++ b/fail2ban/tests/failmanagertestcase.py
1385@@ -45,11 +45,11 @@ class AddFailure(unittest.TestCase):
1386 super(AddFailure, self).tearDown()
1387
1388 def _addDefItems(self):
1389- self.__items = [[u'193.168.0.128', 1167605999.0],
1390- [u'193.168.0.128', 1167605999.0],
1391- [u'193.168.0.128', 1167605999.0],
1392- [u'193.168.0.128', 1167605999.0],
1393- [u'193.168.0.128', 1167605999.0],
1394+ self.__items = [['193.168.0.128', 1167605999.0],
1395+ ['193.168.0.128', 1167605999.0],
1396+ ['193.168.0.128', 1167605999.0],
1397+ ['193.168.0.128', 1167605999.0],
1398+ ['193.168.0.128', 1167605999.0],
1399 ['87.142.124.10', 1167605999.0],
1400 ['87.142.124.10', 1167605999.0],
1401 ['87.142.124.10', 1167605999.0],
1402diff --git a/fail2ban/tests/files/config/apache-auth/digest.py b/fail2ban/tests/files/config/apache-auth/digest.py
1403index 03588594..e2297ab3 100755
1404--- a/fail2ban/tests/files/config/apache-auth/digest.py
1405+++ b/fail2ban/tests/files/config/apache-auth/digest.py
1406@@ -41,7 +41,7 @@ def auth(v):
1407 response="%s"
1408 """ % ( username, algorithm, realm, url, nonce, qop, response )
1409 # opaque="%s",
1410- print(p.method, p.url, p.headers)
1411+ print((p.method, p.url, p.headers))
1412 s = requests.Session()
1413 return s.send(p)
1414
1415@@ -76,18 +76,18 @@ r = auth(v)
1416
1417 # [Sun Jul 28 21:41:20 2013] [error] [client 127.0.0.1] Digest: unknown algorithm `super funky chicken' received: /digest/
1418
1419-print(r.status_code,r.headers, r.text)
1420+print((r.status_code,r.headers, r.text))
1421 v['algorithm'] = algorithm
1422
1423
1424 r = auth(v)
1425-print(r.status_code,r.headers, r.text)
1426+print((r.status_code,r.headers, r.text))
1427
1428 nonce = v['nonce']
1429 v['nonce']=v['nonce'][5:-5]
1430
1431 r = auth(v)
1432-print(r.status_code,r.headers, r.text)
1433+print((r.status_code,r.headers, r.text))
1434
1435 # [Sun Jul 28 21:05:31.178340 2013] [auth_digest:error] [pid 24224:tid 139895539455744] [client 127.0.0.1:56906] AH01793: invalid qop `auth' received: /digest/qop_none/
1436
1437@@ -95,7 +95,7 @@ print(r.status_code,r.headers, r.text)
1438 v['nonce']=nonce[0:11] + 'ZZZ' + nonce[14:]
1439
1440 r = auth(v)
1441-print(r.status_code,r.headers, r.text)
1442+print((r.status_code,r.headers, r.text))
1443
1444 #[Sun Jul 28 21:18:11.769228 2013] [auth_digest:error] [pid 24752:tid 139895505884928] [client 127.0.0.1:56964] AH01776: invalid nonce b9YAiJDiBAZZZ1b1abe02d20063ea3b16b544ea1b0d981c1bafe received - hash is not d42d824dee7aaf50c3ba0a7c6290bd453e3dd35b
1445
1446@@ -107,7 +107,7 @@ import time
1447 time.sleep(1)
1448
1449 r = auth(v)
1450-print(r.status_code,r.headers, r.text)
1451+print((r.status_code,r.headers, r.text))
1452
1453 # Obtained by putting the following code in modules/aaa/mod_auth_digest.c
1454 # in the function initialize_secret
1455@@ -137,7 +137,7 @@ s = sha.sha(apachesecret)
1456
1457 v=preauth()
1458
1459-print(v['nonce'])
1460+print((v['nonce']))
1461 realm = v['Digest realm'][1:-1]
1462
1463 (t,) = struct.unpack('l',base64.b64decode(v['nonce'][1:13]))
1464@@ -156,13 +156,13 @@ print(v)
1465
1466 r = auth(v)
1467 #[Mon Jul 29 02:12:55.539813 2013] [auth_digest:error] [pid 9647:tid 139895522670336] [client 127.0.0.1:58474] AH01777: invalid nonce 59QJppTiBAA=b08983fd166ade9840407df1b0f75b9e6e07d88d received - user attempted time travel
1468-print(r.status_code,r.headers, r.text)
1469+print((r.status_code,r.headers, r.text))
1470
1471 url='/digest_onetime/'
1472 v=preauth()
1473
1474 # Need opaque header handling in auth
1475 r = auth(v)
1476-print(r.status_code,r.headers, r.text)
1477+print((r.status_code,r.headers, r.text))
1478 r = auth(v)
1479-print(r.status_code,r.headers, r.text)
1480+print((r.status_code,r.headers, r.text))
1481diff --git a/fail2ban/tests/filtertestcase.py b/fail2ban/tests/filtertestcase.py
1482index 35785a58..8eeb6902 100644
1483--- a/fail2ban/tests/filtertestcase.py
1484+++ b/fail2ban/tests/filtertestcase.py
1485@@ -22,7 +22,7 @@
1486 __copyright__ = "Copyright (c) 2004 Cyril Jaquier; 2012 Yaroslav Halchenko"
1487 __license__ = "GPL"
1488
1489-from __builtin__ import open as fopen
1490+from builtins import open as fopen
1491 import unittest
1492 import os
1493 import re
1494@@ -204,7 +204,7 @@ def _copy_lines_between_files(in_, fout, n=None, skip=0, mode='a', terminal_line
1495 else:
1496 fin = in_
1497 # Skip
1498- for i in xrange(skip):
1499+ for i in range(skip):
1500 fin.readline()
1501 # Read
1502 i = 0
1503@@ -244,7 +244,7 @@ def _copy_lines_to_journal(in_, fields={},n=None, skip=0, terminal_line=""): # p
1504 # Required for filtering
1505 fields.update(TEST_JOURNAL_FIELDS)
1506 # Skip
1507- for i in xrange(skip):
1508+ for i in range(skip):
1509 fin.readline()
1510 # Read/Write
1511 i = 0
1512@@ -306,18 +306,18 @@ class BasicFilter(unittest.TestCase):
1513 def testTest_tm(self):
1514 unittest.F2B.SkipIfFast()
1515 ## test function "_tm" works correct (returns the same as slow strftime):
1516- for i in xrange(1417512352, (1417512352 // 3600 + 3) * 3600):
1517+ for i in range(1417512352, (1417512352 // 3600 + 3) * 3600):
1518 tm = MyTime.time2str(i)
1519 if _tm(i) != tm: # pragma: no cover - never reachable
1520 self.assertEqual((_tm(i), i), (tm, i))
1521
1522 def testWrongCharInTupleLine(self):
1523 ## line tuple has different types (ascii after ascii / unicode):
1524- for a1 in ('', u'', b''):
1525- for a2 in ('2016-09-05T20:18:56', u'2016-09-05T20:18:56', b'2016-09-05T20:18:56'):
1526+ for a1 in ('', '', b''):
1527+ for a2 in ('2016-09-05T20:18:56', '2016-09-05T20:18:56', b'2016-09-05T20:18:56'):
1528 for a3 in (
1529 'Fail for "g\xc3\xb6ran" from 192.0.2.1',
1530- u'Fail for "g\xc3\xb6ran" from 192.0.2.1',
1531+ 'Fail for "g\xc3\xb6ran" from 192.0.2.1',
1532 b'Fail for "g\xc3\xb6ran" from 192.0.2.1'
1533 ):
1534 # join should work if all arguments have the same type:
1535@@ -435,7 +435,7 @@ class IgnoreIP(LogCaptureTestCase):
1536
1537 def testAddAttempt(self):
1538 self.filter.setMaxRetry(3)
1539- for i in xrange(1, 1+3):
1540+ for i in range(1, 1+3):
1541 self.filter.addAttempt('192.0.2.1')
1542 self.assertLogged('Attempt 192.0.2.1', '192.0.2.1:%d' % i, all=True, wait=True)
1543 self.jail.actions._Actions__checkBan()
1544@@ -472,7 +472,7 @@ class IgnoreIP(LogCaptureTestCase):
1545 # like both test-cases above, just cached (so once per key)...
1546 self.filter.ignoreCache = {"key":"<ip>"}
1547 self.filter.ignoreCommand = 'if [ "<ip>" = "10.0.0.1" ]; then exit 0; fi; exit 1'
1548- for i in xrange(5):
1549+ for i in range(5):
1550 self.pruneLog()
1551 self.assertTrue(self.filter.inIgnoreIPList("10.0.0.1"))
1552 self.assertFalse(self.filter.inIgnoreIPList("10.0.0.0"))
1553@@ -483,7 +483,7 @@ class IgnoreIP(LogCaptureTestCase):
1554 # by host of IP:
1555 self.filter.ignoreCache = {"key":"<ip-host>"}
1556 self.filter.ignoreCommand = 'if [ "<ip-host>" = "test-host" ]; then exit 0; fi; exit 1'
1557- for i in xrange(5):
1558+ for i in range(5):
1559 self.pruneLog()
1560 self.assertTrue(self.filter.inIgnoreIPList(FailTicket("2001:db8::1")))
1561 self.assertFalse(self.filter.inIgnoreIPList(FailTicket("2001:db8::ffff")))
1562@@ -495,7 +495,7 @@ class IgnoreIP(LogCaptureTestCase):
1563 self.filter.ignoreCache = {"key":"<F-USER>", "max-count":"10", "max-time":"1h"}
1564 self.assertEqual(self.filter.ignoreCache, ["<F-USER>", 10, 60*60])
1565 self.filter.ignoreCommand = 'if [ "<F-USER>" = "tester" ]; then exit 0; fi; exit 1'
1566- for i in xrange(5):
1567+ for i in range(5):
1568 self.pruneLog()
1569 self.assertTrue(self.filter.inIgnoreIPList(FailTicket("tester", data={'user': 'tester'})))
1570 self.assertFalse(self.filter.inIgnoreIPList(FailTicket("root", data={'user': 'root'})))
1571@@ -644,7 +644,7 @@ class LogFileFilterPoll(unittest.TestCase):
1572 fc = FileContainer(fname, self.filter.getLogEncoding())
1573 fc.open()
1574 # no time - nothing should be found :
1575- for i in xrange(10):
1576+ for i in range(10):
1577 f.write("[sshd] error: PAM: failure len 1\n")
1578 f.flush()
1579 fc.setPos(0); self.filter.seekToTime(fc, time)
1580@@ -718,14 +718,14 @@ class LogFileFilterPoll(unittest.TestCase):
1581 # variable length of file (ca 45K or 450K before and hereafter):
1582 # write lines with smaller as search time:
1583 t = time - count - 1
1584- for i in xrange(count):
1585+ for i in range(count):
1586 f.write("%s [sshd] error: PAM: failure\n" % _tm(t))
1587 t += 1
1588 f.flush()
1589 fc.setPos(0); self.filter.seekToTime(fc, time)
1590 self.assertEqual(fc.getPos(), 47*count)
1591 # write lines with exact search time:
1592- for i in xrange(10):
1593+ for i in range(10):
1594 f.write("%s [sshd] error: PAM: failure\n" % _tm(time))
1595 f.flush()
1596 fc.setPos(0); self.filter.seekToTime(fc, time)
1597@@ -734,8 +734,8 @@ class LogFileFilterPoll(unittest.TestCase):
1598 self.assertEqual(fc.getPos(), 47*count)
1599 # write lines with greater as search time:
1600 t = time+1
1601- for i in xrange(count//500):
1602- for j in xrange(500):
1603+ for i in range(count//500):
1604+ for j in range(500):
1605 f.write("%s [sshd] error: PAM: failure\n" % _tm(t))
1606 t += 1
1607 f.flush()
1608@@ -1488,10 +1488,10 @@ def get_monitor_failures_journal_testcase(Filter_): # pragma: systemd no cover
1609 # Add direct utf, unicode, blob:
1610 for l in (
1611 "error: PAM: Authentication failure for \xe4\xf6\xfc\xdf from 192.0.2.1",
1612- u"error: PAM: Authentication failure for \xe4\xf6\xfc\xdf from 192.0.2.1",
1613+ "error: PAM: Authentication failure for \xe4\xf6\xfc\xdf from 192.0.2.1",
1614 b"error: PAM: Authentication failure for \xe4\xf6\xfc\xdf from 192.0.2.1".decode('utf-8', 'replace'),
1615 "error: PAM: Authentication failure for \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f from 192.0.2.2",
1616- u"error: PAM: Authentication failure for \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f from 192.0.2.2",
1617+ "error: PAM: Authentication failure for \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f from 192.0.2.2",
1618 b"error: PAM: Authentication failure for \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f from 192.0.2.2".decode('utf-8', 'replace')
1619 ):
1620 fields = self.journal_fields
1621@@ -1520,7 +1520,7 @@ class GetFailures(LogCaptureTestCase):
1622
1623 # so that they could be reused by other tests
1624 FAILURES_01 = ('193.168.0.128', 3, 1124013599.0,
1625- [u'Aug 14 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 193.168.0.128']*3)
1626+ ['Aug 14 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 193.168.0.128']*3)
1627
1628 def setUp(self):
1629 """Call before every test case."""
1630@@ -1595,8 +1595,8 @@ class GetFailures(LogCaptureTestCase):
1631
1632 def testGetFailures02(self):
1633 output = ('141.3.81.106', 4, 1124013539.0,
1634- [u'Aug 14 11:%d:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:141.3.81.106 port 51332 ssh2'
1635- % m for m in 53, 54, 57, 58])
1636+ ['Aug 14 11:%d:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:141.3.81.106 port 51332 ssh2'
1637+ % m for m in (53, 54, 57, 58)])
1638
1639 self.filter.addLogPath(GetFailures.FILENAME_02, autoSeek=0)
1640 self.filter.addFailRegex(r"Failed .* from <HOST>")
1641@@ -1691,17 +1691,17 @@ class GetFailures(LogCaptureTestCase):
1642 # We should still catch failures with usedns = no ;-)
1643 output_yes = (
1644 ('93.184.216.34', 2, 1124013539.0,
1645- [u'Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2',
1646- u'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.34 port 51332 ssh2']
1647+ ['Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2',
1648+ 'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.34 port 51332 ssh2']
1649 ),
1650 ('2606:2800:220:1:248:1893:25c8:1946', 1, 1124013299.0,
1651- [u'Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2']
1652+ ['Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2']
1653 ),
1654 )
1655
1656 output_no = (
1657 ('93.184.216.34', 1, 1124013539.0,
1658- [u'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.34 port 51332 ssh2']
1659+ ['Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.34 port 51332 ssh2']
1660 )
1661 )
1662
1663@@ -1807,9 +1807,9 @@ class DNSUtilsTests(unittest.TestCase):
1664 self.assertTrue(c.get('a') is None)
1665 self.assertEqual(c.get('a', 'test'), 'test')
1666 # exact 5 elements :
1667- for i in xrange(5):
1668+ for i in range(5):
1669 c.set(i, i)
1670- for i in xrange(5):
1671+ for i in range(5):
1672 self.assertEqual(c.get(i), i)
1673 # remove unavailable key:
1674 c.unset('a'); c.unset('a')
1675@@ -1817,30 +1817,30 @@ class DNSUtilsTests(unittest.TestCase):
1676 def testCacheMaxSize(self):
1677 c = Utils.Cache(maxCount=5, maxTime=60)
1678 # exact 5 elements :
1679- for i in xrange(5):
1680+ for i in range(5):
1681 c.set(i, i)
1682- self.assertEqual([c.get(i) for i in xrange(5)], [i for i in xrange(5)])
1683- self.assertNotIn(-1, (c.get(i, -1) for i in xrange(5)))
1684+ self.assertEqual([c.get(i) for i in range(5)], [i for i in range(5)])
1685+ self.assertNotIn(-1, (c.get(i, -1) for i in range(5)))
1686 # add one - too many:
1687 c.set(10, i)
1688 # one element should be removed :
1689- self.assertIn(-1, (c.get(i, -1) for i in xrange(5)))
1690+ self.assertIn(-1, (c.get(i, -1) for i in range(5)))
1691 # test max size (not expired):
1692- for i in xrange(10):
1693+ for i in range(10):
1694 c.set(i, 1)
1695 self.assertEqual(len(c), 5)
1696
1697 def testCacheMaxTime(self):
1698 # test max time (expired, timeout reached) :
1699 c = Utils.Cache(maxCount=5, maxTime=0.0005)
1700- for i in xrange(10):
1701+ for i in range(10):
1702 c.set(i, 1)
1703 st = time.time()
1704 self.assertTrue(Utils.wait_for(lambda: time.time() >= st + 0.0005, 1))
1705 # we have still 5 elements (or fewer if too slow test mashine):
1706 self.assertTrue(len(c) <= 5)
1707 # but all that are expiered also:
1708- for i in xrange(10):
1709+ for i in range(10):
1710 self.assertTrue(c.get(i) is None)
1711 # here the whole cache should be empty:
1712 self.assertEqual(len(c), 0)
1713@@ -1861,7 +1861,7 @@ class DNSUtilsTests(unittest.TestCase):
1714 c = count
1715 while c:
1716 c -= 1
1717- s = xrange(0, 256, 1) if forw else xrange(255, -1, -1)
1718+ s = range(0, 256, 1) if forw else range(255, -1, -1)
1719 if random: shuffle([i for i in s])
1720 for i in s:
1721 IPAddr('192.0.2.'+str(i), IPAddr.FAM_IPv4)
1722@@ -1983,15 +1983,15 @@ class DNSUtilsNetworkTests(unittest.TestCase):
1723
1724 def testAddr2bin(self):
1725 res = IPAddr('10.0.0.0')
1726- self.assertEqual(res.addr, 167772160L)
1727+ self.assertEqual(res.addr, 167772160)
1728 res = IPAddr('10.0.0.0', cidr=None)
1729- self.assertEqual(res.addr, 167772160L)
1730- res = IPAddr('10.0.0.0', cidr=32L)
1731- self.assertEqual(res.addr, 167772160L)
1732- res = IPAddr('10.0.0.1', cidr=32L)
1733- self.assertEqual(res.addr, 167772161L)
1734- res = IPAddr('10.0.0.1', cidr=31L)
1735- self.assertEqual(res.addr, 167772160L)
1736+ self.assertEqual(res.addr, 167772160)
1737+ res = IPAddr('10.0.0.0', cidr=32)
1738+ self.assertEqual(res.addr, 167772160)
1739+ res = IPAddr('10.0.0.1', cidr=32)
1740+ self.assertEqual(res.addr, 167772161)
1741+ res = IPAddr('10.0.0.1', cidr=31)
1742+ self.assertEqual(res.addr, 167772160)
1743
1744 self.assertEqual(IPAddr('10.0.0.0').hexdump, '0a000000')
1745 self.assertEqual(IPAddr('1::2').hexdump, '00010000000000000000000000000002')
1746@@ -2067,9 +2067,9 @@ class DNSUtilsNetworkTests(unittest.TestCase):
1747 '93.184.216.34': 'ip4-test',
1748 '2606:2800:220:1:248:1893:25c8:1946': 'ip6-test'
1749 }
1750- d2 = dict([(IPAddr(k), v) for k, v in d.iteritems()])
1751- self.assertTrue(isinstance(d.keys()[0], basestring))
1752- self.assertTrue(isinstance(d2.keys()[0], IPAddr))
1753+ d2 = dict([(IPAddr(k), v) for k, v in d.items()])
1754+ self.assertTrue(isinstance(list(d.keys())[0], str))
1755+ self.assertTrue(isinstance(list(d2.keys())[0], IPAddr))
1756 self.assertEqual(d.get(ip4[2], ''), 'ip4-test')
1757 self.assertEqual(d.get(ip6[2], ''), 'ip6-test')
1758 self.assertEqual(d2.get(str(ip4[2]), ''), 'ip4-test')
1759diff --git a/fail2ban/tests/misctestcase.py b/fail2ban/tests/misctestcase.py
1760index 9b986f53..94f7a8de 100644
1761--- a/fail2ban/tests/misctestcase.py
1762+++ b/fail2ban/tests/misctestcase.py
1763@@ -29,9 +29,9 @@ import tempfile
1764 import shutil
1765 import fnmatch
1766 from glob import glob
1767-from StringIO import StringIO
1768+from io import StringIO
1769
1770-from utils import LogCaptureTestCase, logSys as DefLogSys
1771+from .utils import LogCaptureTestCase, logSys as DefLogSys
1772
1773 from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack, getLogger, \
1774 splitwords, uni_decode, uni_string
1775@@ -67,7 +67,7 @@ class HelpersTest(unittest.TestCase):
1776 self.assertEqual(splitwords(' 1\n 2'), ['1', '2'])
1777 self.assertEqual(splitwords(' 1\n 2, 3'), ['1', '2', '3'])
1778 # string as unicode:
1779- self.assertEqual(splitwords(u' 1\n 2, 3'), ['1', '2', '3'])
1780+ self.assertEqual(splitwords(' 1\n 2, 3'), ['1', '2', '3'])
1781
1782
1783 if sys.version_info >= (2,7):
1784@@ -197,11 +197,11 @@ class TestsUtilsTest(LogCaptureTestCase):
1785
1786 def testUniConverters(self):
1787 self.assertRaises(Exception, uni_decode,
1788- (b'test' if sys.version_info >= (3,) else u'test'), 'f2b-test::non-existing-encoding')
1789- uni_decode((b'test\xcf' if sys.version_info >= (3,) else u'test\xcf'))
1790+ (b'test' if sys.version_info >= (3,) else 'test'), 'f2b-test::non-existing-encoding')
1791+ uni_decode((b'test\xcf' if sys.version_info >= (3,) else 'test\xcf'))
1792 uni_string(b'test\xcf')
1793 uni_string('test\xcf')
1794- uni_string(u'test\xcf')
1795+ uni_string('test\xcf')
1796
1797 def testSafeLogging(self):
1798 # logging should be exception-safe, to avoid possible errors (concat, str. conversion, representation failures, etc)
1799@@ -213,7 +213,7 @@ class TestsUtilsTest(LogCaptureTestCase):
1800 if self.err:
1801 raise Exception('no represenation for test!')
1802 else:
1803- return u'conv-error (\xf2\xf0\xe5\xf2\xe8\xe9), unterminated utf \xcf'
1804+ return 'conv-error (\xf2\xf0\xe5\xf2\xe8\xe9), unterminated utf \xcf'
1805 test = Test()
1806 logSys.log(logging.NOTICE, "test 1a: %r", test)
1807 self.assertLogged("Traceback", "no represenation for test!")
1808@@ -261,7 +261,7 @@ class TestsUtilsTest(LogCaptureTestCase):
1809 func_raise()
1810
1811 try:
1812- print deep_function(3)
1813+ print(deep_function(3))
1814 except ValueError:
1815 s = tb()
1816
1817@@ -278,7 +278,7 @@ class TestsUtilsTest(LogCaptureTestCase):
1818 self.assertIn(':', s)
1819
1820 def _testAssertionErrorRE(self, regexp, fun, *args, **kwargs):
1821- self.assertRaisesRegexp(AssertionError, regexp, fun, *args, **kwargs)
1822+ self.assertRaisesRegex(AssertionError, regexp, fun, *args, **kwargs)
1823
1824 def testExtendedAssertRaisesRE(self):
1825 ## test _testAssertionErrorRE several fail cases:
1826@@ -316,13 +316,13 @@ class TestsUtilsTest(LogCaptureTestCase):
1827 self._testAssertionErrorRE(r"'a' unexpectedly found in 'cba'",
1828 self.assertNotIn, 'a', 'cba')
1829 self._testAssertionErrorRE(r"1 unexpectedly found in \[0, 1, 2\]",
1830- self.assertNotIn, 1, xrange(3))
1831+ self.assertNotIn, 1, range(3))
1832 self._testAssertionErrorRE(r"'A' unexpectedly found in \['C', 'A'\]",
1833 self.assertNotIn, 'A', (c.upper() for c in 'cba' if c != 'b'))
1834 self._testAssertionErrorRE(r"'a' was not found in 'xyz'",
1835 self.assertIn, 'a', 'xyz')
1836 self._testAssertionErrorRE(r"5 was not found in \[0, 1, 2\]",
1837- self.assertIn, 5, xrange(3))
1838+ self.assertIn, 5, range(3))
1839 self._testAssertionErrorRE(r"'A' was not found in \['C', 'B'\]",
1840 self.assertIn, 'A', (c.upper() for c in 'cba' if c != 'a'))
1841 ## assertLogged, assertNotLogged positive case:
1842diff --git a/fail2ban/tests/observertestcase.py b/fail2ban/tests/observertestcase.py
1843index 8e944454..ed520286 100644
1844--- a/fail2ban/tests/observertestcase.py
1845+++ b/fail2ban/tests/observertestcase.py
1846@@ -69,7 +69,7 @@ class BanTimeIncr(LogCaptureTestCase):
1847 a.setBanTimeExtra('multipliers', multipliers)
1848 # test algorithm and max time 24 hours :
1849 self.assertEqual(
1850- [a.calcBanTime(600, i) for i in xrange(1, 11)],
1851+ [a.calcBanTime(600, i) for i in range(1, 11)],
1852 [1200, 2400, 4800, 9600, 19200, 38400, 76800, 86400, 86400, 86400]
1853 )
1854 # with extra large max time (30 days):
1855@@ -81,38 +81,38 @@ class BanTimeIncr(LogCaptureTestCase):
1856 if multcnt < 11:
1857 arr = arr[0:multcnt-1] + ([arr[multcnt-2]] * (11-multcnt))
1858 self.assertEqual(
1859- [a.calcBanTime(600, i) for i in xrange(1, 11)],
1860+ [a.calcBanTime(600, i) for i in range(1, 11)],
1861 arr
1862 )
1863 a.setBanTimeExtra('maxtime', '1d')
1864 # change factor :
1865 a.setBanTimeExtra('factor', '2');
1866 self.assertEqual(
1867- [a.calcBanTime(600, i) for i in xrange(1, 11)],
1868+ [a.calcBanTime(600, i) for i in range(1, 11)],
1869 [2400, 4800, 9600, 19200, 38400, 76800, 86400, 86400, 86400, 86400]
1870 )
1871 # factor is float :
1872 a.setBanTimeExtra('factor', '1.33');
1873 self.assertEqual(
1874- [int(a.calcBanTime(600, i)) for i in xrange(1, 11)],
1875+ [int(a.calcBanTime(600, i)) for i in range(1, 11)],
1876 [1596, 3192, 6384, 12768, 25536, 51072, 86400, 86400, 86400, 86400]
1877 )
1878 a.setBanTimeExtra('factor', None);
1879 # change max time :
1880 a.setBanTimeExtra('maxtime', '12h')
1881 self.assertEqual(
1882- [a.calcBanTime(600, i) for i in xrange(1, 11)],
1883+ [a.calcBanTime(600, i) for i in range(1, 11)],
1884 [1200, 2400, 4800, 9600, 19200, 38400, 43200, 43200, 43200, 43200]
1885 )
1886 a.setBanTimeExtra('maxtime', '24h')
1887 ## test randomization - not possibe all 10 times we have random = 0:
1888 a.setBanTimeExtra('rndtime', '5m')
1889 self.assertTrue(
1890- False in [1200 in [a.calcBanTime(600, 1) for i in xrange(10)] for c in xrange(10)]
1891+ False in [1200 in [a.calcBanTime(600, 1) for i in range(10)] for c in range(10)]
1892 )
1893 a.setBanTimeExtra('rndtime', None)
1894 self.assertFalse(
1895- False in [1200 in [a.calcBanTime(600, 1) for i in xrange(10)] for c in xrange(10)]
1896+ False in [1200 in [a.calcBanTime(600, 1) for i in range(10)] for c in range(10)]
1897 )
1898 # restore default:
1899 a.setBanTimeExtra('multipliers', None)
1900@@ -124,7 +124,7 @@ class BanTimeIncr(LogCaptureTestCase):
1901 # this multipliers has the same values as default formula, we test stop growing after count 9:
1902 self.testDefault('1 2 4 8 16 32 64 128 256')
1903 # this multipliers has exactly the same values as default formula, test endless growing (stops by count 31 only):
1904- self.testDefault(' '.join([str(1<<i) for i in xrange(31)]))
1905+ self.testDefault(' '.join([str(1<<i) for i in range(31)]))
1906
1907 def testFormula(self):
1908 a = self.__jail;
1909@@ -136,38 +136,38 @@ class BanTimeIncr(LogCaptureTestCase):
1910 a.setBanTimeExtra('multipliers', None)
1911 # test algorithm and max time 24 hours :
1912 self.assertEqual(
1913- [int(a.calcBanTime(600, i)) for i in xrange(1, 11)],
1914+ [int(a.calcBanTime(600, i)) for i in range(1, 11)],
1915 [1200, 2400, 4800, 9600, 19200, 38400, 76800, 86400, 86400, 86400]
1916 )
1917 # with extra large max time (30 days):
1918 a.setBanTimeExtra('maxtime', '30d')
1919 self.assertEqual(
1920- [int(a.calcBanTime(600, i)) for i in xrange(1, 11)],
1921+ [int(a.calcBanTime(600, i)) for i in range(1, 11)],
1922 [1200, 2400, 4800, 9600, 19200, 38400, 76800, 153601, 307203, 614407]
1923 )
1924 a.setBanTimeExtra('maxtime', '24h')
1925 # change factor :
1926 a.setBanTimeExtra('factor', '1');
1927 self.assertEqual(
1928- [int(a.calcBanTime(600, i)) for i in xrange(1, 11)],
1929+ [int(a.calcBanTime(600, i)) for i in range(1, 11)],
1930 [1630, 4433, 12051, 32758, 86400, 86400, 86400, 86400, 86400, 86400]
1931 )
1932 a.setBanTimeExtra('factor', '2.0 / 2.885385')
1933 # change max time :
1934 a.setBanTimeExtra('maxtime', '12h')
1935 self.assertEqual(
1936- [int(a.calcBanTime(600, i)) for i in xrange(1, 11)],
1937+ [int(a.calcBanTime(600, i)) for i in range(1, 11)],
1938 [1200, 2400, 4800, 9600, 19200, 38400, 43200, 43200, 43200, 43200]
1939 )
1940 a.setBanTimeExtra('maxtime', '24h')
1941 ## test randomization - not possibe all 10 times we have random = 0:
1942 a.setBanTimeExtra('rndtime', '5m')
1943 self.assertTrue(
1944- False in [1200 in [int(a.calcBanTime(600, 1)) for i in xrange(10)] for c in xrange(10)]
1945+ False in [1200 in [int(a.calcBanTime(600, 1)) for i in range(10)] for c in range(10)]
1946 )
1947 a.setBanTimeExtra('rndtime', None)
1948 self.assertFalse(
1949- False in [1200 in [int(a.calcBanTime(600, 1)) for i in xrange(10)] for c in xrange(10)]
1950+ False in [1200 in [int(a.calcBanTime(600, 1)) for i in range(10)] for c in range(10)]
1951 )
1952 # restore default:
1953 a.setBanTimeExtra('factor', None);
1954@@ -230,7 +230,7 @@ class BanTimeIncrDB(LogCaptureTestCase):
1955 ticket = FailTicket(ip, stime, [])
1956 # test ticket not yet found
1957 self.assertEqual(
1958- [self.incrBanTime(ticket, 10) for i in xrange(3)],
1959+ [self.incrBanTime(ticket, 10) for i in range(3)],
1960 [10, 10, 10]
1961 )
1962 # add a ticket banned
1963@@ -285,7 +285,7 @@ class BanTimeIncrDB(LogCaptureTestCase):
1964 )
1965 # increase ban multiple times:
1966 lastBanTime = 20
1967- for i in xrange(10):
1968+ for i in range(10):
1969 ticket.setTime(stime + lastBanTime + 5)
1970 banTime = self.incrBanTime(ticket, 10)
1971 self.assertEqual(banTime, lastBanTime * 2)
1972@@ -481,7 +481,7 @@ class BanTimeIncrDB(LogCaptureTestCase):
1973 ticket = FailTicket(ip, stime-120, [])
1974 failManager = FailManager()
1975 failManager.setMaxRetry(3)
1976- for i in xrange(3):
1977+ for i in range(3):
1978 failManager.addFailure(ticket)
1979 obs.add('failureFound', failManager, jail, ticket)
1980 obs.wait_empty(5)
1981diff --git a/fail2ban/tests/samplestestcase.py b/fail2ban/tests/samplestestcase.py
1982index 0bbd05f5..479b564a 100644
1983--- a/fail2ban/tests/samplestestcase.py
1984+++ b/fail2ban/tests/samplestestcase.py
1985@@ -138,7 +138,7 @@ class FilterSamplesRegex(unittest.TestCase):
1986
1987 @staticmethod
1988 def _filterOptions(opts):
1989- return dict((k, v) for k, v in opts.iteritems() if not k.startswith('test.'))
1990+ return dict((k, v) for k, v in opts.items() if not k.startswith('test.'))
1991
1992 def testSampleRegexsFactory(name, basedir):
1993 def testFilter(self):
1994@@ -249,10 +249,10 @@ def testSampleRegexsFactory(name, basedir):
1995 self.assertTrue(faildata.get('match', False),
1996 "Line matched when shouldn't have")
1997 self.assertEqual(len(ret), 1,
1998- "Multiple regexs matched %r" % (map(lambda x: x[0], ret)))
1999+ "Multiple regexs matched %r" % ([x[0] for x in ret]))
2000
2001 # Verify match captures (at least fid/host) and timestamp as expected
2002- for k, v in faildata.iteritems():
2003+ for k, v in faildata.items():
2004 if k not in ("time", "match", "desc", "filter"):
2005 fv = fail.get(k, None)
2006 if fv is None:
2007@@ -294,7 +294,7 @@ def testSampleRegexsFactory(name, basedir):
2008 '\n'.join(pprint.pformat(fail).splitlines())))
2009
2010 # check missing samples for regex using each filter-options combination:
2011- for fltName, flt in self._filters.iteritems():
2012+ for fltName, flt in self._filters.items():
2013 flt, regexsUsedIdx = flt
2014 regexList = flt.getFailRegex()
2015 for failRegexIndex, failRegex in enumerate(regexList):
2016diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py
2017index 55e72455..7925ab1e 100644
2018--- a/fail2ban/tests/servertestcase.py
2019+++ b/fail2ban/tests/servertestcase.py
2020@@ -124,14 +124,14 @@ class TransmitterBase(LogCaptureTestCase):
2021 self.transm.proceed(["get", jail, cmd]), (0, []))
2022 for n, value in enumerate(values):
2023 ret = self.transm.proceed(["set", jail, cmdAdd, value])
2024- self.assertSortedEqual((ret[0], map(str, ret[1])), (0, map(str, values[:n+1])), level=2)
2025+ self.assertSortedEqual((ret[0], list(map(str, ret[1]))), (0, list(map(str, values[:n+1]))), level=2)
2026 ret = self.transm.proceed(["get", jail, cmd])
2027- self.assertSortedEqual((ret[0], map(str, ret[1])), (0, map(str, values[:n+1])), level=2)
2028+ self.assertSortedEqual((ret[0], list(map(str, ret[1]))), (0, list(map(str, values[:n+1]))), level=2)
2029 for n, value in enumerate(values):
2030 ret = self.transm.proceed(["set", jail, cmdDel, value])
2031- self.assertSortedEqual((ret[0], map(str, ret[1])), (0, map(str, values[n+1:])), level=2)
2032+ self.assertSortedEqual((ret[0], list(map(str, ret[1]))), (0, list(map(str, values[n+1:]))), level=2)
2033 ret = self.transm.proceed(["get", jail, cmd])
2034- self.assertSortedEqual((ret[0], map(str, ret[1])), (0, map(str, values[n+1:])), level=2)
2035+ self.assertSortedEqual((ret[0], list(map(str, ret[1]))), (0, list(map(str, values[n+1:]))), level=2)
2036
2037 def jailAddDelRegexTest(self, cmd, inValues, outValues, jail):
2038 cmdAdd = "add" + cmd
2039@@ -930,7 +930,7 @@ class TransmitterLogging(TransmitterBase):
2040
2041 def testLogTarget(self):
2042 logTargets = []
2043- for _ in xrange(3):
2044+ for _ in range(3):
2045 tmpFile = tempfile.mkstemp("fail2ban", "transmitter")
2046 logTargets.append(tmpFile[1])
2047 os.close(tmpFile[0])
2048@@ -1003,26 +1003,26 @@ class TransmitterLogging(TransmitterBase):
2049 self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "rolled over"))
2050 l.warning("After flushlogs")
2051 with open(fn2,'r') as f:
2052- line1 = f.next()
2053+ line1 = next(f)
2054 if line1.find('Changed logging target to') >= 0:
2055- line1 = f.next()
2056+ line1 = next(f)
2057 self.assertTrue(line1.endswith("Before file moved\n"))
2058- line2 = f.next()
2059+ line2 = next(f)
2060 self.assertTrue(line2.endswith("After file moved\n"))
2061 try:
2062- n = f.next()
2063+ n = next(f)
2064 if n.find("Command: ['flushlogs']") >=0:
2065- self.assertRaises(StopIteration, f.next)
2066+ self.assertRaises(StopIteration, f.__next__)
2067 else:
2068 self.fail("Exception StopIteration or Command: ['flushlogs'] expected. Got: %s" % n)
2069 except StopIteration:
2070 pass # on higher debugging levels this is expected
2071 with open(fn,'r') as f:
2072- line1 = f.next()
2073+ line1 = next(f)
2074 if line1.find('rollover performed on') >= 0:
2075- line1 = f.next()
2076+ line1 = next(f)
2077 self.assertTrue(line1.endswith("After flushlogs\n"))
2078- self.assertRaises(StopIteration, f.next)
2079+ self.assertRaises(StopIteration, f.__next__)
2080 f.close()
2081 finally:
2082 os.remove(fn2)
2083@@ -1185,7 +1185,7 @@ class LoggingTests(LogCaptureTestCase):
2084 os.remove(f)
2085
2086
2087-from clientreadertestcase import ActionReader, JailsReader, CONFIG_DIR
2088+from .clientreadertestcase import ActionReader, JailsReader, CONFIG_DIR
2089
2090 class ServerConfigReaderTests(LogCaptureTestCase):
2091
2092diff --git a/fail2ban/tests/sockettestcase.py b/fail2ban/tests/sockettestcase.py
2093index 69bf8d8b..60f49e57 100644
2094--- a/fail2ban/tests/sockettestcase.py
2095+++ b/fail2ban/tests/sockettestcase.py
2096@@ -153,7 +153,7 @@ class Socket(LogCaptureTestCase):
2097 org_handler = RequestHandler.found_terminator
2098 try:
2099 RequestHandler.found_terminator = lambda self: self.close()
2100- self.assertRaisesRegexp(RuntimeError, r"socket connection broken",
2101+ self.assertRaisesRegex(RuntimeError, r"socket connection broken",
2102 lambda: client.send(testMessage, timeout=unittest.F2B.maxWaitTime(10)))
2103 finally:
2104 RequestHandler.found_terminator = org_handler
2105diff --git a/fail2ban/tests/utils.py b/fail2ban/tests/utils.py
2106index fcfddba7..cb234e0d 100644
2107--- a/fail2ban/tests/utils.py
2108+++ b/fail2ban/tests/utils.py
2109@@ -35,7 +35,7 @@ import time
2110 import threading
2111 import unittest
2112
2113-from cStringIO import StringIO
2114+from io import StringIO
2115 from functools import wraps
2116
2117 from ..helpers import getLogger, str2LogLevel, getVerbosityFormat, uni_decode
2118@@ -174,8 +174,8 @@ def initProcess(opts):
2119
2120 # Let know the version
2121 if opts.verbosity != 0:
2122- print("Fail2ban %s test suite. Python %s. Please wait..." \
2123- % (version, str(sys.version).replace('\n', '')))
2124+ print(("Fail2ban %s test suite. Python %s. Please wait..." \
2125+ % (version, str(sys.version).replace('\n', ''))))
2126
2127 return opts;
2128
2129@@ -322,7 +322,7 @@ def initTests(opts):
2130 c = DNSUtils.CACHE_ipToName
2131 # increase max count and max time (too many entries, long time testing):
2132 c.setOptions(maxCount=10000, maxTime=5*60)
2133- for i in xrange(256):
2134+ for i in range(256):
2135 c.set('192.0.2.%s' % i, None)
2136 c.set('198.51.100.%s' % i, None)
2137 c.set('203.0.113.%s' % i, None)
2138@@ -541,8 +541,8 @@ def gatherTests(regexps=None, opts=None):
2139 import difflib, pprint
2140 if not hasattr(unittest.TestCase, 'assertDictEqual'):
2141 def assertDictEqual(self, d1, d2, msg=None):
2142- self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
2143- self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
2144+ self.assertTrue(isinstance(d1, dict), 'First argument is not a dictionary')
2145+ self.assertTrue(isinstance(d2, dict), 'Second argument is not a dictionary')
2146 if d1 != d2:
2147 standardMsg = '%r != %r' % (d1, d2)
2148 diff = ('\n' + '\n'.join(difflib.ndiff(
2149@@ -560,7 +560,7 @@ def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None):
2150 # used to recognize having element as nested dict, list or tuple:
2151 def _is_nested(v):
2152 if isinstance(v, dict):
2153- return any(isinstance(v, (dict, list, tuple)) for v in v.itervalues())
2154+ return any(isinstance(v, (dict, list, tuple)) for v in v.values())
2155 return any(isinstance(v, (dict, list, tuple)) for v in v)
2156 # level comparison routine:
2157 def _assertSortedEqual(a, b, level, nestedOnly, key):
2158@@ -573,7 +573,7 @@ def assertSortedEqual(self, a, b, level=1, nestedOnly=True, key=repr, msg=None):
2159 return
2160 raise ValueError('%r != %r' % (a, b))
2161 if isinstance(a, dict) and isinstance(b, dict): # compare dict's:
2162- for k, v1 in a.iteritems():
2163+ for k, v1 in a.items():
2164 v2 = b[k]
2165 if isinstance(v1, (dict, list, tuple)) and isinstance(v2, (dict, list, tuple)):
2166 _assertSortedEqual(v1, v2, level-1 if level != 0 else 0, nestedOnly, key)
2167@@ -608,14 +608,14 @@ if not hasattr(unittest.TestCase, 'assertRaisesRegexp'):
2168 self.fail('\"%s\" does not match \"%s\"' % (regexp, e))
2169 else:
2170 self.fail('%s not raised' % getattr(exccls, '__name__'))
2171- unittest.TestCase.assertRaisesRegexp = assertRaisesRegexp
2172+ unittest.TestCase.assertRaisesRegex = assertRaisesRegexp
2173
2174 # always custom following methods, because we use atm better version of both (support generators)
2175 if True: ## if not hasattr(unittest.TestCase, 'assertIn'):
2176 def assertIn(self, a, b, msg=None):
2177 bb = b
2178 wrap = False
2179- if msg is None and hasattr(b, '__iter__') and not isinstance(b, basestring):
2180+ if msg is None and hasattr(b, '__iter__') and not isinstance(b, str):
2181 b, bb = itertools.tee(b)
2182 wrap = True
2183 if a not in b:
2184@@ -626,7 +626,7 @@ if True: ## if not hasattr(unittest.TestCase, 'assertIn'):
2185 def assertNotIn(self, a, b, msg=None):
2186 bb = b
2187 wrap = False
2188- if msg is None and hasattr(b, '__iter__') and not isinstance(b, basestring):
2189+ if msg is None and hasattr(b, '__iter__') and not isinstance(b, str):
2190 b, bb = itertools.tee(b)
2191 wrap = True
2192 if a in b:
2193diff --git a/setup.py b/setup.py
2194deleted file mode 100755
2195index ce1eedf6..00000000
2196--- a/setup.py
2197+++ /dev/null
2198@@ -1,326 +0,0 @@
2199-#!/usr/bin/env python
2200-# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
2201-# vi: set ft=python sts=4 ts=4 sw=4 noet :
2202-
2203-# This file is part of Fail2Ban.
2204-#
2205-# Fail2Ban is free software; you can redistribute it and/or modify
2206-# it under the terms of the GNU General Public License as published by
2207-# the Free Software Foundation; either version 2 of the License, or
2208-# (at your option) any later version.
2209-#
2210-# Fail2Ban is distributed in the hope that it will be useful,
2211-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2212-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2213-# GNU General Public License for more details.
2214-#
2215-# You should have received a copy of the GNU General Public License
2216-# along with Fail2Ban; if not, write to the Free Software
2217-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2218-
2219-__author__ = "Cyril Jaquier, Steven Hiscocks, Yaroslav Halchenko"
2220-__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2008-2016 Fail2Ban Contributors"
2221-__license__ = "GPL"
2222-
2223-import platform
2224-
2225-try:
2226- import setuptools
2227- from setuptools import setup
2228- from setuptools.command.install import install
2229- from setuptools.command.install_scripts import install_scripts
2230-except ImportError:
2231- setuptools = None
2232- from distutils.core import setup
2233-
2234-# all versions
2235-from distutils.command.build_py import build_py
2236-from distutils.command.build_scripts import build_scripts
2237-if setuptools is None:
2238- from distutils.command.install import install
2239- from distutils.command.install_scripts import install_scripts
2240-try:
2241- # python 3.x
2242- from distutils.command.build_py import build_py_2to3
2243- from distutils.command.build_scripts import build_scripts_2to3
2244- _2to3 = True
2245-except ImportError:
2246- # python 2.x
2247- _2to3 = False
2248-
2249-import os
2250-from os.path import isfile, join, isdir, realpath
2251-import re
2252-import sys
2253-import warnings
2254-from glob import glob
2255-
2256-from fail2ban.setup import updatePyExec
2257-
2258-
2259-source_dir = os.path.realpath(os.path.dirname(
2260- # __file__ seems to be overwritten sometimes on some python versions (e.g. bug of 2.6 by running under cProfile, etc.):
2261- sys.argv[0] if os.path.basename(sys.argv[0]) == 'setup.py' else __file__
2262-))
2263-
2264-# Wrapper to install python binding (to current python version):
2265-class install_scripts_f2b(install_scripts):
2266-
2267- def get_outputs(self):
2268- outputs = install_scripts.get_outputs(self)
2269- # setup.py --dry-run install:
2270- dry_run = not outputs
2271- self.update_scripts(dry_run)
2272- if dry_run:
2273- #bindir = self.install_dir
2274- bindir = self.build_dir
2275- print('creating fail2ban-python binding -> %s (dry-run, real path can be different)' % (bindir,))
2276- print('Copying content of %s to %s' % (self.build_dir, self.install_dir));
2277- return outputs
2278- fn = None
2279- for fn in outputs:
2280- if os.path.basename(fn) == 'fail2ban-server':
2281- break
2282- bindir = os.path.dirname(fn)
2283- print('creating fail2ban-python binding -> %s' % (bindir,))
2284- updatePyExec(bindir)
2285- return outputs
2286-
2287- def update_scripts(self, dry_run=False):
2288- buildroot = os.path.dirname(self.build_dir)
2289- install_dir = self.install_dir
2290- try:
2291- # remove root-base from install scripts path:
2292- root = self.distribution.command_options['install']['root'][1]
2293- if install_dir.startswith(root):
2294- install_dir = install_dir[len(root):]
2295- except: # pragma: no cover
2296- print('WARNING: Cannot find root-base option, check the bin-path to fail2ban-scripts in "fail2ban.service".')
2297- print('Creating %s/fail2ban.service (from fail2ban.service.in): @BINDIR@ -> %s' % (buildroot, install_dir))
2298- with open(os.path.join(source_dir, 'files/fail2ban.service.in'), 'r') as fn:
2299- lines = fn.readlines()
2300- fn = None
2301- if not dry_run:
2302- fn = open(os.path.join(buildroot, 'fail2ban.service'), 'w')
2303- try:
2304- for ln in lines:
2305- ln = re.sub(r'@BINDIR@', lambda v: install_dir, ln)
2306- if dry_run:
2307- sys.stdout.write(' | ' + ln)
2308- continue
2309- fn.write(ln)
2310- finally:
2311- if fn: fn.close()
2312- if dry_run:
2313- print(' `')
2314-
2315-
2316-# Wrapper to specify fail2ban own options:
2317-class install_command_f2b(install):
2318- user_options = install.user_options + [
2319- ('disable-2to3', None, 'Specify to deactivate 2to3, e.g. if the install runs from fail2ban test-cases.'),
2320- ('without-tests', None, 'without tests files installation'),
2321- ]
2322- def initialize_options(self):
2323- self.disable_2to3 = None
2324- self.without_tests = None
2325- install.initialize_options(self)
2326- def finalize_options(self):
2327- global _2to3
2328- ## in the test cases 2to3 should be already done (fail2ban-2to3):
2329- if self.disable_2to3:
2330- _2to3 = False
2331- if _2to3:
2332- cmdclass = self.distribution.cmdclass
2333- cmdclass['build_py'] = build_py_2to3
2334- cmdclass['build_scripts'] = build_scripts_2to3
2335- if self.without_tests:
2336- self.distribution.scripts.remove('bin/fail2ban-testcases')
2337-
2338- self.distribution.packages.remove('fail2ban.tests')
2339- self.distribution.packages.remove('fail2ban.tests.action_d')
2340-
2341- del self.distribution.package_data['fail2ban.tests']
2342- install.finalize_options(self)
2343- def run(self):
2344- install.run(self)
2345-
2346-
2347-# Update fail2ban-python env to current python version (where f2b-modules located/installed)
2348-updatePyExec(os.path.join(source_dir, 'bin'))
2349-
2350-if setuptools and "test" in sys.argv:
2351- import logging
2352- logSys = logging.getLogger("fail2ban")
2353- hdlr = logging.StreamHandler(sys.stdout)
2354- fmt = logging.Formatter("%(asctime)-15s %(message)s")
2355- hdlr.setFormatter(fmt)
2356- logSys.addHandler(hdlr)
2357- if set(["-q", "--quiet"]) & set(sys.argv):
2358- logSys.setLevel(logging.CRITICAL)
2359- warnings.simplefilter("ignore")
2360- sys.warnoptions.append("ignore")
2361- elif set(["-v", "--verbose"]) & set(sys.argv):
2362- logSys.setLevel(logging.DEBUG)
2363- else:
2364- logSys.setLevel(logging.INFO)
2365-elif "test" in sys.argv:
2366- print("python distribute required to execute fail2ban tests")
2367- print("")
2368-
2369-longdesc = '''
2370-Fail2Ban scans log files like /var/log/pwdfail or
2371-/var/log/apache/error_log and bans IP that makes
2372-too many password failures. It updates firewall rules
2373-to reject the IP address or executes user defined
2374-commands.'''
2375-
2376-if setuptools:
2377- setup_extra = {
2378- 'test_suite': "fail2ban.tests.utils.gatherTests",
2379- 'use_2to3': True,
2380- }
2381-else:
2382- setup_extra = {}
2383-
2384-data_files_extra = []
2385-if os.path.exists('/var/run'):
2386- # if we are on the system with /var/run -- we are to use it for having fail2ban/
2387- # directory there for socket file etc.
2388- # realpath is used to possibly resolve /var/run -> /run symlink
2389- data_files_extra += [(realpath('/var/run/fail2ban'), '')]
2390-
2391-# Installing documentation files only under Linux or other GNU/ systems
2392-# (e.g. GNU/kFreeBSD), since others might have protective mechanisms forbidding
2393-# installation there (see e.g. #1233)
2394-platform_system = platform.system().lower()
2395-doc_files = ['README.md', 'DEVELOP', 'FILTERS', 'doc/run-rootless.txt']
2396-if platform_system in ('solaris', 'sunos'):
2397- doc_files.append('README.Solaris')
2398-if platform_system in ('linux', 'solaris', 'sunos') or platform_system.startswith('gnu'):
2399- data_files_extra.append(
2400- ('/usr/share/doc/fail2ban', doc_files)
2401- )
2402-
2403-# Get version number, avoiding importing fail2ban.
2404-# This is due to tests not functioning for python3 as 2to3 takes place later
2405-exec(open(join("fail2ban", "version.py")).read())
2406-
2407-setup(
2408- name = "fail2ban",
2409- version = version,
2410- description = "Ban IPs that make too many password failures",
2411- long_description = longdesc,
2412- author = "Cyril Jaquier & Fail2Ban Contributors",
2413- author_email = "cyril.jaquier@fail2ban.org",
2414- url = "http://www.fail2ban.org",
2415- license = "GPL",
2416- platforms = "Posix",
2417- cmdclass = {
2418- 'build_py': build_py, 'build_scripts': build_scripts,
2419- 'install_scripts': install_scripts_f2b, 'install': install_command_f2b
2420- },
2421- scripts = [
2422- 'bin/fail2ban-client',
2423- 'bin/fail2ban-server',
2424- 'bin/fail2ban-regex',
2425- 'bin/fail2ban-testcases',
2426- # 'bin/fail2ban-python', -- link (binary), will be installed via install_scripts_f2b wrapper
2427- ],
2428- packages = [
2429- 'fail2ban',
2430- 'fail2ban.client',
2431- 'fail2ban.server',
2432- 'fail2ban.tests',
2433- 'fail2ban.tests.action_d',
2434- ],
2435- package_data = {
2436- 'fail2ban.tests':
2437- [ join(w[0], f).replace("fail2ban/tests/", "", 1)
2438- for w in os.walk('fail2ban/tests/files')
2439- for f in w[2]] +
2440- [ join(w[0], f).replace("fail2ban/tests/", "", 1)
2441- for w in os.walk('fail2ban/tests/config')
2442- for f in w[2]] +
2443- [ join(w[0], f).replace("fail2ban/tests/", "", 1)
2444- for w in os.walk('fail2ban/tests/action_d')
2445- for f in w[2]]
2446- },
2447- data_files = [
2448- ('/etc/fail2ban',
2449- glob("config/*.conf")
2450- ),
2451- ('/etc/fail2ban/filter.d',
2452- glob("config/filter.d/*.conf")
2453- ),
2454- ('/etc/fail2ban/filter.d/ignorecommands',
2455- [p for p in glob("config/filter.d/ignorecommands/*") if isfile(p)]
2456- ),
2457- ('/etc/fail2ban/action.d',
2458- glob("config/action.d/*.conf") +
2459- glob("config/action.d/*.py")
2460- ),
2461- ('/etc/fail2ban/fail2ban.d',
2462- ''
2463- ),
2464- ('/etc/fail2ban/jail.d',
2465- ''
2466- ),
2467- ('/var/lib/fail2ban',
2468- ''
2469- ),
2470- ] + data_files_extra,
2471- **setup_extra
2472-)
2473-
2474-# Do some checks after installation
2475-# Search for obsolete files.
2476-obsoleteFiles = []
2477-elements = {
2478- "/etc/":
2479- [
2480- "fail2ban.conf"
2481- ],
2482- "/usr/bin/":
2483- [
2484- "fail2ban.py"
2485- ],
2486- "/usr/lib/fail2ban/":
2487- [
2488- "version.py",
2489- "protocol.py"
2490- ]
2491-}
2492-
2493-for directory in elements:
2494- for f in elements[directory]:
2495- path = join(directory, f)
2496- if isfile(path):
2497- obsoleteFiles.append(path)
2498-
2499-if obsoleteFiles:
2500- print("")
2501- print("Obsolete files from previous Fail2Ban versions were found on "
2502- "your system.")
2503- print("Please delete them:")
2504- print("")
2505- for f in obsoleteFiles:
2506- print("\t" + f)
2507- print("")
2508-
2509-if isdir("/usr/lib/fail2ban"):
2510- print("")
2511- print("Fail2ban is not installed under /usr/lib anymore. The new "
2512- "location is under /usr/share. Please remove the directory "
2513- "/usr/lib/fail2ban and everything under this directory.")
2514- print("")
2515-
2516-# Update config file
2517-if sys.argv[1] == "install":
2518- print("")
2519- print("Please do not forget to update your configuration files.")
2520- print("They are in \"/etc/fail2ban/\".")
2521- print("")
2522- print("You can also install systemd service-unit file from \"build/fail2ban.service\"")
2523- print("resp. corresponding init script from \"files/*-initd\".")
2524- print("")
2525--
25262.17.1
2527