static void prefs_gpg_account_save_func(PrefsPage *_page) { struct GPGAccountPage *page = (struct GPGAccountPage *) _page; GPGAccountConfig *config; config = prefs_gpg_account_get_config(page->account); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_default))) config->sign_key = SIGN_KEY_DEFAULT; else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_by_from))) config->sign_key = SIGN_KEY_BY_FROM; else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom))) { config->sign_key = SIGN_KEY_CUSTOM; g_free(config->sign_key_id); config->sign_key_id = gtk_editable_get_chars(GTK_EDITABLE(page->keyid), 0, -1); } prefs_gpg_account_set_config(page->account, config); prefs_gpg_account_free_config(config); }
gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account, const gchar *from_addr) { GPGAccountConfig *config; const gchar *signer_addr = account->address; gpgme_signers_clear(ctx); if (from_addr) signer_addr = from_addr; config = prefs_gpg_account_get_config(account); switch(config->sign_key) { case SIGN_KEY_DEFAULT: debug_print("using default gnupg key\n"); break; case SIGN_KEY_BY_FROM: debug_print("using key for %s\n", signer_addr); break; case SIGN_KEY_CUSTOM: debug_print("using key for %s\n", config->sign_key_id); break; } if (config->sign_key != SIGN_KEY_DEFAULT) { const gchar *keyid; gpgme_key_t key, found_key; gpgme_error_t err; if (config->sign_key == SIGN_KEY_BY_FROM) keyid = signer_addr; else if (config->sign_key == SIGN_KEY_CUSTOM) keyid = config->sign_key_id; else goto bail; found_key = NULL; /* Look for any key, not just private ones, or GPGMe doesn't * correctly set the revoked flag. */ err = gpgme_op_keylist_start(ctx, keyid, 0); while ((err = gpgme_op_keylist_next(ctx, &key)) == 0) { if (key == NULL) continue; if (!key->can_sign) continue; if (key->protocol != gpgme_get_protocol(ctx)) { debug_print("skipping a key (wrong protocol %d)\n", key->protocol); gpgme_key_release(key); continue; } if (key->expired) { debug_print("skipping a key, expired"); gpgme_key_release(key); continue; } if (key->revoked) { debug_print("skipping a key, revoked"); gpgme_key_release(key); continue; } if (key->disabled) { debug_print("skipping a key, disabled"); gpgme_key_release(key); continue; } if (found_key != NULL) { gpgme_key_release(key); gpgme_op_keylist_end(ctx); g_warning("ambiguous specification of secret key '%s'\n", keyid); privacy_set_error(_("Secret key specification is ambiguous")); goto bail; } found_key = key; } gpgme_op_keylist_end(ctx); if (found_key == NULL) { g_warning("setup_signers start: %s", gpgme_strerror(err)); privacy_set_error(_("Secret key not found (%s)"), gpgme_strerror(err)); goto bail; } err = gpgme_signers_add(ctx, found_key); debug_print("got key (proto %d (pgp %d, smime %d).\n", found_key->protocol, GPGME_PROTOCOL_OpenPGP, GPGME_PROTOCOL_CMS); gpgme_key_release(found_key); if (err) { g_warning("error adding secret key: %s\n", gpgme_strerror(err)); privacy_set_error(_("Error setting secret key: %s"), gpgme_strerror(err)); goto bail; } } prefs_gpg_account_free_config(config); return TRUE; bail: prefs_gpg_account_free_config(config); return FALSE; }
gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account, const gchar *from_addr) { GPGAccountConfig *config; const gchar *signer_addr = account->address; gpgme_signers_clear(ctx); if (from_addr) signer_addr = from_addr; config = prefs_gpg_account_get_config(account); switch(config->sign_key) { case SIGN_KEY_DEFAULT: debug_print("using default gnupg key\n"); break; case SIGN_KEY_BY_FROM: debug_print("using key for %s\n", signer_addr); break; case SIGN_KEY_CUSTOM: debug_print("using key for %s\n", config->sign_key_id); break; } if (config->sign_key != SIGN_KEY_DEFAULT) { const gchar *keyid; gpgme_key_t key, key2; gpgme_error_t err; if (config->sign_key == SIGN_KEY_BY_FROM) keyid = signer_addr; else if (config->sign_key == SIGN_KEY_CUSTOM) keyid = config->sign_key_id; else goto bail; err = gpgme_op_keylist_start(ctx, keyid, 1); if (!err) { do { err = gpgme_op_keylist_next(ctx, &key); if (!err && key && key->protocol == gpgme_get_protocol(ctx) && !key->expired && !key->revoked && !key->disabled) break; if (!err && key && key->protocol != gpgme_get_protocol(ctx)) { debug_print("skipping a key (wrong protocol %d)\n", key->protocol); gpgme_key_release(key); } if (!err && key && (key->expired || key->revoked || key->disabled)) { debug_print("skipping a key"); if (key->expired) debug_print(" expired"); if (key->revoked) debug_print(" revoked"); if (key->disabled) debug_print(" disabled"); debug_print("\n"); gpgme_key_release(key); } } while (!err); } if (err) { g_warning("setup_signers start: %s", gpgme_strerror(err)); privacy_set_error(_("Secret key not found (%s)"), gpgme_strerror(err)); goto bail; } do { err = gpgme_op_keylist_next(ctx, &key2); if (!err && key2 && key2->protocol == gpgme_get_protocol(ctx) && !key2->expired && !key2->revoked && !key2->disabled) break; if (!err && key2 && key2->protocol != gpgme_get_protocol(ctx)) { debug_print("skipping a key (wrong protocol %d)\n", key2->protocol); gpgme_key_release(key2); } if (!err && key2 && (key2->expired || key2->revoked || key2->disabled)) { debug_print("skipping a key"); if (key2->expired) debug_print(" expired"); if (key2->revoked) debug_print(" revoked"); if (key2->disabled) debug_print(" disabled"); debug_print("\n"); gpgme_key_release(key2); } } while (!err); if (!err) { gpgme_key_release(key2); g_warning("ambiguous specification of secret key '%s'\n", keyid); privacy_set_error(_("Secret key specification is ambiguous")); goto bail; } gpgme_op_keylist_end(ctx); err = gpgme_signers_add(ctx, key); debug_print("got key (proto %d (pgp %d, smime %d).\n", key->protocol, GPGME_PROTOCOL_OpenPGP, GPGME_PROTOCOL_CMS); gpgme_key_release(key); if (err) { g_warning("error adding secret key: %s\n", gpgme_strerror(err)); privacy_set_error(_("Error setting secret key: %s"), gpgme_strerror(err)); goto bail; } } prefs_gpg_account_free_config(config); return TRUE; bail: prefs_gpg_account_free_config(config); return FALSE; }