Wire through the missingBlockIsIntegrityViolation setting

This commit is contained in:
Sebastian Messmer 2017-09-16 16:49:33 +01:00
parent b6ce7c3ae4
commit 5299be5dda
10 changed files with 52 additions and 31 deletions

View File

@ -228,7 +228,7 @@ namespace cryfs {
try {
auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir());
auto config = _loadOrCreateConfig(options);
CryDevice device(std::move(config.configFile), std::move(blockStore), config.myClientId, options.noIntegrityChecks());
CryDevice device(std::move(config.configFile), std::move(blockStore), config.myClientId, options.noIntegrityChecks(), config.configFile.config()->missingBlockIsIntegrityViolation());
_sanityCheckFilesystem(&device);
fspp::FilesystemImpl fsimpl(&device);
fspp::fuse::Fuse fuse(&fsimpl, "cryfs", "cryfs@"+options.baseDir().native());

View File

@ -149,6 +149,10 @@ void CryConfig::SetExclusiveClientId(optional<uint32_t> value) {
_exclusiveClientId = value;
}
bool CryConfig::missingBlockIsIntegrityViolation() const {
return _exclusiveClientId != boost::none;
}
#ifndef CRYFS_NO_COMPATIBILITY
bool CryConfig::HasVersionNumbers() const {
return _hasVersionNumbers;

View File

@ -44,6 +44,8 @@ public:
boost::optional<uint32_t> ExclusiveClientId() const;
void SetExclusiveClientId(boost::optional<uint32_t> value);
bool missingBlockIsIntegrityViolation() const;
#ifndef CRYFS_NO_COMPATIBILITY
// This is a trigger to recognize old file systems that didn't have version numbers.
// Version numbers cannot be disabled, but the file system will be migrated to version numbers automatically.

View File

@ -57,14 +57,14 @@ namespace bf = boost::filesystem;
namespace cryfs {
CryDevice::CryDevice(CryConfigFile configFile, unique_ref<BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks)
: _fsBlobStore(CreateFsBlobStore(std::move(blockStore), &configFile, myClientId, noIntegrityChecks)),
CryDevice::CryDevice(CryConfigFile configFile, unique_ref<BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation)
: _fsBlobStore(CreateFsBlobStore(std::move(blockStore), &configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation)),
_rootKey(GetOrCreateRootKey(&configFile)),
_onFsAction() {
}
unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CryDevice::CreateFsBlobStore(unique_ref<BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks) {
auto blobStore = CreateBlobStore(std::move(blockStore), configFile, myClientId, noIntegrityChecks);
unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CryDevice::CreateFsBlobStore(unique_ref<BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation) {
auto blobStore = CreateBlobStore(std::move(blockStore), configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation);
#ifndef CRYFS_NO_COMPATIBILITY
auto fsBlobStore = MigrateOrCreateFsBlobStore(std::move(blobStore), configFile);
@ -89,8 +89,8 @@ unique_ref<fsblobstore::FsBlobStore> CryDevice::MigrateOrCreateFsBlobStore(uniqu
}
#endif
unique_ref<blobstore::BlobStore> CryDevice::CreateBlobStore(unique_ref<BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks) {
auto integrityEncryptedBlockStore = CreateIntegrityEncryptedBlockStore(std::move(blockStore), configFile, myClientId, noIntegrityChecks);
unique_ref<blobstore::BlobStore> CryDevice::CreateBlobStore(unique_ref<BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation) {
auto integrityEncryptedBlockStore = CreateIntegrityEncryptedBlockStore(std::move(blockStore), configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation);
// Create integrityEncryptedBlockStore not in the same line as BlobStoreOnBlocks, because it can modify BlocksizeBytes
// in the configFile and therefore has to be run before the second parameter to the BlobStoreOnBlocks parameter is evaluated.
return make_unique_ref<BlobStoreOnBlocks>(
@ -102,7 +102,7 @@ unique_ref<blobstore::BlobStore> CryDevice::CreateBlobStore(unique_ref<BlockStor
configFile->config()->BlocksizeBytes());
}
unique_ref<BlockStore2> CryDevice::CreateIntegrityEncryptedBlockStore(unique_ref<BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks) {
unique_ref<BlockStore2> CryDevice::CreateIntegrityEncryptedBlockStore(unique_ref<BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation) {
auto encryptedBlockStore = CreateEncryptedBlockStore(*configFile->config(), std::move(blockStore));
auto statePath = LocalStateDir::forFilesystemId(configFile->config()->FilesystemId());
auto integrityFilePath = statePath / "integritydata";
@ -115,8 +115,8 @@ unique_ref<BlockStore2> CryDevice::CreateIntegrityEncryptedBlockStore(unique_ref
configFile->save();
}
#endif
return make_unique_ref<IntegrityBlockStore2>(std::move(encryptedBlockStore), integrityFilePath, myClientId, noIntegrityChecks, false);
return make_unique_ref<IntegrityBlockStore2>(std::move(encryptedBlockStore), integrityFilePath, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation);
}
Key CryDevice::CreateRootBlobAndReturnKey() {

View File

@ -18,7 +18,7 @@ namespace cryfs {
class CryDevice final: public fspp::Device {
public:
CryDevice(CryConfigFile config, cpputils::unique_ref<blockstore::BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks);
CryDevice(CryConfigFile config, cpputils::unique_ref<blockstore::BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override;
@ -53,12 +53,12 @@ private:
blockstore::Key GetOrCreateRootKey(CryConfigFile *config);
blockstore::Key CreateRootBlobAndReturnKey();
static cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CreateFsBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks);
static cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CreateFsBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
#ifndef CRYFS_NO_COMPATIBILITY
static cpputils::unique_ref<fsblobstore::FsBlobStore> MigrateOrCreateFsBlobStore(cpputils::unique_ref<blobstore::BlobStore> blobStore, CryConfigFile *configFile);
#endif
static cpputils::unique_ref<blobstore::BlobStore> CreateBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks);
static cpputils::unique_ref<blockstore::BlockStore2> CreateIntegrityEncryptedBlockStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks);
static cpputils::unique_ref<blobstore::BlobStore> CreateBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
static cpputils::unique_ref<blockstore::BlockStore2> CreateIntegrityEncryptedBlockStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
static cpputils::unique_ref<blockstore::BlockStore2> CreateEncryptedBlockStore(const CryConfig &config, cpputils::unique_ref<blockstore::BlockStore2> baseBlockStore);
struct BlobWithParent {

View File

@ -21,7 +21,7 @@ using cpputils::make_unique_ref;
using cpputils::unique_ref;
using cpputils::TempFile;
template<bool MissingBlockIsIntegrityViolation>
template<bool NoIntegrityChecks, bool MissingBlockIsIntegrityViolation>
class IntegrityBlockStoreTestFixture: public BlockStoreTestFixture {
public:
IntegrityBlockStoreTestFixture() :stateFile(false) {}
@ -29,26 +29,41 @@ public:
TempFile stateFile;
unique_ref<BlockStore> createBlockStore() override {
return make_unique_ref<LowToHighLevelBlockStore>(
make_unique_ref<IntegrityBlockStore2>(make_unique_ref<InMemoryBlockStore2>(), stateFile.path(), 0x12345678, MissingBlockIsIntegrityViolation)
make_unique_ref<IntegrityBlockStore2>(make_unique_ref<InMemoryBlockStore2>(), stateFile.path(), 0x12345678, NoIntegrityChecks, MissingBlockIsIntegrityViolation)
);
}
};
using IntegrityBlockStoreTestFixture_multiclient = IntegrityBlockStoreTestFixture<false, false>;
using IntegrityBlockStoreTestFixture_singleclient = IntegrityBlockStoreTestFixture<false, true>;
using IntegrityBlockStoreTestFixture_multiclient_noIntegrityChecks = IntegrityBlockStoreTestFixture<true, false>;
using IntegrityBlockStoreTestFixture_singleclient_noIntegrityChecks = IntegrityBlockStoreTestFixture<true, true>;
// TODO Why is here no IntegrityBlockStoreWithRandomKeysTest?
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_multiclient, BlockStoreTest, IntegrityBlockStoreTestFixture<false>);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_singleclient, BlockStoreTest, IntegrityBlockStoreTestFixture<true>);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_multiclient, BlockStoreTest, IntegrityBlockStoreTestFixture_multiclient);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_singleclient, BlockStoreTest, IntegrityBlockStoreTestFixture_singleclient);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_multiclient_noIntegrityChecks, BlockStoreTest, IntegrityBlockStoreTestFixture_multiclient_noIntegrityChecks);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_singleclient_noIntegrityChecks, BlockStoreTest, IntegrityBlockStoreTestFixture_singleclient_noIntegrityChecks);
template<bool MissingBlockIsIntegrityViolation>
template<bool NoIntegrityChecks, bool MissingBlockIsIntegrityViolation>
class IntegrityBlockStore2TestFixture: public BlockStore2TestFixture {
public:
IntegrityBlockStore2TestFixture() :stateFile(false) {}
TempFile stateFile;
unique_ref<BlockStore2> createBlockStore() override {
return make_unique_ref<IntegrityBlockStore2>(make_unique_ref<InMemoryBlockStore2>(), stateFile.path(), 0x12345678, MissingBlockIsIntegrityViolation);
return make_unique_ref<IntegrityBlockStore2>(make_unique_ref<InMemoryBlockStore2>(), stateFile.path(), 0x12345678, NoIntegrityChecks, MissingBlockIsIntegrityViolation);
}
};
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_multiclient, BlockStore2Test, IntegrityBlockStore2TestFixture<false>);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_singleclient, BlockStore2Test, IntegrityBlockStore2TestFixture<true>);
using IntegrityBlockStore2TestFixture_multiclient = IntegrityBlockStore2TestFixture<false, false>;
using IntegrityBlockStore2TestFixture_singleclient = IntegrityBlockStore2TestFixture<false, true>;
using IntegrityBlockStore2TestFixture_multiclient_noIntegrityChecks = IntegrityBlockStore2TestFixture<true, false>;
using IntegrityBlockStore2TestFixture_singleclient_noIntegrityChecks = IntegrityBlockStore2TestFixture<true, true>;
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_multiclient, BlockStore2Test, IntegrityBlockStore2TestFixture_multiclient);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_singleclient, BlockStore2Test, IntegrityBlockStore2TestFixture_singleclient);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_multiclient_noIntegrityChecks, BlockStore2Test, IntegrityBlockStore2TestFixture_multiclient_noIntegrityChecks);
INSTANTIATE_TYPED_TEST_CASE_P(Integrity_singleclient_noIntegrityChecks, BlockStore2Test, IntegrityBlockStore2TestFixture_singleclient_noIntegrityChecks);

