2006-08-14 [cleroy] 2.4.0cvs50
authorColin Leroy <colin@colino.net>
Mon, 14 Aug 2006 15:45:51 +0000 (15:45 +0000)
committerColin Leroy <colin@colino.net>
Mon, 14 Aug 2006 15:45:51 +0000 (15:45 +0000)
* src/gtk/pluginwindow.c
New layout (maybe to be changed?)
* src/gtk/gtkutils.c
Fix a bit label_window
* src/plugins/pgpcore/passphrase.c
* src/plugins/pgpcore/passphrase.h
* src/plugins/pgpcore/plugin.c
* src/plugins/pgpcore/prefs_gpg.c
* src/plugins/pgpcore/prefs_gpg.h
* src/plugins/pgpcore/sgpgme.c
* src/plugins/pgpcore/sgpgme.h
Allow to create a PGP private key via the GUI

12 files changed:
ChangeLog
PATCHSETS
configure.ac
src/gtk/gtkutils.c
src/gtk/pluginwindow.c
src/plugins/pgpcore/passphrase.c
src/plugins/pgpcore/passphrase.h
src/plugins/pgpcore/plugin.c
src/plugins/pgpcore/prefs_gpg.c
src/plugins/pgpcore/prefs_gpg.h
src/plugins/pgpcore/sgpgme.c
src/plugins/pgpcore/sgpgme.h

index c81f2900de40701f72fa380a1e54440a0bb00fbb..08960d837dc707ee58b26799438536345e0beb9b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2006-08-14 [cleroy]    2.4.0cvs50
+
+       * src/gtk/pluginwindow.c
+               New layout (maybe to be changed?)
+       * src/gtk/gtkutils.c
+               Fix a bit label_window
+       * src/plugins/pgpcore/passphrase.c
+       * src/plugins/pgpcore/passphrase.h
+       * src/plugins/pgpcore/plugin.c
+       * src/plugins/pgpcore/prefs_gpg.c
+       * src/plugins/pgpcore/prefs_gpg.h
+       * src/plugins/pgpcore/sgpgme.c
+       * src/plugins/pgpcore/sgpgme.h
+               Allow to create a PGP private key via the GUI
+
 2006-08-14 [wwp]       2.4.0cvs49
 
        * src/addressbook_foldersel.c
index 805309855b126aeae75e6dec2535bad58f06b470..5740457f005d80cf61fb6114831034de324c4595 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.16.2.19 -r 1.16.2.20 src/prefs_display_header.c;  ) > 2.4.0cvs47.patchset
 ( cvs diff -u -r 1.12.2.26 -r 1.12.2.27 src/gtk/prefswindow.c;  ) > 2.4.0cvs48.patchset
 ( cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/addressbook_foldersel.c;  ) > 2.4.0cvs49.patchset
+( cvs diff -u -r 1.5.2.35 -r 1.5.2.36 src/gtk/gtkutils.c;  cvs diff -u -r 1.5.2.31 -r 1.5.2.32 src/gtk/pluginwindow.c;  cvs diff -u -r 1.1.2.15 -r 1.1.2.16 src/plugins/pgpcore/passphrase.c;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/plugins/pgpcore/passphrase.h;  cvs diff -u -r 1.1.2.8 -r 1.1.2.9 src/plugins/pgpcore/plugin.c;  cvs diff -u -r 1.1.2.9 -r 1.1.2.10 src/plugins/pgpcore/prefs_gpg.c;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/plugins/pgpcore/prefs_gpg.h;  cvs diff -u -r 1.1.2.23 -r 1.1.2.24 src/plugins/pgpcore/sgpgme.c;  cvs diff -u -r 1.1.2.4 -r 1.1.2.5 src/plugins/pgpcore/sgpgme.h;  ) > 2.4.0cvs50.patchset
index 3e5df212d49ad2118058ac14cd46fb5eb34cd968..f9808337eeff6d8834935c1c8a0868c9af457bfe 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=4
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=49
+EXTRA_VERSION=50
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index f2f8a5fc6d4cbd2d1b11417478fc4aeef265a983..10f539626d480d04f3818b9b97525b148590b265 100644 (file)
@@ -832,9 +832,12 @@ GtkWidget *label_window_create(const gchar *str)
 
        label = gtk_label_new(str);
        gtk_container_add(GTK_CONTAINER(window), label);
