/fail2ban/tests/action_d/test_smtp.py

https://github.com/yarikoptic/fail2ban · Python · 132 lines · 90 code · 23 blank · 19 comment · 4 complexity · 8307b7de4a1bbba665829579722919d7 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. import os
  19. import smtpd
  20. import asyncore
  21. import threading
  22. import unittest
  23. import sys
  24. if sys.version_info >= (3, 3):
  25. import importlib
  26. else:
  27. import imp
  28. from ..dummyjail import DummyJail
  29. from ..utils import CONFIG_DIR
  30. class TestSMTPServer(smtpd.SMTPServer):
  31. def process_message(self, peer, mailfrom, rcpttos, data):
  32. self.peer = peer
  33. self.mailfrom = mailfrom
  34. self.rcpttos = rcpttos
  35. self.data = data
  36. class SMTPActionTest(unittest.TestCase):
  37. def setUp(self):
  38. """Call before every test case."""
  39. self.jail = DummyJail()
  40. pythonModule = os.path.join(CONFIG_DIR, "action.d", "smtp.py")
  41. pythonModuleName = os.path.basename(pythonModule.rstrip(".py"))
  42. if sys.version_info >= (3, 3):
  43. customActionModule = importlib.machinery.SourceFileLoader(
  44. pythonModuleName, pythonModule).load_module()
  45. else:
  46. customActionModule = imp.load_source(
  47. pythonModuleName, pythonModule)
  48. self.smtpd = TestSMTPServer(("localhost", 0), None)
  49. port = self.smtpd.socket.getsockname()[1]
  50. self.action = customActionModule.Action(
  51. self.jail, "test", host="127.0.0.1:%i" % port)
  52. self._loop_thread = threading.Thread(
  53. target=asyncore.loop, kwargs={'timeout': 1})
  54. self._loop_thread.start()
  55. def tearDown(self):
  56. """Call after every test case."""
  57. self.smtpd.close()
  58. self._loop_thread.join()
  59. def testStart(self):
  60. self.action.start()
  61. self.assertEqual(self.smtpd.mailfrom, "fail2ban")
  62. self.assertEqual(self.smtpd.rcpttos, ["root"])
  63. self.assertTrue(
  64. "Subject: [Fail2Ban] %s: started" % self.jail.name
  65. in self.smtpd.data)
  66. def testStop(self):
  67. self.action.stop()
  68. self.assertEqual(self.smtpd.mailfrom, "fail2ban")
  69. self.assertEqual(self.smtpd.rcpttos, ["root"])
  70. self.assertTrue(
  71. "Subject: [Fail2Ban] %s: stopped" %
  72. self.jail.name in self.smtpd.data)
  73. def testBan(self):
  74. aInfo = {
  75. 'ip': "127.0.0.2",
  76. 'failures': 3,
  77. 'matches': "Test fail 1\n",
  78. 'ipjailmatches': "Test fail 1\nTest Fail2\n",
  79. 'ipmatches': "Test fail 1\nTest Fail2\nTest Fail3\n",
  80. }
  81. self.action.ban(aInfo)
  82. self.assertEqual(self.smtpd.mailfrom, "fail2ban")
  83. self.assertEqual(self.smtpd.rcpttos, ["root"])
  84. subject = "Subject: [Fail2Ban] %s: banned %s" % (
  85. self.jail.name, aInfo['ip'])
  86. self.assertIn(subject, self.smtpd.data.replace("\n", ""))
  87. self.assertTrue(
  88. "%i attempts" % aInfo['failures'] in self.smtpd.data)
  89. self.action.matches = "matches"
  90. self.action.ban(aInfo)
  91. self.assertIn(aInfo['matches'], self.smtpd.data)
  92. self.action.matches = "ipjailmatches"
  93. self.action.ban(aInfo)
  94. self.assertIn(aInfo['ipjailmatches'], self.smtpd.data)
  95. self.action.matches = "ipmatches"
  96. self.action.ban(aInfo)
  97. self.assertIn(aInfo['ipmatches'], self.smtpd.data)
  98. def testOptions(self):
  99. self.action.start()
  100. self.assertEqual(self.smtpd.mailfrom, "fail2ban")
  101. self.assertEqual(self.smtpd.rcpttos, ["root"])
  102. self.action.fromname = "Test"
  103. self.action.fromaddr = "test@example.com"
  104. self.action.toaddr = "test@example.com, test2@example.com"
  105. self.action.start()
  106. self.assertEqual(self.smtpd.mailfrom, "test@example.com")
  107. self.assertTrue("From: %s <%s>" %
  108. (self.action.fromname, self.action.fromaddr) in self.smtpd.data)
  109. self.assertEqual(set(self.smtpd.rcpttos), set(["test@example.com", "test2@example.com"]))