View File

@ -27,7 +27,7 @@ public:
IntegrityBlockStoreTest():
stateFile(false),
baseBlockStore(new InMemoryBlockStore2),
blockStore(make_unique_ref<IntegrityBlockStore2>(std::move(cpputils::nullcheck(std::unique_ptr<InMemoryBlockStore2>(baseBlockStore)).value()), stateFile.path(), myClientId, false)),
blockStore(make_unique_ref<IntegrityBlockStore2>(std::move(cpputils::nullcheck(std::unique_ptr<InMemoryBlockStore2>(baseBlockStore)).value()), stateFile.path(), myClientId, false, false)),
data(DataFixture::generate(BLOCKSIZE)) {
}
static constexpr uint32_t myClientId = 0x12345678;
@ -38,13 +38,13 @@ public:
std::pair<InMemoryBlockStore2 *, unique_ptr<IntegrityBlockStore2>> makeBlockStoreWithDeletionPrevention() {
InMemoryBlockStore2 *baseBlockStore = new InMemoryBlockStore2;
auto blockStore = make_unique<IntegrityBlockStore2>(std::move(cpputils::nullcheck(std::unique_ptr<InMemoryBlockStore2>(baseBlockStore)).value()), stateFile.path(), myClientId, true);
auto blockStore = make_unique<IntegrityBlockStore2>(std::move(cpputils::nullcheck(std::unique_ptr<InMemoryBlockStore2>(baseBlockStore)).value()), stateFile.path(), myClientId, false, true);
return std::make_pair(baseBlockStore, std::move(blockStore));
}
std::pair<InMemoryBlockStore2 *, unique_ptr<IntegrityBlockStore2>> makeBlockStoreWithoutDeletionPrevention() {
InMemoryBlockStore2 *baseBlockStore = new InMemoryBlockStore2;
auto blockStore = make_unique<IntegrityBlockStore2>(std::move(cpputils::nullcheck(std::unique_ptr<InMemoryBlockStore2>(baseBlockStore)).value()), stateFile.path(), myClientId, false);
auto blockStore = make_unique<IntegrityBlockStore2>(std::move(cpputils::nullcheck(std::unique_ptr<InMemoryBlockStore2>(baseBlockStore)).value()), stateFile.path(), myClientId, false, false);
return std::make_pair(baseBlockStore, std::move(blockStore));
}

