Compare commits
9
Commits
debian/python3
...
0.6.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ba3346dec | ||
|
|
ed0f57dbad | ||
|
|
0a8f24c5f4 | ||
|
|
8a253db9b5 | ||
|
|
adf7827efd | ||
|
|
bfbf8a70d2 | ||
|
|
089770d1c0 | ||
|
|
2304f07a38 | ||
|
|
22995edd97 |
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>fail2ban-stable</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?>
|
||||
|
||||
<pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.4</pydev_property>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/fail2ban-stable/confreader</path>
|
||||
<path>/fail2ban-stable/firewall</path>
|
||||
<path>/fail2ban-stable/logreader</path>
|
||||
<path>/fail2ban-stable/utils</path>
|
||||
</pydev_pathproperty>
|
||||
</pydev_project>
|
||||
@@ -4,9 +4,19 @@
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
=============================================================
|
||||
Fail2Ban (version 0.6.1) 2006/03/16
|
||||
Fail2Ban (version 0.6.2) 2006/12/11
|
||||
=============================================================
|
||||
|
||||
ver. 0.6.2 (2006/12/11) - stable
|
||||
----------
|
||||
- Fixed UTF-8 log file parsing
|
||||
- Propagated patches introduced by Debian maintainer
|
||||
(Yaroslav Halchenko):
|
||||
* Made locale configurable
|
||||
* Fixed warning if ignoreip is empty
|
||||
- Added named group "host" for "failregex". Fixed security
|
||||
vulnerability CVE-2006-6302
|
||||
|
||||
ver. 0.6.1 (2006/03/16) - stable
|
||||
----------
|
||||
- Added permanent banning. Set banTime to a negative value to
|
||||
@@ -22,7 +32,7 @@ ver. 0.6.1 (2006/03/16) - stable
|
||||
- Added parsing of timestamp in TAI64N format (#1275325).
|
||||
Thanks to Mark Edgington
|
||||
- Added patch #1382936 (Default formatted syslog logging).
|
||||
Thanks to Patrick Börjesson
|
||||
Thanks to Patrick B�rjesson
|
||||
- Removed 192.168.0.0/16 from ignoreip. Attacks could also
|
||||
come from the local network.
|
||||
- Robust startup: if iptables module does not get fully
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
=============================================================
|
||||
Fail2Ban (version 0.6.1) 2006/03/16
|
||||
Fail2Ban (version 0.6.2) 2006/12/11
|
||||
=============================================================
|
||||
|
||||
Fail2Ban scans log files like /var/log/pwdfail and bans IP
|
||||
@@ -58,8 +58,8 @@ Require: python-2.4 (http://www.python.org)
|
||||
|
||||
To install, just do:
|
||||
|
||||
> tar xvfj fail2ban-0.6.1.tar.bz2
|
||||
> cd fail2ban-0.6.1
|
||||
> tar xvfj fail2ban-0.6.2.tar.bz2
|
||||
> cd fail2ban-0.6.2
|
||||
> python setup.py install
|
||||
|
||||
This will install Fail2Ban into /usr/lib/fail2ban. The
|
||||
@@ -116,6 +116,12 @@ options:
|
||||
-v verbose. Use twice for greater effect
|
||||
-V print software version
|
||||
|
||||
Please note that a vulnerability (CVE-2006-6302) affects
|
||||
version < 0.6.2. Since 0.6.2, a named group "host" was added
|
||||
to "failregex". This group must match the host address. Old
|
||||
configuration files will still work but will generate a
|
||||
warning. In this case, please update your configuration file.
|
||||
|
||||
Contact:
|
||||
--------
|
||||
|
||||
@@ -130,10 +136,10 @@ Cyril Jaquier: <lostcontrol@users.sourceforge.net>
|
||||
Thanks:
|
||||
-------
|
||||
|
||||
Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker,
|
||||
Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker,
|
||||
Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko,
|
||||
Jonathan Kamens, Stephen Gildea, Markus Hoffmann, Mark
|
||||
Edgington, Patrick Börjesson, kojiro, zugeschmiert
|
||||
Edgington, Patrick Börjesson, kojiro, zugeschmiert
|
||||
|
||||
License:
|
||||
--------
|
||||
|
||||
@@ -11,6 +11,15 @@
|
||||
#
|
||||
background = false
|
||||
|
||||
# Option: locale
|
||||
# Notes.: global (cannot be redefined per section) locale to use for
|
||||
# timestamp pattern matching by changing LC_TIME for
|
||||
# fail2ban process. Empty entry sets locale to default one
|
||||
# (usually specified by LC_ALL environment variable).
|
||||
# Values: LOCALE Default:
|
||||
#
|
||||
locale =
|
||||
|
||||
# Option: logtargets
|
||||
# Notes.: log targets. Space separated list of logging targets.
|
||||
# Values: STDERR SYSLOG file Default: /var/log/fail2ban.log
|
||||
@@ -248,7 +257,7 @@ timepattern = %%a %%b %%d %%H:%%M:%%S %%Y
|
||||
# Notes.: regex to match the password failure messages in the logfile.
|
||||
# Values: TEXT Default: authentication failure|user .* not found
|
||||
#
|
||||
failregex = authentication failure|user .* not found
|
||||
failregex = [[]client (?P<host>\S*)[]] user .*(?:: authentication failure|not found)
|
||||
|
||||
|
||||
[VSFTPD]
|
||||
@@ -288,7 +297,7 @@ timepattern = %%b %%d %%H:%%M:%%S
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT Default: Authentication failure|Failed password|Invalid user
|
||||
#
|
||||
failregex = FAIL LOGIN
|
||||
failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=(?P<host>\S+)
|
||||
|
||||
|
||||
[SSH]
|
||||
@@ -324,4 +333,4 @@ timepattern = %%b %%d %%H:%%M:%%S
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT Default: Authentication failure|Failed password|Invalid user
|
||||
#
|
||||
failregex = Authentication failure|Failed password|Invalid user
|
||||
failregex = : (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)
|
||||
|
||||
@@ -11,6 +11,15 @@
|
||||
#
|
||||
background = false
|
||||
|
||||
# Option: locale
|
||||
# Notes.: global (cannot be redefined per section) locale to use for
|
||||
# timestamp pattern matching by changing LC_TIME for
|
||||
# fail2ban process. Empty entry sets locale to default one
|
||||
# (usually specified by LC_ALL environment variable).
|
||||
# Values: LOCALE Default:
|
||||
#
|
||||
locale =
|
||||
|
||||
# Option: logtargets
|
||||
# Notes.: log targets. Space separated list of logging targets.
|
||||
# Values: STDERR SYSLOG file Default: /var/log/fail2ban.log
|
||||
@@ -276,7 +285,7 @@ timepattern = %%a %%b %%d %%H:%%M:%%S %%Y
|
||||
# Notes.: regex to match the password failure messages in the logfile.
|
||||
# Values: TEXT Default: authentication failure|user .* not found
|
||||
#
|
||||
failregex = authentication failure|user .* not found
|
||||
failregex = [[]client (?P<host>\S*)[]] user .*(?:: authentication failure|not found)
|
||||
|
||||
|
||||
[VSFTPD]
|
||||
@@ -316,7 +325,7 @@ timepattern = %%b %%d %%H:%%M:%%S
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT Default: Authentication failure|Failed password|Invalid user
|
||||
#
|
||||
failregex = FAIL LOGIN
|
||||
failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=(?P<host>\S+)
|
||||
|
||||
|
||||
[SSH]
|
||||
@@ -330,8 +339,7 @@ enabled = true
|
||||
# Notes.: logfile to monitor.
|
||||
# Values: FILE Default: /var/log/secure
|
||||
#
|
||||
#logfile = /var/log/secure
|
||||
logfile = /home/cyril/workspace/fail2ban-stable/log-test/test
|
||||
logfile = /var/log/secure
|
||||
|
||||
# Option: port
|
||||
# Notes.: specifies port to monitor
|
||||
@@ -359,4 +367,4 @@ timepattern = %%b %%d %%H:%%M:%%S
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT Default: Authentication failure|Failed password|Invalid user
|
||||
#
|
||||
failregex = Authentication failure|Failed password|Invalid user
|
||||
failregex = : (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)
|
||||
|
||||
@@ -11,6 +11,15 @@
|
||||
#
|
||||
background = false
|
||||
|
||||
# Option: locale
|
||||
# Notes.: global (cannot be redefined per section) locale to use for
|
||||
# timestamp pattern matching by changing LC_TIME for
|
||||
# fail2ban process. Empty entry sets locale to default one
|
||||
# (usually specified by LC_ALL environment variable).
|
||||
# Values: LOCALE Default:
|
||||
#
|
||||
locale =
|
||||
|
||||
# Option: logtargets
|
||||
# Notes.: log targets. Space separated list of logging targets.
|
||||
# Values: STDERR SYSLOG file Default: /var/log/fail2ban.log
|
||||
@@ -242,7 +251,8 @@ timepattern = %%a %%b %%d %%H:%%M:%%S %%Y
|
||||
# Notes.: regex to match the password failure messages in the logfile.
|
||||
# Values: TEXT Default: authentication failure|user .* not found
|
||||
#
|
||||
failregex = authentication failure|user .* not found
|
||||
failregex = [[]client (?P<host>\S*)[]] user .*(?:: authentication failure|not found)
|
||||
|
||||
|
||||
[VSFTPD]
|
||||
# Option: enabled
|
||||
@@ -275,7 +285,7 @@ timepattern = %%b %%d %%H:%%M:%%S
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT Default: Authentication failure|Failed password|Invalid user
|
||||
#
|
||||
failregex = FAIL LOGIN
|
||||
failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=(?P<host>\S+)
|
||||
|
||||
|
||||
[SSH]
|
||||
@@ -311,4 +321,4 @@ timepattern = %%b %%d %%H:%%M:%%S
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT Default: Authentication failure|Failed password|Invalid user
|
||||
#
|
||||
failregex = Authentication failure|Failed password|Invalid user
|
||||
failregex = : (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)
|
||||
|
||||
@@ -26,14 +26,7 @@ __date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import sys, traceback, logging, locale
|
||||
|
||||
# Set the locale with the user's default setting
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
except Exception:
|
||||
print "Unable to set locale to " + `locale.getdefaultlocale()`
|
||||
sys.exit(-1)
|
||||
import sys, traceback, logging
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
|
||||
+58
-46
@@ -25,7 +25,8 @@ __date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import time, sys, getopt, os, string, signal, logging, logging.handlers, copy
|
||||
import time, sys, getopt, os, string, signal, logging, logging.handlers, \
|
||||
copy, locale
|
||||
from ConfigParser import *
|
||||
|
||||
from version import version
|
||||
@@ -192,7 +193,7 @@ def main():
|
||||
# Reads the command line options.
|
||||
try:
|
||||
cmdOpts = 'hvVbdkc:t:i:r:p:'
|
||||
cmdLongOpts = ['help','version']
|
||||
cmdLongOpts = ['help', 'version']
|
||||
optList, args = getopt.getopt(sys.argv[1:], cmdOpts, cmdLongOpts)
|
||||
except getopt.GetoptError:
|
||||
dispUsage()
|
||||
@@ -212,19 +213,20 @@ def main():
|
||||
confReader.openConf()
|
||||
|
||||
# Options
|
||||
optionValues = (["bool", "background", False],
|
||||
["str", "logtargets", "/var/log/fail2ban.log"],
|
||||
["str", "syslog-target", "/dev/log"],
|
||||
["int", "syslog-facility", 1],
|
||||
["str", "pidlock", "/var/run/fail2ban.pid"],
|
||||
["int", "maxfailures", 5],
|
||||
["int", "bantime", 600],
|
||||
["int", "findtime", 600],
|
||||
["str", "ignoreip", ""],
|
||||
["int", "polltime", 1],
|
||||
["str", "cmdstart", ""],
|
||||
["str", "cmdend", ""],
|
||||
["int", "reinittime", 100],
|
||||
optionValues = (["bool", "background", False],
|
||||
["str", "logtargets", "/var/log/fail2ban.log"],
|
||||
["str", "syslog-target", "/dev/log"],
|
||||
["int", "syslog-facility", 1],
|
||||
["str", "pidlock", "/var/run/fail2ban.pid"],
|
||||
["str", "locale", ""],
|
||||
["int", "maxfailures", 5],
|
||||
["int", "bantime", 600],
|
||||
["int", "findtime", 600],
|
||||
["str", "ignoreip", ""],
|
||||
["int", "polltime", 1],
|
||||
["str", "cmdstart", ""],
|
||||
["str", "cmdend", ""],
|
||||
["int", "reinittime", 100],
|
||||
["int", "maxreinits", 100])
|
||||
|
||||
# Gets global configuration options
|
||||
@@ -236,6 +238,14 @@ def main():
|
||||
# PID lock
|
||||
pidLock.setPath(conf["pidlock"])
|
||||
|
||||
# Set the LC_TIME with the user's default setting
|
||||
try:
|
||||
logSys.info("Setting LC_TIME locale option to '%s'"%conf["locale"])
|
||||
locale.setlocale(locale.LC_TIME, conf["locale"])
|
||||
except Exception:
|
||||
logSys.error("Unable to set locale to '%s'"%conf["locale"])
|
||||
sys.exit(-1)
|
||||
|
||||
# Now we can kill properly a running instance if needed
|
||||
if conf["kill"]:
|
||||
pid = pidLock.exists()
|
||||
@@ -270,7 +280,7 @@ def main():
|
||||
# a socket (file, so it starts with /)
|
||||
# or hostname
|
||||
# or hostname:port
|
||||
syslogtargets = re.findall("(/[\w/]*)|([^/ ][^: ]*)(:(\d+)){,1}",
|
||||
syslogtargets = re.findall("(/[\w/]*)|([^/ ][^: ]*)(:(\d+)){,1}",
|
||||
conf["syslog-target"])
|
||||
# we are waiting for a single match
|
||||
syslogtargets = syslogtargets[0]
|
||||
@@ -284,7 +294,7 @@ def main():
|
||||
if len(syslogtargets) == 0: # everything default
|
||||
hdlr = logging.handlers.SysLogHandler()
|
||||
else:
|
||||
if not ( syslogtargets[0] == "" ): # got socket
|
||||
if not (syslogtargets[0] == ""): # got socket
|
||||
syslogtarget = syslogtargets[0]
|
||||
else: # got hostname and maybe a port
|
||||
if syslogtargets[3] == "": # no port specified
|
||||
@@ -326,7 +336,9 @@ def main():
|
||||
"ONLY DISPLAYED IN THE LOG MESSAGES")
|
||||
|
||||
# Ignores IP list
|
||||
ignoreIPList = conf["ignoreip"].split(' ')
|
||||
# and filter out empty entries. Otherwise
|
||||
# WARNING: is not a valid IP address
|
||||
ignoreIPList = filter(None, conf["ignoreip"].split(' '))
|
||||
|
||||
# Checks for root user. This is necessary because log files
|
||||
# are owned by root and firewall needs root access.
|
||||
@@ -352,15 +364,15 @@ def main():
|
||||
logSys.debug("MaxFailure is " + `conf["maxfailures"]`)
|
||||
|
||||
# Options
|
||||
optionValues = (["bool", "enabled", False],
|
||||
["str", "host", "localhost"],
|
||||
["int", "port", "25"],
|
||||
["str", "from", "root"],
|
||||
["str", "to", "root"],
|
||||
["str", "user", ''],
|
||||
["str", "password", ''],
|
||||
["bool", "localtime", False],
|
||||
["str", "subject", "[Fail2Ban] Banned <ip>"],
|
||||
optionValues = (["bool", "enabled", False],
|
||||
["str", "host", "localhost"],
|
||||
["int", "port", "25"],
|
||||
["str", "from", "root"],
|
||||
["str", "to", "root"],
|
||||
["str", "user", ''],
|
||||
["str", "password", ''],
|
||||
["bool", "localtime", False],
|
||||
["str", "subject", "[Fail2Ban] Banned <ip>"],
|
||||
["str", "message", "Fail2Ban notification"])
|
||||
|
||||
# Gets global configuration options
|
||||
@@ -378,18 +390,18 @@ def main():
|
||||
logSys.debug("to: " + mailConf["to"] + " from: " + mailConf["from"])
|
||||
|
||||
# Options
|
||||
optionValues = (["bool", "enabled", False],
|
||||
["str", "logfile", "/dev/null"],
|
||||
["int", "maxfailures", conf["maxfailures"]],
|
||||
["int", "bantime", conf["bantime"]],
|
||||
["int", "findtime", conf["findtime"]],
|
||||
["str", "timeregex", ""],
|
||||
["str", "timepattern", ""],
|
||||
["str", "failregex", ""],
|
||||
["str", "fwstart", ""],
|
||||
["str", "fwend", ""],
|
||||
["str", "fwban", ""],
|
||||
["str", "fwunban", ""],
|
||||
optionValues = (["bool", "enabled", False],
|
||||
["str", "logfile", "/dev/null"],
|
||||
["int", "maxfailures", conf["maxfailures"]],
|
||||
["int", "bantime", conf["bantime"]],
|
||||
["int", "findtime", conf["findtime"]],
|
||||
["str", "timeregex", ""],
|
||||
["str", "timepattern", ""],
|
||||
["str", "failregex", ""],
|
||||
["str", "fwstart", ""],
|
||||
["str", "fwend", ""],
|
||||
["str", "fwban", ""],
|
||||
["str", "fwunban", ""],
|
||||
["str", "fwcheck", ""])
|
||||
|
||||
logSys.info("Fail2Ban v" + version + " is running")
|
||||
@@ -399,10 +411,10 @@ def main():
|
||||
l = confReader.getLogOptions(t, optionValues)
|
||||
if l["enabled"]:
|
||||
# Creates a logreader object
|
||||
lObj = LogReader(l["logfile"], l["timeregex"], l["timepattern"],
|
||||
lObj = LogReader(l["logfile"], l["timeregex"], l["timepattern"],
|
||||
l["failregex"], l["maxfailures"], l["findtime"])
|
||||
# Creates a firewall object
|
||||
fObj = Firewall(l["fwstart"], l["fwend"], l["fwban"], l["fwunban"],
|
||||
fObj = Firewall(l["fwstart"], l["fwend"], l["fwban"], l["fwunban"],
|
||||
l["fwcheck"], l["bantime"])
|
||||
# "Name" the firewall
|
||||
fObj.setSection(t)
|
||||
@@ -474,7 +486,7 @@ def main():
|
||||
e = element[1].getFailures()
|
||||
for key in e.iterkeys():
|
||||
if element[3].has_key(key):
|
||||
element[3][key] = (element[3][key][0] + e[key][0],
|
||||
element[3][key] = (element[3][key][0] + e[key][0],
|
||||
e[key][1])
|
||||
else:
|
||||
element[3][key] = (e[key][0], e[key][1])
|
||||
@@ -491,9 +503,9 @@ def main():
|
||||
if failTime < unixTime - findTime:
|
||||
del element[3][attempt]
|
||||
elif fails[attempt][0] >= element[1].getMaxRetry():
|
||||
aInfo = {"section": element[0],
|
||||
"ip": attempt,
|
||||
"failures": element[3][attempt][0],
|
||||
aInfo = {"section": element[0],
|
||||
"ip": attempt,
|
||||
"failures": element[3][attempt][0],
|
||||
"failtime": failTime}
|
||||
logSys.info(element[0] + ": " + aInfo["ip"] +
|
||||
" has " + `aInfo["failures"]` +
|
||||
@@ -501,7 +513,7 @@ def main():
|
||||
element[2].addBanIP(aInfo, conf["debug"])
|
||||
# Send a mail notification
|
||||
if 'mail' in locals():
|
||||
mail.sendmail(mailConf["subject"],
|
||||
mail.sendmail(mailConf["subject"],
|
||||
mailConf["message"], aInfo)
|
||||
del element[3][attempt]
|
||||
except ExternalError, e:
|
||||
|
||||
+15
-1
@@ -136,6 +136,11 @@ class LogReader:
|
||||
self.setFilePos(logFile)
|
||||
lastLine = None
|
||||
for line in logFile:
|
||||
try:
|
||||
# Try to convert UTF-8 string to Latin-1
|
||||
line = line.decode('utf-8').encode('latin-1')
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
if not self.hasTime(line):
|
||||
# There is no valid time in this line
|
||||
continue
|
||||
@@ -172,7 +177,16 @@ class LogReader:
|
||||
timeMatch = re.search(self.timeregex, match.string)
|
||||
if timeMatch:
|
||||
date = self.getUnixTime(timeMatch.group())
|
||||
ipMatch = textToIp(match.string)
|
||||
try:
|
||||
# Fix for CVE-2006-6302
|
||||
matchString = match.group("host")
|
||||
except IndexError:
|
||||
# However does not break the current configuration
|
||||
logSys.warn("No 'host' group defined. This is a security " +
|
||||
"issue. Please fix your configuration file " +
|
||||
"and look at CVE-2006-6302")
|
||||
matchString = match.string
|
||||
ipMatch = textToIp(matchString)
|
||||
if ipMatch:
|
||||
for ip in ipMatch:
|
||||
failList.append([ip, date])
|
||||
|
||||
+1
-1
@@ -24,4 +24,4 @@ __date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
|
||||
Reference in New Issue
Block a user