From 39a6abc0bc2f1986f29e52de15ccbdde9586bc08 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 30 Mar 2016 11:18:54 +0200 Subject: [PATCH] nix verify: Support checking against signatures in other stores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typical usage is to check local paths using the signatures from a binary cache: $ nix verify-paths -r /run/current-system -s https://cache.nixos.org path ‘/nix/store/c1k4zqfb74wba5sn4yflb044gvap0x6k-nixos-system-mandark-16.03.git.fc2d7a5M’ is untrusted ... checked 844 paths, 119 untrusted --- src/nix/verify.cc | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 1bd2a000a..0c05f450a 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -14,17 +14,24 @@ struct MixVerify : virtual Args { bool noContents = false; bool noSigs = false; + Strings substituterUris; MixVerify() { mkFlag(0, "no-contents", "do not verify the contents of each store path", &noContents); mkFlag(0, "no-sigs", "do not verify whether each store path has a valid signature", &noSigs); + mkFlag('s', "substituter", {"store-uri"}, "use signatures from specified store", 1, + [&](Strings ss) { substituterUris.push_back(ss.front()); }); } void verifyPaths(ref store, const Paths & storePaths) { restoreAffinity(); // FIXME + std::vector> substituters; + for (auto & s : substituterUris) + substituters.push_back(openStoreAt(s)); + auto publicKeys = getDefaultPublicKeys(); std::atomic untrusted{0}; @@ -56,7 +63,9 @@ struct MixVerify : virtual Args auto doPath = [&](const Path & storePath) { try { - progressBar.startActivity(format("checking ‘%s’") % storePath); + checkInterrupt(); + + auto activity(progressBar.startActivity(format("checking ‘%s’") % storePath)); auto info = store->queryPathInfo(storePath); @@ -78,7 +87,29 @@ struct MixVerify : virtual Args if (!noSigs) { - if (!info.ultimate && !info.checkSignatures(publicKeys)) { + bool good = false; + + if (info.ultimate) + good = true; + + if (!good && info.checkSignatures(publicKeys)) + good = true; + + if (!good) { + for (auto & store2 : substituters) { + // FIXME: catch errors? + if (!store2->isValidPath(storePath)) continue; + auto info2 = store2->queryPathInfo(storePath); + auto info3(info); + info3.sigs = info2.sigs; + if (info3.checkSignatures(publicKeys)) { + good = true; + break; + } + } + } + + if (!good) { untrusted++; printMsg(lvlError, format("path ‘%s’ is untrusted") % storePath); }