From 05fbc606fc1ce4a764276b7dee6ed49859de9d57 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 7 Apr 2016 15:14:12 +0200 Subject: nix verify-paths: Add ‘--sigs-needed ’ flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This specifies the number of distinct signatures required to consider each path "trusted". Also renamed ‘--no-sigs’ to ‘--no-trust’ for the flag that disables verifying whether a path is trusted (since a path can also be trusted if it has no signatures, but was built locally). --- src/nix/verify.cc | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) (limited to 'src/nix/verify.cc') diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 0c05f450a493..9214d3b651d1 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -13,15 +13,17 @@ using namespace nix; struct MixVerify : virtual Args { bool noContents = false; - bool noSigs = false; + bool noTrust = false; Strings substituterUris; + size_t sigsNeeded; 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(0, "no-trust", "do not verify whether each store path is trusted", &noTrust); mkFlag('s', "substituter", {"store-uri"}, "use signatures from specified store", 1, [&](Strings ss) { substituterUris.push_back(ss.front()); }); + mkIntFlag('n', "sigs-needed", "require that each path has at least N valid signatures", &sigsNeeded); } void verifyPaths(ref store, const Paths & storePaths) @@ -85,28 +87,42 @@ struct MixVerify : virtual Args } - if (!noSigs) { + if (!noTrust) { bool good = false; - if (info.ultimate) + if (info.ultimate && !sigsNeeded) good = true; - if (!good && info.checkSignatures(publicKeys)) - good = true; + else { + + StringSet sigsSeen; + size_t actualSigsNeeded = sigsNeeded ? sigsNeeded : 1; + size_t validSigs = 0; + + auto doSigs = [&](StringSet sigs) { + for (auto sig : sigs) { + if (sigsSeen.count(sig)) continue; + sigsSeen.insert(sig); + if (info.checkSignature(publicKeys, sig)) + validSigs++; + } + }; + + doSigs(info.sigs); - 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 (validSigs >= actualSigsNeeded) break; + try { + if (!store2->isValidPath(storePath)) continue; + doSigs(store2->queryPathInfo(storePath).sigs); + } catch (Error & e) { + printMsg(lvlError, format(ANSI_RED "error:" ANSI_NORMAL " %s") % e.what()); } } + + if (validSigs >= actualSigsNeeded) + good = true; } if (!good) { -- cgit 1.4.1