From b6bee63bed4f013064c0d902e7c8b83ed7514ade Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 23 Feb 2020 00:20:30 +0100 Subject: gnu: Default to Guile 3.0. This patch changes three things: 1. package derivations are built using Guile 3.0; 2. 'gexp->derivation' defaults to Guile 3.0; 3. "guile3.0-" packages are deprecated aliases for the regular package, which now depends on Guile 3.0; "guile2.2-" packages are introduced; "guile-next" is renamed to "guile". * gnu/packages/guile.scm (guile-2.0/fixed): Remove. (guile-3.0/fixed): New variable. (package-for-guile-3.0): Remove. (package-for-guile-2.2): New variable. (define-deprecated-guile3.0-package): New macro. (guile-3.0)[name]: Change to "guile". (guile-json-3)[native-inputs, inputs]: New fields. (guile2.2-json): New variable. (guile3.0-json): Deprecate. (guile-gdbm-ffi)[native-inputs]: Switch to GUILE-3.0. (guile2.2-gdbm-ffi): New variable. (guile3.0-gdbm-ffi): Deprecate. (guile-sqlite3): Switch to GUILE-3.0. (guile2.2-sqlite3): New variable. (guile3.0-sqlite3): Deprecate. (guile-bytestructures): Switch to GUILE-3.0. (guile2.2-bytestructures): New variable. (guile3.0-bytestructures): Deprecate. (guile-git): Switch to GUILE-3.0. (guile2.2-git): New variable. (guile3.0-git): Deprecate. (guile-2.2/bug-fix): * gnu/packages/ci.scm (cuirass): Switch to GUILE-3.0. * gnu/packages/emacs-xyz.scm (emacs-guix): Switch to GUILE-3.0. * gnu/packages/gtk.scm (guile-cairo)[arguments]: New field. Switch to GUILE-3.0. (guile2.2-cairo): New variable. (guile3.0-cairo): Deprecate. (guile-rsvg): Switch to GUILE-3.0. (guile2.2-cairo): New variable. (guile3.0-cairo): Deprecate. (guile-present): Switch to GUILE-3.0. (guile2.2-present): New variable. (guile3.0-present): Deprecate. (guile-gnome)[propagated-inputs]: Use GUILE2.2-CAIRO and GUILE2.2-LIB. * gnu/packages/guile-xyz.scm (guile-fibers)[arguments]: Add #:configure-flags. Switch to GUILE-3.0. (guile2.2-fibers): New variable. (guile3.0-fibers): Deprecate. (guile-syntax-highlight): Switch to GUILE-3.0. (guile2.2-syntax-highlight): New variable. (guile3.0-syntax-highlight): Deprecate. (guile-colorized): Switch to GUILE-3.0. (guile2.2-colorized): New variable. (guile3.0-colorized): Deprecate. (guile-pfds): Switch to GUILE-3.0. (guile2.2-pfds): New variable. (guile3.0-pfds): Deprecate. (guile-simple-zmq): Switch to GUILE-3.0. (guile2.2-simple-zmq): New variable. (guile3.0-simple-zmq): Deprecate. (guile-newt): Switch to GUILE-3.0. (guile2.2-newt): New variable. (guile3.0-newt): Deprecate. (guile-parted): Switch to GUILE-3.0. (guile2.2-parted): New variable. (guile3.0-parted): Deprecate. (guile-config): Switch to GUILE-3.0. (guile2.2-config): New variable. (guile3.0-config): Deprecate. (guile-hall): Switch to GUILE-3.0. (guile2.2-hall): New variable. (guile3.0-hall): Deprecate. (guile-ics): Switch to GUILE-3.0. (guile2.2-ics): New variable. (guile3.0-ics): Deprecate. (guile-wisp)[arguments]: Add 'support-guile-3.0' phase. Switch to GUILE-3.0. (guile2.2-wisp): New variable. (guile3.0-wisp): Deprecate. (guile-lib): Switch to GUILE-3.0. (guile2.2-lib): New variable. (guile3.0-lib): Deprecate. (guile-minikanren): Switch to GUILE-3.0. (guile2.2-minikanren): New variable. (guile3.0-minikanren): Deprecate. (guile-irregex): Switch to GUILE-3.0. (guile2.2-irregex): New variable. (guile3.0-irregex): Deprecate. (haunt): Switch to GUILE-3.0, and remove GUILE-READER. (guile2.2-haunt): New variable. (guile3.0-haunt): Deprecate. (guile-commonmark): Switch to GUILE-3.0. (guile2.2-commonmark): New variable. (guile3.0-commonmark): Deprecate. (mcron): Switch to GUILE-3.0. (guile2.0-mcron): New variable. (guile3.0-mcron): Deprecate. (guile-picture-language): Switch to GUILE-3.0. (guile2.2-picture-language): New variable. (guile3.0-picture-language): Deprecate. (guile-gi): Switch to GUILE-3.0. (guile2.2-gi): New variable. (guile3.0-gi): Deprecate. (guile-hashing): Switch to GUILE-3.0. (guile2.2-hashing): New variable. (guile3.0-hashing): Deprecate. * gnu/packages/package-management.scm (guix): Switch to GUILE-3.0. (guile2.2-guix): New variable. (guile3.0-guix): Deprecate. (gwl): Replace "guile3.0-" with "guile-". (guix-jupyter)[source]: Adjust for Guile 3.0. Switch to GUILE-3.0. * gnu/packages/ssh.scm (guile-ssh): Switch to GUILE-3.0. (guile2.2-ssh): New variable. (guile3.0-ssh): Deprecate. * gnu/packages/admin.scm (shepherd): Switch to GUILE-3.0. (guile2.2-shepherd): New variable. (guile3.0-shepherd): Deprecate. * gnu/packages/mail.scm (mailutils): Switch to GUILE-3.0. (guile2.2-mailutils): New variable. (guile3.0-mailutils): Deprecate. * gnu/packages/plotutils.scm (guile-charting): Switch to GUILE-3.0. (guile2.2-charting): New variable. (guile3.0-charting): Deprecate. * gnu/packages/version-control.scm (libgit2): Switch to GUILE-3.0. * gnu/packages/vpn.scm (vpnc-scripts): Switch to GUILE-3.0. * gnu/packages/web.scm (guix-data-service): Switch to GUILE-3.0. (hpcguix-web): Switch to GUILE-3.0. * guix/self.scm (specification->package): Refer to the "guile-" variants instead of "guile3.0-". * guix/gexp.scm (default-guile): Change to GUILE-3.0. * build-aux/build-self.scm (build): #:guile-version defaults to "3.0". * gnu/packages/commencement.scm (guile-final): Base on GUILE-3.0/FIXED. --- build-aux/build-self.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'build-aux') diff --git a/build-aux/build-self.scm b/build-aux/build-self.scm index f2e785b7f1..b30adfeb9f 100644 --- a/build-aux/build-self.scm +++ b/build-aux/build-self.scm @@ -383,11 +383,11 @@ interface (FFI) of Guile.") #:key verbose? (version (date-version-string)) system (pull-version 0) - ;; For the standalone Guix, default to Guile 2.2. For old + ;; For the standalone Guix, default to Guile 3.0. For old ;; versions of 'guix pull' (pre-0.15.0), we have to use the ;; same Guile as the current one. (guile-version (if (> pull-version 0) - "2.2" + "3.0" (effective-version))) #:allow-other-keys -- cgit v1.2.3 From 051a45e642ff21908375bee24d272c536096d026 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 30 Apr 2020 16:39:44 +0200 Subject: git-authenticate: Use (guix openpgp). It can now authenticate 14K+ commits in 23s instead of 4mn20. * build-aux/git-authenticate.scm (%authorized-signing-keys): Turn fingerprints into bytevectors. (with-temporary-files): Remove. (commit-signing-key): Add 'keyring' parameter. Use 'string->openpgp-packet' and 'verify-openpgp-signature' instead of (guix gnupg) procedures. (authenticate-commit): Add 'keyring' parameter. Pass it to 'commit-signing-key'. Adjust to SIGNING-KEY being an . (authenticate-commits): Remove 'parameterize'. Load keyring with 'get-openpgp-keyring'. (git-authenticate): When printing stats, adjust to SIGNER being an . --- build-aux/git-authenticate.scm | 131 +++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 69 deletions(-) (limited to 'build-aux') diff --git a/build-aux/git-authenticate.scm b/build-aux/git-authenticate.scm index bb48dddc59..0d5eb4caa9 100644 --- a/build-aux/git-authenticate.scm +++ b/build-aux/git-authenticate.scm @@ -23,8 +23,9 @@ (use-modules (git) (guix git) - (guix gnupg) - (guix utils) + (guix openpgp) + ((guix utils) #:select (config-directory)) + (guix base16) ((guix build utils) #:select (mkdir-p)) (guix i18n) (guix progress) @@ -215,7 +216,8 @@ ;; Fingerprint of authorized signing keys. (map (match-lambda ((name fingerprint) - (string-filter char-set:graphic fingerprint))) + (base16-string->bytevector + (string-downcase (string-filter char-set:graphic fingerprint))))) %committers)) (define %commits-with-bad-signature @@ -226,75 +228,63 @@ ;; Commits lacking a signature. '()) -(define-syntax-rule (with-temporary-files file1 file2 exp ...) - (call-with-temporary-output-file - (lambda (file1 port1) - (call-with-temporary-output-file - (lambda (file2 port2) - exp ...))))) - -(define (commit-signing-key repo commit-id) - "Return the OpenPGP key ID that signed COMMIT-ID (an OID). Raise an -exception if the commit is unsigned or has an invalid signature." +(define (commit-signing-key repo commit-id keyring) + "Return the OpenPGP key that signed COMMIT-ID (an OID). Raise an exception +if the commit is unsigned, has an invalid signature, or if its signing key is +not in KEYRING." (let-values (((signature signed-data) (catch 'git-error (lambda () (commit-extract-signature repo commit-id)) (lambda _ (values #f #f))))) - (if (not signature) - (raise (condition - (&message - (message (format #f (G_ "commit ~a lacks a signature") - commit-id))))) - (begin - (with-fluids ((%default-port-encoding "UTF-8")) - (with-temporary-files data-file signature-file - (call-with-output-file data-file - (cut display signed-data <>)) - (call-with-output-file signature-file - (cut display signature <>)) - - (let-values (((status data) - (with-error-to-port (%make-void-port "w") - (lambda () - (gnupg-verify* signature-file data-file - #:key-download 'always))))) - (match status - ('invalid-signature - ;; There's a signature but it's invalid. - (raise (condition - (&message - (message (format #f (G_ "signature verification failed \ + (unless signature + (raise (condition + (&message + (message (format #f (G_ "commit ~a lacks a signature") + commit-id)))))) + + (let ((signature (string->openpgp-packet signature))) + (with-fluids ((%default-port-encoding "UTF-8")) + (let-values (((status data) + (verify-openpgp-signature signature keyring + (open-input-string signed-data)))) + (match status + ('bad-signature + ;; There's a signature but it's invalid. + (raise (condition + (&message + (message (format #f (G_ "signature verification failed \ for commit ~a") - (oid->string commit-id))))))) - ('missing-key - (raise (condition - (&message - (message (format #f (G_ "could not authenticate \ + (oid->string commit-id))))))) + ('missing-key + (raise (condition + (&message + (message (format #f (G_ "could not authenticate \ commit ~a: key ~a is missing") - (oid->string commit-id) - data)))))) - ('valid-signature - (match data - ((fingerprint . user) - fingerprint))))))))))) - -(define (authenticate-commit repository commit) + (oid->string commit-id) + data)))))) + ('good-signature data))))))) + +(define (authenticate-commit repository commit keyring) "Authenticate COMMIT from REPOSITORY and return the signing key fingerprint. Raise an error when authentication fails." (define id (commit-id commit)) (define signing-key - (commit-signing-key repository id)) + (commit-signing-key repository id keyring)) - (unless (member signing-key %authorized-signing-keys) + (unless (member (openpgp-public-key-fingerprint signing-key) + %authorized-signing-keys) (raise (condition (&message (message (format #f (G_ "commit ~a not signed by an authorized \ key: ~a") - (oid->string id) signing-key)))))) + (oid->string id) + (openpgp-format-fingerprint + (openpgp-public-key-fingerprint + signing-key)))))))) signing-key) @@ -302,17 +292,21 @@ key: ~a") #:key (report-progress (const #t))) "Authenticate COMMITS, a list of commit objects, calling REPORT-PROGRESS for each of them. Return an alist showing the number of occurrences of each key." - (parameterize ((current-keyring (string-append (config-directory) - "/keyrings/channels/guix.kbx"))) - (fold (lambda (commit stats) - (report-progress) - (let ((signer (authenticate-commit repository commit))) - (match (assoc signer stats) - (#f (cons `(,signer . 1) stats)) - ((_ . count) (cons `(,signer . ,(+ count 1)) - (alist-delete signer stats)))))) - '() - commits))) + (define keyring-file + (string-append (config-directory) "/keyrings/channels/guix.kbx")) + + (define keyring + (call-with-input-file keyring-file get-openpgp-keyring)) + + (fold (lambda (commit stats) + (report-progress) + (let ((signer (authenticate-commit repository commit keyring))) + (match (assq signer stats) + (#f (cons `(,signer . 1) stats)) + ((_ . count) (cons `(,signer . ,(+ count 1)) + (alist-delete signer stats)))))) + '() + commits)) (define commit-short-id (compose (cut string-take <> 7) oid->string commit-id)) @@ -409,7 +403,10 @@ COMMIT-ID is written to cache, though)." (format #t (G_ "Signing statistics:~%")) (for-each (match-lambda ((signer . count) - (format #t " ~a ~10d~%" signer count))) + (format #t " ~a ~10d~%" + (openpgp-format-fingerprint + (openpgp-public-key-fingerprint signer)) + count))) (sort stats (match-lambda* (((_ . count1) (_ . count2)) @@ -423,7 +420,3 @@ COMMIT-ID is written to cache, though)." (G_ "Usage: git-authenticate START [END] Authenticate commits START to END or the current head.\n")))))) - -;;; Local Variables: -;;; eval: (put 'with-temporary-files 'scheme-indent-function 2) -;;; End: -- cgit v1.2.3 From 92db1036b7d3ad12548c81450a31e401b4c4f2b5 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 1 May 2020 16:30:41 +0200 Subject: git-authenticate: Load the list of authorized keys from the tree. * build-aux/git-authenticate.scm (read-authorizations) (commit-authorized-keys): New procedures. (authenticate-commit): Use it instead of %AUTHORIZED-SIGNING-KEYS. --- build-aux/git-authenticate.scm | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'build-aux') diff --git a/build-aux/git-authenticate.scm b/build-aux/git-authenticate.scm index 0d5eb4caa9..fc02f9ef66 100644 --- a/build-aux/git-authenticate.scm +++ b/build-aux/git-authenticate.scm @@ -34,6 +34,7 @@ (srfi srfi-26) (srfi srfi-34) (srfi srfi-35) + (rnrs bytevectors) (rnrs io ports) (ice-9 match) (ice-9 format) @@ -266,6 +267,39 @@ commit ~a: key ~a is missing") data)))))) ('good-signature data))))))) +(define (read-authorizations port) + "Read authorizations in the '.guix-authorizations' format from PORT, and +return a list of authorized fingerprints." + (match (read port) + (('authorizations ('version 0) + (((? string? fingerprints) _ ...) ...) + _ ...) + (map (lambda (fingerprint) + (base16-string->bytevector + (string-downcase (string-filter char-set:graphic fingerprint)))) + fingerprints)))) + +(define* (commit-authorized-keys repository commit + #:optional (default-authorizations '())) + "Return the list of OpenPGP fingerprints authorized to sign COMMIT, based on +authorizations listed in its parent commits. If one of the parent commits +does not specify anything, fall back to DEFAULT-AUTHORIZATIONS." + (define (commit-authorizations commit) + (catch 'git-error + (lambda () + (let* ((tree (commit-tree commit)) + (entry (tree-entry-bypath tree ".guix-authorizations")) + (blob (blob-lookup repository (tree-entry-id entry)))) + (read-authorizations + (open-bytevector-input-port (blob-content blob))))) + (lambda (key error) + (if (= (git-error-code error) GIT_ENOTFOUND) + default-authorizations + (throw key error))))) + + (apply lset-intersection bytevector=? + (map commit-authorizations (commit-parents commit)))) + (define (authenticate-commit repository commit keyring) "Authenticate COMMIT from REPOSITORY and return the signing key fingerprint. Raise an error when authentication fails." @@ -276,7 +310,8 @@ Raise an error when authentication fails." (commit-signing-key repository id keyring)) (unless (member (openpgp-public-key-fingerprint signing-key) - %authorized-signing-keys) + (commit-authorized-keys repository commit + %authorized-signing-keys)) (raise (condition (&message (message (format #f (G_ "commit ~a not signed by an authorized \ -- cgit v1.2.3 From 041dc3a9c0694ada41b86115b9774a23c9d50f73 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 1 May 2020 18:27:21 +0200 Subject: git-authenticate: Load the keyring from the repository. * build-aux/git-authenticate.scm (load-keyring-from-blob) (load-keyring-from-reference): New procedures. (authenticate-commits): Add #:keyring-reference and use 'load-keyring-from-reference'. --- build-aux/git-authenticate.scm | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'build-aux') diff --git a/build-aux/git-authenticate.scm b/build-aux/git-authenticate.scm index fc02f9ef66..632471ac74 100644 --- a/build-aux/git-authenticate.scm +++ b/build-aux/git-authenticate.scm @@ -24,7 +24,6 @@ (use-modules (git) (guix git) (guix openpgp) - ((guix utils) #:select (config-directory)) (guix base16) ((guix build utils) #:select (mkdir-p)) (guix i18n) @@ -323,15 +322,42 @@ key: ~a") signing-key) +(define (load-keyring-from-blob repository oid keyring) + "Augment KEYRING with the keyring available in the blob at OID, which may or +may not be ASCII-armored." + (let* ((blob (blob-lookup repository oid)) + (port (open-bytevector-input-port (blob-content blob)))) + (get-openpgp-keyring (if (port-ascii-armored? port) + (open-bytevector-input-port (read-radix-64 port)) + port) + keyring))) + +(define (load-keyring-from-reference repository reference) + "Load the '.key' files from the tree at REFERENCE in REPOSITORY and return +an OpenPGP keyring." + (let* ((reference (reference-lookup repository reference)) + (target (reference-target reference)) + (commit (commit-lookup repository target)) + (tree (commit-tree commit))) + (fold (lambda (name keyring) + (if (string-suffix? ".key" name) + (let ((entry (tree-entry-bypath tree name))) + (load-keyring-from-blob repository + (tree-entry-id entry) + keyring)) + keyring)) + %empty-keyring + (tree-list tree)))) + (define* (authenticate-commits repository commits - #:key (report-progress (const #t))) + #:key + (keyring-reference "refs/heads/keyring") + (report-progress (const #t))) "Authenticate COMMITS, a list of commit objects, calling REPORT-PROGRESS for -each of them. Return an alist showing the number of occurrences of each key." - (define keyring-file - (string-append (config-directory) "/keyrings/channels/guix.kbx")) - +each of them. Return an alist showing the number of occurrences of each key. +The OpenPGP keyring is loaded from KEYRING-REFERENCE in REPOSITORY." (define keyring - (call-with-input-file keyring-file get-openpgp-keyring)) + (load-keyring-from-reference repository keyring-reference)) (fold (lambda (commit stats) (report-progress) -- cgit v1.2.3 From aea6ab2f4ca060e68f8539cd612b0ce088627557 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Mon, 4 May 2020 11:08:42 +0200 Subject: git-authenticate: Add missing import. * build-aux/git-authenticate.scm: Import (guix utils), used by the cache handling code and inadvertently removed in 041dc3a9c0694ada41b86115b9774a23c9d50f73. --- build-aux/git-authenticate.scm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'build-aux') diff --git a/build-aux/git-authenticate.scm b/build-aux/git-authenticate.scm index 632471ac74..7bb3af6ecb 100644 --- a/build-aux/git-authenticate.scm +++ b/build-aux/git-authenticate.scm @@ -25,6 +25,8 @@ (guix git) (guix openpgp) (guix base16) + ((guix utils) + #:select (cache-directory with-atomic-file-output)) ((guix build utils) #:select (mkdir-p)) (guix i18n) (guix progress) -- cgit v1.2.3 From 8d65a71e5fb21303df8628f89e84d2684738f145 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 7 May 2020 11:52:23 +0200 Subject: git-authenticate: Use the 'origin/keyring' branch by default. Previously one would need to have a worktree for the local 'keyring' branch. Reported by reepca and bricewge on #guix. * build-aux/git-authenticate.scm (load-keyring-from-reference): Use 'branch-lookup' instead of 'reference-lookup'. Add "origin/" to REFERENCE. (authenticate-commits): Have #:keyring-reference default to "keyring". --- build-aux/git-authenticate.scm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'build-aux') diff --git a/build-aux/git-authenticate.scm b/build-aux/git-authenticate.scm index 7bb3af6ecb..ab50459369 100644 --- a/build-aux/git-authenticate.scm +++ b/build-aux/git-authenticate.scm @@ -337,7 +337,9 @@ may not be ASCII-armored." (define (load-keyring-from-reference repository reference) "Load the '.key' files from the tree at REFERENCE in REPOSITORY and return an OpenPGP keyring." - (let* ((reference (reference-lookup repository reference)) + (let* ((reference (branch-lookup repository + (string-append "origin/" reference) + BRANCH-REMOTE)) (target (reference-target reference)) (commit (commit-lookup repository target)) (tree (commit-tree commit))) @@ -353,7 +355,7 @@ an OpenPGP keyring." (define* (authenticate-commits repository commits #:key - (keyring-reference "refs/heads/keyring") + (keyring-reference "keyring") (report-progress (const #t))) "Authenticate COMMITS, a list of commit objects, calling REPORT-PROGRESS for each of them. Return an alist showing the number of occurrences of each key. -- cgit v1.2.3