From 7989e662702c2c6897cf078e2a7e7346e6729872 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Wed, 4 Oct 2006 22:17:53 +0000 Subject: [PATCH] - Added "-s" option to specify the socket path - Modified the server server/socket/transmitter design git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@406 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- CHANGELOG | 1 + client/csocket.py | 5 ++--- fail2ban-client | 22 ++++++++++++---------- fail2ban-server | 8 ++++++-- man/fail2ban-client.1 | 3 +++ man/fail2ban-server.1 | 3 +++ server/server.py | 15 ++++++++++++--- server/ssocket.py | 17 +++++++++-------- server/transmitter.py | 29 ----------------------------- 9 files changed, 48 insertions(+), 55 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e9fac9e8..4dfe51c4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,7 @@ ver. 0.7.4 (2006/09/28) - beta - Improved configuration files. Thanks to Yaroslav Halchenko - Added man page for "fail2ban-regex" - Moved ban/unban messages from "info" level to "warn" +- Added "-s" option to specify the socket path ver. 0.7.3 (2006/09/28) - beta ---------- diff --git a/client/csocket.py b/client/csocket.py index 4ab3da80..33477ecf 100644 --- a/client/csocket.py +++ b/client/csocket.py @@ -30,14 +30,13 @@ import socket class CSocket: END_STRING = "" - SOCKET_FILE = "/tmp/fail2ban.sock" - def __init__(self): + def __init__(self, sock = "/tmp/fail2ban.sock"): # Create an INET, STREAMing socket #self.csock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__csock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) #self.csock.connect(("localhost", 2222)) - self.__csock.connect(CSocket.SOCKET_FILE) + self.__csock.connect(sock) def send(self, msg): # Convert every list member to string diff --git a/fail2ban-client b/fail2ban-client index 450f5cf4..fdb6da39 100755 --- a/fail2ban-client +++ b/fail2ban-client @@ -58,6 +58,7 @@ class Fail2banClient: self.__conf["force"] = False self.__conf["verbose"] = 2 self.__conf["interactive"] = False + self.__conf["socket"] = "/tmp/fail2ban.sock" def dispVersion(self): print "Fail2Ban v" + version @@ -79,6 +80,7 @@ class Fail2banClient: print print "Options:" print " -c configuration directory" + print " -s socket path" print " -d dump configuration. For debugging" print " -i interactive mode" print " -v increase verbosity" @@ -118,6 +120,8 @@ class Fail2banClient: for opt in optList: if opt[0] == "-c": self.__conf["conf"] = opt[1] + elif opt[0] == "-s": + self.__conf["socket"] = opt[1] elif opt[0] == "-d": self.__conf["dump"] = True elif opt[0] == "-v": @@ -136,15 +140,14 @@ class Fail2banClient: sys.exit(0) def __ping(self): - return self.processCmd([["ping"]], False) + return self.__processCmd([["ping"]], False) - @staticmethod - def processCmd(cmd, showRet = True): + def __processCmd(self, cmd, showRet = True): beautifier = Beautifier() for c in cmd: beautifier.setInputCmd(c) try: - client = CSocket() + client = CSocket(self.__conf["socket"]) ret = client.send(c) if ret[0] == 0: logSys.debug("OK : " + `ret[1]`) @@ -183,7 +186,7 @@ class Fail2banClient: # Wait for the server to start self.__waitOnServer() # Configure the server - self.processCmd(self.__stream, False) + self.__processCmd(self.__stream, False) return True except ServerExecutionException: logSys.error("Could not start server. Try -x option") @@ -191,14 +194,14 @@ class Fail2banClient: elif len(cmd) == 1 and cmd[0] == "reload": if self.__ping(): self.__readConfig() - self.processCmd([['stop', 'all']], False) + self.__processCmd([['stop', 'all']], False) # Configure the server - return self.processCmd(self.__stream, False) + return self.__processCmd(self.__stream, False) else: logSys.error("Could not find server") return False else: - return self.processCmd([cmd]) + return self.__processCmd([cmd]) ## @@ -244,7 +247,7 @@ class Fail2banClient: # Reads the command line options. try: - cmdOpts = 'hc:xdviqV' + cmdOpts = 'hc:s:xdviqV' cmdLongOpts = ['help', 'version'] optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts) except getopt.GetoptError: @@ -327,4 +330,3 @@ if __name__ == "__main__": sys.exit(0) else: sys.exit(-1) - diff --git a/fail2ban-server b/fail2ban-server index 41c0f4fb..c7877971 100755 --- a/fail2ban-server +++ b/fail2ban-server @@ -50,6 +50,7 @@ class Fail2banServer: self.__conf = dict() self.__conf["background"] = True self.__conf["force"] = False + self.__conf["socket"] = "/tmp/fail2ban.sock" def dispVersion(self): print "Fail2Ban v" + version @@ -75,6 +76,7 @@ class Fail2banServer: print "Options:" print " -b start in background" print " -f start in foreground" + print " -s socket path" print " -x force execution of the server" print " -h, --help display this help message" print " -V, --version print the version" @@ -89,6 +91,8 @@ class Fail2banServer: self.__conf["background"] = True if opt[0] == "-f": self.__conf["background"] = False + if opt[0] == "-s": + self.__conf["socket"] = opt[1] if opt[0] == "-x": self.__conf["force"] = True if opt[0] in ["-h", "--help"]: @@ -104,7 +108,7 @@ class Fail2banServer: # Reads the command line options. try: - cmdOpts = 'bfxhV' + cmdOpts = 'bfs:xhV' cmdLongOpts = ['help', 'version'] optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts) except getopt.GetoptError: @@ -114,7 +118,7 @@ class Fail2banServer: try: self.__server = Server(self.__conf["background"]) - self.__server.start(self.__conf["force"]) + self.__server.start(self.__conf["socket"], self.__conf["force"]) return True except Exception, e: print e diff --git a/man/fail2ban-client.1 b/man/fail2ban-client.1 index 13abfd71..6833de5d 100644 --- a/man/fail2ban-client.1 +++ b/man/fail2ban-client.1 @@ -13,6 +13,9 @@ and bans the corresponding IP addresses using firewall rules. \fB\-c\fR configuration directory .TP +\fB\-s\fR +socket path +.TP \fB\-d\fR dump configuration. For debugging .TP diff --git a/man/fail2ban-server.1 b/man/fail2ban-server.1 index db9329c8..bcdcc0dd 100644 --- a/man/fail2ban-server.1 +++ b/man/fail2ban-server.1 @@ -19,6 +19,9 @@ start in background \fB\-f\fR start in foreground .TP +\fB\-s\fR +socket path +.TP \fB\-x\fR force execution of the server .TP diff --git a/server/server.py b/server/server.py index 932d8e86..fb035eb5 100644 --- a/server/server.py +++ b/server/server.py @@ -26,6 +26,8 @@ __license__ = "GPL" from jails import Jails from transmitter import Transmitter +from ssocket import SSocket +from ssocket import SSocketErrorException import logging, logging.handlers, sys, os, signal # Gets the instance of the logger. @@ -37,13 +39,14 @@ class Server: self.__jails = Jails() self.__daemon = daemon self.__transm = Transmitter(self) + self.__socket = SSocket(self.__transm) self.__logLevel = 3 self.__logTarget = "STDOUT" # Set logging level self.setLogLevel(self.__logLevel) self.setLogTarget(self.__logTarget) - def start(self, force): + def start(self, sock, force = False): logSys.info("Starting Fail2ban") # First set the mask to only allow access to owner os.umask(0077) @@ -56,12 +59,18 @@ class Server: raise ServerInitializationError("Could not create daemon") # Start the communication logSys.debug("Starting communication") - self.__transm.start(force) + try: + self.__socket.initialize(sock, force) + self.__socket.start() + self.__socket.join() + except SSocketErrorException: + logSys.error("Could not start server") logSys.info("Exiting Fail2ban") def quit(self): self.stopAllJail() - self.__transm.stop() + # Stop communication + self.__socket.stop() def addJail(self, name): self.__jails.add(name) diff --git a/server/ssocket.py b/server/ssocket.py index 59d0c5e9..26511d29 100644 --- a/server/ssocket.py +++ b/server/ssocket.py @@ -34,21 +34,22 @@ logSys = logging.getLogger("fail2ban.comm") class SSocket(Thread): END_STRING = "" - SOCKET_FILE = "/tmp/fail2ban.sock" def __init__(self, transmitter): Thread.__init__(self) self.__transmit = transmitter self.__isRunning = False + self.__socket = "/tmp/fail2ban.sock" logSys.debug("Created SSocket") - def initialize(self, force = False): + def initialize(self, sock = "/tmp/fail2ban.sock", force = False): + self.__socket = sock # Remove socket - if os.path.exists(SSocket.SOCKET_FILE): + if os.path.exists(sock): logSys.error("Fail2ban seems to be already running") if force: logSys.warn("Forcing execution of the server") - os.remove(SSocket.SOCKET_FILE) + os.remove(sock) else: raise SSocketErrorException("Server already running") # Create an INET, STREAMing socket @@ -62,7 +63,7 @@ class SSocket(Thread): self.ssock.settimeout(1) # Bind the socket to a public host and a well-known port #self.ssock.bind(("localhost", 2222)) - self.ssock.bind(SSocket.SOCKET_FILE) + self.ssock.bind(sock) # Become a server socket self.ssock.listen(5) @@ -78,9 +79,9 @@ class SSocket(Thread): pass self.ssock.close() # Remove socket - if os.path.exists(SSocket.SOCKET_FILE): - logSys.debug("Removed socket file " + SSocket.SOCKET_FILE) - os.remove(SSocket.SOCKET_FILE) + if os.path.exists(self.__socket): + logSys.debug("Removed socket file " + self.__socket) + os.remove(self.__socket) logSys.debug("Socket shutdown") return True diff --git a/server/transmitter.py b/server/transmitter.py index 8740fa55..a326fccf 100644 --- a/server/transmitter.py +++ b/server/transmitter.py @@ -24,8 +24,6 @@ __date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -from ssocket import SSocket -from ssocket import SSocketErrorException from threading import Lock import logging, time @@ -37,33 +35,6 @@ class Transmitter: def __init__(self, server): self.__lock = Lock() self.__server = server - self.__socket = SSocket(self) - - ## - # Start the transmittion server. - # - # This function wait for the socket thread. - - def start(self, force): - try: - self.__lock.acquire() - self.__socket.initialize(force) - self.__socket.start() - self.__lock.release() - self.__socket.join() - except SSocketErrorException: - logSys.error("Could not start server") - self.__lock.release() - - ## - # Stop the transmitter. - # - # @bug Fix the issue with join(). When using servertestcase.py, errors - # happen which disappear when using join() in this function. - - def stop(self): - self.__socket.stop() - self.__socket.join() def proceed(self, action): # Deserialize object