diff options
author | Christopher Baines <mail@cbaines.net> | 2021-11-14 12:28:17 +0000 |
---|---|---|
committer | Christopher Baines <mail@cbaines.net> | 2021-11-14 12:28:17 +0000 |
commit | af7a43933347ee3a362490315ec9e4d12dfff884 (patch) | |
tree | 2907f63da02d1ed82da026c00fcd4bc85fe5fbe3 /guix-build-coordinator/agent-messaging | |
parent | d0611a4054fb1baa0360a30a482562f24000e122 (diff) | |
download | build-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.scm | 53 |
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)))) |