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)) {
_______________________________________________
SVN-commits-list mailing list (read only)
http://mail.gnome.org/mailman/listinfo/svn-commits-list

Want to limit the commits to a few modules? Go to above URL, log in to edit 
your options and select the modules ('topics') you want.
Module maintainer? It is possible to set the reply-to to your development 
mailing list. Email [EMAIL PROTECTED] if interested.

Reply via email to