diff --git a/src/main.cpp b/src/main.cpp index 0d9d028c..60b2728c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,11 +78,20 @@ string askPassword() { return password; }; -CryConfigFile loadOrCreateConfig(const bf::path &filename) { +bf::path determineConfigFile(const ProgramOptions &options) { + auto configFile = options.configFile(); + if (configFile == none) { + return options.baseDir() + "cryfs.config"; + } + return *configFile; +} + +CryConfigFile loadOrCreateConfig(const ProgramOptions &options) { try { + auto configFile = determineConfigFile(options); auto console = make_unique_ref(); auto &keyGenerator = Random::OSRandom(); - return CryConfigLoader(std::move(console), keyGenerator, &askPassword).loadOrCreate(filename); + return CryConfigLoader(std::move(console), keyGenerator, &askPassword).loadOrCreate(configFile); } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; exit(1); @@ -90,7 +99,7 @@ CryConfigFile loadOrCreateConfig(const bf::path &filename) { } void runFilesystem(const ProgramOptions &options) { - auto config = loadOrCreateConfig(options.configFile()); + auto config = loadOrCreateConfig(options); //TODO This daemonize causes error messages from CryDevice initialization to get lost. // However, initializing CryDevice might (?) already spawn threads and we have to do daemonization before that // because it doesn't fork threads. What to do? diff --git a/src/program_options/Parser.cpp b/src/program_options/Parser.cpp index e90616ff..085efd0d 100644 --- a/src/program_options/Parser.cpp +++ b/src/program_options/Parser.cpp @@ -29,14 +29,17 @@ ProgramOptions Parser::parse() const { string baseDir = vm["base-dir"].as(); string mountDir = vm["mount-dir"].as(); - string configFile = vm["config"].as(); + optional configfile = none; + if (vm.count("config")) { + configfile = vm["config"].as(); + } bool foreground = vm.count("foreground"); optional logfile = none; if (vm.count("logfile")) { logfile = vm["logfile"].as(); } - return ProgramOptions(baseDir, mountDir, configFile, foreground, logfile, options.second); + return ProgramOptions(baseDir, mountDir, configfile, foreground, logfile, options.second); } po::variables_map Parser::_parseOptionsOrShowHelp(const vector options) { @@ -68,7 +71,7 @@ void Parser::_addAllowedOptions(po::options_description *desc) { po::options_description options("Allowed options"); options.add_options() ("help,h", "show help message") - ("config,c", po::value()->required(), "Configuration file") + ("config,c", po::value(), "Configuration file") ("foreground,f", "Run CryFS in foreground.") ("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/program_options/ProgramOptions.cpp b/src/program_options/ProgramOptions.cpp index 7289d5dc..7d5ac080 100644 --- a/src/program_options/ProgramOptions.cpp +++ b/src/program_options/ProgramOptions.cpp @@ -7,7 +7,7 @@ using std::string; using std::vector; using boost::optional; -ProgramOptions::ProgramOptions(const string &baseDir, const string &mountDir, const string &configFile, +ProgramOptions::ProgramOptions(const string &baseDir, const string &mountDir, const optional &configFile, bool foreground, const optional &logFile, const vector &fuseOptions) :_baseDir(baseDir), _mountDir(new char[mountDir.size()+1]), _configFile(configFile), _foreground(foreground), _logFile(logFile), _fuseOptions(fuseOptions) { @@ -38,7 +38,7 @@ string ProgramOptions::mountDir() const { return string(_mountDir); } -const string &ProgramOptions::configFile() const { +const optional &ProgramOptions::configFile() const { return _configFile; } @@ -46,7 +46,7 @@ bool ProgramOptions::foreground() const { return _foreground; } -const optional ProgramOptions::logFile() const { +const optional &ProgramOptions::logFile() const { return _logFile; } diff --git a/src/program_options/ProgramOptions.h b/src/program_options/ProgramOptions.h index 5704c3f8..f242fd52 100644 --- a/src/program_options/ProgramOptions.h +++ b/src/program_options/ProgramOptions.h @@ -11,7 +11,7 @@ namespace cryfs { namespace program_options { class ProgramOptions final { public: - ProgramOptions(const std::string &baseDir, const std::string &mountDir, const std::string &configFile, + ProgramOptions(const std::string &baseDir, const std::string &mountDir, const boost::optional &configFile, bool foreground, const boost::optional &logFile, const std::vector &fuseOptions); ProgramOptions(ProgramOptions &&rhs); @@ -19,15 +19,15 @@ namespace cryfs { const std::string &baseDir() const; std::string mountDir() const; - const std::string &configFile() const; + const boost::optional &configFile() const; bool foreground() const; - const boost::optional logFile() const; + const boost::optional &logFile() const; const std::vector &fuseOptions() const; private: std::string _baseDir; char *_mountDir; - std::string _configFile; + boost::optional _configFile; bool _foreground; boost::optional _logFile; std::vector _fuseOptions; diff --git a/test/program_options/ParserTest.cpp b/test/program_options/ParserTest.cpp index 746660ec..37bed5cb 100644 --- a/test/program_options/ParserTest.cpp +++ b/test/program_options/ParserTest.cpp @@ -3,6 +3,7 @@ using namespace cryfs::program_options; using std::vector; +using boost::none; class ProgramOptionsParserTest: public ProgramOptionsTestBase { public: @@ -28,13 +29,6 @@ TEST_F(ProgramOptionsParserDeathTest, MissingDir) { ); } -TEST_F(ProgramOptionsParserDeathTest, ConfigFileMissing) { - EXPECT_DEATH( - parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir"}), - "Usage:" - ); -} - TEST_F(ProgramOptionsParserDeathTest, HelpLongOption) { EXPECT_DEATH( parse({"./myExecutable", "--help"}), @@ -50,14 +44,26 @@ TEST_F(ProgramOptionsParserDeathTest, HelpShortOption) { } TEST_F(ProgramOptionsParserTest, NoSpecialOptions) { - ProgramOptions options = parse({"./myExecutable", "--config", "/home/user/configFile", "/home/user/baseDir", "/home/user/mountDir"}); + ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir"}); EXPECT_EQ("/home/user/baseDir", options.baseDir()); EXPECT_EQ("/home/user/mountDir", options.mountDir()); + EXPECT_EQ(none, options.logFile()); + EXPECT_EQ(none, options.configFile()); EXPECT_VECTOR_EQ({"./myExecutable", "/home/user/mountDir"}, options.fuseOptions()); } +TEST_F(ProgramOptionsParserTest, LogfileGiven) { + ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "--logfile", "/home/user/logfile", "/home/user/mountDir"}); + EXPECT_EQ("/home/user/mylogfile", options.logFile().value()); +} + +TEST_F(ProgramOptionsParserTest, ConfigfileGiven) { + ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "--configfile", "/home/user/configfile", "/home/user/mountDir"}); + EXPECT_EQ("/home/user/myconfigfile", options.configFile().value()); +} + TEST_F(ProgramOptionsParserTest, FuseOptionGiven) { - ProgramOptions options = parse({"./myExecutable", "--config", "/home/user/configFile", "/home/user/baseDir", "/home/user/mountDir", "--", "-f"}); + ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir", "--", "-f"}); EXPECT_EQ("/home/user/baseDir", options.baseDir()); EXPECT_EQ("/home/user/mountDir", options.mountDir()); EXPECT_VECTOR_EQ({"./myExecutable", "/home/user/mountDir", "-f"}, options.fuseOptions()); diff --git a/test/program_options/ProgramOptionsTest.cpp b/test/program_options/ProgramOptionsTest.cpp index eb997e4d..46a48803 100644 --- a/test/program_options/ProgramOptionsTest.cpp +++ b/test/program_options/ProgramOptionsTest.cpp @@ -10,48 +10,53 @@ using std::string; class ProgramOptionsTest: public ProgramOptionsTestBase {}; TEST_F(ProgramOptionsTest, BaseDir) { - ProgramOptions testobj("/home/user/mydir", "", "", false, none, options({"./myExecutable"})); + ProgramOptions testobj("/home/user/mydir", "", none, false, none, options({"./myExecutable"})); EXPECT_EQ("/home/user/mydir", testobj.baseDir()); } TEST_F(ProgramOptionsTest, MountDir) { - ProgramOptions testobj("", "/home/user/mydir", "", false, none, options({"./myExecutable"})); + ProgramOptions testobj("", "/home/user/mydir", none, false, none, options({"./myExecutable"})); EXPECT_EQ("/home/user/mydir", testobj.mountDir()); } -TEST_F(ProgramOptionsTest, ConfigFile) { - ProgramOptions testobj("", "", "/home/user/configfile", false, none, options({"./myExecutable"})); - EXPECT_EQ("/home/user/configfile", testobj.configFile()); +TEST_F(ProgramOptionsTest, ConfigfileNone) { + ProgramOptions testobj("", "", none, true, none, options({"./myExecutable"})); + EXPECT_EQ(none, testobj.configFile()); +} + +TEST_F(ProgramOptionsTest, ConfigfileSome) { + ProgramOptions testobj("", "", string("/home/user/configfile"), true, none, options({"./myExecutable"})); + EXPECT_EQ("/home/user/configfile", testobj.configFile().get()); } TEST_F(ProgramOptionsTest, ForegroundFalse) { - ProgramOptions testobj("", "", "/home/user/configfile", false, none, options({"./myExecutable"})); + ProgramOptions testobj("", "", none, false, none, options({"./myExecutable"})); EXPECT_FALSE(testobj.foreground()); } TEST_F(ProgramOptionsTest, ForegroundTrue) { - ProgramOptions testobj("", "", "/home/user/configfile", true, none, options({"./myExecutable"})); + ProgramOptions testobj("", "", none, true, none, options({"./myExecutable"})); EXPECT_TRUE(testobj.foreground()); } TEST_F(ProgramOptionsTest, LogfileNone) { - ProgramOptions testobj("", "", "/home/user/configfile", true, none, options({"./myExecutable"})); + ProgramOptions testobj("", "", none, true, none, options({"./myExecutable"})); EXPECT_EQ(none, testobj.logFile()); } TEST_F(ProgramOptionsTest, LogfileSome) { - ProgramOptions testobj("", "", "/home/user/configfile", true, string("logfile"), options({"./myExecutable"})); + ProgramOptions testobj("", "", none, true, string("logfile"), options({"./myExecutable"})); EXPECT_EQ("logfile", testobj.logFile().get()); } TEST_F(ProgramOptionsTest, EmptyFuseOptions) { - ProgramOptions testobj("/rootDir", "/home/user/mydir", "/home/user/configfile", false, none, options({"./myExecutable"})); + ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, options({"./myExecutable"})); //Fuse should have the mount dir as first parameter EXPECT_VECTOR_EQ({"./myExecutable", "/home/user/mydir"}, testobj.fuseOptions()); } TEST_F(ProgramOptionsTest, SomeFuseOptions) { - ProgramOptions testobj("/rootDir", "/home/user/mydir", "/home/user/configfile", false, none, options({"./myExecutable", "-f", "--longoption"})); + ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, options({"./myExecutable", "-f", "--longoption"})); //Fuse should have the mount dir as first parameter EXPECT_VECTOR_EQ({"./myExecutable", "/home/user/mydir", "-f", "--longoption"}, testobj.fuseOptions()); }