# HG changeset patch # User Mikael Berthe # Date 1444247918 -7200 # Node ID 8811fe9d6ef02e3944deca5c9f18cf6493643c76 # Parent 40ddaebeb81e418e04477e229241846d22d5df73 Improve support for GnuPG v2+ If the gnupg engine detected is not 1.x, do not check the environment variable GPG_AGENT_INFO and do not set up a password callback. diff -r 40ddaebeb81e -r 8811fe9d6ef0 mcabber/mcabber/api.h --- a/mcabber/mcabber/api.h Wed Oct 07 21:55:51 2015 +0200 +++ b/mcabber/mcabber/api.h Wed Oct 07 21:58:38 2015 +0200 @@ -4,7 +4,7 @@ #include #include // For MCABBER_BRANCH -#define MCABBER_API_VERSION 38 +#define MCABBER_API_VERSION 39 #define MCABBER_API_MIN 38 #define MCABBER_BRANCH_DEV 1 diff -r 40ddaebeb81e -r 8811fe9d6ef0 mcabber/mcabber/main.c --- a/mcabber/mcabber/main.c Wed Oct 07 21:55:51 2015 +0200 +++ b/mcabber/mcabber/main.c Wed Oct 07 21:58:38 2015 +0200 @@ -262,25 +262,39 @@ bool pgp_agent; int retries; + pk = settings_opt_get("pgp_private_key"); + + if (!pk) + scr_LogPrint(LPRINT_LOGNORM, "WARNING: unknown PGP private key"); + + if (gpg_init(pk, NULL)) { + scr_LogPrint(LPRINT_LOGNORM, "WARNING: Could not initialize PGP."); + return; + } + + // We're done if the PGP engine version is > 1 + // since the agent is mandatory and password mechanism is external. + if (!gpg_is_version1()) + return; + + p = getenv("GPG_AGENT_INFO"); pgp_agent = (p && strchr(p, ':')); - pk = settings_opt_get("pgp_private_key"); - pp = settings_opt_get("pgp_passphrase"); - if (settings_opt_get("pgp_passphrase_retries")) retries = settings_opt_get_int("pgp_passphrase_retries"); else retries = 2; + pp = settings_opt_get("pgp_passphrase"); + if (!pk) { - scr_LogPrint(LPRINT_LOGNORM, "WARNING: unknown PGP private key"); pgp_invalid = TRUE; } else if (!(pp || pgp_agent)) { // Request PGP passphrase pp = typed_passwd = ask_password("your PGP passphrase"); } - gpg_init(pk, pp); + gpg_set_passphrase(pp); // Erase password from the settings array if (pp) { memset((char*)pp, 0, strlen(pp)); diff -r 40ddaebeb81e -r 8811fe9d6ef0 mcabber/mcabber/pgp.c --- a/mcabber/mcabber/pgp.c Wed Oct 07 21:55:51 2015 +0200 +++ b/mcabber/mcabber/pgp.c Wed Oct 07 21:58:38 2015 +0200 @@ -38,7 +38,8 @@ static struct gpg_struct { - int enabled; + int enabled; + int version1; char *private_key; char *passphrase; } gpg; @@ -53,6 +54,9 @@ { gpgme_error_t err; + gpgme_ctx_t ctx; + gpgme_engine_info_t info; + // Check for version and OpenPGP protocol support. if (!gpgme_check_version(MIN_GPGME_VERSION)) { scr_LogPrint(LPRINT_LOGNORM, @@ -75,10 +79,38 @@ gpg_set_private_key(priv_key); gpg_set_passphrase(passphrase); + err = gpgme_new(&ctx); + if (err) return -1; + + // Check OpenPGP engine version; with version 2+ the agent is mandatory + // and we do not manage the passphrase. + gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); + if (err) return -1; + + err = gpgme_get_engine_info (&info); + if (!err) { + while (info && info->protocol != gpgme_get_protocol (ctx)) + info = info->next; + + if (info && info->version) { + if (!strncmp(info->version, "1.", 2)) + gpg.version1 = TRUE; + scr_log_print(LPRINT_DEBUG, "GPGME: Engine version is '%s'.", + info->version); + } + } + gpg.enabled = 1; return 0; } +// gpg_is_version1() +// Return TRUE if the GnuPG OpenPGP engine version is 1.x +int gpg_is_version1(void) +{ + return gpg.version1; +} + // gpg_terminate() // Destroy data and free memory. void gpg_terminate(void) @@ -264,7 +296,6 @@ { gpgme_ctx_t ctx; gpgme_data_t in, out; - char *p; char *signed_data = NULL; size_t nread; gpgme_key_t key; @@ -284,9 +315,12 @@ gpgme_set_textmode(ctx, 0); gpgme_set_armor(ctx, 1); - p = getenv("GPG_AGENT_INFO"); - if (!(p && strchr(p, ':'))) - gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); + if (gpg.version1) { + // GPG_AGENT_INFO isn't used by GnuPG version 2+ + char *p = getenv("GPG_AGENT_INFO"); + if (!(p && strchr(p, ':'))) + gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); + } err = gpgme_get_key(ctx, gpg.private_key, &key, 1); if (err || !key) { @@ -332,7 +366,7 @@ { gpgme_ctx_t ctx; gpgme_data_t in, out; - char *p, *data; + char *data; char *decrypted_data = NULL; size_t nread; gpgme_error_t err; @@ -351,9 +385,12 @@ gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); - p = getenv("GPG_AGENT_INFO"); - if (!(p && strchr(p, ':'))) - gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); + if (gpg.version1) { + // GPG_AGENT_INFO isn't used by GnuPG version 2+ + char *p = getenv("GPG_AGENT_INFO"); + if (!(p && strchr(p, ':'))) + gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); + } // Surround the given data with the prefix & suffix data = g_new(char, sizeof(prefix) + sizeof(suffix) + strlen(gpg_data)); diff -r 40ddaebeb81e -r 8811fe9d6ef0 mcabber/mcabber/pgp.h --- a/mcabber/mcabber/pgp.h Wed Oct 07 21:55:51 2015 +0200 +++ b/mcabber/mcabber/pgp.h Wed Oct 07 21:58:38 2015 +0200 @@ -9,6 +9,7 @@ #include int gpg_init(const char *priv_key, const char *passphrase); +int gpg_is_version1(void); void gpg_terminate(void); void gpg_set_passphrase(const char *passphrase); void gpg_set_private_key(const char *priv_keyid);