You are not logged in.

#1 2025-02-16 12:26:57

lightstream
Member
From: Britain
Registered: 2011-10-30
Posts: 69

[SOLVED] Timeout when encrypting a file on the command line with gpg

I've been banging my head against the wall all morning trying to disable the timeout for the pinentry program used by gpg.

My problem is that I want to encrypt a file with a long difficult-to-remember passphrase, and I'm trying with a command like this one:

gpg --cipher-algo AES256 --symmetric sourcefile

I have the following config at ~/.gnupg/gpg-agent.conf :

pinentry-timeout 0
pinentry-program /usr/bin/pinentry-curses

I've reloaded the config with "gpgconf --reload gpg-agent" but the passphrase dialog still times out (after about 60 seconds) and gives me the message:

gpg: problem with the agent: Timeout
gpg: error creating passphrase: Operation cancelled
gpg: symmetric encryption of 'sourcefile' failed: Operation cancelled

I know that it is reading my config correctly because if I change the program to /usr/bin/pinentry-tty I get a different prompt for the passphrase (but it still times out after 60 seconds or so).

Last edited by lightstream (2025-02-19 00:51:33)

Offline

#2 2025-02-16 13:05:26

Head_on_a_Stick
Member
From: The Wirral
Registered: 2014-02-20
Posts: 8,999
Website

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

Does pinentry-tty work any better? The default pinentry-timeout is zero but the pinentry application may have it's own timeout.


Jin, Jîyan, Azadî

Offline

#3 2025-02-16 14:55:16

lightstream
Member
From: Britain
Registered: 2011-10-30
Posts: 69

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

No it seems to be just the same, in terms of timeout. I've tried this on two separate Arch machines now and both behave exactly the same.

Last edited by lightstream (2025-02-16 14:55:38)

Offline

#4 2025-02-16 16:49:09

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 70,997

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

The timeout is from gpg, not the pinentry.
Try

qarma --password | gpg --passphrase-fd 0 --pinentry-mode loopback --batch --cipher-algo AES256 --symmetric sourcefile

(ie. have gpg read the password from stdin)

Offline

#5 2025-02-16 19:30:08

lightstream
Member
From: Britain
Registered: 2011-10-30
Posts: 69

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

Thanks for the pointer. I've not installed that qarma program yet, I'd rather fix this without AUR packages if I can.

Am I doing something wrong? Is this not the correct way to encrypt a file on the command line?

A requirement to type in and confirm the passphrase within 60 seconds just doesn't seem like a good idea. It seems it would make users take shortcuts that reduce security, such as using less secure easy-to-type phrases, using cut+paste etc.

Offline

#6 2025-02-16 20:52:24

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 70,997

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

qarma is just shameless advertisement, the point is to use sdtin, any dialog will do

printf 'SETQUALITYBAR\nSETREPEAT\nGETPIN\n' | pinentry-gtk | gpg --passphrase-fd 0 --pinentry-mode loopback --batch --cipher-algo AES256 --symmetric sourcefile

