Hello community, here is the log from the commit of package fail2ban for openSUSE:Factory checked in at 2012-12-07 14:08:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fail2ban (Old) and /work/SRC/openSUSE:Factory/.fail2ban.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fail2ban", Maintainer is "[email protected]" Changes: -------- --- /work/SRC/openSUSE:Factory/fail2ban/fail2ban.changes 2012-12-05 13:50:59.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.fail2ban.new/fail2ban.changes 2012-12-07 14:08:30.000000000 +0100 @@ -1,0 +2,38 @@ +Thu Dec 6 15:32:02 UTC 2012 - [email protected] + +One of the important changes is escaping of the <matches> content -- so if you +crafted some custom action which uses it -- you must upgrade, or you +would be at a significant security risk. + +- Fixes: + Alan Jenkins + * [8c38907] Removed 'POSSIBLE BREAK-IN ATTEMPT' from sshd filter to avoid + banning due to misconfigured DNS. Close gh-64 + Yaroslav Halchenko + * [83109bc] IMPORTANT: escape the content of <matches> (if used in + custom action files) since its value could contain arbitrary + symbols. Thanks for discovery go to the NBS System security + team + * [0935566,5becaf8] Various python 2.4 and 2.5 compatibility fixes. Close gh-83 + * [b159eab] do not enable pyinotify backend if pyinotify < 0.8.3 + * [37a2e59] store IP as a base, non-unicode str to avoid spurious messages + in the console. Close gh-91 + +- New features: + David Engeset + * [2d672d1,6288ec2] 'unbanip' command for the client + avoidance of touching + the log file to take 'banip' or 'unbanip' in effect. Close gh-81, gh-86 + +- Enhancements: + * [2d66f31] replaced uninformative "Invalid command" message with warning log + exception why command actually failed + * [958a1b0] improved failregex to "support" auth.backend = "htdigest" + * [9e7a3b7] until we make it proper module -- adjusted sys.path only if + system-wide run + * [f52ba99] downgraded "already banned" from WARN to INFO level. Closes gh-79 + * [f105379] added hints into the log on some failure return codes (e.g. 0x7f00 + for this gh-87) + * Various others: travis-ci integration, script to run tests + against all available Python versions, etc + +------------------------------------------------------------------- Old: ---- fail2ban_0.8.7.1.orig.tar.gz New: ---- fail2ban_0.8.8.orig.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fail2ban.spec ++++++ --- /var/tmp/diff_new_pack.qpnn8d/_old 2012-12-07 14:08:31.000000000 +0100 +++ /var/tmp/diff_new_pack.qpnn8d/_new 2012-12-07 14:08:31.000000000 +0100 @@ -30,7 +30,7 @@ %endif BuildRequires: python-devel PreReq: %fillup_prereq -Version: 0.8.7.1 +Version: 0.8.8 Release: 0 Url: http://www.fail2ban.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ fail2ban_0.8.7.1.orig.tar.gz -> fail2ban_0.8.8.orig.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/.travis.yml new/fail2ban-0.8.8/.travis.yml --- old/fail2ban-0.8.7.1/.travis.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/fail2ban-0.8.8/.travis.yml 2012-12-06 04:51:29.000000000 +0100 @@ -0,0 +1,11 @@ +# vim ft=yaml +# travis-ci.org definition for Fail2Ban build +language: python +python: + - "2.5" + - "2.6" + - "2.7" +install: + - "pip install pyinotify" +script: + - python ./fail2ban-testcases diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/ChangeLog new/fail2ban-0.8.8/ChangeLog --- old/fail2ban-0.8.7.1/ChangeLog 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/ChangeLog 2012-12-06 04:51:29.000000000 +0100 @@ -4,9 +4,41 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.7) 2012/07/31 +Fail2Ban (version 0.8.8) 2012/12/06 ================================================================================ +ver. 0.8.8 (2012/12/06) - stable +---------- +- Fixes: + Alan Jenkins + * [8c38907] Removed 'POSSIBLE BREAK-IN ATTEMPT' from sshd filter to avoid + banning due to misconfigured DNS. Close gh-64 + Yaroslav Halchenko + * [83109bc] IMPORTANT: escape the content of <matches> (if used in + custom action files) since its value could contain arbitrary + symbols. Thanks for discovery go to the NBS System security + team + * [0935566,5becaf8] Various python 2.4 and 2.5 compatibility fixes. Close gh-83 + * [b159eab] do not enable pyinotify backend if pyinotify < 0.8.3 + * [37a2e59] store IP as a base, non-unicode str to avoid spurious messages + in the console. Close gh-91 +- New features: + David Engeset + * [2d672d1,6288ec2] 'unbanip' command for the client + avoidance of touching + the log file to take 'banip' or 'unbanip' in effect. Close gh-81, gh-86 + Yaroslav Halchenko +- Enhancements: + * [2d66f31] replaced uninformative "Invalid command" message with warning log + exception why command actually failed + * [958a1b0] improved failregex to "support" auth.backend = "htdigest" + * [9e7a3b7] until we make it proper module -- adjusted sys.path only if + system-wide run + * [f52ba99] downgraded "already banned" from WARN to INFO level. Closes gh-79 + * [f105379] added hints into the log on some failure return codes (e.g. 0x7f00 + for this gh-87) + * Various others: travis-ci integration, script to run tests + against all available Python versions, etc + ver. 0.8.7.1 (2012/07/31) - stable ---------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/DEVELOP new/fail2ban-0.8.8/DEVELOP --- old/fail2ban-0.8.7.1/DEVELOP 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/DEVELOP 2012-12-06 04:51:29.000000000 +0100 @@ -7,18 +7,18 @@ How to develop for Fail2Ban ================================================================================ -Fail2Ban uses GIT (http://git-scm.com/) distributed source control. This gives -each developer their own complete copy of the entire repository. Developers can -add and switch branches and commit changes when ever they want and then ask a +Fail2Ban uses GIT (http://git-scm.com/) distributed source control. This gives +each developer their own complete copy of the entire repository. Developers can +add and switch branches and commit changes when ever they want and then ask a maintainer to merge their changes. -Fail2Ban uses GitHub (https://github.com/fail2ban/fail2ban) to manage access to -the Git repository. GitHub provides free hosting for open-source projects as +Fail2Ban uses GitHub (https://github.com/fail2ban/fail2ban) to manage access to +the Git repository. GitHub provides free hosting for open-source projects as well as a web-based Git repository browser and an issue tracker. -If you are familiar with Python and you have a bug fix or a feature that you -would like to add to Fail2Ban, the best way to do so it to use the GitHub Pull -Request feature. You can find more details on the Fail2Ban wiki +If you are familiar with Python and you have a bug fix or a feature that you +would like to add to Fail2Ban, the best way to do so it to use the GitHub Pull +Request feature. You can find more details on the Fail2Ban wiki (http://www.fail2ban.org/wiki/index.php/Get_Involved) Testing @@ -26,7 +26,7 @@ Existing tests can be run by executing `fail2ban-testcases`. -Documentation about creating tests (when tests are required and some guidelines +Documentation about creating tests (when tests are required and some guidelines for creating good tests) will be added soon. Coding Standards @@ -58,18 +58,20 @@ RF-Note just a note which might be useful to address while doing RF JailThread -> Filter -> FileFilter -> {FilterPoll, FilterPyinotify, ...} - | | * FileContainer - | + FailManager - | + DateDetector - \- -> Actions - * Actions - + BanManager - + | * FileContainer + + FailManager + + DateDetector + + Jail (provided in __init__) which contains this Filter + (used for passing tickets from FailManager to Jail's __queue) Server + Jails * Jail - + Filter + + Filter (in __filter) * tickets (in __queue) + + Actions (in __action) + * Action + + BanManager + failmanager.py ~~~~~~~~~~~~~~ @@ -147,7 +149,7 @@ except FailManagerEmpty: self.failManager.cleanup(MyTime.time()) -thus channeling "ban tickets" from their failManager to a +thus channeling "ban tickets" from their failManager to the corresponding jail. action.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/README new/fail2ban-0.8.8/README --- old/fail2ban-0.8.7.1/README 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/README 2012-12-06 04:51:29.000000000 +0100 @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.7) 2012/07/31 +Fail2Ban (version 0.8.8) 2012/07/31 ================================================================================ Fail2Ban scans log files like /var/log/pwdfail and bans IP that makes too many @@ -31,8 +31,8 @@ To install, just do: -> tar xvfj fail2ban-0.8.7.tar.bz2 -> cd fail2ban-0.8.7 +> tar xvfj fail2ban-0.8.8.tar.bz2 +> cd fail2ban-0.8.8 > python setup.py install This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/common/protocol.py new/fail2ban-0.8.8/common/protocol.py --- old/fail2ban-0.8.7.1/common/protocol.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/common/protocol.py 2012-12-06 04:51:29.000000000 +0100 @@ -64,6 +64,7 @@ ["set <JAIL> bantime <TIME>", "sets the number of seconds <TIME> a host will be banned for <JAIL>"], ["set <JAIL> usedns <VALUE>", "sets the usedns mode for <JAIL>"], ["set <JAIL> banip <IP>", "manually Ban <IP> for <JAIL>"], +["set <JAIL> unbanip <IP>", "manually Unban <IP> in <JAIL>"], ["set <JAIL> maxretry <RETRY>", "sets the number of failures <RETRY> before banning the host for <JAIL>"], ["set <JAIL> addaction <ACT>", "adds a new action named <NAME> for <JAIL>"], ["set <JAIL> delaction <ACT>", "removes the action <NAME> from <JAIL>"], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/common/version.py new/fail2ban-0.8.8/common/version.py --- old/fail2ban-0.8.7.1/common/version.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/common/version.py 2012-12-06 04:51:29.000000000 +0100 @@ -21,8 +21,8 @@ # # $Revision$ -__author__ = "Cyril Jaquier" +__author__ = "Cyril Jaquier, Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko" __license__ = "GPL" -version = "0.8.7" +version = "0.8.8" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/config/action.d/complain.conf new/fail2ban-0.8.8/config/action.d/complain.conf --- old/fail2ban-0.8.7.1/config/action.d/complain.conf 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/config/action.d/complain.conf 2012-12-06 04:51:29.000000000 +0100 @@ -12,8 +12,22 @@ # any other addresses found in the whois record, with a few exceptions. # If no addresses are found, no e-mail is sent. # -# $Revision$ +# WARNING +# ------- # +# Please do not use this action unless you are certain that fail2ban +# does not result in "false positives" for your deployment. False +# positive reports could serve a mis-favor to the original cause by +# flooding corresponding contact addresses, and complicating the work +# of administration personnel responsible for handling (verified) legit +# complains. +# +# Please consider using e.g. sendmail-whois-lines.conf action which +# would send the reports with relevant information to you, so the +# report could be first reviewed and then forwarded to a corresponding +# contact if legit. +# + [Definition] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/config/filter.d/lighttpd-auth.conf new/fail2ban-0.8.8/config/filter.d/lighttpd-auth.conf --- old/fail2ban-0.8.7.1/config/filter.d/lighttpd-auth.conf 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/config/filter.d/lighttpd-auth.conf 2012-12-06 04:51:29.000000000 +0100 @@ -9,8 +9,7 @@ # Notes.: regex to match wrong passwords as notified by lighttpd's auth Module # Values: TEXT # -failregex = .*http_auth.*password doesn\'t match.*IP: <HOST>\s*$ - +failregex = .*http_auth.*(password doesn\'t match|wrong password).*IP: <HOST>\s*$ # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/config/filter.d/sshd.conf new/fail2ban-0.8.8/config/filter.d/sshd.conf --- old/fail2ban-0.8.7.1/config/filter.d/sshd.conf 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/config/filter.d/sshd.conf 2012-12-06 04:51:29.000000000 +0100 @@ -32,7 +32,6 @@ ^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$ ^%(__prefix_line)s(?:pam_unix\(sshd:auth\):\s)?authentication failure; logname=\S* uid=\S* euid=\S* tty=\S* ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$ ^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$ - ^%(__prefix_line)sAddress <HOST> .* POSSIBLE BREAK-IN ATTEMPT!*\s*$ ^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$ # Option: ignoreregex diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/fail2ban-client new/fail2ban-0.8.8/fail2ban-client --- old/fail2ban-0.8.7.1/fail2ban-client 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/fail2ban-client 2012-12-06 04:51:29.000000000 +0100 @@ -18,13 +18,7 @@ # along with Fail2Ban; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# Author: Cyril Jaquier -# -# $Revision$ - __author__ = "Cyril Jaquier" -__version__ = "$Revision$" -__date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -33,7 +27,9 @@ # Inserts our own modules path first in the list # fix for bug #343821 -sys.path.insert(1, "/usr/share/fail2ban") +if os.path.abspath(__file__).startswith('/usr/'): + # makes sense to use system-wide library iff -client is also under /usr/ + sys.path.insert(1, "/usr/share/fail2ban") # Now we can import our modules from common.version import version @@ -69,7 +65,7 @@ def dispVersion(self): print "Fail2Ban v" + version print - print "Copyright (c) 2004-2008 Cyril Jaquier" + print "Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors" print "Copyright of modifications held by their respective authors." print "Licensed under the GNU General Public License v2 (GPL)." print diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/fail2ban-regex new/fail2ban-0.8.8/fail2ban-regex --- old/fail2ban-0.8.7.1/fail2ban-regex 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/fail2ban-regex 2012-12-06 04:51:29.000000000 +0100 @@ -15,21 +15,17 @@ # along with Fail2Ban; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# Author: Cyril Jaquier -# -# $Revision$ - -__author__ = "Cyril Jaquier" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004 Cyril Jaquier" +__author__ = "Cyril Jaquier, Yaroslav Halchenko" +__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012 Yaroslav Halchenko" __license__ = "GPL" import getopt, sys, time, logging, os # Inserts our own modules path first in the list # fix for bug #343821 -sys.path.insert(1, "/usr/share/fail2ban") +if os.path.abspath(__file__).startswith('/usr/'): + # makes sense to use system-wide library iff -regex is also under /usr/ + sys.path.insert(1, "/usr/share/fail2ban") from client.configparserinc import SafeConfigParserWithIncludes from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/fail2ban-server new/fail2ban-0.8.8/fail2ban-server --- old/fail2ban-0.8.7.1/fail2ban-server 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/fail2ban-server 2012-12-06 04:51:29.000000000 +0100 @@ -18,21 +18,17 @@ # along with Fail2Ban; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# Author: Cyril Jaquier -# -# $Revision$ - __author__ = "Cyril Jaquier" -__version__ = "$Revision$" -__date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -import getopt, sys, logging +import getopt, sys, logging, os # Inserts our own modules path first in the list # fix for bug #343821 -sys.path.insert(1, "/usr/share/fail2ban") +if os.path.abspath(__file__).startswith('/usr/'): + # makes sense to use system-wide library iff -server is also under /usr/ + sys.path.insert(1, "/usr/share/fail2ban") from common.version import version from server.server import Server @@ -61,7 +57,7 @@ def dispVersion(self): print "Fail2Ban v" + version print - print "Copyright (c) 2004-2008 Cyril Jaquier" + print "Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors" print "Copyright of modifications held by their respective authors." print "Licensed under the GNU General Public License v2 (GPL)." print diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/fail2ban-testcases new/fail2ban-0.8.8/fail2ban-testcases --- old/fail2ban-0.8.7.1/fail2ban-testcases 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/fail2ban-testcases 2012-12-06 04:51:29.000000000 +0100 @@ -20,12 +20,8 @@ # along with Fail2Ban; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# Author: Cyril Jaquier - __author__ = "Cyril Jaquier" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004 Cyril Jaquier" +__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012- Yaroslav Halchenko" __license__ = "GPL" @@ -100,7 +96,8 @@ # Let know the version # if not opts.log_level or opts.log_level != 'fatal': - print "Fail2ban " + version + " test suite. Please wait..." + print "Fail2ban %s test suite. Python %s. Please wait..." \ + % (version, str(sys.version).replace('\n', '')) # @@ -125,6 +122,7 @@ tests.addTest(unittest.makeSuite(filtertestcase.LogFileMonitor)) tests.addTest(unittest.makeSuite(filtertestcase.GetFailures)) tests.addTest(unittest.makeSuite(filtertestcase.DNSUtilsTests)) +tests.addTest(unittest.makeSuite(filtertestcase.JailTests)) # DateDetector tests.addTest(unittest.makeSuite(datedetectortestcase.DateDetectorTest)) @@ -142,14 +140,14 @@ try: from server.filtergamin import FilterGamin filters.append(FilterGamin) -except: - pass +except Exception, e: + print "I: Skipping gamin backend testing. Got exception '%s'" % e try: from server.filterpyinotify import FilterPyinotify filters.append(FilterPyinotify) -except: - pass +except Exception, e: + print "I: Skipping pyinotify backend testing. Got exception '%s'" % e for Filter_ in filters: tests.addTest(unittest.makeSuite( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/fail2ban-testcases-all new/fail2ban-0.8.8/fail2ban-testcases-all --- old/fail2ban-0.8.7.1/fail2ban-testcases-all 1970-01-01 01:00:00.000000000 +0100 +++ new/fail2ban-0.8.8/fail2ban-testcases-all 2012-12-06 04:51:29.000000000 +0100 @@ -0,0 +1,18 @@ +#!/bin/bash +# Simple helper script to exercise unittests using all available +# (under /usr/bin and /usr/local/bin python2.*) + +set -eu + +failed= +for python in /usr/{,local/}bin/python2.[0-9]{,.*}{,-dbg} +do + [ -e "$python" ] || continue + echo "Testing using $python" + $python ./fail2ban-testcases "$@" || failed+=" $python" +done + +if [ ! -z "$failed" ]; then + echo "E: Failed with $failed" + exit 1 +fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/action.py new/fail2ban-0.8.8/server/action.py --- old/fail2ban-0.8.7.1/server/action.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/action.py 2012-12-06 04:51:29.000000000 +0100 @@ -37,6 +37,17 @@ # Create a lock for running system commands _cmd_lock = threading.Lock() +# Some hints on common abnormal exit codes +_RETCODE_HINTS = { + 0x7f00: '"Command not found". Make sure that all commands in %(realCmd)r ' + 'are in the PATH of fail2ban-server process ' + '(grep -a PATH= /proc/`pidof -x fail2ban-server`/environ). ' + 'You may want to start ' + '"fail2ban-server -f" separately, initiate it with ' + '"fail2ban-client reload" in another shell session and observe if ' + 'additional informative error messages appear in the terminals.' + } + ## # Execute commands. # @@ -230,7 +241,14 @@ def execActionStop(self): stopCmd = Action.replaceTag(self.__actionStop, self.__cInfo) return Action.executeCmd(stopCmd) - + + def escapeTag(tag): + for c in '\\#&;`|*?~<>^()[]{}$\n': + if c in tag: + tag = tag.replace(c, '\\' + c) + return tag + escapeTag = staticmethod(escapeTag) + ## # Replaces tags in query with property values in aInfo. # @@ -243,8 +261,13 @@ """ Replace tags in query """ string = query - for tag in aInfo: - string = string.replace('<' + tag + '>', str(aInfo[tag])) + for tag, value in aInfo.iteritems(): + value = str(value) # assure string + if tag == 'matches': + # That one needs to be escaped since its content is + # out of our control + value = Action.escapeTag(value) + string = string.replace('<' + tag + '>', value) # New line string = string.replace("<br>", '\n') return string @@ -318,7 +341,11 @@ logSys.debug("%s returned successfully" % realCmd) return True else: - logSys.error("%s returned %x" % (realCmd, retcode)) + msg = _RETCODE_HINTS.get(retcode, None) + logSys.error("%s returned %x" % (realCmd, retcode)) + if msg: + logSys.info("HINT on %x: %s" + % (retcode, msg % locals())) except OSError, e: logSys.error("%s failed with %s" % (realCmd, e)) finally: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/actions.py new/fail2ban-0.8.8/server/actions.py --- old/fail2ban-0.8.7.1/server/actions.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/actions.py 2012-12-06 04:51:29.000000000 +0100 @@ -121,6 +121,19 @@ return self.__banManager.getBanTime() ## + # Remove a banned IP now, rather than waiting for it to expire, even if set to never expire. + # + # @return the IP string or 'None' if not unbanned. + def removeBannedIP(self, ip): + # Find the ticket with the IP. + ticket = self.__banManager.getTicketByIP(ip) + if ticket is not None: + # Unban the IP. + self.__unBan(ticket) + return ip + return 'None' + + ## # Main loop. # # This function is the main loop of the thread. It checks the Jail @@ -163,13 +176,13 @@ aInfo["time"] = bTicket.getTime() aInfo["matches"] = "".join(bTicket.getMatches()) if self.__banManager.addBanTicket(bTicket): - logSys.warn("[%s] Ban %s" % (self.jail.getName(), str(aInfo["ip"]))) + logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"])) for action in self.__actions: action.execActionBan(aInfo) return True else: - logSys.warn("[%s] %s already banned" % (self.jail.getName(), - str(aInfo["ip"]))) + logSys.info("[%s] %s already banned" % (self.jail.getName(), + aInfo["ip"])) return False ## diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/banmanager.py new/fail2ban-0.8.8/server/banmanager.py --- old/fail2ban-0.8.7.1/server/banmanager.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/banmanager.py 2012-12-06 04:51:29.000000000 +0100 @@ -208,7 +208,7 @@ return unBanList finally: self.__lock.release() - + ## # Flush the ban list. # @@ -223,3 +223,21 @@ return uBList finally: self.__lock.release() + + ## + # Gets the ticket for the specified IP. + # + # @return the ticket for the IP or False. + def getTicketByIP(self, ip): + try: + self.__lock.acquire() + + # Find the ticket the IP goes with and return it + for i, ticket in enumerate(self.__banList): + if ticket.getIP() == ip: + # Return the ticket after removing (popping) + # if from the ban list. + return self.__banList.pop(i) + finally: + self.__lock.release() + return None # if none found diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/filter.py new/fail2ban-0.8.8/server/filter.py --- old/fail2ban-0.8.7.1/server/filter.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/filter.py 2012-12-06 04:51:29.000000000 +0100 @@ -27,6 +27,7 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" +from failmanager import FailManagerEmpty from failmanager import FailManager from ticket import FailTicket from jailthread import JailThread @@ -220,10 +221,18 @@ # to enable banip fail2ban-client BAN command def addBannedIP(self, ip): - unixTime = time.time() + unixTime = MyTime.time() for i in xrange(self.failManager.getMaxRetry()): self.failManager.addFailure(FailTicket(ip, unixTime)) + # Perform the banning of the IP now. + try: + while True: + ticket = self.failManager.toBan() + self.jail.putFailTicket(ticket) + except FailManagerEmpty: + self.failManager.cleanup(MyTime.time()) + return ip ## diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/filterpyinotify.py new/fail2ban-0.8.8/server/filterpyinotify.py --- old/fail2ban-0.8.7.1/server/filterpyinotify.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/filterpyinotify.py 2012-12-06 04:51:29.000000000 +0100 @@ -23,12 +23,18 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Lee Clemens, 2012 Yaroslav Halchenko" __license__ = "GPL" +from distutils.version import LooseVersion + from failmanager import FailManagerEmpty from filter import FileFilter from mytime import MyTime import time, logging, pyinotify +if not hasattr(pyinotify, '__version__') \ + or LooseVersion(pyinotify.__version__) < '0.8.3': + raise ImportError("Fail2Ban requires pyinotify >= 0.8.3") + from os.path import dirname, sep as pathsep # Gets the instance of the logger. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/jail.py new/fail2ban-0.8.8/server/jail.py --- old/fail2ban-0.8.7.1/server/jail.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/jail.py 2012-12-06 04:51:29.000000000 +0100 @@ -33,7 +33,9 @@ class Jail: #Known backends. Each backend should have corresponding __initBackend method - _BACKENDS = ('pyinotify', 'gamin', 'polling') + # yoh: stored in a list instead of a tuple since only + # list had .index until 2.6 + _BACKENDS = ['pyinotify', 'gamin', 'polling'] def __init__(self, name, backend = "auto"): self.__name = name diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/server.py new/fail2ban-0.8.8/server/server.py --- old/fail2ban-0.8.7.1/server/server.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/server.py 2012-12-06 04:51:29.000000000 +0100 @@ -241,6 +241,9 @@ def setBanIP(self, name, value): return self.__jails.getFilter(name).addBannedIP(value) + def setUnbanIP(self, name, value): + return self.__jails.getAction(name).removeBannedIP(value) + def getBanTime(self, name): return self.__jails.getAction(name).getBanTime() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/ticket.py new/fail2ban-0.8.8/server/ticket.py --- old/fail2ban-0.8.7.1/server/ticket.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/ticket.py 2012-12-06 04:51:29.000000000 +0100 @@ -42,7 +42,7 @@ @param matches (log) lines caused the ticket """ - self.__ip = ip + self.setIP(ip) self.__time = time self.__attempt = 0 self.__file = None @@ -54,6 +54,9 @@ def setIP(self, value): + if isinstance(value, basestring): + # guarantee using regular str instead of unicode for the IP + value = str(value) self.__ip = value def getIP(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/server/transmitter.py new/fail2ban-0.8.8/server/transmitter.py --- old/fail2ban-0.8.7.1/server/transmitter.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/server/transmitter.py 2012-12-06 04:51:29.000000000 +0100 @@ -55,7 +55,8 @@ ret = self.__commandHandler(command) ack = 0, ret except Exception, e: - logSys.warn("Invalid command: " + `command`) + logSys.warn("Command %r has failed. Received %r" + % (command, e)) ack = 1, e return ack @@ -174,6 +175,9 @@ elif command[1] == "banip": value = command[2] return self.__server.setBanIP(name,value) + elif command[1] == "unbanip": + value = command[2] + return self.__server.setUnbanIP(name,value) elif command[1] == "addaction": value = command[2] self.__server.addAction(name, value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/setup.py new/fail2ban-0.8.8/setup.py --- old/fail2ban-0.8.7.1/setup.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/setup.py 2012-12-06 04:51:29.000000000 +0100 @@ -18,13 +18,7 @@ # along with Fail2Ban; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# Author: Cyril Jaquier -# -# $Revision$ - __author__ = "Cyril Jaquier" -__version__ = "$Revision$" -__date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/testcases/actiontestcase.py new/fail2ban-0.8.8/testcases/actiontestcase.py --- old/fail2ban-0.8.7.1/testcases/actiontestcase.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/testcases/actiontestcase.py 2012-12-06 04:51:29.000000000 +0100 @@ -28,7 +28,9 @@ __license__ = "GPL" import unittest, time +import logging, sys from server.action import Action +from StringIO import StringIO class ExecuteAction(unittest.TestCase): @@ -36,15 +38,43 @@ """Call before every test case.""" self.__action = Action("Test") + # 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')) + def tearDown(self): """Call after every test case.""" + # print "O: >>%s<<" % self._log.getvalue() + logSys = logging.getLogger("fail2ban") + logSys.handlers = self._old_handlers + logSys.level = self._old_level self.__action.execActionStop() - + + def _is_logged(self, s): + return s in self._log.getvalue() + 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 ]") - + + self.assertFalse(self._is_logged('returned')) + # no action was actually executed yet + self.assertTrue(self.__action.execActionBan(None)) - + 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"')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/testcases/failmanagertestcase.py new/fail2ban-0.8.8/testcases/failmanagertestcase.py --- old/fail2ban-0.8.7.1/testcases/failmanagertestcase.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/testcases/failmanagertestcase.py 2012-12-06 04:51:29.000000000 +0100 @@ -35,11 +35,11 @@ def setUp(self): """Call before every test case.""" - self.__items = [['193.168.0.128', 1167605999.0], - ['193.168.0.128', 1167605999.0], - ['193.168.0.128', 1167605999.0], - ['193.168.0.128', 1167605999.0], - ['193.168.0.128', 1167605999.0], + self.__items = [[u'193.168.0.128', 1167605999.0], + [u'193.168.0.128', 1167605999.0], + [u'193.168.0.128', 1167605999.0], + [u'193.168.0.128', 1167605999.0], + [u'193.168.0.128', 1167605999.0], ['87.142.124.10', 1167605999.0], ['87.142.124.10', 1167605999.0], ['87.142.124.10', 1167605999.0], @@ -80,6 +80,7 @@ #ticket = FailTicket('193.168.0.128', None) ticket = self.__failManager.toBan() self.assertEqual(ticket.getIP(), "193.168.0.128") + self.assertTrue(isinstance(ticket.getIP(), str)) def testbanNOK(self): self.__failManager.setMaxRetry(10) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/testcases/files/logs/lighttpd new/fail2ban-0.8.8/testcases/files/logs/lighttpd --- old/fail2ban-0.8.7.1/testcases/files/logs/lighttpd 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/testcases/files/logs/lighttpd 2012-12-06 04:51:29.000000000 +0100 @@ -1,2 +1,3 @@ #authentification failure (mod_auth) 2011-12-25 17:09:20: (http_auth.c.875) password doesn't match for /gitweb/ username: francois, IP: 4.4.4.4 +2012-09-26 10:24:35: (http_auth.c.1136) digest: auth failed for xxx : wrong password, IP: 4.4.4.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/testcases/files/logs/sshd new/fail2ban-0.8.8/testcases/files/logs/sshd --- old/fail2ban-0.8.7.1/testcases/files/logs/sshd 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/testcases/files/logs/sshd 2012-12-06 04:51:29.000000000 +0100 @@ -22,6 +22,7 @@ Nov 11 23:33:27 Server sshd[5174]: refused connect from _U2FsdGVkX19P3BCJmFBHhjLza8BcMH06WCUVwttMHpE=_@::ffff:218.249.210.161 (::ffff:218.249.210.161) #7 added exclamation mark to BREAK-IN +# Now should be a negative since we decided not to catch those Oct 15 19:51:35 server sshd[7592]: Address 1.2.3.4 maps to 1234.bbbbbb.com, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT Oct 15 19:51:35 server sshd[7592]: Address 1.2.3.4 maps to 1234.bbbbbb.com, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fail2ban-0.8.7.1/testcases/filtertestcase.py new/fail2ban-0.8.8/testcases/filtertestcase.py --- old/fail2ban-0.8.7.1/testcases/filtertestcase.py 2012-08-01 03:45:04.000000000 +0200 +++ new/fail2ban-0.8.8/testcases/filtertestcase.py 2012-12-06 04:51:29.000000000 +0100 @@ -28,6 +28,7 @@ import time import tempfile +from server.jail import Jail from server.filterpoll import FilterPoll from server.filter import FileFilter, DNSUtils from server.failmanager import FailManager @@ -626,3 +627,10 @@ self.assertEqual(res, ['192.0.43.10']) else: self.assertEqual(res, []) + +class JailTests(unittest.TestCase): + + def testSetBackend_gh83(self): + # smoke test + jail = Jail('test', backend='polling') # Must not fail to initiate + -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
