11#!/usr/bin/python3
22
33from gi .repository import Gtk , Gdk
4- import sqlite3
4+ import hashlib
55import pyPassMan .models as models
66
77class MainWindow (Gtk .Window ):
88
9+ initialized = False
910 COLOR_INVALID = Gdk .Color (50000 , 0 , 0 )
1011
1112 def __init__ (self ):
12- Gtk .Window .__init__ (self , title = "Password Manager" )
1313 self .settings = models .Settings ()
14- self .AccountManager = models .AccountManager (sqlite3 .connect (self .settings .get_db_path ()), models .AESCipher (self .settings .master_pass ))
15- self ._build ()
14+ Gtk .Window .__init__ (self , title = "Password Manager" )
15+
16+ key = self .show_master_password_dialog ()
17+ if key is None :
18+ self .close ()
19+ else :
20+ self .AccountManager = models .AccountManager (self .settings .get_db_path (), models .AESCipher (key ))
21+ self ._build ()
22+ self .initialized = True
23+
24+ def show_master_password_dialog (self ):
25+ dialog = MasterKeyInputDialog (self )
26+ correct = False
27+ master_pass = None
28+ while not correct :
29+ response = dialog .run ()
30+ if response == Gtk .ResponseType .OK :
31+ master_pass = dialog .master_pass_input .get_text ()
32+ if hashlib .sha512 (master_pass .encode ('utf-8' )).hexdigest () == self .settings .master_pass :
33+ correct = True
34+ dialog .destroy ()
35+ else :
36+ dialog .destroy ()
37+ break
38+ return None if not correct else master_pass
1639
1740 def _build (self ):
1841 self .set_icon (self .render_icon (Gtk .STOCK_DIALOG_AUTHENTICATION , Gtk .IconSize .MENU ))
@@ -145,6 +168,7 @@ def on_preferences_clicked(self, widget):
145168 if response == Gtk .ResponseType .OK :
146169 new_master_pass = dialog .form_parts ['master_pass' ].input .get_text ()
147170 if new_master_pass and new_master_pass is not self .settings .master_pass :
171+ new_master_pass = hashlib .sha512 (new_master_pass .encode ('utf-8' )).hexdigest ()
148172 self .AccountManager .update_all (models .AESCipher (new_master_pass ))
149173 self .settings .master_pass = new_master_pass
150174 self .settings .write ()
@@ -250,12 +274,11 @@ def _build(self, settings):
250274 labels_box = Gtk .Box (orientation = Gtk .Orientation .VERTICAL , spacing = 10 )
251275 inputs_box = Gtk .Box (orientation = Gtk .Orientation .VERTICAL , spacing = 10 )
252276
253- master_pass = models .Field (Gtk .Label ('Master password' ), Gtk .Entry ())
277+ master_pass = models .Field (Gtk .Label ('Change Master password' ), Gtk .Entry ())
254278 master_pass .label .set_alignment (0 , 0 )
255279 master_pass .input .set_activates_default (True )
256280 master_pass .input .set_visibility (False )
257281 master_pass .input .set_tooltip_text ('A length of 16 characters is recommended' )
258- master_pass .input .set_text (settings .master_pass )
259282 # Save the part for processing in submit callbacks.
260283 self .form_parts ['master_pass' ] = master_pass
261284
@@ -268,11 +291,37 @@ def _build(self, settings):
268291 box .add (hbox )
269292
270293
294+ class MasterKeyInputDialog (Gtk .Dialog ):
295+
296+ def __init__ (self , parent ):
297+
298+ Gtk .Dialog .__init__ (self , 'Enter the master password' , parent ,
299+ Gtk .DialogFlags .MODAL , buttons = (
300+ Gtk .STOCK_OK , Gtk .ResponseType .OK ))
301+
302+ self ._build (parent .settings )
303+ self .show_all ()
304+ self .set_default_response (Gtk .ResponseType .OK )
305+
306+ def _build (self , settings ):
307+ vbox = Gtk .Box (orientation = Gtk .Orientation .VERTICAL , spacing = 10 )
308+
309+ master_pass_input = Gtk .Entry ()
310+ master_pass_input .set_activates_default (True )
311+ master_pass_input .set_visibility (False )
312+ # Save the part for processing in submit callbacks.
313+ self .master_pass_input = master_pass_input
314+
315+ vbox .pack_start (master_pass_input , True , True , 20 )
316+
317+ self .get_content_area ().add (vbox )
318+
271319def main ():
272320 win = MainWindow ()
273- win .connect ("delete-event" , Gtk .main_quit )
274- win .show_all ()
275- Gtk .main ()
321+ if win .initialized :
322+ win .connect ("delete-event" , Gtk .main_quit )
323+ win .show_all ()
324+ Gtk .main ()
276325
277326if __name__ == "__main__" :
278327 main ()
0 commit comments