Merge branch '0.10' into patch-1

pull/1685/head
Serg G. Brester 2017-02-15 20:33:36 +01:00 committed by GitHub
commit 7f63809afb
8 changed files with 35 additions and 19 deletions

View File

@ -11,6 +11,7 @@ python:
- 3.3 - 3.3
- 3.4 - 3.4
- 3.5 - 3.5
- 3.6
- pypy3 - pypy3
before_install: before_install:
- if [[ $TRAVIS_PYTHON_VERSION == 2* || $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then export F2B_PY_2=true && echo "Set F2B_PY_2"; fi - if [[ $TRAVIS_PYTHON_VERSION == 2* || $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then export F2B_PY_2=true && echo "Set F2B_PY_2"; fi

View File

@ -12,7 +12,7 @@ before = common.conf
_daemon = postfix(-\w+)?/smtpd _daemon = postfix(-\w+)?/smtpd
failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 454 4\.7\.1 Service unavailable; Client host \[\S+\] blocked using .* from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$ failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b
ignoreregex = ignoreregex =

View File

@ -150,7 +150,7 @@ class Actions(JailThread, Mapping):
# reload actions after all parameters set via stream: # reload actions after all parameters set via stream:
for name, initOpts in self._reload_actions.iteritems(): for name, initOpts in self._reload_actions.iteritems():
if name in self._actions: if name in self._actions:
self._actions[name].reload(**initOpts if initOpts else {}) self._actions[name].reload(**(initOpts if initOpts else {}))
# remove obsolete actions (untouched by reload process): # remove obsolete actions (untouched by reload process):
delacts = OrderedDict((name, action) for name, action in self._actions.iteritems() delacts = OrderedDict((name, action) for name, action in self._actions.iteritems()
if name not in self._reload_actions) if name not in self._reload_actions)

View File

@ -284,7 +284,7 @@ class DateDetector(object):
if preMatch is not None: if preMatch is not None:
# get cached or create a copy with modified name/pattern, using preMatch replacement for {DATE}: # get cached or create a copy with modified name/pattern, using preMatch replacement for {DATE}:
template = _getAnchoredTemplate(template, template = _getAnchoredTemplate(template,
wrap=lambda s: RE_DATE_PREMATCH.sub(s, preMatch)) wrap=lambda s: RE_DATE_PREMATCH.sub(lambda m: s, preMatch))
# append date detector template (ignore duplicate if some was added before default): # append date detector template (ignore duplicate if some was added before default):
self._appendTemplate(template, ignoreDup=ignoreDup) self._appendTemplate(template, ignoreDup=ignoreDup)

View File

@ -30,18 +30,22 @@ else:
from ..dummyjail import DummyJail from ..dummyjail import DummyJail
from ..utils import CONFIG_DIR, asyncserver from ..utils import CONFIG_DIR, asyncserver, Utils, uni_decode
class TestSMTPServer(smtpd.SMTPServer): class TestSMTPServer(smtpd.SMTPServer):
def process_message(self, peer, mailfrom, rcpttos, data): def __init__(self, *args):
smtpd.SMTPServer.__init__(self, *args)
self.ready = False
def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
self.peer = peer self.peer = peer
self.mailfrom = mailfrom self.mailfrom = mailfrom
self.rcpttos = rcpttos self.rcpttos = rcpttos
self.org_data = data self.org_data = data
# replace new line (with tab or space) for possible mime translations (word wrap): # replace new line (with tab or space) for possible mime translations (word wrap),
self.data = re.sub(r"\n[\t ]", " ", data) self.data = re.sub(r"\n[\t ]", " ", uni_decode(data))
self.ready = True
class SMTPActionTest(unittest.TestCase): class SMTPActionTest(unittest.TestCase):
@ -78,8 +82,14 @@ class SMTPActionTest(unittest.TestCase):
self._active = False self._active = False
self._loop_thread.join() self._loop_thread.join()
def _exec_and_wait(self, doaction, timeout=3, short=False):
if short: timeout /= 25
self.smtpd.ready = False
doaction()
Utils.wait_for(lambda: self.smtpd.ready, timeout)
def testStart(self): def testStart(self):
self.action.start() self._exec_and_wait(self.action.start)
self.assertEqual(self.smtpd.mailfrom, "fail2ban") self.assertEqual(self.smtpd.mailfrom, "fail2ban")
self.assertEqual(self.smtpd.rcpttos, ["root"]) self.assertEqual(self.smtpd.rcpttos, ["root"])
self.assertTrue( self.assertTrue(
@ -87,7 +97,7 @@ class SMTPActionTest(unittest.TestCase):
in self.smtpd.data) in self.smtpd.data)
def testStop(self): def testStop(self):
self.action.stop() self._exec_and_wait(self.action.stop)
self.assertEqual(self.smtpd.mailfrom, "fail2ban") self.assertEqual(self.smtpd.mailfrom, "fail2ban")
self.assertEqual(self.smtpd.rcpttos, ["root"]) self.assertEqual(self.smtpd.rcpttos, ["root"])
self.assertTrue( self.assertTrue(
@ -105,7 +115,7 @@ class SMTPActionTest(unittest.TestCase):
if restored: if restored:
aInfo['restored'] = 1 aInfo['restored'] = 1
self.action.ban(aInfo) self._exec_and_wait(lambda: self.action.ban(aInfo), short=restored)
if restored: # no mail, should raises attribute error: if restored: # no mail, should raises attribute error:
self.assertRaises(AttributeError, lambda: self.smtpd.mailfrom) self.assertRaises(AttributeError, lambda: self.smtpd.mailfrom)
return return
@ -118,15 +128,15 @@ class SMTPActionTest(unittest.TestCase):
"%i attempts" % aInfo['failures'], self.smtpd.data) "%i attempts" % aInfo['failures'], self.smtpd.data)
self.action.matches = "matches" self.action.matches = "matches"
self.action.ban(aInfo) self._exec_and_wait(lambda: self.action.ban(aInfo))
self.assertIn(aInfo['matches'], self.smtpd.data) self.assertIn(aInfo['matches'], self.smtpd.data)
self.action.matches = "ipjailmatches" self.action.matches = "ipjailmatches"
self.action.ban(aInfo) self._exec_and_wait(lambda: self.action.ban(aInfo))
self.assertIn(aInfo['ipjailmatches'], self.smtpd.data) self.assertIn(aInfo['ipjailmatches'], self.smtpd.data)
self.action.matches = "ipmatches" self.action.matches = "ipmatches"
self.action.ban(aInfo) self._exec_and_wait(lambda: self.action.ban(aInfo))
self.assertIn(aInfo['ipmatches'], self.smtpd.data) self.assertIn(aInfo['ipmatches'], self.smtpd.data)
def testBan(self): def testBan(self):
@ -136,14 +146,14 @@ class SMTPActionTest(unittest.TestCase):
self._testBan(restored=True) self._testBan(restored=True)
def testOptions(self): def testOptions(self):
self.action.start() self._exec_and_wait(self.action.start)
self.assertEqual(self.smtpd.mailfrom, "fail2ban") self.assertEqual(self.smtpd.mailfrom, "fail2ban")
self.assertEqual(self.smtpd.rcpttos, ["root"]) self.assertEqual(self.smtpd.rcpttos, ["root"])
self.action.fromname = "Test" self.action.fromname = "Test"
self.action.fromaddr = "test@example.com" self.action.fromaddr = "test@example.com"
self.action.toaddr = "test@example.com, test2@example.com" self.action.toaddr = "test@example.com, test2@example.com"
self.action.start() self._exec_and_wait(self.action.start)
self.assertEqual(self.smtpd.mailfrom, "test@example.com") self.assertEqual(self.smtpd.mailfrom, "test@example.com")
self.assertTrue("From: %s <%s>" % self.assertTrue("From: %s <%s>" %
(self.action.fromname, self.action.fromaddr) in self.smtpd.data) (self.action.fromname, self.action.fromaddr) in self.smtpd.data)

View File

@ -3,3 +3,6 @@ Dec 30 18:19:15 xxx postfix/smtpd[1574]: NOQUEUE: reject: RCPT from badguy.examp
# failJSON: { "time": "2004-12-30T18:19:15", "match": true , "host": "93.184.216.34" } # failJSON: { "time": "2004-12-30T18:19:15", "match": true , "host": "93.184.216.34" }
Dec 30 18:19:15 xxx postfix-incoming/smtpd[1574]: NOQUEUE: reject: RCPT from badguy.example.com[93.184.216.34]: 454 4.7.1 Service unavailable; Client host [93.184.216.34] blocked using rbl.example.com; http://www.example.com/query?ip=93.184.216.34; from=<spammer@example.com> to=<goodguy@example.com> proto=ESMTP helo=<badguy.example.com> Dec 30 18:19:15 xxx postfix-incoming/smtpd[1574]: NOQUEUE: reject: RCPT from badguy.example.com[93.184.216.34]: 454 4.7.1 Service unavailable; Client host [93.184.216.34] blocked using rbl.example.com; http://www.example.com/query?ip=93.184.216.34; from=<spammer@example.com> to=<goodguy@example.com> proto=ESMTP helo=<badguy.example.com>
# failJSON: { "time": "2005-02-07T12:25:45", "match": true , "host": "87.236.233.182" }
Feb 7 12:25:45 xxx12345 postfix/smtpd[13275]: NOQUEUE: reject: RCPT from unknown[87.236.233.182]: 554 5.7.1 Service unavailable; Client host [87.236.233.182] blocked using rbl.example.com; https://www.example.com/query/ip/87.236.233.182; from=<spammer@example.com> to=<goodguy@example.com> proto=SMTP helo=<WIN-5N8GBBS0R5I>

View File

@ -992,9 +992,10 @@ class LoggingTests(LogCaptureTestCase):
badThread = _BadThread() badThread = _BadThread()
badThread.start() badThread.start()
badThread.join() badThread.join()
self.assertLogged("Unhandled exception") self.assertTrue( Utils.wait_for( lambda: len(x) and self._is_logged("Unhandled exception"), 3) )
finally: finally:
sys.__excepthook__ = prev_exchook sys.__excepthook__ = prev_exchook
self.assertLogged("Unhandled exception")
self.assertEqual(len(x), 1) self.assertEqual(len(x), 1)
self.assertEqual(x[0][0], RuntimeError) self.assertEqual(x[0][0], RuntimeError)
@ -1646,7 +1647,8 @@ class ServerConfigReaderTests(LogCaptureTestCase):
r' echo mail \1 ) | cat', realCmd) r' echo mail \1 ) | cat', realCmd)
# replace abuse retrieving (possible no-network), just replace first occurrence of 'dig...': # replace abuse retrieving (possible no-network), just replace first occurrence of 'dig...':
realCmd = re.sub(r'\bADDRESSES=\$\(dig\s[^\n]+', realCmd = re.sub(r'\bADDRESSES=\$\(dig\s[^\n]+',
'ADDRESSES="abuse-1@abuse-test-server, abuse-2@abuse-test-server"', realCmd, 1) lambda m: 'ADDRESSES="abuse-1@abuse-test-server, abuse-2@abuse-test-server"',
realCmd, 1)
# execute action: # execute action:
return _actions.CommandAction.executeCmd(realCmd, timeout=timeout) return _actions.CommandAction.executeCmd(realCmd, timeout=timeout)

View File

@ -37,7 +37,7 @@ import unittest
from cStringIO import StringIO from cStringIO import StringIO
from functools import wraps from functools import wraps
from ..helpers import getLogger, str2LogLevel, getVerbosityFormat from ..helpers import getLogger, str2LogLevel, getVerbosityFormat, uni_decode
from ..server.ipdns import DNSUtils from ..server.ipdns import DNSUtils
from ..server.mytime import MyTime from ..server.mytime import MyTime
from ..server.utils import Utils from ..server.utils import Utils