Merge from develop

This commit is contained in:
Sebastian Messmer 2018-02-01 11:21:26 -08:00
commit 05f3726ec3
15 changed files with 152 additions and 55 deletions

View File

@ -15,6 +15,13 @@ Fixed bugs:
* `du` shows correct file system size on Mac OS X.
Version 0.9.9 (unreleased)
--------------
Improvements:
* Add --allow-filesystem-upgrade option which will upgrade old file systems without asking the user. This will be especially helpful for GUI tools.
* Add --version option that shows the CryFS version and exits.
Version 0.9.8
--------------
Compatibility:

View File

@ -19,7 +19,7 @@ cryfs \- cryptographic filesystem for the cloud
[\fB\-\-\fR \fIfuse-options\fR]
.br
.\" show-ciphers syntax
.B cryfs \-\-help\fR|\fB\-\-show-ciphers
.B cryfs \-\-help\fR|\fB\-\-version\fR|\fB\-\-show-ciphers
.
.
.
@ -119,6 +119,12 @@ Show a help message containing short descriptions for all options.
Show a list of all supported encryption ciphers.
.
.
.TP
\fB\-\-version\fR
.
Show the CryFS version number.
.
.
.SS Encryption parameters
.
.TP
@ -157,6 +163,12 @@ Run CryFS in the foreground. Stop using CTRL-C.
.
.
.TP
\fB\-\-allow-filesystem-upgrade\fI
.
Allow upgrading the file system if it was created with an old CryFS version. After the upgrade, older CryFS versions might not be able to use the file system anymore.
.
.
.TP
\fB\-\-logfile\fR \fIfile\fR
.
Write status information to \fIfile\fR. If no logfile is given, CryFS will

View File

@ -207,7 +207,7 @@ namespace cryfs {
CryConfigLoader::ConfigLoadResult Cli::_loadOrCreateConfig(const ProgramOptions &options) {
try {
auto configFile = _determineConfigFile(options);
auto config = _loadOrCreateConfigFile(std::move(configFile), options.cipher(), options.blocksizeBytes(), options.missingBlockIsIntegrityViolation());
auto config = _loadOrCreateConfigFile(std::move(configFile), options.cipher(), options.blocksizeBytes(), options.allowFilesystemUpgrade(), options.missingBlockIsIntegrityViolation());
if (config == none) {
std::cerr << "Could not load config file. Did you enter the correct password?" << std::endl;
exit(1);
@ -220,17 +220,17 @@ namespace cryfs {
}
}
optional<CryConfigLoader::ConfigLoadResult> Cli::_loadOrCreateConfigFile(bf::path configFilePath, const optional<string> &cipher, const optional<uint32_t> &blocksizeBytes, const optional<bool> &missingBlockIsIntegrityViolation) {
optional<CryConfigLoader::ConfigLoadResult> Cli::_loadOrCreateConfigFile(bf::path configFilePath, const optional<string> &cipher, const optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const optional<bool> &missingBlockIsIntegrityViolation) {
if (_noninteractive) {
return CryConfigLoader(_console, _keyGenerator, _scryptSettings,
&Cli::_askPasswordNoninteractive,
&Cli::_askPasswordNoninteractive,
cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath));
cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath), allowFilesystemUpgrade);
} else {
return CryConfigLoader(_console, _keyGenerator, _scryptSettings,
&Cli::_askPasswordForExistingFilesystem,
&Cli::_askPasswordForNewFilesystem,
cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath));
cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath), allowFilesystemUpgrade);
}
}

View File

@ -24,7 +24,7 @@ namespace cryfs {
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);
boost::optional<CryConfigLoader::ConfigLoadResult> _loadOrCreateConfigFile(boost::filesystem::path configFilePath, const boost::optional<std::string> &cipher, const boost::optional<uint32_t> &blocksizeBytes, const boost::optional<bool> &missingBlockIsIntegrityViolation);
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);
boost::filesystem::path _determineConfigFile(const program_options::ProgramOptions &options);
static std::string _askPasswordForExistingFilesystem();
static std::string _askPasswordForNewFilesystem();

View File

