balsa r7848 - in trunk: . libbalsa src



Author: pawels
Date: Sun Feb 10 20:02:31 2008
New Revision: 7848
URL: http://svn.gnome.org/viewvc/balsa?rev=7848&view=rev

Log:
* libbalsa/rfc3156.[hc]: libbalsa_can_encrypt_for_all().
* libbalsa/identity.[ch]: remind if encryption is possible.
* src/sendmsg-window.c: encourage encryption if possible.
* configure.in: stop if gpgme-enabled build requested but
  gpgme-config not found (PS).


Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/libbalsa/identity.c
   trunk/libbalsa/identity.h
   trunk/libbalsa/rfc3156.c
   trunk/libbalsa/rfc3156.h
   trunk/src/sendmsg-window.c

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Sun Feb 10 20:02:31 2008
@@ -380,6 +380,9 @@
 if test x"$gpgmecfg" = xyes ; then
 	AC_MSG_RESULT(yes)
 	AC_PATH_PROG(gpgmecfg, gpgme-config, no)
+	if test "$gpgmecfg" = no; then
+	AC_MSG_ERROR([GPGme build requested but gpgme-config program not found.])
+        fi
 fi
 if test x"$gpgmecfg" != xno ; then
 	AC_MSG_CHECKING([gpgme library version])

Modified: trunk/libbalsa/identity.c
==============================================================================
--- trunk/libbalsa/identity.c	(original)
+++ trunk/libbalsa/identity.c	Sun Feb 10 20:02:31 2008
@@ -113,6 +113,7 @@
     ident->gpg_sign = FALSE;
     ident->gpg_encrypt = FALSE;
     ident->always_trust = FALSE;
+    ident->warn_send_plain = TRUE;
     ident->crypt_protocol = LIBBALSA_PROTECT_OPENPGP;
 #endif
     ident->request_mdn = FALSE;
@@ -1037,7 +1038,7 @@
 #endif
     /* create the "Security" tab */
     table =
-        append_ident_notebook_page(notebook, 4, _("Security"), footnote);
+        append_ident_notebook_page(notebook, 5, _("Security"), footnote);
     row = 0;
     ident_dialog_add_checkbutton(table, row++, dialog, 
                                  _("sign messages by default"),
@@ -1051,6 +1052,9 @@
     ident_dialog_add_checkbutton(table, row++, dialog,
                                  _("always trust GnuPG keys when encrypting"),
                                  "identity-trust-always", TRUE);
+    ident_dialog_add_checkbutton(table, row++, dialog,
+                                 _("remind me if messages can be encrypted"),
+                                 "identity-warn-send-plain", TRUE);
 #ifndef HAVE_GPGME
     gtk_widget_set_sensitive(table, FALSE);
 #endif
@@ -1491,6 +1495,7 @@
     id->gpg_sign        = ident_dialog_get_bool(dlg, "identity-gpgsign");
     id->gpg_encrypt     = ident_dialog_get_bool(dlg, "identity-gpgencrypt");
     id->always_trust    = ident_dialog_get_bool(dlg, "identity-trust-always");
+    id->warn_send_plain = ident_dialog_get_bool(dlg, "identity-warn-send-plain");
     id->crypt_protocol  = GPOINTER_TO_INT(ident_dialog_get_value
                                           (dlg, "identity-crypt-protocol"));
 #endif
@@ -1871,6 +1876,8 @@
                               ident->gpg_encrypt);    
     display_frame_set_boolean(dialog, "identity-trust-always", 
                               ident->always_trust);    
+    display_frame_set_boolean(dialog, "identity-warn-send-plain", 
+                              ident->warn_send_plain);    
     display_frame_set_gpg_mode(dialog, "identity-crypt-protocol",
 			   &ident->crypt_protocol);
 #endif
