Ask before migrating an old CryFS file system to a new version.
This commit is contained in:
parent
010833e25b
commit
9a0b0a0c36
@ -28,7 +28,7 @@ using namespace cpputils::logging;
|
|||||||
namespace cryfs {
|
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, bool noninteractive)
|
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, bool noninteractive)
|
||||||
: _creator(std::move(console), keyGenerator, noninteractive), _scryptSettings(scryptSettings),
|
: _console(console), _creator(console, keyGenerator, noninteractive), _scryptSettings(scryptSettings),
|
||||||
_askPasswordForExistingFilesystem(askPasswordForExistingFilesystem), _askPasswordForNewFilesystem(askPasswordForNewFilesystem),
|
_askPasswordForExistingFilesystem(askPasswordForExistingFilesystem), _askPasswordForNewFilesystem(askPasswordForNewFilesystem),
|
||||||
_cipherFromCommandLine(cipherFromCommandLine), _blocksizeBytesFromCommandLine(blocksizeBytesFromCommandLine) {
|
_cipherFromCommandLine(cipherFromCommandLine), _blocksizeBytesFromCommandLine(blocksizeBytesFromCommandLine) {
|
||||||
}
|
}
|
||||||
@ -57,12 +57,13 @@ optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CryConfigLoader::_checkVersion(const CryConfig &config) {
|
void CryConfigLoader::_checkVersion(const CryConfig &config) {
|
||||||
const string allowedVersionPrefix = string() + gitversion::MajorVersion() + "." + gitversion::MinorVersion() + ".";
|
|
||||||
if (!boost::starts_with(config.Version(), allowedVersionPrefix)) {
|
|
||||||
throw std::runtime_error(string() + "This filesystem was created with CryFS " + config.Version() + " and is incompatible. Please create a new one with your version of CryFS and migrate your data.");
|
|
||||||
}
|
|
||||||
if (gitversion::VersionCompare::isOlderThan(gitversion::VersionString(), config.Version())) {
|
if (gitversion::VersionCompare::isOlderThan(gitversion::VersionString(), config.Version())) {
|
||||||
throw std::runtime_error(string() + "This filesystem was used with CryFS " + config.Version() + " and should not be opened with older versions anymore. Please update your CryFS version.");
|
throw std::runtime_error(string() + "This filesystem is for CryFS " + config.Version() + " and should not be opened with older versions. Please update your CryFS version.");
|
||||||
|
}
|
||||||
|
if (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?")) {
|
||||||
|
throw std::runtime_error(string() + "Not migrating file system.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,9 +21,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
boost::optional<CryConfigFile> _loadConfig(const boost::filesystem::path &filename);
|
boost::optional<CryConfigFile> _loadConfig(const boost::filesystem::path &filename);
|
||||||
CryConfigFile _createConfig(const boost::filesystem::path &filename);
|
CryConfigFile _createConfig(const boost::filesystem::path &filename);
|
||||||
static void _checkVersion(const CryConfig &config);
|
void _checkVersion(const CryConfig &config);
|
||||||
void _checkCipher(const CryConfig &config) const;
|
void _checkCipher(const CryConfig &config) const;
|
||||||
|
|
||||||
|
std::shared_ptr<cpputils::Console> _console;
|
||||||
CryConfigCreator _creator;
|
CryConfigCreator _creator;
|
||||||
cpputils::SCryptSettings _scryptSettings;
|
cpputils::SCryptSettings _scryptSettings;
|
||||||
std::function<std::string()> _askPasswordForExistingFilesystem;
|
std::function<std::string()> _askPasswordForExistingFilesystem;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <cpp-utils/random/Random.h>
|
#include <cpp-utils/random/Random.h>
|
||||||
#include <cpp-utils/crypto/symmetric/ciphers.h>
|
#include <cpp-utils/crypto/symmetric/ciphers.h>
|
||||||
#include <gitversion/gitversion.h>
|
#include <gitversion/gitversion.h>
|
||||||
|
#include <gitversion/VersionCompare.h>
|
||||||
|
|
||||||
using cpputils::unique_ref;
|
using cpputils::unique_ref;
|
||||||
using cpputils::make_unique_ref;
|
using cpputils::make_unique_ref;
|
||||||
@ -16,6 +17,7 @@ using std::string;
|
|||||||
using std::ostream;
|
using std::ostream;
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
|
using ::testing::HasSubstr;
|
||||||
|
|
||||||
using namespace cryfs;
|
using namespace cryfs;
|
||||||
|
|
||||||
@ -29,11 +31,13 @@ namespace boost {
|
|||||||
|
|
||||||
class CryConfigLoaderTest: public ::testing::Test, public TestWithMockConsole {
|
class CryConfigLoaderTest: public ::testing::Test, public TestWithMockConsole {
|
||||||
public:
|
public:
|
||||||
CryConfigLoaderTest(): file(false) {}
|
CryConfigLoaderTest(): file(false) {
|
||||||
|
console = mockConsole();
|
||||||
|
}
|
||||||
|
|
||||||
CryConfigLoader loader(const string &password, bool noninteractive, const optional<string> &cipher = none) {
|
CryConfigLoader loader(const string &password, bool noninteractive, const optional<string> &cipher = none) {
|
||||||
auto askPassword = [password] { return password;};
|
auto askPassword = [password] { return password;};
|
||||||
return CryConfigLoader(mockConsole(), cpputils::Random::PseudoRandom(), SCrypt::TestSettings, askPassword, askPassword, cipher, none, noninteractive);
|
return CryConfigLoader(console, cpputils::Random::PseudoRandom(), SCrypt::TestSettings, askPassword, askPassword, cipher, none, noninteractive);
|
||||||
}
|
}
|
||||||
|
|
||||||
CryConfigFile Create(const string &password = "mypassword", const optional<string> &cipher = none, bool noninteractive = false) {
|
CryConfigFile Create(const string &password = "mypassword", const optional<string> &cipher = none, bool noninteractive = false) {
|
||||||
@ -71,6 +75,24 @@ public:
|
|||||||
cfg.save();
|
cfg.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string olderVersion() {
|
||||||
|
string olderVersion;
|
||||||
|
if (std::stol(gitversion::MinorVersion()) > 0) {
|
||||||
|
olderVersion = gitversion::MajorVersion() + "." + std::to_string(std::stol(gitversion::MinorVersion()) - 1);
|
||||||
|
} else {
|
||||||
|
olderVersion = std::to_string(std::stol(gitversion::MajorVersion()) - 1) + "." + gitversion::MinorVersion();
|
||||||
|
}
|
||||||
|
assert(gitversion::VersionCompare::isOlderThan(olderVersion, gitversion::VersionString()));
|
||||||
|
return olderVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
string newerVersion() {
|
||||||
|
string newerVersion = gitversion::MajorVersion()+"."+std::to_string(std::stol(gitversion::MinorVersion())+1);
|
||||||
|
assert(gitversion::VersionCompare::isOlderThan(gitversion::VersionString(), newerVersion));
|
||||||
|
return newerVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MockConsole> console;
|
||||||
TempFile file;
|
TempFile file;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -176,3 +198,42 @@ TEST_F(CryConfigLoaderTest, Version_Create) {
|
|||||||
EXPECT_EQ(gitversion::VersionString(), created.config()->Version());
|
EXPECT_EQ(gitversion::VersionString(), created.config()->Version());
|
||||||
EXPECT_EQ(gitversion::VersionString(), created.config()->CreatedWithVersion());
|
EXPECT_EQ(gitversion::VersionString(), created.config()->CreatedWithVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CryConfigLoaderTest, RefusesToLoadNewerFilesystem) {
|
||||||
|
string version = newerVersion();
|
||||||
|
CreateWithVersion(version);
|
||||||
|
try {
|
||||||
|
Load();
|
||||||
|
EXPECT_TRUE(false); // expect throw
|
||||||
|
} catch (const std::runtime_error &e) {
|
||||||
|
EXPECT_THAT(e.what(), HasSubstr("Please update your CryFS version"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CryConfigLoaderTest, AsksWhenMigratingOlderFilesystem) {
|
||||||
|
EXPECT_CALL(*console, askYesNo(HasSubstr("Do you want to migrate it?"))).Times(1).WillOnce(Return(true));
|
||||||
|
|
||||||
|
string version = olderVersion();
|
||||||
|
CreateWithVersion(version);
|
||||||
|
EXPECT_NE(boost::none, Load());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CryConfigLoaderTest, DoesNotAskForMigrationWhenCorrectVersion) {
|
||||||
|
EXPECT_CALL(*console, askYesNo(HasSubstr("Do you want to migrate it?"))).Times(0);
|
||||||
|
|
||||||
|
CreateWithVersion(gitversion::VersionString());
|
||||||
|
EXPECT_NE(boost::none, Load());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CryConfigLoaderTest, DontMigrateWhenAnsweredNo) {
|
||||||
|
EXPECT_CALL(*console, askYesNo(HasSubstr("Do you want to migrate it?"))).Times(1).WillOnce(Return(false));
|
||||||
|
|
||||||
|
string version = olderVersion();
|
||||||
|
CreateWithVersion(version);
|
||||||
|
try {
|
||||||
|
Load();
|
||||||
|
EXPECT_TRUE(false); // expect throw
|
||||||
|
} catch (const std::runtime_error &e) {
|
||||||
|
EXPECT_THAT(e.what(), HasSubstr("Not migrating file system"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user