View File

@ -56,20 +56,20 @@ public:
TEST_F(CryFsTest, CreatedRootdirIsLoadableAfterClosing) {
{
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678);
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
}
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678);
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
auto rootDir = dev.LoadDir(bf::path("/"));
rootDir.value()->children();
}
TEST_F(CryFsTest, LoadingFilesystemDoesntModifyConfigFile) {
{
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678);
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
}
Data configAfterCreating = Data::LoadFromFile(config.path()).value();
{
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678);
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
}
Data configAfterLoading = Data::LoadFromFile(config.path()).value();
EXPECT_EQ(configAfterCreating, configAfterLoading);

View File

@ -32,7 +32,7 @@ public:
auto askPassword = [] {return "mypassword";};
auto config = CryConfigLoader(make_shared<NoninteractiveConsole>(mockConsole()), Random::PseudoRandom(), SCrypt::TestSettings, askPassword, askPassword, none, none, none)
.loadOrCreate(configFile.path()).value();
return make_unique_ref<CryDevice>(std::move(config.configFile), std::move(blockStore), config.myClientId);
return make_unique_ref<CryDevice>(std::move(config.configFile), std::move(blockStore), config.myClientId, false, false);
}
cpputils::TempFile configFile;

View File

@ -11,7 +11,7 @@ class CryTestBase : public TestWithFakeHomeDirectory {
public:
CryTestBase(): _configFile(false), _device(nullptr) {
auto fakeBlockStore = cpputils::make_unique_ref<blockstore::inmemory::InMemoryBlockStore2>();
_device = std::make_unique<cryfs::CryDevice>(configFile(), std::move(fakeBlockStore), 0x12345678);
_device = std::make_unique<cryfs::CryDevice>(configFile(), std::move(fakeBlockStore), 0x12345678, false, false);
}
cryfs::CryConfigFile configFile() {