diff --git a/COPYING b/COPYING index d511905c..aae0eb8f 100644 --- a/COPYING +++ b/COPYING @@ -1,3 +1,7 @@ +The following copyright applies to all files present in the Fail2ban package, +except if a different copyright is explicitly defined in this file. + + GNU GENERAL PUBLIC LICENSE Version 2, June 1991 @@ -337,3 +341,28 @@ proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. + +--------------------------------- +The file server/iso8601.py is licensed under the following terms. + + +Copyright (c) 2007 Michael Twomey + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ChangeLog b/ChangeLog index f9c82d8e..c54efc49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,19 +4,31 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.2) 2008/03/06 +Fail2Ban (version 0.8.3) 2008/07/17 ============================================================= -From ver. 0.8.3 (2008/??/??) - stable +ver. 0.8.3 (2008/07/17) - stable ---------- - Process failtickets as long as failmanager is not empty. +- Added "pam-generic" filter and more configuration fixes. + Thanks to Yaroslav Halchenko. +- Fixed socket path in redhat and suse init script. Thanks to + Jim Wight. - Fixed PID file while started in daemon mode. Thanks to Christian Jobic who submitted a similar patch. - Fixed "fail2ban-client get logpath". Bug #1916986. -- Changed some log levels. - Added gssftpd filter. Thanks to Kevin Zembower. - Added "Day/Month/Year Hour:Minute:Second" date template. Thanks to Dennis Winter. +- Fixed ignoreregex processing in fail2ban-client. Thanks to + René Berber. +- Added ISO 8601 date/time format. +- Added and changed some logging level and messages. +- Added missing ignoreregex to filters. Thanks to Klaus + Lehmann. +- Use poll instead of select in asyncore.loop. This should + solve the "Unknown error 514". Thanks to Michael Geiger and + Klaus Lehmann. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/PKG-INFO b/PKG-INFO index 74670ebd..4a30de06 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: fail2ban -Version: 0.8.2 +Version: 0.8.3 Summary: Ban IPs that make too many password failure Home-page: http://www.fail2ban.org Author: Cyril Jaquier diff --git a/README b/README index d9e1e3f0..d413aca7 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.2) 2008/03/06 +Fail2Ban (version 0.8.3) 2008/07/17 ============================================================= Fail2Ban scans log files like /var/log/pwdfail and bans IP @@ -28,8 +28,8 @@ Optional: To install, just do: -> tar xvfj fail2ban-0.8.2.tar.bz2 -> cd fail2ban-0.8.2 +> tar xvfj fail2ban-0.8.3.tar.bz2 +> cd fail2ban-0.8.3 > python setup.py install This will install Fail2Ban into /usr/share/fail2ban. The diff --git a/client/jailreader.py b/client/jailreader.py index af245ae1..c77aad57 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 659 $ +# $Revision: 690 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 659 $" -__date__ = "$Date: 2008-03-05 00:09:30 +0100 (Wed, 05 Mar 2008) $" +__version__ = "$Revision: 690 $" +__date__ = "$Date: 2008-05-12 10:34:42 +0200 (Mon, 12 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -122,7 +122,10 @@ class JailReader(ConfigReader): elif opt == "failregex": stream.append(["set", self.__name, "failregex", self.__opts[opt]]) elif opt == "ignoreregex": - stream.append(["set", self.__name, "ignoreregex", self.__opts[opt]]) + for regex in self.__opts[opt].split('\n'): + # Do not send a command if the rule is empty. + if regex != '': + stream.append(["set", self.__name, "addignoreregex", regex]) stream.extend(self.__filter.convert()) for action in self.__actions: stream.extend(action.convert()) diff --git a/common/version.py b/common/version.py index 3dd7f9bf..416848bb 100644 --- a/common/version.py +++ b/common/version.py @@ -16,12 +16,12 @@ # Author: Cyril Jaquier # -# $Revision: 673 $ +# $Revision: 703 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 673 $" -__date__ = "$Date: 2008-03-06 00:19:45 +0100 (Thu, 06 Mar 2008) $" +__version__ = "$Revision: 703 $" +__date__ = "$Date: 2008-07-17 23:28:51 +0200 (Thu, 17 Jul 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -version = "0.8.2" +version = "0.8.3" diff --git a/config/action.d/mail-buffered.conf b/config/action.d/mail-buffered.conf index da7f2d68..04788ab9 100644 --- a/config/action.d/mail-buffered.conf +++ b/config/action.d/mail-buffered.conf @@ -2,7 +2,7 @@ # # Author: Cyril Jaquier # -# $Revision: 668 $ +# $Revision: 701 $ # [Definition] @@ -50,7 +50,7 @@ actioncheck = # actionban = printf %%b "`date`: ( failures)\n" >> LINE=$( wc -l | awk '{ print $1 }' ) - if [ $LINE -eq ]; then + if [ $LINE -ge ]; then printf %%b "Hi,\n These hosts have been banned by Fail2Ban.\n `cat ` diff --git a/config/action.d/sendmail-buffered.conf b/config/action.d/sendmail-buffered.conf index c37a71d2..90a482de 100644 --- a/config/action.d/sendmail-buffered.conf +++ b/config/action.d/sendmail-buffered.conf @@ -2,7 +2,7 @@ # # Author: Cyril Jaquier # -# $Revision: 660 $ +# $Revision: 701 $ # [Definition] @@ -59,7 +59,7 @@ actioncheck = # actionban = printf %%b "`date`: ( failures)\n" >> LINE=$( wc -l | awk '{ print $1 }' ) - if [ $LINE -eq ]; then + if [ $LINE -ge ]; then printf %%b "Subject: [Fail2Ban] : summary From: Fail2Ban <> To: \n diff --git a/config/filter.d/gssftpd.conf b/config/filter.d/gssftpd.conf index 15fe6871..ee000ed9 100644 --- a/config/filter.d/gssftpd.conf +++ b/config/filter.d/gssftpd.conf @@ -2,7 +2,7 @@ # # Author: Kevin Zembower (copied from wsftpd.conf) # -# $Revision: 1 $ +# $Revision: 699 $ # [Definition] @@ -12,3 +12,9 @@ # Values: TEXT # failregex = ftpd(?:\[\d+\])?:\s+repeated login failures from \(\S+\)$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/named-refused.conf b/config/filter.d/named-refused.conf index c6aed9bb..69b36970 100644 --- a/config/filter.d/named-refused.conf +++ b/config/filter.d/named-refused.conf @@ -4,7 +4,7 @@ # # Author: Yaroslav Halchenko # -# $Revision: 616 $ +# $Revision: 699 $ # [Definition] @@ -28,4 +28,8 @@ __line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)? # failregex = %(__line_prefix)sclient #\S+: query(?: \(cache\))? '.*' denied\s*$ - +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/pam-generic.conf b/config/filter.d/pam-generic.conf index 55e9efd0..7e48a08d 100644 --- a/config/filter.d/pam-generic.conf +++ b/config/filter.d/pam-generic.conf @@ -23,3 +23,9 @@ __pam_combs_re=(?:%(__pid_re)s?:\s+%(__pam_re)s|%(__pam_re)s%(__pid_re)s?:) # Values: TEXT # failregex = \s\S+ \S+%(__pam_combs_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=(?:\s+user=.*)?\s*$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/proftpd.conf b/config/filter.d/proftpd.conf index 52a741e8..552c2935 100644 --- a/config/filter.d/proftpd.conf +++ b/config/filter.d/proftpd.conf @@ -2,7 +2,7 @@ # # Author: Yaroslav Halchenko # -# $Revision: 665 $ +# $Revision: 677 $ # [Definition] @@ -14,7 +14,7 @@ # (?:::f{4,6}:)?(?P\S+) # Values: TEXT # -failregex = \(\S+\[\]\)[: -]+ USER \S+: no such user found from \S+ \[[0-9.]+\] to \S+:\S+$ +failregex = \(\S+\[\]\)[: -]+ USER \S+: no such user found from \S+ \[\S+\] to \S+:\S+$ \(\S+\[\]\)[: -]+ USER \S+ \(Login failed\): Incorrect password\.$ \(\S+\[\]\)[: -]+ SECURITY VIOLATION: \S+ login attempted\.$ \(\S+\[\]\)[: -]+ Maximum login attempts \(\d+\) exceeded$ diff --git a/config/filter.d/wuftpd.conf b/config/filter.d/wuftpd.conf index 7c2a8acb..0bf997b1 100644 --- a/config/filter.d/wuftpd.conf +++ b/config/filter.d/wuftpd.conf @@ -2,7 +2,7 @@ # # Author: Yaroslav Halchenko # -# $Revision: 592 $ +# $Revision: 699 $ # [Definition] @@ -12,3 +12,9 @@ # Values: TEXT # failregex = wu-ftpd(?:\[\d+\])?:\s+\(pam_unix\)\s+authentication failure.* rhost=$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/debian/changelog b/debian/changelog index fe71ae5b..cbdfac9c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fail2ban (0.8.2-4) UNRELEASED; urgency=low + + * Adjusted vcs paths + + -- Yaroslav Halchenko Thu, 17 Jul 2008 11:21:15 -0400 + fail2ban (0.8.2-3) unstable; urgency=low * Changes propagated from upstream trunk (future 0.8.3): diff --git a/debian/control b/debian/control index 1ae7275b..415bb903 100644 --- a/debian/control +++ b/debian/control @@ -6,8 +6,8 @@ Build-Depends: debhelper (>= 5.0.37.2), python Build-Depends-Indep: python-central (>= 0.5.6) XS-Python-Version: current, >= 2.4 Homepage: http://www.fail2ban.org -Vcs-Browser: http://git.onerussian.com/?p=fail2ban -Vcs-git: http://git.onerussian.com/vcs/fail2ban +Vcs-Browser: http://git.onerussian.com/?p=deb/fail2ban.git +Vcs-git: http://git.onerussian.com/vcs/deb/fail2ban.git Standards-Version: 3.7.3 diff --git a/files/redhat-initd b/files/redhat-initd index 529aef25..75c7f808 100755 --- a/files/redhat-initd +++ b/files/redhat-initd @@ -27,7 +27,7 @@ start() { echo -n $"Starting fail2ban: " getpid if [ -z "$pid" ]; then - rm -rf /tmp/fail2ban.sock # in case of unclean shutdown + rm -rf /var/run/fail2ban/fail2ban.sock # in case of unclean shutdown $FAIL2BAN start > /dev/null RETVAL=$? fi diff --git a/files/suse-initd b/files/suse-initd index bbd679aa..ecd55d9a 100755 --- a/files/suse-initd +++ b/files/suse-initd @@ -16,7 +16,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/sbin:/usr/bin:/bin FAIL2BAN_BIN=/usr/local/bin/fail2ban-client FAIL2BAN_SERVER=/usr/local/bin/fail2ban-server -FAIL2BAN_SOCKET=/tmp/fail2ban.sock +FAIL2BAN_SOCKET=/var/run/fail2ban/fail2ban.sock test -x $FAIL2BAN_BIN || { echo "$FAIL2BAN_BIN not installed"; if [ "$1" = "stop" ]; then exit 0; else exit 5; fi; } diff --git a/server/action.py b/server/action.py index 41c85241..70f4c378 100644 --- a/server/action.py +++ b/server/action.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 635 $ +# $Revision: 682 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 635 $" -__date__ = "$Date: 2007-12-16 22:38:04 +0100 (Sun, 16 Dec 2007) $" +__version__ = "$Revision: 682 $" +__date__ = "$Date: 2008-04-08 00:25:16 +0200 (Tue, 08 Apr 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" diff --git a/server/asyncserver.py b/server/asyncserver.py index 548a8226..13a74dac 100644 --- a/server/asyncserver.py +++ b/server/asyncserver.py @@ -132,7 +132,7 @@ class AsyncServer(asyncore.dispatcher): # Sets the init flag. self.__init = True # TODO Add try..catch - asyncore.loop() + asyncore.loop(use_poll = True) ## # Stops the communication server. diff --git a/server/datedetector.py b/server/datedetector.py index 85dcc4c0..4198a1cd 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -16,19 +16,17 @@ # Author: Cyril Jaquier # -# $Revision: 645 $ +# $Revision: 692 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 645 $" -__date__ = "$Date: 2008-01-16 23:55:04 +0100 (Wed, 16 Jan 2008) $" +__version__ = "$Revision: 692 $" +__date__ = "$Date: 2008-05-18 21:53:18 +0200 (Sun, 18 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" import time, logging -from datetemplate import DateStrptime -from datetemplate import DateTai64n -from datetemplate import DateEpoch +from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601 from threading import Lock # Gets the instance of the logger. @@ -99,6 +97,10 @@ class DateDetector: template = DateEpoch() template.setName("Epoch") self.__templates.append(template) + # ISO 8601 + template = DateISO8601() + template.setName("ISO 8601") + self.__templates.append(template) finally: self.__lock.release() diff --git a/server/datetemplate.py b/server/datetemplate.py index 25c2d71d..18d433d6 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -17,17 +17,18 @@ # Author: Cyril Jaquier # -# $Revision: 652 $ +# $Revision: 692 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 652 $" -__date__ = "$Date: 2008-02-29 00:01:30 +0100 (Fri, 29 Feb 2008) $" +__version__ = "$Revision: 692 $" +__date__ = "$Date: 2008-05-18 21:53:18 +0200 (Sun, 18 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" import re, time from mytime import MyTime +import iso8601 class DateTemplate: @@ -163,4 +164,24 @@ class DateTai64n(DateTemplate): value = dateMatch.group() seconds_since_epoch = value[2:17] date = list(time.gmtime(int(seconds_since_epoch, 16))) - return date \ No newline at end of file + return date + + +class DateISO8601(DateTemplate): + + def __init__(self): + DateTemplate.__init__(self) + date_re = "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}" \ + ".[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?" \ + "(Z|(([-+])([0-9]{2}):([0-9]{2})))?" + self.setRegex(date_re) + + def getDate(self, line): + date = None + dateMatch = self.matchDate(line) + if dateMatch: + # Parses the date. + value = dateMatch.group() + print value + date = list(iso8601.parse_date(value).utctimetuple()) + return date diff --git a/server/filter.py b/server/filter.py index 0cf5b08b..6ccd81fe 100644 --- a/server/filter.py +++ b/server/filter.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 656 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 656 $" -__date__ = "$Date: 2008-03-04 01:17:56 +0100 (Tue, 04 Mar 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -68,7 +68,7 @@ class Filter(JailThread): self.dateDetector = DateDetector() self.dateDetector.addDefaultTemplate() - logSys.info("Created Filter") + logSys.debug("Created Filter") ## diff --git a/server/filtergamin.py b/server/filtergamin.py index 87d7f7a3..445e9b8d 100644 --- a/server/filtergamin.py +++ b/server/filtergamin.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 649 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 649 $" -__date__ = "$Date: 2008-02-02 18:04:11 +0100 (Sat, 02 Feb 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -53,7 +53,7 @@ class FilterGamin(FileFilter): self.__modified = False # Gamin monitor self.monitor = gamin.WatchMonitor() - logSys.info("Created FilterGamin") + logSys.debug("Created FilterGamin") def callback(self, path, event): diff --git a/server/filterpoll.py b/server/filterpoll.py index 6fa61678..00b26b2d 100644 --- a/server/filterpoll.py +++ b/server/filterpoll.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 649 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 649 $" -__date__ = "$Date: 2008-02-02 18:04:11 +0100 (Sat, 02 Feb 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -54,7 +54,7 @@ class FilterPoll(FileFilter): ## The time of the last modification of the file. self.__lastModTime = dict() self.__file404Cnt = dict() - logSys.info("Created FilterPoll") + logSys.debug("Created FilterPoll") ## # Add a log file path diff --git a/server/iso8601.py b/server/iso8601.py new file mode 100644 index 00000000..71dccfea --- /dev/null +++ b/server/iso8601.py @@ -0,0 +1,123 @@ +# Copyright (c) 2007 Michael Twomey +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +"""ISO 8601 date time string parsing + +Basic usage: +>>> import iso8601 +>>> iso8601.parse_date("2007-01-25T12:00:00Z") +datetime.datetime(2007, 1, 25, 12, 0, tzinfo=) +>>> + +""" + +from datetime import datetime, timedelta, tzinfo +import re + +__all__ = ["parse_date", "ParseError"] + +# Adapted from http://delete.me.uk/2005/03/iso8601.html +ISO8601_REGEX = re.compile(r"(?P[0-9]{4})(-(?P[0-9]{1,2})(-(?P[0-9]{1,2})" + r"((?P.)(?P[0-9]{2}):(?P[0-9]{2})(:(?P[0-9]{2})(\.(?P[0-9]+))?)?" + r"(?PZ|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?" +) +TIMEZONE_REGEX = re.compile("(?P[+-])(?P[0-9]{2}).(?P[0-9]{2})") + +class ParseError(Exception): + """Raised when there is a problem parsing a date string""" + +# Yoinked from python docs +ZERO = timedelta(0) +class Utc(tzinfo): + """UTC + + """ + def utcoffset(self, dt): + return ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return ZERO +UTC = Utc() + +class FixedOffset(tzinfo): + """Fixed offset in hours and minutes from UTC + + """ + def __init__(self, offset_hours, offset_minutes, name): + self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes) + self.__name = name + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return self.__name + + def dst(self, dt): + return ZERO + + def __repr__(self): + return "" % self.__name + +def parse_timezone(tzstring, default_timezone=UTC): + """Parses ISO 8601 time zone specs into tzinfo offsets + + """ + if tzstring == "Z": + return default_timezone + # This isn't strictly correct, but it's common to encounter dates without + # timezones so I'll assume the default (which defaults to UTC). + # Addresses issue 4. + if tzstring is None: + return default_timezone + m = TIMEZONE_REGEX.match(tzstring) + prefix, hours, minutes = m.groups() + hours, minutes = int(hours), int(minutes) + if prefix == "-": + hours = -hours + minutes = -minutes + return FixedOffset(hours, minutes, tzstring) + +def parse_date(datestring, default_timezone=UTC): + """Parses ISO 8601 dates into datetime objects + + The timezone is parsed from the date string. However it is quite common to + have dates without a timezone (not strictly correct). In this case the + default timezone specified in default_timezone is used. This is UTC by + default. + """ + if not isinstance(datestring, basestring): + raise ParseError("Expecting a string %r" % datestring) + m = ISO8601_REGEX.match(datestring) + if not m: + raise ParseError("Unable to parse date string %r" % datestring) + groups = m.groupdict() + tz = parse_timezone(groups["timezone"], default_timezone=default_timezone) + if groups["fraction"] is None: + groups["fraction"] = 0 + else: + groups["fraction"] = int(float("0.%s" % groups["fraction"]) * 1e6) + return datetime(int(groups["year"]), int(groups["month"]), int(groups["day"]), + int(groups["hour"]), int(groups["minute"]), int(groups["second"]), + int(groups["fraction"]), tz) diff --git a/server/jail.py b/server/jail.py index 1d006de3..ca123e88 100644 --- a/server/jail.py +++ b/server/jail.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 567 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 567 $" -__date__ = "$Date: 2007-03-26 23:17:31 +0200 (Mon, 26 Mar 2007) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -37,6 +37,7 @@ class Jail: self.__name = name self.__queue = Queue.Queue() self.__filter = None + logSys.info("Creating new jail '%s'" % self.__name) if backend == "polling": self.__initPoller() else: @@ -47,14 +48,14 @@ class Jail: self.__action = Actions(self) def __initPoller(self): - logSys.info("Using poller") + logSys.info("Jail '%s' uses poller" % self.__name) from filterpoll import FilterPoll self.__filter = FilterPoll(self) def __initGamin(self): # Try to import gamin import gamin - logSys.info("Using Gamin") + logSys.info("Jail '%s' uses Gamin" % self.__name) from filtergamin import FilterGamin self.__filter = FilterGamin(self) @@ -82,12 +83,14 @@ class Jail: def start(self): self.__filter.start() self.__action.start() + logSys.info("Jail '%s' started" % self.__name) def stop(self): self.__filter.stop() self.__action.stop() self.__filter.join() self.__action.join() + logSys.info("Jail '%s' stopped" % self.__name) def isAlive(self): isAlive0 = self.__filter.isAlive() diff --git a/server/server.py b/server/server.py index 6e0ebeda..941fc43c 100644 --- a/server/server.py +++ b/server/server.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 647 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 647 $" -__date__ = "$Date: 2008-01-20 17:30:35 +0100 (Sun, 20 Jan 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -46,11 +46,11 @@ class Server: self.__daemon = daemon self.__transm = Transmitter(self) self.__asyncServer = AsyncServer(self.__transm) - self.__logLevel = 3 - self.__logTarget = "STDOUT" + self.__logLevel = None + self.__logTarget = None # Set logging level - self.setLogLevel(self.__logLevel) - self.setLogTarget(self.__logTarget) + self.setLogLevel(3) + self.setLogTarget("STDOUT") def __sigTERMhandler(self, signum, frame): logSys.debug("Caught signal %d. Exiting" % signum) @@ -66,6 +66,7 @@ class Server: # First set the mask to only allow access to owner os.umask(0077) if self.__daemon: + logSys.info("Starting in daemon mode") ret = self.__createDaemon() if ret: logSys.info("Daemon started") @@ -345,7 +346,6 @@ class Server: logSys.error("Unable to log to " + target) logSys.info("Logging to previous target " + self.__logTarget) return False - self.__logTarget = target # Removes previous handlers for handler in logging.getLogger("fail2ban").handlers: # Closes the handler. @@ -354,6 +354,12 @@ class Server: # tell the handler to use this format hdlr.setFormatter(formatter) logging.getLogger("fail2ban").addHandler(hdlr) + # Does not display this message at startup. + if not self.__logTarget == None: + logSys.info("Changed logging target to %s for Fail2ban v%s" % + (target, version.version)) + # Sets the logging target. + self.__logTarget = target return True finally: self.__loggingLock.release() diff --git a/setup.py b/setup.py index d30b6810..c0f6c649 100755 --- a/setup.py +++ b/setup.py @@ -18,11 +18,11 @@ # Author: Cyril Jaquier # -# $Revision: 671 $ +# $Revision: 678 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 671 $" -__date__ = "$Date: 2008-03-06 00:12:41 +0100 (Thu, 06 Mar 2008) $" +__version__ = "$Revision: 678 $" +__date__ = "$Date: 2008-03-10 23:34:46 +0100 (Mon, 10 Mar 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -68,6 +68,9 @@ setup( ), ('/etc/fail2ban/action.d', glob("config/action.d/*.conf") + ), + ('/var/run/fail2ban', + '' ) ] )