7 Module implementing the password manager. |
7 Module implementing the password manager. |
8 """ |
8 """ |
9 |
9 |
10 import os |
10 import os |
11 |
11 |
12 from PyQt4.QtCore import pyqtSignal, QObject, QByteArray, QUrl |
12 from PyQt4.QtCore import pyqtSignal, QObject, QByteArray, QUrl, QCoreApplication |
|
13 from PyQt4.QtGui import QProgressDialog, QApplication |
13 from PyQt4.QtNetwork import QNetworkRequest |
14 from PyQt4.QtNetwork import QNetworkRequest |
14 from PyQt4.QtWebKit import QWebSettings, QWebPage |
15 from PyQt4.QtWebKit import QWebSettings, QWebPage |
15 |
16 |
16 from E5Gui import E5MessageBox |
17 from E5Gui import E5MessageBox |
17 |
18 |
18 from Helpviewer.JavaScriptResources import parseForms_js |
19 from Helpviewer.JavaScriptResources import parseForms_js |
19 |
20 |
20 from Utilities.AutoSaver import AutoSaver |
21 from Utilities.AutoSaver import AutoSaver |
21 import Utilities |
22 import Utilities |
|
23 import Utilities.crypto |
22 import Preferences |
24 import Preferences |
23 |
25 |
24 |
26 |
25 class LoginForm(object): |
27 class LoginForm(object): |
26 """ |
28 """ |
127 if not self.__loaded: |
129 if not self.__loaded: |
128 self.__load() |
130 self.__load() |
129 |
131 |
130 key = self.__createKey(url, realm) |
132 key = self.__createKey(url, realm) |
131 try: |
133 try: |
132 return self.__logins[key][0], Utilities.pwDecode(self.__logins[key][1]) |
134 return self.__logins[key][0], Utilities.crypto.pwConvert( |
|
135 self.__logins[key][1], encode=False) |
133 except KeyError: |
136 except KeyError: |
134 return "", "" |
137 return "", "" |
135 |
138 |
136 def setLogin(self, url, realm, username, password): |
139 def setLogin(self, url, realm, username, password): |
137 """ |
140 """ |
144 """ |
147 """ |
145 if not self.__loaded: |
148 if not self.__loaded: |
146 self.__load() |
149 self.__load() |
147 |
150 |
148 key = self.__createKey(url, realm) |
151 key = self.__createKey(url, realm) |
149 self.__logins[key] = (username, Utilities.pwEncode(password)) |
152 self.__logins[key] = (username, Utilities.crypto.pwConvert(password, encode=True)) |
150 self.changed.emit() |
153 self.changed.emit() |
151 |
154 |
152 def __createKey(self, url, realm): |
155 def __createKey(self, url, realm): |
153 """ |
156 """ |
154 Private method to create the key string for the login credentials. |
157 Private method to create the key string for the login credentials. |
306 self.__load() |
309 self.__load() |
307 |
310 |
308 if site not in self.__logins: |
311 if site not in self.__logins: |
309 return None |
312 return None |
310 |
313 |
311 return self.__logins[site][0], Utilities.pwDecode(self.__logins[site][1]) |
314 return self.__logins[site][0], Utilities.crypto.pwConvert( |
|
315 self.__logins[site][1], encode=False) |
312 |
316 |
313 def post(self, request, data): |
317 def post(self, request, data): |
314 """ |
318 """ |
315 Public method to check, if the data to be sent contains login data. |
319 Public method to check, if the data to be sent contains login data. |
316 |
320 |
317 @param request reference to the network request (QNetworkRequest) |
321 @param request reference to the network request (QNetworkRequest) |
318 @param data data to be sent (QByteArray) |
322 @param data data to be sent (QByteArray) |
319 """ |
323 """ |
320 # shall passwords be saved? |
324 # shall passwords be saved? |
321 if not Preferences.getHelp("SavePasswords"): |
325 if not Preferences.getUser("SavePasswords"): |
322 return |
326 return |
323 |
327 |
324 # observe privacy |
328 # observe privacy |
325 if QWebSettings.globalSettings().testAttribute( |
329 if QWebSettings.globalSettings().testAttribute( |
326 QWebSettings.PrivateBrowsingEnabled): |
330 QWebSettings.PrivateBrowsingEnabled): |
405 elif password == "" and \ |
409 elif password == "" and \ |
406 type_ == "password": |
410 type_ == "password": |
407 password = element[1] |
411 password = element[1] |
408 form.elements[index] = (element[0], "--PASSWORD--") |
412 form.elements[index] = (element[0], "--PASSWORD--") |
409 if user and password: |
413 if user and password: |
410 self.__logins[key] = (user, Utilities.pwEncode(password)) |
414 self.__logins[key] = (user, Utilities.crypto.pwConvert(password, encode=True)) |
411 self.__loginForms[key] = form |
415 self.__loginForms[key] = form |
412 self.changed.emit() |
416 self.changed.emit() |
413 |
417 |
414 def __stripUrl(self, url): |
418 def __stripUrl(self, url): |
415 """ |
419 """ |
436 """ |
440 """ |
437 form = LoginForm() |
441 form = LoginForm() |
438 if boundary is not None: |
442 if boundary is not None: |
439 args = self.__extractMultipartQueryItems(data, boundary) |
443 args = self.__extractMultipartQueryItems(data, boundary) |
440 else: |
444 else: |
441 argsUrl = QUrl.fromEncoded(QByteArray("foo://bar.com/?" + data)) |
445 argsUrl = QUrl.fromEncoded( |
|
446 QByteArray("foo://bar.com/?" + data.replace(b"+", b"%20"))) |
442 encodedArgs = argsUrl.queryItems() |
447 encodedArgs = argsUrl.queryItems() |
443 args = set() |
448 args = set() |
444 for arg in encodedArgs: |
449 for arg in encodedArgs: |
445 key = arg[0] |
450 key = arg[0] |
446 value = arg[1].replace("+", " ") |
451 value = arg[1] |
447 args.add((key, value)) |
452 args.add((key, value)) |
448 |
453 |
449 # extract the forms |
454 # extract the forms |
450 lst = webPage.mainFrame().evaluateJavaScript(parseForms_js) |
455 lst = webPage.mainFrame().evaluateJavaScript(parseForms_js) |
451 for map in lst: |
456 for map in lst: |
558 'document.forms[{0}].elements["{1}"].type'.format(formName, name)) |
563 'document.forms[{0}].elements["{1}"].type'.format(formName, name)) |
559 if type_ == "" or \ |
564 if type_ == "" or \ |
560 type_ in ["hidden", "reset", "submit"]: |
565 type_ in ["hidden", "reset", "submit"]: |
561 continue |
566 continue |
562 if type_ == "password": |
567 if type_ == "password": |
563 value = Utilities.pwDecode(self.__logins[key][1]) |
568 value = Utilities.crypto.pwConvert(self.__logins[key][1], encode=False) |
564 setType = type_ == "checkbox" and "checked" or "value" |
569 setType = type_ == "checkbox" and "checked" or "value" |
565 value = value.replace("\\", "\\\\") |
570 value = value.replace("\\", "\\\\") |
566 value = value.replace('"', '\\"') |
571 value = value.replace('"', '\\"') |
567 javascript = 'document.forms[{0}].elements["{1}"].{2}="{3}";'.format( |
572 javascript = 'document.forms[{0}].elements["{1}"].{2}="{3}";'.format( |
568 formName, name, setType, value) |
573 formName, name, setType, value) |
569 page.mainFrame().evaluateJavaScript(javascript) |
574 page.mainFrame().evaluateJavaScript(javascript) |
|
575 |
|
576 def masterPasswordChanged(self, oldPassword, newPassword): |
|
577 """ |
|
578 Public slot to handle the change of the master password. |
|
579 |
|
580 @param oldPassword current master password (string) |
|
581 @param newPassword new master password (string) |
|
582 """ |
|
583 if not self.__loaded: |
|
584 self.__load() |
|
585 |
|
586 progress = QProgressDialog(self.trUtf8("Re-encoding saved passwords..."), |
|
587 None, 0, len(self.__logins), QApplication.activeModalWidget()) |
|
588 progress.setMinimumDuration(0) |
|
589 count = 0 |
|
590 |
|
591 for key in self.__logins: |
|
592 progress.setValue(count) |
|
593 QCoreApplication.processEvents() |
|
594 username, hash = self.__logins[key] |
|
595 hash = Utilities.crypto.pwRecode(hash, oldPassword, newPassword) |
|
596 self.__logins[key] = (username, hash) |
|
597 count += 1 |
|
598 |
|
599 progress.setValue(len(self.__logins)) |
|
600 QCoreApplication.processEvents() |
|
601 self.changed.emit() |