Add environment variable to specify local storage directory
This commit is contained in:
parent
b0077e7a81
commit
d7a41089ba
@ -192,8 +192,8 @@ namespace cryfs {
|
||||
return *configFile;
|
||||
}
|
||||
|
||||
void Cli::_checkConfigIntegrity(const bf::path& basedir, const CryConfigFile& config, bool allowReplacedFilesystem) {
|
||||
auto basedirMetadata = BasedirMetadata::load();
|
||||
void Cli::_checkConfigIntegrity(const bf::path& basedir, const LocalStateDir& localStateDir, const CryConfigFile& config, bool allowReplacedFilesystem) {
|
||||
auto basedirMetadata = BasedirMetadata::load(localStateDir);
|
||||
if (!allowReplacedFilesystem && !basedirMetadata.filesystemIdForBasedirIsCorrect(basedir, config.config()->FilesystemId())) {
|
||||
if (!_console->askYesNo("The filesystem id in the config file is different to the last time we loaded a filesystem from this basedir. This can be genuine if you replaced the filesystem with a different one. If you didn't do that, it is possible that an attacker did. Do you want to continue loading the file system?", false)) {
|
||||
throw CryfsException(
|
||||
@ -205,24 +205,24 @@ namespace cryfs {
|
||||
basedirMetadata.save();
|
||||
}
|
||||
|
||||
CryConfigLoader::ConfigLoadResult Cli::_loadOrCreateConfig(const ProgramOptions &options) {
|
||||
CryConfigLoader::ConfigLoadResult Cli::_loadOrCreateConfig(const ProgramOptions &options, const LocalStateDir& localStateDir) {
|
||||
auto configFile = _determineConfigFile(options);
|
||||
auto config = _loadOrCreateConfigFile(std::move(configFile), options.cipher(), options.blocksizeBytes(), options.allowFilesystemUpgrade(), options.missingBlockIsIntegrityViolation(), options.allowReplacedFilesystem());
|
||||
auto config = _loadOrCreateConfigFile(std::move(configFile), localStateDir, options.cipher(), options.blocksizeBytes(), options.allowFilesystemUpgrade(), options.missingBlockIsIntegrityViolation(), options.allowReplacedFilesystem());
|
||||
if (config == none) {
|
||||
throw CryfsException("Could not load config file. Did you enter the correct password?", ErrorCode::WrongPassword);
|
||||
}
|
||||
_checkConfigIntegrity(options.baseDir(), config->configFile, options.allowReplacedFilesystem());
|
||||
_checkConfigIntegrity(options.baseDir(), localStateDir, config->configFile, options.allowReplacedFilesystem());
|
||||
return std::move(*config);
|
||||
}
|
||||
|
||||
optional<CryConfigLoader::ConfigLoadResult> Cli::_loadOrCreateConfigFile(bf::path configFilePath, const optional<string> &cipher, const optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem) {
|
||||
optional<CryConfigLoader::ConfigLoadResult> Cli::_loadOrCreateConfigFile(bf::path configFilePath, LocalStateDir localStateDir, const optional<string> &cipher, const optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem) {
|
||||
if (_noninteractive) {
|
||||
return CryConfigLoader(_console, _keyGenerator, _scryptSettings,
|
||||
return CryConfigLoader(_console, _keyGenerator, std::move(localStateDir), _scryptSettings,
|
||||
&Cli::_askPasswordNoninteractive,
|
||||
&Cli::_askPasswordNoninteractive,
|
||||
cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath), allowFilesystemUpgrade, allowReplacedFilesystem);
|
||||
} else {
|
||||
return CryConfigLoader(_console, _keyGenerator, _scryptSettings,
|
||||
return CryConfigLoader(_console, _keyGenerator, std::move(localStateDir), _scryptSettings,
|
||||
&Cli::_askPasswordForExistingFilesystem,
|
||||
&Cli::_askPasswordForNewFilesystem,
|
||||
cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath), allowFilesystemUpgrade, allowReplacedFilesystem);
|
||||
@ -231,9 +231,10 @@ namespace cryfs {
|
||||
|
||||
void Cli::_runFilesystem(const ProgramOptions &options) {
|
||||
try {
|
||||
LocalStateDir localStateDir(Environment::localStateDir());
|
||||
auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir());
|
||||
auto config = _loadOrCreateConfig(options);
|
||||
CryDevice device(std::move(config.configFile), std::move(blockStore), config.myClientId,
|
||||
auto config = _loadOrCreateConfig(options, localStateDir);
|
||||
CryDevice device(std::move(config.configFile), std::move(blockStore), std::move(localStateDir), config.myClientId,
|
||||
options.noIntegrityChecks(), config.configFile.config()->missingBlockIsIntegrityViolation());
|
||||
_sanityCheckFilesystem(&device);
|
||||
fspp::FilesystemImpl fsimpl(&device);
|
||||
|
@ -23,9 +23,9 @@ namespace cryfs {
|
||||
private:
|
||||
void _checkForUpdates(cpputils::unique_ref<cpputils::HttpClient> httpClient);
|
||||
void _runFilesystem(const program_options::ProgramOptions &options);
|
||||
CryConfigLoader::ConfigLoadResult _loadOrCreateConfig(const program_options::ProgramOptions &options);
|
||||
void _checkConfigIntegrity(const boost::filesystem::path& basedir, const CryConfigFile& config, bool allowReplacedFilesystem);
|
||||
boost::optional<CryConfigLoader::ConfigLoadResult> _loadOrCreateConfigFile(boost::filesystem::path configFilePath, const boost::optional<std::string> &cipher, const boost::optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const boost::optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem);
|
||||
CryConfigLoader::ConfigLoadResult _loadOrCreateConfig(const program_options::ProgramOptions &options, const LocalStateDir& localStateDir);
|
||||
void _checkConfigIntegrity(const boost::filesystem::path& basedir, const LocalStateDir& localStateDir, const CryConfigFile& config, bool allowReplacedFilesystem);
|
||||
boost::optional<CryConfigLoader::ConfigLoadResult> _loadOrCreateConfigFile(boost::filesystem::path configFilePath, LocalStateDir localStateDir, const boost::optional<std::string> &cipher, const boost::optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const boost::optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem);
|
||||
boost::filesystem::path _determineConfigFile(const program_options::ProgramOptions &options);
|
||||
static std::string _askPasswordForExistingFilesystem();
|
||||
static std::string _askPasswordForNewFilesystem();
|
||||
|
@ -1,12 +1,16 @@
|
||||
#include "Environment.h"
|
||||
#include <cstdlib>
|
||||
#include <cpp-utils/system/homedir.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using std::string;
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace cryfs {
|
||||
const string Environment::FRONTEND_KEY = "CRYFS_FRONTEND";
|
||||
const string Environment::FRONTEND_NONINTERACTIVE = "noninteractive";
|
||||
const string Environment::NOUPDATECHECK_KEY = "CRYFS_NO_UPDATE_CHECK";
|
||||
const string Environment::LOCALSTATEDIR_KEY = "CRYFS_LOCAL_STATE_DIR";
|
||||
|
||||
bool Environment::isNoninteractive() {
|
||||
char *frontend = std::getenv(FRONTEND_KEY.c_str());
|
||||
@ -16,4 +20,19 @@ namespace cryfs {
|
||||
bool Environment::noUpdateCheck() {
|
||||
return nullptr != std::getenv(NOUPDATECHECK_KEY.c_str());
|
||||
}
|
||||
|
||||
const bf::path& Environment::defaultLocalStateDir() {
|
||||
static const bf::path value = cpputils::system::HomeDirectory::get() / ".cryfs";
|
||||
return value;
|
||||
}
|
||||
|
||||
bf::path Environment::localStateDir() {
|
||||
const char* localStateDir = std::getenv(LOCALSTATEDIR_KEY.c_str());
|
||||
|
||||
if (nullptr == localStateDir) {
|
||||
return defaultLocalStateDir();
|
||||
}
|
||||
|
||||
return bf::absolute(localStateDir);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#define MESSMER_CRYFS_CLI_ENVIRONMENT_H
|
||||
|
||||
#include <string>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
@ -10,10 +11,13 @@ namespace cryfs {
|
||||
public:
|
||||
static bool isNoninteractive();
|
||||
static bool noUpdateCheck();
|
||||
static boost::filesystem::path localStateDir();
|
||||
static const boost::filesystem::path& defaultLocalStateDir();
|
||||
|
||||
static const std::string FRONTEND_KEY;
|
||||
static const std::string FRONTEND_NONINTERACTIVE;
|
||||
static const std::string NOUPDATECHECK_KEY;
|
||||
static const std::string LOCALSTATEDIR_KEY;
|
||||
|
||||
private:
|
||||
Environment() = delete;
|
||||
|
@ -210,6 +210,11 @@ void Parser::_showHelp() {
|
||||
<< " " << Environment::NOUPDATECHECK_KEY << "=true\n"
|
||||
<< "\tBy default, CryFS connects to the internet to check for known\n"
|
||||
<< "\tsecurity vulnerabilities and new versions. This option disables this.\n"
|
||||
<< " " << Environment::LOCALSTATEDIR_KEY << "=[path]\n"
|
||||
<< "\tSets the directory cryfs uses to store local state. This local state\n"
|
||||
<< "\tis used to recognize known file systems and run integrity checks\n"
|
||||
<< "\t(i.e. check that they haven't been modified by an attacker.\n"
|
||||
<< "\tDefault value: " << Environment::defaultLocalStateDir().c_str() << "\n"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ using boost::none;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
CryConfigCreator::CryConfigCreator(shared_ptr<Console> console, RandomGenerator &encryptionKeyGenerator)
|
||||
:_console(console), _configConsole(console), _encryptionKeyGenerator(encryptionKeyGenerator) {
|
||||
CryConfigCreator::CryConfigCreator(shared_ptr<Console> console, RandomGenerator &encryptionKeyGenerator, LocalStateDir localStateDir)
|
||||
:_console(console), _configConsole(console), _encryptionKeyGenerator(encryptionKeyGenerator), _localStateDir(std::move(localStateDir)) {
|
||||
}
|
||||
|
||||
CryConfigCreator::ConfigCreateResult CryConfigCreator::create(const optional<string> &cipherFromCommandLine, const optional<uint32_t> &blocksizeBytesFromCommandLine, const optional<bool> &missingBlockIsIntegrityViolationFromCommandLine, bool allowReplacedFilesystem) {
|
||||
@ -29,7 +29,7 @@ namespace cryfs {
|
||||
config.SetRootBlob(_generateRootBlobId());
|
||||
config.SetFilesystemId(_generateFilesystemID());
|
||||
auto encryptionKey = _generateEncKey(config.Cipher());
|
||||
auto localState = LocalStateMetadata::loadOrGenerate(LocalStateDir::forFilesystemId(config.FilesystemId()), cpputils::Data::FromString(encryptionKey), allowReplacedFilesystem);
|
||||
auto localState = LocalStateMetadata::loadOrGenerate(_localStateDir.forFilesystemId(config.FilesystemId()), cpputils::Data::FromString(encryptionKey), allowReplacedFilesystem);
|
||||
uint32_t myClientId = localState.myClientId();
|
||||
config.SetEncryptionKey(std::move(encryptionKey));
|
||||
config.SetExclusiveClientId(_generateExclusiveClientId(missingBlockIsIntegrityViolationFromCommandLine, myClientId));
|
||||
|
@ -5,13 +5,14 @@
|
||||
#include <cpp-utils/pointer/unique_ref.h>
|
||||
#include <cpp-utils/random/RandomGenerator.h>
|
||||
#include <cpp-utils/io/Console.h>
|
||||
#include <cryfs/localstate/LocalStateDir.h>
|
||||
#include "CryConfig.h"
|
||||
#include "CryConfigConsole.h"
|
||||
|
||||
namespace cryfs {
|
||||
class CryConfigCreator final {
|
||||
public:
|
||||
CryConfigCreator(std::shared_ptr<cpputils::Console> console, cpputils::RandomGenerator &encryptionKeyGenerator);
|
||||
CryConfigCreator(std::shared_ptr<cpputils::Console> console, cpputils::RandomGenerator &encryptionKeyGenerator, LocalStateDir localStateDir);
|
||||
CryConfigCreator(CryConfigCreator &&rhs) = default;
|
||||
|
||||
struct ConfigCreateResult {
|
||||
@ -32,6 +33,7 @@ namespace cryfs {
|
||||
std::shared_ptr<cpputils::Console> _console;
|
||||
CryConfigConsole _configConsole;
|
||||
cpputils::RandomGenerator &_encryptionKeyGenerator;
|
||||
LocalStateDir _localStateDir;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryConfigCreator);
|
||||
};
|
||||
|
@ -25,11 +25,12 @@ using namespace cpputils::logging;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
CryConfigLoader::CryConfigLoader(shared_ptr<Console> console, RandomGenerator &keyGenerator, const SCryptSettings &scryptSettings, function<string()> askPasswordForExistingFilesystem, function<string()> askPasswordForNewFilesystem, const optional<string> &cipherFromCommandLine, const boost::optional<uint32_t> &blocksizeBytesFromCommandLine, const boost::optional<bool> &missingBlockIsIntegrityViolationFromCommandLine)
|
||||
: _console(console), _creator(std::move(console), keyGenerator), _scryptSettings(scryptSettings),
|
||||
CryConfigLoader::CryConfigLoader(shared_ptr<Console> console, RandomGenerator &keyGenerator, LocalStateDir localStateDir, const SCryptSettings &scryptSettings, function<string()> askPasswordForExistingFilesystem, function<string()> askPasswordForNewFilesystem, const optional<string> &cipherFromCommandLine, const boost::optional<uint32_t> &blocksizeBytesFromCommandLine, const boost::optional<bool> &missingBlockIsIntegrityViolationFromCommandLine)
|
||||
: _console(console), _creator(std::move(console), keyGenerator, localStateDir), _scryptSettings(scryptSettings),
|
||||
_askPasswordForExistingFilesystem(askPasswordForExistingFilesystem), _askPasswordForNewFilesystem(askPasswordForNewFilesystem),
|
||||
_cipherFromCommandLine(cipherFromCommandLine), _blocksizeBytesFromCommandLine(blocksizeBytesFromCommandLine),
|
||||
_missingBlockIsIntegrityViolationFromCommandLine(missingBlockIsIntegrityViolationFromCommandLine) {
|
||||
_missingBlockIsIntegrityViolationFromCommandLine(missingBlockIsIntegrityViolationFromCommandLine),
|
||||
_localStateDir(std::move(localStateDir)) {
|
||||
}
|
||||
|
||||
optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::_loadConfig(bf::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem) {
|
||||
@ -62,7 +63,7 @@ optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::_loadConfig(bf::pat
|
||||
config->save();
|
||||
}
|
||||
_checkCipher(*config->config());
|
||||
auto localState = LocalStateMetadata::loadOrGenerate(LocalStateDir::forFilesystemId(config->config()->FilesystemId()), cpputils::Data::FromString(config->config()->EncryptionKey()), allowReplacedFilesystem);
|
||||
auto localState = LocalStateMetadata::loadOrGenerate(_localStateDir.forFilesystemId(config->config()->FilesystemId()), cpputils::Data::FromString(config->config()->EncryptionKey()), allowReplacedFilesystem);
|
||||
uint32_t myClientId = localState.myClientId();
|
||||
_checkMissingBlocksAreIntegrityViolations(&*config, myClientId);
|
||||
return ConfigLoadResult {std::move(*config), myClientId};
|
||||
|
@ -13,7 +13,7 @@ namespace cryfs {
|
||||
|
||||
class CryConfigLoader final {
|
||||
public:
|
||||
CryConfigLoader(std::shared_ptr<cpputils::Console> console, cpputils::RandomGenerator &keyGenerator, const cpputils::SCryptSettings &scryptSettings, std::function<std::string()> askPasswordForExistingFilesystem, std::function<std::string()> askPasswordForNewFilesystem, const boost::optional<std::string> &cipherFromCommandLine, const boost::optional<uint32_t> &blocksizeBytesFromCommandLine, const boost::optional<bool> &missingBlockIsIntegrityViolationFromCommandLine);
|
||||
CryConfigLoader(std::shared_ptr<cpputils::Console> console, cpputils::RandomGenerator &keyGenerator, LocalStateDir localStateDir, const cpputils::SCryptSettings &scryptSettings, std::function<std::string()> askPasswordForExistingFilesystem, std::function<std::string()> askPasswordForNewFilesystem, const boost::optional<std::string> &cipherFromCommandLine, const boost::optional<uint32_t> &blocksizeBytesFromCommandLine, const boost::optional<bool> &missingBlockIsIntegrityViolationFromCommandLine);
|
||||
CryConfigLoader(CryConfigLoader &&rhs) = default;
|
||||
|
||||
struct ConfigLoadResult {
|
||||
@ -38,6 +38,7 @@ private:
|
||||
boost::optional<std::string> _cipherFromCommandLine;
|
||||
boost::optional<uint32_t> _blocksizeBytesFromCommandLine;
|
||||
boost::optional<bool> _missingBlockIsIntegrityViolationFromCommandLine;
|
||||
LocalStateDir _localStateDir;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryConfigLoader);
|
||||
};
|
||||
|
@ -51,14 +51,14 @@ namespace bf = boost::filesystem;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
CryDevice::CryDevice(CryConfigFile configFile, unique_ref<BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation)
|
||||
: _fsBlobStore(CreateFsBlobStore(std::move(blockStore), &configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation)),
|
||||
CryDevice::CryDevice(CryConfigFile configFile, unique_ref<BlockStore2> blockStore, const LocalStateDir& localStateDir, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation)
|
||||
: _fsBlobStore(CreateFsBlobStore(std::move(blockStore), &configFile, localStateDir, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation)),
|
||||
_rootBlobId(GetOrCreateRootBlobId(&configFile)),
|
||||
_onFsAction() {
|
||||
}
|
||||
|
||||
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);
|
||||
unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CryDevice::CreateFsBlobStore(unique_ref<BlockStore2> blockStore, CryConfigFile *configFile, const LocalStateDir& localStateDir, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation) {
|
||||
auto blobStore = CreateBlobStore(std::move(blockStore), localStateDir, configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation);
|
||||
|
||||
#ifndef CRYFS_NO_COMPATIBILITY
|
||||
auto fsBlobStore = MigrateOrCreateFsBlobStore(std::move(blobStore), configFile);
|
||||
@ -83,8 +83,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, bool missingBlockIsIntegrityViolation) {
|
||||
auto integrityEncryptedBlockStore = CreateIntegrityEncryptedBlockStore(std::move(blockStore), configFile, myClientId, noIntegrityChecks, missingBlockIsIntegrityViolation);
|
||||
unique_ref<blobstore::BlobStore> CryDevice::CreateBlobStore(unique_ref<BlockStore2> blockStore, const LocalStateDir& localStateDir, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation) {
|
||||
auto integrityEncryptedBlockStore = CreateIntegrityEncryptedBlockStore(std::move(blockStore), localStateDir, 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>(
|
||||
@ -96,9 +96,9 @@ 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, bool missingBlockIsIntegrityViolation) {
|
||||
unique_ref<BlockStore2> CryDevice::CreateIntegrityEncryptedBlockStore(unique_ref<BlockStore2> blockStore, const LocalStateDir& localStateDir, 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 statePath = localStateDir.forFilesystemId(configFile->config()->FilesystemId());
|
||||
auto integrityFilePath = statePath / "integritydata";
|
||||
|
||||
#ifndef CRYFS_NO_COMPATIBILITY
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <fspp/fs_interface/Device.h>
|
||||
#include <cryfs/localstate/LocalStateDir.h>
|
||||
|
||||
#include "parallelaccessfsblobstore/ParallelAccessFsBlobStore.h"
|
||||
#include "parallelaccessfsblobstore/DirBlobRef.h"
|
||||
@ -18,7 +19,7 @@ namespace cryfs {
|
||||
|
||||
class CryDevice final: public fspp::Device {
|
||||
public:
|
||||
CryDevice(CryConfigFile config, cpputils::unique_ref<blockstore::BlockStore2> blockStore, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
|
||||
CryDevice(CryConfigFile config, cpputils::unique_ref<blockstore::BlockStore2> blockStore, const LocalStateDir& localStateDir, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
|
||||
|
||||
void statfs(const boost::filesystem::path &path, struct ::statvfs *fsstat) override;
|
||||
|
||||
@ -53,12 +54,12 @@ private:
|
||||
|
||||
blockstore::BlockId GetOrCreateRootBlobId(CryConfigFile *config);
|
||||
blockstore::BlockId CreateRootBlobAndReturnId();
|
||||
static cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CreateFsBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
|
||||
static cpputils::unique_ref<parallelaccessfsblobstore::ParallelAccessFsBlobStore> CreateFsBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, CryConfigFile *configFile, const LocalStateDir& localStateDir, 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, 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<blobstore::BlobStore> CreateBlobStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, const LocalStateDir& localStateDir, CryConfigFile *configFile, uint32_t myClientId, bool noIntegrityChecks, bool missingBlockIsIntegrityViolation);
|
||||
static cpputils::unique_ref<blockstore::BlockStore2> CreateIntegrityEncryptedBlockStore(cpputils::unique_ref<blockstore::BlockStore2> blockStore, const LocalStateDir& localStateDir, 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 {
|
||||
|
@ -42,15 +42,17 @@ string jsonPathForBasedir(const bf::path &basedir) {
|
||||
|
||||
}
|
||||
|
||||
BasedirMetadata::BasedirMetadata(ptree data)
|
||||
:_data(data) {}
|
||||
BasedirMetadata::BasedirMetadata(ptree data, bf::path filename)
|
||||
:_filename(std::move(filename)), _data(std::move(data)) {}
|
||||
|
||||
BasedirMetadata BasedirMetadata::load() {
|
||||
return BasedirMetadata(_load(LocalStateDir::forBasedirMetadata()));
|
||||
BasedirMetadata BasedirMetadata::load(const LocalStateDir& localStateDir) {
|
||||
auto filename = localStateDir.forBasedirMetadata();
|
||||
auto loaded = _load(filename);
|
||||
return BasedirMetadata(std::move(loaded), std::move(filename));
|
||||
}
|
||||
|
||||
void BasedirMetadata::save() {
|
||||
_save(LocalStateDir::forBasedirMetadata(), _data);
|
||||
_save(_filename, _data);
|
||||
}
|
||||
|
||||
bool BasedirMetadata::filesystemIdForBasedirIsCorrect(const bf::path &basedir, const CryConfig::FilesystemID &filesystemId) const {
|
||||
|
@ -5,12 +5,13 @@
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include "../config/CryConfig.h"
|
||||
#include "LocalStateDir.h"
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class BasedirMetadata final {
|
||||
public:
|
||||
static BasedirMetadata load();
|
||||
static BasedirMetadata load(const LocalStateDir& localStateDir);
|
||||
void save();
|
||||
|
||||
BasedirMetadata(const BasedirMetadata&) = delete;
|
||||
@ -22,8 +23,9 @@ public:
|
||||
BasedirMetadata& updateFilesystemIdForBasedir(const boost::filesystem::path &basedir, const CryConfig::FilesystemID &filesystemId);
|
||||
|
||||
private:
|
||||
BasedirMetadata(boost::property_tree::ptree data);
|
||||
BasedirMetadata(boost::property_tree::ptree data, boost::filesystem::path filename);
|
||||
|
||||
boost::filesystem::path _filename;
|
||||
boost::property_tree::ptree _data;
|
||||
};
|
||||
|
||||
|
@ -1,28 +1,23 @@
|
||||
#include "LocalStateDir.h"
|
||||
#include <cpp-utils/system/homedir.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace cryfs {
|
||||
namespace {
|
||||
bf::path appDir() {
|
||||
return cpputils::system::HomeDirectory::get() / ".cryfs";
|
||||
}
|
||||
}
|
||||
LocalStateDir::LocalStateDir(bf::path appDir): _appDir(std::move(appDir)) {}
|
||||
|
||||
bf::path LocalStateDir::forFilesystemId(const CryConfig::FilesystemID &filesystemId) {
|
||||
_createDirIfNotExists(appDir());
|
||||
bf::path filesystems_dir = appDir() / "filesystems";
|
||||
bf::path LocalStateDir::forFilesystemId(const CryConfig::FilesystemID &filesystemId) const {
|
||||
_createDirIfNotExists(_appDir);
|
||||
bf::path filesystems_dir = _appDir / "filesystems";
|
||||
_createDirIfNotExists(filesystems_dir);
|
||||
bf::path this_filesystem_dir = filesystems_dir / filesystemId.ToString();
|
||||
_createDirIfNotExists(this_filesystem_dir);
|
||||
return this_filesystem_dir;
|
||||
}
|
||||
|
||||
bf::path LocalStateDir::forBasedirMetadata() {
|
||||
_createDirIfNotExists(appDir());
|
||||
return appDir() / "basedirs";
|
||||
bf::path LocalStateDir::forBasedirMetadata() const {
|
||||
_createDirIfNotExists(_appDir);
|
||||
return _appDir / "basedirs";
|
||||
}
|
||||
|
||||
void LocalStateDir::_createDirIfNotExists(const bf::path &path) {
|
||||
|
@ -10,11 +10,13 @@ namespace cryfs {
|
||||
|
||||
class LocalStateDir final {
|
||||
public:
|
||||
static boost::filesystem::path forFilesystemId(const CryConfig::FilesystemID &filesystemId);
|
||||
static boost::filesystem::path forBasedirMetadata();
|
||||
LocalStateDir(boost::filesystem::path appDir);
|
||||
|
||||
boost::filesystem::path forFilesystemId(const CryConfig::FilesystemID &filesystemId) const;
|
||||
boost::filesystem::path forBasedirMetadata() const;
|
||||
|
||||
private:
|
||||
LocalStateDir(); // static functions only
|
||||
boost::filesystem::path _appDir;
|
||||
|
||||
static void _createDirIfNotExists(const boost::filesystem::path &path);
|
||||
};
|
||||
|
@ -1,12 +1,15 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <cryfs-cli/Environment.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using namespace cryfs;
|
||||
using std::string;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
class EnvironmentTest : public ::testing::Test {
|
||||
public:
|
||||
// WithEnv sets an environment variable while it is in scope.
|
||||
@ -62,3 +65,22 @@ TEST_F(EnvironmentTest, NoUpdateCheck_SetToOtherValue) {
|
||||
// No matter what the value is, setting the environment variable says we don't do update checks.
|
||||
EXPECT_TRUE(Environment::noUpdateCheck());
|
||||
}
|
||||
|
||||
TEST_F(EnvironmentTest, LocalStateDir_NotSet) {
|
||||
EXPECT_EQ(Environment::defaultLocalStateDir(), Environment::localStateDir());
|
||||
}
|
||||
|
||||
TEST_F(EnvironmentTest, LocalStateDir_Set) {
|
||||
WithEnv env("CRYFS_LOCAL_STATE_DIR", "/my/local/state/dir");
|
||||
EXPECT_EQ("/my/local/state/dir", Environment::localStateDir().native());
|
||||
}
|
||||
|
||||
TEST_F(EnvironmentTest, LocalStateDir_ConvertsRelativeToAbsolutePath_WithDot) {
|
||||
WithEnv env("CRYFS_LOCAL_STATE_DIR", "./dir");
|
||||
EXPECT_EQ((bf::current_path() / "./dir").native(), Environment::localStateDir().native());
|
||||
}
|
||||
|
||||
TEST_F(EnvironmentTest, LocalStateDir_ConvertsRelativeToAbsolutePath_WithoutDot) {
|
||||
WithEnv env("CRYFS_LOCAL_STATE_DIR", "dir");
|
||||
EXPECT_EQ((bf::current_path() / "dir").native(), Environment::localStateDir().native());
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../testutils/TestWithFakeHomeDirectory.h"
|
||||
#include <cpp-utils/io/NoninteractiveConsole.h>
|
||||
#include <gitversion/gitversion.h>
|
||||
#include <cryfs/localstate/LocalStateDir.h>
|
||||
|
||||
using namespace cryfs;
|
||||
|
||||
@ -43,12 +44,15 @@ class CryConfigCreatorTest: public ::testing::Test, TestWithFakeHomeDirectory {
|
||||
public:
|
||||
CryConfigCreatorTest()
|
||||
: console(make_shared<MockConsole>()),
|
||||
creator(console, cpputils::Random::PseudoRandom()),
|
||||
noninteractiveCreator(make_shared<NoninteractiveConsole>(console), cpputils::Random::PseudoRandom()) {
|
||||
tempLocalStateDir(), localStateDir(tempLocalStateDir.path()),
|
||||
creator(console, cpputils::Random::PseudoRandom(), localStateDir),
|
||||
noninteractiveCreator(make_shared<NoninteractiveConsole>(console), cpputils::Random::PseudoRandom(), localStateDir) {
|
||||
EXPECT_CALL(*console, ask(HasSubstr("block cipher"), _)).WillRepeatedly(ChooseAnyCipher());
|
||||
EXPECT_CALL(*console, ask(HasSubstr("block size"), _)).WillRepeatedly(Return(0));
|
||||
}
|
||||
shared_ptr<MockConsole> console;
|
||||
cpputils::TempDir tempLocalStateDir;
|
||||
LocalStateDir localStateDir;
|
||||
CryConfigCreator creator;
|
||||
CryConfigCreator noninteractiveCreator;
|
||||
|
||||
|
@ -56,17 +56,17 @@ private:
|
||||
|
||||
class CryConfigLoaderTest: public ::testing::Test, public TestWithMockConsole, TestWithFakeHomeDirectory {
|
||||
public:
|
||||
CryConfigLoaderTest(): file(false) {
|
||||
CryConfigLoaderTest(): file(false), tempLocalStateDir(), localStateDir(tempLocalStateDir.path()) {
|
||||
console = mockConsole();
|
||||
}
|
||||
|
||||
CryConfigLoader loader(const string &password, bool noninteractive, const optional<string> &cipher = none) {
|
||||
auto askPassword = [password] { return password;};
|
||||
if(noninteractive) {
|
||||
return CryConfigLoader(make_shared<NoninteractiveConsole>(console), cpputils::Random::PseudoRandom(), SCrypt::TestSettings, askPassword,
|
||||
return CryConfigLoader(make_shared<NoninteractiveConsole>(console), cpputils::Random::PseudoRandom(), localStateDir, SCrypt::TestSettings, askPassword,
|
||||
askPassword, cipher, none, none);
|
||||
} else {
|
||||
return CryConfigLoader(console, cpputils::Random::PseudoRandom(), SCrypt::TestSettings, askPassword,
|
||||
return CryConfigLoader(console, cpputils::Random::PseudoRandom(), localStateDir, SCrypt::TestSettings, askPassword,
|
||||
askPassword, cipher, none, none);
|
||||
}
|
||||
}
|
||||
@ -100,7 +100,7 @@ public:
|
||||
void CreateWithEncryptionKey(const string &encKey, const string &password = "mypassword") {
|
||||
auto askPassword = [password] { return password;};
|
||||
FakeRandomGenerator generator(Data::FromString(encKey));
|
||||
auto loader = CryConfigLoader(console, generator, SCrypt::TestSettings, askPassword,
|
||||
auto loader = CryConfigLoader(console, generator, localStateDir, SCrypt::TestSettings, askPassword,
|
||||
askPassword, none, none, none);
|
||||
ASSERT_NE(boost::none, loader.loadOrCreate(file.path(), false, false));
|
||||
}
|
||||
@ -151,6 +151,8 @@ public:
|
||||
|
||||
std::shared_ptr<MockConsole> console;
|
||||
TempFile file;
|
||||
cpputils::TempDir tempLocalStateDir;
|
||||
LocalStateDir localStateDir;
|
||||
};
|
||||
|
||||
TEST_F(CryConfigLoaderTest, CreatesNewIfNotExisting) {
|
||||
|
@ -33,38 +33,40 @@ using namespace cryfs;
|
||||
|
||||
class CryFsTest: public Test, public TestWithMockConsole, public TestWithFakeHomeDirectory {
|
||||
public:
|
||||
CryFsTest(): rootdir(), config(false) {
|
||||
CryFsTest(): tempLocalStateDir(), localStateDir(tempLocalStateDir.path()), rootdir(), config(false) {
|
||||
}
|
||||
|
||||
CryConfigFile loadOrCreateConfig() {
|
||||
auto askPassword = [] {return "mypassword";};
|
||||
return CryConfigLoader(make_shared<NoninteractiveConsole>(mockConsole()), Random::PseudoRandom(), SCrypt::TestSettings, askPassword, askPassword, none, none, none).loadOrCreate(config.path(), false, false).value().configFile;
|
||||
return CryConfigLoader(make_shared<NoninteractiveConsole>(mockConsole()), Random::PseudoRandom(), localStateDir, SCrypt::TestSettings, askPassword, askPassword, none, none, none).loadOrCreate(config.path(), false, false).value().configFile;
|
||||
}
|
||||
|
||||
unique_ref<OnDiskBlockStore2> blockStore() {
|
||||
return make_unique_ref<OnDiskBlockStore2>(rootdir.path());
|
||||
}
|
||||
|
||||
cpputils::TempDir tempLocalStateDir;
|
||||
LocalStateDir localStateDir;
|
||||
TempDir rootdir;
|
||||
TempFile config;
|
||||
};
|
||||
|
||||
TEST_F(CryFsTest, CreatedRootdirIsLoadableAfterClosing) {
|
||||
{
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), localStateDir, 0x12345678, false, false);
|
||||
}
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), localStateDir, 0x12345678, false, false);
|
||||
auto rootDir = dev.LoadDir(bf::path("/"));
|
||||
rootDir.value()->children();
|
||||
}
|
||||
|
||||
TEST_F(CryFsTest, LoadingFilesystemDoesntModifyConfigFile) {
|
||||
{
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), localStateDir, 0x12345678, false, false);
|
||||
}
|
||||
Data configAfterCreating = Data::LoadFromFile(config.path()).value();
|
||||
{
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), 0x12345678, false, false);
|
||||
CryDevice dev(loadOrCreateConfig(), blockStore(), localStateDir, 0x12345678, false, false);
|
||||
}
|
||||
Data configAfterLoading = Data::LoadFromFile(config.path()).value();
|
||||
EXPECT_EQ(configAfterCreating, configAfterLoading);
|
||||
|
@ -23,16 +23,18 @@ class CryFsTestFixture: public FileSystemTestFixture, public TestWithMockConsole
|
||||
public:
|
||||
CryFsTestFixture()
|
||||
// Don't create config tempfile yet
|
||||
: configFile(false) {}
|
||||
: tempLocalStateDir(), localStateDir(tempLocalStateDir.path()), configFile(false) {}
|
||||
|
||||
unique_ref<Device> createDevice() override {
|
||||
auto blockStore = cpputils::make_unique_ref<InMemoryBlockStore2>();
|
||||
auto askPassword = [] {return "mypassword";};
|
||||
auto config = CryConfigLoader(make_shared<NoninteractiveConsole>(mockConsole()), Random::PseudoRandom(), SCrypt::TestSettings, askPassword, askPassword, none, none, none)
|
||||
auto config = CryConfigLoader(make_shared<NoninteractiveConsole>(mockConsole()), Random::PseudoRandom(), localStateDir, SCrypt::TestSettings, askPassword, askPassword, none, none, none)
|
||||
.loadOrCreate(configFile.path(), false, false).value();
|
||||
return make_unique_ref<CryDevice>(std::move(config.configFile), std::move(blockStore), config.myClientId, false, false);
|
||||
return make_unique_ref<CryDevice>(std::move(config.configFile), std::move(blockStore), localStateDir, config.myClientId, false, false);
|
||||
}
|
||||
|
||||
cpputils::TempDir tempLocalStateDir;
|
||||
LocalStateDir localStateDir;
|
||||
cpputils::TempFile configFile;
|
||||
};
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
class CryTestBase : public TestWithFakeHomeDirectory {
|
||||
public:
|
||||
CryTestBase(): _configFile(false), _device(nullptr) {
|
||||
CryTestBase(): _tempLocalStateDir(), _localStateDir(_tempLocalStateDir.path()), _configFile(false), _device(nullptr) {
|
||||
auto fakeBlockStore = cpputils::make_unique_ref<blockstore::inmemory::InMemoryBlockStore2>();
|
||||
_device = std::make_unique<cryfs::CryDevice>(configFile(), std::move(fakeBlockStore), 0x12345678, false, false);
|
||||
_device = std::make_unique<cryfs::CryDevice>(configFile(), std::move(fakeBlockStore), _localStateDir, 0x12345678, false, false);
|
||||
}
|
||||
|
||||
cryfs::CryConfigFile configFile() {
|
||||
@ -27,6 +27,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
cpputils::TempDir _tempLocalStateDir;
|
||||
cryfs::LocalStateDir _localStateDir;
|
||||
cpputils::TempFile _configFile;
|
||||
std::unique_ptr<cryfs::CryDevice> _device;
|
||||
};
|
||||
|
@ -14,6 +14,9 @@ using FilesystemID = cryfs::CryConfig::FilesystemID ;
|
||||
|
||||
class BasedirMetadataTest : public ::testing::Test, TestWithFakeHomeDirectory {
|
||||
public:
|
||||
TempDir tempLocalStateDir;
|
||||
cryfs::LocalStateDir localStateDir;
|
||||
|
||||
TempDir tempdir;
|
||||
bf::path basedir1;
|
||||
bf::path basedir2;
|
||||
@ -21,7 +24,9 @@ public:
|
||||
const FilesystemID id2;
|
||||
|
||||
BasedirMetadataTest()
|
||||
: tempdir()
|
||||
: tempLocalStateDir()
|
||||
, localStateDir(tempLocalStateDir.path())
|
||||
, tempdir()
|
||||
, basedir1(tempdir.path() / "my/basedir")
|
||||
, basedir2(tempdir.path() / "my/other/basedir")
|
||||
, id1(FilesystemID::FromString("1491BB4932A389EE14BC7090AC772972"))
|
||||
@ -35,32 +40,32 @@ public:
|
||||
};
|
||||
|
||||
TEST_F(BasedirMetadataTest, givenEmptyState_whenCalled_thenSucceeds) {
|
||||
EXPECT_TRUE(BasedirMetadata::load().filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
EXPECT_TRUE(BasedirMetadata::load(localStateDir).filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
}
|
||||
|
||||
TEST_F(BasedirMetadataTest, givenStateWithBasedir_whenCalledForDifferentBasedir_thenSucceeds) {
|
||||
BasedirMetadata::load().updateFilesystemIdForBasedir(basedir2, id1).save();
|
||||
EXPECT_TRUE(BasedirMetadata::load().filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
BasedirMetadata::load(localStateDir).updateFilesystemIdForBasedir(basedir2, id1).save();
|
||||
EXPECT_TRUE(BasedirMetadata::load(localStateDir).filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
}
|
||||
|
||||
TEST_F(BasedirMetadataTest, givenStateWithBasedir_whenCalledWithSameId_thenSucceeds) {
|
||||
BasedirMetadata::load().updateFilesystemIdForBasedir(basedir1, id1).save();
|
||||
EXPECT_TRUE(BasedirMetadata::load().filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
BasedirMetadata::load(localStateDir).updateFilesystemIdForBasedir(basedir1, id1).save();
|
||||
EXPECT_TRUE(BasedirMetadata::load(localStateDir).filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
}
|
||||
|
||||
TEST_F(BasedirMetadataTest, givenStateWithBasedir_whenCalledWithDifferentId_thenFails) {
|
||||
BasedirMetadata::load().updateFilesystemIdForBasedir(basedir1, id2).save();
|
||||
EXPECT_FALSE(BasedirMetadata::load().filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
BasedirMetadata::load(localStateDir).updateFilesystemIdForBasedir(basedir1, id2).save();
|
||||
EXPECT_FALSE(BasedirMetadata::load(localStateDir).filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
}
|
||||
|
||||
TEST_F(BasedirMetadataTest, givenStateWithUpdatedBasedir_whenCalledWithSameId_thenSucceeds) {
|
||||
BasedirMetadata::load().updateFilesystemIdForBasedir(basedir1, id2).save();
|
||||
BasedirMetadata::load().updateFilesystemIdForBasedir(basedir1, id1).save();
|
||||
EXPECT_TRUE(BasedirMetadata::load().filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
BasedirMetadata::load(localStateDir).updateFilesystemIdForBasedir(basedir1, id2).save();
|
||||
BasedirMetadata::load(localStateDir).updateFilesystemIdForBasedir(basedir1, id1).save();
|
||||
EXPECT_TRUE(BasedirMetadata::load(localStateDir).filesystemIdForBasedirIsCorrect(basedir1, id1));
|
||||
}
|
||||
|
||||
TEST_F(BasedirMetadataTest, givenStateWithUpdatedBasedir_whenCalledWithDifferentId_thenFails) {
|
||||
BasedirMetadata::load().updateFilesystemIdForBasedir(basedir1, id2).save();
|
||||
BasedirMetadata::load().updateFilesystemIdForBasedir(basedir1, id1).save();
|
||||
EXPECT_FALSE(BasedirMetadata::load().filesystemIdForBasedirIsCorrect(basedir1, id2));
|
||||
BasedirMetadata::load(localStateDir).updateFilesystemIdForBasedir(basedir1, id2).save();
|
||||
BasedirMetadata::load(localStateDir).updateFilesystemIdForBasedir(basedir1, id1).save();
|
||||
EXPECT_FALSE(BasedirMetadata::load(localStateDir).filesystemIdForBasedirIsCorrect(basedir1, id2));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user