aboutsummaryrefslogtreecommitdiff
path: root/guix-build-coordinator/agent-messaging
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2021-11-14 12:28:17 +0000
committerChristopher Baines <mail@cbaines.net>2021-11-14 12:28:17 +0000
commitaf7a43933347ee3a362490315ec9e4d12dfff884 (patch)
tree2907f63da02d1ed82da026c00fcd4bc85fe5fbe3 /guix-build-coordinator/agent-messaging
parentd0611a4054fb1baa0360a30a482562f24000e122 (diff)
downloadbuild-coordinator-af7a43933347ee3a362490315ec9e4d12dfff884.tar
build-coordinator-af7a43933347ee3a362490315ec9e4d12dfff884.tar.gz
Start checking the hashes of submitted outputs
This provides some extra safety on top of the guarantees from TCP around the integrity of the data received. I'm introducing this now in preparation for supporting resuming partial uploads. Because this will add some extra complexity around receiving uploads, this extra check should ensure that issues with the implementation cannot lead to corrupt uploads.
Diffstat (limited to 'guix-build-coordinator/agent-messaging')
-rw-r--r--guix-build-coordinator/agent-messaging/http/server.scm53
1 files changed, 36 insertions, 17 deletions
diff --git a/guix-build-coordinator/agent-messaging/http/server.scm b/guix-build-coordinator/agent-messaging/http/server.scm
index 23fa120..a21ae80 100644
--- a/guix-build-coordinator/agent-messaging/http/server.scm
+++ b/guix-build-coordinator/agent-messaging/http/server.scm
@@ -36,7 +36,10 @@
#:use-module (web request)
#:use-module (web response)
#:use-module (web uri)
+ #:use-module (lzlib)
+ #:use-module (gcrypt hash)
#:use-module (prometheus)
+ #:use-module (guix base32)
#:use-module (guix base64)
#:use-module (guix build utils)
#:use-module (guix-build-coordinator utils)
@@ -444,9 +447,16 @@ port. Also, the port used can be changed by passing the --port option.\n"
0.1)))
bytes-read)
last-progress-update-bytes-read))))))))
- (rename-file tmp-output-file-name
- output-file-name)
- #t)))
+
+ ;; Compute the hash of the file
+ (let ((hash (bytevector->nix-base32-string
+ (call-with-input-file tmp-output-file-name
+ (lambda (compressed-port)
+ (call-with-lzip-input-port compressed-port
+ port-sha256))))))
+ (rename-file tmp-output-file-name
+ output-file-name)
+ hash))))
(if (authenticated? agent-id-for-build request)
(let* ((output-file-name
@@ -456,20 +466,29 @@ port. Also, the port used can be changed by passing the --port option.\n"
(mkdir-p (dirname output-file-name))
(when (file-exists? tmp-output-file-name)
(delete-file tmp-output-file-name))
- (if (if (bytevector? body)
- (begin
- (call-with-output-file tmp-output-file-name
- (lambda (output-port)
- (put-bytevector output-port body)))
- (rename-file tmp-output-file-name
- output-file-name)
- #t)
- (receive-file output-file-name
- tmp-output-file-name))
- (no-content)
- (render-json
- "error"
- #:code 500)))
+ (let ((hash
+ (if (bytevector? body)
+ (begin
+ (call-with-output-file tmp-output-file-name
+ (lambda (output-port)
+ (put-bytevector output-port body)))
+
+ (let ((hash (bytevector->nix-base32-string
+ (call-with-input-file tmp-output-file-name
+ (lambda (compressed-port)
+ (call-with-lzip-input-port compressed-port
+ port-sha256))))))
+ (rename-file tmp-output-file-name
+ output-file-name)
+ hash))
+ (receive-file output-file-name
+ tmp-output-file-name))))
+
+ (call-with-output-file (string-append output-file-name ".hash")
+ (lambda (port)
+ (simple-format port "~A\n" hash)))
+
+ (no-content)))
(render-json
'(("error" . "access denied"))
#:code 403))))