Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os, random, string, sqlite3, itertools, ctypes, logging
- from tkinter import *
- from tkinter.ttk import Treeview
- from tkinter.messagebox import askyesno, showerror, showinfo
- from tkinter.simpledialog import askstring
- class Core:
- def __init__(self, file='pass.db'):
- self.connection = sqlite3.connect(file)
- self.connection.cursor().execute('CREATE TABLE IF NOT EXISTS accounts (accountID INTEGER PRIMARY KEY AUTOINCREMENT, encryptedService BLOB, encryptedUsername BLOB, encryptedPass BLOB)')
- self.connection.commit()
- def getAccountList(self, masterPassword):
- accounts = dict()
- for id, service, username in self.connection.cursor().execute('SELECT accountID, encryptedService, encryptedUsername FROM accounts'):
- accounts.setdefault(Core.xor(service.decode(), masterPassword), []).append((id, Core.xor(username.decode(), masterPassword)))
- return accounts
- def getDecrypted(self, accountID, masterPassword):
- cursor = self.connection.cursor()
- cursor.execute('SELECT encryptedService, encryptedUsername, encryptedPass FROM accounts WHERE accountID=?', (accountID,))
- result = cursor.fetchone()
- return (Core.xor(result[0].decode(), masterPassword), Core.xor(result[1].decode(), masterPassword), Core.xor(result[2].decode(), masterPassword))
- def generateAccount(self, service, username, length, masterPassword):
- return self.importAccount(service, username, Core.generatePassword(length), masterPassword)
- def importAccount(self, service, username, password, masterPassword):
- cur = self.connection.cursor()
- cur.execute('INSERT INTO accounts (encryptedService, encryptedUsername, encryptedPass) VALUES (?, ?, ?)', (Core.strToBlob(Core.xor(service, masterPassword)), Core.strToBlob(Core.xor(username, masterPassword)), Core.strToBlob(Core.xor(password, masterPassword))))
- self.connection.commit()
- return cur.lastrowid
- def deleteAccount(self, accountID):
- self.connection.cursor().execute('DELETE FROM accounts WHERE accountID = ?', (accountID,))
- self.connection.commit()
- @staticmethod
- def generatePassword(n, special=True):
- "Generates a password of n length."
- return(''.join(random.SystemRandom().choice(string.ascii_letters + string.digits + ('','!@#$%^&*()-+_={}|[]')[special == True]) for dummy in range(n)))
- @staticmethod
- def xor(data, key):
- "Expand key if smaller, and encrypt/decrypt"
- k=key
- if len(key) < len(data):
- k = Core.repeatToLength(key, len(data))
- return "".join(chr(ord(a) ^ ord(b)) for a, b in zip(data, k))
- @staticmethod
- def repeatToLength(str, length):
- if (str != ''):
- return (str * ((length//len(str))+1))[:length]
- else:
- return ''
- @staticmethod
- def strToBlob(s):
- return sqlite3.Binary(bytearray(str.encode(s)))
- class GUI:
- def __init__(self):
- self.core = Core()
- self.root = Tk(text)
- self.topframe=Frame(self.root)
- self.topframe.pack()
- self.bottomframe=Frame(self.root)
- self.bottomframe.pack()
- self.scrollbar = Scrollbar(self.topframe)
- self.scrollbar.pack(side=RIGHT, fill=Y)
- self.tree = Treeview(self.topframe, yscrollcommand=self.scrollbar)
- self.tree["columns"]=("one", "two", "three")
- self.tree.column("one", width=100 )
- self.tree.column("two", width=100)
- self.tree.column("three", width=100)
- self.tree.heading("one", text="ID")
- self.tree.heading("two", text="Username")
- self.tree.heading("three", text="Password")
- self.tree.bind("<Double-1>", self.onDoubleClick)
- self.tree.bind("<Delete>", self.onDelete)
- self.tree.bind("<BackSpace>", self.onDelete)
- self.tree.pack(side=LEFT, fill=X)
- self.genButton = Button(self.bottomframe, text="Generate new account", command=self.createAcc)
- self.copyButton = Button(self.bottomframe, text="Copy password to clipboard", command=self.copyPwd)
- self.importButton = Button(self.bottomframe, text="Import account", command=self.importAcc)
- self.deleteButton = Button(self.bottomframe, text="Delete account", command=self.deleteAcc)
- self.genButton.pack(side=LEFT)
- self.copyButton.pack(side=LEFT)
- self.importButton.pack(side=LEFT)
- self.deleteButton.pack(side=LEFT)
- accounts=self.core.getAccountList(GUI.promptPassword(self.root))
- for service in accounts:
- self.tree.insert("", END, service, text=service)
- for account in accounts[service]:
- self.tree.insert(service, END, values=account+("********",))
- self.root.mainloop()
- def onDoubleClick(self, evt):
- self.copyPwd()
- def onDelete(self, evt):
- self.deleteAcc()
- def createAcc(self):
- dialog = Toplevel()
- Label(dialog, text="Service").grid(row=0, sticky=W)
- Label(dialog, text="Username").grid(row=1, sticky=W)
- Label(dialog, text="Length").grid(row=2, sticky=W)
- serviceEntry = Entry(dialog)
- serviceEntry.grid(row=0, column=1)
- usernameEntry = Entry(dialog)
- usernameEntry.grid(row=1, column=1)
- lengthEntry = Entry(dialog)
- lengthEntry.grid(row=2, column=1)
- def onEntry():
- try:
- len = int(lengthEntry.get())
- service = serviceEntry.get()
- if not self.tree.exists(service):
- self.tree.insert("", END, service, text=service)
- id = self.core.generateAccount(service, usernameEntry.get(), len, GUI.promptPassword(dialog))
- self.tree.insert(service, END, values=(id, usernameEntry.get(),"********"))
- dialog.destroy()
- except:
- showerror("Create", "Please enter a number for the length")
- Button(dialog, text="Create", command = onEntry).grid(row=3, columnspan=2)
- dialog.mainloop()
- def importAcc(self):
- dialog = Toplevel()
- Label(dialog, text="Service").grid(row=0, sticky=W)
- Label(dialog, text="Username").grid(row=1, sticky=W)
- Label(dialog, text="Password").grid(row=2, sticky=W)
- serviceEntry = Entry(dialog)
- serviceEntry.grid(row=0, column=1)
- usernameEntry = Entry(dialog)
- usernameEntry.grid(row=1, column=1)
- passwordEntry = Entry(dialog, show='*')
- passwordEntry.grid(row=2, column=1)
- def onEntry():
- service = serviceEntry.get()
- id = self.core.importAccount(service, usernameEntry.get(), passwordEntry.get(), GUI.promptPassword(dialog))
- if not self.tree.exists(service):
- self.tree.insert("", END, service, text=service)
- self.tree.insert(service, END, values=(id, usernameEntry.get(),"********"))
- dialog.destroy()
- Button(dialog, text="Import", command = onEntry).grid(row=3, columnspan=2)
- dialog.mainloop()
- def deleteAcc(self):
- item = self.tree.selection()[0]
- if askyesno("Delete", "Delete this account?"):
- self.core.deleteAccount(self.tree.item(item, "values")[0])
- parent = self.tree.parent(item)
- self.tree.delete(item)
- if not self.tree.get_children(parent):
- self.tree.delete(parent)
- def copyPwd(self):
- password = GUI.promptPassword(self.root)
- self.root.clipboard_clear()
- self.root.clipboard_append(self.core.getDecrypted(self.tree.item(self.tree.selection()[0], "values")[0], password)[2])
- self.root.update()
- showinfo(message="Password copied")
- @staticmethod
- def promptPassword(root):
- return askstring("Master Password", "Enter the master password", show='*', parent=root)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement