diff --git a/ChangeLog.txt b/ChangeLog.txt index 8a4ada4d..15a4e6ce 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -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 -------------- diff --git a/src/cryfs-cli/Cli.cpp b/src/cryfs-cli/Cli.cpp index f675172c..a0e5fea3 100644 --- a/src/cryfs-cli/Cli.cpp +++ b/src/cryfs-cli/Cli.cpp @@ -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 Cli::_loadOrCreateConfigFile(const bf::path &configFilePath, const optional &cipher, const optional &blocksizeBytes) { + optional Cli::_loadOrCreateConfigFile(const bf::path &configFilePath, const optional &cipher, const optional &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); } } diff --git a/src/cryfs-cli/Cli.h b/src/cryfs-cli/Cli.h index 9f53216f..2a3d9f4b 100644 --- a/src/cryfs-cli/Cli.h +++ b/src/cryfs-cli/Cli.h @@ -22,7 +22,7 @@ namespace cryfs { void _checkForUpdates(); void _runFilesystem(const program_options::ProgramOptions &options); CryConfigFile _loadOrCreateConfig(const program_options::ProgramOptions &options); - boost::optional _loadOrCreateConfigFile(const boost::filesystem::path &configFilePath, const boost::optional &cipher, const boost::optional &blocksizeBytes); + boost::optional _loadOrCreateConfigFile(const boost::filesystem::path &configFilePath, const boost::optional &cipher, const boost::optional &blocksizeBytes, bool allowFilesystemUpgrade); boost::filesystem::path _determineConfigFile(const program_options::ProgramOptions &options); static std::string _askPasswordForExistingFilesystem(); static std::string _askPasswordForNewFilesystem(); diff --git a/src/cryfs-cli/program_options/Parser.cpp b/src/cryfs-cli/program_options/Parser.cpp index 0391f20b..31eb85ae 100644 --- a/src/cryfs-cli/program_options/Parser.cpp +++ b/src/cryfs-cli/program_options/Parser.cpp @@ -51,6 +51,7 @@ ProgramOptions Parser::parse(const vector &supportedCiphers) const { if (foreground) { options.second.push_back(const_cast("-f")); } + bool allowFilesystemUpgrade = vm.count("allow-filesystem-upgrade"); optional unmountAfterIdleMinutes = none; if (vm.count("unmount-idle")) { unmountAfterIdleMinutes = vm["unmount-idle"].as(); @@ -69,7 +70,7 @@ ProgramOptions Parser::parse(const vector &supportedCiphers) const { blocksizeBytes = vm["blocksize"].as(); } - 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 &supportedCiphers) { @@ -130,6 +131,7 @@ void Parser::_addAllowedOptions(po::options_description *desc) { ("foreground,f", "Run CryFS in foreground.") ("cipher", po::value(), cipher_description.c_str()) ("blocksize", po::value(), 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(), "Automatically unmount after specified number of idle minutes.") ("logfile", po::value(), "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.") diff --git a/src/cryfs-cli/program_options/ProgramOptions.cpp b/src/cryfs-cli/program_options/ProgramOptions.cpp index 83d7cd84..a5fe2827 100644 --- a/src/cryfs-cli/program_options/ProgramOptions.cpp +++ b/src/cryfs-cli/program_options/ProgramOptions.cpp @@ -9,11 +9,11 @@ using boost::optional; namespace bf = boost::filesystem; ProgramOptions::ProgramOptions(const bf::path &baseDir, const bf::path &mountDir, const optional &configFile, - bool foreground, const optional &unmountAfterIdleMinutes, + bool foreground, bool allowFilesystemUpgrade, const optional &unmountAfterIdleMinutes, const optional &logFile, const optional &cipher, const optional &blocksizeBytes, const vector &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 &ProgramOptions::unmountAfterIdleMinutes() const { return _unmountAfterIdleMinutes; } diff --git a/src/cryfs-cli/program_options/ProgramOptions.h b/src/cryfs-cli/program_options/ProgramOptions.h index bab474f5..887fffa6 100644 --- a/src/cryfs-cli/program_options/ProgramOptions.h +++ b/src/cryfs-cli/program_options/ProgramOptions.h @@ -14,7 +14,7 @@ namespace cryfs { public: ProgramOptions(const boost::filesystem::path &baseDir, const boost::filesystem::path &mountDir, const boost::optional &configFile, - bool foreground, const boost::optional &unmountAfterIdleMinutes, + bool foreground, bool allowFilesystemUpgrade, const boost::optional &unmountAfterIdleMinutes, const boost::optional &logFile, const boost::optional &cipher, const boost::optional &blocksizeBytes, @@ -25,6 +25,8 @@ namespace cryfs { const boost::filesystem::path &mountDir() const; const boost::optional &configFile() const; bool foreground() const; + // TODO add test cases for allowFilesystemUpgrade + bool allowFilesystemUpgrade() const; const boost::optional &cipher() const; const boost::optional &blocksizeBytes() const; const boost::optional &unmountAfterIdleMinutes() const; @@ -36,6 +38,7 @@ namespace cryfs { boost::filesystem::path _mountDir; boost::optional _configFile; bool _foreground; + bool _allowFilesystemUpgrade; boost::optional _cipher; boost::optional _blocksizeBytes; boost::optional _unmountAfterIdleMinutes; diff --git a/src/cryfs/config/CryConfigLoader.cpp b/src/cryfs/config/CryConfigLoader.cpp index ae0e627b..64bf034c 100644 --- a/src/cryfs/config/CryConfigLoader.cpp +++ b/src/cryfs/config/CryConfigLoader.cpp @@ -32,7 +32,7 @@ CryConfigLoader::CryConfigLoader(shared_ptr console, RandomGenerator &k _cipherFromCommandLine(cipherFromCommandLine), _blocksizeBytesFromCommandLine(blocksizeBytesFromCommandLine) { } -optional CryConfigLoader::_loadConfig(const bf::path &filename) { +optional 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 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 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 CryConfigLoader::loadOrCreate(const bf::path &filename) { +optional CryConfigLoader::loadOrCreate(const bf::path &filename, bool allowFilesystemUpgrade) { if (bf::exists(filename)) { - return _loadConfig(filename); + return _loadConfig(filename, allowFilesystemUpgrade); } else { return _createConfig(filename); } diff --git a/src/cryfs/config/CryConfigLoader.h b/src/cryfs/config/CryConfigLoader.h index 48b2a930..6c01b652 100644 --- a/src/cryfs/config/CryConfigLoader.h +++ b/src/cryfs/config/CryConfigLoader.h @@ -16,12 +16,12 @@ public: CryConfigLoader(std::shared_ptr console, cpputils::RandomGenerator &keyGenerator, const cpputils::SCryptSettings &scryptSettings, std::function askPasswordForExistingFilesystem, std::function askPasswordForNewFilesystem, const boost::optional &cipherFromCommandLine, const boost::optional &blocksizeBytesFromCommandLine); CryConfigLoader(CryConfigLoader &&rhs) = default; - boost::optional loadOrCreate(const boost::filesystem::path &filename); + boost::optional loadOrCreate(const boost::filesystem::path &filename, bool allowFilesystemUpgrade); private: - boost::optional _loadConfig(const boost::filesystem::path &filename); + boost::optional _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 _console;