mirror of https://github.com/fail2ban/fail2ban
Merge remote-tracking branch 'pr/167/head': FD_CLOEXEC bug fixes (filters) + support (actions). Avoid sockets descriptors leak.
* pr/167/head: FD_CLOEXEC supportpull/172/merge
commit
301460f451
|
@ -29,7 +29,7 @@ __license__ = "GPL"
|
||||||
|
|
||||||
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
||||||
from common import helpers
|
from common import helpers
|
||||||
import asyncore, asynchat, socket, os, logging, sys, traceback
|
import asyncore, asynchat, socket, os, logging, sys, traceback, fcntl
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger("fail2ban.server")
|
logSys = logging.getLogger("fail2ban.server")
|
||||||
|
@ -107,6 +107,7 @@ class AsyncServer(asyncore.dispatcher):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logSys.warning("Type error")
|
logSys.warning("Type error")
|
||||||
return
|
return
|
||||||
|
AsyncServer.__markCloseOnExec(conn)
|
||||||
# Creates an instance of the handler class to handle the
|
# Creates an instance of the handler class to handle the
|
||||||
# request/response on the incoming connection.
|
# request/response on the incoming connection.
|
||||||
RequestHandler(conn, self.__transmitter)
|
RequestHandler(conn, self.__transmitter)
|
||||||
|
@ -134,6 +135,7 @@ class AsyncServer(asyncore.dispatcher):
|
||||||
self.bind(sock)
|
self.bind(sock)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise AsyncServerException("Unable to bind socket %s" % self.__sock)
|
raise AsyncServerException("Unable to bind socket %s" % self.__sock)
|
||||||
|
AsyncServer.__markCloseOnExec(self.socket)
|
||||||
self.listen(1)
|
self.listen(1)
|
||||||
# Sets the init flag.
|
# Sets the init flag.
|
||||||
self.__init = True
|
self.__init = True
|
||||||
|
@ -159,6 +161,18 @@ class AsyncServer(asyncore.dispatcher):
|
||||||
os.remove(self.__sock)
|
os.remove(self.__sock)
|
||||||
logSys.debug("Socket shutdown")
|
logSys.debug("Socket shutdown")
|
||||||
|
|
||||||
|
##
|
||||||
|
# Marks socket as close-on-exec to avoid leaking file descriptors when
|
||||||
|
# running actions involving command execution.
|
||||||
|
|
||||||
|
# @param sock: socket file.
|
||||||
|
|
||||||
|
#@staticmethod
|
||||||
|
def __markCloseOnExec(sock):
|
||||||
|
fd = sock.fileno()
|
||||||
|
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||||
|
fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)
|
||||||
|
__markCloseOnExec = staticmethod(__markCloseOnExec)
|
||||||
|
|
||||||
##
|
##
|
||||||
# AsyncServerException is used to wrap communication exceptions.
|
# AsyncServerException is used to wrap communication exceptions.
|
||||||
|
|
|
@ -554,7 +554,8 @@ class FileContainer:
|
||||||
self.__handler = open(self.__filename)
|
self.__handler = open(self.__filename)
|
||||||
# Set the file descriptor to be FD_CLOEXEC
|
# Set the file descriptor to be FD_CLOEXEC
|
||||||
fd = self.__handler.fileno()
|
fd = self.__handler.fileno()
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFD, fd | fcntl.FD_CLOEXEC)
|
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||||
|
fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
|
||||||
firstLine = self.__handler.readline()
|
firstLine = self.__handler.readline()
|
||||||
# Computes the MD5 of the first line.
|
# Computes the MD5 of the first line.
|
||||||
myHash = md5sum(firstLine).digest()
|
myHash = md5sum(firstLine).digest()
|
||||||
|
|
|
@ -27,7 +27,7 @@ from failmanager import FailManagerEmpty
|
||||||
from filter import FileFilter
|
from filter import FileFilter
|
||||||
from mytime import MyTime
|
from mytime import MyTime
|
||||||
|
|
||||||
import time, logging, gamin
|
import time, logging, gamin, fcntl
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger("fail2ban.filter")
|
logSys = logging.getLogger("fail2ban.filter")
|
||||||
|
@ -52,6 +52,9 @@ class FilterGamin(FileFilter):
|
||||||
self.__modified = False
|
self.__modified = False
|
||||||
# Gamin monitor
|
# Gamin monitor
|
||||||
self.monitor = gamin.WatchMonitor()
|
self.monitor = gamin.WatchMonitor()
|
||||||
|
fd = self.monitor.get_fd()
|
||||||
|
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||||
|
fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)
|
||||||
logSys.debug("Created FilterGamin")
|
logSys.debug("Created FilterGamin")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue