gnupg: Use 'gpgv' and keybox files; adjust 'guix refresh' accordingly.
* guix/gnupg.scm (%gpgv-command, current-keyring): New variables (gnupg-verify): Add optional 'keyring' parameter. Use 'gpgv' instead of 'gpg' and pass it '--keyring'. (gnupg-receive-keys): Add optional 'keyring' parameter and honor it. (gnupg-verify*): Add #:keyring and honor it. * guix/scripts/refresh.scm (%options, show-help): Add '--keyring'. (guix-refresh): Parameterize CURRENT-KEYRING. * doc/guix.texi (Invoking guix refresh): Document '--keyring' and the keybox format.
This commit is contained in:
parent
3c0e16391e
commit
b9e1fddfd8
|
@ -7268,6 +7268,36 @@ The following options can be used to customize GnuPG operation:
|
||||||
Use @var{command} as the GnuPG 2.x command. @var{command} is searched
|
Use @var{command} as the GnuPG 2.x command. @var{command} is searched
|
||||||
for in @code{$PATH}.
|
for in @code{$PATH}.
|
||||||
|
|
||||||
|
@item --keyring=@var{file}
|
||||||
|
Use @var{file} as the keyring for upstream keys. @var{file} must be in the
|
||||||
|
@dfn{keybox format}. Keybox files usually have a name ending in @file{.kbx}
|
||||||
|
and the GNU@tie{}Privacy Guard (GPG) can manipulate these files
|
||||||
|
(@pxref{kbxutil, @command{kbxutil},, gnupg, Using the GNU Privacy Guard}, for
|
||||||
|
information on a tool to manipulate keybox files).
|
||||||
|
|
||||||
|
When this option is omitted, @command{guix refresh} uses
|
||||||
|
@file{~/.config/guix/upstream/trustedkeys.kbx} as the keyring for upstream
|
||||||
|
signing keys. OpenPGP signatures are checked against keys from this keyring;
|
||||||
|
missing keys are downloaded to this keyring as well (see
|
||||||
|
@option{--key-download} below.)
|
||||||
|
|
||||||
|
You can export keys from your default GPG keyring into a keybox file using
|
||||||
|
commands like this one:
|
||||||
|
|
||||||
|
@example
|
||||||
|
gpg --export rms@@gnu.org | kbxutil --import-openpgp >> mykeyring.kbx
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Likewise, you can fetch keys to a specific keybox file like this:
|
||||||
|
|
||||||
|
@example
|
||||||
|
gpg --no-default-keyring --keyring mykeyring.kbx \
|
||||||
|
--recv-keys @value{OPENPGP-SIGNING-KEY-ID}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@ref{GPG Configuration Options, @option{--keyring},, gnupg, Using the GNU
|
||||||
|
Privacy Guard}, for more information on GPG's @option{--keyring} option.
|
||||||
|
|
||||||
@item --key-download=@var{policy}
|
@item --key-download=@var{policy}
|
||||||
Handle missing OpenPGP keys according to @var{policy}, which may be one
|
Handle missing OpenPGP keys according to @var{policy}, which may be one
|
||||||
of:
|
of:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2010, 2011, 2013, 2014, 2016 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2010, 2011, 2013, 2014, 2016, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
|
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
|
@ -24,9 +24,12 @@
|
||||||
#:use-module (ice-9 rdelim)
|
#:use-module (ice-9 rdelim)
|
||||||
#:use-module (ice-9 i18n)
|
#:use-module (ice-9 i18n)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (guix ui)
|
#:use-module (guix i18n)
|
||||||
|
#:use-module ((guix utils) #:select (config-directory))
|
||||||
|
#:use-module ((guix build utils) #:select (mkdir-p))
|
||||||
#:export (%gpg-command
|
#:export (%gpg-command
|
||||||
%openpgp-key-server
|
%openpgp-key-server
|
||||||
|
current-keyring
|
||||||
gnupg-verify
|
gnupg-verify
|
||||||
gnupg-verify*
|
gnupg-verify*
|
||||||
gnupg-status-good-signature?
|
gnupg-status-good-signature?
|
||||||
|
@ -42,13 +45,25 @@
|
||||||
;; The GnuPG 2.x command-line program name.
|
;; The GnuPG 2.x command-line program name.
|
||||||
(make-parameter (or (getenv "GUIX_GPG_COMMAND") "gpg")))
|
(make-parameter (or (getenv "GUIX_GPG_COMMAND") "gpg")))
|
||||||
|
|
||||||
|
(define %gpgv-command
|
||||||
|
;; The 'gpgv' program.
|
||||||
|
(make-parameter (or (getenv "GUIX_GPGV_COMMAND") "gpgv")))
|
||||||
|
|
||||||
|
(define current-keyring
|
||||||
|
;; The default keyring of "trusted keys".
|
||||||
|
(make-parameter (string-append (config-directory #:ensure? #f)
|
||||||
|
"/gpg/trustedkeys.kbx")))
|
||||||
|
|
||||||
(define %openpgp-key-server
|
(define %openpgp-key-server
|
||||||
;; The default key server. Note that keys.gnupg.net appears to be
|
;; The default key server. Note that keys.gnupg.net appears to be
|
||||||
;; unreliable.
|
;; unreliable.
|
||||||
(make-parameter "pgp.mit.edu"))
|
(make-parameter "pgp.mit.edu"))
|
||||||
|
|
||||||
(define (gnupg-verify sig file)
|
(define* (gnupg-verify sig file
|
||||||
"Verify signature SIG for FILE. Return a status s-exp if GnuPG failed."
|
#:optional (keyring (current-keyring)))
|
||||||
|
"Verify signature SIG for FILE against the keys in KEYRING. All the keys in
|
||||||
|
KEYRING as assumed to be \"trusted\", whether or not they expired or were
|
||||||
|
revoked. Return a status s-exp if GnuPG failed."
|
||||||
|
|
||||||
(define (status-line->sexp line)
|
(define (status-line->sexp line)
|
||||||
;; See file `doc/DETAILS' in GnuPG.
|
;; See file `doc/DETAILS' in GnuPG.
|
||||||
|
@ -117,8 +132,8 @@
|
||||||
(loop (read-line input)
|
(loop (read-line input)
|
||||||
(cons (status-line->sexp line) result)))))
|
(cons (status-line->sexp line) result)))))
|
||||||
|
|
||||||
(let* ((pipe (open-pipe* OPEN_READ (%gpg-command) "--status-fd=1"
|
(let* ((pipe (open-pipe* OPEN_READ (%gpgv-command) "--status-fd=1"
|
||||||
"--verify" sig file))
|
"--keyring" keyring sig file))
|
||||||
(status (parse-status pipe)))
|
(status (parse-status pipe)))
|
||||||
;; Ignore PIPE's exit status since STATUS above should contain all the
|
;; Ignore PIPE's exit status since STATUS above should contain all the
|
||||||
;; info we need.
|
;; info we need.
|
||||||
|
@ -145,12 +160,21 @@ missing key."
|
||||||
(_ #f)))
|
(_ #f)))
|
||||||
status))
|
status))
|
||||||
|
|
||||||
(define (gnupg-receive-keys key-id server)
|
(define* (gnupg-receive-keys key-id server
|
||||||
(system* (%gpg-command) "--keyserver" server "--recv-keys" key-id))
|
#:optional (keyring (current-keyring)))
|
||||||
|
(unless (file-exists? keyring)
|
||||||
|
(mkdir-p (dirname keyring))
|
||||||
|
(call-with-output-file keyring (const #t))) ;create an empty keybox
|
||||||
|
|
||||||
|
(system* (%gpg-command) "--keyserver" server
|
||||||
|
"--no-default-keyring" "--keyring" keyring
|
||||||
|
"--recv-keys" key-id))
|
||||||
|
|
||||||
(define* (gnupg-verify* sig file
|
(define* (gnupg-verify* sig file
|
||||||
#:key (key-download 'interactive)
|
#:key
|
||||||
(server (%openpgp-key-server)))
|
(key-download 'interactive)
|
||||||
|
(server (%openpgp-key-server))
|
||||||
|
(keyring (current-keyring)))
|
||||||
"Like `gnupg-verify', but try downloading the public key if it's missing.
|
"Like `gnupg-verify', but try downloading the public key if it's missing.
|
||||||
Return #t if the signature was good, #f otherwise. KEY-DOWNLOAD specifies a
|
Return #t if the signature was good, #f otherwise. KEY-DOWNLOAD specifies a
|
||||||
download policy for missing OpenPGP keys; allowed values: 'always', 'never',
|
download policy for missing OpenPGP keys; allowed values: 'always', 'never',
|
||||||
|
@ -161,15 +185,17 @@ and 'interactive' (default)."
|
||||||
(define (download-and-try-again)
|
(define (download-and-try-again)
|
||||||
;; Download the missing key and try again.
|
;; Download the missing key and try again.
|
||||||
(begin
|
(begin
|
||||||
(gnupg-receive-keys missing server)
|
(gnupg-receive-keys missing server keyring)
|
||||||
(gnupg-status-good-signature? (gnupg-verify sig file))))
|
(gnupg-status-good-signature? (gnupg-verify sig file
|
||||||
|
keyring))))
|
||||||
|
|
||||||
(define (receive?)
|
(define (receive?)
|
||||||
(let ((answer
|
(let ((answer
|
||||||
(begin (format #t (G_ "~a~a~%")
|
(begin
|
||||||
"Would you like to download this key "
|
(format #t (G_ "Would you like to add this key \
|
||||||
"and add it to your keyring?")
|
to keyring '~a'?~%")
|
||||||
(read-line))))
|
keyring)
|
||||||
|
(read-line))))
|
||||||
(string-match (locale-yes-regexp) answer)))
|
(string-match (locale-yes-regexp) answer)))
|
||||||
|
|
||||||
(and missing
|
(and missing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
|
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
|
||||||
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
|
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
|
||||||
;;; Copyright © 2015 Alex Kost <alezost@gmail.com>
|
;;; Copyright © 2015 Alex Kost <alezost@gmail.com>
|
||||||
|
@ -89,6 +89,9 @@
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'list-dependent? #t result)))
|
(alist-cons 'list-dependent? #t result)))
|
||||||
|
|
||||||
|
(option '("keyring") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'keyring arg result)))
|
||||||
(option '("key-server") #t #f
|
(option '("key-server") #t #f
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'key-server arg result)))
|
(alist-cons 'key-server arg result)))
|
||||||
|
@ -138,6 +141,8 @@ specified with `--select'.\n"))
|
||||||
-l, --list-dependent list top-level dependent packages that would need to
|
-l, --list-dependent list top-level dependent packages that would need to
|
||||||
be rebuilt as a result of upgrading PACKAGE..."))
|
be rebuilt as a result of upgrading PACKAGE..."))
|
||||||
(newline)
|
(newline)
|
||||||
|
(display (G_ "
|
||||||
|
--keyring=FILE use FILE as the keyring of upstream OpenPGP keys"))
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
--key-server=HOST use HOST as the OpenPGP key server"))
|
--key-server=HOST use HOST as the OpenPGP key server"))
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
|
@ -437,7 +442,11 @@ update would trigger a complete rebuild."
|
||||||
(%openpgp-key-server)))
|
(%openpgp-key-server)))
|
||||||
(%gpg-command
|
(%gpg-command
|
||||||
(or (assoc-ref opts 'gpg-command)
|
(or (assoc-ref opts 'gpg-command)
|
||||||
(%gpg-command))))
|
(%gpg-command)))
|
||||||
|
(current-keyring
|
||||||
|
(or (assoc-ref opts 'keyring)
|
||||||
|
(string-append (config-directory)
|
||||||
|
"/upstream/trustedkeys.kbx"))))
|
||||||
(for-each
|
(for-each
|
||||||
(cut update-package store <> updaters
|
(cut update-package store <> updaters
|
||||||
#:key-download key-download
|
#:key-download key-download
|
||||||
|
|
Loading…
Reference in New Issue