gpgme_error_t gpgmegtk_passphrase_cb(void *opaque, const char *uid_hint, const char *passphrase_hint, int prev_bad, int fd) { const char *pass; #ifdef G_OS_WIN32 HANDLE hd = (HANDLE)fd; DWORD n; #endif if (prefs_common.store_passphrase && last_pass != NULL && !prev_bad) { #ifdef G_OS_WIN32 WriteFile(hd, last_pass, strlen(last_pass), &n, NULL); WriteFile(hd, "\n", 1, &n, NULL); #else write(fd, last_pass, strlen(last_pass)); write(fd, "\n", 1); #endif return GPG_ERR_NO_ERROR; } gpgmegtk_set_passphrase_grab (prefs_common.passphrase_grab); debug_print ("%% requesting passphrase for `%s':\n", uid_hint); pass = passphrase_mbox (uid_hint, passphrase_hint, prev_bad); gpgmegtk_free_passphrase(); if (!pass) { debug_print ("%% cancel passphrase entry\n"); #ifdef G_OS_WIN32 WriteFile(hd, "\n", 1, &n, NULL); CloseHandle(hd); /* somehow it will block without this */ #else write(fd, "\n", 1); #endif return GPG_ERR_CANCELED; } else { if (prefs_common.store_passphrase) { last_pass = g_strdup(pass); #if HAVE_MLOCK if (mlock(last_pass, strlen(last_pass)) == -1) debug_print("%% locking passphrase failed\n"); #endif if (prefs_common.store_passphrase_timeout > 0) { g_timeout_add_full(G_PRIORITY_LOW, prefs_common.store_passphrase_timeout * 60 * 1000, free_passphrase, NULL, NULL); } } debug_print ("%% sending passphrase\n"); } #ifdef G_OS_WIN32 WriteFile(hd, pass, strlen(pass), &n, NULL); WriteFile(hd, "\n", 1, &n, NULL); #else write(fd, pass, strlen(pass)); write(fd, "\n", 1); #endif return GPG_ERR_NO_ERROR; }
const char* gpgmegtk_passphrase_cb (void *opaque, const char *desc, void **r_hd) { struct passphrase_cb_info_s *info = opaque; GpgmeCtx ctx = info ? info->c : NULL; const char *pass; if (!desc) { /* FIXME: cleanup by looking at *r_hd */ return NULL; } if (prefs_gpg_get_config()->store_passphrase && last_pass != NULL && strncmp(desc, "TRY_AGAIN", 9) != 0) return g_strdup(last_pass); gpgmegtk_set_passphrase_grab (prefs_gpg_get_config()->passphrase_grab); debug_print ("%% requesting passphrase for `%s': ", desc); pass = passphrase_mbox (desc); gpgmegtk_free_passphrase(); if (!pass) { debug_print ("%% cancel passphrase entry"); gpgme_cancel (ctx); } else { if (prefs_gpg_get_config()->store_passphrase) { last_pass = g_strdup(pass); if (mlock(last_pass, strlen(last_pass)) == -1) debug_print("%% locking passphrase failed"); if (prefs_gpg_get_config()->store_passphrase_timeout > 0) { gtk_timeout_add(prefs_gpg_get_config()->store_passphrase_timeout*60*1000, free_passphrase, NULL); } } debug_print ("%% sending passphrase"); } return pass; }
void sgpgme_create_secret_key(PrefsAccount *account, gboolean ask_create) { AlertValue val = G_ALERTDEFAULT; 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 (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"), _("Claws Mail 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); } 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: RSA\n" "Key-Length: 2048\n" "Subkey-Type: RSA\n" "Subkey-Length: 2048\n" "Name-Real: %s\n" "Name-Email: %s\n" "Expire-Date: 0\n" "%s%s%s" "</GnupgKeyParms>\n", 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"); 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 a new key pair: %s"), gpgme_strerror(err)); g_free(key_parms); return; } 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); g_free(key_parms); label_window_destroy(window); if (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 a new key pair: unknown error")); gpgme_release(ctx); return; } else { 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(); gpgme_release(ctx); }