21 # __IGNORE_EXCEPTION__ |
21 # __IGNORE_EXCEPTION__ |
22 except (AttributeError, ImportError): |
22 except (AttributeError, ImportError): |
23 PYQT_WEBENGINE_VERSION = QT_VERSION |
23 PYQT_WEBENGINE_VERSION = QT_VERSION |
24 from PyQt5.QtWebChannel import QWebChannel |
24 from PyQt5.QtWebChannel import QWebChannel |
25 |
25 |
|
26 try: |
|
27 from PyQt5.QtNetwork import QSslConfiguration, QSslCertificate |
|
28 SSL_AVAILABLE = True |
|
29 except ImportError: |
|
30 SSL_AVAILABLE = False |
|
31 |
26 from E5Gui import E5MessageBox |
32 from E5Gui import E5MessageBox |
27 |
33 |
28 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
34 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
29 |
35 |
30 from .JavaScript.ExternalJsObject import ExternalJsObject |
36 from .JavaScript.ExternalJsObject import ExternalJsObject |
31 |
37 |
32 from .Tools.WebHitTestResult import WebHitTestResult |
38 from .Tools.WebHitTestResult import WebHitTestResult |
33 from .Tools import Scripts |
39 from .Tools import Scripts |
34 |
40 |
35 import Preferences |
41 import Preferences |
|
42 import Globals |
36 |
43 |
37 |
44 |
38 class WebBrowserPage(QWebEnginePage): |
45 class WebBrowserPage(QWebEnginePage): |
39 """ |
46 """ |
40 Class implementing an enhanced web page. |
47 Class implementing an enhanced web page. |
45 malicious web site as determined by safe browsing |
52 malicious web site as determined by safe browsing |
46 @signal printPageRequested() emitted to indicate a print request of the |
53 @signal printPageRequested() emitted to indicate a print request of the |
47 shown web page |
54 shown web page |
48 @signal navigationRequestAccepted(url, navigation type, main frame) emitted |
55 @signal navigationRequestAccepted(url, navigation type, main frame) emitted |
49 to signal an accepted navigation request |
56 to signal an accepted navigation request |
|
57 @signal sslConfigurationChanged() emitted to indicate a change of the |
|
58 stored SSL configuration data |
50 """ |
59 """ |
51 SafeJsWorld = QWebEngineScript.ApplicationWorld |
60 SafeJsWorld = QWebEngineScript.ApplicationWorld |
52 UnsafeJsWorld = QWebEngineScript.MainWorld |
61 UnsafeJsWorld = QWebEngineScript.MainWorld |
53 |
62 |
54 safeBrowsingAbort = pyqtSignal() |
63 safeBrowsingAbort = pyqtSignal() |
55 safeBrowsingBad = pyqtSignal(str, str) |
64 safeBrowsingBad = pyqtSignal(str, str) |
56 |
65 |
57 printPageRequested = pyqtSignal() |
66 printPageRequested = pyqtSignal() |
58 navigationRequestAccepted = pyqtSignal(QUrl, QWebEnginePage.NavigationType, |
67 navigationRequestAccepted = pyqtSignal(QUrl, QWebEnginePage.NavigationType, |
59 bool) |
68 bool) |
|
69 |
|
70 sslConfigurationChanged = pyqtSignal() |
60 |
71 |
61 def __init__(self, parent=None): |
72 def __init__(self, parent=None): |
62 """ |
73 """ |
63 Constructor |
74 Constructor |
64 |
75 |
86 self.registerProtocolHandlerRequested.connect( |
97 self.registerProtocolHandlerRequested.connect( |
87 self.__registerProtocolHandlerRequested) |
98 self.__registerProtocolHandlerRequested) |
88 except AttributeError: |
99 except AttributeError: |
89 # defined for Qt >= 5.11 |
100 # defined for Qt >= 5.11 |
90 pass |
101 pass |
|
102 |
|
103 self.__sslConfiguration = None |
91 |
104 |
92 # Workaround for changing webchannel world inside |
105 # Workaround for changing webchannel world inside |
93 # acceptNavigationRequest not working |
106 # acceptNavigationRequest not working |
94 self.__channelUrl = QUrl() |
107 self.__channelUrl = QUrl() |
95 self.__channelWorldId = -1 |
108 self.__channelWorldId = -1 |
612 self.__registerProtocolHandlerRequest.origin().host()) |
625 self.__registerProtocolHandlerRequest.origin().host()) |
613 ): |
626 ): |
614 return self.__registerProtocolHandlerRequest.scheme() |
627 return self.__registerProtocolHandlerRequest.scheme() |
615 else: |
628 else: |
616 return "" |
629 return "" |
|
630 |
|
631 ############################################################# |
|
632 ## SSL configuration handling below |
|
633 ############################################################# |
|
634 |
|
635 def setSslConfiguration(self, sslConfiguration): |
|
636 """ |
|
637 Public slot to set the SSL configuration data of the page. |
|
638 |
|
639 @param sslConfiguration SSL configuration to be set |
|
640 @type QSslConfiguration |
|
641 """ |
|
642 self.__sslConfiguration = QSslConfiguration(sslConfiguration) |
|
643 self.__sslConfiguration.url = self.url() |
|
644 self.sslConfigurationChanged.emit() |
|
645 |
|
646 def getSslConfiguration(self): |
|
647 """ |
|
648 Public method to return a reference to the current SSL configuration. |
|
649 |
|
650 @return reference to the SSL configuration in use |
|
651 @rtype QSslConfiguration |
|
652 """ |
|
653 return self.__sslConfiguration |
|
654 |
|
655 def clearSslConfiguration(self): |
|
656 """ |
|
657 Public slot to clear the stored SSL configuration data. |
|
658 """ |
|
659 self.__sslConfiguration = None |
|
660 self.sslConfigurationChanged.emit() |
|
661 |
|
662 def getSslCertificate(self): |
|
663 """ |
|
664 Public method to get a reference to the SSL certificate. |
|
665 |
|
666 @return amended SSL certificate |
|
667 @rtype QSslCertificate |
|
668 """ |
|
669 if self.__sslConfiguration is None: |
|
670 return None |
|
671 |
|
672 sslCertificate = self.__sslConfiguration.peerCertificate() |
|
673 sslCertificate.url = QUrl(self.__sslConfiguration.url) |
|
674 return sslCertificate |
|
675 |
|
676 def getSslCertificateChain(self): |
|
677 """ |
|
678 Public method to get a reference to the SSL certificate chain. |
|
679 |
|
680 @return SSL certificate chain |
|
681 @rtype list of QSslCertificate |
|
682 """ |
|
683 if self.__sslConfiguration is None: |
|
684 return [] |
|
685 |
|
686 chain = self.__sslConfiguration.peerCertificateChain() |
|
687 return chain |
|
688 |
|
689 def showSslInfo(self, pos): |
|
690 """ |
|
691 Public slot to show some SSL information for the loaded page. |
|
692 |
|
693 @param pos position to show the info at |
|
694 @type QPoint |
|
695 """ |
|
696 if SSL_AVAILABLE and self.__sslConfiguration is not None: |
|
697 from E5Network.E5SslInfoWidget import E5SslInfoWidget |
|
698 widget = E5SslInfoWidget(self.url(), self.__sslConfiguration, |
|
699 self.view()) |
|
700 widget.showAt(pos) |
|
701 else: |
|
702 E5MessageBox.warning( |
|
703 self.view(), |
|
704 self.tr("SSL Info"), |
|
705 self.tr("""This site does not contain SSL information.""")) |
|
706 |
|
707 def hasValidSslInfo(self): |
|
708 """ |
|
709 Public method to check, if the page has a valid SSL certificate. |
|
710 |
|
711 @return flag indicating a valid SSL certificate |
|
712 @rtype bool |
|
713 """ |
|
714 if self.__sslConfiguration is None: |
|
715 return False |
|
716 |
|
717 certList = self.__sslConfiguration.peerCertificateChain() |
|
718 if not certList: |
|
719 return False |
|
720 |
|
721 certificateDict = Globals.toDict( |
|
722 Preferences.Prefs.settings.value("Ssl/CaCertificatesDict")) |
|
723 for server in certificateDict: |
|
724 localCAList = QSslCertificate.fromData(certificateDict[server]) |
|
725 for cert in certList: |
|
726 if cert in localCAList: |
|
727 return True |
|
728 |
|
729 for cert in certList: |
|
730 if cert.isBlacklisted(): |
|
731 return False |
|
732 |
|
733 return True |