diff --git a/ChangeLog.txt b/ChangeLog.txt index 4cbb23ac..71b1d5ac 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,6 @@ Version 0.9.0 (unreleased) --------------- + (warning) file systems created with earlier CryFS versions are incompatible with this release * Fully support file access times Version 0.8.6 (unreleased) diff --git a/src/config/CryConfig.cpp b/src/config/CryConfig.cpp index d3946d61..7f193b66 100644 --- a/src/config/CryConfig.cpp +++ b/src/config/CryConfig.cpp @@ -15,11 +15,11 @@ using cpputils::Data; namespace cryfs { CryConfig::CryConfig() -: _rootBlob(""), _encKey(""), _cipher("") { +: _rootBlob(""), _encKey(""), _cipher(""), _version("") { } CryConfig::CryConfig(CryConfig &&rhs) -: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)) { +: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)), _version(std::move(rhs._version)) { } CryConfig CryConfig::load(const Data &data) { @@ -32,6 +32,7 @@ CryConfig CryConfig::load(const Data &data) { cfg._rootBlob = pt.get("cryfs.rootblob", ""); cfg._encKey = pt.get("cryfs.key", ""); cfg._cipher = pt.get("cryfs.cipher", ""); + cfg._version = pt.get("cryfs.version", "0.8"); // CryFS 0.8 didn't specify this field, so if the field doesn't exist, it's 0.8. return cfg; } @@ -41,6 +42,7 @@ Data CryConfig::save() const { pt.put("cryfs.rootblob", _rootBlob); pt.put("cryfs.key", _encKey); pt.put("cryfs.cipher", _cipher); + pt.put("cryfs.version", _version); stringstream stream; write_json(stream, pt); @@ -71,4 +73,12 @@ void CryConfig::SetCipher(const std::string &value) { _cipher = value; } +const std::string &CryConfig::Version() const { + return _version; +} + +void CryConfig::SetVersion(const std::string &value) { + _version = value; +} + } diff --git a/src/config/CryConfig.h b/src/config/CryConfig.h index 89cf31c1..bae98545 100644 --- a/src/config/CryConfig.h +++ b/src/config/CryConfig.h @@ -24,6 +24,9 @@ public: const std::string &Cipher() const; void SetCipher(const std::string &value); + const std::string &Version() const; + void SetVersion(const std::string &value); + static CryConfig load(const cpputils::Data &data); cpputils::Data save() const; @@ -31,6 +34,7 @@ private: std::string _rootBlob; std::string _encKey; std::string _cipher; + std::string _version; DISALLOW_COPY_AND_ASSIGN(CryConfig); }; diff --git a/src/config/CryConfigCreator.cpp b/src/config/CryConfigCreator.cpp index a9aa4d7c..1214f5ac 100644 --- a/src/config/CryConfigCreator.cpp +++ b/src/config/CryConfigCreator.cpp @@ -1,5 +1,6 @@ #include "CryConfigCreator.h" #include "CryCipher.h" +#include using cpputils::Console; using cpputils::unique_ref; @@ -21,6 +22,7 @@ namespace cryfs { config.SetCipher(_generateCipher(cipherFromCommandLine)); config.SetEncryptionKey(_generateEncKey(config.Cipher())); config.SetRootBlob(_generateRootBlobKey()); + config.SetVersion(version::VERSION_STRING); return config; } diff --git a/src/config/CryConfigLoader.cpp b/src/config/CryConfigLoader.cpp index 9797d4e9..7a4408c8 100644 --- a/src/config/CryConfigLoader.cpp +++ b/src/config/CryConfigLoader.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include namespace bf = boost::filesystem; using cpputils::unique_ref; @@ -37,12 +39,24 @@ optional CryConfigLoader::_loadConfig(const bf::path &filename) { return none; } std::cout << "done" << std::endl; - if (_cipherFromCommandLine != none && config->config()->Cipher() != *_cipherFromCommandLine) { - throw std::runtime_error("Filesystem uses "+config->config()->Cipher()+" cipher and not "+*_cipherFromCommandLine+" as specified."); - } + _checkVersion(*config->config()); + _checkCipher(*config->config()); return std::move(*config); } +void CryConfigLoader::_checkVersion(const CryConfig &config) { + const string allowedVersionPrefix = string() + version::VERSION_COMPONENTS[0] + "." + version::VERSION_COMPONENTS[1] + "."; + 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."); + } +} + +void CryConfigLoader::_checkCipher(const CryConfig &config) const { + if (_cipherFromCommandLine != none && config.Cipher() != *_cipherFromCommandLine) { + throw std::runtime_error(string() + "Filesystem uses " + config.Cipher() + " cipher and not " + *_cipherFromCommandLine + " as specified."); + } +} + optional CryConfigLoader::loadOrCreate(const bf::path &filename) { if (bf::exists(filename)) { return _loadConfig(filename); diff --git a/src/config/CryConfigLoader.h b/src/config/CryConfigLoader.h index 417d9cb6..069dcbc0 100644 --- a/src/config/CryConfigLoader.h +++ b/src/config/CryConfigLoader.h @@ -21,6 +21,8 @@ public: private: boost::optional _loadConfig(const boost::filesystem::path &filename); CryConfigFile _createConfig(const boost::filesystem::path &filename); + static void _checkVersion(const CryConfig &config); + void _checkCipher(const CryConfig &config) const; CryConfigCreator _creator; cpputils::SCryptSettings _scryptSettings;