Add a 'exclusive client' option to the config file

This commit is contained in:
Sebastian Messmer 2016-06-26 15:23:00 -07:00
parent 514dbcb6c7
commit b838046246
3 changed files with 61 additions and 2 deletions

View File

@ -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<string>("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<string>("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<uint64_t>("cryfs.blocksizeBytes", 32832); // CryFS <= 0.9.2 used a 32KB block size which was this physical block size.
cfg._exclusiveClientId = pt.get_optional<uint32_t>("cryfs.exclusiveClientId");
#ifndef CRYFS_NO_COMPATIBILITY
cfg._hasVersionNumbers = pt.get<bool>("cryfs.migrations.hasVersionNumbers", false);
#endif
@ -65,6 +66,9 @@ Data CryConfig::save() const {
pt.put<string>("cryfs.createdWithVersion", _createdWithVersion);
pt.put<uint64_t>("cryfs.blocksizeBytes", _blocksizeBytes);
pt.put<string>("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<uint32_t> CryConfig::ExclusiveClientId() const {
return _exclusiveClientId;
}
void CryConfig::SetExclusiveClientId(optional<uint32_t> value) {
_exclusiveClientId = value;
}
#ifndef CRYFS_NO_COMPATIBILITY
bool CryConfig::HasVersionNumbers() const {
return _hasVersionNumbers;

View File

@ -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<uint32_t> ExclusiveClientId() const;
void SetExclusiveClientId(boost::optional<uint32_t> 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<uint32_t> _exclusiveClientId;
#ifndef CRYFS_NO_COMPATIBILITY
bool _hasVersionNumbers;
#endif

View File

@ -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());
}