diff --git a/configure.ac b/configure.ac index ac0ae1b..f043557 100644 --- a/configure.ac +++ b/configure.ac @@ -163,6 +163,11 @@ AC_ARG_WITH(libsecret, [Link to libsecret instead of gnome-keyring (default=no)]), [with_libsecret=$withval],[with_libsecret=no]) +AC_ARG_WITH(gcr, + AC_HELP_STRING([--with-gcr], + [Use libgcr-3 for dealing with TLS certificates (experimental, default=no)]), + [with_gcr=$withval],[with_gcr=no]) + AC_ARG_ENABLE(more-warnings, AC_HELP_STRING([--enable-more-warnings], [Enable maximum compiler warnings (default=yes)]), @@ -607,6 +612,14 @@ if test x$with_libnotify != xno; then with_libnotify=" >= 0.$notifyver" fi +# gcr configuration +if test x$with_gcr != xno; then + PKG_CHECK_MODULES(GCR, [ gcr-3 ]) + AC_DEFINE(HAVE_GCR,1,[Defined when gcr-3 can be used.]) + BALSA_CFLAGS="$BALSA_CFLAGS $GCR_CFLAGS" + BALSA_LIBS="$BALSA_LIBS $GCR_LIBS" +fi + # Compface configuration # AC_MSG_CHECKING([whether to build Compface support]) @@ -888,6 +901,7 @@ echo " Use GtkSourceView: $with_gtksourceview" echo " Use Compface: $with_compface" echo " Install extra MIME icons: $install_mimeicons" echo " Use libsecret: $with_libsecret" +echo " Use gcr: $with_gcr" dnl echo " Use SASL: $need_sasl" echo "" diff --git a/libbalsa/libbalsa.c b/libbalsa/libbalsa.c index ad92f80..8504463 100644 --- a/libbalsa/libbalsa.c +++ b/libbalsa/libbalsa.c @@ -51,6 +51,11 @@ #include #endif +#if HAVE_GCR +#define GCR_API_SUBJECT_TO_CHANGE +#include +#endif + #include "misc.h" #include "missing.h" #include @@ -347,6 +352,9 @@ libbalsa_ask(gboolean (*cb)(void *arg), void *arg) static int libbalsa_ask_for_cert_acceptance(X509 *cert, const char *explanation); + +#ifndef HAVE_GCR + static char* asn1time_to_string(ASN1_UTCTIME *tm) { @@ -403,6 +411,8 @@ x509_fingerprint (char *s, unsigned len, X509 * cert) s[i] = '\0'; } +#endif /* HAVE_GCR */ + static GList *accepted_certs = NULL; /* certs accepted for this session */ static GMutex certificate_lock; @@ -494,6 +504,69 @@ struct AskCertData { const char *explanation; }; +#if HAVE_GCR + +static int +ask_cert_real(void *data) +{ + struct AskCertData *acd = (struct AskCertData*)data; + GtkWidget *dialog; + GtkWidget *cert_widget; + GString *str; + unsigned i; + unsigned char *der_buf = NULL; + int der_len; + GcrCertificate *gcr_cert; + GtkWidget *label; + + dialog = gtk_dialog_new_with_buttons(_("SSL/TLS certificate"), + NULL, /* FIXME: NULL parent */ + GTK_DIALOG_MODAL | + libbalsa_dialog_flags(), + _("_Accept Once"), 0, + _("Accept&_Save"), 1, + _("_Reject"), GTK_RESPONSE_CANCEL, + NULL); + gtk_window_set_wmclass(GTK_WINDOW(dialog), "tls_cert_dialog", "Balsa"); + der_len = i2d_X509(acd->certificate, &der_buf); + gcr_cert = gcr_simple_certificate_new(der_buf, der_len); + OPENSSL_free(der_buf); + cert_widget = GTK_WIDGET(gcr_certificate_widget_new(gcr_cert)); + g_object_unref(G_OBJECT(gcr_cert)); + + str = g_string_new(""); + g_string_printf(str, _("Authenticity of this certificate " + "could not be verified.\n" + "Reason: %s"), + acd->explanation); + label = gtk_label_new(str->str); + g_string_free(str, TRUE); + gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), + label, FALSE, FALSE, 1); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), + cert_widget, TRUE, TRUE, 1); + gtk_widget_show(cert_widget); + + switch(gtk_dialog_run(GTK_DIALOG(dialog))) { + case 0: + i = 1; + break; + case 1: + i = 2; + break; + case GTK_RESPONSE_CANCEL: + default: + i = 0; + break; + } + gtk_widget_destroy(dialog); + return i; +} + +#else + static int ask_cert_real(void *data) { @@ -583,6 +656,8 @@ ask_cert_real(void *data) return i; } +#endif /* HAVE_GCR */ + static int libbalsa_ask_for_cert_acceptance(X509 *cert, const char *explanation) {