diff --git a/lix/libstore/local-store.cc b/lix/libstore/local-store.cc index e52f562ab..6124f15e0 100644 --- a/lix/libstore/local-store.cc +++ b/lix/libstore/local-store.cc @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -173,7 +174,6 @@ void migrateCASchema(SQLite& db, Path schemaPath, AutoCloseFD& lockFd) LocalStore::LocalStore(LocalStoreConfig config) : Store(config) , config_(std::move(config)) - , publicKeys(getDefaultPublicKeys()) , dbDir(config_.stateDir + "/db") , linksDir(config_.realStoreDir + "/.links") , reservedSpacePath(dbDir + "/reserved") @@ -1173,14 +1173,22 @@ void LocalStore::invalidatePath(DBState & state, const StorePath & path) } } +const PublicKeys & LocalStore::getPublicKeys() +{ + std::call_once(publicKeysFlag, [](std::unique_ptr &pks) -> void { + pks = std::make_unique(getDefaultPublicKeys()); + }, publicKeys); + return *publicKeys; +} + bool LocalStore::pathInfoIsUntrusted(const ValidPathInfo & info) { - return config_.requireSigs && !info.checkSignatures(*this, publicKeys); + return config_.requireSigs && !info.checkSignatures(*this, getPublicKeys()); } bool LocalStore::realisationIsUntrusted(const Realisation & realisation) { - return config_.requireSigs && !realisation.checkSignatures(publicKeys); + return config_.requireSigs && !realisation.checkSignatures(getPublicKeys()); } void LocalStore::addToStore(const ValidPathInfo & info, Source & source, diff --git a/lix/libstore/local-store.hh b/lix/libstore/local-store.hh index a06f6daff..534036ac9 100644 --- a/lix/libstore/local-store.hh +++ b/lix/libstore/local-store.hh @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include @@ -80,7 +82,15 @@ private: */ AutoCloseFD globalLock; - const PublicKeys publicKeys; + /** + * Trusted public keys by this store. Initialized lazily by getPublicKeys(). + * + * Note that this lazy initialization is load-bearing: on the daemon, the + * store is initialized very early, before settings including + * trusted-public-keys are received from the client. + */ + std::unique_ptr publicKeys = nullptr; + std::once_flag publicKeysFlag; struct DBState { @@ -134,6 +144,10 @@ public: LocalStoreConfig & config() override { return config_; } const LocalStoreConfig & config() const override { return config_; } +private: + + const PublicKeys & getPublicKeys(); + protected: /** diff --git a/tests/functional/binary-cache-regression-fj647.sh b/tests/functional/binary-cache-regression-fj647.sh new file mode 100644 index 000000000..bc33ba2fe --- /dev/null +++ b/tests/functional/binary-cache-regression-fj647.sh @@ -0,0 +1,17 @@ +source common.sh +# Regression test for https://git.lix.systems/lix-project/lix/issues/647 + +# Create the binary cache. +clearStore +clearCache +outPath=$(nix-build dependencies.nix --no-out-link) + +nix key generate-secret --key-name test > "$TEST_ROOT/priv.key" +pubkey="$(nix key convert-secret-to-public < "$TEST_ROOT/priv.key")" +_NIX_FORCE_HTTP= nix copy --to file://$cacheDir?secret-key="$TEST_ROOT/priv.key" "$outPath" + +clearStore +startDaemon + +expect 1 nix-store -r --substituters file://$cacheDir "$outPath" +nix-store -r --trusted-public-keys "$pubkey" --substituters file://$cacheDir "$outPath" diff --git a/tests/functional/meson.build b/tests/functional/meson.build index e54daa1a3..2d905d79f 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -92,6 +92,7 @@ functional_tests_scripts = [ 'user-envs.sh', 'user-envs-migration.sh', 'binary-cache.sh', + 'binary-cache-regression-fj647.sh', 'multiple-outputs.sh', 'nix-build.sh', 'gc-concurrent.sh',