nix verify: Support checking against signatures in other stores
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
This commit is contained in:
parent
88541569a2
commit
39a6abc0bc
1 changed files with 33 additions and 2 deletions
|
@ -14,17 +14,24 @@ struct MixVerify : virtual Args
|
||||||
{
|
{
|
||||||
bool noContents = false;
|
bool noContents = false;
|
||||||
bool noSigs = false;
|
bool noSigs = false;
|
||||||
|
Strings substituterUris;
|
||||||
|
|
||||||
MixVerify()
|
MixVerify()
|
||||||
{
|
{
|
||||||
mkFlag(0, "no-contents", "do not verify the contents of each store path", &noContents);
|
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-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> store, const Paths & storePaths)
|
void verifyPaths(ref<Store> store, const Paths & storePaths)
|
||||||
{
|
{
|
||||||
restoreAffinity(); // FIXME
|
restoreAffinity(); // FIXME
|
||||||
|
|
||||||
|
std::vector<ref<Store>> substituters;
|
||||||
|
for (auto & s : substituterUris)
|
||||||
|
substituters.push_back(openStoreAt(s));
|
||||||
|
|
||||||
auto publicKeys = getDefaultPublicKeys();
|
auto publicKeys = getDefaultPublicKeys();
|
||||||
|
|
||||||
std::atomic<size_t> untrusted{0};
|
std::atomic<size_t> untrusted{0};
|
||||||
|
@ -56,7 +63,9 @@ struct MixVerify : virtual Args
|
||||||
|
|
||||||
auto doPath = [&](const Path & storePath) {
|
auto doPath = [&](const Path & storePath) {
|
||||||
try {
|
try {
|
||||||
progressBar.startActivity(format("checking ‘%s’") % storePath);
|
checkInterrupt();
|
||||||
|
|
||||||
|
auto activity(progressBar.startActivity(format("checking ‘%s’") % storePath));
|
||||||
|
|
||||||
auto info = store->queryPathInfo(storePath);
|
auto info = store->queryPathInfo(storePath);
|
||||||
|
|
||||||
|
@ -78,7 +87,29 @@ struct MixVerify : virtual Args
|
||||||
|
|
||||||
if (!noSigs) {
|
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++;
|
untrusted++;
|
||||||
printMsg(lvlError, format("path ‘%s’ is untrusted") % storePath);
|
printMsg(lvlError, format("path ‘%s’ is untrusted") % storePath);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue