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.
--- 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 <glib.h>
#include <mcabber/config.h> // For MCABBER_BRANCH
-#define MCABBER_API_VERSION 38
+#define MCABBER_API_VERSION 39
#define MCABBER_API_MIN 38
#define MCABBER_BRANCH_DEV 1
--- 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));
--- 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));
--- 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 <gpgme.h>
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);