- Improved synchronization

git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@452 a942ae1a-1317-0410-a47c-b1dcaea8d605
0.x
Cyril Jaquier 2006-11-06 22:48:46 +00:00
parent 7659452ade
commit cdf5ae19db
4 changed files with 292 additions and 234 deletions

View File

@ -27,7 +27,6 @@ __license__ = "GPL"
import Queue, logging import Queue, logging
from actions import Actions from actions import Actions
from threading import Lock
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.jail") logSys = logging.getLogger("fail2ban.jail")
@ -35,7 +34,6 @@ logSys = logging.getLogger("fail2ban.jail")
class Jail: class Jail:
def __init__(self, name, backend = "auto"): def __init__(self, name, backend = "auto"):
self.__lock = Lock()
self.__name = name self.__name = name
self.__queue = Queue.Queue() self.__queue = Queue.Queue()
self.__filter = None self.__filter = None
@ -61,89 +59,51 @@ class Jail:
self.__filter = FilterGamin(self) self.__filter = FilterGamin(self)
def setName(self, name): def setName(self, name):
self.__lock.acquire()
self.__name = name self.__name = name
self.__lock.release()
def getName(self): def getName(self):
try: return self.__name
self.__lock.acquire()
return self.__name
finally:
self.__lock.release()
def getFilter(self): def getFilter(self):
try: return self.__filter
self.__lock.acquire()
return self.__filter
finally:
self.__lock.release()
def getAction(self): def getAction(self):
try: return self.__action
self.__lock.acquire()
return self.__action
finally:
self.__lock.release()
def putFailTicket(self, ticket): def putFailTicket(self, ticket):
self.__lock.acquire()
self.__queue.put(ticket) self.__queue.put(ticket)
self.__lock.release()
def getFailTicket(self): def getFailTicket(self):
try: try:
self.__lock.acquire() return self.__queue.get(False)
try: except Queue.Empty:
return self.__queue.get(False) return False
except Queue.Empty:
return False
finally:
self.__lock.release()
def start(self): def start(self):
self.__lock.acquire()
self.__filter.start() self.__filter.start()
self.__action.start() self.__action.start()
self.__lock.release()
def stop(self): def stop(self):
self.__lock.acquire()
self.__filter.stop() self.__filter.stop()
self.__action.stop() self.__action.stop()
self.__lock.release()
self.__filter.join() self.__filter.join()
self.__action.join() self.__action.join()
def isActive(self): def isActive(self):
try: isActive0 = self.__filter.isActive()
self.__lock.acquire() isActive1 = self.__action.isActive()
isActive0 = self.__filter.isActive() return isActive0 or isActive1
isActive1 = self.__action.isActive()
return isActive0 or isActive1
finally:
self.__lock.release()
def setIdle(self, value): def setIdle(self, value):
self.__lock.acquire()
self.__filter.setIdle(value) self.__filter.setIdle(value)
self.__action.setIdle(value) self.__action.setIdle(value)
self.__lock.release()
def getIdle(self): def getIdle(self):
try: return self.__filter.getIdle() or self.__action.getIdle()
self.__lock.acquire()
return self.__filter.getIdle() or self.__action.getIdle()
finally:
self.__lock.release()
def getStatus(self): def getStatus(self):
try: fStatus = self.__filter.status()
self.__lock.acquire() aStatus = self.__action.status()
fStatus = self.__filter.status() ret = [("filter", fStatus),
aStatus = self.__action.status() ("action", aStatus)]
ret = [("filter", fStatus), return ret
("action", aStatus)]
return ret
finally:
self.__lock.release()

View File

@ -28,29 +28,63 @@ __license__ = "GPL"
from jail import Jail from jail import Jail
from threading import Lock from threading import Lock
##
# Handles the jails.
#
# This class handles the jails. Creation, deletion or access to a jail must be
# done through this class. This class is thread-safe which is not the case of
# the jail itself, including filter and actions.
class Jails: class Jails:
##
# Constructor.
def __init__(self): def __init__(self):
self.__lock = Lock() self.__lock = Lock()
self.__jails = dict() self.__jails = dict()
##
# Adds a jail.
#
# Adds a new jail which should use the given backend. Raises a
# <code>DuplicateJailException</code> if the jail is already defined.
# @param name The name of the jail
# @param backend The backend to use
def add(self, name, backend): def add(self, name, backend):
self.__lock.acquire() try:
if self.__jails.has_key(name): self.__lock.acquire()
self.__lock.release() if self.__jails.has_key(name):
raise DuplicateJailException(name) raise DuplicateJailException(name)
else: else:
self.__jails[name] = Jail(name, backend) self.__jails[name] = Jail(name, backend)
finally:
self.__lock.release() self.__lock.release()
##
# Removes a jail.
#
# Removes the jail <code>name</code>. Raise an <code>UnknownJailException</code>
# if the jail does not exist.
# @param name The name of the jail
def remove(self, name): def remove(self, name):
self.__lock.acquire() try:
if self.__jails.has_key(name): self.__lock.acquire()
del self.__jails[name] if self.__jails.has_key(name):
del self.__jails[name]
else:
raise UnknownJailException(name)
finally:
self.__lock.release() self.__lock.release()
else:
self.__lock.release() ##
raise UnknownJailException(name) # Returns a jail.
#
# Returns the jail <code>name</code>. Raise an <code>UnknownJailException</code>
# if the jail does not exist.
# @param name The name of the jail
def get(self, name): def get(self, name):
try: try:
@ -63,6 +97,13 @@ class Jails:
finally: finally:
self.__lock.release() self.__lock.release()
##
# Returns an action class instance.
#
# Returns the action object of the jail <code>name</code>. Raise an
# <code>UnknownJailException</code> if the jail does not exist.
# @param name The name of the jail
def getAction(self, name): def getAction(self, name):
try: try:
self.__lock.acquire() self.__lock.acquire()
@ -74,6 +115,13 @@ class Jails:
finally: finally:
self.__lock.release() self.__lock.release()
##
# Returns a filter class instance.
#
# Returns the filter object of the jail <code>name</code>. Raise an
# <code>UnknownJailException</code> if the jail does not exist.
# @param name The name of the jail
def getFilter(self, name): def getFilter(self, name):
try: try:
self.__lock.acquire() self.__lock.acquire()
@ -85,6 +133,11 @@ class Jails:
finally: finally:
self.__lock.release() self.__lock.release()
##
# Returns the jails.
#
# Returns a copy of the jails list.
def getAll(self): def getAll(self):
try: try:
self.__lock.acquire() self.__lock.acquire()
@ -92,6 +145,11 @@ class Jails:
finally: finally:
self.__lock.release() self.__lock.release()
##
# Returns the size of the jails.
#
# Returns the number of jails.
def size(self): def size(self):
try: try:
self.__lock.acquire() self.__lock.acquire()

View File

