Refactor CryConfigCreator (factor out CryConfigConsole). This is preparation for adding a 'use default config' question.
This commit is contained in:
parent
e2ab25803c
commit
16bdbcc2ca
|
@ -56,6 +56,7 @@ using std::make_shared;
|
|||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::function;
|
||||
using std::make_shared;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
using boost::chrono::duration;
|
||||
|
@ -173,8 +174,8 @@ namespace cryfs {
|
|||
CryConfigFile Cli::_loadOrCreateConfig(const ProgramOptions &options) {
|
||||
try {
|
||||
auto configFile = _determineConfigFile(options);
|
||||
auto console = make_unique_ref<IOStreamConsole>();
|
||||
auto config = CryConfigLoader(std::move(console), _keyGenerator, _scryptSettings,
|
||||
auto console = make_shared<IOStreamConsole>();
|
||||
auto config = CryConfigLoader(console, _keyGenerator, _scryptSettings,
|
||||
std::bind(&Cli::_getPassword, this, std::cref(options), &Cli::_askPasswordForExistingFilesystem),
|
||||
std::bind(&Cli::_getPassword, this, std::cref(options), &Cli::_askPasswordForNewFilesystem),
|
||||
options.cipher()).loadOrCreate(configFile);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#include "CryConfigConsole.h"
|
||||
#include "CryCipher.h"
|
||||
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::Console;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::shared_ptr;
|
||||
|
||||
namespace cryfs {
|
||||
CryConfigConsole::CryConfigConsole(shared_ptr<Console> console)
|
||||
: _console(std::move(console)) {
|
||||
}
|
||||
|
||||
string CryConfigConsole::askCipher() const {
|
||||
vector<string> ciphers = CryCiphers::supportedCipherNames();
|
||||
string cipherName = "";
|
||||
bool askAgain = true;
|
||||
while(askAgain) {
|
||||
int cipherIndex = _console->ask("Which block cipher do you want to use?", ciphers);
|
||||
cipherName = ciphers[cipherIndex];
|
||||
askAgain = !_showWarningForCipherAndReturnIfOk(cipherName);
|
||||
};
|
||||
return cipherName;
|
||||
}
|
||||
|
||||
bool CryConfigConsole::_showWarningForCipherAndReturnIfOk(const string &cipherName) const {
|
||||
auto warning = CryCiphers::find(cipherName).warning();
|
||||
if (warning == none) {
|
||||
return true;
|
||||
}
|
||||
return _console->askYesNo(string() + (*warning) + " Do you want to take this cipher nevertheless?");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYCONFIGCONSOLE_H
|
||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYCONFIGCONSOLE_H
|
||||
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
#include <messmer/cpp-utils/io/Console.h>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace cryfs {
|
||||
//TODO Test
|
||||
class CryConfigConsole final {
|
||||
public:
|
||||
struct Config {
|
||||
std::string cipher;
|
||||
};
|
||||
|
||||
CryConfigConsole(std::shared_ptr<cpputils::Console> console);
|
||||
CryConfigConsole(CryConfigConsole &&rhs) = default;
|
||||
|
||||
std::string askCipher() const;
|
||||
|
||||
private:
|
||||
static constexpr const char *DEFAULT_CIPHER = "aes-256-gcm";
|
||||
|
||||
bool _showWarningForCipherAndReturnIfOk(const std::string &cipherName) const;
|
||||
|
||||
std::shared_ptr<cpputils::Console> _console;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryConfigConsole);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -5,53 +5,34 @@ using cpputils::Console;
|
|||
using cpputils::unique_ref;
|
||||
using cpputils::RandomGenerator;
|
||||
using std::string;
|
||||
using std::shared_ptr;
|
||||
using std::vector;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
CryConfigCreator::CryConfigCreator(unique_ref<Console> console, RandomGenerator &encryptionKeyGenerator)
|
||||
:_console(std::move(console)), _encryptionKeyGenerator(encryptionKeyGenerator) {
|
||||
CryConfigCreator::CryConfigCreator(shared_ptr<Console> console, RandomGenerator &encryptionKeyGenerator)
|
||||
:_console(console), _configConsole(console), _encryptionKeyGenerator(encryptionKeyGenerator) {
|
||||
}
|
||||
|
||||
CryConfig CryConfigCreator::create(const optional<string> &cipher) {
|
||||
CryConfig CryConfigCreator::create(const optional<string> &cipherFromCommandLine) {
|
||||
CryConfig config;
|
||||
config.SetCipher(_generateCipher(cipher));
|
||||
config.SetCipher(_generateCipher(cipherFromCommandLine));
|
||||
config.SetEncryptionKey(_generateEncKey(config.Cipher()));
|
||||
config.SetRootBlob(_generateRootBlobKey());
|
||||
return config;
|
||||
}
|
||||
|
||||
string CryConfigCreator::_generateCipher(const optional<string> &cipher) {
|
||||
if (cipher != none) {
|
||||
ASSERT(std::find(CryCiphers::supportedCipherNames().begin(), CryCiphers::supportedCipherNames().end(), *cipher) != CryCiphers::supportedCipherNames().end(), "Invalid cipher");
|
||||
return *cipher;
|
||||
string CryConfigCreator::_generateCipher(const optional<string> &cipherFromCommandLine) {
|
||||
if (cipherFromCommandLine != none) {
|
||||
ASSERT(std::find(CryCiphers::supportedCipherNames().begin(), CryCiphers::supportedCipherNames().end(), *cipherFromCommandLine) != CryCiphers::supportedCipherNames().end(), "Invalid cipher");
|
||||
return *cipherFromCommandLine;
|
||||
} else {
|
||||
return _askCipher();
|
||||
return _configConsole.askCipher();
|
||||
}
|
||||
}
|
||||
|
||||
string CryConfigCreator::_askCipher() {
|
||||
vector<string> ciphers = CryCiphers::supportedCipherNames();
|
||||
string cipherName = "";
|
||||
bool askAgain = true;
|
||||
while(askAgain) {
|
||||
int cipherIndex = _console->ask("Which block cipher do you want to use?", ciphers);
|
||||
cipherName = ciphers[cipherIndex];
|
||||
askAgain = !_showWarningForCipherAndReturnIfOk(cipherName);
|
||||
};
|
||||
return cipherName;
|
||||
}
|
||||
|
||||
bool CryConfigCreator::_showWarningForCipherAndReturnIfOk(const string &cipherName) {
|
||||
auto warning = CryCiphers::find(cipherName).warning();
|
||||
if (warning == boost::none) {
|
||||
return true;
|
||||
}
|
||||
return _console->askYesNo(string() + (*warning) + " Do you want to take this cipher nevertheless?");
|
||||
}
|
||||
|
||||
string CryConfigCreator::_generateEncKey(const std::string &cipher) {
|
||||
_console->print("\nGenerating secure encryption key...");
|
||||
auto key = CryCiphers::find(cipher).createKey(_encryptionKeyGenerator);
|
||||
|
@ -63,5 +44,4 @@ namespace cryfs {
|
|||
//An empty root blob entry will tell CryDevice to create a new root blob
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,22 +6,22 @@
|
|||
#include <messmer/cpp-utils/random/RandomGenerator.h>
|
||||
#include <messmer/cpp-utils/io/Console.h>
|
||||
#include "CryConfig.h"
|
||||
#include "CryConfigConsole.h"
|
||||
|
||||
namespace cryfs {
|
||||
class CryConfigCreator final {
|
||||
public:
|
||||
CryConfigCreator(cpputils::unique_ref<cpputils::Console> console, cpputils::RandomGenerator &encryptionKeyGenerator);
|
||||
CryConfigCreator(std::shared_ptr<cpputils::Console> console, cpputils::RandomGenerator &encryptionKeyGenerator);
|
||||
CryConfigCreator(CryConfigCreator &&rhs) = default;
|
||||
|
||||
CryConfig create(const boost::optional<std::string> &cipher);
|
||||
CryConfig create(const boost::optional<std::string> &cipherFromCommandLine);
|
||||
private:
|
||||
std::string _generateCipher(const boost::optional<std::string> &cipher);
|
||||
std::string _askCipher();
|
||||
std::string _generateCipher(const boost::optional<std::string> &cipherFromCommandLine);
|
||||
std::string _generateEncKey(const std::string &cipher);
|
||||
std::string _generateRootBlobKey();
|
||||
bool _showWarningForCipherAndReturnIfOk(const std::string &cipherName);
|
||||
|
||||
cpputils::unique_ref<cpputils::Console> _console;
|
||||
std::shared_ptr<cpputils::Console> _console;
|
||||
CryConfigConsole _configConsole;
|
||||
cpputils::RandomGenerator &_encryptionKeyGenerator;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryConfigCreator);
|
||||
|
|
|
@ -14,6 +14,7 @@ using cpputils::RandomGenerator;
|
|||
using cpputils::SCryptSettings;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
using std::shared_ptr;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::function;
|
||||
|
@ -22,10 +23,10 @@ using namespace cpputils::logging;
|
|||
|
||||
namespace cryfs {
|
||||
|
||||
CryConfigLoader::CryConfigLoader(unique_ref<Console> console, RandomGenerator &keyGenerator, const SCryptSettings &scryptSettings, function<string()> askPasswordForExistingFilesystem, function<string()> askPasswordForNewFilesystem, const optional<string> &cipher)
|
||||
CryConfigLoader::CryConfigLoader(shared_ptr<Console> console, RandomGenerator &keyGenerator, const SCryptSettings &scryptSettings, function<string()> askPasswordForExistingFilesystem, function<string()> askPasswordForNewFilesystem, const optional<string> &cipherFromCommandLine)
|
||||
: _creator(std::move(console), keyGenerator), _scryptSettings(scryptSettings),
|
||||
_askPasswordForExistingFilesystem(askPasswordForExistingFilesystem), _askPasswordForNewFilesystem(askPasswordForNewFilesystem),
|
||||
_cipher(cipher) {
|
||||
_cipherFromCommandLine(cipherFromCommandLine) {
|
||||
}
|
||||
|
||||
optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
|
||||
|
@ -37,8 +38,8 @@ optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
|
|||
return none;
|
||||
}
|
||||
std::cout << "done" << std::endl;
|
||||
if (_cipher != none && config->config()->Cipher() != *_cipher) {
|
||||
throw std::runtime_error("Filesystem uses "+config->config()->Cipher()+" cipher and not "+*_cipher+" as specified.");
|
||||
if (_cipherFromCommandLine != none && config->config()->Cipher() != *_cipherFromCommandLine) {
|
||||
throw std::runtime_error("Filesystem uses "+config->config()->Cipher()+" cipher and not "+*_cipherFromCommandLine+" as specified.");
|
||||
}
|
||||
return std::move(*config);
|
||||
}
|
||||
|
@ -52,7 +53,7 @@ optional<CryConfigFile> CryConfigLoader::loadOrCreate(const bf::path &filename)
|
|||
}
|
||||
|
||||
CryConfigFile CryConfigLoader::_createConfig(const bf::path &filename) {
|
||||
auto config = _creator.create(_cipher);
|
||||
auto config = _creator.create(_cipherFromCommandLine);
|
||||
//TODO Ask confirmation if using insecure password (<8 characters)
|
||||
string password = _askPasswordForNewFilesystem();
|
||||
std::cout << "Creating config file..." << std::flush;
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace cryfs {
|
|||
|
||||
class CryConfigLoader final {
|
||||
public:
|
||||
CryConfigLoader(cpputils::unique_ref<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> &cipher);
|
||||
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);
|
||||
CryConfigLoader(CryConfigLoader &&rhs) = default;
|
||||
|
||||
boost::optional<CryConfigFile> loadOrCreate(const boost::filesystem::path &filename);
|
||||
|
@ -26,7 +26,7 @@ private:
|
|||
cpputils::SCryptSettings _scryptSettings;
|
||||
std::function<std::string()> _askPasswordForExistingFilesystem;
|
||||
std::function<std::string()> _askPasswordForNewFilesystem;
|
||||
boost::optional<std::string> _cipher;
|
||||
boost::optional<std::string> _cipherFromCommandLine;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryConfigLoader);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,8 @@ using cpputils::unique_ref;
|
|||
using cpputils::make_unique_ref;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::shared_ptr;
|
||||
using std::make_shared;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::Invoke;
|
||||
|
@ -25,12 +27,10 @@ using ::testing::WithParamInterface;
|
|||
class CryConfigCreatorTest: public ::testing::Test {
|
||||
public:
|
||||
CryConfigCreatorTest()
|
||||
: _console(make_unique_ref<MockConsole>()),
|
||||
console(_console.get()),
|
||||
creator(std::move(_console), cpputils::Random::PseudoRandom()) {
|
||||
: console(make_shared<MockConsole>()),
|
||||
creator(console, cpputils::Random::PseudoRandom()) {
|
||||
}
|
||||
unique_ref<MockConsole> _console;
|
||||
MockConsole *console;
|
||||
shared_ptr<MockConsole> console;
|
||||
CryConfigCreator creator;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ ACTION_P(ChooseCipher, cipherName) {
|
|||
class TestWithMockConsole {
|
||||
public:
|
||||
// Return a console that chooses a valid cryfs setting
|
||||
static cpputils::unique_ref<MockConsole> mockConsole() {
|
||||
auto console = cpputils::make_unique_ref<MockConsole>();
|
||||
static std::shared_ptr<MockConsole> mockConsole() {
|
||||
auto console = std::make_shared<MockConsole>();
|
||||
EXPECT_CALL(*console, ask(::testing::_, ::testing::_)).WillRepeatedly(ChooseCipher("aes-256-gcm"));
|
||||
EXPECT_CALL(*console, askYesNo(::testing::_)).WillRepeatedly(::testing::Return(true));
|
||||
return console;
|
||||
|
|
Loading…
Reference in New Issue