From b8380462460af4bb4f4d68d4a27f85635093d38b Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sun, 26 Jun 2016 15:23:00 -0700 Subject: [PATCH] Add a 'exclusive client' option to the config file --- src/cryfs/config/CryConfig.cpp | 16 +++++++++-- src/cryfs/config/CryConfig.h | 6 +++++ test/cryfs/config/CryConfigTest.cpp | 41 +++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/cryfs/config/CryConfig.cpp b/src/cryfs/config/CryConfig.cpp index 5aa93eef..a7bcdacb 100644 --- a/src/cryfs/config/CryConfig.cpp +++ b/src/cryfs/config/CryConfig.cpp @@ -21,11 +21,11 @@ using cpputils::Random; namespace cryfs { CryConfig::CryConfig() -: _rootBlob(""), _encKey(""), _cipher(""), _version(""), _createdWithVersion(""), _blocksizeBytes(0), _filesystemId(FilesystemID::Null()), _hasVersionNumbers(true) { +: _rootBlob(""), _encKey(""), _cipher(""), _version(""), _createdWithVersion(""), _blocksizeBytes(0), _filesystemId(FilesystemID::Null()), _exclusiveClientId(none), _hasVersionNumbers(true) { } CryConfig::CryConfig(CryConfig &&rhs) -: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)), _version(std::move(rhs._version)), _createdWithVersion(std::move(rhs._createdWithVersion)), _blocksizeBytes(rhs._blocksizeBytes), _filesystemId(std::move(rhs._filesystemId)), _hasVersionNumbers(rhs._hasVersionNumbers) { +: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)), _version(std::move(rhs._version)), _createdWithVersion(std::move(rhs._createdWithVersion)), _blocksizeBytes(rhs._blocksizeBytes), _filesystemId(std::move(rhs._filesystemId)), _exclusiveClientId(std::move(rhs._exclusiveClientId)), _hasVersionNumbers(rhs._hasVersionNumbers) { } CryConfig CryConfig::load(const Data &data) { @@ -41,6 +41,7 @@ CryConfig CryConfig::load(const Data &data) { cfg._version = pt.get("cryfs.version", "0.8"); // CryFS 0.8 didn't specify this field, so if the field doesn't exist, it's 0.8. cfg._createdWithVersion = pt.get("cryfs.createdWithVersion", cfg._version); // In CryFS <= 0.9.2, we didn't have this field, but also didn't update cryfs.version, so we can use this field instead. cfg._blocksizeBytes = pt.get("cryfs.blocksizeBytes", 32832); // CryFS <= 0.9.2 used a 32KB block size which was this physical block size. + cfg._exclusiveClientId = pt.get_optional("cryfs.exclusiveClientId"); #ifndef CRYFS_NO_COMPATIBILITY cfg._hasVersionNumbers = pt.get("cryfs.migrations.hasVersionNumbers", false); #endif @@ -65,6 +66,9 @@ Data CryConfig::save() const { pt.put("cryfs.createdWithVersion", _createdWithVersion); pt.put("cryfs.blocksizeBytes", _blocksizeBytes); pt.put("cryfs.filesystemId", _filesystemId.ToString()); + if (_exclusiveClientId != none) { + pt.put("cryfs.exclusiveClientId", *_exclusiveClientId); + } #ifndef CRYFS_NO_COMPATIBILITY pt.put("cryfs.migrations.hasVersionNumbers", _hasVersionNumbers); #endif @@ -130,6 +134,14 @@ void CryConfig::SetFilesystemId(const FilesystemID &value) { _filesystemId = value; } +optional CryConfig::ExclusiveClientId() const { + return _exclusiveClientId; +} + +void CryConfig::SetExclusiveClientId(optional value) { + _exclusiveClientId = value; +} + #ifndef CRYFS_NO_COMPATIBILITY bool CryConfig::HasVersionNumbers() const { return _hasVersionNumbers; diff --git a/src/cryfs/config/CryConfig.h b/src/cryfs/config/CryConfig.h index c4f4e95a..3b3ebd30 100644 --- a/src/cryfs/config/CryConfig.h +++ b/src/cryfs/config/CryConfig.h @@ -38,6 +38,11 @@ public: const FilesystemID &FilesystemId() const; void SetFilesystemId(const FilesystemID &value); + // If the exclusive client Id is set, then additional integrity measures (i.e. treating missing blocks as integrity violations) are enabled. + // Because this only works in a single-client setting, only this one client Id is allowed to access the file system. + boost::optional ExclusiveClientId() const; + void SetExclusiveClientId(boost::optional value); + #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. @@ -56,6 +61,7 @@ private: std::string _createdWithVersion; uint64_t _blocksizeBytes; FilesystemID _filesystemId; + boost::optional _exclusiveClientId; #ifndef CRYFS_NO_COMPATIBILITY bool _hasVersionNumbers; #endif diff --git a/test/cryfs/config/CryConfigTest.cpp b/test/cryfs/config/CryConfigTest.cpp index 800e2a11..33ee5089 100644 --- a/test/cryfs/config/CryConfigTest.cpp +++ b/test/cryfs/config/CryConfigTest.cpp @@ -5,6 +5,7 @@ using namespace cryfs; using cpputils::Data; using cpputils::DataFixture; +using boost::none; class CryConfigTest: public ::testing::Test { public: @@ -165,3 +166,43 @@ TEST_F(CryConfigTest, FilesystemID_AfterSaveAndLoad) { CryConfig loaded = SaveAndLoad(std::move(cfg)); EXPECT_EQ(fixture, loaded.FilesystemId()); } + +TEST_F(CryConfigTest, ExclusiveClientId_Init) { + EXPECT_EQ(none, cfg.ExclusiveClientId()); +} + +TEST_F(CryConfigTest, ExclusiveClientId_Some) { + cfg.SetExclusiveClientId(0x12345678u); + EXPECT_EQ(0x12345678u, cfg.ExclusiveClientId().value()); +} + +TEST_F(CryConfigTest, ExclusiveClientId_None) { + cfg.SetExclusiveClientId(0x12345678u); + cfg.SetExclusiveClientId(none); + EXPECT_EQ(none, cfg.ExclusiveClientId()); +} + +TEST_F(CryConfigTest, ExclusiveClientId_Some_AfterMove) { + cfg.SetExclusiveClientId(0x12345678u); + CryConfig moved = std::move(cfg); + EXPECT_EQ(0x12345678u, moved.ExclusiveClientId().value()); +} + +TEST_F(CryConfigTest, ExclusiveClientId_None_AfterMove) { + cfg.SetExclusiveClientId(0x12345678u); + cfg.SetExclusiveClientId(none); + CryConfig moved = std::move(cfg); + EXPECT_EQ(none, moved.ExclusiveClientId()); +} + +TEST_F(CryConfigTest, ExclusiveClientId_Some_AfterSaveAndLoad) { + cfg.SetExclusiveClientId(0x12345678u); + CryConfig loaded = SaveAndLoad(std::move(cfg)); + EXPECT_EQ(0x12345678u, loaded.ExclusiveClientId().value()); +} + +TEST_F(CryConfigTest, ExclusiveClientId_None_AfterSaveAndLoad) { + cfg.SetExclusiveClientId(none); + CryConfig loaded = SaveAndLoad(std::move(cfg)); + EXPECT_EQ(none, loaded.ExclusiveClientId()); +}