@ -11,6 +11,7 @@ using namespace cryfs::program_options;
using cryfs::CryConfigConsole;
using std::vector;
using std::cerr;
using std::cout;
using std::endl;
using std::string;
using boost::optional;
@ -58,6 +59,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
if (foreground) {
fuseOptions.push_back(const_cast<char*>("-f"));
}
bool allowFilesystemUpgrade = vm.count("allow-filesystem-upgrade");
optional<double> unmountAfterIdleMinutes = none;
if (vm.count("unmount-idle")) {
unmountAfterIdleMinutes = vm["unmount-idle"].as<double>();
@ -91,7 +93,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
}
}
return ProgramOptions(std::move(baseDir), std::move(mountDir), std::move(configfile), foreground, std::move(unmountAfterIdleMinutes), std::move(logfile), std::move(cipher), blocksizeBytes, noIntegrityChecks, std::move(missingBlockIsIntegrityViolation), std::move(fuseOptions));
return ProgramOptions(std::move(baseDir), std::move(mountDir), std::move(configfile), foreground, allowFilesystemUpgrade, std::move(unmountAfterIdleMinutes), std::move(logfile), std::move(cipher), blocksizeBytes, noIntegrityChecks, std::move(missingBlockIsIntegrityViolation), std::move(fuseOptions));
}
void Parser::_checkValidCipher(const string &cipher, const vector<string> &supportedCiphers) {
@ -126,6 +128,9 @@ po::variables_map Parser::_parseOptions(const vector<string> &options, const vec
if (vm.count("show-ciphers")) {
_showCiphersAndExit(supportedCiphers);
}
if (vm.count("version")) {
_showVersionAndExit();
}
po::notify(vm);
return vm;
@ -155,9 +160,11 @@ void Parser::_addAllowedOptions(po::options_description *desc) {
("blocksize", po::value<uint32_t>(), blocksize_description.c_str())
("no-integrity-checks", "Disable integrity checks. Integrity checks ensure that your file system was not manipulated or rolled back to an earlier version. Disabling them is needed if you want to load an old snapshot of your file system.")
("missing-block-is-integrity-violation", po::value<bool>(), "Whether to treat a missing block as an integrity violation. This makes sure you notice if an attacker deleted some of your files, but only works in single-client mode. You will not be able to use the file system on other devices.")
("allow-filesystem-upgrade", "Allow upgrading the file system if it was created with an old CryFS version. After the upgrade, older CryFS versions might not be able to use the file system anymore.")
("show-ciphers", "Show list of supported ciphers.")
("unmount-idle", po::value<double>(), "Automatically unmount after specified number of idle minutes.")
("logfile", po::value<string>(), "Specify the file to write log messages to. If this is not specified, log messages will go to stdout, or syslog if CryFS is running in the background.")
("version", "Show CryFS version number")
;
desc->add(options);
}
@ -197,3 +204,8 @@ void Parser::_addPositionalOptionForBaseDir(po::options_description *desc, po::p
<< endl;
exit(1);
}
[[noreturn]] void Parser::_showVersionAndExit() {
// no need to show version because it was already shown in the CryFS header before parsing program options
exit(0);
}

View File

@ -21,6 +21,7 @@ namespace cryfs {
boost::program_options::positional_options_description *positional);
[[noreturn]] static void _showHelpAndExit();
[[noreturn]] static void _showCiphersAndExit(const std::vector<std::string> &supportedCiphers);
[[noreturn]] static void _showVersionAndExit();
static boost::program_options::variables_map _parseOptionsOrShowHelp(const std::vector<std::string> &options, const std::vector<std::string> &supportedCiphers);
static boost::program_options::variables_map _parseOptions(const std::vector<std::string> &options, const std::vector<std::string> &supportedCiphers);
static void _checkValidCipher(const std::string &cipher, const std::vector<std::string> &supportedCiphers);

View File

@ -9,13 +9,13 @@ using boost::optional;
namespace bf = boost::filesystem;
ProgramOptions::ProgramOptions(bf::path baseDir, bf::path mountDir, optional<bf::path> configFile,
bool foreground, optional<double> unmountAfterIdleMinutes,
bool foreground, bool allowFilesystemUpgrade, optional<double> unmountAfterIdleMinutes,
optional<bf::path> logFile, optional<string> cipher,
optional<uint32_t> blocksizeBytes,
bool noIntegrityChecks,
boost::optional<bool> missingBlockIsIntegrityViolation,
vector<string> fuseOptions)
:_baseDir(std::move(baseDir)), _mountDir(std::move(mountDir)), _configFile(std::move(configFile)), _foreground(foreground), _noIntegrityChecks(noIntegrityChecks),
:_baseDir(std::move(baseDir)), _mountDir(std::move(mountDir)), _configFile(std::move(configFile)), _foreground(foreground), _allowFilesystemUpgrade(allowFilesystemUpgrade), _noIntegrityChecks(noIntegrityChecks),
_cipher(std::move(cipher)), _blocksizeBytes(std::move(blocksizeBytes)), _unmountAfterIdleMinutes(std::move(unmountAfterIdleMinutes)),
_missingBlockIsIntegrityViolation(std::move(missingBlockIsIntegrityViolation)), _logFile(std::move(logFile)), _fuseOptions(std::move(fuseOptions)) {
}
@ -36,6 +36,10 @@ bool ProgramOptions::foreground() const {
return _foreground;
}
bool ProgramOptions::allowFilesystemUpgrade() const {
return _allowFilesystemUpgrade;
}
const optional<double> &ProgramOptions::unmountAfterIdleMinutes() const {
return _unmountAfterIdleMinutes;
}

View File

@ -14,7 +14,7 @@ namespace cryfs {
public:
ProgramOptions(boost::filesystem::path baseDir, boost::filesystem::path mountDir,
boost::optional<boost::filesystem::path> configFile,
bool foreground, boost::optional<double> unmountAfterIdleMinutes,
bool foreground, bool allowFilesystemUpgrade, boost::optional<double> unmountAfterIdleMinutes,
boost::optional<boost::filesystem::path> logFile,
boost::optional<std::string> cipher,
boost::optional<uint32_t> blocksizeBytes,
@ -27,6 +27,7 @@ namespace cryfs {
const boost::filesystem::path &mountDir() const;
const boost::optional<boost::filesystem::path> &configFile() const;
bool foreground() const;
bool allowFilesystemUpgrade() const;
const boost::optional<std::string> &cipher() const;
const boost::optional<uint32_t> &blocksizeBytes() const;
const boost::optional<double> &unmountAfterIdleMinutes() const;
@ -40,6 +41,7 @@ namespace cryfs {
boost::filesystem::path _mountDir;
boost::optional<boost::filesystem::path> _configFile;
bool _foreground;
bool _allowFilesystemUpgrade;
bool _noIntegrityChecks;
boost::optional<std::string> _cipher;
boost::optional<uint32_t> _blocksizeBytes;

View File

@ -31,7 +31,7 @@ CryConfigLoader::CryConfigLoader(shared_ptr<Console> console, RandomGenerator &k
_missingBlockIsIntegrityViolationFromCommandLine(missingBlockIsIntegrityViolationFromCommandLine) {
}
optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::_loadConfig(bf::path filename) {
optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::_loadConfig(bf::path filename, bool allowFilesystemUpgrade) {
string password = _askPasswordForExistingFilesystem();
std::cout << "Loading config file (this can take some time)..." << std::flush;
auto config = CryConfigFile::load(std::move(filename), password);
@ -39,7 +39,7 @@ optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::_loadConfig(bf::pat
return none;
}
std::cout << "done" << std::endl;
_checkVersion(*config->config());
_checkVersion(*config->config(), allowFilesystemUpgrade);
#ifndef CRYFS_NO_COMPATIBILITY
//Since 0.9.3-alpha set the config value cryfs.blocksizeBytes wrongly to 32768 (but didn't use the value), we have to fix this here.
if (config->config()->Version() != "0+unknown" && VersionCompare::isOlderThan(config->config()->Version(), "0.9.3-rc1")) {
@ -57,13 +57,13 @@ optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::_loadConfig(bf::pat
return ConfigLoadResult {std::move(*config), myClientId};
}
void CryConfigLoader::_checkVersion(const CryConfig &config) {
void CryConfigLoader::_checkVersion(const CryConfig &config, bool allowFilesystemUpgrade) {
if (gitversion::VersionCompare::isOlderThan(gitversion::VersionString(), config.Version())) {
if (!_console->askYesNo("This filesystem is for CryFS " + config.Version() + " and should not be opened with older versions. It is strongly recommended to update your CryFS version. However, if you have backed up your base directory and know what you're doing, you can continue trying to load it. Do you want to continue?", false)) {
throw std::runtime_error("This filesystem is for CryFS " + config.Version() + ". Please update your CryFS version.");
}
}
if (gitversion::VersionCompare::isOlderThan(config.Version(), gitversion::VersionString())) {
if (!allowFilesystemUpgrade && gitversion::VersionCompare::isOlderThan(config.Version(), gitversion::VersionString())) {
if (!_console->askYesNo("This filesystem is for CryFS " + config.Version() + ". It can be migrated to CryFS " + gitversion::VersionString() + ", but afterwards couldn't be opened anymore with older versions. Do you want to migrate it?", false)) {
throw std::runtime_error("This filesystem is for CryFS " + config.Version() + ". It has to be migrated.");
}
@ -95,9 +95,9 @@ void CryConfigLoader::_checkMissingBlocksAreIntegrityViolations(CryConfigFile *c
}
}
optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::loadOrCreate(bf::path filename) {
optional<CryConfigLoader::ConfigLoadResult> CryConfigLoader::loadOrCreate(bf::path filename, bool allowFilesystemUpgrade) {
if (bf::exists(filename)) {
return _loadConfig(std::move(filename));
return _loadConfig(std::move(filename), allowFilesystemUpgrade);
} else {
return _createConfig(std::move(filename));
}

View File

@ -21,12 +21,12 @@ public:
uint32_t myClientId;
};
boost::optional<ConfigLoadResult> loadOrCreate(boost::filesystem::path filename);
boost::optional<ConfigLoadResult> loadOrCreate(boost::filesystem::path filename, bool allowFilesystemUpgrade);
private:
boost::optional<ConfigLoadResult> _loadConfig(boost::filesystem::path filename);
boost::optional<ConfigLoadResult> _loadConfig(boost::filesystem::path filename, bool allowFilesystemUpgrade);
ConfigLoadResult _createConfig(boost::filesystem::path filename);
void _checkVersion(const CryConfig &config);
void _checkVersion(const CryConfig &config, bool allowFilesystemUpgrade);
void _checkCipher(const CryConfig &config) const;
void _checkMissingBlocksAreIntegrityViolations(CryConfigFile *configFile, uint32_t myClientId);

View File

@ -2,6 +2,7 @@
#include <cryfs-cli/program_options/Parser.h>
#include <cryfs/config/CryCipher.h>
#include <cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
#include <gitversion/gitversion.h>
using namespace cryfs;
using namespace cryfs::program_options;
@ -54,6 +55,16 @@ TEST_F(ProgramOptionsParserTest, ShowCiphers) {
);
}
TEST_F(ProgramOptionsParserTest, Version) {
string expected = "CryFS Version " + gitversion::VersionString();
EXPECT_EXIT(
parse({"./myExecutable", "--version"}),
::testing::ExitedWithCode(0),
expected.c_str()
);
}
TEST_F(ProgramOptionsParserTest, BaseDir_Absolute) {
ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir"});
EXPECT_EQ("/home/user/baseDir", options.baseDir());
@ -74,6 +85,26 @@ TEST_F(ProgramOptionsParserTest, MountDir_Relative) {
EXPECT_EQ(bf::current_path() / "mountDir", options.mountDir());
}
TEST_F(ProgramOptionsParserTest, Foreground_False) {
ProgramOptions options = parse({"./myExecutable", "/home/user/basedir", "mountdir"});
EXPECT_FALSE(options.foreground());
}
TEST_F(ProgramOptionsParserTest, Foreground_True) {
ProgramOptions options = parse({"./myExecutable", "-f", "/home/user/basedir", "mountdir"});
EXPECT_TRUE(options.foreground());
}
TEST_F(ProgramOptionsParserTest, AllowFilesystemUpgrade_False) {
ProgramOptions options = parse({"./myExecutable", "/home/user/basedir", "mountdir"});
EXPECT_FALSE(options.allowFilesystemUpgrade());
}
TEST_F(ProgramOptionsParserTest, AllowFilesystemUpgrade_True) {
ProgramOptions options = parse({"./myExecutable", "--allow-filesystem-upgrade", "/home/user/basedir", "mountdir"});
EXPECT_TRUE(options.allowFilesystemUpgrade());
}
TEST_F(ProgramOptionsParserTest, LogfileGiven) {
ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "--logfile", "/home/user/mylogfile", "/home/user/mountDir"});
EXPECT_EQ("/home/user/mylogfile", options.logFile().value());

View File

@ -22,108 +22,119 @@ namespace boost {
class ProgramOptionsTest: public ProgramOptionsTestBase {};
TEST_F(ProgramOptionsTest, BaseDir) {
ProgramOptions testobj("/home/user/mydir", "", none, false, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("/home/user/mydir", "", none, false, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ("/home/user/mydir", testobj.baseDir());
}
TEST_F(ProgramOptionsTest, MountDir) {
ProgramOptions testobj("", "/home/user/mydir", none, false, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "/home/user/mydir", none, false, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ("/home/user/mydir", testobj.mountDir());
}
TEST_F(ProgramOptionsTest, ConfigfileNone) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(none, testobj.configFile());
}
TEST_F(ProgramOptionsTest, ConfigfileSome) {
ProgramOptions testobj("", "", bf::path("/home/user/configfile"), true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", bf::path("/home/user/configfile"), true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ("/home/user/configfile", testobj.configFile().get());
}
TEST_F(ProgramOptionsTest, ForegroundFalse) {
ProgramOptions testobj("", "", none, false, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, false, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_FALSE(testobj.foreground());
}
TEST_F(ProgramOptionsTest, ForegroundTrue) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_TRUE(testobj.foreground());
}
TEST_F(ProgramOptionsTest, AllowFilesystemUpgradeFalse) {
ProgramOptions testobj("", "", none, false, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_FALSE(testobj.allowFilesystemUpgrade());
}
TEST_F(ProgramOptionsTest, AllowFilesystemUpgradeTrue) {
ProgramOptions testobj("", "", none, false, true, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_TRUE(testobj.allowFilesystemUpgrade());
}
TEST_F(ProgramOptionsTest, LogfileNone) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(none, testobj.logFile());
}
TEST_F(ProgramOptionsTest, LogfileSome) {
ProgramOptions testobj("", "", none, true, none, bf::path("logfile"), none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, bf::path("logfile"), none, none, false, none, {"./myExecutable"});
EXPECT_EQ("logfile", testobj.logFile().get());
}
TEST_F(ProgramOptionsTest, UnmountAfterIdleMinutesNone) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(none, testobj.unmountAfterIdleMinutes());
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(none, testobj.unmountAfterIdleMinutes());
}
TEST_F(ProgramOptionsTest, UnmountAfterIdleMinutesSome) {
ProgramOptions testobj("", "", none, true, 10, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, 10, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(10, testobj.unmountAfterIdleMinutes().get());
}
TEST_F(ProgramOptionsTest, CipherNone) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(none, testobj.cipher());
}
TEST_F(ProgramOptionsTest, CipherSome) {
ProgramOptions testobj("", "", none, true, none, none, string("aes-256-gcm"), none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, string("aes-256-gcm"), none, false, none, {"./myExecutable"});
EXPECT_EQ("aes-256-gcm", testobj.cipher().get());
}
TEST_F(ProgramOptionsTest, BlocksizeBytesNone) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(none, testobj.blocksizeBytes());
}
TEST_F(ProgramOptionsTest, BlocksizeBytesSome) {
ProgramOptions testobj("", "", none, true, none, none, none, 10*1024, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, 10*1024, false, none, {"./myExecutable"});
EXPECT_EQ(10*1024u, testobj.blocksizeBytes().get());
}
TEST_F(ProgramOptionsTest, MissingBlockIsIntegrityViolationTrue) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, true, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, true, {"./myExecutable"});
EXPECT_TRUE(testobj.missingBlockIsIntegrityViolation().value());
}
TEST_F(ProgramOptionsTest, MissingBlockIsIntegrityViolationFalse) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, false, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, false, {"./myExecutable"});
EXPECT_FALSE(testobj.missingBlockIsIntegrityViolation().value());
}
TEST_F(ProgramOptionsTest, MissingBlockIsIntegrityViolationNone) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_EQ(none, testobj.missingBlockIsIntegrityViolation());
}
TEST_F(ProgramOptionsTest, NoIntegrityChecksFalse) {
ProgramOptions testobj("", "", none, true, none, none, none, none, false, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, false, none, {"./myExecutable"});
EXPECT_FALSE(testobj.noIntegrityChecks());
}
TEST_F(ProgramOptionsTest, NoIntegrityChecksTrue) {
ProgramOptions testobj("", "", none, true, none, none, none, none, true, none, {"./myExecutable"});
ProgramOptions testobj("", "", none, true, false, none, none, none, none, true, none, {"./myExecutable"});
EXPECT_TRUE(testobj.noIntegrityChecks());
}
TEST_F(ProgramOptionsTest, EmptyFuseOptions) {
ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, none, none, none, false, none, {});
ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, false, none, none, none, none, false, none, {});
//Fuse should have the mount dir as first parameter
EXPECT_VECTOR_EQ({}, testobj.fuseOptions());
}
TEST_F(ProgramOptionsTest, SomeFuseOptions) {
ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, none, none, none, false, none, {"-f", "--longoption"});
ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, false, none, none, none, none, false, none, {"-f", "--longoption"});
//Fuse should have the mount dir as first parameter
EXPECT_VECTOR_EQ({"-f", "--longoption"}, testobj.fuseOptions());
}

View File

@ -22,6 +22,7 @@ using std::ostream;
using std::make_shared;
using ::testing::Return;
using ::testing::HasSubstr;
using ::testing::_;
using namespace cryfs;
@ -71,12 +72,12 @@ public:
CryConfigFile Create(const string &password = "mypassword", const optional<string> &cipher = none, bool noninteractive = false) {
EXPECT_FALSE(file.exists());
return loader(password, noninteractive, cipher).loadOrCreate(file.path()).value().configFile;
return loader(password, noninteractive, cipher).loadOrCreate(file.path(), false).value().configFile;
}
optional<CryConfigFile> Load(const string &password = "mypassword", const optional<string> &cipher = none, bool noninteractive = false) {
optional<CryConfigFile> Load(const string &password = "mypassword", const optional<string> &cipher = none, bool noninteractive = false, bool allowFilesystemUpgrade = false) {
EXPECT_TRUE(file.exists());
auto loadResult = loader(password, noninteractive, cipher).loadOrCreate(file.path());
auto loadResult = loader(password, noninteractive, cipher).loadOrCreate(file.path(), allowFilesystemUpgrade);
if (loadResult == none) {
return none;
}
@ -84,13 +85,13 @@ public:
}
void CreateWithRootBlob(const string &rootBlob, const string &password = "mypassword") {
auto cfg = loader(password, false).loadOrCreate(file.path()).value().configFile;
auto cfg = loader(password, false).loadOrCreate(file.path(), false).value().configFile;
cfg.config()->SetRootBlob(rootBlob);
cfg.save();
}
void CreateWithCipher(const string &cipher, const string &password = "mypassword") {
auto cfg = loader(password, false).loadOrCreate(file.path()).value().configFile;
auto cfg = loader(password, false).loadOrCreate(file.path(), false).value().configFile;
cfg.config()->SetCipher(cipher);
cfg.save();
}
@ -100,7 +101,7 @@ public:
FakeRandomGenerator generator(Data::FromString(encKey));
auto loader = CryConfigLoader(console, generator, SCrypt::TestSettings, askPassword,
askPassword, none, none, none);
ASSERT_NE(boost::none, loader.loadOrCreate(file.path()));
ASSERT_NE(boost::none, loader.loadOrCreate(file.path(), false));
}
void ChangeEncryptionKey(const string &encKey, const string& password = "mypassword") {
@ -110,14 +111,14 @@ public:
}
void CreateWithVersion(const string &version, const string &password = "mypassword") {
auto cfg = loader(password, false).loadOrCreate(file.path()).value().configFile;
auto cfg = loader(password, false).loadOrCreate(file.path(), false).value().configFile;
cfg.config()->SetVersion(version);
cfg.config()->SetCreatedWithVersion(version);
cfg.save();
}
void CreateWithFilesystemID(const CryConfig::FilesystemID &filesystemId, const string &password = "mypassword") {
auto cfg = loader(password, false).loadOrCreate(file.path()).value().configFile;
auto cfg = loader(password, false).loadOrCreate(file.path(), false).value().configFile;
cfg.config()->SetFilesystemId(filesystemId);
cfg.save();
}
@ -325,12 +326,28 @@ TEST_F(CryConfigLoaderTest, DontMigrateWhenAnsweredNo) {
TEST_F(CryConfigLoaderTest, MyClientIdIsIndeterministic) {
TempFile file1(false);
TempFile file2(false);
uint32_t myClientId = loader("mypassword", true).loadOrCreate(file1.path()).value().myClientId;
EXPECT_NE(myClientId, loader("mypassword", true).loadOrCreate(file2.path()).value().myClientId);
uint32_t myClientId = loader("mypassword", true).loadOrCreate(file1.path(), false).value().myClientId;
EXPECT_NE(myClientId, loader("mypassword", true).loadOrCreate(file2.path(), false).value().myClientId);
}
TEST_F(CryConfigLoaderTest, MyClientIdIsLoadedCorrectly) {
TempFile file(false);
uint32_t myClientId = loader("mypassword", true).loadOrCreate(file.path()).value().myClientId;
EXPECT_EQ(myClientId, loader("mypassword", true).loadOrCreate(file.path()).value().myClientId);
uint32_t myClientId = loader("mypassword", true).loadOrCreate(file.path(), false).value().myClientId;
EXPECT_EQ(myClientId, loader("mypassword", true).loadOrCreate(file.path(), false).value().myClientId);
}
TEST_F(CryConfigLoaderTest, DoesNotAskForMigrationWhenUpgradesAllowedByProgramArguments_NoninteractiveMode) {
EXPECT_CALL(*console, askYesNo(HasSubstr("migrate"), _)).Times(0);
string version = olderVersion();
CreateWithVersion(version);
EXPECT_NE(boost::none, Load("mypassword", none, true, true));
}
TEST_F(CryConfigLoaderTest, DoesNotAskForMigrationWhenUpgradesAllowedByProgramArguments_InteractiveMode) {
EXPECT_CALL(*console, askYesNo(HasSubstr("migrate"), _)).Times(0);
string version = olderVersion();
CreateWithVersion(version);
EXPECT_NE(boost::none, Load("mypassword", none, false, true));
}

View File

@ -38,7 +38,7 @@ public:
CryConfigFile loadOrCreateConfig() {
auto askPassword = [] {return "mypassword";};
return CryConfigLoader(make_shared<NoninteractiveConsole>(mockConsole()), Random::PseudoRandom(), SCrypt::TestSettings, askPassword, askPassword, none, none, none).loadOrCreate(config.path()).value().configFile;
return CryConfigLoader(make_shared<NoninteractiveConsole>(mockConsole()), Random::PseudoRandom(), SCrypt::TestSettings, askPassword, askPassword, none, none, none).loadOrCreate(config.path(), false).value().configFile;
}
unique_ref<OnDiskBlockStore2> blockStore() {

View File

@ -29,7 +29,7 @@ public:
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)
.loadOrCreate(configFile.path()).value();
.loadOrCreate(configFile.path(), false).value();
return make_unique_ref<CryDevice>(std::move(config.configFile), std::move(blockStore), config.myClientId, false, false);
}