#!/usr/bin/env python import os import time import locale passfile="/somewhere/somefile.txt" colred='\x1b[1;37;41m' colb= '\x1b[1;37;40m' coln= '\x1b[0;37;40m' col1= '\x1b[0;37;40m' col2= '\x1b[1;31;40m' colst= '\x1b[1;33;44m' colend='\x1b[0m' def notab(s): """returns s but eliminating any tabs found within """ l=len(s) r='' for c in s : if c!='\t' : r=r+c return r def left(s,max): """like basic's left() returns upto max first chars of s """ if len(s)>max : return(s[0:max]) else : return(s) def niceline(line,showpass) : """formats a line from password file so that it get's printed nicely showpass=1 means show the passwd also (0=don't) note that a line has this format person->login->password->notes (-> stands for tab) """ # b0,1,2,3 are the separator strings which will be printed before field 0,1,2,3 b0='\x1b[0m' b1=' \x1b[1;35;40m' b2=' \x1b[1;30;42m' b3='\x1b[0m ' x=line.split('\t') if len(x)<3 : return('>>>INVALID LINE: '+line) else: ret=b0+x[0]+b1+x[1] if showpass : ret=ret+b2+x[2] if len(x)>=4 : ret=ret+b3+x[3] return(ret) def PrintLine(cnt,astr,showpass): """prints line astr found at line cnt of the file """ return( coln+str(cnt)+': '+colb+" " + niceline(astr,showpass) ) def myGrep(word1,word2): """greps -i through the text file for words word1, word2(optional) """ linenos=[] word1=word1.lower() word2=word2.lower() maxshow=20 # max lines to print cnt=1 # counter of line number show_cnt=0 # counter of shown lines f=open(passfile, 'r') for line in f.readlines(200000) : # read no more than about 200000 bytes l=line.lower() if l.find(word1)<>-1 and l.find(word2)<>-1 : if show_cntmaxshow : print colred, show_cnt-maxshow, "more matching lines not shown", coln," " return(linenos) def GetLine(cnt): """reads line at lineno#cnt from the file """ f=open(passfile, 'r') lines=f.readlines(200000) if len(lines)>=cnt : line=lines[cnt-1] else: line='invalid number\tinvalid number\tinvalid number\tinvalid number' f.close() return(line) # # INITIALISATION # #set locale locale.setlocale(locale.LC_ALL,'el_GR') #regarding limit of querys/sec max_s_tokens=2 s_tokens=max_s_tokens start=time.time() word1='' word2='' NumList=[] # # (UN)WELCOME MESSAGE # print col1 print "Password DB" print "Don't use this programm if you are not authorized to do so (hit ctrl-C to exit)" print "" # # MAIN LOOP # while 1 : BadCmd=1 # # get and condition input from user # cmd=left(raw_input(colst+'?word, number, +, * '+colend+'>').strip(),255) x=cmd # x may change, cmd will be lef intact if x=="" : x=" " if x[0]=="?" : # command ?: find WORD1, WORD2 if len(x)>1 : x=x[1:].strip() at=x.find(' ') if at<>-1 : word1=x[0:at].strip() word2=x[at:len(x)].strip() else : word1=x word2='' NumList=myGrep(word1,word2) BadCmd=0 elif x=="+" : # command +: user wants to add a new password line # get input f1=notab(left(raw_input( 'Person/Company (ENTER to cancel) :'),50)).strip() if f1 : f2=notab(left(raw_input('Login :'),50)).strip() f3=notab(left(raw_input('Password :'),50)) f4=notab(left(raw_input('What\'s this passwd for :'),300)).strip() if f2+f3+f4 : # add one line to passwords file newline='\n' + f1 + '\t' + f2 + '\t' + f3 + '\t' + f4 + '\n' f=open(passfile,'a') f.write(newline) f.close() print "++ADDED++" ret=os.system('echo "+ '+newline+'" | mail -s PASS.SHELL ndemou@enlogic.local') BadCmd=0 elif x.isdigit() : # command num: user wants to see a password at line num cnt=int(x) if cnt in NumList : #update s_tokens limit (s_tokens=2 means the user can make two more queries for passwords) s_tokens=s_tokens-1 TimeSinceLastQuery=(time.time()-start) TokensEarned=TimeSinceLastQuery/180 # earn a token for a query every 3 minutes # todo: security BUG! If the user exits the shell and reconect he will # restore his tokens to the initial value # I must save in users home dir and restore it upon programm launch # ...hmm... this might have the added benefit that I might not need to # care if the user initiates multiple sessions - will see s_tokens=int(s_tokens+TokensEarned) if s_tokens>max_s_tokens : s_tokens = max_s_tokens start=time.time() if s_tokens!=0 : #answer the query print PrintLine(cnt , GetLine(cnt) , 1) ret=os.system('echo "'+PrintLine(cnt, GetLine(cnt), 0)+'" | mail -s PASS.SHELL ndemou@enlogic.local') else : #query came too fast print "please wait" ret=os.system('echo "'+cmd+'" | mail -s TOO_FAST_PASS.SHELL ndemou@enlogic.local') else : print "you can only ask for a number presented in the last ? query" BadCmd=0 elif x=="*" : print colred+"You are about to change the password you enter when you login to this password management utility" print "If you are at this point by accident hit ENTER or ctrl-C to abort\x1b[0;37;40m" ret=os.system('passwd') ret=os.system('echo "PASSWD returned '+str(ret)+'" | mail -s PASS.SHELL ndemou@enlogic.local') BadCmd=0 if BadCmd==1 : print col2+"******Bad Command******"+coln print "done"