mirror of https://github.com/fail2ban/fail2ban
code review
parent
5c1d01bf58
commit
16a84ca0b5
|
@ -895,7 +895,7 @@ class FileFilter(Filter):
|
||||||
# see http://python.org/dev/peps/pep-3151/
|
# see http://python.org/dev/peps/pep-3151/
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
logSys.error("Unable to open %s", filename)
|
logSys.error("Unable to open %s", filename)
|
||||||
if e.errno != 2:
|
if e.errno != 2: # errno.ENOENT
|
||||||
logSys.exception(e)
|
logSys.exception(e)
|
||||||
return False
|
return False
|
||||||
except OSError as e: # pragma: no cover - requires race condition to tigger this
|
except OSError as e: # pragma: no cover - requires race condition to tigger this
|
||||||
|
|
|
@ -89,23 +89,12 @@ class FilterPyinotify(FileFilter):
|
||||||
logSys.log(7, "[%s] %sCallback for Event: %s", self.jailName, origin, event)
|
logSys.log(7, "[%s] %sCallback for Event: %s", self.jailName, origin, event)
|
||||||
path = event.pathname
|
path = event.pathname
|
||||||
# check watching of this path:
|
# check watching of this path:
|
||||||
isWF = isWD = False
|
isWF = False
|
||||||
if path in self.__watchDirs:
|
isWD = path in self.__watchDirs
|
||||||
isWD = True
|
if not isWD and path in self.__watchFiles:
|
||||||
elif path in self.__watchFiles:
|
|
||||||
isWF = True
|
isWF = True
|
||||||
# fix pyinotify behavior with '-unknown-path' (if target not watched also):
|
|
||||||
if (event.mask & pyinotify.IN_MOVE_SELF and
|
|
||||||
path.endswith('-unknown-path') and not isWF and not isWD
|
|
||||||
):
|
|
||||||
path = path[:-len('-unknown-path')]
|
|
||||||
isWD = path in self.__watchDirs
|
|
||||||
assumeNoDir = False
|
assumeNoDir = False
|
||||||
if event.mask & ( pyinotify.IN_CREATE | pyinotify.IN_MOVED_TO ):
|
if event.mask & ( pyinotify.IN_CREATE | pyinotify.IN_MOVED_TO ):
|
||||||
# refresh watched dir (may be expected):
|
|
||||||
if isWD:
|
|
||||||
self._refreshWatcher(path, isDir=True)
|
|
||||||
return
|
|
||||||
# skip directories altogether
|
# skip directories altogether
|
||||||
if event.mask & pyinotify.IN_ISDIR:
|
if event.mask & pyinotify.IN_ISDIR:
|
||||||
logSys.debug("Ignoring creation of directory %s", path)
|
logSys.debug("Ignoring creation of directory %s", path)
|
||||||
|
@ -116,8 +105,14 @@ class FilterPyinotify(FileFilter):
|
||||||
return
|
return
|
||||||
self._refreshWatcher(path)
|
self._refreshWatcher(path)
|
||||||
elif event.mask & (pyinotify.IN_IGNORED | pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF):
|
elif event.mask & (pyinotify.IN_IGNORED | pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF):
|
||||||
# watch was removed for some reasons (log-rotate?):
|
|
||||||
assumeNoDir = event.mask & (pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF)
|
assumeNoDir = event.mask & (pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF)
|
||||||
|
# fix pyinotify behavior with '-unknown-path' (if target not watched also):
|
||||||
|
if (assumeNoDir and
|
||||||
|
path.endswith('-unknown-path') and not isWF and not isWD
|
||||||
|
):
|
||||||
|
path = path[:-len('-unknown-path')]
|
||||||
|
isWD = path in self.__watchDirs
|
||||||
|
# watch was removed for some reasons (log-rotate?):
|
||||||
if isWD and (assumeNoDir or not os.path.isdir(path)):
|
if isWD and (assumeNoDir or not os.path.isdir(path)):
|
||||||
self._addPending(path, event, isDir=True)
|
self._addPending(path, event, isDir=True)
|
||||||
elif not isWF:
|
elif not isWF:
|
||||||
|
@ -153,7 +148,7 @@ class FilterPyinotify(FileFilter):
|
||||||
|
|
||||||
def _addPending(self, path, reason, isDir=False):
|
def _addPending(self, path, reason, isDir=False):
|
||||||
if path not in self.__pending:
|
if path not in self.__pending:
|
||||||
self.__pending[path] = [self.sleeptime / 10, isDir];
|
self.__pending[path] = [Utils.DEFAULT_SLEEP_INTERVAL, isDir];
|
||||||
self.__pendingNextTime = 0
|
self.__pendingNextTime = 0
|
||||||
if isinstance(reason, pyinotify.Event):
|
if isinstance(reason, pyinotify.Event):
|
||||||
reason = [reason.maskname, reason.pathname]
|
reason = [reason.maskname, reason.pathname]
|
||||||
|
@ -166,43 +161,49 @@ class FilterPyinotify(FileFilter):
|
||||||
except KeyError: pass
|
except KeyError: pass
|
||||||
|
|
||||||
def _checkPending(self):
|
def _checkPending(self):
|
||||||
if self.__pending:
|
if not self.__pending:
|
||||||
ntm = time.time()
|
return
|
||||||
if ntm > self.__pendingNextTime:
|
ntm = time.time()
|
||||||
found = {}
|
if ntm < self.__pendingNextTime:
|
||||||
minTime = 60
|
return
|
||||||
for path, (retardTM, isDir) in self.__pending.iteritems():
|
found = {}
|
||||||
if ntm - self.__pendingChkTime < retardTM:
|
minTime = 60
|
||||||
if minTime > retardTM: minTime = retardTM
|
for path, (retardTM, isDir) in self.__pending.iteritems():
|
||||||
continue
|
if ntm - self.__pendingChkTime < retardTM:
|
||||||
chkpath = os.path.isdir if isDir else os.path.isfile
|
if minTime > retardTM: minTime = retardTM
|
||||||
if not chkpath(path): # not found - prolong for next time
|
continue
|
||||||
if retardTM < 60: retardTM *= 2
|
chkpath = os.path.isdir if isDir else os.path.isfile
|
||||||
if minTime > retardTM: minTime = retardTM
|
if not chkpath(path): # not found - prolong for next time
|
||||||
self.__pending[path][0] = retardTM
|
if retardTM < 60: retardTM *= 2
|
||||||
continue
|
if minTime > retardTM: minTime = retardTM
|
||||||
logSys.log(logging.MSG, "Log presence detected for %s %s",
|
self.__pending[path][0] = retardTM
|
||||||
"directory" if isDir else "file", path)
|
continue
|
||||||
found[path] = isDir
|
logSys.log(logging.MSG, "Log presence detected for %s %s",
|
||||||
for path in found:
|
"directory" if isDir else "file", path)
|
||||||
try:
|
found[path] = isDir
|
||||||
del self.__pending[path]
|
for path in found:
|
||||||
except KeyError: pass
|
try:
|
||||||
self.__pendingChkTime = time.time()
|
del self.__pending[path]
|
||||||
self.__pendingNextTime = self.__pendingChkTime + minTime
|
except KeyError: pass
|
||||||
# process now because we'he missed it in monitoring:
|
self.__pendingChkTime = time.time()
|
||||||
for path, isDir in found.iteritems():
|
self.__pendingNextTime = self.__pendingChkTime + minTime
|
||||||
self._refreshWatcher(path, isDir=isDir)
|
# process now because we've missed it in monitoring:
|
||||||
if isDir:
|
for path, isDir in found.iteritems():
|
||||||
for logpath in self.__watchFiles:
|
# refresh monitoring of this:
|
||||||
if logpath.startswith(path + pathsep):
|
self._refreshWatcher(path, isDir=isDir)
|
||||||
if not os.path.isfile(logpath):
|
if isDir:
|
||||||
self._addPending(logpath, ['FROM_PARDIR', path])
|
# check all files belong to this dir:
|
||||||
else:
|
for logpath in self.__watchFiles:
|
||||||
self._refreshWatcher(logpath)
|
if logpath.startswith(path + pathsep):
|
||||||
self._process_file(logpath)
|
# if still no file - add to pending, otherwise refresh and process:
|
||||||
else:
|
if not os.path.isfile(logpath):
|
||||||
self._process_file(path)
|
self._addPending(logpath, ('FROM_PARDIR', path))
|
||||||
|
else:
|
||||||
|
self._refreshWatcher(logpath)
|
||||||
|
self._process_file(logpath)
|
||||||
|
else:
|
||||||
|
# process (possibly no old events for it from watcher):
|
||||||
|
self._process_file(path)
|
||||||
|
|
||||||
def _refreshWatcher(self, oldPath, newPath=None, isDir=False):
|
def _refreshWatcher(self, oldPath, newPath=None, isDir=False):
|
||||||
if not newPath: newPath = oldPath
|
if not newPath: newPath = oldPath
|
||||||
|
@ -286,7 +287,7 @@ class FilterPyinotify(FileFilter):
|
||||||
def __process_default(self, event):
|
def __process_default(self, event):
|
||||||
try:
|
try:
|
||||||
self.callback(event, origin='Default ')
|
self.callback(event, origin='Default ')
|
||||||
except Exception as e:
|
except Exception as e: # pragma: no cover
|
||||||
logSys.error("Error in FilterPyinotify callback: %s",
|
logSys.error("Error in FilterPyinotify callback: %s",
|
||||||
e, exc_info=logSys.getEffectiveLevel() <= logging.DEBUG)
|
e, exc_info=logSys.getEffectiveLevel() <= logging.DEBUG)
|
||||||
self.ticks += 1
|
self.ticks += 1
|
||||||
|
@ -300,7 +301,7 @@ class FilterPyinotify(FileFilter):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# check pending files/dirs (logrotate ready):
|
# check pending files/dirs (logrotate ready):
|
||||||
if not self.idle:
|
if not self.idle and self.active:
|
||||||
self._checkPending()
|
self._checkPending()
|
||||||
|
|
||||||
self.ticks += 1
|
self.ticks += 1
|
||||||
|
|
Loading…
Reference in New Issue