+       gtk_label_set_line_wrap(label, TRUE);
        gtk_widget_show(label);
 
        gtk_widget_show_now(window);
+       
+       GTK_EVENTS_FLUSH();
 
        return window;
 }
index 7a7d8b3c204a611e8626191728a2f251316a3a8a..9fd54e230e2211e2ef09f6ce5e78d0c9080c3100 100644 (file)
@@ -272,6 +272,7 @@ void pluginwindow_create()
        GtkWidget *unload_btn;
        GtkWidget *close_btn;
        GtkWidget *get_more_btn;
+       GtkWidget *desc_lbl;
        static GdkGeometry geometry;
        
        debug_print("Creating plugins window...\n");
@@ -286,6 +287,18 @@ void pluginwindow_create()
        vbox1 = gtk_vbox_new(FALSE, 4);
        gtk_widget_show(vbox1);
        gtk_container_add(GTK_CONTAINER(window), vbox1);
+       gtk_box_set_homogeneous(GTK_BOX(vbox1), FALSE);
+       gtk_widget_realize(window);
+
+       desc_lbl = gtk_label_new(_("Plugins are a way to greatly extend Sylpheed-Claws' capabilities."));
+       gtk_misc_set_alignment(GTK_MISC(desc_lbl), 0, 0.5);
+       gtk_widget_show(desc_lbl);
+       gtk_box_pack_start(GTK_BOX(vbox1), desc_lbl, FALSE, FALSE, 0);
+
+       get_more_btn = gtkut_get_link_btn(window, PLUGINS_URI, _("Get more..."));
+       gtk_misc_set_alignment(GTK_MISC(GTK_BIN(get_more_btn)->child), 0, 0.5);
+       gtk_widget_show(get_more_btn);
+       gtk_box_pack_start(GTK_BOX(vbox1), get_more_btn, FALSE, FALSE, 0);
 
        hbox2 = gtk_hbox_new(FALSE, 8);
        gtk_widget_show(hbox2);
@@ -333,12 +346,6 @@ void pluginwindow_create()
        hbuttonbox1 = gtk_hbutton_box_new();
        gtk_widget_show(hbuttonbox1);
 
-       gtk_widget_realize(window);
-       get_more_btn = gtkut_get_link_btn(window, PLUGINS_URI, _("Get more..."));
-       gtk_misc_set_alignment(GTK_MISC(GTK_BIN(get_more_btn)->child), 0, 0.5);
-       gtk_widget_show(get_more_btn);
-
-       gtk_box_pack_start(GTK_BOX(hbox3), get_more_btn, TRUE, TRUE, 0);
        gtk_box_pack_start(GTK_BOX(hbox3), hbuttonbox1, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(vbox1), hbox3, FALSE, FALSE, 0);
 
@@ -430,7 +437,7 @@ static void pluginwindow_create_list_view_columns(GtkWidget *list_view)
 
        renderer = gtk_cell_renderer_text_new();
        column = gtk_tree_view_column_new_with_attributes
-               (_("Plugins"),
+               (_("Loaded plugins"),
                 renderer,
                 "text", PLUGINWINDOW_NAME,
                 "style", PLUGINWINDOW_STYLE,
index ef5d22c794e81a8cc83db038e130ce65c23d9125..12b4d968858dbf0fddac2d195185daff0f31bd0f 100644 (file)
@@ -68,11 +68,9 @@ static gint passphrase_deleted(GtkWidget *widget, GdkEventAny *event,
                               gpointer data);
 static gboolean passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event,
                                       gpointer data);
-static gchar* passphrase_mbox(const gchar *uid_hint, const gchar *pass_hint,
-                             gint prev_bad);
 
 static GtkWidget *create_description(const gchar *uid_hint,
-                                    const gchar *pass_hint, gint prev_bad);
+                                    const gchar *pass_hint, gint prev_bad, gint new_key);
 
 void
 gpgmegtk_set_passphrase_grab(gint yes)
