2014-03-28 19:06:41 -04:00
|
|
|
|
;;; GNU Guix --- Functional package management for GNU
|
|
|
|
|
;;; Copyright © 2014 Nikita Karetnikov <nikita@karetnikov.org>
|
2023-06-08 16:43:05 -04:00
|
|
|
|
;;; Copyright © 2014-2015, 2017-2019, 2021-2023 Ludovic Courtès <ludo@gnu.org>
|
2014-03-28 19:06:41 -04:00
|
|
|
|
;;;
|
|
|
|
|
;;; This file is part of GNU Guix.
|
|
|
|
|
;;;
|
|
|
|
|
;;; GNU Guix is free software; you can redistribute it and/or modify it
|
|
|
|
|
;;; under the terms of the GNU General Public License as published by
|
|
|
|
|
;;; the Free Software Foundation; either version 3 of the License, or (at
|
|
|
|
|
;;; your option) any later version.
|
|
|
|
|
;;;
|
|
|
|
|
;;; GNU Guix is distributed in the hope that it will be useful, but
|
|
|
|
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;;; GNU General Public License for more details.
|
|
|
|
|
;;;
|
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
2015-03-25 05:34:27 -04:00
|
|
|
|
(define-module (test-substitute)
|
|
|
|
|
#:use-module (guix scripts substitute)
|
guix: Move narinfo code from substitute script to module.
This separation between the code for dealing with narinfos from the code doing
that for a purpose should make things clearer, and better support components
other that the substitute script in using this code.
This is just moving the code around, no code should have been significantly
changed.
* guix/scripts/substitute.scm (<narinfo>): Move record type to (guix narinfo).
(fields->alist, narinfo-hash-algorithm+value, narinfo-hash->sha256,
narinfo-signature->canonical-sexp, narinfo-maker, read-narinfo,
narinfo-sha256, valid-narinfo?, write-narinfo, narinfo->string,
string->narinfo, equivalent-narinfo?, supported-compression?,
compresses-better?, narinfo-best-uri): Move procedures to (guix narinfo).
(%compression-methods): Move variable to (guix narinfo).
* guix/narinfo.scm: New file.
* Makefile.am (MODULES): Add it.
* po/guix/POTFILES.in: Add 'guix/narinfo.scm'.
2020-12-24 10:50:54 -05:00
|
|
|
|
#:use-module (guix narinfo)
|
2014-03-28 19:06:41 -04:00
|
|
|
|
#:use-module (guix base64)
|
Switch to Guile-Gcrypt.
This removes (guix hash) and (guix pk-crypto), which now live as part of
Guile-Gcrypt (version 0.1.0.)
* guix/gcrypt.scm, guix/hash.scm, guix/pk-crypto.scm,
tests/hash.scm, tests/pk-crypto.scm: Remove.
* configure.ac: Test for Guile-Gcrypt. Remove LIBGCRYPT and
LIBGCRYPT_LIBDIR assignments.
* m4/guix.m4 (GUIX_ASSERT_LIBGCRYPT_USABLE): Remove.
* README: Add Guile-Gcrypt to the dependencies; move libgcrypt as
"required unless --disable-daemon".
* doc/guix.texi (Requirements): Likewise.
* gnu/packages/bash.scm, guix/derivations.scm, guix/docker.scm,
guix/git.scm, guix/http-client.scm, guix/import/cpan.scm,
guix/import/cran.scm, guix/import/crate.scm, guix/import/elpa.scm,
guix/import/gnu.scm, guix/import/hackage.scm,
guix/import/texlive.scm, guix/import/utils.scm, guix/nar.scm,
guix/pki.scm, guix/scripts/archive.scm,
guix/scripts/authenticate.scm, guix/scripts/download.scm,
guix/scripts/hash.scm, guix/scripts/pack.scm,
guix/scripts/publish.scm, guix/scripts/refresh.scm,
guix/scripts/substitute.scm, guix/store.scm,
guix/store/deduplication.scm, guix/tests.scm, tests/base32.scm,
tests/builders.scm, tests/challenge.scm, tests/cpan.scm,
tests/crate.scm, tests/derivations.scm, tests/gem.scm,
tests/nar.scm, tests/opam.scm, tests/pki.scm,
tests/publish.scm, tests/pypi.scm, tests/store-deduplication.scm,
tests/store.scm, tests/substitute.scm: Adjust imports.
* gnu/system/vm.scm: Likewise.
(guile-sqlite3&co): Rename to...
(gcrypt-sqlite3&co): ... this. Add GUILE-GCRYPT.
(expression->derivation-in-linux-vm)[config]: Remove.
(iso9660-image)[config]: Remove.
(qemu-image)[config]: Remove.
(system-docker-image)[config]: Remove.
* guix/scripts/pack.scm: Adjust imports.
(guile-sqlite3&co): Rename to...
(gcrypt-sqlite3&co): ... this. Add GUILE-GCRYPT.
(self-contained-tarball)[build]: Call 'make-config.scm' without
#:libgcrypt argument.
(squashfs-image)[libgcrypt]: Remove.
[build]: Call 'make-config.scm' without #:libgcrypt.
(docker-image)[config, json]: Remove.
[build]: Add GUILE-GCRYPT to the extensions Remove (guix config) from
the imported modules.
* guix/self.scm (specification->package): Remove "libgcrypt", add
"guile-gcrypt".
(compiled-guix): Remove #:libgcrypt.
[guile-gcrypt]: New variable.
[dependencies]: Add it.
[*core-modules*]: Remove #:libgcrypt from 'make-config.scm' call.
Add #:extensions.
[*config*]: Remove #:libgcrypt from 'make-config.scm' call.
(%dependency-variables): Remove %libgcrypt.
(make-config.scm): Remove #:libgcrypt.
* build-aux/build-self.scm (guile-gcrypt): New variable.
(make-config.scm): Remove #:libgcrypt.
(build-program)[fake-gcrypt-hash]: New variable.
Add (gcrypt hash) to the imported modules. Adjust load path
assignments.
* gnu/packages/package-management.scm (guix)[propagated-inputs]: Add
GUILE-GCRYPT.
[arguments]: In 'wrap-program' phase, add GUILE-GCRYPT to the search
path.
2018-08-31 11:07:07 -04:00
|
|
|
|
#:use-module (gcrypt hash)
|
Break module cycle involving (guix store) and (guix ui).
Before, there was a cycle along the lines of:
(guix store) -> (guix nar) -> (guix ui) -> (guix store)
This caused problems, as discussed at:
http://lists.gnu.org/archive/html/guix-devel/2014-10/msg00109.html
This patch removes cycles in the (guix ...) modules.
* guix/nar.scm (&nar-error, &nar-read-error, dump, write-contents,
read-contents, %archive-version-1, write-file, restore-file): Move to...
* guix/serialization.scm: ... here.
* guix/store.scm: Remove dependency on (guix nar).
* guix/scripts/hash.scm, guix/scripts/offload.scm,
guix/scripts/substitute-binary.scm, tests/nar.scm, tests/store.scm,
tests/substitute-binary.scm: Adjust accordingly.
2014-10-09 17:46:13 -04:00
|
|
|
|
#:use-module (guix serialization)
|
Switch to Guile-Gcrypt.
This removes (guix hash) and (guix pk-crypto), which now live as part of
Guile-Gcrypt (version 0.1.0.)
* guix/gcrypt.scm, guix/hash.scm, guix/pk-crypto.scm,
tests/hash.scm, tests/pk-crypto.scm: Remove.
* configure.ac: Test for Guile-Gcrypt. Remove LIBGCRYPT and
LIBGCRYPT_LIBDIR assignments.
* m4/guix.m4 (GUIX_ASSERT_LIBGCRYPT_USABLE): Remove.
* README: Add Guile-Gcrypt to the dependencies; move libgcrypt as
"required unless --disable-daemon".
* doc/guix.texi (Requirements): Likewise.
* gnu/packages/bash.scm, guix/derivations.scm, guix/docker.scm,
guix/git.scm, guix/http-client.scm, guix/import/cpan.scm,
guix/import/cran.scm, guix/import/crate.scm, guix/import/elpa.scm,
guix/import/gnu.scm, guix/import/hackage.scm,
guix/import/texlive.scm, guix/import/utils.scm, guix/nar.scm,
guix/pki.scm, guix/scripts/archive.scm,
guix/scripts/authenticate.scm, guix/scripts/download.scm,
guix/scripts/hash.scm, guix/scripts/pack.scm,
guix/scripts/publish.scm, guix/scripts/refresh.scm,
guix/scripts/substitute.scm, guix/store.scm,
guix/store/deduplication.scm, guix/tests.scm, tests/base32.scm,
tests/builders.scm, tests/challenge.scm, tests/cpan.scm,
tests/crate.scm, tests/derivations.scm, tests/gem.scm,
tests/nar.scm, tests/opam.scm, tests/pki.scm,
tests/publish.scm, tests/pypi.scm, tests/store-deduplication.scm,
tests/store.scm, tests/substitute.scm: Adjust imports.
* gnu/system/vm.scm: Likewise.
(guile-sqlite3&co): Rename to...
(gcrypt-sqlite3&co): ... this. Add GUILE-GCRYPT.
(expression->derivation-in-linux-vm)[config]: Remove.
(iso9660-image)[config]: Remove.
(qemu-image)[config]: Remove.
(system-docker-image)[config]: Remove.
* guix/scripts/pack.scm: Adjust imports.
(guile-sqlite3&co): Rename to...
(gcrypt-sqlite3&co): ... this. Add GUILE-GCRYPT.
(self-contained-tarball)[build]: Call 'make-config.scm' without
#:libgcrypt argument.
(squashfs-image)[libgcrypt]: Remove.
[build]: Call 'make-config.scm' without #:libgcrypt.
(docker-image)[config, json]: Remove.
[build]: Add GUILE-GCRYPT to the extensions Remove (guix config) from
the imported modules.
* guix/self.scm (specification->package): Remove "libgcrypt", add
"guile-gcrypt".
(compiled-guix): Remove #:libgcrypt.
[guile-gcrypt]: New variable.
[dependencies]: Add it.
[*core-modules*]: Remove #:libgcrypt from 'make-config.scm' call.
Add #:extensions.
[*config*]: Remove #:libgcrypt from 'make-config.scm' call.
(%dependency-variables): Remove %libgcrypt.
(make-config.scm): Remove #:libgcrypt.
* build-aux/build-self.scm (guile-gcrypt): New variable.
(make-config.scm): Remove #:libgcrypt.
(build-program)[fake-gcrypt-hash]: New variable.
Add (gcrypt hash) to the imported modules. Adjust load path
assignments.
* gnu/packages/package-management.scm (guix)[propagated-inputs]: Add
GUILE-GCRYPT.
[arguments]: In 'wrap-program' phase, add GUILE-GCRYPT to the search
path.
2018-08-31 11:07:07 -04:00
|
|
|
|
#:use-module (gcrypt pk-crypto)
|
2014-03-28 19:06:41 -04:00
|
|
|
|
#:use-module (guix pki)
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
#:use-module (guix config)
|
2014-03-30 16:11:22 -04:00
|
|
|
|
#:use-module (guix base32)
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
#:use-module ((guix store) #:select (%store-prefix))
|
2014-03-30 16:25:47 -04:00
|
|
|
|
#:use-module ((guix ui) #:select (guix-warning-port))
|
daemon: Let 'guix substitute' perform hash checks.
This way, the hash of the store item can be computed as it is restored,
thereby avoiding an additional file tree traversal ('hashPath' call)
later on in the daemon. Consequently, it should reduce latency between
subsequent substitute downloads.
This is a followup to 5ff521452b9ec2aae9ed8e4bb7bdc250a581f203.
* guix/scripts/substitute.scm (narinfo-hash-algorithm+value): New
procedure.
(process-substitution): Wrap INPUT into a hash input port, 'hashed', and
read from it. Compare the actual and expected hashes, and print a
"hash-mismatch" status line when they differ. When they match, print
not just "success" but also the nar hash and size.
* nix/libstore/build.cc (class SubstitutionGoal)[expectedHashStr]:
Remove.
(SubstitutionGoal::finished): Tokenize 'status'. Parse it and handle
"success" and "hash-mismatch" accordingly. Call 'hashPath' only when
the returned hash is not SHA256.
(SubstitutionGoal::handleChildOutput): Remove 'expectedHashStr'
handling.
* tests/substitute.scm ("substitute, invalid hash"): Rename to...
("substitute, invalid narinfo hash"): ... this.
("substitute, invalid hash"): New test.
2020-12-13 16:46:03 -05:00
|
|
|
|
#:use-module ((guix utils)
|
|
|
|
|
#:select (call-with-temporary-directory
|
|
|
|
|
call-with-compressed-output-port))
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
#:use-module ((guix build utils)
|
2019-05-31 10:26:08 -04:00
|
|
|
|
#:select (mkdir-p delete-file-recursively dump-port))
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
#:use-module (guix tests http)
|
2014-03-28 19:06:41 -04:00
|
|
|
|
#:use-module (rnrs bytevectors)
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
#:use-module (rnrs io ports)
|
|
|
|
|
#:use-module (web uri)
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
#:use-module (ice-9 regex)
|
daemon: Let 'guix substitute' perform hash checks.
This way, the hash of the store item can be computed as it is restored,
thereby avoiding an additional file tree traversal ('hashPath' call)
later on in the daemon. Consequently, it should reduce latency between
subsequent substitute downloads.
This is a followup to 5ff521452b9ec2aae9ed8e4bb7bdc250a581f203.
* guix/scripts/substitute.scm (narinfo-hash-algorithm+value): New
procedure.
(process-substitution): Wrap INPUT into a hash input port, 'hashed', and
read from it. Compare the actual and expected hashes, and print a
"hash-mismatch" status line when they differ. When they match, print
not just "success" but also the nar hash and size.
* nix/libstore/build.cc (class SubstitutionGoal)[expectedHashStr]:
Remove.
(SubstitutionGoal::finished): Tokenize 'status'. Parse it and handle
"success" and "hash-mismatch" accordingly. Call 'hashPath' only when
the returned hash is not SHA256.
(SubstitutionGoal::handleChildOutput): Remove 'expectedHashStr'
handling.
* tests/substitute.scm ("substitute, invalid hash"): Rename to...
("substitute, invalid narinfo hash"): ... this.
("substitute, invalid hash"): New test.
2020-12-13 16:46:03 -05:00
|
|
|
|
#:use-module (srfi srfi-11)
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
#:use-module (srfi srfi-26)
|
2014-03-28 19:06:41 -04:00
|
|
|
|
#:use-module (srfi srfi-34)
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
#:use-module (srfi srfi-35)
|
2014-03-28 19:06:41 -04:00
|
|
|
|
#:use-module ((srfi srfi-64) #:hide (test-error)))
|
|
|
|
|
|
2014-03-30 16:25:47 -04:00
|
|
|
|
(define-syntax-rule (test-quit name error-rx exp)
|
|
|
|
|
"Emit a test that passes when EXP throws to 'quit' with value 1, and when
|
|
|
|
|
it writes to GUIX-WARNING-PORT a messages that matches ERROR-RX."
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(test-equal name
|
2014-03-30 16:25:47 -04:00
|
|
|
|
'(1 #t)
|
|
|
|
|
(let ((error-output (open-output-string)))
|
2020-12-01 09:01:40 -05:00
|
|
|
|
(parameterize ((current-error-port error-output)
|
|
|
|
|
(guix-warning-port error-output))
|
2014-03-30 16:25:47 -04:00
|
|
|
|
(catch 'quit
|
|
|
|
|
(lambda ()
|
|
|
|
|
exp
|
|
|
|
|
#f)
|
|
|
|
|
(lambda (key value)
|
|
|
|
|
(list value
|
|
|
|
|
(let ((message (get-output-string error-output)))
|
|
|
|
|
(->bool (string-match error-rx message))))))))))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(define (request-substitution item destination)
|
|
|
|
|
"Run 'guix substitute --substitute' to fetch ITEM to DESTINATION."
|
2023-05-22 11:19:39 -04:00
|
|
|
|
(false-if-exception (delete-file destination))
|
|
|
|
|
(with-input-from-string (string-append "substitute " item " "
|
|
|
|
|
destination "\n")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--substitute"))))
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
|
2014-03-28 19:06:41 -04:00
|
|
|
|
(define %public-key
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
;; This key is known to be in the ACL by default.
|
|
|
|
|
(call-with-input-file (string-append %config-directory "/signing-key.pub")
|
|
|
|
|
(compose string->canonical-sexp get-string-all)))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
|
|
|
|
(define %private-key
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(call-with-input-file (string-append %config-directory "/signing-key.sec")
|
|
|
|
|
(compose string->canonical-sexp get-string-all)))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(define* (signature-body bv #:key (public-key %public-key))
|
|
|
|
|
"Return the signature of BV as the base64-encoded body of a narinfo's
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
'Signature' field."
|
2014-03-28 19:06:41 -04:00
|
|
|
|
(base64-encode
|
|
|
|
|
(string->utf8
|
|
|
|
|
(canonical-sexp->string
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(signature-sexp (bytevector->hash-data (sha256 bv)
|
2014-03-28 19:06:41 -04:00
|
|
|
|
#:key-type 'rsa)
|
|
|
|
|
%private-key
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
public-key)))))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
|
|
|
|
(define %wrong-public-key
|
|
|
|
|
(string->canonical-sexp "(public-key
|
|
|
|
|
(rsa
|
|
|
|
|
(n #00E05873AC2B168760343145918E954EE9AB73C026355693B192E01EE835261AA689E9EF46642E895BCD65C648524059FC450E4BA77A68F4C52D0E39EF0CC9359709AB6AAB153B63782201871325B0FDA19CB401CD99FD0C31A91CA9000AA90A77E82B89E036FB63BC1D3961207469B3B12468977148D376F8012BB12A4B11A8F1#)
|
|
|
|
|
(e #010001#)
|
|
|
|
|
)
|
|
|
|
|
)"))
|
|
|
|
|
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(define* (signature-field bv-or-str
|
|
|
|
|
#:key (version "1") (public-key %public-key))
|
|
|
|
|
"Return the 'Signature' field value of bytevector/string BV-OR-STR, using
|
|
|
|
|
PUBLIC-KEY as the signature's principal, and using VERSION as the signature
|
|
|
|
|
version identifier.."
|
|
|
|
|
(string-append version ";example.gnu.org;"
|
|
|
|
|
(signature-body (if (string? bv-or-str)
|
|
|
|
|
(string->utf8 bv-or-str)
|
|
|
|
|
bv-or-str)
|
|
|
|
|
#:public-key public-key)))
|
|
|
|
|
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
2015-03-25 05:34:27 -04:00
|
|
|
|
(test-begin "substitute")
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
2014-03-30 16:25:47 -04:00
|
|
|
|
(test-quit "not a number"
|
|
|
|
|
"signature version"
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(narinfo-signature->canonical-sexp
|
|
|
|
|
(signature-field "foo" #:version "not a number")))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
2014-03-30 16:25:47 -04:00
|
|
|
|
(test-quit "wrong version number"
|
|
|
|
|
"unsupported.*version"
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(narinfo-signature->canonical-sexp
|
|
|
|
|
(signature-field "foo" #:version "2")))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
|
|
|
|
(test-assert "valid narinfo-signature->canonical-sexp"
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(canonical-sexp? (narinfo-signature->canonical-sexp (signature-field "foo"))))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
|
|
|
|
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(define %main-substitute-directory
|
|
|
|
|
;; The place where 'call-with-narinfo' stores its data by default.
|
|
|
|
|
(uri-path (string->uri (getenv "GUIX_BINARY_SUBSTITUTE_URL"))))
|
|
|
|
|
|
|
|
|
|
(define %alternate-substitute-directory
|
|
|
|
|
;; Another place.
|
|
|
|
|
(string-append (dirname %main-substitute-directory)
|
|
|
|
|
"/substituter-alt-data"))
|
|
|
|
|
|
2022-09-21 11:21:48 -04:00
|
|
|
|
(define %unroutable-substitute-url
|
|
|
|
|
;; Substitute URL with an unroutable server address, as per
|
|
|
|
|
;; <https://www.rfc-editor.org/rfc/rfc5737>.
|
|
|
|
|
"http://203.0.113.1")
|
|
|
|
|
|
|
|
|
|
|
2014-03-28 19:06:41 -04:00
|
|
|
|
(define %narinfo
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
;; Skeleton of the narinfo used below.
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(string-append "StorePath: " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo
|
2014-03-30 16:11:22 -04:00
|
|
|
|
URL: example.nar
|
|
|
|
|
Compression: none
|
|
|
|
|
NarHash: sha256:" (bytevector->nix-base32-string
|
|
|
|
|
(sha256 (string->utf8 "Substitutable data."))) "
|
2014-03-28 19:06:41 -04:00
|
|
|
|
NarSize: 42
|
|
|
|
|
References: bar baz
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
Deriver: " (%store-prefix) "/foo.drv
|
|
|
|
|
System: mips64el-linux\n"))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(define* (call-with-narinfo narinfo thunk
|
|
|
|
|
#:optional
|
|
|
|
|
(narinfo-directory %main-substitute-directory))
|
|
|
|
|
"Call THUNK in a context where the directory at URL is populated with
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
a file for NARINFO."
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(mkdir-p narinfo-directory)
|
|
|
|
|
(let ((cache-directory (string-append (getenv "XDG_CACHE_HOME")
|
|
|
|
|
"/guix/substitute/")))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(dynamic-wind
|
|
|
|
|
(lambda ()
|
|
|
|
|
(when (file-exists? cache-directory)
|
|
|
|
|
(delete-file-recursively cache-directory))
|
|
|
|
|
(call-with-output-file (string-append narinfo-directory
|
|
|
|
|
"/nix-cache-info")
|
|
|
|
|
(lambda (port)
|
|
|
|
|
(format port "StoreDir: ~a\nWantMassQuery: 0\n"
|
|
|
|
|
(%store-prefix))))
|
|
|
|
|
(call-with-output-file (string-append narinfo-directory "/"
|
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
|
".narinfo")
|
|
|
|
|
(cut display narinfo <>))
|
|
|
|
|
|
2014-03-30 16:11:22 -04:00
|
|
|
|
;; Prepare the nar.
|
|
|
|
|
(call-with-output-file
|
|
|
|
|
(string-append narinfo-directory "/example.out")
|
|
|
|
|
(cut display "Substitutable data." <>))
|
|
|
|
|
(call-with-output-file
|
|
|
|
|
(string-append narinfo-directory "/example.nar")
|
|
|
|
|
(cute write-file
|
|
|
|
|
(string-append narinfo-directory "/example.out") <>))
|
|
|
|
|
|
2019-11-26 06:30:45 -05:00
|
|
|
|
(%allow-unauthenticated-substitutes? #f))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
thunk
|
|
|
|
|
(lambda ()
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(when (file-exists? cache-directory)
|
|
|
|
|
(delete-file-recursively cache-directory))))))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
|
|
|
|
(define-syntax-rule (with-narinfo narinfo body ...)
|
|
|
|
|
(call-with-narinfo narinfo (lambda () body ...)))
|
|
|
|
|
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(define-syntax-rule (with-narinfo* narinfo directory body ...)
|
|
|
|
|
(call-with-narinfo narinfo (lambda () body ...) directory))
|
|
|
|
|
|
2015-03-25 05:34:27 -04:00
|
|
|
|
;; Transmit these options to 'guix substitute'.
|
2017-08-31 17:27:26 -04:00
|
|
|
|
(substitute-urls (list (getenv "GUIX_BINARY_SUBSTITUTE_URL")))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
;; Never use file descriptor 4, unlike what happens when invoked by the
|
|
|
|
|
;; daemon.
|
2021-04-06 06:10:29 -04:00
|
|
|
|
(%reply-file-descriptor #f)
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
|
|
|
|
|
|
2014-03-30 16:11:22 -04:00
|
|
|
|
(test-equal "query narinfo without signature"
|
|
|
|
|
"" ; not substitutable
|
|
|
|
|
|
|
|
|
|
(with-narinfo %narinfo
|
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
2015-03-25 05:34:27 -04:00
|
|
|
|
(guix-substitute "--query"))))))))
|
2014-03-30 16:11:22 -04:00
|
|
|
|
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(test-equal "query narinfo with invalid hash"
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
;; The hash in the signature differs from the hash of %NARINFO.
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
""
|
|
|
|
|
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field "different body")
|
|
|
|
|
"\n")
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
2015-03-25 05:34:27 -04:00
|
|
|
|
(guix-substitute "--query"))))))))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
2018-12-13 13:45:47 -05:00
|
|
|
|
(test-equal "query narinfo with signature over nothing"
|
|
|
|
|
;; The signature is computed over the empty string, not over the important
|
|
|
|
|
;; parts, so the narinfo must be ignored.
|
|
|
|
|
""
|
|
|
|
|
|
|
|
|
|
(with-narinfo (string-append "Signature: " (signature-field "") "\n"
|
|
|
|
|
%narinfo "\n")
|
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--query"))))))))
|
|
|
|
|
|
|
|
|
|
(test-equal "query narinfo with signature over irrelevant bits"
|
|
|
|
|
;; The signature is valid but it does not cover the
|
|
|
|
|
;; StorePath/NarHash/References tuple and is thus irrelevant; the narinfo
|
|
|
|
|
;; must be ignored.
|
|
|
|
|
""
|
|
|
|
|
|
|
|
|
|
(let ((prefix (string-append "StorePath: " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo
|
|
|
|
|
URL: example.nar
|
|
|
|
|
Compression: none\n")))
|
|
|
|
|
(with-narinfo (string-append prefix
|
|
|
|
|
"Signature: " (signature-field prefix) "
|
|
|
|
|
NarHash: sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
|
|
|
NarSize: 42
|
|
|
|
|
References: bar baz
|
|
|
|
|
Deriver: " (%store-prefix) "/foo.drv
|
|
|
|
|
System: mips64el-linux\n")
|
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--query")))))))))
|
2022-02-09 12:36:35 -05:00
|
|
|
|
|
|
|
|
|
(test-equal "query narinfo with signature over relevant subset"
|
|
|
|
|
;; The signature covers the StorePath/NarHash/References tuple, so it is
|
|
|
|
|
;; valid; it does not cover non-normative fields, which is fine.
|
|
|
|
|
(string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
|
|
|
|
|
(let ((prefix (string-append "StorePath: " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo
|
|
|
|
|
NarHash: sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
|
|
|
References: bar baz\n")))
|
|
|
|
|
(with-narinfo (string-append prefix
|
|
|
|
|
"Signature: " (signature-field prefix) "
|
|
|
|
|
URL: example.nar
|
|
|
|
|
Compression: none
|
|
|
|
|
NarSize: 42
|
|
|
|
|
Deriver: " (%store-prefix) "/foo.drv")
|
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--query")))))))))
|
2018-12-13 13:45:47 -05:00
|
|
|
|
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(test-equal "query narinfo signed with authorized key"
|
|
|
|
|
(string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo)
|
|
|
|
|
"\n")
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
2015-03-25 05:34:27 -04:00
|
|
|
|
(guix-substitute "--query"))))))))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
2022-09-21 11:21:48 -04:00
|
|
|
|
(test-equal "query narinfo signed with authorized key, unroutable URL first"
|
|
|
|
|
(string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
|
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo)
|
|
|
|
|
"\n")
|
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(list %unroutable-substitute-url
|
|
|
|
|
(string-append "file://"
|
|
|
|
|
%main-substitute-directory))))
|
|
|
|
|
(guix-substitute "--query")))))))))
|
|
|
|
|
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(test-equal "query narinfo signed with unauthorized key"
|
|
|
|
|
"" ; not substitutable
|
|
|
|
|
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key)
|
|
|
|
|
"\n")
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
(string-trim-both
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(with-input-from-string (string-append "have " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
(lambda ()
|
2015-03-25 05:34:27 -04:00
|
|
|
|
(guix-substitute "--query"))))))))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
2014-03-30 16:25:47 -04:00
|
|
|
|
(test-quit "substitute, no signature"
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
"no valid substitute"
|
2014-03-30 16:11:22 -04:00
|
|
|
|
(with-narinfo %narinfo
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(with-input-from-string (string-append "substitute "
|
|
|
|
|
(%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo"
|
|
|
|
|
" foo\n")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--substitute")))))
|
2014-03-30 16:11:22 -04:00
|
|
|
|
|
daemon: Let 'guix substitute' perform hash checks.
This way, the hash of the store item can be computed as it is restored,
thereby avoiding an additional file tree traversal ('hashPath' call)
later on in the daemon. Consequently, it should reduce latency between
subsequent substitute downloads.
This is a followup to 5ff521452b9ec2aae9ed8e4bb7bdc250a581f203.
* guix/scripts/substitute.scm (narinfo-hash-algorithm+value): New
procedure.
(process-substitution): Wrap INPUT into a hash input port, 'hashed', and
read from it. Compare the actual and expected hashes, and print a
"hash-mismatch" status line when they differ. When they match, print
not just "success" but also the nar hash and size.
* nix/libstore/build.cc (class SubstitutionGoal)[expectedHashStr]:
Remove.
(SubstitutionGoal::finished): Tokenize 'status'. Parse it and handle
"success" and "hash-mismatch" accordingly. Call 'hashPath' only when
the returned hash is not SHA256.
(SubstitutionGoal::handleChildOutput): Remove 'expectedHashStr'
handling.
* tests/substitute.scm ("substitute, invalid hash"): Rename to...
("substitute, invalid narinfo hash"): ... this.
("substitute, invalid hash"): New test.
2020-12-13 16:46:03 -05:00
|
|
|
|
(test-quit "substitute, invalid narinfo hash"
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
"no valid substitute"
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
;; The hash in the signature differs from the hash of %NARINFO.
|
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field "different body")
|
|
|
|
|
"\n")
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(with-input-from-string (string-append "substitute "
|
|
|
|
|
(%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo"
|
|
|
|
|
" foo\n")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--substitute")))))
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
|
daemon: Let 'guix substitute' perform hash checks.
This way, the hash of the store item can be computed as it is restored,
thereby avoiding an additional file tree traversal ('hashPath' call)
later on in the daemon. Consequently, it should reduce latency between
subsequent substitute downloads.
This is a followup to 5ff521452b9ec2aae9ed8e4bb7bdc250a581f203.
* guix/scripts/substitute.scm (narinfo-hash-algorithm+value): New
procedure.
(process-substitution): Wrap INPUT into a hash input port, 'hashed', and
read from it. Compare the actual and expected hashes, and print a
"hash-mismatch" status line when they differ. When they match, print
not just "success" but also the nar hash and size.
* nix/libstore/build.cc (class SubstitutionGoal)[expectedHashStr]:
Remove.
(SubstitutionGoal::finished): Tokenize 'status'. Parse it and handle
"success" and "hash-mismatch" accordingly. Call 'hashPath' only when
the returned hash is not SHA256.
(SubstitutionGoal::handleChildOutput): Remove 'expectedHashStr'
handling.
* tests/substitute.scm ("substitute, invalid hash"): Rename to...
("substitute, invalid narinfo hash"): ... this.
("substitute, invalid hash"): New test.
2020-12-13 16:46:03 -05:00
|
|
|
|
(test-equal "substitute, invalid hash"
|
|
|
|
|
(string-append "hash-mismatch sha256 "
|
|
|
|
|
(bytevector->nix-base32-string (sha256 #vu8())) " "
|
|
|
|
|
(let-values (((port get-hash)
|
|
|
|
|
(open-hash-port (hash-algorithm sha256)))
|
|
|
|
|
((content)
|
|
|
|
|
"Substitutable data."))
|
|
|
|
|
(write-file-tree "foo" port
|
|
|
|
|
#:file-type+size
|
|
|
|
|
(lambda _
|
|
|
|
|
(values 'regular
|
|
|
|
|
(string-length content)))
|
|
|
|
|
#:file-port
|
|
|
|
|
(lambda _
|
|
|
|
|
(open-input-string content)))
|
|
|
|
|
(close-port port)
|
|
|
|
|
(bytevector->nix-base32-string (get-hash)))
|
|
|
|
|
"\n")
|
|
|
|
|
|
|
|
|
|
;; Arrange so the actual data hash does not match the 'NarHash' field in the
|
|
|
|
|
;; narinfo.
|
|
|
|
|
(with-output-to-string
|
|
|
|
|
(lambda ()
|
|
|
|
|
(let ((narinfo (string-append "StorePath: " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-wrong-hash
|
|
|
|
|
URL: example.nar
|
|
|
|
|
Compression: none
|
|
|
|
|
NarHash: sha256:" (bytevector->nix-base32-string (sha256 #vu8())) "
|
|
|
|
|
NarSize: 42
|
|
|
|
|
References:
|
|
|
|
|
Deriver: " (%store-prefix) "/foo.drv
|
|
|
|
|
System: mips64el-linux\n")))
|
|
|
|
|
(with-narinfo (string-append narinfo "Signature: "
|
|
|
|
|
(signature-field narinfo) "\n")
|
|
|
|
|
(call-with-temporary-directory
|
|
|
|
|
(lambda (directory)
|
|
|
|
|
(with-input-from-string (string-append
|
|
|
|
|
"substitute " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-wrong-hash "
|
|
|
|
|
directory "/wrong-hash\n")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--substitute"))))))))))
|
|
|
|
|
|
2014-03-30 16:25:47 -04:00
|
|
|
|
(test-quit "substitute, unauthorized key"
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
"no valid substitute"
|
tests: Simplify 'substitute-binary' tests; reduce use of global variables.
* tests/substitute-binary.scm (signature-body): Change 'str' parameter
to 'bv', and expect it to be a bytevector.
(%signature-body, %wrong-signature, %acl): Remove.
(signature): Rename to...
(signature-field): ... this. Add 'bv-or-str' parameter. Change 'str'
parameter to #:version. Add #:public-key parameter. Call
'signature-body' directly. Change domain part of the signature to
'example.gnu.org'.
("not a number", "wrong version number", "valid
narinfo-signature->canonical-sexp"): Use 'signature-field' instead of
'signature' or %SIGNATURE.
(test-error-condition): Add 'message-rx' parameter and honor it.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Adjust accordingly.
(narinfo, %signed-narinfo): Remove.
("query narinfo with invalid hash"): Use '%narinfo' and
'signature-field' instead of 'narinfo' and '%signature'.
("query narinfo signed with authorized key", "query narinfo signed
with unauthorized key", "substitute, invalid hash", "substitute,
unauthorized key"): Likewise.
2014-03-30 15:35:22 -04:00
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key)
|
|
|
|
|
"\n")
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(with-input-from-string (string-append "substitute "
|
|
|
|
|
(%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo"
|
|
|
|
|
" foo\n")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--substitute")))))
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
2014-03-30 16:11:22 -04:00
|
|
|
|
(test-equal "substitute, authorized key"
|
2020-12-14 08:33:06 -05:00
|
|
|
|
'("Substitutable data." 1 #o444)
|
2014-03-30 16:11:22 -04:00
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved")
|
2020-12-14 08:33:06 -05:00
|
|
|
|
(list (call-with-input-file "substitute-retrieved" get-string-all)
|
|
|
|
|
(stat:mtime (lstat "substitute-retrieved"))
|
|
|
|
|
(stat:perms (lstat "substitute-retrieved"))))
|
2014-03-30 16:11:22 -04:00
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved"))))))
|
|
|
|
|
|
2022-09-21 11:21:48 -04:00
|
|
|
|
(test-equal "substitute, authorized key, first substitute URL is unroutable"
|
|
|
|
|
'("Substitutable data." 1 #o444)
|
|
|
|
|
(with-narinfo (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; Pick an unroutable URL as the first one. This shouldn't be a
|
|
|
|
|
;; problem.
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(list %unroutable-substitute-url
|
|
|
|
|
(string-append "file://"
|
|
|
|
|
%main-substitute-directory))))
|
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved")
|
|
|
|
|
(list (call-with-input-file "substitute-retrieved" get-string-all)
|
|
|
|
|
(stat:mtime (lstat "substitute-retrieved"))
|
|
|
|
|
(stat:perms (lstat "substitute-retrieved")))))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved"))))))
|
|
|
|
|
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(test-equal "substitute, unauthorized narinfo comes first"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo*
|
|
|
|
|
(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key))
|
|
|
|
|
%alternate-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; Remove this file so that the substitute can only be retrieved
|
|
|
|
|
;; from %ALTERNATE-SUBSTITUTE-DIRECTORY.
|
|
|
|
|
(delete-file (string-append %main-substitute-directory
|
|
|
|
|
"/example.nar"))
|
|
|
|
|
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(map (cut string-append "file://" <>)
|
|
|
|
|
(list %alternate-substitute-directory
|
|
|
|
|
%main-substitute-directory))))
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
|
|
|
|
(test-equal "substitute, unsigned narinfo comes first"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo* %narinfo ;not signed!
|
|
|
|
|
%alternate-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; Remove this file so that the substitute can only be retrieved
|
|
|
|
|
;; from %ALTERNATE-SUBSTITUTE-DIRECTORY.
|
|
|
|
|
(delete-file (string-append %main-substitute-directory
|
|
|
|
|
"/example.nar"))
|
|
|
|
|
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(map (cut string-append "file://" <>)
|
|
|
|
|
(list %alternate-substitute-directory
|
|
|
|
|
%main-substitute-directory))))
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
substitute: Retry downloading when a nar is unavailable.
Fixes <https://issues.guix.gnu.org/57978>
Reported by Attila Lendvai <attila@lendvai.name>.
Previously, if a narinfo was available but its corresponding nar was
missing (for instance because the narinfo was cached and the server
became unreachable in the meantime), 'guix substitute --substitute'
would try to download the nar from its preferred location and abort when
that fails. This change forces one retry with each of the URLs.
* guix/scripts/substitute.scm (download-nar): Do not catch
'http-get-error?' exceptions.
(system-error?, network-error?, process-substitution/fallback): New
procedures.
(process-substitution): Call 'process-substitution/fallback' upon
'network-error?'.
* tests/substitute.scm ("substitute, first URL has narinfo but lacks nar, second URL unauthorized")
("substitute, first URL has narinfo but nar is 404, both URLs authorized")
("substitute, first URL has narinfo but nar is 404, one URL authorized")
("substitute, narinfo is available but nar is missing"): New tests.
2022-09-23 02:00:13 -04:00
|
|
|
|
(test-equal "substitute, first URL has narinfo but lacks nar, second URL unauthorized"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo*
|
|
|
|
|
(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key))
|
|
|
|
|
%alternate-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; Remove this file so that the substitute can only be retrieved
|
|
|
|
|
;; from %ALTERNATE-SUBSTITUTE-DIRECTORY.
|
|
|
|
|
(delete-file (string-append %main-substitute-directory
|
|
|
|
|
"/example.nar"))
|
|
|
|
|
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(map (cut string-append "file://" <>)
|
|
|
|
|
(list %main-substitute-directory
|
|
|
|
|
%alternate-substitute-directory))))
|
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
|
|
|
|
(test-equal "substitute, first URL has narinfo but nar is 404, both URLs authorized"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo*
|
|
|
|
|
(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-http-server `((200 ,(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo)))
|
|
|
|
|
(404 "Sorry, nar is missing!"))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(list (%local-url)
|
|
|
|
|
(string-append "file://"
|
|
|
|
|
%main-substitute-directory))))
|
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
|
|
|
|
(test-equal "substitute, first URL has narinfo but nar is 404, one URL authorized"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo*
|
|
|
|
|
(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-http-server `((200 ,(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key)))
|
|
|
|
|
(404 "Sorry, nar is missing!"))
|
|
|
|
|
(let ((url1 (%local-url)))
|
|
|
|
|
(parameterize ((%http-server-port 0))
|
|
|
|
|
(with-http-server `((200 ,(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo)))
|
|
|
|
|
(404 "Sorry, nar is missing!"))
|
|
|
|
|
(let ((url2 (%local-url)))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(list url1 url2
|
|
|
|
|
(string-append "file://"
|
|
|
|
|
%main-substitute-directory))))
|
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))))))
|
|
|
|
|
|
2023-05-22 11:19:39 -04:00
|
|
|
|
(test-equal "substitute, preferred nar URL is 404, other is 200"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: " (signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-http-server `((200 ,(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo)
|
|
|
|
|
"\n"
|
|
|
|
|
"URL: example.nar.lz\n"
|
|
|
|
|
"Compression: lzip\n"))
|
|
|
|
|
(404 "Sorry, nar.lz is missing!")
|
|
|
|
|
(200 ,(call-with-input-file
|
|
|
|
|
(string-append %main-substitute-directory
|
|
|
|
|
"/example.nar")
|
|
|
|
|
get-bytevector-all)))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
(parameterize ((substitute-urls (list (%local-url))))
|
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
2023-06-08 16:43:05 -04:00
|
|
|
|
(test-equal "substitute, previous partial download around"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: " (signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-http-server `((200 ,(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo)))
|
|
|
|
|
(200 ,(call-with-input-file
|
|
|
|
|
(string-append %main-substitute-directory
|
|
|
|
|
"/example.nar")
|
|
|
|
|
get-bytevector-all)))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
(parameterize ((substitute-urls (list (%local-url))))
|
|
|
|
|
(mkdir-p "substitute-retrieved/a/b/c/d") ;add stale data
|
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
substitute: Retry downloading when a nar is unavailable.
Fixes <https://issues.guix.gnu.org/57978>
Reported by Attila Lendvai <attila@lendvai.name>.
Previously, if a narinfo was available but its corresponding nar was
missing (for instance because the narinfo was cached and the server
became unreachable in the meantime), 'guix substitute --substitute'
would try to download the nar from its preferred location and abort when
that fails. This change forces one retry with each of the URLs.
* guix/scripts/substitute.scm (download-nar): Do not catch
'http-get-error?' exceptions.
(system-error?, network-error?, process-substitution/fallback): New
procedures.
(process-substitution): Call 'process-substitution/fallback' upon
'network-error?'.
* tests/substitute.scm ("substitute, first URL has narinfo but lacks nar, second URL unauthorized")
("substitute, first URL has narinfo but nar is 404, both URLs authorized")
("substitute, first URL has narinfo but nar is 404, one URL authorized")
("substitute, narinfo is available but nar is missing"): New tests.
2022-09-23 02:00:13 -04:00
|
|
|
|
(test-quit "substitute, narinfo is available but nar is missing"
|
|
|
|
|
"failed to find alternative substitute"
|
|
|
|
|
(with-narinfo*
|
|
|
|
|
(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-http-server `((200 ,(string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo)))
|
|
|
|
|
(404 "Sorry, nar is missing!"))
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(list (%local-url)
|
|
|
|
|
(string-append "file://"
|
|
|
|
|
%main-substitute-directory))))
|
|
|
|
|
(delete-file (string-append %main-substitute-directory
|
|
|
|
|
"/example.nar"))
|
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved")
|
|
|
|
|
(not (file-exists? "substitute-retrieved"))))))
|
|
|
|
|
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(test-equal "substitute, first narinfo is unsigned and has wrong hash"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo* (regexp-substitute #f
|
|
|
|
|
(string-match "NarHash: [[:graph:]]+"
|
|
|
|
|
%narinfo)
|
|
|
|
|
'pre
|
|
|
|
|
"NarHash: sha256:"
|
|
|
|
|
(bytevector->nix-base32-string
|
|
|
|
|
(make-bytevector 32))
|
|
|
|
|
'post)
|
|
|
|
|
%alternate-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; This time remove the file so that the substitute can only be
|
|
|
|
|
;; retrieved from %MAIN-SUBSTITUTE-DIRECTORY.
|
|
|
|
|
(delete-file (string-append %alternate-substitute-directory
|
|
|
|
|
"/example.nar"))
|
|
|
|
|
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(map (cut string-append "file://" <>)
|
|
|
|
|
(list %alternate-substitute-directory
|
|
|
|
|
%main-substitute-directory))))
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
|
|
|
|
(test-equal "substitute, first narinfo is unsigned and has wrong refs"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(with-narinfo* (regexp-substitute #f
|
|
|
|
|
(string-match "References: ([^\n]+)\n"
|
|
|
|
|
%narinfo)
|
|
|
|
|
'pre "References: " 1
|
|
|
|
|
" wrong set of references\n"
|
|
|
|
|
'post)
|
|
|
|
|
%alternate-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: "
|
|
|
|
|
(signature-field %narinfo))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
;; This time remove the file so that the substitute can only be
|
|
|
|
|
;; retrieved from %MAIN-SUBSTITUTE-DIRECTORY.
|
|
|
|
|
(delete-file (string-append %alternate-substitute-directory
|
|
|
|
|
"/example.nar"))
|
|
|
|
|
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(map (cut string-append "file://" <>)
|
|
|
|
|
(list %alternate-substitute-directory
|
|
|
|
|
%main-substitute-directory))))
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
|
|
|
|
(test-quit "substitute, two invalid narinfos"
|
|
|
|
|
"no valid substitute"
|
|
|
|
|
(with-narinfo* %narinfo ;not signed
|
|
|
|
|
%alternate-substitute-directory
|
|
|
|
|
|
|
|
|
|
(with-narinfo* (string-append %narinfo "Signature: " ;unauthorized
|
|
|
|
|
(signature-field
|
|
|
|
|
%narinfo
|
|
|
|
|
#:public-key %wrong-public-key))
|
|
|
|
|
%main-substitute-directory
|
|
|
|
|
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(with-input-from-string (string-append "substitute "
|
|
|
|
|
(%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo"
|
|
|
|
|
" substitute-retrieved\n")
|
|
|
|
|
(lambda ()
|
|
|
|
|
(guix-substitute "--substitute"))))))
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
|
2019-05-31 10:26:08 -04:00
|
|
|
|
(test-equal "substitute, narinfo with several URLs"
|
|
|
|
|
"Substitutable data."
|
|
|
|
|
(let ((narinfo (string-append "StorePath: " (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo
|
|
|
|
|
URL: example.nar.gz
|
|
|
|
|
Compression: gzip
|
|
|
|
|
URL: example.nar.lz
|
|
|
|
|
Compression: lzip
|
|
|
|
|
URL: example.nar
|
|
|
|
|
Compression: none
|
|
|
|
|
NarHash: sha256:" (bytevector->nix-base32-string
|
|
|
|
|
(sha256 (string->utf8 "Substitutable data."))) "
|
|
|
|
|
NarSize: 42
|
|
|
|
|
References: bar baz
|
|
|
|
|
Deriver: " (%store-prefix) "/foo.drv
|
|
|
|
|
System: mips64el-linux\n")))
|
|
|
|
|
(with-narinfo (string-append narinfo "Signature: "
|
|
|
|
|
(signature-field narinfo))
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(const #t)
|
|
|
|
|
(lambda ()
|
|
|
|
|
(define (compress input output compression)
|
|
|
|
|
(call-with-output-file output
|
|
|
|
|
(lambda (port)
|
|
|
|
|
(call-with-compressed-output-port compression port
|
|
|
|
|
(lambda (port)
|
|
|
|
|
(call-with-input-file input
|
|
|
|
|
(lambda (input)
|
|
|
|
|
(dump-port input port))))))))
|
|
|
|
|
|
|
|
|
|
(let ((nar (string-append %main-substitute-directory
|
|
|
|
|
"/example.nar")))
|
|
|
|
|
(compress nar (string-append nar ".gz") 'gzip)
|
Use "guile-zlib" and "guile-lzlib" instead of (guix config).
* Makefile.am (MODULES): Remove guix/zlib.scm and guix/lzlib.scm,
(SCM_TESTS): remove tests/zlib.scm, tests/lzlib.scm.
* build-aux/build-self.scm (make-config.scm): Remove unused %libz variable.
* configure.ac: Remove LIBZ and LIBLZ variables and check instead for
Guile-zlib and Guile-lzlib.
* doc/guix.texi ("Requirements"): Remove zlib requirement and add Guile-zlib
and Guile-lzlib instead.
* gnu/packages/package-management.scm (guix)[native-inputs]: Add "guile-zlib"
and "guile-lzlib",
[inputs]: remove "zlib" and "lzlib",
[propagated-inputs]: ditto,
[arguments]: add "guile-zlib" and "guile-lzlib" to Guile load path.
* guix/config.scm.in (%libz, %liblz): Remove them.
* guix/lzlib.scm: Remove it.
* guix/man-db.scm: Use (zlib) instead of (guix zlib).
* guix/profiles.scm (manual-database): Do not stub (guix config) in imported
modules list, instead add "guile-zlib" to the extension list.
* guix/scripts/publish.scm: Use (zlib) instead of (guix zlib) and (lzlib)
instead of (guix lzlib),
(string->compression-type, effective-compression): do not check for zlib and
lzlib availability.
* guix/scripts/substitute.scm (%compression-methods): Do not check for lzlib
availability.
* guix/self.scm (specification->package): Add "guile-zlib" and "guile-lzlib"
and remove "zlib" and "lzlib",
(compiled-guix): remove "zlib" and "lzlib" arguments and add guile-zlib and
guile-lzlib to the dependencies, also do not pass "zlib" and "lzlib" to
"make-config.scm" procedure,
(make-config.scm): remove "zlib" and "lzlib" arguments as well as %libz and
%liblz variables.
* guix/utils.scm (lzip-port): Use (lzlib) instead of (guix lzlib) and do not
check for lzlib availability.
* guix/zlib.scm: Remove it.
* m4/guix.m4 (GUIX_LIBZ_LIBDIR, GUIX_LIBLZ_FILE_NAME): Remove them.
* tests/lzlib.scm: Use (zlib) instead of (guix zlib) and (lzlib)
instead of (guix lzlib), and do not check for zlib and lzlib availability.
* tests/publish.scm: Ditto.
* tests/substitute.scm: Do not check for lzlib availability.
* tests/utils.scm: Ditto.
* tests/zlib.scm: Remove it.
2020-07-27 10:36:39 -04:00
|
|
|
|
(compress nar (string-append nar ".lz") 'lzip))
|
2019-05-31 10:26:08 -04:00
|
|
|
|
|
|
|
|
|
(parameterize ((substitute-urls
|
|
|
|
|
(list (string-append "file://"
|
|
|
|
|
%main-substitute-directory))))
|
daemon: Run 'guix substitute --substitute' as an agent.
This avoids spawning one substitute process per substitution.
* nix/libstore/build.cc (class Worker)[substituter]: New field.
[outPipe, logPipe, pid]: Remove.
(class SubstitutionGoal)[expectedHashStr, status, substituter]: New fields.
(SubstitutionGoal::timedOut): Adjust to check 'substituter'.
(SubstitutionGoal::tryToRun): Remove references to 'outPipe' and
'logPipe'. Run "guix substitute --substitute" as an 'Agent'. Send the
request with 'writeLine'.
(SubstitutionGoal::finished): Likewise.
(SubstitutionGoal::handleChildOutput): Change to fill in
'expectedHashStr' and 'status'.
(SubstitutionGoal::handleEOF): Call 'wakeUp' unconditionally.
(SubstitutionGoal::~SubstitutionGoal): Adjust to check 'substituter'.
* guix/scripts/substitute.scm (process-substitution): Write "success\n"
to stdout upon success.
(%error-to-file-descriptor-4?): New variable.
(guix-substitute): Set 'current-error-port' to file descriptor 4
unless (%error-to-file-descriptor-4?) is false.
Remove "--substitute" arguments. Loop reading line from stdin.
* tests/substitute.scm <top level>: Call '%error-to-file-descriptor-4?'.
(request-substitution): New procedure.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key")
("substitute, authorized key")
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, two invalid narinfos")
("substitute, narinfo with several URLs"): Adjust to new "guix
substitute --substitute" calling convention.
2020-12-02 10:27:34 -05:00
|
|
|
|
(request-substitution (string-append (%store-prefix)
|
|
|
|
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
|
|
|
|
"substitute-retrieved"))
|
2019-05-31 10:26:08 -04:00
|
|
|
|
(call-with-input-file "substitute-retrieved" get-string-all))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(false-if-exception (delete-file "substitute-retrieved")))))))
|
|
|
|
|
|
2015-03-25 05:34:27 -04:00
|
|
|
|
(test-end "substitute")
|
2014-03-28 19:06:41 -04:00
|
|
|
|
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
;;; Local Variables:
|
|
|
|
|
;;; eval: (put 'with-narinfo 'scheme-indent-function 1)
|
substitute: Download from unauthorized sources that provide the right content.
This allows substitutes to be downloaded from unauthorized servers, as
long as they advertise the same hash and references as one of the
authorized servers.
* guix/scripts/substitute.scm (assert-valid-narinfo): Remove.
(valid-narinfo?): Add #:verbose?. Handle each case of
'signature-case'.
(equivalent-narinfo?): New procedure.
(lookup-narinfos/diverse): Add 'authorized?' parameter and honor it.
[select-hit]: New procedure.
(lookup-narinfo): Add 'authorized?' parameter and pass it.
(process-query): Adjust callers accordingly.
(process-substitution): Remove call to 'assert-valid-narinfo'. Check
whether 'lookup-narinfo' returns true and call 'leave' if not.
* tests/substitute.scm (%main-substitute-directory)
(%alternate-substitute-directory): New variables.
(call-with-narinfo): Make 'narinfo-directory' a parameter. Call
'mkdir-p' to create it. Change unwind handler to check whether
CACHE-DIRECTORY exists before deleting it.
(with-narinfo*): New macro.
("substitute, no signature")
("substitute, invalid hash")
("substitute, unauthorized key"): Change expected error message to "no
valid substitute".
("substitute, unauthorized narinfo comes first")
("substitute, unsigned narinfo comes first")
("substitute, first narinfo is unsigned and has wrong hash")
("substitute, first narinfo is unsigned and has wrong refs")
("substitute, unsigned narinfo comes first")
("substitute, two invalid narinfos"): New tests.
* doc/guix.texi (Substitutes): Explain the new behavior.
2017-08-31 18:15:31 -04:00
|
|
|
|
;;; eval: (put 'with-narinfo* 'scheme-indent-function 2)
|
2014-03-30 16:25:47 -04:00
|
|
|
|
;;; eval: (put 'test-quit 'scheme-indent-function 2)
|
substitute-binary: Defer narinfo authentication and authorization checks.
* guix/scripts/substitute-binary.scm (narinfo-signature->canonical-sexp):
Catch 'gcry-error' around 'string->canonical-sexp' call, and re-raise
as a SRFI-35 &message and &nar-signature-error.
(narinfo-maker): Handle when SIGNATURE is #f or an invalid canonical
sexp.
(&nar-signature-error, &nar-invalid-hash-error): New variables.
(assert-valid-signature): Use them. Expect 'signature' to be a
canonical sexp.
(read-narinfo): Remove authentication and authorization checks.
(%signature-line-rx): New variable.
(assert-valid-narinfo, valid-narinfo?): New procedures.
(guix-substitute-binary): Wrap body in 'with-error-handling'.
[valid?]: New procedure.
<--query>: Show only store items of narinfos that match
'valid-narinfo?'.
<--substitute>: Call 'assert-valid-narinfo'.
* tests/substitute-binary.scm (test-error*): Use 'test-equal'.
(%keypair): Remove.
(%public-key, %private-key): Load from signing-key.{pub,sec}.
(signature-body): Add #:public-key parameter.
(call-with-narinfo): New procedure.
(with-narinfo): New macro.
("corrupt signature data", "unauthorized public key", "invalid
signature"): Make the first argument to 'assert-valid-signature' a
canonical sexp.
("invalid hash", "valid read-narinfo", "valid write-narinfo"):
Remove.
("query narinfo with invalid hash", "query narinfo signed with
authorized key", "query narinfo signed with unauthorized key",
"substitute, invalid hash", "substitute, unauthorized key"): New
tests.
2014-03-30 16:29:35 -04:00
|
|
|
|
;;; End:
|