Each file system gets a unique ID. This ID will later be used to store local configuration of a client for that file system.

This commit is contained in:
Sebastian Messmer 2016-06-20 16:14:07 -07:00
parent b3c5d4b5e3
commit e4501d51e5
6 changed files with 84 additions and 3 deletions

View File

@ -5,23 +5,27 @@
#include <boost/property_tree/json_parser.hpp>
#include <sstream>
#include <gitversion/VersionCompare.h>
#include <cpp-utils/random/Random.h>
namespace bf = boost::filesystem;
using boost::property_tree::ptree;
using boost::optional;
using boost::none;
using std::string;
using std::stringstream;
using cpputils::Data;
using gitversion::VersionCompare;
using cpputils::Random;
namespace cryfs {
CryConfig::CryConfig()
: _rootBlob(""), _encKey(""), _cipher(""), _version(""), _createdWithVersion(""), _blocksizeBytes(0) {
: _rootBlob(""), _encKey(""), _cipher(""), _version(""), _createdWithVersion(""), _blocksizeBytes(0), _filesystemId(FilesystemID::Null()) {
}
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) {
: _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)) {
}
CryConfig CryConfig::load(const Data &data) {
@ -35,8 +39,16 @@ CryConfig CryConfig::load(const Data &data) {
cfg._encKey = pt.get("cryfs.key", "");
cfg._cipher = pt.get("cryfs.cipher", "");
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 Crfys <= 0.9.2, we didn't have this field, but also didn't update cryfs.version, so we can use this field instead.
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<uint64_t>("cryfs.blocksizeBytes", 32832); // CryFS <= 0.9.2 used a 32KB block size which was this physical block size.
string filesystemIdOpt = pt.get("cryfs.filesystemId", "");
if (filesystemIdOpt == "") {
cfg._filesystemId = Random::PseudoRandom().getFixedSize<FilesystemID::BINARY_LENGTH>();
} else {
cfg._filesystemId = FilesystemID::FromString(filesystemIdOpt);
}
return cfg;
}
@ -49,6 +61,7 @@ Data CryConfig::save() const {
pt.put("cryfs.version", _version);
pt.put("cryfs.createdWithVersion", _createdWithVersion);
pt.put<uint64_t>("cryfs.blocksizeBytes", _blocksizeBytes);
pt.put("cryfs.filesystemId", _filesystemId.ToString());
stringstream stream;
write_json(stream, pt);
@ -103,4 +116,12 @@ void CryConfig::SetBlocksizeBytes(uint64_t value) {
_blocksizeBytes = value;
}
const CryConfig::FilesystemID &CryConfig::FilesystemId() const {
return _filesystemId;
}
void CryConfig::SetFilesystemId(const FilesystemID &value) {
_filesystemId = value;
}
}

View File

@ -6,6 +6,7 @@
#include <cpp-utils/data/Data.h>
#include <iostream>
#include <cpp-utils/data/FixedSizeData.h>
namespace cryfs {
@ -33,6 +34,10 @@ public:
uint64_t BlocksizeBytes() const;
void SetBlocksizeBytes(uint64_t value);
using FilesystemID = cpputils::FixedSizeData<16>;
const FilesystemID &FilesystemId() const;
void SetFilesystemId(const FilesystemID &value);
static CryConfig load(const cpputils::Data &data);
cpputils::Data save() const;
@ -43,6 +48,7 @@ private:
std::string _version;
std::string _createdWithVersion;
uint64_t _blocksizeBytes;
FilesystemID _filesystemId;
DISALLOW_COPY_AND_ASSIGN(CryConfig);
};

View File

@ -1,10 +1,12 @@
#include "CryConfigCreator.h"
#include "CryCipher.h"
#include <gitversion/gitversion.h>
#include <cpp-utils/random/Random.h>
using cpputils::Console;
using cpputils::unique_ref;
using cpputils::RandomGenerator;
using cpputils::Random;
using std::string;
using std::shared_ptr;
using std::vector;
@ -25,6 +27,7 @@ namespace cryfs {
config.SetBlocksizeBytes(_generateBlocksizeBytes(blocksizeBytesFromCommandLine));
config.SetRootBlob(_generateRootBlobKey());
config.SetEncryptionKey(_generateEncKey(config.Cipher()));
config.SetFilesystemId(_generateFilesystemID());
return config;
}
@ -57,4 +60,8 @@ namespace cryfs {
//An empty root blob entry will tell CryDevice to create a new root blob
return "";
}
CryConfig::FilesystemID CryConfigCreator::_generateFilesystemID() {
return Random::PseudoRandom().getFixedSize<CryConfig::FilesystemID::BINARY_LENGTH>();
}
}

