How to prevent passphrase-caching from within a gpgme-based Python script?

Ángel angel at pgp.16bits.net
Tue Apr 16 23:23:52 CEST 2019


On 2019-04-12 at 07:12 -0400, Kynn Jones wrote:
> Hi everyone!
> 
> The following short Python script takes three command-line arguments:
> a passphrase, an input path, and an output path.  Then it uses the
> passphrase to decrypt the contents of the input path, and puts the
> decrypted content in the output path.
> 
(...)
> This decryption works fine, as long as the correct passphrase is
> provided, but it apparently results in the caching of such correct
> passphrase, so that any subsequent decryption attempts succeed
> irrespective of the passphrase one provides.  (I give a fuller
> illustration of what I mean at the end of this post, together with
> version details.)
> 
> Clearly, there's some passphrase caching going on, but I don't really
> understand the details.

Yes. gpg will use a gpg-agent, launching it if needed, and that agent is
caching the passphrase:

>        --default-cache-ttl n
>               Set the time a cache entry is valid to n seconds.  The default is 600 seconds.
>        --max-cache-ttl n
>               Set the maximum time a cache entry is valid to n seconds.  After this time a cache  entry
>               will  be  expired even if it has been accessed recently or has been set using gpg-preset-
>               passphrase.  The default is 2 hours (7200 seconds).
> 

> 
> What I want to know is: how can I modify the Python script so that it
> disables the caching of passphrases?  Note that I am not interested in
> how to disable passphrase caching outside of the script!  I want the
> script to disable passphrase caching autonomously.  Is that possible?

There doesn't seem to be any command to set a passphrase with just a ttl
in the agent protocol. Which is not that strange, given the gpg client
passing the passphrase to the agent is the weird case. It could of
course issue a CLEAR_PASSPHRASE before each operation, but that would be
racy.

I think you should launch your own gpg-agent for your script, with the
configuration you wish. For example, I expect that running this wrapper
instead of demo.py would fix it: 

#!/bin/sh
eval $(gpg-agent --daemon --sh --max-cache-ttl 0)
exec python ./demo.py "$@"


Of course, you could instead run gpg-agent from python and set
GPG_AGENT_INFO there. The gpg python package is calling gpg under the
hood, so it should pick the GPG_AGENT_INFO variable from the
environment.


In the script above, after running the script you could do
> kill $(echo "$GPG_AGENT_INFO" | cut -d : -f 2)
since nobody would use that agent again, anyway.

A more optimized version would use a dedicated agent just for demo.py,
but reuse it amongst several invocations of demo.py.


Best regards





More information about the Gnupg-users mailing list