From 0ac2a0fd1813fb5c04b22f6443d8f8a96d3c9645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Fri, 19 Dec 2025 09:34:47 +0100 Subject: [PATCH] authenticate: Report failure to load keys to the daemon. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, when failing to load a signing key, ‘guix authenticate’ would print a backtrace and exit with a non-zero code. That, in turn, would lead the guix-daemon child process to crash with: nix/libutil/serialise.cc:15: virtual nix::BufferedSink::~BufferedSink(): Assertion `!bufPos' failed. This patch fixes it by reporting the error to the daemon as was intended. * guix/scripts/authenticate.scm (guix-authenticate): Arrange to call ‘load-key-pair’ from within ‘with-reply’. * tests/guix-authenticate.sh: Test it. Fixes: guix/guix#4928 Reported-by: Rutherther Change-Id: I8654ad6fdfbe18c55e1e85647d0c49f408d0574a Signed-off-by: Ludovic Courtès Merges: #4961 --- guix/scripts/authenticate.scm | 33 ++++++++++++++++++--------------- tests/guix-authenticate.sh | 7 ++++++- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/guix/scripts/authenticate.scm b/guix/scripts/authenticate.scm index 48e76c61c8a..f90eeeec8de 100644 --- a/guix/scripts/authenticate.scm +++ b/guix/scripts/authenticate.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2020 Ludovic Courtès +;;; Copyright © 2013-2017, 2020, 2025 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -196,20 +196,23 @@ Sign data or verify signatures. This tool is meant to be used internally by ;; Read a request on standard input and reply. (match (read-command (current-input-port)) (("sign" signing-key (= base16-string->bytevector hash)) - (let* ((key-pairs keys - (match (vhash-assoc signing-key key-pairs) - ((_ . keys) - (values key-pairs keys)) - (#f - (let ((keys (load-key-pair signing-key))) - (values (vhash-cons signing-key keys - key-pairs) - keys)))))) - (with-reply (canonical-sexp->string - (match keys - ((public . secret) - (sign-with-key public secret hash))))) - (loop key-pairs))) + (let ((cached-keys (match (vhash-assoc signing-key key-pairs) + ((_ . keys) keys) + (#f #f))) + (new-keys #f)) + (with-reply (begin + (unless cached-keys + ;; Delay 'load-key-pair' call so that failure + ;; to load keys is reported via 'with-reply'. + (set! new-keys (load-key-pair signing-key))) + (canonical-sexp->string + (match (or cached-keys new-keys) + ((public . secret) + (sign-with-key public secret hash)))))) + (loop (if new-keys + (vhash-cons signing-key new-keys + key-pairs) + key-pairs)))) (("verify" signature) (with-reply (bytevector->base16-string (validate-signature diff --git a/tests/guix-authenticate.sh b/tests/guix-authenticate.sh index 0de6da18784..ddd39d09c44 100644 --- a/tests/guix-authenticate.sh +++ b/tests/guix-authenticate.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2013, 2014, 2020 Ludovic Courtès +# Copyright © 2013, 2014, 2020, 2025 Ludovic Courtès # # This file is part of GNU Guix. # @@ -85,3 +85,8 @@ sed -i "$sig" -e's/^0 //g' echo "verify $(cat $sig)" | guix authenticate hash2="$(echo "verify $(cat $sig)" | guix authenticate | cut -f2 -d ' ')" test "$(echo $hash2 | cut -d : -f 2)" = "$hash" + +# Make sure an error is properly reported for unreadable key pairs, with exit +# code zero (the process would keep running commands on standard input). +echo "sign 9:/dev/null $hash_len:$hash" | guix authenticate +test $(echo "sign 9:/dev/null $hash_len:$hash" | guix authenticate | cut -f1 -d ' ') = 500