Add --allow-filesystem-upgrade option which will upgrade old file systems without asking the user. This will be especially helpful for GUI tools.

This commit is contained in:
Sebastian Messmer 2018-02-01 02:04:59 -08:00
parent 2e41233041
commit 8da4f4d362
8 changed files with 29 additions and 19 deletions

View File

@ -1,6 +1,7 @@
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.
Version 0.9.8
--------------

View File

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

View File

@ -22,7 +22,7 @@ namespace cryfs {
void _checkForUpdates();
void _runFilesystem(const program_options::ProgramOptions &options);
CryConfigFile _loadOrCreateConfig(const program_options::ProgramOptions &options);
boost::optional<CryConfigFile> _loadOrCreateConfigFile(const boost::filesystem::path &configFilePath, const boost::optional<std::string> &cipher, const boost::optional<uint32_t> &blocksizeBytes);
boost::optional<CryConfigFile> _loadOrCreateConfigFile(const boost::filesystem::path &configFilePath, const boost::optional<std::string> &cipher, const boost::optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade);
boost::filesystem::path _determineConfigFile(const program_options::ProgramOptions &options);
static std::string _askPasswordForExistingFilesystem();
static std::string _askPasswordForNewFilesystem();

View File

@ -51,6 +51,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
if (foreground) {
options.second.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>();
@ -69,7 +70,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
blocksizeBytes = vm["blocksize"].as<uint32_t>();
}
return ProgramOptions(baseDir, mountDir, configfile, foreground, unmountAfterIdleMinutes, logfile, cipher, blocksizeBytes, options.second);
return ProgramOptions(baseDir, mountDir, configfile, foreground, allowFilesystemUpgrade, unmountAfterIdleMinutes, logfile, cipher, blocksizeBytes, options.second);
}
void Parser::_checkValidCipher(const string &cipher, const vector<string> &supportedCiphers) {
@ -130,6 +131,7 @@ void Parser::_addAllowedOptions(po::options_description *desc) {
("foreground,f", "Run CryFS in foreground.")
("cipher", po::value<string>(), cipher_description.c_str())
("blocksize", po::value<uint32_t>(), blocksize_description.c_str())
("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.")

View File

@ -9,11 +9,11 @@ using boost::optional;
namespace bf = boost::filesystem;
ProgramOptions::ProgramOptions(const bf::path &baseDir, const bf::path &mountDir, const optional<bf::path> &configFile,
bool foreground, const optional<double> &unmountAfterIdleMinutes,
bool foreground, bool allowFilesystemUpgrade, const optional<double> &unmountAfterIdleMinutes,
const optional<bf::path> &logFile, const optional<string> &cipher,
const optional<uint32_t> &blocksizeBytes,
const vector<string> &fuseOptions)
:_baseDir(baseDir), _mountDir(mountDir), _configFile(configFile), _foreground(foreground),
:_baseDir(baseDir), _mountDir(mountDir), _configFile(configFile), _foreground(foreground), _allowFilesystemUpgrade(allowFilesystemUpgrade),
_cipher(cipher), _blocksizeBytes(blocksizeBytes), _unmountAfterIdleMinutes(unmountAfterIdleMinutes),
_logFile(logFile), _fuseOptions(fuseOptions) {
}
@ -34,6 +34,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(const boost::filesystem::path &baseDir, const boost::filesystem::path &mountDir,
const boost::optional<boost::filesystem::path> &configFile,
bool foreground, const boost::optional<double> &unmountAfterIdleMinutes,
bool foreground, bool allowFilesystemUpgrade, const boost::optional<double> &unmountAfterIdleMinutes,
const boost::optional<boost::filesystem::path> &logFile,
const boost::optional<std::string> &cipher,
const boost::optional<uint32_t> &blocksizeBytes,
@ -25,6 +25,8 @@ namespace cryfs {
const boost::filesystem::path &mountDir() const;
const boost::optional<boost::filesystem::path> &configFile() const;
bool foreground() const;
// TODO add test cases for allowFilesystemUpgrade
bool allowFilesystemUpgrade() const;
const boost::optional<std::string> &cipher() const;
const boost::optional<uint32_t> &blocksizeBytes() const;
const boost::optional<double> &unmountAfterIdleMinutes() const;
@ -36,6 +38,7 @@ namespace cryfs {
boost::filesystem::path _mountDir;
boost::optional<boost::filesystem::path> _configFile;
bool _foreground;
bool _allowFilesystemUpgrade;
boost::optional<std::string> _cipher;
boost::optional<uint32_t> _blocksizeBytes;
boost::optional<double> _unmountAfterIdleMinutes;

View File

@ -32,7 +32,7 @@ CryConfigLoader::CryConfigLoader(shared_ptr<Console> console, RandomGenerator &k
_cipherFromCommandLine(cipherFromCommandLine), _blocksizeBytesFromCommandLine(blocksizeBytesFromCommandLine) {
}
optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename, bool allowFilesystemUpgrade) {
string password = _askPasswordForExistingFilesystem();
std::cout << "Loading config file (this can take some time)..." << std::flush;
auto config = CryConfigFile::load(filename, password);
@ -40,7 +40,7 @@ optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
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")) {
@ -55,13 +55,13 @@ optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
return std::move(*config);
}
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.");
}
@ -74,9 +74,9 @@ void CryConfigLoader::_checkCipher(const CryConfig &config) const {
}
}
optional<CryConfigFile> CryConfigLoader::loadOrCreate(const bf::path &filename) {
optional<CryConfigFile> CryConfigLoader::loadOrCreate(const bf::path &filename, bool allowFilesystemUpgrade) {
if (bf::exists(filename)) {
return _loadConfig(filename);
return _loadConfig(filename, allowFilesystemUpgrade);
} else {
return _createConfig(filename);
}

View File

@ -16,12 +16,12 @@ 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);
CryConfigLoader(CryConfigLoader &&rhs) = default;
boost::optional<CryConfigFile> loadOrCreate(const boost::filesystem::path &filename);
boost::optional<CryConfigFile> loadOrCreate(const boost::filesystem::path &filename, bool allowFilesystemUpgrade);
private:
boost::optional<CryConfigFile> _loadConfig(const boost::filesystem::path &filename);
boost::optional<CryConfigFile> _loadConfig(const boost::filesystem::path &filename, bool allowFilesystemUpgrade);
CryConfigFile _createConfig(const boost::filesystem::path &filename);
void _checkVersion(const CryConfig &config);
void _checkVersion(const CryConfig &config, bool allowFilesystemUpgrade);
void _checkCipher(const CryConfig &config) const;
std::shared_ptr<cpputils::Console> _console;