mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 03:06:10 +00:00
Broken worker: First clone of ssh does not include information
2nd maybe too
This commit is contained in:
parent
a515f03904
commit
8a57773fcc
2 changed files with 90 additions and 34 deletions
|
@ -17,7 +17,10 @@ class PeriodTaks():
|
||||||
#Define message types
|
#Define message types
|
||||||
FROM_KERNEL = 1
|
FROM_KERNEL = 1
|
||||||
TO_KERNEL = 2
|
TO_KERNEL = 2
|
||||||
|
|
||||||
|
def debug(self,msg):
|
||||||
|
print "WDBG ",msg
|
||||||
|
|
||||||
def __init__(self,outqueue,inqueue, timeout,sleeptime, logfile):
|
def __init__(self,outqueue,inqueue, timeout,sleeptime, logfile):
|
||||||
self.outqueue= outqueue
|
self.outqueue= outqueue
|
||||||
self.inqueue = inqueue
|
self.inqueue = inqueue
|
||||||
|
@ -39,54 +42,79 @@ class PeriodTaks():
|
||||||
#Get current date if the files are older than the timeout remove them
|
#Get current date if the files are older than the timeout remove them
|
||||||
t0 = int(time.strftime("%s"))
|
t0 = int(time.strftime("%s"))
|
||||||
files = dircache.listdir(queue)
|
files = dircache.listdir(queue)
|
||||||
|
mlist = []
|
||||||
for file in files:
|
for file in files:
|
||||||
af = queue + os.sep + file
|
af = queue + os.sep + file
|
||||||
|
self.debug("found file : %s"%af)
|
||||||
s = os.stat(af)
|
s = os.stat(af)
|
||||||
t1 = int(s[os.path.stat.ST_CTIME])
|
t1 = int(s[os.path.stat.ST_CTIME])
|
||||||
delta = t0 - t1
|
delta = t0 - t1
|
||||||
if (delta > self.timeout):
|
if (delta > self.timeout):
|
||||||
|
self.debug("%s exceeds threshold"%af)
|
||||||
#Old file was found record it
|
#Old file was found record it
|
||||||
if queue == self.outqueue:
|
if queue == self.outqueue:
|
||||||
msg = self.record_message(af,t1,PeriodTaks.FROM_KERNEL)
|
msg = self.record_message(af,t1,PeriodTaks.FROM_KERNEL)
|
||||||
|
mlist.append(msg)
|
||||||
if queue == self.inqueue:
|
if queue == self.inqueue:
|
||||||
msg = self.record_message(af,t1,PeriodTaks.TO_KERNEL)
|
msg = self.record_message(af,t1,PeriodTaks.TO_KERNEL)
|
||||||
|
mlist.append(msg)
|
||||||
#Remove it
|
#Remove it
|
||||||
self.aha.silent_clean(af)
|
self.aha.silent_clean(af)
|
||||||
#Return the message for further processing
|
return mlist
|
||||||
return msg
|
|
||||||
|
|
||||||
def clean_input_queue(self):
|
def clean_input_queue(self):
|
||||||
try:
|
try:
|
||||||
self.remove_old_msg(self.inqueue)
|
self.remove_old_msg(self.inqueue)
|
||||||
except OSError,e:
|
except OSError,e:
|
||||||
sys.stderr.write(str(e))
|
sys.stderr.write("%s\n"%str(e))
|
||||||
|
|
||||||
|
def maintain_process_tree(self,mlist,exportFile):
|
||||||
|
if mlist == None:
|
||||||
|
return
|
||||||
|
for msg in mlist:
|
||||||
|
self.handle_msg(msg,exportFile)
|
||||||
|
|
||||||
def maintain_process_tree(self,msg):
|
def handle_msg(self,msg,exportFile):
|
||||||
try:
|
try:
|
||||||
pid = int(msg['pid'][0])
|
if msg:
|
||||||
ppid = int(msg['ppid'][0])
|
type = int(msg['type'][0])
|
||||||
type = int(msg['type'][0])
|
pid = int(msg['pid'][0])
|
||||||
#Focus on do_execve messages
|
ppid = int(msg['ppid'][0])
|
||||||
if (type == 1 ) or (type== 2):
|
#sys_execve messages
|
||||||
self.ptree.searchTree(pid,ppid)
|
if (type == 1):
|
||||||
#Focus on sys_close
|
self.debug('Got sys_execve message')
|
||||||
if (type == 3):
|
#Is there a new user
|
||||||
self.ptree.silent_remove_pid(pid)
|
file = msg['file'][0]
|
||||||
except IndexError,e:
|
self.debug('Got command: %s'%file)
|
||||||
|
if file == '/usr/sbin/sshd':
|
||||||
|
self.debug("New user found %s"%pid)
|
||||||
|
self.ptree.addUser(pid)
|
||||||
|
#Check all pids and ppids
|
||||||
|
if self.ptree.searchTree(pid,ppid):
|
||||||
|
self.ptree.annotateProcessList(msg)
|
||||||
|
self.debug("User related command")
|
||||||
|
self.ptree.exportUserListTxt(exportFile)
|
||||||
|
else:
|
||||||
|
self.debug("System related command")
|
||||||
|
#TODO free annotated list
|
||||||
|
# Remove dead processes from process tree
|
||||||
|
if (type == 3):
|
||||||
|
pid = int(msg['pid'][0])
|
||||||
|
self.ptree.silent_remove_pid(pid)
|
||||||
|
except KeyError,e:
|
||||||
pass
|
pass
|
||||||
except ValueError,e:
|
except ValueError,e:
|
||||||
pass
|
pass
|
||||||
|
except IndexError,e:
|
||||||
|
pass
|
||||||
|
|
||||||
def clean_output_queue(self):
|
def clean_output_queue(self):
|
||||||
try:
|
try:
|
||||||
msg = self.remove_old_msg(self.outqueue)
|
mlist = self.remove_old_msg(self.outqueue)
|
||||||
if msg:
|
#Propagate message list for further processor
|
||||||
self.maintain_process_tree(msg)
|
return mlist
|
||||||
|
|
||||||
except OSError,e:
|
except OSError,e:
|
||||||
sys.stderr.write(str(e))
|
sys.stderr.write("%s\n"%(str(e)))
|
||||||
|
|
||||||
#Parse the file an put the information in a log file for later processing
|
#Parse the file an put the information in a log file for later processing
|
||||||
#One log file is handier than for each message a file
|
#One log file is handier than for each message a file
|
||||||
|
@ -106,7 +134,7 @@ class PeriodTaks():
|
||||||
return msg
|
return msg
|
||||||
except IOError,e:
|
except IOError,e:
|
||||||
sys.stderr.write('Failed to record message: %s\n'%filename)
|
sys.stderr.write('Failed to record message: %s\n'%filename)
|
||||||
return None
|
return mlist
|
||||||
|
|
||||||
def usage(exitcode):
|
def usage(exitcode):
|
||||||
print """
|
print """
|
||||||
|
@ -148,12 +176,15 @@ try:
|
||||||
inqueue = c.get('common','inqueue')
|
inqueue = c.get('common','inqueue')
|
||||||
outqueue= c.get('common','outqueue')
|
outqueue= c.get('common','outqueue')
|
||||||
logfile = c.get('worker','logfile')
|
logfile = c.get('worker','logfile')
|
||||||
|
userlistFile = c.get('worker','exportdir') + os.sep + 'userlist'
|
||||||
|
|
||||||
p = PeriodTaks(outqueue, inqueue, timeout,sleeptime,logfile)
|
p = PeriodTaks(outqueue, inqueue, timeout,sleeptime,logfile)
|
||||||
print "Start working ..."
|
print "Start working ..."
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
p.clean_input_queue()
|
p.clean_input_queue()
|
||||||
p.clean_output_queue()
|
mlist = p.clean_output_queue()
|
||||||
|
p.maintain_process_tree(mlist,userlistFile)
|
||||||
time.sleep(sleeptime)
|
time.sleep(sleeptime)
|
||||||
print "Resume ..."
|
print "Resume ..."
|
||||||
|
|
||||||
|
|
|
@ -104,14 +104,29 @@ class ProcessTrees:
|
||||||
self.processList = {}
|
self.processList = {}
|
||||||
self.foundUser = 0
|
self.foundUser = 0
|
||||||
self.aplist = {}
|
self.aplist = {}
|
||||||
|
#This first clone of /usr/sbin/sshd does not has the
|
||||||
|
#SSH specific environment variables
|
||||||
|
#FIXME search is only done at first level of the tree
|
||||||
|
#pid is the ssh clone for this user
|
||||||
|
def search_ssh_info(self,pid):
|
||||||
|
for child in self.processList:
|
||||||
|
if child == pid:
|
||||||
|
#Found a child of the first priviledged seperated process
|
||||||
|
if self.aplist[child].has_key('ssh_client'):
|
||||||
|
return self.aplist[child]['ssh_client']
|
||||||
|
# Retuns None if ssh related information was not found
|
||||||
|
return None
|
||||||
|
|
||||||
# Record additional information about processes like SSH parameters
|
# Record additional information about processes like SSH parameters
|
||||||
# and timestamps etc
|
# and timestamps etc
|
||||||
#TODO annotate SSH_LOGNAME
|
#TODO annotate SSH_LOGNAME
|
||||||
#TODO annotate used terminal
|
#TODO annotate used terminal
|
||||||
def annotateProcessList(self,msg):
|
def annotateProcessList(self,msg):
|
||||||
try:
|
try:
|
||||||
pid = msg['pid'][0]
|
pid = int(msg['pid'][0])
|
||||||
ppid = msg['ppid'][0]
|
ppid = int(msg['ppid'][0])
|
||||||
|
print "Annotate process ",pid
|
||||||
|
print msg
|
||||||
if self.aplist.has_key(pid) == False:
|
if self.aplist.has_key(pid) == False:
|
||||||
#Got a new process, so create a new dictionary for meta data
|
#Got a new process, so create a new dictionary for meta data
|
||||||
self.aplist[pid] = dict()
|
self.aplist[pid] = dict()
|
||||||
|
@ -125,10 +140,12 @@ class ProcessTrees:
|
||||||
if ev.startswith('SSH_CLIENT='):
|
if ev.startswith('SSH_CLIENT='):
|
||||||
ev = ev.replace('SSH_CLIENT=','')
|
ev = ev.replace('SSH_CLIENT=','')
|
||||||
self.aplist[pid]['ssh_client'] = ev
|
self.aplist[pid]['ssh_client'] = ev
|
||||||
break
|
print"GROAAAAAAAAAAAAAAAAAAAAARRRRRRRRRRRRRRR: ",pid
|
||||||
# Is there a timestamp?
|
# Is there a timestamp?
|
||||||
if msg.has_key('timestamp'):
|
if msg.has_key('timestamp'):
|
||||||
self.aplist[pid]['timestamp'] = msg['timestamp']
|
self.aplist[pid]['timestamp'] = msg['timestamp']
|
||||||
|
print "annotated list"
|
||||||
|
print self.aplist
|
||||||
|
|
||||||
except ValueError,e:
|
except ValueError,e:
|
||||||
pass
|
pass
|
||||||
|
@ -182,13 +199,21 @@ class ProcessTrees:
|
||||||
for pid in self.userList.keys():
|
for pid in self.userList.keys():
|
||||||
#See if some annotation is found for this pid
|
#See if some annotation is found for this pid
|
||||||
if self.aplist.has_key(pid):
|
if self.aplist.has_key(pid):
|
||||||
if self.aplist[pid].has_key('ssh_client'):
|
#Look for SSH variables in the first child process
|
||||||
f.write("User:%s\n"%self.aplist[pid]['ssh_client'])
|
sshinfo = self.search_ssh_info(pid)
|
||||||
if self.aplist[pid].has_key('timestamp'):
|
if sshinfo:
|
||||||
#Convert timestamp
|
f.write(sshinfo)
|
||||||
ts = self.aplist[pid]['timestamp']
|
else:
|
||||||
obj=datetime.datetime.fromtimestamp(float(ts))
|
sys.stderr.write("No SSH information is there\n")
|
||||||
f.write("Connection date:%s\n\n"%str(obj))
|
if self.aplist[pid].has_key('timestamp'):
|
||||||
|
#Convert timestamp
|
||||||
|
ts = self.aplist[pid]['timestamp']
|
||||||
|
obj=datetime.datetime.fromtimestamp(float(ts))
|
||||||
|
f.write("Connection date:%s\n\n"%str(obj))
|
||||||
|
else:
|
||||||
|
f.write("No timestamp information is there\n")
|
||||||
|
else:
|
||||||
|
sys.stderr.write("No annotations found for pid: %d\n"%pid)
|
||||||
f.close()
|
f.close()
|
||||||
except IOError,e:
|
except IOError,e:
|
||||||
#TODO implement logging of internal errors
|
#TODO implement logging of internal errors
|
||||||
|
|
Loading…
Reference in a new issue