View File

@ -20,6 +20,7 @@ namespace cryfs {
std::string _generateEncKey(const std::string &cipher);
std::string _generateRootBlobKey();
uint32_t _generateBlocksizeBytes(const boost::optional<uint32_t> &blocksizeBytesFromCommandLine);
CryConfig::FilesystemID _generateFilesystemID();
std::shared_ptr<cpputils::Console> _console;
CryConfigConsole _configConsole;

View File

@ -4,6 +4,7 @@
#include <cpp-utils/tempfile/TempFile.h>
#include <cpp-utils/random/Random.h>
#include <cpp-utils/crypto/symmetric/ciphers.h>
#include <cpp-utils/data/DataFixture.h>
#include <gitversion/gitversion.h>
#include <gitversion/VersionCompare.h>
@ -11,6 +12,7 @@ using cpputils::unique_ref;
using cpputils::make_unique_ref;
using cpputils::TempFile;
using cpputils::SCrypt;
using cpputils::DataFixture;
using boost::optional;
using boost::none;
using std::string;
@ -75,6 +77,12 @@ public:
cfg.save();
}
void CreateWithFilesystemID(const CryConfig::FilesystemID &filesystemId, const string &password = "mypassword") {
auto cfg = loader(password, false).loadOrCreate(file.path()).value();
cfg.config()->SetFilesystemId(filesystemId);
cfg.save();
}
string olderVersion() {
string olderVersion;
if (std::stol(gitversion::MinorVersion()) > 0) {
@ -199,6 +207,18 @@ TEST_F(CryConfigLoaderTest, Version_Create) {
EXPECT_EQ(gitversion::VersionString(), created.config()->CreatedWithVersion());
}
TEST_F(CryConfigLoaderTest, FilesystemID_Load) {
auto fixture = DataFixture::generateFixedSize<CryConfig::FilesystemID::BINARY_LENGTH>();
CreateWithFilesystemID(fixture);
auto loaded = Load().value();
EXPECT_EQ(fixture, loaded.config()->FilesystemId());
}
TEST_F(CryConfigLoaderTest, FilesystemID_Create) {
auto created = Create();
EXPECT_NE(CryConfig::FilesystemID::Null(), created.config()->FilesystemId());
}
TEST_F(CryConfigLoaderTest, AsksWhenLoadingNewerFilesystem_AnswerYes) {
EXPECT_CALL(*console, askYesNo(HasSubstr("should not be opened with older versions"))).Times(1).WillOnce(Return(true));

View File

@ -1,8 +1,10 @@
#include <gtest/gtest.h>
#include <cryfs/config/CryConfig.h>
#include <cpp-utils/data/DataFixture.h>
using namespace cryfs;
using cpputils::Data;
using cpputils::DataFixture;
class CryConfigTest: public ::testing::Test {
public:
@ -139,3 +141,27 @@ TEST_F(CryConfigTest, BlocksizeBytes_AfterSaveAndLoad) {
CryConfig loaded = SaveAndLoad(std::move(cfg));
EXPECT_EQ(10*1024u, loaded.BlocksizeBytes());
}
TEST_F(CryConfigTest, FilesystemID_Init) {
EXPECT_EQ(CryConfig::FilesystemID::Null(), cfg.FilesystemId());
}
TEST_F(CryConfigTest, FilesystemID) {
auto fixture = DataFixture::generateFixedSize<CryConfig::FilesystemID::BINARY_LENGTH>();
cfg.SetFilesystemId(fixture);
EXPECT_EQ(fixture, cfg.FilesystemId());
}
TEST_F(CryConfigTest, FilesystemID_AfterMove) {
auto fixture = DataFixture::generateFixedSize<CryConfig::FilesystemID::BINARY_LENGTH>();
cfg.SetFilesystemId(fixture);
CryConfig moved = std::move(cfg);
EXPECT_EQ(fixture, moved.FilesystemId());
}
TEST_F(CryConfigTest, FilesystemID_AfterSaveAndLoad) {
auto fixture = DataFixture::generateFixedSize<CryConfig::FilesystemID::BINARY_LENGTH>();
cfg.SetFilesystemId(fixture);
CryConfig loaded = SaveAndLoad(std::move(cfg));
EXPECT_EQ(fixture, loaded.FilesystemId());
}