Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.79 KB | None | 0 0
  1. import os, random, string, sqlite3, itertools, ctypes, logging
  2. from tkinter import *
  3. from tkinter.ttk import Treeview
  4. from tkinter.messagebox import askyesno, showerror, showinfo
  5. from tkinter.simpledialog import askstring
  6. class Core:
  7. def __init__(self, file='pass.db'):
  8. self.connection = sqlite3.connect(file)
  9. self.connection.cursor().execute('CREATE TABLE IF NOT EXISTS accounts (accountID INTEGER PRIMARY KEY AUTOINCREMENT, encryptedService BLOB, encryptedUsername BLOB, encryptedPass BLOB)')
  10. self.connection.commit()
  11.  
  12. def getAccountList(self, masterPassword):
  13. accounts = dict()
  14. for id, service, username in self.connection.cursor().execute('SELECT accountID, encryptedService, encryptedUsername FROM accounts'):
  15. accounts.setdefault(Core.xor(service.decode(), masterPassword), []).append((id, Core.xor(username.decode(), masterPassword)))
  16. return accounts
  17.  
  18. def getDecrypted(self, accountID, masterPassword):
  19. cursor = self.connection.cursor()
  20. cursor.execute('SELECT encryptedService, encryptedUsername, encryptedPass FROM accounts WHERE accountID=?', (accountID,))
  21. result = cursor.fetchone()
  22. return (Core.xor(result[0].decode(), masterPassword), Core.xor(result[1].decode(), masterPassword), Core.xor(result[2].decode(), masterPassword))
  23.  
  24. def generateAccount(self, service, username, length, masterPassword):
  25. return self.importAccount(service, username, Core.generatePassword(length), masterPassword)
  26.  
  27. def importAccount(self, service, username, password, masterPassword):
  28. cur = self.connection.cursor()
  29. 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))))
  30. self.connection.commit()
  31. return cur.lastrowid
  32.  
  33. def deleteAccount(self, accountID):
  34. self.connection.cursor().execute('DELETE FROM accounts WHERE accountID = ?', (accountID,))
  35. self.connection.commit()
  36.  
  37. @staticmethod
  38. def generatePassword(n, special=True):
  39. "Generates a password of n length."
  40. return(''.join(random.SystemRandom().choice(string.ascii_letters + string.digits + ('','!@#$%^&*()-+_={}|[]')[special == True]) for dummy in range(n)))
  41.  
  42. @staticmethod
  43. def xor(data, key):
  44. "Expand key if smaller, and encrypt/decrypt"
  45. k=key
  46. if len(key) < len(data):
  47. k = Core.repeatToLength(key, len(data))
  48. return "".join(chr(ord(a) ^ ord(b)) for a, b in zip(data, k))
  49.  
  50. @staticmethod
  51. def repeatToLength(str, length):
  52. if (str != ''):
  53. return (str * ((length//len(str))+1))[:length]
  54. else:
  55. return ''
  56.  
  57. @staticmethod
  58. def strToBlob(s):
  59. return sqlite3.Binary(bytearray(str.encode(s)))
  60.  
  61. class GUI:
  62. def __init__(self):
  63. self.core = Core()
  64. self.root = Tk(text)
  65. self.topframe=Frame(self.root)
  66. self.topframe.pack()
  67. self.bottomframe=Frame(self.root)
  68. self.bottomframe.pack()
  69. self.scrollbar = Scrollbar(self.topframe)
  70. self.scrollbar.pack(side=RIGHT, fill=Y)
  71. self.tree = Treeview(self.topframe, yscrollcommand=self.scrollbar)
  72. self.tree["columns"]=("one", "two", "three")
  73. self.tree.column("one", width=100 )
  74. self.tree.column("two", width=100)
  75. self.tree.column("three", width=100)
  76. self.tree.heading("one", text="ID")
  77. self.tree.heading("two", text="Username")
  78. self.tree.heading("three", text="Password")
  79. self.tree.bind("<Double-1>", self.onDoubleClick)
  80. self.tree.bind("<Delete>", self.onDelete)
  81. self.tree.bind("<BackSpace>", self.onDelete)
  82. self.tree.pack(side=LEFT, fill=X)
  83. self.genButton = Button(self.bottomframe, text="Generate new account", command=self.createAcc)
  84. self.copyButton = Button(self.bottomframe, text="Copy password to clipboard", command=self.copyPwd)
  85. self.importButton = Button(self.bottomframe, text="Import account", command=self.importAcc)
  86. self.deleteButton = Button(self.bottomframe, text="Delete account", command=self.deleteAcc)
  87. self.genButton.pack(side=LEFT)
  88. self.copyButton.pack(side=LEFT)
  89. self.importButton.pack(side=LEFT)
  90. self.deleteButton.pack(side=LEFT)
  91. accounts=self.core.getAccountList(GUI.promptPassword(self.root))
  92. for service in accounts:
  93. self.tree.insert("", END, service, text=service)
  94. for account in accounts[service]:
  95. self.tree.insert(service, END, values=account+("********",))
  96. self.root.mainloop()
  97. def onDoubleClick(self, evt):
  98. self.copyPwd()
  99.  
  100. def onDelete(self, evt):
  101. self.deleteAcc()
  102.  
  103. def createAcc(self):
  104. dialog = Toplevel()
  105. Label(dialog, text="Service").grid(row=0, sticky=W)
  106. Label(dialog, text="Username").grid(row=1, sticky=W)
  107. Label(dialog, text="Length").grid(row=2, sticky=W)
  108. serviceEntry = Entry(dialog)
  109. serviceEntry.grid(row=0, column=1)
  110. usernameEntry = Entry(dialog)
  111. usernameEntry.grid(row=1, column=1)
  112. lengthEntry = Entry(dialog)
  113. lengthEntry.grid(row=2, column=1)
  114. def onEntry():
  115. try:
  116. len = int(lengthEntry.get())
  117. service = serviceEntry.get()
  118. if not self.tree.exists(service):
  119. self.tree.insert("", END, service, text=service)
  120. id = self.core.generateAccount(service, usernameEntry.get(), len, GUI.promptPassword(dialog))
  121. self.tree.insert(service, END, values=(id, usernameEntry.get(),"********"))
  122. dialog.destroy()
  123. except:
  124. showerror("Create", "Please enter a number for the length")
  125. Button(dialog, text="Create", command = onEntry).grid(row=3, columnspan=2)
  126. dialog.mainloop()
  127. def importAcc(self):
  128. dialog = Toplevel()
  129. Label(dialog, text="Service").grid(row=0, sticky=W)
  130. Label(dialog, text="Username").grid(row=1, sticky=W)
  131. Label(dialog, text="Password").grid(row=2, sticky=W)
  132. serviceEntry = Entry(dialog)
  133. serviceEntry.grid(row=0, column=1)
  134. usernameEntry = Entry(dialog)
  135. usernameEntry.grid(row=1, column=1)
  136. passwordEntry = Entry(dialog, show='*')
  137. passwordEntry.grid(row=2, column=1)
  138. def onEntry():
  139. service = serviceEntry.get()
  140. id = self.core.importAccount(service, usernameEntry.get(), passwordEntry.get(), GUI.promptPassword(dialog))
  141. if not self.tree.exists(service):
  142. self.tree.insert("", END, service, text=service)
  143. self.tree.insert(service, END, values=(id, usernameEntry.get(),"********"))
  144. dialog.destroy()
  145. Button(dialog, text="Import", command = onEntry).grid(row=3, columnspan=2)
  146. dialog.mainloop()
  147. def deleteAcc(self):
  148. item = self.tree.selection()[0]
  149. if askyesno("Delete", "Delete this account?"):
  150. self.core.deleteAccount(self.tree.item(item, "values")[0])
  151. parent = self.tree.parent(item)
  152. self.tree.delete(item)
  153. if not self.tree.get_children(parent):
  154. self.tree.delete(parent)
  155. def copyPwd(self):
  156. password = GUI.promptPassword(self.root)
  157. self.root.clipboard_clear()
  158. self.root.clipboard_append(self.core.getDecrypted(self.tree.item(self.tree.selection()[0], "values")[0], password)[2])
  159. self.root.update()
  160. showinfo(message="Password copied")
  161.  
  162. @staticmethod
  163. def promptPassword(root):
  164. return askstring("Master Password", "Enter the master password", show='*', parent=root)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement