From c6185b4dc1fe87018d6129fc908791c0d2b37f82 Mon Sep 17 00:00:00 2001 From: Astro Date: Tue, 20 Oct 2020 16:05:33 +0200 Subject: [PATCH 2/2] sign narinfo on the fly --- src/lib/Hydra/Controller/Root.pm | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm index 2df4323a..251800b2 100644 --- a/src/lib/Hydra/Controller/Root.pm +++ b/src/lib/Hydra/Controller/Root.pm @@ -10,12 +10,13 @@ use Hydra::View::TT; use Digest::SHA1 qw(sha1_hex); use Nix::Store; use Nix::Config; +use Nix::Utils; +use Nix::Manifest; use Encode; use File::Basename; use JSON; use List::MoreUtils qw{any}; use Net::Prometheus; -use IO::Handle; # Put this controller at top-level. __PACKAGE__->config->{namespace} = ''; @@ -321,7 +322,7 @@ sub nar :Local :Args(1) { $c->stash->{storePath} = $path; } - elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+(.+)") { + elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+([^\?]+)") { $c->response->content_type('application/x-nix-archive'); $path = "/" . $1 . "/nar/$path"; @@ -380,13 +381,32 @@ sub narinfo :LocalRegex('^([a-z0-9]+).narinfo$') :Args(0) { $c->forward('Hydra::View::NARInfo'); } - elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+(.+)") { + elsif (isLocalBinaryCacheStore && getStoreUri =~ "^file:/+([^\?]+)") { $c->response->content_type('application/x-nix-archive'); + setCacheHeaders($c, 24 * 60 * 60); my $path = "/" . $1 . "/" . $hash . ".narinfo"; - my $fh = new IO::Handle; - open $fh, "<", $path; - $c->response->body($fh); + my $secretKeyFile = $c->config->{binary_cache_secret_key_file}; + if (! defined $secretKeyFile && getStoreUri =~ "[\?\&]secret-key=([^\?\&]+)") { + $secretKeyFile = $1; + } + if (defined $secretKeyFile) { + # Optionally, sign the NAR info file + my $secretKey = readFile $secretKeyFile; + my $storePath = queryPathFromHashPart($hash); + my ($deriver, $narHash, $time, $narSize, $refs) = queryPathInfo($storePath, 1); + my $fingerprint = fingerprintPath($storePath, $narHash, $narSize, $refs); + my $sig = signString($secretKey, $fingerprint); + + my $info = readFile $path; + $info .= "Sig: $sig\n"; + $c->response->body($info); + } + else { + my $fh = new IO::Handle; + open $fh, "<", $path; + $c->response->body($fh); + } } else { -- 2.28.0