Improve some sieve-related translations
[claws.git] / src / gtk / sslcertwindow.c
blobb71f6aedca512895e8d207a98c539cdb454ebef7
1 /*
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/>.
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #include "claws-features.h"
22 #endif
24 #ifdef USE_GNUTLS
26 #include <gnutls/gnutls.h>
27 #include <gnutls/x509.h>
28 #include <gnutls/crypto.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <string.h>
35 #include <glib.h>
36 #include <glib/gi18n.h>
37 #include <gtk/gtk.h>
39 #include "prefs_common.h"
40 #include "defs.h"
41 #include "ssl_certificate.h"
42 #include "utils.h"
43 #include "alertpanel.h"
44 #include "hooks.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;
66 size_t n;
67 char buf[100];
68 unsigned char md[128];
69 char *tmp;
70 time_t exp_time_t;
71 struct tm lt;
72 guint ret;
74 /* issuer */
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);
82 n = 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);
86 n = BUFFSIZE;
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);
94 } else {
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);
101 g_free(tmp);
104 n = BUFFSIZE;
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);
109 n = BUFFSIZE;
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);
113 n = BUFFSIZE;
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);
121 } else {
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);
128 g_free(tmp);
131 n = BUFFSIZE;
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, &lt));
141 exp_date = (*buf) ? g_strdup(buf):g_strdup("?");
142 } else
143 exp_date = g_strdup("");
145 /* fingerprints */
146 n = 0;
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) {
149 if (n <= sizeof(md))
150 ret = gnutls_x509_crt_get_fingerprint(cert->x509_cert, GNUTLS_DIG_SHA1, md, &n);
153 if (ret != 0) {
154 g_warning("failed to obtain SHA1 fingerprint: %d", ret);
155 sha1_fingerprint = g_strdup("-");
156 } else {
157 sha1_fingerprint = readable_fingerprint(md, (int)n);
160 n = 0;
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) {
163 if (n <= sizeof(md))
164 ret = gnutls_x509_crt_get_fingerprint(cert->x509_cert, GNUTLS_DIG_SHA256, md, &n);
167 if (ret != 0) {
168 g_warning("failed to obtain SHA256 fingerprint: %d", ret);
169 sha256_fingerprint = g_strdup("-");
170 } else {
171 sha256_fingerprint = readable_fingerprint(md, (int)n);
175 /* signature */
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);
281 g_free(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);
333 g_free(sig_status);
334 g_free(exp_date);
335 return vbox;
338 static gboolean sslcert_ask_hook(gpointer source, gpointer data)
340 SSLCertHookData *hookdata = (SSLCertHookData *)source;
342 if (hookdata == NULL) {
343 return FALSE;
346 if (prefs_common.skip_ssl_cert_check) {
347 hookdata->accept = TRUE;
348 return TRUE;
351 if (hookdata->old_cert == NULL) {
352 if (hookdata->expired)
353 hookdata->accept = sslcertwindow_ask_expired_cert(hookdata->cert);
354 else
355 hookdata->accept = sslcertwindow_ask_new_cert(hookdata->cert);
356 } else {
357 hookdata->accept = sslcertwindow_ask_changed_cert(hookdata->old_cert, hookdata->cert);
360 return TRUE;
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);
371 gchar *buf;
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);
376 g_free(buf);
379 static gchar *sslcertwindow_get_invalid_str(SSLCertificate *cert)
381 gchar *subject_cn = NULL;
382 gchar *str = NULL;
384 if (ssl_certificate_check_subject_cn(cert))
385 return g_strdup("");
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);
392 g_free(subject_cn);
394 return str;
397 static gboolean sslcertwindow_ask_new_cert(SSLCertificate *cert)
399 gchar *buf, *sig_status;
400 AlertValue val;
401 GtkWidget *vbox;
402 GtkWidget *label;
403 GtkWidget *button;
404 GtkWidget *cert_widget;
405 gchar *invalid_str = sslcertwindow_get_invalid_str(cert);
406 const gchar *title;
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);
410 g_free(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);
415 g_free(buf);
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);
426 g_free(buf);
427 g_free(sig_status);
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");
436 else
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;
449 AlertValue val;
450 GtkWidget *vbox;
451 GtkWidget *label;
452 GtkWidget *button;
453 GtkWidget *cert_widget;
454 gchar *invalid_str = sslcertwindow_get_invalid_str(cert);
455 const gchar *title;
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);
459 g_free(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);
464 g_free(buf);
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);
476 g_free(buf);
477 g_free(sig_status);
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");
486 else
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);
500 GtkWidget *vbox;
501 gchar *buf, *sig_status;
502 GtkWidget *vbox2;
503 GtkWidget *label;
504 GtkWidget *button;
505 AlertValue val;
506 gchar *invalid_str = sslcertwindow_get_invalid_str(new_cert);
507 const gchar *title;
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);
523 g_free(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);
528 g_free(buf);
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);
540 g_free(buf);
541 g_free(sig_status);
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");
549 else
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);
557 #endif