Created jira script
[clearscm.git] / bin / bice.py
1 #!/usr/bin/python
2
3 import sys
4 import getopt
5 import fcntl
6 import re
7
8 from array import *
9
10 security_logfile = '/var/log/auth.log'
11 verbose = False
12 debug   = False
13 update  = False
14 email   = False
15
16 def Error (msg = '', errno = 0):
17   sys.stderr.write ('Error: ' + msg)
18
19   if (errno <> 0):  
20     sys.exit (errno)
21
22 def Verbose (msg, linefeed = True):
23   global verbose
24   
25   if (linefeed):
26     msg += '\n'
27     
28   if (verbose):
29     print msg
30
31 def Usage (msg = ''):
32   if msg != '':
33     print msg
34     
35   print """
36 Usage: bice.py [-u|sage] [-v|erbose] [-d|ebug] [-nou|pdate] [-nom|ail]
37                [-f|ilename <filename> ]
38
39 Where:
40   -u|sage     Print this usage
41   -v|erbose:  Verbose mode (Default: -verbose)
42   -nou|pdate: Don't update security logfile file (Default: -update)
43   -nom|ail:   Don't send emails (Default: -mail)
44   -f|ilename: Open alternate messages file (Default: /var/log/auth.log)
45   """
46   
47   sys.exit (1)
48
49 def processLogfile (logfile):
50   violations = {}
51     
52   try:
53     readlog = open (logfile)
54
55     fcntl.flock (readlog, fcntl.LOCK_EX)
56   except IOError:
57     Error ("Unable to get exclusive access to " + logfile + " - $!", 1)
58     
59   invalid_user           = re.compile ("^(\S+\s+\S+\s+\S+)\s+.*Invalid user (\w+) from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})")
60   authentication_failure = re.compile ("^(\S+\s+\S+\s+\S+)\s+.*authentication failure.*ruser=(\S+).*rhost=(\S+)")
61   failed_password        = re.compile ("^(\S+\s+\S+\s+\S+)\s+.*Failed password for (\w+) from (\d{1,3}\.\d{1,3}\.d{1,3}\.d{1,3})")
62   
63   for newline in readlog:
64     violation = {}
65     newline = newline.strip ()
66     
67     timestamp = ''
68     user      = ''
69     ip        = ''
70     
71     for (timestamp, user, ip) in invalid_user.findall (newline):
72       continue
73       
74     for (timestamp, user, ip) in authentication_failure.findall (newline):
75       continue
76       
77     for (timestamp, user, ip) in failed_password.findall (newline):
78       continue
79      
80     if (ip == ''):
81       continue
82       
83     if (ip in violations):
84       violation = violations[ip]
85
86     if (user in violation):
87       violation[user].append (timestamp)
88     else:
89       violation[user] = [];
90       violation[user].append (timestamp)
91     
92     violations[ip] = violation
93     
94   return violations
95
96 def ReportBreakins (logfile):
97   violations = processLogfile (logfile)
98   
99   nbrViolations = len (violations)
100   
101   if (nbrViolations == 0):
102     Verbose ('No violations found')
103   elif (nbrViolations == 1):
104     Verbose ('1 site attempting to violate our perimeter')
105   else:
106     Verbose ('{} violations'.format(nbrViolations))
107
108   for ip in violations:
109     print 'IP: ' + ip + ' violations:'
110     for key in sorted (violations[ip].iterkeys ()):
111       print "\t{}: {}".format (key, violations[ip][key])
112                     
113 def dumpargs ():
114   global verbose, debug, update, email, security_logfile
115
116   print 'Args:'
117   print 'verbose', verbose
118   print 'debug',   debug
119   print 'update',  update
120   print 'email',   email
121   print 'file',    security_logfile
122
123 def main (argv):
124   global verbose, debug, update, email, security_logfile
125   
126   try:
127     opts, args = getopt.getopt (argv, "vd", ['verbose', 'debug', 'usage', 'update', 'mail', 'file='])
128   except getopt.GetoptError:
129     Usage ();
130     sys.exit (1);
131
132   for opt, arg in opts:
133     if opt in ['-v', '--verbose']:
134       verbose = 1
135     elif opt in ['-d', '--debug']:
136       debug = 1
137     elif opt in ['-u', '--usage']:
138       Usage 
139     elif opt in ['--update']:
140       update = 1
141     elif opt in ['-m', '--mail']:
142       email = 1
143     elif opt in ['-f', '--file']:
144       security_logfile = arg
145   
146   if security_logfile == '':
147     Usage ('Must specify filename')
148     
149   ReportBreakins (security_logfile)
150 #  dumpargs ()
151   
152 if __name__ == '__main__':
153   main (sys.argv [1:])