gnupg-verify* crashes when stdin is not /dev/tty

  • Open
  • quality assurance status badge
Details
One participant
  • Maxim Cournoyer
Owner
unassigned
Submitted by
Maxim Cournoyer
Severity
normal
M
M
Maxim Cournoyer wrote 4 days ago
(name . bug-guix)(address . bug-guix@gnu.org)
87bjve7c2p.fsf@gmail.com
Hello,

I've discovered this problem using './pre-inst-env guix refresh -u' and
xargs, which by default doesn't connect stdin to /dev/tty
(non-interactive):

Toggle snippet (51 lines)
$ echo alsa-utils | xargs ./pre-inst-env guix refresh -u
Starting download of /tmp/guix-file.nWaumi
From https://www.alsa-project.org/files/pub/utils/alsa-utils-1.2.13.tar.bz2...
….2.13.tar.bz2 1.6MiB 1.1MiB/s 00:01 ???????????????????? 100.0%

Starting download of /tmp/guix-file.Y9WAfh
From https://www.alsa-project.org/files/pub/utils/alsa-utils-1.2.13.tar.bz2.sig...
….13.tar.bz2.sig 833B 4.2MiB/s 00:00 ???????????????????? 100.0%
gpgv: Signature faite le mar. 12 nov. 2024 18:50:14 JST
gpgv: avec la clef RSA F04DF50737AC1A884C4B3D718380596DA6E59C91
gpgv: Impossible de vérifier la signature : Pas de clef publique
Would you like to add this key to keyring '/home/maxim/.config/guix/upstream/trustedkeys.kbx'?
Backtrace:
In ice-9/boot-9.scm:
1752:10 18 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
In unknown file:
17 (apply-smob/0 #<thunk 7f44d41132a0>)
In ice-9/boot-9.scm:
724:2 16 (call-with-prompt _ _ #<procedure default-prompt-handler (k proc)>)
In ice-9/eval.scm:
619:8 15 (_ #(#(#<directory (guile-user) 7f44d4118c80>)))
In guix/ui.scm:
2332:7 14 (run-guix . _)
2295:10 13 (run-guix-command _ . _)
In ice-9/boot-9.scm:
1752:10 12 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
1752:10 11 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
In guix/store.scm:
689:37 10 (thunk)
2210:25 9 (run-with-store #<store-connection 256.100 7f44b67232d0> _ #:guile-for-build _ #:system _ # _)
In guix/scripts/refresh.scm:
635:18 8 (_ _)
In srfi/srfi-1.scm:
634:9 7 (for-each #<procedure 7f44c0adac40 at guix/scripts/refresh.scm:636:19 (update)> _)
In guix/scripts/refresh.scm:
375:22 6 (update-package _ #<package alsa-utils@1.2.11 gnu/packages/linux.scm:3153 7f44b6e04790> _ _ # …)
In guix/upstream.scm:
473:22 5 (package-update/url-fetch #<store-connection 256.100 7f44b67232d0> #<package alsa-utils@1.2.…> …)
343:34 4 (download-tarball _ "https://www.alsa-project.org/files/pub/utils/alsa-utils-1.2.13.tar.bz2" # …)
In ice-9/regex.scm:
133:5 3 (gnupg-verify* "/gnu/store/qzqb2phrikb9mnkajxppz9qp9gz1c2bd-alsa-utils-1.2.13.tar.bz2.sig" "…" …)
In unknown file:
2 (regexp-exec #<regexp 7f44b43e9600> #<eof> 0 #<undefined>)
In ice-9/boot-9.scm:
1685:16 1 (raise-exception _ #:continuable? _)
1685:16 0 (raise-exception _ #:continuable? _)

ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure regexp-exec: Wrong type argument in position 2 (expecting string): #<eof>

Using the '--open-tty' argument of xargs works around the issue:

Toggle snippet (24 lines)
$ echo alsa-plugins alsa-utils | xargs -o ./pre-inst-env guix refresh -u
gnu/packages/linux.scm:3195:2: warning: no updater for alsa-plugins

Starting download of /tmp/guix-file.OIHJYF
From https://www.alsa-project.org/files/pub/utils/alsa-utils-1.2.13.tar.bz2...
….2.13.tar.bz2 1.6MiB 1.0MiB/s 00:01 ???????????????????? 100.0%

Starting download of /tmp/guix-file.cTAkPz
From https://www.alsa-project.org/files/pub/utils/alsa-utils-1.2.13.tar.bz2.sig...
….13.tar.bz2.sig 833B 4.0MiB/s 00:00 ???????????????????? 100.0%
gpgv: Signature faite le mar. 12 nov. 2024 18:50:14 JST
gpgv: avec la clef RSA F04DF50737AC1A884C4B3D718380596DA6E59C91
gpgv: Impossible de vérifier la signature : Pas de clef publique
Would you like to add this key to keyring '/home/maxim/.config/guix/upstream/trustedkeys.kbx'?
y
gpg: clef 8380596DA6E59C91 : clef publique « ALSA Release Team (Package Signing Key v1) <release@alsa-project.org> » importée
gpg: Quantité totale traitée : 1
gpg: importées : 1
gpgv: Signature faite le mar. 12 nov. 2024 18:50:14 JST
gpgv: avec la clef RSA F04DF50737AC1A884C4B3D718380596DA6E59C91
gpgv: Bonne signature de « ALSA Release Team (Package Signing Key v1) <release@alsa-project.org> »
gnu/packages/linux.scm:3155:13: alsa-utils: updating from version 1.2.11 to version 1.2.13...

--
Thanks,
Maxim
M
M
Maxim Cournoyer wrote 3 days ago
[PATCH] gnupg: Automatically fallback to 'always policy when non-interactive.
(address . 76112@debbugs.gnu.org)(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
cc48d46b08ff0d35ecdc56a1868dae71edd8cdec.1738916949.git.maxim.cournoyer@gmail.com
Previously to this change, the 'guix refresh' download
policy (--key-download)would default to 'interactive', which would throw a
backtrace when guix was invoked with its stdin not connected to a peusdo
terminal (tty). This change makes the new default value 'auto' use
interactive only in an interactive environment, with 'always' used as
fallback.

* doc/guix.texi (Invoking guix refresh): Adjust doc.
* etc/completion/fish/guix.fish: Adjust accordingly.
* etc/completion/zsh/_guix (_guix_list_installed_packages): Likewise.
* guix/gnupg.scm (gnupg-verify*): Change default #:key-download argument value
to 'auto. Update doc. Validate argument. Raise an error in case read-line
returns #<eof>.
* guix/import/gnu.scm (gnu-package->sexp): <#:key-download>: Change default
value to 'auto.
* guix/import/gnu.scm (gnu->guix-package): <#:key-download>: Likewise.
* guix/scripts/import/gnu.scm (%options): Add "auto" to accepted
--key-download values.
(%default-options): Set default key-download option to the 'auto value.
(show-help): Update doc.
* guix/scripts/refresh.scm (show-help): Update doc.
(update-package) <#:key-download>: Change default value to 'auto. Update doc.
* guix/upstream.scm (download-tarball): <#:key-download>: Likewise.
(package-update): Likewise.

Change-Id: Id1ca8fd6d453ca4bc5b372534445e3beab9133a8
---
doc/guix.texi | 7 ++++++-
etc/completion/fish/guix.fish | 4 ++--
etc/completion/zsh/_guix | 2 +-
guix/gnupg.scm | 37 +++++++++++++++++++++++++++++------
guix/import/gnu.scm | 6 +++---
guix/scripts/import/gnu.scm | 8 ++++----
guix/scripts/refresh.scm | 13 ++++++------
guix/upstream.scm | 10 +++++-----
8 files changed, 59 insertions(+), 28 deletions(-)

Toggle diff (283 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 9f1e4bf0f0..c2c68d313b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -15321,7 +15321,12 @@ Invoking guix refresh
@item interactive
When a package signed with an unknown OpenPGP key is encountered, ask
-the user whether to download it or not. This is the default behavior.
+the user whether to download it or not.
+
+@item auto
+Automatically selects the @code{interactive} policy when the standard
+input is connected to a pseudo terminal (TTY), else @code{always}. This
+is the default behavior.
@end table
@item --key-server=@var{host}
diff --git a/etc/completion/fish/guix.fish b/etc/completion/fish/guix.fish
index e6c290256f..9e3b3211ea 100644
--- a/etc/completion/fish/guix.fish
+++ b/etc/completion/fish/guix.fish
@@ -284,7 +284,7 @@ complete -f -c guix -n '__fish_guix_using_command refresh' -l list-updaters -d '
complete -f -c guix -n '__fish_guix_using_command refresh' -l list-dependent -d 'list top-level dependent packages that would need to be rebuilt as a result of upgrading PACKAGE'
complete -f -c guix -n '__fish_guix_using_command refresh' -a "--key-server=" -d 'use HOST as the OpenPGP key server'
complete -f -c guix -n '__fish_guix_using_command refresh' -a "--gpg=" -d 'use COMMAND as the GnuPG 2.x command'
-complete -f -c guix -n '__fish_guix_using_command refresh' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY.' --exclusive --arguments "always never interactive"
+complete -f -c guix -n '__fish_guix_using_command refresh' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY.' --exclusive --arguments "always auto never interactive"
#### publish
set -l remotecommands port= listen= user= compression ttl= repl
@@ -321,7 +321,7 @@ set -l remotecommands import gnu nix pypi cpan hackage elpa gem cran crate texli
complete -f -c guix -n '__fish_guix_needs_command' -a import -d 'Run IMPORTER with ARGS'
##### import gnu
complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a gnu -d 'Return a package declaration template for PACKAGE, a GNU package.'
-complete -f -c guix -n '__fish_guix_using_command import; and __fish_seen_subcommand_from gnu' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY: "always", "never", and "interactive", which is also used when "key-download" is not specified.'
+complete -f -c guix -n '__fish_guix_using_command import; and __fish_seen_subcommand_from gnu' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY: "always", "auto", "never", and "interactive", which is also used when "key-download" is not specified.'
##### import pypi
complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a pypi -d 'Import and convert the PyPI package for PACKAGE-NAME.'
##### import cpan
diff --git a/etc/completion/zsh/_guix b/etc/completion/zsh/_guix
index 9b1f16c664..42b92475a9 100644
--- a/etc/completion/zsh/_guix
+++ b/etc/completion/zsh/_guix
@@ -507,7 +507,7 @@ _guix_list_installed_packages()
'--keyring=[use FILE as the keyring of upstream OpenPGP keys]:FILE:_files' \
'--key-server=[use HOST as the OpenPGP key server]:HOST_hosts' \
'--gpg=[use COMMAND as the GnuPG 2.x command]:COMMAND' \
- '--key-download=[handle missing OpenPGP keys according to POLICY:]:POLICY:(always interactive never)' \
+ '--key-download=[handle missing OpenPGP keys according to POLICY:]:POLICY:(always auto interactive never)' \
'--load-path=[prepend DIR to the package module search path]:DIR:_files -/' \
{-V,--version}'[display version information and exit]' \
'*:package:->packages'
diff --git a/guix/gnupg.scm b/guix/gnupg.scm
index 088bebc0de..ef9b71a2cb 100644
--- a/guix/gnupg.scm
+++ b/guix/gnupg.scm
@@ -2,7 +2,7 @@
;;; Copyright © 2010, 2011, 2013, 2014, 2016, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
-;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021, 2025 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -26,6 +26,8 @@ (define-module (guix gnupg)
#:use-module (ice-9 rdelim)
#:use-module (ice-9 i18n)
#:use-module (srfi srfi-1)
+ #:use-module ((srfi srfi-34) #:select (raise))
+ #:use-module (guix diagnostics)
#:use-module (guix i18n)
#:use-module ((guix utils) #:select (config-directory))
#:use-module ((guix build utils) #:select (mkdir-p))
@@ -201,7 +203,7 @@ (define* (gnupg-receive-keys fingerprint/key-id
(define* (gnupg-verify* sig file
#:key
- (key-download 'interactive)
+ (key-download 'auto)
server
(keyring (current-keyring)))
"Like `gnupg-verify', but try downloading the public key if it's missing.
@@ -210,9 +212,29 @@ (define* (gnupg-verify* sig file
'invalid-signature with a fingerprint if the signature is invalid.
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'always', 'never', and 'interactive' (default). Return a
+values: 'auto', 'always', 'never', and 'interactive' The default policy is
+auto, which automatically selects the interactive policy when a TTY is
+connected to the standard input, or the always policy otherwise. Return a
fingerprint/user name pair on success and #f otherwise."
- (let ((status (gnupg-verify sig file)))
+ (let* ((interactive? (isatty? (current-input-port)))
+ ;; Validate or compute (in the case of 'auto) the KEY-DOWNLOAD
+ ;; argument.
+ (key-download (match key-download
+ ('auto (if interactive?
+ 'interactive
+ 'always))
+ ('interactive
+ (unless interactive?
+ (raise (formatted-message
+ (G_ "cannot use interactive policy\
+ without TTY input")))))
+ ((or 'always 'never)
+ key-download)
+ (_
+ (raise (formatted-message
+ (G_ "invalid key-download policy: ~a")
+ key-download)))))
+ (status (gnupg-verify sig file)))
(match (gnupg-status-good-signature? status)
((fingerprint . user)
(values 'valid-signature (cons fingerprint user)))
@@ -236,7 +258,10 @@ (define* (gnupg-verify* sig file
(format #t (G_ "Would you like to add this key \
to keyring '~a'?~%")
keyring)
- (read-line))))
+ (match (read-line)
+ ((? eof-object?)
+ (error "read-line unexpectedly returned #<eof>"))
+ (other other)))))
(string-match (locale-yes-regexp) answer)))
(case key-download
@@ -244,7 +269,7 @@ (define* (gnupg-verify* sig file
(values 'missing-key missing))
((always)
(download-and-try-again))
- (else
+ (else ;interactive
(if (receive?)
(download-and-try-again)
(values 'missing-key missing)))))))))
diff --git a/guix/import/gnu.scm b/guix/import/gnu.scm
index fb61332fb8..e68dc06824 100644
--- a/guix/import/gnu.scm
+++ b/guix/import/gnu.scm
@@ -1,7 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com>
-;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021, 2025 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -54,7 +54,7 @@ (define (preferred-archive-type release)
'("xz" "lz" "bz2" "tbz2" "gz" "tgz" "Z")))
(define* (gnu-package->sexp package release
- #:key (key-download 'interactive))
+ #:key (key-download 'auto))
"Return the 'package' sexp for the RELEASE (a <gnu-release>) of PACKAGE (a
<gnu-package>), or #f upon failure. Use KEY-DOWNLOAD as the OpenPGP key
download policy (see 'download-tarball' for details.)"
@@ -106,7 +106,7 @@ (define* (gnu-package->sexp package release
#f))))
(define* (gnu->guix-package name
- #:key (key-download 'interactive)
+ #:key (key-download 'auto)
#:allow-other-keys)
"Return the package declaration for NAME as an s-expression. Use
KEY-DOWNLOAD as the OpenPGP key download policy (see 'download-tarball' for
diff --git a/guix/scripts/import/gnu.scm b/guix/scripts/import/gnu.scm
index 344e363abe..93ab6043c7 100644
--- a/guix/scripts/import/gnu.scm
+++ b/guix/scripts/import/gnu.scm
@@ -35,7 +35,7 @@ (define-module (guix scripts import gnu)
;;;
(define %default-options
- '((key-download . interactive)))
+ '((key-download . auto)))
(define (show-help)
(display (G_ "Usage: guix import gnu [OPTION...] PACKAGE
@@ -44,8 +44,8 @@ (define (show-help)
(display (G_ "
--key-download=POLICY
handle missing OpenPGP keys according to POLICY:
- 'always', 'never', and 'interactive', which is also
- used when 'key-download' is not specified"))
+ 'auto' (default), 'always', 'never', and
+ 'interactive'"))
(newline)
(display (G_ "
-h, --help display this help and exit"))
@@ -66,7 +66,7 @@ (define %options
(option '("key-download") #t #f ;from (guix scripts refresh)
(lambda (opt name arg result)
(match arg
- ((or "interactive" "always" "never")
+ ((or "auto" "interactive" "always" "never")
(alist-cons 'key-download (string->symbol arg)
result))
(x
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index 8c72d0c545..6532feef25 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -10,7 +10,7 @@
;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com>
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
-;;; Copyright © 2023 Maxim Cournoyer maxim.cournoyer@gmail.com>
+;;; Copyright © 2023, 2025 Maxim Cournoyer maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -193,8 +193,9 @@ (define (show-help)
(display (G_ "
--key-download=POLICY
handle missing OpenPGP keys according to POLICY:
- 'always', 'never', and 'interactive', which is also
- used when 'key-download' is not specified"))
+ 'auto', 'always', 'never', and 'interactive'.
+ When left unspecified, the default policy is 'auto',
+ which automatically selects interactive or always."))
(newline)
(display (G_ "
-L, --load-path=DIR prepend DIR to the package module search path"))
@@ -364,12 +365,12 @@ (define (warn-no-updater package)
(package-name package)))
(define* (update-package store package version updaters
- #:key (key-download 'interactive) key-server
+ #:key (key-download 'auto) key-server
warn?)
"Update the source file that defines PACKAGE with the new version.
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'interactive' (default), 'always', and 'never'. When WARN? is true,
-warn about packages that have no matching updater."
+values: 'auto' (default), interactive', 'always', and 'never'. When WARN? is
+true, warn about packages that have no matching updater."
(if (lookup-updater package updaters)
(let ((version output source
(package-update store package updaters
diff --git a/guix/upstream.scm b/guix/upstream.scm
index 62ba6c9d39..169d260c2d 100644
--- a/guix/upstream.scm
+++ b/guix/upstream.scm
@@ -314,14 +314,14 @@ (define (uncompressed-tarball name tarball)
#$output)))))
(define* (download-tarball store url signature-url
- #:key (key-download 'interactive) key-server)
+ #:key (key-download 'auto) key-server)
"Download the tarball at URL to the store; check its OpenPGP signature at
SIGNATURE-URL, unless SIGNATURE-URL is false. On success, return the tarball
file name; return #f on failure (network failure or authentication failure).
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'interactive' (default), 'always', and 'never'; KEY-SERVER specifies
-the OpenPGP key server where the key should be looked up."
+values: 'auto' (default), 'always', 'interactive' and 'never'; KEY-SERVER
+specifies the OpenPGP key server where the key should be looked up."
(let ((tarball (download-to-store store url)))
(if (not signature-url)
tarball
@@ -512,12 +512,12 @@ (define %method-updates
(define* (package-update store package
#:optional (updaters (force %updaters))
#:key (version #f)
- (key-download 'interactive) key-server)
+ (key-download 'auto) key-server)
"Return the new version, the file name of the new version tarball, and input
changes for PACKAGE; return #f (three values) when PACKAGE is up-to-date;
raise an error when the updater could not determine available releases.
KEY-DOWNLOAD specifies a download policy for missing OpenPGP keys; allowed
-values: 'always', 'never', and 'interactive' (default).
+values: 'always', 'auto' (default), 'never', and 'interactive'.
When VERSION is specified, update PACKAGE to that version, even if that is a
downgrade."

base-commit: 220ef58440668c39ddf7c6434c0fbfc82d3dd507
--
2.48.1
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send an email to 76112@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 76112
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch