diff --git a/src/command/commands.c b/src/command/commands.c index 7167e26d..082b1bf8 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -486,8 +486,12 @@ cmd_account(ProfWin *window, const char * const command, gchar **args) } cons_show(""); } else if (strcmp(property, "pgpkeyid") == 0) { - accounts_set_pgp_keyid(account_name, value); - cons_show("Updated PGP key ID for account %s: %s", account_name, value); + if (!p_gpg_valid_key(value)) { + cons_show("Invalid PGP key ID specified, see /pgp keys"); + } else { + accounts_set_pgp_keyid(account_name, value); + cons_show("Updated PGP key ID for account %s: %s", account_name, value); + } cons_show(""); } else if (valid_resource_presence_string(property)) { int intval; @@ -4337,8 +4341,8 @@ cmd_pgp(ProfWin *window, const char * const command, gchar **args) } ProfAccount *account = accounts_get_account(jabber_get_account_name()); - if (!account->pgp_keyid) { - ui_current_print_formatted_line('!', 0, "You must specify a PGP key ID for this account to start PGP encryption."); + if (!p_gpg_valid_key(account->pgp_keyid)) { + ui_current_print_formatted_line('!', 0, "You must specify a valid PGP key ID for this account to start PGP encryption."); account_free(account); return TRUE; } diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index 39e743eb..81462f80 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -153,7 +153,7 @@ p_gpg_on_connect(const char * const barejid) error = gpgme_get_key(ctx, keyid, &key, 1); g_free(keyid); if (error || key == NULL) { - log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + log_warning("GPG: Failed to get key for %s: %s %s", jid, gpgme_strsource(error), gpgme_strerror(error)); continue; } @@ -280,6 +280,35 @@ p_gpg_free_key(ProfPGPKey *key) } } +gboolean +p_gpg_valid_key(const char * const keyid) +{ + gpgme_ctx_t ctx; + gpgme_error_t error = gpgme_new(&ctx); + if (error) { + log_error("GPG: Failed to create gpgme context. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + return FALSE; + } + + gpgme_key_t key = NULL; + error = gpgme_get_key(ctx, keyid, &key, 1); + + if (error || key == NULL) { + log_error("GPG: Failed to get key. %s %s", gpgme_strsource(error), gpgme_strerror(error)); + gpgme_release(ctx); + return FALSE; + } + + if (key) { + gpgme_release(ctx); + gpgme_key_unref(key); + return TRUE; + } + + gpgme_release(ctx); + return FALSE; +} + gboolean p_gpg_available(const char * const barejid) { @@ -484,14 +513,32 @@ p_gpg_decrypt(const char * const barejid, const char * const cipher) error = gpgme_op_decrypt(ctx, cipher_data, plain_data); gpgme_data_release(cipher_data); - gpgme_release(ctx); if (error) { log_error("GPG: Failed to encrypt message. %s %s", gpgme_strsource(error), gpgme_strerror(error)); gpgme_data_release(plain_data); + gpgme_release(ctx); return NULL; } + gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx); + if (res) { + gpgme_recipient_t recipient = res->recipients; + if (recipient) { + gpgme_key_t key; + error = gpgme_get_key(ctx, recipient->keyid, &key, 0); + + if (!error && key) { + const char *addr = gpgme_key_get_string_attr(key, GPGME_ATTR_EMAIL, NULL, 0); + if (addr) { + log_debug("GPG: Decrypted message for recipient: %s", addr); + } + gpgme_key_unref(key); + } + } + } + gpgme_release(ctx); + size_t len = 0; char *plain_str = gpgme_data_release_and_get_mem(plain_data, &len); char *result = NULL; diff --git a/src/pgp/gpg.h b/src/pgp/gpg.h index 77f14d1e..7b3a4433 100644 --- a/src/pgp/gpg.h +++ b/src/pgp/gpg.h @@ -48,6 +48,7 @@ void p_gpg_on_disconnect(void); GSList* p_gpg_list_keys(void); gboolean p_gpg_addkey(const char * const jid, const char * const keyid); GHashTable* p_gpg_fingerprints(void); +gboolean p_gpg_valid_key(const char * const keyid); gboolean p_gpg_available(const char * const barejid); const char* p_gpg_libver(void); void p_gpg_free_key(ProfPGPKey *key); diff --git a/tests/unittests/pgp/stub_gpg.c b/tests/unittests/pgp/stub_gpg.c index f8e05d57..577f7d66 100644 --- a/tests/unittests/pgp/stub_gpg.c +++ b/tests/unittests/pgp/stub_gpg.c @@ -30,6 +30,11 @@ char* p_gpg_sign(const char * const str, const char * const fp) return NULL; } +gboolean p_gpg_valid_key(const char * const keyid) +{ + return FALSE; +} + gboolean p_gpg_available(const char * const barejid) { return FALSE;