@@ -80,8 +78,8 @@ gpgmegtk_set_passphrase_grab(gint yes)
     grab_all = yes;
 }
 
-static gchar*
-passphrase_mbox(const gchar *uid_hint, const gchar *pass_hint, gint prev_bad)
+gchar*
+passphrase_mbox(const gchar *uid_hint, const gchar *pass_hint, gint prev_bad, gint new_key)
 {
     gchar *the_passphrase = NULL;
     GtkWidget *vbox, *hbox;
@@ -114,7 +112,7 @@ passphrase_mbox(const gchar *uid_hint, const gchar *pass_hint, gint prev_bad)
 
     if (uid_hint || pass_hint) {
         GtkWidget *label, *icon;
-        label = create_description (uid_hint, pass_hint, prev_bad);
+        label = create_description (uid_hint, pass_hint, prev_bad, new_key);
        icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION,
                                GTK_ICON_SIZE_DIALOG); 
 
@@ -250,7 +248,7 @@ linelen (const gchar *s)
 }
 
 static GtkWidget *
-create_description(const gchar *uid_hint, const gchar *pass_hint, gint prev_bad)
+create_description(const gchar *uid_hint, const gchar *pass_hint, gint prev_bad, gint new_key)
 {
     const gchar *uid = NULL, *info = NULL;
     gchar *buf;
@@ -271,11 +269,23 @@ create_description(const gchar *uid_hint, const gchar *pass_hint, gint prev_bad)
     while (strchr(my_uid, '>')) 
        *(strchr(my_uid, '>')) = ')';
 
-    buf = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">%sPlease enter the passphrase for:</span>\n\n"
+    if (new_key == 1) {
+           buf = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">%sPlease enter the passphrase for the new key:</span>\n\n"
+                           "%.*s\n"),
+                           prev_bad ?
+                           _("Passphrases did not match.\n") : "",
+                           linelen (my_uid), my_uid);
+    } else if (new_key == 2) {
+           buf = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">Please re-enter the passphrase for the new key:</span>\n\n"
+                           "%.*s\n"),
+                           linelen (my_uid), my_uid);
+    } else {
+           buf = g_strdup_printf (_("<span weight=\"bold\" size=\"larger\">%sPlease enter the passphrase for:</span>\n\n"
                            "%.*s\n"),
                            prev_bad ?
                            _("Bad passphrase.\n") : "",
                            linelen (my_uid), my_uid);
+    }
     g_free(my_uid);
     label = gtk_label_new (buf);
     gtk_label_set_use_markup(GTK_LABEL (label), TRUE);