@ -24,6 +24,7 @@ __date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
from threading import Lock, RLock
from jails import Jails from jails import Jails
from transmitter import Transmitter from transmitter import Transmitter
from ssocket import SSocket from ssocket import SSocket
@ -36,6 +37,8 @@ logSys = logging.getLogger("fail2ban.server")
class Server: class Server:
def __init__(self, daemon = False): def __init__(self, daemon = False):
self.__loggingLock = Lock()
self.__lock = RLock()
self.__jails = Jails() self.__jails = Jails()
self.__daemon = daemon self.__daemon = daemon
self.__transm = Transmitter(self) self.__transm = Transmitter(self)
@ -91,17 +94,29 @@ class Server:
self.__jails.remove(name) self.__jails.remove(name)
def startJail(self, name): def startJail(self, name):
if not self.isActive(name): try:
self.__jails.get(name).start() self.__lock.acquire()
if not self.isActive(name):
self.__jails.get(name).start()
finally:
self.__lock.release()
def stopJail(self, name): def stopJail(self, name):
if self.isActive(name): try:
self.__jails.get(name).stop() self.__lock.acquire()
self.delJail(name) if self.isActive(name):
self.__jails.get(name).stop()
self.delJail(name)
finally:
self.__lock.release()
def stopAllJail(self): def stopAllJail(self):
for jail in self.__jails.getAll(): try:
self.stopJail(jail) self.__lock.acquire()
for jail in self.__jails.getAll():
self.stopJail(jail)
finally:
self.__lock.release()
def isActive(self, name): def isActive(self, name):
return self.__jails.get(name).isActive() return self.__jails.get(name).isActive()
@ -225,15 +240,19 @@ class Server:
# Status # Status
def status(self): def status(self):
jailList = '' try:
for jail in self.__jails.getAll(): self.__lock.acquire()
jailList += jail + ', ' jailList = ''
length = len(jailList) for jail in self.__jails.getAll():
if not length == 0: jailList += jail + ', '
jailList = jailList[:length-2] length = len(jailList)
ret = [("Number of jail", self.__jails.size()), if not length == 0:
("Jail list", jailList)] jailList = jailList[:length-2]
return ret ret = [("Number of jail", self.__jails.size()),
("Jail list", jailList)]
return ret
finally:
self.__lock.release()
def statusJail(self, name): def statusJail(self, name):
return self.__jails.get(name).getStatus() return self.__jails.get(name).getStatus()
@ -252,17 +271,21 @@ class Server:
# @param value the level # @param value the level
def setLogLevel(self, value): def setLogLevel(self, value):
self.__logLevel = value try:
logLevel = logging.DEBUG self.__loggingLock.acquire()
if value == 0: self.__logLevel = value
logLevel = logging.FATAL logLevel = logging.DEBUG
elif value == 1: if value == 0:
logLevel = logging.ERROR logLevel = logging.FATAL
elif value == 2: elif value == 1:
logLevel = logging.WARNING logLevel = logging.ERROR
elif value == 3: elif value == 2:
logLevel = logging.INFO logLevel = logging.WARNING
logging.getLogger("fail2ban").setLevel(logLevel) elif value == 3:
logLevel = logging.INFO
logging.getLogger("fail2ban").setLevel(logLevel)
finally:
self.__loggingLock.release()
## ##
# Get the logging level. # Get the logging level.
@ -271,35 +294,47 @@ class Server:
# @return the log level # @return the log level
def getLogLevel(self): def getLogLevel(self):
return self.__logLevel try:
self.__loggingLock.acquire()
return self.__logLevel
finally:
self.__loggingLock.release()
def setLogTarget(self, target): def setLogTarget(self, target):
# Remove previous handler try:
logging.getLogger("fail2ban").handlers = [] self.__loggingLock.acquire()
self.__logTarget = target # Remove previous handler
if target == "SYSLOG": logging.getLogger("fail2ban").handlers = []
hdlr = logging.handlers.SysLogHandler() if target == "SYSLOG":
elif target == "STDOUT": hdlr = logging.handlers.SysLogHandler()
hdlr = logging.StreamHandler(sys.stdout) elif target == "STDOUT":
elif target == "STDERR": hdlr = logging.StreamHandler(sys.stdout)
hdlr = logging.StreamHandler(sys.stderr) elif target == "STDERR":
else: hdlr = logging.StreamHandler(sys.stderr)
# Target should be a file else:
try: # Target should be a file
open(target, "a") try:
hdlr = logging.FileHandler(target) open(target, "a")
except IOError: hdlr = logging.FileHandler(target)
logSys.error("Unable to log to " + target) except IOError:
return False logSys.error("Unable to log to " + target)
# set a format which is simpler for console use return False
formatter = logging.Formatter("%(asctime)s %(name)-16s: %(levelname)-6s %(message)s") self.__logTarget = target
# tell the handler to use this format # set a format which is simpler for console use
hdlr.setFormatter(formatter) formatter = logging.Formatter("%(asctime)s %(name)-16s: %(levelname)-6s %(message)s")
logging.getLogger("fail2ban").addHandler(hdlr) # tell the handler to use this format
return True hdlr.setFormatter(formatter)
logging.getLogger("fail2ban").addHandler(hdlr)
return True
finally:
self.__loggingLock.release()
def getLogTarget(self): def getLogTarget(self):
return self.__logTarget try:
self.__loggingLock.acquire()
return self.__logTarget
finally:
self.__loggingLock.release()
def __createDaemon(self): def __createDaemon(self):
""" Detach a process from the controlling terminal and run it in the """ Detach a process from the controlling terminal and run it in the

View File

