publish: Do not sign the URL/Compression/FileSize narinfo fields.
This will allow mirror operators to alter these non-normative bits of a narinfo without having to resign narinfos. * guix/scripts/publish.scm (narinfo-string): Remove URL/Compression/FileSize from BASE-INFO. Move them after "Signature". * tests/publish.scm ("/*.narinfo") ("/*.narinfo with properly encoded '+' sign") ("/*.narinfo with lzip + gzip") ("with cache, lzip + gzip"): Adjust accordingly. * tests/substitute.scm ("query narinfo with signature over relevant subset"): New test.
parent
ca87601dd9
commit
6adce1538d
|
@ -1,7 +1,7 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2015 David Thompson <davet@gnu.org>
|
;;; Copyright © 2015 David Thompson <davet@gnu.org>
|
||||||
;;; Copyright © 2020 by Amar M. Singh <nly@disroot.org>
|
;;; Copyright © 2020 by Amar M. Singh <nly@disroot.org>
|
||||||
;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2015-2022 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
||||||
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com>
|
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com>
|
||||||
;;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
|
;;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
|
||||||
|
@ -345,20 +345,10 @@ much needs to be downloaded."
|
||||||
(base-info (format #f
|
(base-info (format #f
|
||||||
"\
|
"\
|
||||||
StorePath: ~a
|
StorePath: ~a
|
||||||
~{~a~}\
|
|
||||||
NarHash: sha256:~a
|
NarHash: sha256:~a
|
||||||
NarSize: ~d
|
NarSize: ~d
|
||||||
References: ~a~%"
|
References: ~a~%"
|
||||||
store-path
|
store-path
|
||||||
(map (lambda (compression)
|
|
||||||
(let ((size (assoc-ref file-sizes
|
|
||||||
compression)))
|
|
||||||
(store-item->recutils store-path
|
|
||||||
#:file-size size
|
|
||||||
#:nar-path nar-path
|
|
||||||
#:compression
|
|
||||||
compression)))
|
|
||||||
compressions)
|
|
||||||
hash size references))
|
hash size references))
|
||||||
;; Do not render a "Deriver" line if we are rendering info for a
|
;; Do not render a "Deriver" line if we are rendering info for a
|
||||||
;; derivation. Also do not render a "System" line that would be
|
;; derivation. Also do not render a "System" line that would be
|
||||||
|
@ -369,7 +359,22 @@ References: ~a~%"
|
||||||
base-info (basename deriver))))
|
base-info (basename deriver))))
|
||||||
(signature (base64-encode-string
|
(signature (base64-encode-string
|
||||||
(canonical-sexp->string (signed-string info)))))
|
(canonical-sexp->string (signed-string info)))))
|
||||||
(format #f "~aSignature: 1;~a;~a~%" info (gethostname) signature)))
|
(format #f "~aSignature: 1;~a;~a~%~{~a~}"
|
||||||
|
info (gethostname) signature
|
||||||
|
|
||||||
|
;; Move information about the actual nars
|
||||||
|
;; (URL/Compression/FileSize) *after* the normative part that is
|
||||||
|
;; signed. That makes it possible to alter these bits of the
|
||||||
|
;; narinfo without having to resign them.
|
||||||
|
(map (lambda (compression)
|
||||||
|
(let ((size (assoc-ref file-sizes
|
||||||
|
compression)))
|
||||||
|
(store-item->recutils store-path
|
||||||
|
#:file-size size
|
||||||
|
#:nar-path nar-path
|
||||||
|
#:compression
|
||||||
|
compression)))
|
||||||
|
compressions))))
|
||||||
|
|
||||||
(define* (not-found request
|
(define* (not-found request
|
||||||
#:key (phrase "Resource not found")
|
#:key (phrase "Resource not found")
|
||||||
|
|
|
@ -142,15 +142,10 @@
|
||||||
(unsigned-info
|
(unsigned-info
|
||||||
(format #f
|
(format #f
|
||||||
"StorePath: ~a
|
"StorePath: ~a
|
||||||
URL: nar/~a
|
|
||||||
Compression: none
|
|
||||||
FileSize: ~a
|
|
||||||
NarHash: sha256:~a
|
NarHash: sha256:~a
|
||||||
NarSize: ~d
|
NarSize: ~d
|
||||||
References: ~a~%"
|
References: ~a~%"
|
||||||
%item
|
%item
|
||||||
(basename %item)
|
|
||||||
(path-info-nar-size info)
|
|
||||||
(bytevector->nix-base32-string
|
(bytevector->nix-base32-string
|
||||||
(path-info-hash info))
|
(path-info-hash info))
|
||||||
(path-info-nar-size info)
|
(path-info-nar-size info)
|
||||||
|
@ -159,8 +154,13 @@ References: ~a~%"
|
||||||
(string->utf8
|
(string->utf8
|
||||||
(canonical-sexp->string
|
(canonical-sexp->string
|
||||||
(signed-string unsigned-info))))))
|
(signed-string unsigned-info))))))
|
||||||
(format #f "~aSignature: 1;~a;~a~%"
|
(format #f "~aSignature: 1;~a;~a
|
||||||
unsigned-info (gethostname) signature))
|
URL: nar/~a
|
||||||
|
Compression: none
|
||||||
|
FileSize: ~a\n"
|
||||||
|
unsigned-info (gethostname) signature
|
||||||
|
(basename %item)
|
||||||
|
(path-info-nar-size info)))
|
||||||
(utf8->string
|
(utf8->string
|
||||||
(http-get-body
|
(http-get-body
|
||||||
(publish-uri
|
(publish-uri
|
||||||
|
@ -173,15 +173,10 @@ References: ~a~%"
|
||||||
(unsigned-info
|
(unsigned-info
|
||||||
(format #f
|
(format #f
|
||||||
"StorePath: ~a
|
"StorePath: ~a
|
||||||
URL: nar/~a
|
|
||||||
Compression: none
|
|
||||||
FileSize: ~a
|
|
||||||
NarHash: sha256:~a
|
NarHash: sha256:~a
|
||||||
NarSize: ~d
|
NarSize: ~d
|
||||||
References: ~%"
|
References: ~%"
|
||||||
item
|
item
|
||||||
(uri-encode (basename item))
|
|
||||||
(path-info-nar-size info)
|
|
||||||
(bytevector->nix-base32-string
|
(bytevector->nix-base32-string
|
||||||
(path-info-hash info))
|
(path-info-hash info))
|
||||||
(path-info-nar-size info)))
|
(path-info-nar-size info)))
|
||||||
|
@ -189,8 +184,13 @@ References: ~%"
|
||||||
(string->utf8
|
(string->utf8
|
||||||
(canonical-sexp->string
|
(canonical-sexp->string
|
||||||
(signed-string unsigned-info))))))
|
(signed-string unsigned-info))))))
|
||||||
(format #f "~aSignature: 1;~a;~a~%"
|
(format #f "~aSignature: 1;~a;~a
|
||||||
unsigned-info (gethostname) signature))
|
URL: nar/~a
|
||||||
|
Compression: none
|
||||||
|
FileSize: ~a~%"
|
||||||
|
unsigned-info (gethostname) signature
|
||||||
|
(uri-encode (basename item))
|
||||||
|
(path-info-nar-size info)))
|
||||||
|
|
||||||
(let ((item (add-text-to-store %store "fake-gtk+" "Congrats!")))
|
(let ((item (add-text-to-store %store "fake-gtk+" "Congrats!")))
|
||||||
(utf8->string
|
(utf8->string
|
||||||
|
@ -324,7 +324,12 @@ References: ~%"
|
||||||
(part (store-path-hash-part %item))
|
(part (store-path-hash-part %item))
|
||||||
(url (string-append base part ".narinfo"))
|
(url (string-append base part ".narinfo"))
|
||||||
(body (http-get-port url)))
|
(body (http-get-port url)))
|
||||||
(list (take (recutils->alist body) 5)
|
(list (filter (match-lambda
|
||||||
|
(("StorePath" . _) #t)
|
||||||
|
(("URL" . _) #t)
|
||||||
|
(("Compression" . _) #t)
|
||||||
|
(_ #f))
|
||||||
|
(recutils->alist body))
|
||||||
(response-code
|
(response-code
|
||||||
(http-get (string-append base "nar/gzip/"
|
(http-get (string-append base "nar/gzip/"
|
||||||
(basename %item))))
|
(basename %item))))
|
||||||
|
@ -504,16 +509,22 @@ References: ~%"
|
||||||
(basename %item))))
|
(basename %item))))
|
||||||
(and (file-exists? (nar "gzip"))
|
(and (file-exists? (nar "gzip"))
|
||||||
(file-exists? (nar "lzip"))
|
(file-exists? (nar "lzip"))
|
||||||
(equal? (take (pk 'narinfo/gzip+lzip narinfo) 7)
|
(match (pk 'narinfo/gzip+lzip narinfo)
|
||||||
`(("StorePath" . ,%item)
|
((("StorePath" . path)
|
||||||
("URL" . ,(nar-url "gzip"))
|
_ ...
|
||||||
("Compression" . "gzip")
|
("Signature" . _)
|
||||||
("FileSize" . ,(number->string
|
("URL" . gzip-url)
|
||||||
(stat:size (stat (nar "gzip")))))
|
("Compression" . "gzip")
|
||||||
("URL" . ,(nar-url "lzip"))
|
("FileSize" . (= string->number gzip-size))
|
||||||
("Compression" . "lzip")
|
("URL" . lzip-url)
|
||||||
("FileSize" . ,(number->string
|
("Compression" . "lzip")
|
||||||
(stat:size (stat (nar "lzip")))))))
|
("FileSize" . (= string->number lzip-size)))
|
||||||
|
(and (string=? gzip-url (nar-url "gzip"))
|
||||||
|
(string=? lzip-url (nar-url "lzip"))
|
||||||
|
(= gzip-size
|
||||||
|
(stat:size (stat (nar "gzip"))))
|
||||||
|
(= lzip-size
|
||||||
|
(stat:size (stat (nar "lzip")))))))
|
||||||
(list (response-code
|
(list (response-code
|
||||||
(http-get (string-append base (nar-url "gzip"))))
|
(http-get (string-append base (nar-url "gzip"))))
|
||||||
(response-code
|
(response-code
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2014 Nikita Karetnikov <nikita@karetnikov.org>
|
;;; Copyright © 2014 Nikita Karetnikov <nikita@karetnikov.org>
|
||||||
;;; Copyright © 2014, 2015, 2017, 2018, 2019, 2021 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2014-2015, 2017-2019, 2021-2022 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -268,6 +268,29 @@ System: mips64el-linux\n")
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(guix-substitute "--query")))))))))
|
(guix-substitute "--query")))))))))
|
||||||
|
|
||||||
|
(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")))))))))
|
||||||
|
|
||||||
(test-equal "query narinfo signed with authorized key"
|
(test-equal "query narinfo signed with authorized key"
|
||||||
(string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
(string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
||||||
|
|
||||||
|
|
Reference in New Issue