@@ -311,7 +321,7 @@ gpgmegtk_passphrase_cb(void *opaque, const char *uid_hint,
     else {
     gpgmegtk_set_passphrase_grab (prefs_gpg_get_config()->passphrase_grab);
     debug_print ("%% requesting passphrase for '%s'\n ", uid_hint);
-    pass = passphrase_mbox (uid_hint, passphrase_hint, prev_bad);
+    pass = passphrase_mbox (uid_hint, passphrase_hint, prev_bad, FALSE);
     gpgmegtk_free_passphrase();
     if (!pass) {
         debug_print ("%% cancel passphrase entry\n");
index 0dd7c5a6adac769aa35a6ad1bbf4ecca4bc7f042..7f126221dab4fa130bb3f5ac7e2fb155bdab496d 100644 (file)
@@ -31,5 +31,7 @@ void gpgmegtk_set_passphrase_grab (gint yesno);
 gpgme_error_t gpgmegtk_passphrase_cb(void *opaque, const char *uid_hint,
 const char *passphrase_info, int prev_bad, int fd);
 void gpgmegtk_free_passphrase();
+gchar* passphrase_mbox(const gchar *uid_hint, const gchar *pass_hint,
+                             gint prev_bad, gint new_key);
 
 #endif /* GPGMEGTK_PASSPHRASE_H */
index 70720e10cfaaf687228205a059088a52711984ca..be342f4f078149e243e7337198c44ce2526e330c 100644 (file)
@@ -44,7 +44,7 @@ gint plugin_init(gchar **error)
 
        sgpgme_init();
        prefs_gpg_init();
-
+       sgpgme_check_create_key();
        return 0;       
 }
 
index 47d0e6883b4a6f90bfaf0eb85323e4d829299b37..c59fd33412fcdbd28056ce8d46a4bb321d4e5df4 100644 (file)
@@ -26,6 +26,7 @@
 #include "prefs.h"
 #include "prefs_gtk.h"
 #include "prefs_gpg.h"
+#include "sgpgme.h"
 
 struct GPGConfig prefs_gpg;
 
@@ -43,6 +44,8 @@ static PrefParam param[] = {
         NULL, NULL, NULL},
        {"gpg_warning", "TRUE", &prefs_gpg.gpg_warning, P_BOOL,
         NULL, NULL, NULL},
+       {"gpg_ask_create_key", "TRUE", &prefs_gpg.gpg_ask_create_key, P_BOOL,
+        NULL, NULL, NULL},
 
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
@@ -193,6 +196,9 @@ struct GPGAccountPage
        GtkWidget *key_custom;
        GtkWidget *keyid;
        GtkWidget *keyid_label;
+       GtkWidget *new_key_label;
+       GtkWidget *new_key_btn;
+       GtkWidget *new_key_box;
 
        PrefsAccount *account;
 };
@@ -209,6 +215,12 @@ void key_custom_toggled(GtkToggleButton *togglebutton, gpointer user_data)
                gtk_editable_delete_text(GTK_EDITABLE(page->keyid), 0, -1);
 }
 
+static void new_key_clicked(GtkWidget *widget, gpointer user_data)
+{
+       struct GPGAccountPage *page = (struct GPGAccountPage *) user_data;
+       sgpgme_create_secret_key(page->account);
+}
+
 static void prefs_gpg_account_create_widget_func(PrefsPage *_page,
                                                 GtkWindow *window,
                                                 gpointer data)
@@ -227,6 +239,10 @@ static void prefs_gpg_account_create_widget_func(PrefsPage *_page,
        GtkWidget *key_custom;
        GtkWidget *keyid_label;
        GtkWidget *keyid;
+       GtkWidget *image;
+       GtkWidget *new_key_label;
+       GtkWidget *new_key_btn;
+       GtkWidget *new_key_box;
 
        vbox = gtk_vbox_new(FALSE, VSPACING);
        gtk_container_set_border_width (GTK_CONTAINER (vbox), VBOX_BORDER);
@@ -305,10 +321,30 @@ static void prefs_gpg_account_create_widget_func(PrefsPage *_page,
                break;
        }
 
+       new_key_box = gtk_hbox_new(FALSE, 6);
+       
+       image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING,
+                       GTK_ICON_SIZE_SMALL_TOOLBAR);
+
+       gtk_box_pack_start(GTK_BOX(new_key_box), image, FALSE, FALSE, 0);
+       new_key_label = gtk_label_new(
+                       _("No secret key found."));
+       gtk_box_pack_start(GTK_BOX(new_key_box), new_key_label, FALSE, FALSE, 0);
+       new_key_btn = gtk_button_new_with_label(_("Generate new secret key"));
+       gtk_box_pack_start(GTK_BOX(new_key_box), new_key_btn, FALSE, FALSE, 0);
+
+       gtk_box_pack_start(GTK_BOX(vbox2), new_key_box, FALSE, FALSE, 0);
+
+       gtk_widget_show_all(new_key_box);
+
+       if (sgpgme_has_secret_key())
+               gtk_widget_hide(new_key_box);
+
        if (config->sign_key_id != NULL)
                gtk_entry_set_text(GTK_ENTRY(keyid), config->sign_key_id);
 
        g_signal_connect(G_OBJECT(key_custom), "toggled", G_CALLBACK(key_custom_toggled), page);