@@ -1971,6 +1978,7 @@
     ident->gpg_sign = libbalsa_conf_get_bool("GpgSign");
     ident->gpg_encrypt = libbalsa_conf_get_bool("GpgEncrypt");
     ident->always_trust = libbalsa_conf_get_bool("GpgTrustAlways");
+    ident->warn_send_plain = libbalsa_conf_get_bool("GpgWarnSendPlain=true");
     ident->crypt_protocol = libbalsa_conf_get_int("CryptProtocol=16");
 #endif
 
@@ -2016,6 +2024,7 @@
     libbalsa_conf_set_bool("GpgSign", ident->gpg_sign);
     libbalsa_conf_set_bool("GpgEncrypt", ident->gpg_encrypt);
     libbalsa_conf_set_bool("GpgTrustAlways", ident->always_trust);
+    libbalsa_conf_set_bool("GpgWarnSendPlain", ident->warn_send_plain);
     libbalsa_conf_set_int("CryptProtocol", ident->crypt_protocol);
 #endif
 

Modified: trunk/libbalsa/identity.h
==============================================================================
--- trunk/libbalsa/identity.h	(original)
+++ trunk/libbalsa/identity.h	Sun Feb 10 20:02:31 2008
@@ -84,6 +84,7 @@
 	gboolean gpg_sign;
 	gboolean gpg_encrypt;
 	gboolean always_trust;
+	gboolean warn_send_plain;
 	gint crypt_protocol;
 #endif
 #if ENABLE_ESMTP

Modified: trunk/libbalsa/rfc3156.c
==============================================================================
--- trunk/libbalsa/rfc3156.c	(original)
+++ trunk/libbalsa/rfc3156.c	Sun Feb 10 20:02:31 2008
@@ -65,6 +65,8 @@
 				     GMimeGpgmeContext * ctx);
 static gboolean gpg_updates_trustdb(void);
 static gchar *fix_EMail_info(gchar * str);
+static gboolean have_pub_key_for(gpgme_ctx_t gpgme_ctx,
+				 InternetAddressList * recipients);
 
 
 /* ==== public functions =================================================== */
@@ -141,6 +143,43 @@
 }
 
 
+/* return TRUE if we can encrypt for every recipient in the recipients list
+ * using protocol */
+gboolean
+libbalsa_can_encrypt_for_all(InternetAddressList * recipients,
+			     gpgme_protocol_t protocol)
+{
+    gpgme_ctx_t gpgme_ctx;
+    gboolean result;
+
+    /* silent paranoia checks */
+    if (!recipients)
+	return TRUE;  /* we can of course encrypt for nobody... */
+#ifndef HAVE_SMIME
+    if (protocol == GPGME_PROTOCOL_OpenPGP)
+	return FALSE;
+#endif
+
+    /* check if gpg is currently available */
+    if (protocol == GPGME_PROTOCOL_OpenPGP && gpg_updates_trustdb())
+	return FALSE;
+
+    /* create the gpgme context and set the protocol */
+    if (gpgme_new(&gpgme_ctx) != GPG_ERR_NO_ERROR)
+	return FALSE;
+    if (gpgme_set_protocol(gpgme_ctx, protocol) != GPG_ERR_NO_ERROR) {
+	gpgme_release(gpgme_ctx);
+	return FALSE;
+    }
+
+    /* loop over all recipients and try to find valid keys */
+    result = have_pub_key_for(gpgme_ctx, recipients);
+    gpgme_release(gpgme_ctx);
+
+    return result;
+}
+
+
 /*
  * Check if body (and eventually its subparts) are RFC 2633 or RFC 3156 signed
  * or encrypted.
@@ -1692,4 +1731,49 @@
 	return FALSE;
 }
 
+
+/* check if the context contains a public key for the passed recipients */
+#define KEY_IS_OK(k)   (!((k)->expired || (k)->revoked || \
+                          (k)->disabled || (k)->invalid))
+static gboolean
+have_pub_key_for(gpgme_ctx_t gpgme_ctx, InternetAddressList * recipients)
+{
+    gpgme_key_t key;
+    gboolean result = TRUE;
+    time_t now = time(NULL);
+
+    for (; result && recipients; recipients = recipients->next) {
+        InternetAddress *ia = recipients->address;
+
+	/* check all entries in the list, handle groups recursively */
+	if (ia->type == INTERNET_ADDRESS_GROUP)
+	    result = have_pub_key_for(gpgme_ctx, ia->value.members);
+	else if (recipients->address->type == INTERNET_ADDRESS_NAME) {
+	    if (gpgme_op_keylist_start(gpgme_ctx, ia->value.addr, FALSE) !=
+		GPG_ERR_NO_ERROR)
+		return FALSE;
+
+	    result = FALSE;
+	    while (!result &&
+		   gpgme_op_keylist_next(gpgme_ctx, &key) == GPG_ERR_NO_ERROR) {
+		/* check if this key and the relevant subkey are usable */
+		if (KEY_IS_OK(key)) {
+		    gpgme_subkey_t subkey = key->subkeys;
+
+		    while (subkey && !subkey->can_encrypt)
+			subkey = subkey->next;
+
+		    if (subkey && KEY_IS_OK(subkey) && 
+			(subkey->expires == 0 || subkey->expires > now))
+			result = TRUE;
+		}
+		gpgme_key_unref(key);
+	    }
+	    gpgme_op_keylist_end(gpgme_ctx);
+	}
+    }
+
+    return result;
+}
+
 #endif				/* HAVE_GPGME */

