17 |
17 |
18 class EricSslInfoWidget(QMenu): |
18 class EricSslInfoWidget(QMenu): |
19 """ |
19 """ |
20 Class implementing a widget to show SSL certificate infos. |
20 Class implementing a widget to show SSL certificate infos. |
21 """ |
21 """ |
|
22 |
22 def __init__(self, url, configuration, parent=None): |
23 def __init__(self, url, configuration, parent=None): |
23 """ |
24 """ |
24 Constructor |
25 Constructor |
25 |
26 |
26 @param url URL to show SSL info for (QUrl) |
27 @param url URL to show SSL info for (QUrl) |
27 @param configuration SSL configuration (QSslConfiguration) |
28 @param configuration SSL configuration (QSslConfiguration) |
28 @param parent reference to the parent widget (QWidget) |
29 @param parent reference to the parent widget (QWidget) |
29 """ |
30 """ |
30 super().__init__(parent) |
31 super().__init__(parent) |
31 |
32 |
32 self.__url = QUrl(url) |
33 self.__url = QUrl(url) |
33 self.__configuration = QSslConfiguration(configuration) |
34 self.__configuration = QSslConfiguration(configuration) |
34 |
35 |
35 self.setMinimumWidth(400) |
36 self.setMinimumWidth(400) |
36 |
37 |
37 certList = self.__configuration.peerCertificateChain() |
38 certList = self.__configuration.peerCertificateChain() |
38 cert = certList[0] if certList else QSslCertificate() |
39 cert = certList[0] if certList else QSslCertificate() |
39 |
40 |
40 layout = QGridLayout(self) |
41 layout = QGridLayout(self) |
41 rows = 0 |
42 rows = 0 |
42 |
43 |
43 ########################################## |
44 ########################################## |
44 ## Identity Information |
45 ## Identity Information |
45 ########################################## |
46 ########################################## |
46 imageLabel = QLabel(self) |
47 imageLabel = QLabel(self) |
47 layout.addWidget(imageLabel, rows, 0, Qt.AlignmentFlag.AlignCenter) |
48 layout.addWidget(imageLabel, rows, 0, Qt.AlignmentFlag.AlignCenter) |
48 |
49 |
49 label = QLabel(self) |
50 label = QLabel(self) |
50 label.setWordWrap(True) |
51 label.setWordWrap(True) |
51 label.setSizePolicy(QSizePolicy.Policy.Expanding, |
52 label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred) |
52 QSizePolicy.Policy.Preferred) |
|
53 label.setText(self.tr("Identity")) |
53 label.setText(self.tr("Identity")) |
54 font = label.font() |
54 font = label.font() |
55 font.setBold(True) |
55 font.setBold(True) |
56 label.setFont(font) |
56 label.setFont(font) |
57 layout.addWidget(label, rows, 1) |
57 layout.addWidget(label, rows, 1) |
58 rows += 1 |
58 rows += 1 |
59 |
59 |
60 label = QLabel(self) |
60 label = QLabel(self) |
61 label.setWordWrap(True) |
61 label.setWordWrap(True) |
62 if cert.isNull(): |
62 if cert.isNull(): |
63 label.setText(self.tr( |
63 label.setText(self.tr("Warning: this site is NOT carrying a certificate.")) |
64 "Warning: this site is NOT carrying a certificate.")) |
|
65 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
64 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
66 else: |
65 else: |
67 valid = not cert.isBlacklisted() |
66 valid = not cert.isBlacklisted() |
68 if valid: |
67 if valid: |
69 txt = ", ".join( |
68 txt = ", ".join(cert.issuerInfo(QSslCertificate.SubjectInfo.CommonName)) |
70 cert.issuerInfo(QSslCertificate.SubjectInfo.CommonName)) |
69 label.setText( |
71 label.setText(self.tr( |
70 self.tr( |
72 "The certificate for this site is valid" |
71 "The certificate for this site is valid" |
73 " and has been verified by:\n{0}").format( |
72 " and has been verified by:\n{0}" |
74 Utilities.decodeString(txt))) |
73 ).format(Utilities.decodeString(txt)) |
75 imageLabel.setPixmap( |
74 ) |
76 UI.PixmapCache.getPixmap("securityHigh32")) |
75 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityHigh32")) |
77 else: |
76 else: |
78 label.setText(self.tr( |
77 label.setText(self.tr("The certificate for this site is NOT valid.")) |
79 "The certificate for this site is NOT valid.")) |
78 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
80 imageLabel.setPixmap( |
79 layout.addWidget(label, rows, 1) |
81 UI.PixmapCache.getPixmap("securityLow32")) |
80 rows += 1 |
82 layout.addWidget(label, rows, 1) |
81 |
83 rows += 1 |
|
84 |
|
85 label = QLabel(self) |
82 label = QLabel(self) |
86 label.setWordWrap(True) |
83 label.setWordWrap(True) |
87 label.setText( |
84 label.setText( |
88 '<a href="moresslinfos">' + |
85 '<a href="moresslinfos">' + self.tr("Certificate Information") + "</a>" |
89 self.tr("Certificate Information") + "</a>") |
86 ) |
90 label.linkActivated.connect(self.__showCertificateInfos) |
87 label.linkActivated.connect(self.__showCertificateInfos) |
91 layout.addWidget(label, rows, 1) |
88 layout.addWidget(label, rows, 1) |
92 rows += 1 |
89 rows += 1 |
93 |
90 |
94 ########################################## |
91 ########################################## |
95 ## Identity Information |
92 ## Identity Information |
96 ########################################## |
93 ########################################## |
97 imageLabel = QLabel(self) |
94 imageLabel = QLabel(self) |
98 layout.addWidget(imageLabel, rows, 0, Qt.AlignmentFlag.AlignCenter) |
95 layout.addWidget(imageLabel, rows, 0, Qt.AlignmentFlag.AlignCenter) |
99 |
96 |
100 label = QLabel(self) |
97 label = QLabel(self) |
101 label.setWordWrap(True) |
98 label.setWordWrap(True) |
102 label.setText(self.tr("Encryption")) |
99 label.setText(self.tr("Encryption")) |
103 font = label.font() |
100 font = label.font() |
104 font.setBold(True) |
101 font.setBold(True) |
105 label.setFont(font) |
102 label.setFont(font) |
106 layout.addWidget(label, rows, 1) |
103 layout.addWidget(label, rows, 1) |
107 rows += 1 |
104 rows += 1 |
108 |
105 |
109 cipher = self.__configuration.sessionCipher() |
106 cipher = self.__configuration.sessionCipher() |
110 if cipher.isNull(): |
107 if cipher.isNull(): |
111 label = QLabel(self) |
108 label = QLabel(self) |
112 label.setWordWrap(True) |
109 label.setWordWrap(True) |
113 label.setText(self.tr( |
110 label.setText( |
114 'Your connection to "{0}" is NOT encrypted.\n').format( |
111 self.tr('Your connection to "{0}" is NOT encrypted.\n').format( |
115 self.__url.host())) |
112 self.__url.host() |
|
113 ) |
|
114 ) |
116 layout.addWidget(label, rows, 1) |
115 layout.addWidget(label, rows, 1) |
117 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
116 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
118 rows += 1 |
117 rows += 1 |
119 else: |
118 else: |
120 label = QLabel(self) |
119 label = QLabel(self) |
121 label.setWordWrap(True) |
120 label.setWordWrap(True) |
122 label.setText(self.tr( |
121 label.setText( |
123 'Your connection to "{0}" is encrypted.').format( |
122 self.tr('Your connection to "{0}" is encrypted.').format( |
124 self.__url.host())) |
123 self.__url.host() |
125 layout.addWidget(label, rows, 1) |
124 ) |
126 |
125 ) |
|
126 layout.addWidget(label, rows, 1) |
|
127 |
127 proto = cipher.protocol() |
128 proto = cipher.protocol() |
128 if proto == QSsl.SslProtocol.TlsV1_0: |
129 if proto == QSsl.SslProtocol.TlsV1_0: |
129 sslVersion = "TLS v1.0" |
130 sslVersion = "TLS v1.0" |
130 imageLabel.setPixmap( |
131 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
131 UI.PixmapCache.getPixmap("securityLow32")) |
|
132 elif proto == QSsl.SslProtocol.TlsV1_1: |
132 elif proto == QSsl.SslProtocol.TlsV1_1: |
133 sslVersion = "TLS v1.1" |
133 sslVersion = "TLS v1.1" |
134 imageLabel.setPixmap( |
134 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityMedium32")) |
135 UI.PixmapCache.getPixmap("securityMedium32")) |
|
136 elif proto == QSsl.SslProtocol.TlsV1_2: |
135 elif proto == QSsl.SslProtocol.TlsV1_2: |
137 sslVersion = "TLS v1.2" |
136 sslVersion = "TLS v1.2" |
138 imageLabel.setPixmap( |
137 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityHigh32")) |
139 UI.PixmapCache.getPixmap("securityHigh32")) |
|
140 elif proto == QSsl.SslProtocol.TlsV1_3: |
138 elif proto == QSsl.SslProtocol.TlsV1_3: |
141 sslVersion = "TLS v1.3" |
139 sslVersion = "TLS v1.3" |
142 imageLabel.setPixmap( |
140 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityHigh32")) |
143 UI.PixmapCache.getPixmap("securityHigh32")) |
|
144 elif proto == QSsl.SslProtocol.DtlsV1_0: |
141 elif proto == QSsl.SslProtocol.DtlsV1_0: |
145 sslVersion = "DTLS v1.0" |
142 sslVersion = "DTLS v1.0" |
146 imageLabel.setPixmap( |
143 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
147 UI.PixmapCache.getPixmap("securityLow32")) |
|
148 elif proto == QSsl.SslProtocol.DtlsV1_2: |
144 elif proto == QSsl.SslProtocol.DtlsV1_2: |
149 sslVersion = "DTLS v1.2" |
145 sslVersion = "DTLS v1.2" |
150 imageLabel.setPixmap( |
146 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityHigh32")) |
151 UI.PixmapCache.getPixmap("securityHigh32")) |
|
152 else: |
147 else: |
153 sslVersion = self.tr("unknown") |
148 sslVersion = self.tr("unknown") |
154 imageLabel.setPixmap( |
149 imageLabel.setPixmap(UI.PixmapCache.getPixmap("securityLow32")) |
155 UI.PixmapCache.getPixmap("securityLow32")) |
150 rows += 1 |
156 rows += 1 |
151 |
157 |
152 label = QLabel(self) |
158 label = QLabel(self) |
153 label.setWordWrap(True) |
159 label.setWordWrap(True) |
154 label.setText(self.tr("It uses protocol: {0}").format(sslVersion)) |
160 label.setText(self.tr( |
155 layout.addWidget(label, rows, 1) |
161 "It uses protocol: {0}").format(sslVersion)) |
156 rows += 1 |
162 layout.addWidget(label, rows, 1) |
157 |
163 rows += 1 |
|
164 |
|
165 label = QLabel(self) |
158 label = QLabel(self) |
166 label.setWordWrap(True) |
159 label.setWordWrap(True) |
167 if ( |
160 if ( |
168 not cipher.encryptionMethod() or |
161 not cipher.encryptionMethod() |
169 not cipher.usedBits() or |
162 or not cipher.usedBits() |
170 not cipher.authenticationMethod() or |
163 or not cipher.authenticationMethod() |
171 not cipher.keyExchangeMethod() |
164 or not cipher.keyExchangeMethod() |
172 ): |
165 ): |
173 label.setText(self.tr( |
166 label.setText(self.tr("The cipher data is incomplete or not known.")) |
174 "The cipher data is incomplete or not known." |
|
175 )) |
|
176 else: |
167 else: |
177 label.setText(self.tr( |
168 label.setText( |
178 "It is encrypted using {0} at {1} bits, " |
169 self.tr( |
179 "with {2} for message authentication and " |
170 "It is encrypted using {0} at {1} bits, " |
180 "{3} as key exchange mechanism.\n\n" |
171 "with {2} for message authentication and " |
181 ).format( |
172 "{3} as key exchange mechanism.\n\n" |
182 cipher.encryptionMethod(), |
173 ).format( |
183 cipher.usedBits(), |
174 cipher.encryptionMethod(), |
184 cipher.authenticationMethod(), |
175 cipher.usedBits(), |
185 cipher.keyExchangeMethod() |
176 cipher.authenticationMethod(), |
186 )) |
177 cipher.keyExchangeMethod(), |
187 layout.addWidget(label, rows, 1) |
178 ) |
188 rows += 1 |
179 ) |
189 |
180 layout.addWidget(label, rows, 1) |
|
181 rows += 1 |
|
182 |
190 def showAt(self, pos): |
183 def showAt(self, pos): |
191 """ |
184 """ |
192 Public method to show the widget. |
185 Public method to show the widget. |
193 |
186 |
194 @param pos position to show at (QPoint) |
187 @param pos position to show at (QPoint) |
195 """ |
188 """ |
196 self.adjustSize() |
189 self.adjustSize() |
197 xpos = pos.x() - self.width() |
190 xpos = pos.x() - self.width() |
198 if xpos < 0: |
191 if xpos < 0: |
199 xpos = 10 |
192 xpos = 10 |
200 p = QPoint(xpos, pos.y() + 10) |
193 p = QPoint(xpos, pos.y() + 10) |
201 self.move(p) |
194 self.move(p) |
202 self.show() |
195 self.show() |
203 |
196 |
204 def __showCertificateInfos(self): |
197 def __showCertificateInfos(self): |
205 """ |
198 """ |
206 Private slot to show certificate information. |
199 Private slot to show certificate information. |
207 """ |
200 """ |
208 from .EricSslCertificatesInfoDialog import ( |
201 from .EricSslCertificatesInfoDialog import EricSslCertificatesInfoDialog |
209 EricSslCertificatesInfoDialog |
202 |
210 ) |
203 dlg = EricSslCertificatesInfoDialog(self.__configuration.peerCertificateChain()) |
211 dlg = EricSslCertificatesInfoDialog( |
|
212 self.__configuration.peerCertificateChain()) |
|
213 dlg.exec() |
204 dlg.exec() |
214 |
205 |
215 def accept(self): |
206 def accept(self): |
216 """ |
207 """ |
217 Public method to accept the widget. |
208 Public method to accept the widget. |
218 """ |
209 """ |
219 self.close() |
210 self.close() |