Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 391e40b

Browse files
committed
Store master password as sha512 hash
1 parent ca0ad0a commit 391e40b

3 files changed

Lines changed: 63 additions & 11 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ nosetests.xml
3434
.mr.developer.cfg
3535
.project
3636
.pydevproject
37+
38+
# Geany project
39+
.geanyprj

pyPassMan/gtk3.py

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
11
#!/usr/bin/python3
22

33
from gi.repository import Gtk, Gdk
4-
import sqlite3
4+
import hashlib
55
import pyPassMan.models as models
66

77
class 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+
271319
def 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

277326
if __name__ == "__main__":
278327
main()

pyPassMan/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class AccountManager:
3737
_con = None
3838
_aes = None
3939

40-
def __init__(self, conn, aes_cipher):
41-
self._conn = conn
40+
def __init__(self, conn_path, aes_cipher):
41+
self._conn = sqlite3.connect(conn_path)
4242
self._aes = aes_cipher
4343

4444
# check if db is set

0 commit comments

Comments
 (0)