+       g_signal_connect(G_OBJECT(new_key_btn), "clicked", G_CALLBACK(new_key_clicked), page);
 
        page->key_default = key_default;
        page->key_by_from = key_by_from;
index eca66cc4cd81ab78c6f264a53008c240e601361d..04e6dcd2e1538a2a1a4125ae93604f874ffd5bf8 100644 (file)
@@ -35,6 +35,7 @@ struct GPGConfig
        gint             store_passphrase_timeout;
        gboolean         passphrase_grab;
        gboolean         gpg_warning;
+       gboolean         gpg_ask_create_key;
 };
 
 struct GPGAccountConfig
index d290d61baa2f5832c1dcef9ba617f6d3d26dddd6..d48b05448825d51a4471b5f4506291694701844e 100644 (file)
@@ -30,6 +30,9 @@
 #include <glib/gi18n.h>
 #include <stdio.h>
 #include <errno.h>
+#ifndef G_OS_WIN32
+#include <sys/mman.h>
+#endif
 #if HAVE_LOCALE_H
 #  include <locale.h>
 #endif
@@ -41,6 +44,7 @@
 #include "alertpanel.h"
 #include "passphrase.h"
 #include "prefs_gpg.h"
+#include "account.h"
 #include "select-keys.h"
 
 static void sgpgme_disable_all(void)
@@ -575,4 +579,153 @@ void sgpgme_done()
         gpgmegtk_free_passphrase();
 }
 
