2006-10-21 [paul] 2.5.6cvs4
[claws.git] / src / plugins / pgpcore / sgpgme.c
index d48b05448825d51a4471b5f4506291694701844e..b09805086e8a37b4a0304c80a9ecae9dc531b5ee 100644 (file)
 #include <glib/gi18n.h>
 #include <stdio.h>
 #include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#if (defined(__DragonFly__) || defined (__NetBSD__) || defined (__FreeBSD__) || defined (__OpenBSD__))
+#  include <sys/signal.h>
+#endif
 #ifndef G_OS_WIN32
 #include <sys/mman.h>
 #endif
@@ -479,15 +484,15 @@ gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account)
                        err = gpgme_op_keylist_next(ctx, &key);
                if (err) {
                        g_warning("setup_signers start: %s", gpgme_strerror(err));
-                       privacy_set_error(_("Private key not found (%s)"), gpgme_strerror(err));
+                       privacy_set_error(_("Secret key not found (%s)"), gpgme_strerror(err));
                        goto bail;
                }
                
                err = gpgme_op_keylist_next(ctx, &key2);
                if (!err) {
-                       g_warning("ambiguous specification of private key '%s'\n",
+                       g_warning("ambiguous specification of secret key '%s'\n",
                                keyid);
-                       privacy_set_error(_("Private key specification is ambiguous"));
+                       privacy_set_error(_("Secret key specification is ambiguous"));
                        goto bail;
                }
                
@@ -497,7 +502,7 @@ gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account)
                
                if (err) {
                        g_warning("error adding secret key: %s\n", gpgme_strerror(err));
-                       privacy_set_error(_("Error setting private key: %s"), gpgme_strerror(err));
+                       privacy_set_error(_("Error setting secret key: %s"), gpgme_strerror(err));
                        goto bail;
                }
        }
@@ -579,14 +584,9 @@ void sgpgme_done()
         gpgmegtk_free_passphrase();
 }
 
-void sgpgme_create_secret_key(PrefsAccount *account)
+void sgpgme_create_secret_key(PrefsAccount *account, gboolean ask_create)
 {
-       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);
+       AlertValue val = G_ALERTDEFAULT;
        gchar *key_parms = NULL;
        gchar *name = NULL;
        gchar *email = NULL;
@@ -601,11 +601,24 @@ void sgpgme_create_secret_key(PrefsAccount *account)
        if (account == NULL)
                account = account_get_default();
 
-       if (val == G_ALERTDEFAULT) {
-               prefs_gpg_get_config()->gpg_ask_create_key = FALSE;
-               prefs_gpg_save_config();
+       if (account->address == NULL) {
+               alertpanel_error(_("You have to save the account's information with \"OK\" "
+                                  "before being able to generate a key pair.\n"));
                return;
        }
+       if (ask_create) {
+               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 new key pair now?"),
+                                 GTK_STOCK_NO, "+" GTK_STOCK_YES, NULL);
+               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);
@@ -645,9 +658,12 @@ again:
                                        "Name-Real: %s\n"
                                        "Name-Email: %s\n"
                                        "Expire-Date: 0\n"
-                                       "Passphrase: %s\n"
+                                       "%s%s%s"
                                        "</GnupgKeyParms>\n",
-                                       name, email, passphrase);
+                                       name, email, 
+                                       strlen(passphrase)?"Passphrase: ":"",
+                                       passphrase,
+                                       strlen(passphrase)?"\n":"");
 #ifndef G_PLATFORM_WIN32
        if (mlock(passphrase, strlen(passphrase)) == -1)
                debug_print("couldn't lock passphrase\n");
@@ -662,13 +678,14 @@ again:
        
        err = gpgme_new (&ctx);
        if (err) {
-               alertpanel_error(_("Couldn't generate new key: %s"), gpgme_strerror(err));
+               alertpanel_error(_("Couldn't generate a new key pair: %s"),
+                                gpgme_strerror(err));
                g_free(key_parms);
                return;
        }
        
 
-       window = label_window_create(_("Generating your new key... Please move the mouse "
+       window = label_window_create(_("Generating your new key pair... Please move the mouse "
                              "around to help generate entropy..."));
 
        err = gpgme_op_genkey(ctx, key_parms, NULL, NULL);
@@ -677,19 +694,68 @@ again:
        gtk_widget_destroy(window);
 
        if (err) {
-               alertpanel_error(_("Couldn't generate new key: %s"), gpgme_strerror(err));
+               alertpanel_error(_("Couldn't generate a new key pair: %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"));
+               alertpanel_error(_("Couldn't generate a new key pair: unknown error"));
                gpgme_release(ctx);
                return;
        } else {
-               alertpanel_notice(_("Your secret key has been generated. "
-                                   "Its fingerprint is:\n%s"),
+               gchar *buf = g_strdup_printf(_("Your new key pair has been generated. "
+                                   "Its fingerprint is:\n%s\n\nDo you want to export it "
+                                   "to a keyserver?"),
                                    key->fpr ? key->fpr:"null");
+               AlertValue val = alertpanel(_("Key generated"), buf,
+                                 GTK_STOCK_NO, "+" GTK_STOCK_YES, NULL);
+               g_free(buf);
+               if (val == G_ALERTALTERNATE) {
+#ifndef G_OS_WIN32
+                       gchar *cmd = g_strdup_printf("gpg --no-tty --send-keys %s", key->fpr);
+                       int res = 0;
+                       pid_t pid = 0;
+                       pid = fork();
+                       if (pid == -1) {
+                               res = -1;
+                       } else if (pid == 0) {
+                               /* son */
+                               res = system(cmd);
+                               res = WEXITSTATUS(res);
+                               _exit(res);
+                       } else {
+                               int status = 0;
+                               time_t start_wait = time(NULL);
+                               res = -1;
+                               do {
+                                       if (waitpid(pid, &status, WNOHANG) == 0 || !WIFEXITED(status)) {
+                                               usleep(200000);
+                                       } else {
+                                               res = WEXITSTATUS(status);
+                                               break;
+                                       }
+                                       if (time(NULL) - start_wait > 5) {
+                                               debug_print("SIGTERM'ing gpg\n");
+                                               kill(pid, SIGTERM);
+                                       }
+                                       if (time(NULL) - start_wait > 6) {
+                                               debug_print("SIGKILL'ing gpg\n");
+                                               kill(pid, SIGKILL);
+                                               break;
+                                       }
+                               } while(1);
+                       }
+                       if (res == 0) {
+                               alertpanel_notice(_("Key exported."));
+                       } else {
+                               alertpanel_error(_("Couldn't export key."));
+                       }
+                       g_free(cmd);
+#else
+                       alertpanel_error(_("Key export isn't implemented in Windows."));
+#endif
+               }
        }
        prefs_gpg_get_config()->gpg_ask_create_key = FALSE;
        prefs_gpg_save_config();
@@ -722,7 +788,7 @@ void sgpgme_check_create_key(void)
 {
        if (prefs_gpg_get_config()->gpg_ask_create_key &&
            !sgpgme_has_secret_key()) {
-               sgpgme_create_secret_key(NULL);
+               sgpgme_create_secret_key(NULL, TRUE);
        } else {
                prefs_gpg_get_config()->gpg_ask_create_key = FALSE;
                prefs_gpg_save_config();