/fail2ban/client/filterreader.py

https://github.com/fail2ban/fail2ban · Python · 100 lines · 60 code · 15 blank · 25 comment · 19 complexity · 303969e1d2d6e814a6bfa66d0d9d2fc9 MD5 · raw file

  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. # This file is part of Fail2Ban.
  4. #
  5. # Fail2Ban is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # Fail2Ban is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with Fail2Ban; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. # Author: Cyril Jaquier
  19. #
  20. __author__ = "Cyril Jaquier"
  21. __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
  22. __license__ = "GPL"
  23. import os
  24. import shlex
  25. from .configreader import DefinitionInitConfigReader
  26. from ..helpers import getLogger
  27. # Gets the instance of the logger.
  28. logSys = getLogger(__name__)
  29. class FilterReader(DefinitionInitConfigReader):
  30. _configOpts = {
  31. "usedns": ["string", None],
  32. "prefregex": ["string", None],
  33. "ignoreregex": ["string", None],
  34. "failregex": ["string", None],
  35. "maxlines": ["int", None],
  36. "datepattern": ["string", None],
  37. "journalmatch": ["string", None],
  38. }
  39. def setFile(self, fileName):
  40. self.__file = fileName
  41. DefinitionInitConfigReader.setFile(self, os.path.join("filter.d", fileName))
  42. def getFile(self):
  43. return self.__file
  44. def applyAutoOptions(self, backend):
  45. # set init option to backend-related logtype, considering
  46. # that the filter settings may be overwritten in its local:
  47. if (not self._initOpts.get('logtype') and
  48. not self.has_option('Definition', 'logtype', False)
  49. ):
  50. self._initOpts['logtype'] = ['file','journal'][int(backend.startswith("systemd"))]
  51. def convert(self):
  52. stream = list()
  53. opts = self.getCombined()
  54. if not len(opts):
  55. return stream
  56. return FilterReader._fillStream(stream, opts, self._jailName)
  57. @staticmethod
  58. def _fillStream(stream, opts, jailName):
  59. prio0idx = 0
  60. for opt, value in opts.iteritems():
  61. # Do not send a command if the value is not set (empty).
  62. if value is None: continue
  63. if opt in ("failregex", "ignoreregex"):
  64. multi = []
  65. for regex in value.split('\n'):
  66. # Do not send a command if the rule is empty.
  67. if regex != '':
  68. multi.append(regex)
  69. if len(multi) > 1:
  70. stream.append(["multi-set", jailName, "add" + opt, multi])
  71. elif len(multi):
  72. stream.append(["set", jailName, "add" + opt, multi[0]])
  73. elif opt in ('usedns', 'maxlines', 'prefregex'):
  74. # Be sure we set this options first, and usedns is before all regex(s).
  75. stream.insert(0 if opt == 'usedns' else prio0idx,
  76. ["set", jailName, opt, value])
  77. prio0idx += 1
  78. elif opt in ('datepattern'):
  79. stream.append(["set", jailName, opt, value])
  80. elif opt == 'journalmatch':
  81. for match in value.split("\n"):
  82. if match == '': continue
  83. stream.append(
  84. ["set", jailName, "addjournalmatch"] + shlex.split(match))
  85. return stream