2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2022 the Claws Mail team and Colin Leroy
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "claws-features.h"
26 #include <gnutls/gnutls.h>
27 #include <gnutls/x509.h>
28 #include <gnutls/crypto.h>
29 #include <sys/types.h>
36 #include <glib/gi18n.h>
39 #include "prefs_common.h"
41 #include "ssl_certificate.h"
43 #include "alertpanel.h"
46 static gboolean
sslcertwindow_ask_new_cert(SSLCertificate
*cert
);
47 static gboolean
sslcertwindow_ask_expired_cert(SSLCertificate
*cert
);
48 static gboolean
sslcertwindow_ask_changed_cert(SSLCertificate
*old_cert
, SSLCertificate
*new_cert
);
50 static GtkWidget
*cert_presenter(SSLCertificate
*cert
)
52 GtkWidget
*vbox
= NULL
;
53 GtkWidget
*hbox
= NULL
;
54 GtkWidget
*frame_owner
= NULL
;
55 GtkWidget
*frame_signer
= NULL
;
56 GtkWidget
*frame_status
= NULL
;
57 GtkWidget
*owner_table
= NULL
;
58 GtkWidget
*signer_table
= NULL
;
59 GtkWidget
*status_table
= NULL
;
60 GtkWidget
*label
= NULL
;
62 char *issuer_commonname
, *issuer_location
, *issuer_organization
;
63 char *subject_commonname
, *subject_location
, *subject_organization
;
64 char *sig_status
, *exp_date
;
65 char *sha1_fingerprint
, *sha256_fingerprint
, *fingerprint
;
68 unsigned char md
[128];
75 issuer_commonname
= g_malloc(BUFFSIZE
);
76 issuer_location
= g_malloc(BUFFSIZE
);
77 issuer_organization
= g_malloc(BUFFSIZE
);
78 subject_commonname
= g_malloc(BUFFSIZE
);
79 subject_location
= g_malloc(BUFFSIZE
);
80 subject_organization
= g_malloc(BUFFSIZE
);
83 if (gnutls_x509_crt_get_issuer_dn_by_oid(cert
->x509_cert
,
84 GNUTLS_OID_X520_COMMON_NAME
, 0, 0, issuer_commonname
, &n
))
85 strncpy(issuer_commonname
, _("<not in certificate>"), BUFFSIZE
-1);
88 if (gnutls_x509_crt_get_issuer_dn_by_oid(cert
->x509_cert
,
89 GNUTLS_OID_X520_LOCALITY_NAME
, 0, 0, issuer_location
, &n
)) {
90 if (gnutls_x509_crt_get_issuer_dn_by_oid(cert
->x509_cert
,
91 GNUTLS_OID_X520_COUNTRY_NAME
, 0, 0, issuer_location
, &n
)) {
92 strncpy(issuer_location
, _("<not in certificate>"), BUFFSIZE
-1);
95 tmp
= g_malloc(BUFFSIZE
);
96 if (gnutls_x509_crt_get_issuer_dn_by_oid(cert
->x509_cert
,
97 GNUTLS_OID_X520_COUNTRY_NAME
, 0, 0, tmp
, &n
) == 0) {
98 strncat(issuer_location
, ", ", BUFFSIZE
-strlen(issuer_location
)-1);
99 strncat(issuer_location
, tmp
, BUFFSIZE
-strlen(issuer_location
)-1);
105 if (gnutls_x509_crt_get_issuer_dn_by_oid(cert
->x509_cert
,
106 GNUTLS_OID_X520_ORGANIZATION_NAME
, 0, 0, issuer_organization
, &n
))
107 strncpy(issuer_organization
, _("<not in certificate>"), BUFFSIZE
-1);
110 if (gnutls_x509_crt_get_dn_by_oid(cert
->x509_cert
,
111 GNUTLS_OID_X520_COMMON_NAME
, 0, 0, subject_commonname
, &n
))
112 strncpy(subject_commonname
, _("<not in certificate>"), BUFFSIZE
-1);
115 if (gnutls_x509_crt_get_dn_by_oid(cert
->x509_cert
,
116 GNUTLS_OID_X520_LOCALITY_NAME
, 0, 0, subject_location
, &n
)) {
117 if (gnutls_x509_crt_get_dn_by_oid(cert
->x509_cert
,
118 GNUTLS_OID_X520_COUNTRY_NAME
, 0, 0, subject_location
, &n
)) {
119 strncpy(subject_location
, _("<not in certificate>"), BUFFSIZE
-1);
122 tmp
= g_malloc(BUFFSIZE
);
123 if (gnutls_x509_crt_get_dn_by_oid(cert
->x509_cert
,
124 GNUTLS_OID_X520_COUNTRY_NAME
, 0, 0, tmp
, &n
) == 0) {
125 strncat(subject_location
, ", ", BUFFSIZE
-strlen(subject_location
)-1);
126 strncat(subject_location
, tmp
, BUFFSIZE
-strlen(subject_location
)-1);
132 if (gnutls_x509_crt_get_dn_by_oid(cert
->x509_cert
,
133 GNUTLS_OID_X520_ORGANIZATION_NAME
, 0, 0, subject_organization
, &n
))
134 strncpy(subject_organization
, _("<not in certificate>"), BUFFSIZE
-1);
136 exp_time_t
= gnutls_x509_crt_get_expiration_time(cert
->x509_cert
);
138 memset(buf
, 0, sizeof(buf
));
139 if (exp_time_t
> 0) {
140 fast_strftime(buf
, sizeof(buf
)-1, prefs_common
.date_format
, localtime_r(&exp_time_t
, <
));
141 exp_date
= (*buf
) ? g_strdup(buf
):g_strdup("?");
143 exp_date
= g_strdup("");
147 memset(md
, 0, sizeof(md
));
148 if ((ret
= gnutls_x509_crt_get_fingerprint(cert
->x509_cert
, GNUTLS_DIG_SHA1
, md
, &n
)) == GNUTLS_E_SHORT_MEMORY_BUFFER
) {
150 ret
= gnutls_x509_crt_get_fingerprint(cert
->x509_cert
, GNUTLS_DIG_SHA1
, md
, &n
);
154 g_warning("failed to obtain SHA1 fingerprint: %d", ret
);
155 sha1_fingerprint
= g_strdup("-");
157 sha1_fingerprint
= readable_fingerprint(md
, (int)n
);
161 memset(md
, 0, sizeof(md
));
162 if ((ret
= gnutls_x509_crt_get_fingerprint(cert
->x509_cert
, GNUTLS_DIG_SHA256
, md
, &n
)) == GNUTLS_E_SHORT_MEMORY_BUFFER
) {
164 ret
= gnutls_x509_crt_get_fingerprint(cert
->x509_cert
, GNUTLS_DIG_SHA256
, md
, &n
);
168 g_warning("failed to obtain SHA256 fingerprint: %d", ret
);
169 sha256_fingerprint
= g_strdup("-");
171 sha256_fingerprint
= readable_fingerprint(md
, (int)n
);
176 sig_status
= ssl_certificate_check_signer(cert
, cert
->status
);
178 if (sig_status
==NULL
)
179 sig_status
= g_strdup_printf(_("Correct%s"),exp_time_t
< time(NULL
)? _(" (expired)"): "");
180 else if (exp_time_t
< time(NULL
))
181 sig_status
= g_strconcat(sig_status
,_(" (expired)"),NULL
);
183 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5);
184 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 5);
186 frame_owner
= gtk_frame_new(_("Owner"));
187 frame_signer
= gtk_frame_new(_("Signer"));
188 frame_status
= gtk_frame_new(_("Status"));
190 owner_table
= gtk_grid_new();
191 signer_table
= gtk_grid_new();
192 status_table
= gtk_grid_new();
194 label
= gtk_label_new(_("Name: "));
195 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
196 gtk_grid_attach(GTK_GRID(owner_table
), label
, 0, 0, 1, 1);
197 gtk_widget_set_hexpand(label
, TRUE
);
198 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
200 label
= gtk_label_new(subject_commonname
);
201 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
202 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
203 gtk_grid_attach(GTK_GRID(owner_table
), label
, 1, 0, 1, 1);
204 gtk_widget_set_hexpand(label
, TRUE
);
205 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
207 label
= gtk_label_new(_("Organization: "));
208 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
209 gtk_grid_attach(GTK_GRID(owner_table
), label
, 0, 1, 1, 1);
210 gtk_widget_set_hexpand(label
, TRUE
);
211 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
213 label
= gtk_label_new(subject_organization
);
214 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
215 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
216 gtk_grid_attach(GTK_GRID(owner_table
), label
, 1, 1, 1, 1);
217 gtk_widget_set_hexpand(label
, TRUE
);
218 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
220 label
= gtk_label_new(_("Location: "));
221 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
222 gtk_grid_attach(GTK_GRID(owner_table
), label
, 0, 2, 1, 1);
223 gtk_widget_set_hexpand(label
, TRUE
);
224 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
226 label
= gtk_label_new(subject_location
);
227 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
228 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
229 gtk_grid_attach(GTK_GRID(owner_table
), label
, 1, 2, 1, 1);
230 gtk_widget_set_hexpand(label
, TRUE
);
231 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
233 label
= gtk_label_new(_("Name: "));
234 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
235 gtk_grid_attach(GTK_GRID(signer_table
), label
, 0, 0, 1, 1);
236 gtk_widget_set_hexpand(label
, TRUE
);
237 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
239 label
= gtk_label_new(issuer_commonname
);
240 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
241 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
242 gtk_grid_attach(GTK_GRID(signer_table
), label
, 1, 0, 1, 1);
243 gtk_widget_set_hexpand(label
, TRUE
);
244 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
246 label
= gtk_label_new(_("Organization: "));
247 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
248 gtk_grid_attach(GTK_GRID(signer_table
), label
, 0, 1, 1, 1);
249 gtk_widget_set_hexpand(label
, TRUE
);
250 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
252 label
= gtk_label_new(issuer_organization
);
253 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
254 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
255 gtk_grid_attach(GTK_GRID(signer_table
), label
, 1, 1, 1, 1);
256 gtk_widget_set_hexpand(label
, TRUE
);
257 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
259 label
= gtk_label_new(_("Location: "));
260 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
261 gtk_grid_attach(GTK_GRID(signer_table
), label
, 0, 2, 1, 1);
262 gtk_widget_set_hexpand(label
, TRUE
);
263 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
265 label
= gtk_label_new(issuer_location
);
266 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
267 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
268 gtk_grid_attach(GTK_GRID(signer_table
), label
, 1, 2, 1, 1);
269 gtk_widget_set_hexpand(label
, TRUE
);
270 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
272 label
= gtk_label_new(_("Fingerprint: \n"));
273 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
274 gtk_grid_attach(GTK_GRID(status_table
), label
, 0, 0, 1, 1);
275 gtk_widget_set_hexpand(label
, TRUE
);
276 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
278 fingerprint
= g_strdup_printf("SHA1: %s\nSHA256: %s",
279 sha1_fingerprint
, sha256_fingerprint
);
280 label
= gtk_label_new(fingerprint
);
282 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
283 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
284 gtk_grid_attach(GTK_GRID(status_table
), label
, 1, 0, 1, 1);
285 gtk_widget_set_hexpand(label
, TRUE
);
286 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
288 label
= gtk_label_new(_("Signature status: "));
289 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
290 gtk_grid_attach(GTK_GRID(status_table
), label
, 0, 1, 1, 1);
291 gtk_widget_set_hexpand(label
, TRUE
);
292 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
294 label
= gtk_label_new(sig_status
);
295 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
296 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
297 gtk_grid_attach(GTK_GRID(status_table
), label
, 1, 1, 1, 1);
298 gtk_widget_set_hexpand(label
, TRUE
);
299 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
301 label
= gtk_label_new(exp_time_t
< time(NULL
)? _("Expired on: "): _("Expires on: "));
302 gtk_label_set_xalign(GTK_LABEL(label
), 1.0);
303 gtk_grid_attach(GTK_GRID(status_table
), label
, 0, 2, 1, 1);
304 gtk_widget_set_hexpand(label
, TRUE
);
305 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
307 label
= gtk_label_new(exp_date
);
308 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
309 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
310 gtk_grid_attach(GTK_GRID(status_table
), label
, 1, 2, 1, 1);
311 gtk_widget_set_hexpand(label
, TRUE
);
312 gtk_widget_set_halign(label
, GTK_ALIGN_FILL
);
314 gtk_container_add(GTK_CONTAINER(frame_owner
), GTK_WIDGET(owner_table
));
315 gtk_container_add(GTK_CONTAINER(frame_signer
), GTK_WIDGET(signer_table
));
316 gtk_container_add(GTK_CONTAINER(frame_status
), GTK_WIDGET(status_table
));
318 gtk_box_pack_end(GTK_BOX(hbox
), frame_signer
, TRUE
, TRUE
, 0);
319 gtk_box_pack_end(GTK_BOX(hbox
), frame_owner
, TRUE
, TRUE
, 0);
320 gtk_box_pack_end(GTK_BOX(vbox
), frame_status
, TRUE
, TRUE
, 0);
321 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, TRUE
, TRUE
, 0);
323 gtk_widget_show_all(vbox
);
325 g_free(issuer_commonname
);
326 g_free(issuer_location
);
327 g_free(issuer_organization
);
328 g_free(subject_commonname
);
329 g_free(subject_location
);
330 g_free(subject_organization
);
331 g_free(sha1_fingerprint
);
332 g_free(sha256_fingerprint
);
338 static gboolean
sslcert_ask_hook(gpointer source
, gpointer data
)
340 SSLCertHookData
*hookdata
= (SSLCertHookData
*)source
;
342 if (hookdata
== NULL
) {
346 if (prefs_common
.skip_ssl_cert_check
) {
347 hookdata
->accept
= TRUE
;
351 if (hookdata
->old_cert
== NULL
) {
352 if (hookdata
->expired
)
353 hookdata
->accept
= sslcertwindow_ask_expired_cert(hookdata
->cert
);
355 hookdata
->accept
= sslcertwindow_ask_new_cert(hookdata
->cert
);
357 hookdata
->accept
= sslcertwindow_ask_changed_cert(hookdata
->old_cert
, hookdata
->cert
);
363 void sslcertwindow_register_hook(void)
365 hooks_register_hook(SSLCERT_ASK_HOOKLIST
, sslcert_ask_hook
, NULL
);
368 void sslcertwindow_show_cert(SSLCertificate
*cert
)
370 GtkWidget
*cert_widget
= cert_presenter(cert
);
373 buf
= g_strdup_printf(_("TLS certificate for %s"), cert
->host
);
374 alertpanel_full(buf
, NULL
, "window-close", _("_Close"), NULL
, NULL
, NULL
, NULL
,
375 ALERTFOCUS_FIRST
, FALSE
, cert_widget
, ALERT_NOTICE
);
379 static gchar
*sslcertwindow_get_invalid_str(SSLCertificate
*cert
)
381 gchar
*subject_cn
= NULL
;
384 if (ssl_certificate_check_subject_cn(cert
))
387 subject_cn
= ssl_certificate_get_subject_cn(cert
);
389 str
= g_strdup_printf(_("Certificate is for %s, but connection is to %s.\n"
390 "You may be connecting to a rogue server.\n\n"),
391 subject_cn
, cert
->host
);
397 static gboolean
sslcertwindow_ask_new_cert(SSLCertificate
*cert
)
399 gchar
*buf
, *sig_status
;
404 GtkWidget
*cert_widget
;
405 gchar
*invalid_str
= sslcertwindow_get_invalid_str(cert
);
408 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5);
409 buf
= g_strdup_printf(_("Certificate for %s is unknown.\n%sDo you want to accept it?"), cert
->host
, invalid_str
);
412 label
= gtk_label_new(buf
);
413 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
414 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
417 sig_status
= ssl_certificate_check_signer(cert
, cert
->status
);
418 if (sig_status
==NULL
)
419 sig_status
= g_strdup(_("Correct"));
421 buf
= g_strdup_printf(_("Signature status: %s"), sig_status
);
422 label
= gtk_label_new(buf
);
423 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
424 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
425 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
429 button
= gtk_expander_new_with_mnemonic(_("_View certificate"));
430 gtk_box_pack_start(GTK_BOX(vbox
), button
, FALSE
, FALSE
, 0);
431 cert_widget
= cert_presenter(cert
);
432 gtk_container_add(GTK_CONTAINER(button
), cert_widget
);
434 if (!ssl_certificate_check_subject_cn(cert
))
435 title
= _("TLS certificate is invalid");
437 title
= _("TLS certificate is unknown");
439 val
= alertpanel_full(title
, NULL
,
440 NULL
, _("_Cancel connection"), NULL
, _("_Accept and save"),
441 NULL
, NULL
, ALERTFOCUS_FIRST
, FALSE
, vbox
, ALERT_QUESTION
);
443 return (val
== G_ALERTALTERNATE
);
446 static gboolean
sslcertwindow_ask_expired_cert(SSLCertificate
*cert
)
448 gchar
*buf
, *sig_status
;
453 GtkWidget
*cert_widget
;
454 gchar
*invalid_str
= sslcertwindow_get_invalid_str(cert
);
457 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5);
458 buf
= g_strdup_printf(_("Certificate for %s is expired.\n%sDo you want to continue?"), cert
->host
, invalid_str
);
461 label
= gtk_label_new(buf
);
462 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
463 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
466 sig_status
= ssl_certificate_check_signer(cert
, cert
->status
);
468 if (sig_status
==NULL
)
469 sig_status
= g_strdup(_("Correct"));
471 buf
= g_strdup_printf(_("Signature status: %s"), sig_status
);
472 label
= gtk_label_new(buf
);
473 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
474 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
475 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
479 button
= gtk_expander_new_with_mnemonic(_("_View certificate"));
480 gtk_box_pack_start(GTK_BOX(vbox
), button
, FALSE
, FALSE
, 0);
481 cert_widget
= cert_presenter(cert
);
482 gtk_container_add(GTK_CONTAINER(button
), cert_widget
);
484 if (!ssl_certificate_check_subject_cn(cert
))
485 title
= _("TLS certificate is invalid and expired");
487 title
= _("TLS certificate is expired");
489 val
= alertpanel_full(title
, NULL
,
490 NULL
, _("_Cancel connection"), NULL
, _("_Accept"),
491 NULL
, NULL
, ALERTFOCUS_FIRST
, FALSE
, vbox
, ALERT_QUESTION
);
493 return (val
== G_ALERTALTERNATE
);
496 static gboolean
sslcertwindow_ask_changed_cert(SSLCertificate
*old_cert
, SSLCertificate
*new_cert
)
498 GtkWidget
*old_cert_widget
= cert_presenter(old_cert
);
499 GtkWidget
*new_cert_widget
= cert_presenter(new_cert
);
501 gchar
*buf
, *sig_status
;
506 gchar
*invalid_str
= sslcertwindow_get_invalid_str(new_cert
);
509 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5);
510 label
= gtk_label_new(_("New certificate:"));
511 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
512 gtk_box_pack_end(GTK_BOX(vbox
), new_cert_widget
, TRUE
, TRUE
, 0);
513 gtk_box_pack_end(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
514 gtk_box_pack_end(GTK_BOX(vbox
), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
), TRUE
, TRUE
, 0);
515 label
= gtk_label_new(_("Known certificate:"));
516 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
517 gtk_box_pack_end(GTK_BOX(vbox
), old_cert_widget
, TRUE
, TRUE
, 0);
518 gtk_box_pack_end(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
519 gtk_widget_show_all(vbox
);
521 vbox2
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5);
522 buf
= g_strdup_printf(_("Certificate for %s has changed.\n%sDo you want to accept it?"), new_cert
->host
, invalid_str
);
525 label
= gtk_label_new(buf
);
526 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
527 gtk_box_pack_start(GTK_BOX(vbox2
), label
, TRUE
, TRUE
, 0);
530 sig_status
= ssl_certificate_check_signer(new_cert
, new_cert
->status
);
532 if (sig_status
==NULL
)
533 sig_status
= g_strdup(_("Correct"));
535 buf
= g_strdup_printf(_("Signature status: %s"), sig_status
);
536 label
= gtk_label_new(buf
);
537 gtk_label_set_selectable(GTK_LABEL(label
), TRUE
);
538 gtk_label_set_xalign(GTK_LABEL(label
), 0.0);
539 gtk_box_pack_start(GTK_BOX(vbox2
), label
, TRUE
, TRUE
, 0);
543 button
= gtk_expander_new_with_mnemonic(_("_View certificates"));
544 gtk_box_pack_start(GTK_BOX(vbox2
), button
, FALSE
, FALSE
, 0);
545 gtk_container_add(GTK_CONTAINER(button
), vbox
);
547 if (!ssl_certificate_check_subject_cn(new_cert
))
548 title
= _("TLS certificate changed and is invalid");
550 title
= _("TLS certificate changed");
551 val
= alertpanel_full(title
, NULL
,
552 NULL
, _("_Cancel connection"), NULL
, _("_Accept and save"),
553 NULL
, NULL
, ALERTFOCUS_FIRST
, FALSE
, vbox2
, ALERT_WARNING
);
555 return (val
== G_ALERTALTERNATE
);