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
27from .configreader import ConfigReader
28from .jailreader import JailReader
29from ..helpers import getLogger
30
31# Gets the instance of the logger.
32logSys = getLogger(__name__)
33
34
35class JailsReader(ConfigReader):
36
37	def __init__(self, force_enable=False, **kwargs):
38		"""
39		Parameters
40		----------
41		force_enable : bool, optional
42		  Passed to JailReader to force enable the jails.
43		  It is for internal use
44		"""
45		ConfigReader.__init__(self, **kwargs)
46		self.__jails = list()
47		self.__force_enable = force_enable
48
49	@property
50	def jails(self):
51		return self.__jails
52
53	def read(self):
54		self.__jails = list()
55		return ConfigReader.read(self, "jail")
56
57	def getOptions(self, section=None, ignoreWrong=True):
58		"""Reads configuration for jail(s) and adds enabled jails to __jails
59		"""
60		opts = []
61		self.__opts = ConfigReader.getOptions(self, "Definition", opts)
62
63		if section is None:
64			sections = self.sections()
65		else:
66			sections = [ section ]
67
68		# Get the options of all jails.
69		parse_status = 0
70		for sec in sections:
71			if sec == 'INCLUDES':
72				continue
73			# use the cfg_share for filter/action caching and the same config for all
74			# jails (use_config=...), therefore don't read it here:
75			jail = JailReader(sec, force_enable=self.__force_enable,
76				share_config=self.share_config, use_config=self._cfg)
77			ret = jail.getOptions()
78			if ret:
79				if jail.isEnabled():
80					# at least one jail was successful:
81					parse_status |= 1
82					# We only add enabled jails
83					self.__jails.append(jail)
84			else:
85				logSys.error("Errors in jail %r.%s", sec, " Skipping..." if ignoreWrong else "")
86				self.__jails.append(jail)
87				# at least one jail was invalid:
88				parse_status |= 2
89		return ((ignoreWrong and parse_status & 1) or not (parse_status & 2))
90
91	def convert(self, allow_no_files=False):
92		"""Convert read before __opts and jails to the commands stream
93
94		Parameters
95		----------
96		allow_missing : bool
97		  Either to allow log files to be missing entirely.  Primarily is
98		  used for testing
99		"""
100
101		stream = list()
102		# Convert jails
103		for jail in self.__jails:
104			stream.extend(jail.convert(allow_no_files=allow_no_files))
105		# Start jails
106		for jail in self.__jails:
107			if not jail.options.get('config-error'):
108				stream.append(["start", jail.getName()])
109
110		return stream
111
112