"Fossies" - the Fresh Open Source Software Archive

Member "fail2ban-0.11.1/fail2ban/server/transmitter.py" (11 Jan 2020, 15757 Bytes) of package /linux/misc/fail2ban-0.11.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "transmitter.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.10.5_vs_0.11.1.

    1 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
    2 # vi: set ft=python sts=4 ts=4 sw=4 noet :
    3 
    4 # This file is part of Fail2Ban.
    5 #
    6 # Fail2Ban is free software; you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation; either version 2 of the License, or
    9 # (at your option) any later version.
   10 #
   11 # Fail2Ban is distributed in the hope that it will be useful,
   12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 # GNU General Public License for more details.
   15 #
   16 # You should have received a copy of the GNU General Public License
   17 # along with Fail2Ban; if not, write to the Free Software
   18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   19 
   20 # Author: Cyril Jaquier
   21 # 
   22 
   23 __author__ = "Cyril Jaquier"
   24 __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
   25 __license__ = "GPL"
   26 
   27 import time
   28 import json
   29 
   30 from ..helpers import getLogger, logging
   31 from .. import version
   32 
   33 # Gets the instance of the logger.
   34 logSys = getLogger(__name__)
   35 
   36 
   37 class Transmitter:
   38     
   39     ##
   40     # Constructor.
   41     #
   42     # @param The server reference
   43     
   44     def __init__(self, server):
   45         self.__server = server
   46         self.__quiet = 0
   47         
   48     ##
   49     # Proceeds a command.
   50     #
   51     # Proceeds an incoming command.
   52     # @param command The incoming command
   53     
   54     def proceed(self, command):
   55         # Deserialize object
   56         logSys.log(5, "Command: %r", command)
   57         try:
   58             ret = self.__commandHandler(command)
   59             ack = 0, ret
   60         except Exception as e:
   61             logSys.warning("Command %r has failed. Received %r",
   62                         command, e, 
   63                         exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
   64             ack = 1, e
   65         return ack
   66     
   67     ##
   68     # Handle an command.
   69     #
   70     # 
   71     
   72     def __commandHandler(self, command):
   73         name = command[0]
   74         if name == "ping":
   75             return "pong"
   76         elif name == "add":
   77             name = command[1]
   78             if name == "--all":
   79                 raise Exception("Reserved name %r" % (name,))
   80             try:
   81                 backend = command[2]
   82             except IndexError:
   83                 backend = "auto"
   84             self.__server.addJail(name, backend)
   85             return name
   86         elif name == "multi-set":
   87             return self.__commandSet(command[1:], True)
   88         elif name == "set":
   89             return self.__commandSet(command[1:])
   90         elif name == "start":
   91             name = command[1]
   92             self.__server.startJail(name)
   93             return None
   94         elif name == "stop":
   95             if len(command) == 1:
   96                 self.__server.quit()
   97             elif command[1] == "--all":
   98                 self.__server.stopAllJail()
   99             else:
  100                 name = command[1]
  101                 self.__server.stopJail(name)
  102             return None
  103         elif name == "reload":
  104             opts = command[1:3]
  105             self.__quiet = 1
  106             try:
  107                 self.__server.reloadJails(*opts, begin=True)
  108                 for cmd in command[3]:
  109                     self.__commandHandler(cmd)
  110             finally:
  111                 self.__quiet = 0
  112                 self.__server.reloadJails(*opts, begin=False)
  113             return 'OK'
  114         elif name == "unban" and len(command) >= 2:
  115             # unban in all jails:
  116             value = command[1:]
  117             # if all ips:
  118             if len(value) == 1 and value[0] == "--all":
  119                 return self.__server.setUnbanIP()
  120             return self.__server.setUnbanIP(None, value)
  121         elif name == "echo":
  122             return command[1:]
  123         elif name == "server-status":
  124             logSys.debug("Status: ready")
  125             return "Server ready"
  126         elif name == "server-stream":
  127             self.__quiet = 1
  128             try:
  129                 for cmd in command[1]:
  130                     self.__commandHandler(cmd)
  131             finally:
  132                 self.__quiet = 0
  133             return None
  134         elif name == "sleep":
  135             value = command[1]
  136             time.sleep(float(value))
  137             return None
  138         elif name == "flushlogs":
  139             return self.__server.flushLogs()
  140         elif name == "get":
  141             return self.__commandGet(command[1:])
  142         elif name == "status":
  143             return self.status(command[1:])
  144         elif name == "version":
  145             return version.version
  146         elif name == "config-error":
  147             logSys.error(command[1])
  148             return None
  149         raise Exception("Invalid command")
  150     
  151     def __commandSet(self, command, multiple=False):
  152         name = command[0]
  153         # Logging
  154         if name == "loglevel":
  155             value = command[1]
  156             self.__server.setLogLevel(value)
  157             if self.__quiet: return
  158             return self.__server.getLogLevel()
  159         elif name == "logtarget":
  160             value = command[1]
  161             if self.__server.setLogTarget(value):
  162                 if self.__quiet: return
  163                 return self.__server.getLogTarget()
  164             else:
  165                 raise Exception("Failed to change log target")
  166         elif name == "syslogsocket":
  167             value = command[1]
  168             if self.__server.setSyslogSocket(value):
  169                 if self.__quiet: return
  170                 return self.__server.getSyslogSocket()
  171             else:
  172                 raise Exception("Failed to change syslog socket")
  173         #Thread
  174         elif name == "thread":
  175             value = command[1]
  176             return self.__server.setThreadOptions(value)
  177         #Database
  178         elif name == "dbfile":
  179             self.__server.setDatabase(command[1])
  180             db = self.__server.getDatabase()
  181             if db is None:
  182                 return None
  183             else:
  184                 if self.__quiet: return
  185                 return db.filename
  186         elif name == "dbmaxmatches":
  187             db = self.__server.getDatabase()
  188             if db is None:
  189                 logSys.log(logging.MSG, "dbmaxmatches setting was not in effect since no db yet")
  190                 return None
  191             else:
  192                 db.maxMatches = int(command[1])
  193                 if self.__quiet: return
  194                 return db.maxMatches
  195         elif name == "dbpurgeage":
  196             db = self.__server.getDatabase()
  197             if db is None:
  198                 logSys.log(logging.MSG, "dbpurgeage setting was not in effect since no db yet")
  199                 return None
  200             else:
  201                 db.purgeage = command[1]
  202                 if self.__quiet: return
  203                 return db.purgeage
  204         # Jail
  205         elif command[1] == "idle":
  206             if command[2] == "on":
  207                 self.__server.setIdleJail(name, True)
  208             elif command[2] == "off":
  209                 self.__server.setIdleJail(name, False)
  210             else:
  211                 raise Exception("Invalid idle option, must be 'on' or 'off'")
  212             if self.__quiet: return
  213             return self.__server.getIdleJail(name)
  214         # Filter
  215         elif command[1] == "ignoreself":
  216             value = command[2]
  217             self.__server.setIgnoreSelf(name, value)
  218             if self.__quiet: return
  219             return self.__server.getIgnoreSelf(name)
  220         elif command[1] == "addignoreip":
  221             for value in command[2:]:
  222                 self.__server.addIgnoreIP(name, value)
  223             if self.__quiet: return
  224             return self.__server.getIgnoreIP(name)
  225         elif command[1] == "delignoreip":
  226             value = command[2]
  227             self.__server.delIgnoreIP(name, value)
  228             if self.__quiet: return
  229             return self.__server.getIgnoreIP(name)
  230         elif command[1] == "ignorecommand":
  231             value = command[2]
  232             self.__server.setIgnoreCommand(name, value)
  233             if self.__quiet: return
  234             return self.__server.getIgnoreCommand(name)
  235         elif command[1] == "ignorecache":
  236             value = command[2]
  237             self.__server.setIgnoreCache(name, value)
  238             if self.__quiet: return
  239             return self.__server.getIgnoreCache(name)
  240         elif command[1] == "addlogpath":
  241             value = command[2]
  242             tail = False
  243             if len(command) == 4:
  244                 if command[3].lower()  == "tail":
  245                     tail = True
  246                 elif command[3].lower() != "head":
  247                     raise ValueError("File option must be 'head' or 'tail'")
  248             elif len(command) > 4:
  249                 raise ValueError("Only one file can be added at a time")
  250             self.__server.addLogPath(name, value, tail)
  251             if self.__quiet: return
  252             return self.__server.getLogPath(name)
  253         elif command[1] == "dellogpath":
  254             value = command[2]
  255             self.__server.delLogPath(name, value)
  256             if self.__quiet: return
  257             return self.__server.getLogPath(name)
  258         elif command[1] == "logencoding":
  259             value = command[2]
  260             self.__server.setLogEncoding(name, value)
  261             if self.__quiet: return
  262             return self.__server.getLogEncoding(name)
  263         elif command[1] == "addjournalmatch": # pragma: systemd no cover
  264             value = command[2:]
  265             self.__server.addJournalMatch(name, value)
  266             if self.__quiet: return
  267             return self.__server.getJournalMatch(name)
  268         elif command[1] == "deljournalmatch": # pragma: systemd no cover
  269             value = command[2:]
  270             self.__server.delJournalMatch(name, value)
  271             if self.__quiet: return
  272             return self.__server.getJournalMatch(name)
  273         elif command[1] == "prefregex":
  274             value = command[2]
  275             self.__server.setPrefRegex(name, value)
  276             if self.__quiet: return
  277             return self.__server.getPrefRegex(name)
  278         elif command[1] == "addfailregex":
  279             value = command[2]
  280             self.__server.addFailRegex(name, value, multiple=multiple)
  281             if multiple:
  282                 return True
  283             if self.__quiet: return
  284             return self.__server.getFailRegex(name)
  285         elif command[1] == "delfailregex":
  286             value = int(command[2])
  287             self.__server.delFailRegex(name, value)
  288             if self.__quiet: return
  289             return self.__server.getFailRegex(name)
  290         elif command[1] == "addignoreregex":
  291             value = command[2]
  292             self.__server.addIgnoreRegex(name, value, multiple=multiple)
  293             if multiple:
  294                 return True
  295             if self.__quiet: return
  296             return self.__server.getIgnoreRegex(name)
  297         elif command[1] == "delignoreregex":
  298             value = int(command[2])
  299             self.__server.delIgnoreRegex(name, value)
  300             if self.__quiet: return
  301             return self.__server.getIgnoreRegex(name)
  302         elif command[1] == "usedns":
  303             value = command[2]
  304             self.__server.setUseDns(name, value)
  305             if self.__quiet: return
  306             return self.__server.getUseDns(name)
  307         elif command[1] == "findtime":
  308             value = command[2]
  309             self.__server.setFindTime(name, value)
  310             if self.__quiet: return
  311             return self.__server.getFindTime(name)
  312         elif command[1] == "datepattern":
  313             value = command[2]
  314             self.__server.setDatePattern(name, value)
  315             if self.__quiet: return
  316             return self.__server.getDatePattern(name)
  317         elif command[1] == "logtimezone":
  318             value = command[2]
  319             self.__server.setLogTimeZone(name, value)
  320             if self.__quiet: return
  321             return self.__server.getLogTimeZone(name)
  322         elif command[1] == "maxmatches":
  323             value = command[2]
  324             self.__server.setMaxMatches(name, int(value))
  325             if self.__quiet: return
  326             return self.__server.getMaxMatches(name)
  327         elif command[1] == "maxretry":
  328             value = command[2]
  329             self.__server.setMaxRetry(name, int(value))
  330             if self.__quiet: return
  331             return self.__server.getMaxRetry(name)
  332         elif command[1] == "maxlines":
  333             value = command[2]
  334             self.__server.setMaxLines(name, int(value))
  335             if self.__quiet: return
  336             return self.__server.getMaxLines(name)
  337         # command
  338         elif command[1] == "bantime":
  339             value = command[2]
  340             self.__server.setBanTime(name, value)
  341             if self.__quiet: return
  342             return self.__server.getBanTime(name)
  343         elif command[1] == "attempt":
  344             value = command[2:]
  345             if self.__quiet: return
  346             return self.__server.addAttemptIP(name, *value)
  347         elif command[1].startswith("bantime."):
  348             value = command[2]
  349             opt = command[1][len("bantime."):]
  350             self.__server.setBanTimeExtra(name, opt, value)
  351             if self.__quiet: return
  352             return self.__server.getBanTimeExtra(name, opt)
  353         elif command[1] == "banip":
  354             value = command[2:]
  355             return self.__server.setBanIP(name,value)
  356         elif command[1] == "unbanip":
  357             ifexists = True
  358             if command[2] != "--report-absent":
  359                 value = command[2:]
  360             else:
  361                 ifexists = False
  362                 value = command[3:]
  363             return self.__server.setUnbanIP(name, value, ifexists=ifexists)
  364         elif command[1] == "addaction":
  365             args = [command[2]]
  366             if len(command) > 3:
  367                 args.extend([command[3], json.loads(command[4])])
  368             self.__server.addAction(name, *args)
  369             if self.__quiet: return
  370             return args[0]
  371         elif command[1] == "delaction":
  372             value = command[2]
  373             self.__server.delAction(name, value)
  374             return None
  375         elif command[1] == "action":
  376             actionname = command[2]
  377             action = self.__server.getAction(name, actionname)
  378             if multiple:
  379                 for cmd in command[3]:
  380                     logSys.log(5, "  %r", cmd)
  381                     actionkey = cmd[0]
  382                     if callable(getattr(action, actionkey, None)):
  383                         actionvalue = json.loads(cmd[1]) if len(cmd)>1 else {}
  384                         getattr(action, actionkey)(**actionvalue)
  385                     else:
  386                         actionvalue = cmd[1]
  387                         setattr(action, actionkey, actionvalue)
  388                 return True
  389             else:
  390                 actionkey = command[3]
  391                 if callable(getattr(action, actionkey, None)):
  392                     actionvalue = json.loads(command[4]) if len(command)>4 else {}
  393                     if self.__quiet: return
  394                     return getattr(action, actionkey)(**actionvalue)
  395                 else:
  396                     actionvalue = command[4]
  397                     setattr(action, actionkey, actionvalue)
  398                     if self.__quiet: return
  399                     return getattr(action, actionkey)
  400         raise Exception("Invalid command %r (no set action or not yet implemented)" % (command[1],))
  401     
  402     def __commandGet(self, command):
  403         name = command[0]
  404         # Logging
  405         if name == "loglevel":
  406             return self.__server.getLogLevel()
  407         elif name == "logtarget":
  408             return self.__server.getLogTarget()
  409         elif name == "syslogsocket":
  410             return self.__server.getSyslogSocket()
  411         #Thread
  412         elif name == "thread":
  413             return self.__server.getThreadOptions()
  414         #Database
  415         elif name == "dbfile":
  416             db = self.__server.getDatabase()
  417             if db is None:
  418                 return None
  419             else:
  420                 return db.filename
  421         elif name == "dbmaxmatches":
  422             db = self.__server.getDatabase()
  423             if db is None:
  424                 return None
  425             else:
  426                 return db.maxMatches
  427         elif name == "dbpurgeage":
  428             db = self.__server.getDatabase()
  429             if db is None:
  430                 return None
  431             else:
  432                 return db.purgeage
  433         # Filter
  434         elif command[1] == "logpath":
  435             return self.__server.getLogPath(name)
  436         elif command[1] == "logencoding":
  437             return self.__server.getLogEncoding(name)
  438         elif command[1] == "journalmatch": # pragma: systemd no cover
  439             return self.__server.getJournalMatch(name)
  440         elif command[1] == "ignoreself":
  441             return self.__server.getIgnoreSelf(name)
  442         elif command[1] == "ignoreip":
  443             return self.__server.getIgnoreIP(name)
  444         elif command[1] == "ignorecommand":
  445             return self.__server.getIgnoreCommand(name)
  446         elif command[1] == "ignorecache":
  447             return self.__server.getIgnoreCache(name)
  448         elif command[1] == "prefregex":
  449             return self.__server.getPrefRegex(name)
  450         elif command[1] == "failregex":
  451             return self.__server.getFailRegex(name)
  452         elif command[1] == "ignoreregex":
  453             return self.__server.getIgnoreRegex(name)
  454         elif command[1] == "usedns":
  455             return self.__server.getUseDns(name)
  456         elif command[1] == "findtime":
  457             return self.__server.getFindTime(name)
  458         elif command[1] == "datepattern":
  459             return self.__server.getDatePattern(name)
  460         elif command[1] == "logtimezone":
  461             return self.__server.getLogTimeZone(name)
  462         elif command[1] == "maxmatches":
  463             return self.__server.getMaxMatches(name)
  464         elif command[1] == "maxretry":
  465             return self.__server.getMaxRetry(name)
  466         elif command[1] == "maxlines":
  467             return self.__server.getMaxLines(name)
  468         # Action
  469         elif command[1] == "bantime":
  470             return self.__server.getBanTime(name)
  471         elif command[1] == "banip":
  472             return self.__server.getBanList(name,
  473                 withTime=len(command) > 2 and command[2] == "--with-time")
  474         elif command[1].startswith("bantime."):
  475             opt = command[1][len("bantime."):]
  476             return self.__server.getBanTimeExtra(name, opt)
  477         elif command[1] == "actions":
  478             return self.__server.getActions(name).keys()
  479         elif command[1] == "action":
  480             actionname = command[2]
  481             actionvalue = command[3]
  482             action = self.__server.getAction(name, actionname)
  483             return getattr(action, actionvalue)
  484         elif command[1] == "actionproperties":
  485             actionname = command[2]
  486             action = self.__server.getAction(name, actionname)
  487             return [
  488                 key for key in dir(action)
  489                 if not key.startswith("_") and
  490                     not callable(getattr(action, key))]
  491         elif command[1] == "actionmethods":
  492             actionname = command[2]
  493             action = self.__server.getAction(name, actionname)
  494             return [
  495                 key for key in dir(action)
  496                 if not key.startswith("_") and callable(getattr(action, key))]
  497         raise Exception("Invalid command (no get action or not yet implemented)")
  498     
  499     def status(self, command):
  500         if len(command) == 0:
  501             return self.__server.status()
  502         elif len(command) == 1:
  503             name = command[0]
  504             return self.__server.statusJail(name)
  505         elif len(command) == 2:
  506             name = command[0]
  507             flavor = command[1]
  508             return self.__server.statusJail(name, flavor=flavor)
  509         raise Exception("Invalid command (no status)")