Modified: trunk/libbalsa/rfc3156.h
==============================================================================
--- trunk/libbalsa/rfc3156.h	(original)
+++ trunk/libbalsa/rfc3156.h	Sun Feb 10 20:02:31 2008
@@ -58,6 +58,8 @@
 gboolean libbalsa_check_crypto_engine(gpgme_protocol_t protocol);
 
 gint libbalsa_message_body_protection(LibBalsaMessageBody * body);
+gboolean libbalsa_can_encrypt_for_all(InternetAddressList * recipients,
+				      gpgme_protocol_t protocol);
 
 /* routines dealing with RFC 2633 and RFC 3156 stuff */
 gboolean libbalsa_sign_mime_object(GMimeObject ** content,

Modified: trunk/src/sendmsg-window.c
==============================================================================
--- trunk/src/sendmsg-window.c	(original)
+++ trunk/src/sendmsg-window.c	Sun Feb 10 20:02:31 2008
@@ -5676,6 +5676,116 @@
     return response == GTK_RESPONSE_OK;
 }
 
+#ifdef HAVE_GPGME
+static gboolean
+check_suggest_encryption(BalsaSendmsg * bsmsg)
+{
+    InternetAddressList * ia_list;
+    gboolean can_encrypt;
+    InternetAddressList * from_list;
+    InternetAddressList * cc_list;
+    gpgme_protocol_t protocol;
+
+    /* check if the user wants to see the message */
+    if (!bsmsg->ident->warn_send_plain)
+	return TRUE;
+
+    /* nothing to do if encryption is already enabled */
+    if ((bsmsg->gpg_mode & LIBBALSA_PROTECT_ENCRYPT) != 0)
+	return TRUE;
+
+    /* we can not encrypt if we have bcc recipients */
+    if ((ia_list = libbalsa_address_view_get_list(bsmsg->recipient_view, "Bcc:"))) {
+	internet_address_list_destroy(ia_list);
+	return TRUE;
+    }
+
+    /* collect all to and cc recipients */
+    ia_list = libbalsa_address_view_get_list(bsmsg->recipient_view, "To:");
+    cc_list = libbalsa_address_view_get_list(bsmsg->recipient_view, "Cc:");
+    from_list = internet_address_list_prepend(NULL, bsmsg->ident->ia);
+    protocol = bsmsg->gpg_mode & LIBBALSA_PROTECT_SMIMEV3 ?
+	GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP;
+    can_encrypt = libbalsa_can_encrypt_for_all(from_list, protocol) &
+	libbalsa_can_encrypt_for_all(ia_list, protocol) &
+	libbalsa_can_encrypt_for_all(cc_list, protocol);
+    internet_address_list_destroy(from_list);
+    internet_address_list_destroy(ia_list);
+    internet_address_list_destroy(cc_list);
+
+    /* ask the user if we could encrypt this message */
+    if (can_encrypt) {
+	GtkWidget *dialog;
+	gint choice;
+	gchar * message;
+	GtkWidget *dialog_action_area;
+	GtkWidget *button;
+	GtkWidget *alignment;
+	GtkWidget *hbox;
+	GtkWidget *image;
+	GtkWidget *label;
+
+	message =
+	    g_strdup_printf(_("You did not select encryption for this message, although "
+			      "%s public keys are available for all recipients. In order "
+			      "to protect your privacy, the message could be %s encrypted."),
+			    gpgme_get_protocol_name(protocol),
+			    gpgme_get_protocol_name(protocol));
+	dialog = gtk_message_dialog_new
+	    (GTK_WINDOW(bsmsg->window),
+	     GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
+	     GTK_MESSAGE_QUESTION,
+	     GTK_BUTTONS_NONE,
+	     message);
+
+	dialog_action_area = GTK_DIALOG(dialog)->action_area;
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area), GTK_BUTTONBOX_END);
+ 
+	button = gtk_button_new();
+	gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button, GTK_RESPONSE_YES);
+	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+	gtk_widget_grab_focus(button);
+	alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
+	gtk_container_add(GTK_CONTAINER(button), alignment);
+
+	hbox = gtk_hbox_new(FALSE, 2);
+	gtk_container_add(GTK_CONTAINER(alignment), hbox);
+	image = gtk_image_new_from_stock(BALSA_PIXMAP_GPG_ENCRYPT, GTK_ICON_SIZE_BUTTON);
+	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+	label = gtk_label_new_with_mnemonic(_("Send _encrypted"));
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	gtk_widget_show_all(button);
+
+	button = gtk_button_new();
+	gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button, GTK_RESPONSE_NO);
+	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+	alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
+	gtk_container_add(GTK_CONTAINER(button), alignment);
+
+	hbox = gtk_hbox_new(FALSE, 2);
+	gtk_container_add(GTK_CONTAINER(alignment), hbox);
+	image = gtk_image_new_from_stock(BALSA_PIXMAP_SEND, GTK_ICON_SIZE_BUTTON);
+	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+	label = gtk_label_new_with_mnemonic(_("Send _plain"));
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+	gtk_widget_show_all(button);
+
+	button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+	gtk_widget_show(button);
+	gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button, GTK_RESPONSE_CANCEL);
+	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+
+	choice = gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
+	if (choice == GTK_RESPONSE_YES)
+	    bsmsg_setup_gpg_ui_by_mode(bsmsg, bsmsg->gpg_mode | LIBBALSA_PROTECT_ENCRYPT);
+	else if (choice == GTK_RESPONSE_CANCEL || choice == GTK_RESPONSE_DELETE_EVENT)
+	    return FALSE;
+    }
+
+    return TRUE;
+}
+#endif
 
 /* "send message" menu and toolbar callback.
  */
@@ -5697,6 +5807,9 @@
 	return FALSE;
 
 #ifdef HAVE_GPGME
+    if (!check_suggest_encryption(bsmsg))
+	return FALSE;
+
     if ((bsmsg->gpg_mode & LIBBALSA_PROTECT_OPENPGP) != 0 &&
         (bsmsg->gpg_mode & LIBBALSA_PROTECT_MODE) != 0 &&
 	gtk_tree_model_get_iter_first(BALSA_MSG_ATTACH_MODEL(bsmsg), &iter)) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]