ENGINE-220 empirical nullshit trying to have gpg behave when passphrase callback is set with gpg 2.0.x gpgme_passphrase_cb
authorEdouard Tisserant <edouard@pep-project.org>
Sat, 22 Jul 2017 00:06:09 +0200
branchgpgme_passphrase_cb
changeset 193897fcdff36aa7
parent 1937 e32c06c3ffba
child 1939 d117622a7fe0
ENGINE-220 empirical nullshit trying to have gpg behave when passphrase callback is set with gpg 2.0.x
src/pgp_gpg.c
     1.1 --- a/src/pgp_gpg.c	Fri Jul 21 15:53:57 2017 +0200
     1.2 +++ b/src/pgp_gpg.c	Sat Jul 22 00:06:09 2017 +0200
     1.3 @@ -437,17 +437,31 @@
     1.4      }
     1.5      assert(session->ctx);
     1.6  
     1.7 +    gpgme_engine_info_t info;
     1.8 +    int err = gpg.gpgme_get_engine_info(&info);
     1.9 +    assert(err == GPG_ERR_NO_ERROR);
    1.10 +    if (err != GPG_ERR_NO_ERROR) {
    1.11 +        status = PEP_OUT_OF_MEMORY;
    1.12 +        goto pep_error;
    1.13 +    }
    1.14 +
    1.15 +    DEBUG_LOG("GPGME init", "gpg version", info->version);
    1.16 +
    1.17 +    gpgme_error = gpg.gpgme_set_protocol(session->ctx, GPGME_PROTOCOL_OpenPGP);
    1.18 +    gpgme_error = _GPGERR(gpgme_error);
    1.19 +    assert(gpgme_error == GPG_ERR_NO_ERROR);
    1.20 +
    1.21      gpgme_error = gpg.gpgme_set_passphrase_cb(session->ctx, passphrase_cb, NULL);
    1.22      gpgme_error = _GPGERR(gpgme_error);
    1.23      assert(gpgme_error == GPG_ERR_NO_ERROR);
    1.24  
    1.25 -    gpgme_error = gpg.gpgme_set_pinentry_mode(session->ctx, GPGME_PINENTRY_MODE_LOOPBACK);
    1.26 -    gpgme_error = _GPGERR(gpgme_error);
    1.27 -    assert(gpgme_error == GPG_ERR_NO_ERROR);
    1.28 -
    1.29 -    gpgme_error = gpg.gpgme_set_protocol(session->ctx, GPGME_PROTOCOL_OpenPGP);
    1.30 -    gpgme_error = _GPGERR(gpgme_error);
    1.31 -    assert(gpgme_error == GPG_ERR_NO_ERROR);
    1.32 +    // Enabling Loopback Mode Pinentry crashes gpg 2.0.30 at op_decrypt*
    1.33 +    // while it works with 2.1.17. Arbitrarily disable it for <=2.0
    1.34 +    if(strncmp(info->version, "2.0", 3) > 0) {
    1.35 +        gpgme_error = gpg.gpgme_set_pinentry_mode(session->ctx, GPGME_PINENTRY_MODE_LOOPBACK);
    1.36 +        gpgme_error = _GPGERR(gpgme_error);
    1.37 +        assert(gpgme_error == GPG_ERR_NO_ERROR);
    1.38 +    }
    1.39  
    1.40      gpg.gpgme_set_armor(session->ctx, 1);
    1.41  
    1.42 @@ -1290,6 +1304,11 @@
    1.43          free(parms);
    1.44          return PEP_BUFFER_TOO_SMALL;
    1.45      }
    1.46 +   
    1.47 +    // Versions not supporting create_keys also mess'up with callback on op_genkey 
    1.48 +    gpgme_error = gpg.gpgme_set_passphrase_cb(session->ctx, NULL, NULL);
    1.49 +    gpgme_error = _GPGERR(gpgme_error);
    1.50 +    assert(gpgme_error == GPG_ERR_NO_ERROR);
    1.51  
    1.52      gpgme_error = gpg.gpgme_op_genkey(session->ctx, parms, NULL, NULL);
    1.53      gpgme_error = _GPGERR(gpgme_error);
    1.54 @@ -1311,6 +1330,11 @@
    1.55      assert(gpgme_genkey_result);
    1.56      assert(gpgme_genkey_result->fpr);
    1.57  
    1.58 +    // restore callback
    1.59 +    gpgme_error = gpg.gpgme_set_passphrase_cb(session->ctx, passphrase_cb, NULL);
    1.60 +    gpgme_error = _GPGERR(gpgme_error);
    1.61 +    assert(gpgme_error == GPG_ERR_NO_ERROR);
    1.62 +
    1.63      free(identity->fpr);
    1.64      identity->fpr = strdup(gpgme_genkey_result->fpr);
    1.65      if (identity->fpr == NULL)