File: filterpoll.py

package info (click to toggle)
fail2ban 0.7.5-2etch1
  • links: PTS
  • area: main
  • in suites: etch
  • size: 620 kB
  • ctags: 754
  • sloc: python: 3,245; sh: 735; makefile: 43
file content (141 lines) | stat: -rw-r--r-- 3,987 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# This file is part of Fail2Ban.
#
# Fail2Ban is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Author: Cyril Jaquier
# 
# $Revision: 354 $

__author__ = "Cyril Jaquier"
__version__ = "$Revision: 354 $"
__date__ = "$Date: 2006-09-13 23:31:22 +0200 (Wed, 13 Sep 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

from failmanager import FailManagerEmpty
from filter import Filter
from mytime import MyTime

import time, logging, os

# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.filter")

##
# Log reader class.
#
# This class reads a log file and detects login failures or anything else
# that matches a given regular expression. This class is instanciated by
# a Jail object.

class FilterPoll(Filter):

	##
	# Constructor.
	#
	# Initialize the filter object with default values.
	# @param jail the jail object
	
	def __init__(self, jail):
		Filter.__init__(self, jail)
		self.__modified = False
		## The time of the last modification of the file.
		self.__lastModTime = dict()
		self.__file404Cnt = dict()
		logSys.info("Created FilterPoll")

	##
	# Add a log file path
	#
	# @param path log file path

	def addLogPath(self, path):
		if self.containsLogPath(path):
			logSys.error(path + " already exists")
		else:
			self.__lastModTime[path] = 0
			self.__file404Cnt[path] = 0
			Filter.addLogPath(self, path)
			logSys.info("Added logfile = %s" % path)	
	
	##
	# Delete a log path
	#
	# @param path the log file to delete
	
	def delLogPath(self, path):
		if not self.containsLogPath(path):
			logSys.error(path + " is not monitored")
		else:
			del self.__lastModTime[path]
			del self.__file404Cnt[path]
			Filter.delLogPath(self, path)
			logSys.info("Removed logfile = %s" % path)
	
	##
	# Main loop.
	#
	# This function is the main loop of the thread. It checks if the
	# file has been modified and looks for failures.
	# @return True when the thread exits nicely

	def run(self):
		self.setActive(True)
		while self.isActive():
			if not self.getIdle():
				# Get file modification
				for f in self.getLogPath():
					if self.isModified(f):
						self.getFailures(f)
						self.__modified = True

				if self.__modified:
					try:
						ticket = self.failManager.toBan()
						self.jail.putFailTicket(ticket)
					except FailManagerEmpty:
						self.failManager.cleanup(MyTime.time())
					self.dateDetector.sortTemplate()
					self.__modified = False
				time.sleep(self.getSleepTime())
			else:
				time.sleep(self.getSleepTime())
		logSys.debug(self.jail.getName() + ": filter terminated")
		return True

	##
	# Checks if the log file has been modified.
	#
	# Checks if the log file has been modified using os.stat().
	# @return True if log file has been modified
	
	def isModified(self, filename):
		try:
			logStats = os.stat(filename)
			self.__file404Cnt[filename] = 0
			if self.__lastModTime[filename] == logStats.st_mtime:
				return False
			else:
				logSys.debug(filename + " has been modified")
				self.__lastModTime[filename] = logStats.st_mtime
				return True
		except OSError:
			logSys.error("Unable to get stat on " + filename)
			self.__file404Cnt[filename] = self.__file404Cnt[filename] + 1
			if self.__file404Cnt[filename] > 2:
				logSys.warn("Too much read error. Set the jail idle")
				self.jail.setIdle(True)
				self.__file404Cnt[filename] = 0
			return False