2011-10-07 19:47:50 +00:00
|
|
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
|
|
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
|
|
|
|
2006-10-23 20:13:21 +00:00
|
|
|
# This file is part of Fail2Ban.
|
|
|
|
#
|
|
|
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# Fail2Ban is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with Fail2Ban; if not, write to the Free Software
|
2011-11-21 12:20:20 +00:00
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2006-10-23 20:13:21 +00:00
|
|
|
|
|
|
|
# Author: Cyril Jaquier
|
|
|
|
#
|
|
|
|
|
|
|
|
__author__ = "Cyril Jaquier"
|
|
|
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
|
|
|
__license__ = "GPL"
|
|
|
|
|
|
|
|
import unittest, time
|
2012-11-07 16:33:17 +00:00
|
|
|
import logging, sys
|
2006-10-23 20:13:21 +00:00
|
|
|
from server.action import Action
|
2012-11-07 16:33:17 +00:00
|
|
|
from StringIO import StringIO
|
2006-10-23 20:13:21 +00:00
|
|
|
|
|
|
|
class ExecuteAction(unittest.TestCase):
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
"""Call before every test case."""
|
|
|
|
self.__action = Action("Test")
|
|
|
|
|
2012-11-07 16:33:17 +00:00
|
|
|
# For extended testing of what gets output into logging
|
|
|
|
# system, we will redirect it to a string
|
|
|
|
logSys = logging.getLogger("fail2ban")
|
|
|
|
|
|
|
|
# Keep old settings
|
|
|
|
self._old_level = logSys.level
|
|
|
|
self._old_handlers = logSys.handlers
|
|
|
|
# Let's log everything into a string
|
|
|
|
self._log = StringIO()
|
|
|
|
logSys.handlers = [logging.StreamHandler(self._log)]
|
|
|
|
logSys.setLevel(getattr(logging, 'DEBUG'))
|
|
|
|
|
2006-10-23 20:13:21 +00:00
|
|
|
def tearDown(self):
|
|
|
|
"""Call after every test case."""
|
2012-11-07 16:33:17 +00:00
|
|
|
# print "O: >>%s<<" % self._log.getvalue()
|
|
|
|
logSys = logging.getLogger("fail2ban")
|
|
|
|
logSys.handlers = self._old_handlers
|
|
|
|
logSys.level = self._old_level
|
2006-10-23 20:13:21 +00:00
|
|
|
self.__action.execActionStop()
|
2012-11-07 16:33:17 +00:00
|
|
|
|
|
|
|
def _is_logged(self, s):
|
|
|
|
return s in self._log.getvalue()
|
|
|
|
|
2013-04-29 02:37:16 +00:00
|
|
|
def testSubstituteRecursiveTags(self):
|
|
|
|
aInfo = {
|
|
|
|
'HOST': "192.0.2.0",
|
|
|
|
'ABC': "123 <HOST>",
|
|
|
|
'xyz': "890 <ABC>",
|
|
|
|
}
|
|
|
|
# Recursion is bad
|
|
|
|
self.assertFalse(Action.substituteRecursiveTags({'A': '<A>'}))
|
|
|
|
self.assertFalse(Action.substituteRecursiveTags({'A': '<B>', 'B': '<A>'}))
|
|
|
|
self.assertFalse(Action.substituteRecursiveTags({'A': '<B>', 'B': '<C>', 'C': '<A>'}))
|
|
|
|
# missing tags are ok
|
2013-06-29 19:17:42 +00:00
|
|
|
self.assertEqual(Action.substituteRecursiveTags({'A': '<C>'}), {'A': '<C>'})
|
|
|
|
self.assertEqual(Action.substituteRecursiveTags({'A': '<C> <D> <X>','X':'fun'}), {'A': '<C> <D> fun', 'X':'fun'})
|
|
|
|
self.assertEqual(Action.substituteRecursiveTags({'A': '<C> <B>', 'B': 'cool'}), {'A': '<C> cool', 'B': 'cool'})
|
2013-04-29 02:37:16 +00:00
|
|
|
# rest is just cool
|
2013-06-29 19:17:42 +00:00
|
|
|
self.assertEqual(Action.substituteRecursiveTags(aInfo),
|
2013-04-29 02:37:16 +00:00
|
|
|
{ 'HOST': "192.0.2.0",
|
|
|
|
'ABC': '123 192.0.2.0',
|
|
|
|
'xyz': '890 123 192.0.2.0',
|
|
|
|
})
|
|
|
|
|
2013-04-14 14:58:35 +00:00
|
|
|
def testReplaceTag(self):
|
|
|
|
aInfo = {
|
|
|
|
'HOST': "192.0.2.0",
|
|
|
|
'ABC': "123",
|
|
|
|
'xyz': "890",
|
|
|
|
}
|
2013-04-28 07:11:18 +00:00
|
|
|
self.assertEqual(
|
|
|
|
self.__action.replaceTag("Text<br>text", aInfo),
|
|
|
|
"Text\ntext")
|
2013-04-14 14:58:35 +00:00
|
|
|
self.assertEqual(
|
|
|
|
self.__action.replaceTag("Text <HOST> text", aInfo),
|
|
|
|
"Text 192.0.2.0 text")
|
|
|
|
self.assertEqual(
|
|
|
|
self.__action.replaceTag("Text <xyz> text <ABC> ABC", aInfo),
|
|
|
|
"Text 890 text 123 ABC")
|
|
|
|
self.assertEqual(
|
|
|
|
self.__action.replaceTag("<matches>",
|
|
|
|
{'matches': "some >char< should \< be[ escap}ed&"}),
|
|
|
|
r"some \>char\< should \\\< be\[ escap\}ed\&")
|
|
|
|
|
2006-10-23 20:13:21 +00:00
|
|
|
def testExecuteActionBan(self):
|
|
|
|
self.__action.setActionStart("touch /tmp/fail2ban.test")
|
|
|
|
self.__action.setActionStop("rm -f /tmp/fail2ban.test")
|
|
|
|
self.__action.setActionBan("echo -n")
|
|
|
|
self.__action.setActionCheck("[ -e /tmp/fail2ban.test ]")
|
2012-11-07 16:33:17 +00:00
|
|
|
|
|
|
|
self.assertFalse(self._is_logged('returned'))
|
|
|
|
# no action was actually executed yet
|
|
|
|
|
2006-10-23 20:13:21 +00:00
|
|
|
self.assertTrue(self.__action.execActionBan(None))
|
2012-11-07 16:33:17 +00:00
|
|
|
self.assertTrue(self._is_logged('Invariant check failed'))
|
|
|
|
self.assertTrue(self._is_logged('returned successfully'))
|
|
|
|
|
|
|
|
|
|
|
|
def testExecuteIncorrectCmd(self):
|
|
|
|
Action.executeCmd('/bin/ls >/dev/null\nbogusXXX now 2>/dev/null')
|
|
|
|
self.assertTrue(self._is_logged('HINT on 7f00: "Command not found"'))
|