#!/usr/bin/python # # pwd.py - password manager, written for use on the iPAQ # # dave@grox.net - Sun May 12 12:02:12 EDT 2002 # # GUI generated by Glade # ############################################################ import sys from gtk import * import os import string ############################################################ # globals password = "" ############################################################ # misc functions # # RC4.py # from a 1995 usenet post by Andrew Kuchling at mcgill.ca # # encrypt/decrypt using rc4 # def rc4(text): if password == "": return "" processed = "" state, x, y, i1, i2, key = range(0,256), 0,0, 0,0, password for i in range(0,256): state[i], state[i2], i1, i2= state[(ord(key[i1])+state[i]+i2) % 256], state[i], (i1+1) % len(key), (ord(key[i1])+state[i]+i2) % 256 for s in text: x, y, ch = (x+1) % 255, (y+state[(x+1) % 255])%256, ord(s) state[x], state[y] = state[y], state[x] processed = processed + chr(ch^state[(state[x]+state[y]) % 256]) return processed def gethome(): try: home=os.environ['HOME'] except: home='.' return home def getprog(): try: prog=os.path.basename(sys.argv[0]) except: prog='pwd' return prog def defaultfile(): return os.path.join( gethome() + '/.' + getprog() ) def menuitem(label,list,func): menuitem = GtkMenuItem(label) list.append(label) menuitem.connect("activate", func,label) menuitem.show() return menuitem def mainaddlabel(label,pos,list): l=GtkLabel() list.set_column_widget(pos, l) l.set_usize(-1, -1) l.set_text(label) l.set_justify(JUSTIFY_CENTER) l.set_alignment(0.5, 0.5) l.set_padding(0, 0) ############################################################ # main window # class window_mainWidget: def __init__(self,filename): self.filename = filename window_main=GtkWindow(WINDOW_TOPLEVEL) window_main.set_title("pwd") window_main.set_usize(230,300) window_main.set_policy(FALSE, TRUE, FALSE) window_main.set_position(WIN_POS_NONE) alignment1=GtkAlignment(0.5, 0.5, 1, 1) window_main.add(alignment1) vbox1=GtkVBox() alignment1.add(vbox1) vbox1.set_homogeneous(FALSE) vbox1.set_spacing(0) scrolledwindow1=GtkScrolledWindow() vbox1.pack_start(scrolledwindow1, TRUE, TRUE, 0) scrolledwindow1.set_policy(POLICY_ALWAYS, POLICY_ALWAYS) columns=4 clist1=GtkCList(columns) scrolledwindow1.add(clist1) clist1.column_titles_show() clist1.column_titles_active() colwidths=[38,43,50,48] labels=["system","account","password","comment"] for i in range(0,columns): clist1.set_column_width(i, colwidths[i]) mainaddlabel(labels[i],i,clist1) clist1.show() self.clist1=clist1 self.clist1.connect("select_row",self.RowSelected) self.clist1.connect("click_column",self.SortColumns,self) self.curitem = -1 scrolledwindow1.show() self.scrolledwindow1=scrolledwindow1 hbox1=GtkHBox() vbox1.pack_start(hbox1, FALSE, TRUE, 0) hbox1.set_usize(-1, -1) hbox1.set_homogeneous(FALSE) hbox1.set_spacing(0) self.add=GtkButton("add") hbox1.pack_start(self.add, FALSE, FALSE, 0) self.add.connect("clicked",self.OnAdd) self.change=GtkButton("edit") hbox1.pack_start(self.change, FALSE, FALSE, 0) self.change.connect("clicked",self.OnChange) self.remove=GtkButton("remove") hbox1.pack_start(self.remove, FALSE, FALSE, 0) self.remove.connect("clicked",self.OnRemove) self.savebtn=GtkButton("save") hbox1.pack_start(self.savebtn, FALSE, FALSE, 0) self.savebtn.connect("clicked",self.OnSave) self.pwdbtn=GtkButton("password") hbox1.pack_start(self.pwdbtn, FALSE, FALSE, 0) self.pwdbtn.connect("clicked",self.ChangePassword) self.quit=GtkButton("quit") hbox1.pack_start(self.quit, FALSE, FALSE, 5) self.quit.connect("clicked",self.QuitApp,mainquit) # # now that all the widgets are declared, we can load the data # self.load(mainquit) if len(self.data) > 0: for item in self.data: if len(item) > 1: clist1.append(item) hbox1.show() self.hbox1=hbox1 vbox1.show() self.vbox1=vbox1 alignment1.show() self.alignment1=alignment1 window_main.show_all() self.window_main=window_main def SortColumns(self,widget,col,more): self.clist1.set_sort_column(col) self.clist1.sort() print col def RowSelected(self,widget,row,column,event): self.curitem = row def OnAdd(self,widget): itemDlg = ItemDialog(self.clist1,-1) def OnChange(self,widget): if self.curitem == -1: return itemDlg = ItemDialog(self.clist1,self.curitem) def OnRemove(self,widget): if self.curitem == -1: return self.clist1.remove(self.curitem) def OnSave(self,widget): ret = self.save() def ChangePassword(self,widget): pwd = window_passwordWidget("hidave") ret = self.save() def QuitApp(self,widget,mainquit): # if self.save() != 0: mainquit() mainquit() def load(self,mainquit): self.data = [] if password == "": mb=MsgBox("Please set a password. Defaults not saved.") # self.data = [ ['root','server','foobar','hi there'] ] return try: fp=open(self.filename,'rb') except: s = "unable to open data file: %s." % self.filename mb=MsgBox(s) return s = fp.read() fp.close() contents = string.split(rc4(s),"\n") # print contents if len(contents) == 1: mb=MsgBox("Incorrect password. Data not loaded.") for entry in contents: if len(entry) > 0: self.data.append( string.split(entry,":") ) s = "data loaded from %s." % self.filename mb=MsgBox(s) def save(self): if password == "": mb=MsgBox("Please set a password. Data not saved.") return s = "" for i in range(0,self.clist1.rows): for j in range(0,self.clist1.columns): if j == 0: row = self.clist1.get_text(i,j) else: row = row + ":" + self.clist1.get_text(i,j) s = s + row + "\n" try: fp=open(self.filename,'wb') except: msg = "Error: unable to save data to %s" % self.filename mb=MsgBox(msg) return 0 fp.write( rc4(s) ) fp.close() mb=MsgBox("Data saved to disk.") return 1 ############################################################ # item entry dialog # class ItemDialog: def __init__(self,list,num): window_item=GtkWindow(WINDOW_DIALOG) window_item.set_title("entry") window_item.set_usize(240, 120) window_item.set_policy(TRUE, TRUE, FALSE) window_item.set_position(WIN_POS_NONE) table1=GtkTable(5, 2) window_item.add(table1) table1.set_usize(-1, -1) table1.set_row_spacings(0) table1.set_col_spacings(0) label7=GtkLabel() table1.attach(label7, 0, 1, 1, 2, FILL, 0, 0, 0) label7.set_usize(-1, -1) label7.set_text("system") label7.set_justify(JUSTIFY_CENTER) label7.set_alignment(0, 0.5) label7.set_padding(0, 0) label7.show() self.label7=label7 label8=GtkLabel() table1.attach(label8, 0, 1, 2, 3, FILL, 0, 0, 0) label8.set_usize(-1, -1) label8.set_text("account") label8.set_justify(JUSTIFY_CENTER) label8.set_alignment(0, 0.5) label8.set_padding(0, 0) label8.show() self.label8=label8 label9=GtkLabel() table1.attach(label9, 0, 1, 3, 4, FILL, 0, 0, 0) label9.set_usize(-1, -1) label9.set_text("password") label9.set_justify(JUSTIFY_CENTER) label9.set_alignment(0, 0.5) label9.set_padding(0, 0) label9.show() self.label9=label9 label10=GtkLabel() table1.attach(label10, 0, 1, 4, 5, FILL, 0, 0, 0) label10.set_usize(-1, -1) label10.set_text("comment") label10.set_justify(JUSTIFY_CENTER) label10.set_alignment(0, 0.5) label10.set_padding(0, 0) label10.show() self.label10=label10 entry_system=GtkEntry() table1.attach(entry_system, 1, 2, 1, 2, EXPAND|FILL, 0, 0, 0) entry_system.set_flags(CAN_FOCUS) entry_system.set_usize(-1, -1) entry_system.set_editable(TRUE) entry_system.set_visibility(TRUE) entry_system.set_max_length(0) entry_system.set_text("") entry_system.show() self.entry_system=entry_system entry_account=GtkEntry() table1.attach(entry_account, 1, 2, 2, 3, EXPAND|FILL, 0, 0, 0) entry_account.set_flags(CAN_FOCUS) entry_account.set_usize(-1, -1) entry_account.set_editable(TRUE) entry_account.set_visibility(TRUE) entry_account.set_max_length(0) entry_account.set_text("") entry_account.show() self.entry_account=entry_account entry_password=GtkEntry() table1.attach(entry_password, 1, 2, 3, 4, EXPAND|FILL, 0, 0, 0) entry_password.set_flags(CAN_FOCUS) entry_password.set_usize(-1, -1) entry_password.set_editable(TRUE) entry_password.set_visibility(TRUE) entry_password.set_max_length(0) entry_password.set_text("") entry_password.show() self.entry_password=entry_password entry_comment=GtkEntry() table1.attach(entry_comment, 1, 2, 4, 5, EXPAND|FILL, 0, 0, 0) entry_comment.set_flags(CAN_FOCUS) entry_comment.set_usize(-1, -1) entry_comment.set_editable(TRUE) entry_comment.set_visibility(TRUE) entry_comment.set_max_length(40) entry_comment.set_text("") entry_comment.show() self.entry_comment=entry_comment button_cancel=GtkButton("cancel") table1.attach(button_cancel, 1, 2, 5, 6, 0, 0, 0, 0) button_cancel.show() self.button_cancel=button_cancel self.button_cancel.connect("clicked", window_item.destroy) button_ok=GtkButton("ok") table1.attach(button_ok, 0, 1, 5, 6, 0, 0, 0, 0) button_ok.show() self.button_ok=button_ok self.button_ok.connect("clicked", self.OnOk, list, num) table1.show() self.table1=table1 if num != -1: entry_system.set_text( list.get_text(num,0) ) entry_account.set_text( list.get_text(num,1) ) entry_password.set_text( list.get_text(num,2) ) entry_comment.set_text( list.get_text(num,3) ) window_item.show() self.window_item=window_item def OnOk(self, widget,list,num): sys = self.entry_system.get_text() acct = self.entry_account.get_text() pwd = self.entry_password.get_text() note = self.entry_comment.get_text() if num == -1: list.append([sys,acct,pwd,note]) else: list.set_text(num,0,sys) list.set_text(num,1,acct) list.set_text(num,2,pwd) list.set_text(num,3,note) self.window_item.destroy() ############################################################ # window to allow editing of categories # class CategoriesDialog: def __init__(self,categories): window_categories=GtkWindow(WINDOW_DIALOG) window_categories.set_title("categories") window_categories.set_usize(-1, -1) window_categories.set_policy(TRUE, TRUE, FALSE) window_categories.set_position(WIN_POS_NONE) vbox2=GtkVBox() window_categories.add(vbox2) vbox2.set_usize(-1, -1) vbox2.set_homogeneous(FALSE) vbox2.set_spacing(0) list1=GtkList() vbox2.pack_start(list1, FALSE, FALSE, 0) list1.set_usize(-1, -1) list1.show() self.list1=list1 list_categories=GtkList() vbox2.pack_start(list_categories, TRUE, TRUE, 0) list_categories.set_usize(-1, -1) list_categories.set_border_width(2) list_categories.show() self.list_categories=list_categories hseparator1=GtkHSeparator() vbox2.pack_start(hseparator1, FALSE, TRUE, 0) hseparator1.set_usize(-1, -1) hseparator1.show() self.hseparator1=hseparator1 entry1=GtkEntry() vbox2.pack_start(entry1, FALSE, FALSE, 0) entry1.set_flags(CAN_FOCUS) entry1.set_usize(-1, -1) entry1.set_editable(TRUE) entry1.set_visibility(TRUE) entry1.set_max_length(0) entry1.set_text("") entry1.show() self.entry1=entry1 hbox2=GtkHBox() vbox2.pack_start(hbox2, FALSE, TRUE, 0) hbox2.set_usize(-1, -1) hbox2.set_homogeneous(FALSE) hbox2.set_spacing(0) button_add=GtkButton("add") hbox2.pack_start(button_add, FALSE, FALSE, 5) button_add.show() self.button_add=button_add button_change=GtkButton("change") hbox2.pack_start(button_change, FALSE, FALSE, 5) button_change.show() self.button_change=button_change button_remove=GtkButton("remove") hbox2.pack_start(button_remove, FALSE, FALSE, 5) button_remove.show() self.button_remove=button_remove button_cancel=GtkButton("cancel") hbox2.pack_start(button_cancel, FALSE, FALSE, 5) button_cancel.show() self.button_cancel=button_cancel hbox2.show() self.button_cancel.connect("clicked", window_categories.destroy) self.hbox2=hbox2 vbox2.show() self.vbox2=vbox2 self.window_categories=window_categories self.window_categories.show() def show(self): self.window_categories.show() ############################################################ # password dialog # class window_passwordWidget: def __init__(self,filename): self.filename = filename window_password=GtkWindow(WINDOW_TOPLEVEL) window_password.set_modal(1) window_password.set_title("Enter your passphrase") window_password.set_usize(-1, -1) window_password.set_policy(FALSE, TRUE, FALSE) window_password.set_position(WIN_POS_NONE) vbox3=GtkVBox() window_password.add(vbox3) vbox3.set_usize(-1, -1) vbox3.set_homogeneous(FALSE) vbox3.set_spacing(0) hbox3=GtkHBox() vbox3.pack_start(hbox3, TRUE, TRUE, 0) hbox3.set_usize(-1, -1) hbox3.set_homogeneous(FALSE) hbox3.set_spacing(0) label_password=GtkLabel() hbox3.pack_start(label_password, FALSE, FALSE, 0) label_password.set_usize(-1, -1) label_password.set_text("passphrase:") label_password.set_justify(JUSTIFY_CENTER) label_password.set_alignment(0.5, 0.5) label_password.set_padding(0, 0) label_password.show() self.label_password=label_password entry_passphrase=GtkEntry() hbox3.pack_start(entry_passphrase, TRUE, TRUE, 0) entry_passphrase.set_editable(TRUE) entry_passphrase.set_visibility(FALSE) entry_passphrase.set_max_length(40) entry_passphrase.set_text("") entry_passphrase.connect("changed", self.on_entry_password_changed) entry_passphrase.GTKPY_MAIN = window_passwordWidget entry_passphrase.show() self.entry_passphrase=entry_passphrase hbox3.show() self.hbox3=hbox3 hbuttonbox1=GtkHButtonBox() vbox3.pack_start(hbuttonbox1, TRUE, TRUE, 0) hbuttonbox1.set_usize(-1, -1) hbuttonbox1.set_homogeneous(FALSE) hbuttonbox1.set_spacing(30) hbuttonbox1.set_child_size_default(85, 27) hbuttonbox1.set_child_ipadding_default(7, 0) hbuttonbox1.set_spacing(30) hbuttonbox1.set_layout(BUTTONBOX_DEFAULT_STYLE) button_ok=GtkButton("OK") hbuttonbox1.pack_start(button_ok, TRUE, TRUE, 0) button_ok.set_flags(CAN_FOCUS) button_ok.set_usize(-1, -1) button_ok.connect("clicked", self.on_button_ok_clicked) button_ok.GTKPY_MAIN = window_passwordWidget button_ok.show() self.button_ok=button_ok button_cancel=GtkButton("cancel") hbuttonbox1.pack_start(button_cancel, TRUE, TRUE, 0) button_cancel.set_flags(CAN_FOCUS) button_cancel.set_usize(-1, -1) button_cancel.connect("clicked", mainquit) button_cancel.GTKPY_MAIN = window_passwordWidget button_cancel.show() self.button_cancel=button_cancel hbuttonbox1.show() self.hbuttonbox1=hbuttonbox1 vbox3.show() self.vbox3=vbox3 window_password.show() self.window_password=window_password def on_entry_password_changed(self,widget): global password password = self.entry_passphrase.get_text() def on_button_ok_clicked(self,widget): # print "passphrase: %s" % password self.window_password.destroy() if self.filename != "hidave": window_main=window_mainWidget(self.filename) ############################################################ # class to display a message # class MsgBox(GtkDialog): def __init__(self,txt=""): GtkDialog.__init__(self) self.l = GtkLabel(txt) self.vbox.pack_start(self.l) self.ok=GtkButton('ok') self.action_area.pack_start(self.ok,expand=FALSE) self.ok.connect("clicked",self.destroy) self.show_all() # self.set_modal(1) if __name__ == '__main__': if len(sys.argv) >= 2: filename = argv[1] else: filename = defaultfile() pwd = window_passwordWidget(filename) mainloop()