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 {
|
||||
|
||||
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),
|
||||
_cipherFromCommandLine(cipherFromCommandLine), _blocksizeBytesFromCommandLine(blocksizeBytesFromCommandLine) {
|
||||
}
|
||||
@ -57,12 +57,13 @@ optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
|
||||
}
|
||||
|
||||
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())) {
|
||||
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:
|
||||
boost::optional<CryConfigFile> _loadConfig(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;
|
||||
|
||||
std::shared_ptr<cpputils::Console> _console;
|
||||
CryConfigCreator _creator;
|
||||
cpputils::SCryptSettings _scryptSettings;
|
||||
std::function<std::string()> _askPasswordForExistingFilesystem;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <cpp-utils/random/Random.h>
|
||||
#include <cpp-utils/crypto/symmetric/ciphers.h>
|
||||
#include <gitversion/gitversion.h>
|
||||
#include <gitversion/VersionCompare.h>
|
||||
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
@ -16,6 +17,7 @@ using std::string;
|
||||
using std::ostream;
|
||||
using ::testing::Return;
|
||||
using ::testing::_;
|
||||
using ::testing::HasSubstr;
|
||||
|
||||
using namespace cryfs;
|
||||
|
||||
@ -29,11 +31,13 @@ namespace boost {
|
||||
|
||||
class CryConfigLoaderTest: public ::testing::Test, public TestWithMockConsole {
|
||||
public:
|
||||
CryConfigLoaderTest(): file(false) {}
|
||||
CryConfigLoaderTest(): file(false) {
|
||||
console = mockConsole();
|
||||
}
|
||||
|
||||
CryConfigLoader loader(const string &password, bool noninteractive, const optional<string> &cipher = none) {
|
||||
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) {
|
||||
@ -71,6 +75,24 @@ public:
|
||||
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;
|
||||
};
|
||||
|
||||
@ -176,3 +198,42 @@ TEST_F(CryConfigLoaderTest, Version_Create) {
|
||||
EXPECT_EQ(gitversion::VersionString(), created.config()->Version());
|
||||
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