From 0b3cbf57875fd692e4ba0b336fefa4bee1ed00dc Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Mon, 26 Feb 2018 11:23:00 +0100 Subject: Initial commit for sylpheed 3.7.0 --- src/sigstatus.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 src/sigstatus.c (limited to 'src/sigstatus.c') diff --git a/src/sigstatus.c b/src/sigstatus.c new file mode 100644 index 0000000..4f777e7 --- /dev/null +++ b/src/sigstatus.c @@ -0,0 +1,280 @@ +/* sigstatus.h - GTK+ based signature status display + * Copyright (C) 2001 Werner Koch (dd9jn) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if USE_GPGME + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtkutils.h" +#include "utils.h" +#include "sigstatus.h" + +/* remove the window after 30 seconds to avoid cluttering the deskop + * with too many of them */ +#define MY_TIMEOUT (30*1000) + +struct gpgmegtk_sig_status_s { + GtkWidget *mainwindow; + GtkWidget *label; + gint running; + gint destroy_pending; + guint timeout_id; + gint timeout_id_valid; +}; + + +static void do_destroy(GpgmegtkSigStatus hd) +{ + if (!hd->running) { + if (hd->timeout_id_valid) { + g_source_remove(hd->timeout_id); + hd->timeout_id_valid = 0; + } + if (hd->mainwindow) { + gtk_widget_destroy ( hd->mainwindow ); + hd->mainwindow = NULL; + } + if (hd->destroy_pending) + g_free(hd); + } +} + +static void okay_cb(GtkWidget *widget, gpointer data) +{ + GpgmegtkSigStatus hd = data; + + hd->running = 0; + do_destroy(hd); +} + +static gboolean delete_event(GtkWidget *widget, GdkEventAny *event, gpointer data) +{ + GpgmegtkSigStatus hd = data; + + hd->running = 0; + do_destroy(hd); + + return TRUE; +} + +static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) +{ + GpgmegtkSigStatus hd = data; + + if (event && event->keyval == GDK_Escape) { + hd->running = 0; + do_destroy(hd); + return TRUE; + } + return FALSE; +} + +GpgmegtkSigStatus gpgmegtk_sig_status_create(void) +{ + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *okay_btn; + GtkWidget *okay_area; + GpgmegtkSigStatus hd; + + hd = g_malloc0(sizeof *hd); + hd->running = 1; + + window = gtk_dialog_new(); + hd->mainwindow = window; + gtk_widget_set_size_request(window, 400, -1); + gtk_window_set_title(GTK_WINDOW(window), _("Signature check result")); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE); + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(delete_event), hd); + g_signal_connect(G_OBJECT(window), "key_press_event", + G_CALLBACK(key_pressed), hd); + + vbox = gtk_vbox_new(FALSE, 8); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 12); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), + vbox, TRUE, TRUE, 0); + gtk_widget_show(vbox); + + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show(hbox); + + label = gtk_label_new(_("Checking signature")); + hd->label = label; + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_selectable(GTK_LABEL(label), TRUE); + gtk_widget_show(label); + + gtkut_stock_button_set_create(&okay_area, &okay_btn, GTK_STOCK_OK, + NULL, NULL, NULL, NULL); + gtk_box_pack_end(GTK_BOX(GTK_DIALOG(window)->action_area), + okay_area, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(okay_area), 5); + gtk_widget_grab_default(okay_btn); + gtk_widget_grab_focus(okay_btn); + g_signal_connect(G_OBJECT(okay_btn), "clicked", + G_CALLBACK(okay_cb), hd); + + gtk_widget_show_all(window); + + while (gtk_events_pending()) + gtk_main_iteration(); + + return hd; +} + +static gint timeout_cb(gpointer data) +{ + GpgmegtkSigStatus hd = data; + + gdk_threads_enter(); + + hd->running = 0; + hd->timeout_id_valid = 0; + do_destroy(hd); + + gdk_threads_leave(); + + return FALSE; +} + +void gpgmegtk_sig_status_destroy(GpgmegtkSigStatus hd) +{ + if (hd) { + hd->destroy_pending = 1; + if (hd->running && !hd->timeout_id_valid) { + hd->timeout_id = g_timeout_add(MY_TIMEOUT, + timeout_cb, hd); + hd->timeout_id_valid = 1; + } + do_destroy(hd); + } +} + +void gpgmegtk_sig_status_update(GpgmegtkSigStatus hd, gpgme_ctx_t ctx) +{ + gpgme_verify_result_t result; + gpgme_signature_t sig; + gchar *text = NULL; + + if (!hd || !hd->running || !ctx) + return; + result = gpgme_op_verify_result(ctx); + if (!result) + return; + + sig = result->signatures; + while (sig) { + gchar *tmp; + const gchar *userid; + gpgme_key_t key = NULL; + + if (!gpgme_get_key(ctx, sig->fpr, &key, 0)) { + userid = key->uids->uid; + } else { + userid = "[?]"; + } + tmp = g_strdup_printf + (_("%s%s%s from \"%s\""), + text ? text : "", text ? "\n" : "", + gpgmegtk_sig_status_to_string(sig, FALSE), userid); + g_free (text); + text = tmp; + gpgme_key_unref (key); + sig = sig->next; + } + gtk_label_set_text(GTK_LABEL(hd->label), text); + g_free(text); + + while (gtk_events_pending()) + gtk_main_iteration(); +} + +const gchar *gpgmegtk_sig_status_to_string(gpgme_signature_t signature, + gboolean use_name) +{ + const gchar *result = "?"; + + g_return_val_if_fail(signature != NULL, result); + + switch (gpg_err_code(signature->status)) { + case GPG_ERR_NO_DATA: + result = _("No signature found"); + break; + case GPG_ERR_NO_ERROR: + switch (signature->validity) { + case GPGME_VALIDITY_ULTIMATE: + case GPGME_VALIDITY_FULL: + case GPGME_VALIDITY_MARGINAL: + result = use_name ? _("Good signature from \"%s\"") : + _("Good signature"); + break; + default: + result = use_name ? + _("Valid signature but the key for \"%s\" is not trusted") : + _("Valid signature (untrusted key)"); + break; + } + break; + case GPG_ERR_SIG_EXPIRED: + result = use_name ? _("Signature valid but expired for \"%s\"") : + _("Signature valid but expired"); + break; + case GPG_ERR_KEY_EXPIRED: + result = use_name ? _("Signature valid but the signing key for \"%s\" has expired") : + _("Signature valid but the signing key has expired"); + break; + case GPG_ERR_CERT_REVOKED: + result = use_name ? _("Signature valid but the signing key for \"%s\" has been revoked") : + _("Signature valid but the signing key has been revoked"); + break; + case GPG_ERR_BAD_SIGNATURE: + result = use_name ? _("BAD signature from \"%s\"") : + _("BAD signature"); + break; + case GPG_ERR_NO_PUBKEY: + result = _("No public key to verify the signature"); + break; + default: + result = _("Error verifying the signature"); + break; + } + + return result; +} + +#endif /* USE_GPGME */ -- cgit v1.3