@ -24,7 +24,6 @@ __date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
from threading import Lock
import logging, time import logging, time
# Gets the instance of the logger. # Gets the instance of the logger.
@ -32,229 +31,235 @@ logSys = logging.getLogger("fail2ban.comm")
class Transmitter: class Transmitter:
##
# Constructor.
#
# @param The server reference
def __init__(self, server): def __init__(self, server):
self.__lock = Lock()
self.__server = server self.__server = server
def proceed(self, action): ##
# Proceeds a command.
#
# Proceeds an incoming command.
# @param command The incoming command
def proceed(self, command):
# Deserialize object # Deserialize object
logSys.debug("Command: " + `command`)
try: try:
self.__lock.acquire() ret = self.__commandHandler(command)
logSys.debug("Action: " + `action`) ack = 0, ret
try: except Exception, e:
ret = self.__actionHandler(action) logSys.warn("Invalid command: " + `command`)
ack = 0, ret ack = 1, e
except Exception, e: return ack
logSys.warn("Invalid command: " + `action`)
ack = 1, e
return ack
finally:
self.__lock.release()
## ##
# Handle an action. # Handle an command.
# #
# #
def __actionHandler(self, action): def __commandHandler(self, command):
if action[0] == "ping": if command[0] == "ping":
return "pong" return "pong"
elif action[0] == "add": elif command[0] == "add":
name = action[1] name = command[1]
if name == "all": if name == "all":
raise Exception("Reserved name") raise Exception("Reserved name")
try: try:
backend = action[2] backend = command[2]
except IndexError: except IndexError:
backend = "auto" backend = "auto"
self.__server.addJail(name, backend) self.__server.addJail(name, backend)
return name return name
elif action[0] == "start": elif command[0] == "start":
name = action[1] name = command[1]
self.__server.startJail(name) self.__server.startJail(name)
return None return None
elif action[0] == "stop": elif command[0] == "stop":
if len(action) == 1: if len(command) == 1:
self.__server.quit() self.__server.quit()
elif action[1] == "all": elif command[1] == "all":
self.__server.stopAllJail() self.__server.stopAllJail()
else: else:
name = action[1] name = command[1]
self.__server.stopJail(name) self.__server.stopJail(name)
return None return None
elif action[0] == "sleep": elif command[0] == "sleep":
value = action[1] value = command[1]
time.sleep(int(value)) time.sleep(int(value))
return None return None
elif action[0] == "set": elif command[0] == "set":
return self.__actionSet(action[1:]) return self.__commandSet(command[1:])
elif action[0] == "get": elif command[0] == "get":
return self.__actionGet(action[1:]) return self.__commandGet(command[1:])
elif action[0] == "status": elif command[0] == "status":
return self.status(action[1:]) return self.status(command[1:])
raise Exception("Invalid command") raise Exception("Invalid command")
def __actionSet(self, action): def __commandSet(self, command):
name = action[0] name = command[0]
# Logging # Logging
if name == "loglevel": if name == "loglevel":
value = int(action[1]) value = int(command[1])
self.__server.setLogLevel(value) self.__server.setLogLevel(value)
return self.__server.getLogLevel() return self.__server.getLogLevel()
elif name == "logtarget": elif name == "logtarget":
value = action[1] value = command[1]
self.__server.setLogTarget(value) self.__server.setLogTarget(value)
return self.__server.getLogTarget() return self.__server.getLogTarget()
# Jail # Jail
elif action[1] == "idle": elif command[1] == "idle":
if action[2] == "on": if command[2] == "on":
self.__server.setIdleJail(name, True) self.__server.setIdleJail(name, True)
elif action[2] == "off": elif command[2] == "off":
self.__server.setIdleJail(name, False) self.__server.setIdleJail(name, False)
return self.__server.getIdleJail(name) return self.__server.getIdleJail(name)
# Filter # Filter
elif action[1] == "addignoreip": elif command[1] == "addignoreip":
value = action[2] value = command[2]
self.__server.addIgnoreIP(name, value) self.__server.addIgnoreIP(name, value)
return self.__server.getIgnoreIP(name) return self.__server.getIgnoreIP(name)
elif action[1] == "delignoreip": elif command[1] == "delignoreip":
value = action[2] value = command[2]
self.__server.delIgnoreIP(name, value) self.__server.delIgnoreIP(name, value)
return self.__server.getIgnoreIP(name) return self.__server.getIgnoreIP(name)
elif action[1] == "addlogpath": elif command[1] == "addlogpath":
value = action[2:] value = command[2:]
for path in value: for path in value:
self.__server.addLogPath(name, path) self.__server.addLogPath(name, path)
return self.__server.getLogPath(name) return self.__server.getLogPath(name)
elif action[1] == "dellogpath": elif command[1] == "dellogpath":
value = action[2] value = command[2]
self.__server.delLogPath(name, value) self.__server.delLogPath(name, value)
return self.__server.getLogPath(name) return self.__server.getLogPath(name)
elif action[1] == "timeregex": elif command[1] == "timeregex":
value = action[2] value = command[2]
self.__server.setTimeRegex(name, value) self.__server.setTimeRegex(name, value)
return self.__server.getTimeRegex(name) return self.__server.getTimeRegex(name)
elif action[1] == "timepattern": elif command[1] == "timepattern":
value = action[2] value = command[2]
self.__server.setTimePattern(name, value) self.__server.setTimePattern(name, value)
return self.__server.getTimePattern(name) return self.__server.getTimePattern(name)
elif action[1] == "failregex": elif command[1] == "failregex":
value = action[2] value = command[2]
self.__server.setFailRegex(name, value) self.__server.setFailRegex(name, value)
return self.__server.getFailRegex(name) return self.__server.getFailRegex(name)
elif action[1] == "maxtime": elif command[1] == "maxtime":
value = action[2] value = command[2]
self.__server.setMaxTime(name, int(value)) self.__server.setMaxTime(name, int(value))
return self.__server.getMaxTime(name) return self.__server.getMaxTime(name)
elif action[1] == "findtime": elif command[1] == "findtime":
value = action[2] value = command[2]
self.__server.setFindTime(name, int(value)) self.__server.setFindTime(name, int(value))
return self.__server.getFindTime(name) return self.__server.getFindTime(name)
elif action[1] == "maxretry": elif command[1] == "maxretry":
value = action[2] value = command[2]
self.__server.setMaxRetry(name, int(value)) self.__server.setMaxRetry(name, int(value))
return self.__server.getMaxRetry(name) return self.__server.getMaxRetry(name)
# Action # command
elif action[1] == "bantime": elif command[1] == "bantime":
value = action[2] value = command[2]
self.__server.setBanTime(name, int(value)) self.__server.setBanTime(name, int(value))
return self.__server.getBanTime(name) return self.__server.getBanTime(name)
elif action[1] == "addaction": elif command[1] == "addaction":
value = action[2] value = command[2]
self.__server.addAction(name, value) self.__server.addAction(name, value)
return self.__server.getLastAction(name).getName() return self.__server.getLastcommand(name).getName()
elif action[1] == "delaction": elif command[1] == "delaction":
self.__server.delAction(name, value) self.__server.delAction(name, value)
return None return None
elif action[1] == "setcinfo": elif command[1] == "setcinfo":
act = action[2] act = command[2]
key = action[3] key = command[3]
value = action[4] value = command[4]
self.__server.setCInfo(name, act, key, value) self.__server.setCInfo(name, act, key, value)
return self.__server.getCInfo(name, act, key) return self.__server.getCInfo(name, act, key)
elif action[1] == "delcinfo": elif command[1] == "delcinfo":
act = action[2] act = command[2]
key = action[3] key = command[3]
self.__server.delCInfo(name, act, key) self.__server.delCInfo(name, act, key)
return None return None
elif action[1] == "actionstart": elif command[1] == "actionstart":
act = action[2] act = command[2]
value = action[3] value = command[3]
self.__server.setActionStart(name, act, value) self.__server.setActionStart(name, act, value)
return self.__server.getActionStart(name, act) return self.__server.getActionStart(name, act)
elif action[1] == "actionstop": elif command[1] == "actionstop":
act = action[2] act = command[2]
value = action[3] value = command[3]
self.__server.setActionStop(name, act, value) self.__server.setActionStop(name, act, value)
return self.__server.getActionStop(name, act) return self.__server.getActionStop(name, act)
elif action[1] == "actioncheck": elif command[1] == "actioncheck":
act = action[2] act = command[2]
value = action[3] value = command[3]
self.__server.setActionCheck(name, act, value) self.__server.setActionCheck(name, act, value)
return self.__server.getActionCheck(name, act) return self.__server.getActionCheck(name, act)
elif action[1] == "actionban": elif command[1] == "actionban":
act = action[2] act = command[2]
value = action[3] value = command[3]
self.__server.setActionBan(name, act, value) self.__server.setActionBan(name, act, value)
return self.__server.getActionBan(name, act) return self.__server.getActionBan(name, act)
elif action[1] == "actionunban": elif command[1] == "actionunban":
act = action[2] act = command[2]
value = action[3] value = command[3]
self.__server.setActionUnban(name, act, value) self.__server.setActionUnban(name, act, value)
return self.__server.getActionUnban(name, act) return self.__server.getActionUnban(name, act)
raise Exception("Invalid command (no set action or not yet implemented)") raise Exception("Invalid command (no set action or not yet implemented)")
def __actionGet(self, action): def __commandGet(self, command):
name = action[0] name = command[0]
# Logging # Logging
if name == "loglevel": if name == "loglevel":
return self.__server.getLogLevel() return self.__server.getLogLevel()
elif name == "logtarget": elif name == "logtarget":
return self.__server.getLogTarget() return self.__server.getLogTarget()
# Filter # Filter
elif action[1] == "logpath": elif command[1] == "logpath":
return self.__server.getLogPath(name) return self.__server.getLogPath(name)
elif action[1] == "ignoreip": elif command[1] == "ignoreip":
return self.__server.getIgnoreIP(name) return self.__server.getIgnoreIP(name)
elif action[1] == "timeregex": elif command[1] == "timeregex":
return self.__server.getTimeRegex(name) return self.__server.getTimeRegex(name)
elif action[1] == "timepattern": elif command[1] == "timepattern":
return self.__server.getTimePattern(name) return self.__server.getTimePattern(name)
elif action[1] == "failregex": elif command[1] == "failregex":
return self.__server.getFailRegex(name) return self.__server.getFailRegex(name)
elif action[1] == "maxtime": elif command[1] == "maxtime":
return self.__server.getMaxTime(name) return self.__server.getMaxTime(name)
elif action[1] == "findtime": elif command[1] == "findtime":
return self.__server.getFindTime(name) return self.__server.getFindTime(name)
elif action[1] == "maxretry": elif command[1] == "maxretry":
return self.__server.getMaxRetry(name) return self.__server.getMaxRetry(name)
# Action # Action
elif action[1] == "bantime": elif command[1] == "bantime":
return self.__server.getBanTime(name) return self.__server.getBanTime(name)
elif action[1] == "addaction": elif command[1] == "addaction":
return self.__server.getLastAction(name).getName() return self.__server.getLastAction(name).getName()
elif action[1] == "actionstart": elif command[1] == "actionstart":
act = action[2] act = command[2]
return self.__server.getActionStart(name, act) return self.__server.getActionStart(name, act)
elif action[1] == "actionstop": elif command[1] == "actionstop":
act = action[2] act = command[2]
return self.__server.getActionStop(name, act) return self.__server.getActionStop(name, act)
elif action[1] == "actioncheck": elif command[1] == "actioncheck":
act = action[2] act = command[2]
return self.__server.getActionCheck(name, act) return self.__server.getActionCheck(name, act)
elif action[1] == "actionban": elif command[1] == "actionban":
act = action[2] act = command[2]
return self.__server.getActionBan(name, act) return self.__server.getActionBan(name, act)
elif action[1] == "actionunban": elif command[1] == "actionunban":
act = action[2] act = command[2]
return self.__server.getActionUnban(name, act) return self.__server.getActionUnban(name, act)
raise Exception("Invalid command (no get action or not yet implemented)") raise Exception("Invalid command (no get action or not yet implemented)")
def status(self, action): def status(self, command):
if len(action) == 0: if len(command) == 0:
return self.__server.status() return self.__server.status()
else: else:
name = action[0] name = command[0]
return self.__server.statusJail(name) return self.__server.statusJail(name)
raise Exception("Invalid command (no status)") raise Exception("Invalid command (no status)")