(This doesn't work w/ pinentry-curses which doesn't fails for isatty (you'll have to use a 3rd fd, which is possible but makes the exmple even more complicated)

I don't think you're doing something wrong but could not find a way to impact this behavior of gpg, so the next best thing is to side-step it.

Offline

#7 2025-02-17 14:41:01

lightstream
Member
From: Britain
Registered: 2011-10-30
Posts: 69

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

Thanks for the response. I've spent another morning with this issue, but at least I feel I've got somewhere now.

I actually feel like this is a regression in gpg-agent, which is not passing the pinentry-timeout config setting to the pinentry program. I say regression because I assume this feature must have worked at one time. I've searched the gpg bug-tracker and nobody else appears to have reported this already (but there are older bugs which suggest the config setting did use to work).

What convinces me that the issue is with gpg and is not by design is that I created a script with the following contents:

#!/bin/sh
exec /usr/bin/pinentry-curses --timeout 0 "$@"

Made it executable and then specified it in ~/.gnupg/gpg-agent.conf:

pinentry-program /path/to/file/pinentry-wrapper

Next killed / restarted the agent:

gpgconf --kill gpg-agent

And hey presto, I can encrypt files without any time pressure for entering the passphrase, with just the standard command line e.g. gpg --symmetric sourcefile

I booted up an older copy of Arch with gpg 2.4.5 on, and the same issue exists there. It does seem strange to me that no one else appears to have reported this as a new issue, so I haven't yet sent a mail to the gnupg-devel mailing list. In fact I'm wondering if I should send it to the users mailing list in the first instance.

Last edited by lightstream (2025-02-17 14:42:14)

Offline

#8 2025-02-17 15:04:56

TE
Member
Registered: 2014-06-21
Posts: 85

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

I use GPG to do what you're doing (I also use "age" which I like better[1]), here's what I have on a functional system:

$ cat .gnupg/gpg-agent.conf 
pinentry-program /usr/bin/pinentry-tty
allow-loopback-pinentry
disable-scdaemon
$ cat .gnupg/gpg.conf 
default-key xxxxxxxx

I have all the gnupg-package provided systemd units and sockets disabled in /etc/systemd/, however when logging in LightDM -> XFCE the gpg-agent process is automatically started on user login (but not anything else like dirmgr etc.) by a systemd parent. I just rebooted for some unrelated updates, so looking at a fresh reboot without having run any gpg commands yet:

$ ps -ef
...
xxxxxx       998       1  0 08:28 ?        00:00:00 /usr/lib/systemd/systemd --user
xxxxxx      1097     998  0 08:28 ?        00:00:00 /usr/bin/gpg-agent --supervised

Hope something in here helps you out, I use gpg and age symmetric encryption regularly to keep backup copies of app-specific exported data (JSON files etc.) so it's been a working solution for awhile without having to do any system level hijinks ("just works"). I also used to use duplicity which required this to all be working to encrypt it's tarballs for many years. $0.02

[1] age is portable and minimal install, great for a remote cloud server where you don't need/want the weight of GPG but need to encrypt files. It lacks builtin compression though so you have to two-step it unlike GPG who does compression + encryption in one step by itself. "gpg -c foo.file" => "age -e -p -o foo.file.age foo.file"

Offline

#9 2025-02-17 15:55:21

TE
Member
Registered: 2014-06-21
Posts: 85

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

lightstream wrote:
#!/bin/sh
exec /usr/bin/pinentry-curses --timeout 0 "$@"

Idea: try an unsigned long value in gpg-agent.conf so like "pinentry-timeout 3600" or whatever works for your time needs to make it wait long enough but just not forever.

As I took a look at the source - I'm not a C programmer, but doesn't "if (0)" in C code equivocate to "if false" and avoids running the if condition? In a grep nutshell we're looking at this:

$ find . -type f | xargs grep pinentry_timeout
./agent/agent.h:  unsigned long pinentry_timeout;
./agent/gpg-agent.c:      opt.pinentry_timeout = 0;
./agent/gpg-agent.c:    case oPinentryTimeout: opt.pinentry_timeout = pargs->r.ret_ulong; break;
./agent/call-pinentry.c:  if (opt.pinentry_timeout)
./agent/call-pinentry.c:      if ((optstr = xtryasprintf ("SETTIMEOUT %lu", opt.pinentry_timeout)))

Which leads us to https://github.com/gpg/gnupg/blob/maste … try.c#L604 "if (opt.pinentry_timeout)..." - doesn't it look like the value of 0 is being passed to that if clause? We see the internal default _is_ zero (above) so this could have been a programmer short-hand "if this value is not zero, set it in the call". But when calling pinentry-tty (sic) directly with the --timeout option like in your script it's passed into the next code block.

Then over in the pinentry source, https://github.com/gpg/pinentry/blob/ma … try.c#L170 "pinentry.timeout = 60;" as our internal default, but it looks like the same C "if (0)" clause happens over in the TTY code here https://github.com/gpg/pinentry/blob/ma … tty.c#L532 which basically will not sound the alarm if the value of timeout is 0. I think that's how it works at least, it's another magic 0 evaluation to skip some code logic.

Hope some of this gibberish helps, it seems to make sense to me if I understand in C what "if (0)" does when what I think maybe is needed is "if exists(foo)" or whatever a programmer would do correctly. Seems like a value of 0 escapes their logic when being bounced between gpg-agent -> pinentry using a callout to it on the fly.

Offline

#10 2025-02-17 17:10:12

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 70,997

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

Yes, gpg will only send a postive timeout to pinentry via the ASSUAN protocol, otherwise pinentry will use an internal default either provided via the commandline or hardcoded 60s

I guess what has happened is that historically pinentry had no internal (default) timeout, resp. the default was to not time-out.
At some point in the distant past (90ies) that has probably changed and nobody noticed it because users rarely spend 60s to enter a password.

The implementation and behavior differs from the documentation, feel free to file a bug.

Offline

#11 2025-02-19 00:50:31

lightstream
Member
From: Britain
Registered: 2011-10-30
Posts: 69

Re: [SOLVED] Timeout when encrypting a file on the command line with gpg

TE wrote:

Which leads us to https://github.com/gpg/gnupg/blob/maste … try.c#L604 "if (opt.pinentry_timeout)..." - doesn't it look like the value of 0 is being passed to that if clause?

Nice sleuthing TE! You definitely solved it - I feel a bit silly for not trying other values for the timeout apart from zero.

The documentation is a little confusing about this. This is from the man page for gpg-agent:

       --pinentry-timeout n
              This  option  asks  the Pinentry to timeout after n seconds with no user input.  The default value of 0 does not ask the pinentry to
              timeout, however a Pinentry may use its own default timeout value in this case.  A Pinentry may or may not honor this request.

Whereas this is the info page for pinentry (it doesn't have a man page):

'--timeout SECONDS'
     Give up waiting for input from the user after the specified number
     of seconds and return an error.  The error returned is the same as
     if the Cancel button was selected.  To disable the timeout and wait
     indefinitely, set this to 0, which is the default.

So gpg-agent is working as designed, but pinentry is using an incorrect default. This is in fact one of the bugs I found on the gnupg bug tracker, which was filed in 2021 and had a little activity indicating the default was going to be set to zero, but clearly it never was.

I guess I'll send an email to the mailing list in the next day or two to give them a nudge on it, as it seems a pretty straightforward fix and IMO it would be a better default.

It's good to get to the bottom of it anyway. Thanks both for the help!

Last edited by lightstream (2025-02-19 01:22:47)

Offline

Board footer

Powered by FluxBB