+void sgpgme_create_secret_key(PrefsAccount *account)
+{
+       AlertValue val = alertpanel(_("No PGP key found"),
+                       _("Sylpheed-Claws did not find a secret PGP key, "
+                         "which means that you won't be able to sign "
+                         "emails or receive encrypted emails.\n"
+                         "Do you want to create a secret key now?"),
+                         GTK_STOCK_NO, "+" GTK_STOCK_YES, NULL);
+       gchar *key_parms = NULL;
+       gchar *name = NULL;
+       gchar *email = NULL;
+       gchar *passphrase = NULL, *passphrase_second = NULL;
+       gint prev_bad = 0;
+       gchar *tmp = NULL;
+       gpgme_error_t err = 0;
+       gpgme_ctx_t ctx;
+       GtkWidget *window = NULL;
+       gpgme_genkey_result_t key;
+
+       if (account == NULL)
+               account = account_get_default();
+
+       if (val == G_ALERTDEFAULT) {
+               prefs_gpg_get_config()->gpg_ask_create_key = FALSE;
+               prefs_gpg_save_config();
+               return;
+       }
+
+       if (account->name) {
+               name = g_strdup(account->name);
+       } else {
+               name = g_strdup(account->address);
+       }
+       email = g_strdup(account->address);
+       tmp = g_strdup_printf("%s <%s>", account->name?account->name:account->address, account->address);
+again:
+       passphrase = passphrase_mbox(tmp, NULL, prev_bad, 1);
+       if (passphrase == NULL) {
+               g_free(tmp);
+               g_free(email);
+               g_free(name);           
+               return;
+       }
+       passphrase_second = passphrase_mbox(tmp, NULL, 0, 2);
+       if (passphrase_second == NULL) {
+               g_free(tmp);
+               g_free(email);
+               g_free(passphrase);             
+               g_free(name);           
+               return;
+       }
+       if (strcmp(passphrase, passphrase_second)) {
+               g_free(passphrase);
+               g_free(passphrase_second);
+               prev_bad = 1;
+               goto again;
+       }
+       
+       key_parms = g_strdup_printf("<GnupgKeyParms format=\"internal\">\n"
+                                       "Key-Type: DSA\n"
+                                       "Key-Length: 1024\n"
+                                       "Subkey-Type: ELG-E\n"
+                                       "Subkey-Length: 2048\n"
+                                       "Name-Real: %s\n"
+                                       "Name-Email: %s\n"
+                                       "Expire-Date: 0\n"
+                                       "Passphrase: %s\n"
+                                       "</GnupgKeyParms>\n",
+                                       name, email, passphrase);
+#ifndef G_PLATFORM_WIN32
+       if (mlock(passphrase, strlen(passphrase)) == -1)
+               debug_print("couldn't lock passphrase\n");
+       if (mlock(passphrase_second, strlen(passphrase_second)) == -1)
+               debug_print("couldn't lock passphrase2\n");
+#endif
+       g_free(tmp);
+       g_free(email);
+       g_free(name);
+       g_free(passphrase_second);
+       g_free(passphrase);
+       
+       err = gpgme_new (&ctx);
+       if (err) {
+               alertpanel_error(_("Couldn't generate new key: %s"), gpgme_strerror(err));
+               g_free(key_parms);
+               return;
+       }
+       
+
+       window = label_window_create(_("Generating your new key... Please move the mouse "
+                             "around to help generate entropy..."));
+
+       err = gpgme_op_genkey(ctx, key_parms, NULL, NULL);
+       g_free(key_parms);
+
+       gtk_widget_destroy(window);
+
+       if (err) {
+               alertpanel_error(_("Couldn't generate new key: %s"), gpgme_strerror(err));
+               gpgme_release(ctx);
+               return;
+       }
+       key = gpgme_op_genkey_result(ctx);
+       if (key == NULL) {
+               alertpanel_error(_("Couldn't generate new key: unknown error"));
+               gpgme_release(ctx);
+               return;
+       } else {
+               alertpanel_notice(_("Your secret key has been generated. "
+                                   "Its fingerprint is:\n%s"),
+                                   key->fpr ? key->fpr:"null");
+       }
+       prefs_gpg_get_config()->gpg_ask_create_key = FALSE;
+       prefs_gpg_save_config();
+       gpgme_release(ctx);
+}
+
+gboolean sgpgme_has_secret_key(void)
+{
+       gpgme_error_t err = 0;
+       gpgme_ctx_t ctx;
+       gpgme_key_t key;
+
+       err = gpgme_new (&ctx);
+       if (err) {
+               debug_print("err : %s\n", gpgme_strerror(err));
+               return TRUE;
+       }
+       err = gpgme_op_keylist_start(ctx, NULL, TRUE);
+       if (!err)
+               err = gpgme_op_keylist_next(ctx, &key);
+       gpgme_op_keylist_end(ctx);
+       gpgme_release(ctx);
+       if (gpg_err_code(err) == GPG_ERR_EOF)
+               return FALSE;
+       else
+               return TRUE;
+}
+
+void sgpgme_check_create_key(void)
+{
+       if (prefs_gpg_get_config()->gpg_ask_create_key &&
+           !sgpgme_has_secret_key()) {
+               sgpgme_create_secret_key(NULL);
+       } else {
+               prefs_gpg_get_config()->gpg_ask_create_key = FALSE;
+               prefs_gpg_save_config();
+       }       
+}
 #endif /* USE_GPGME */
index 79367753317eefb36963c110e7b26f22434a4825..1e1769d07ba8ff320d003d8bae992f62a21f356e 100644 (file)
@@ -45,5 +45,7 @@ gpgme_data_t sgpgme_decrypt_verify    (gpgme_data_t cipher,
 gchar *sgpgme_get_encrypt_data         (GSList *recp_names,
                                         gpgme_protocol_t proto);
 gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account);
-
+void sgpgme_check_create_key(void);
+gboolean sgpgme_has_secret_key(void);
+void sgpgme_create_secret_key(PrefsAccount *account);
 #endif /* SGPGME_H */