From 2451a8c46fbf57ccf04fe8b9d6ac72ffa0ea66a8 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sun, 26 Jun 2016 22:07:58 -0700 Subject: [PATCH] Add --missing-block-is-integrity-violation option. The option doesn't have an effect yet though. --- src/cryfs-cli/program_options/Parser.cpp | 7 ++- .../program_options/ProgramOptions.cpp | 7 ++- .../program_options/ProgramOptions.h | 3 ++ test/cryfs-cli/program_options/ParserTest.cpp | 15 ++++++ .../program_options/ProgramOptionsTest.cpp | 49 ++++++++++++------- 5 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/cryfs-cli/program_options/Parser.cpp b/src/cryfs-cli/program_options/Parser.cpp index c5833cf0..d4b3104e 100644 --- a/src/cryfs-cli/program_options/Parser.cpp +++ b/src/cryfs-cli/program_options/Parser.cpp @@ -66,8 +66,12 @@ ProgramOptions Parser::parse(const vector &supportedCiphers) const { if (vm.count("blocksize")) { blocksizeBytes = vm["blocksize"].as(); } + optional missingBlockIsIntegrityViolation = none; + if (vm.count("missing-block-is-integrity-violation")) { + missingBlockIsIntegrityViolation = vm["missing-block-is-integrity-violation"].as(); + } - return ProgramOptions(baseDir, mountDir, configfile, foreground, unmountAfterIdleMinutes, logfile, cipher, blocksizeBytes, options.second); + return ProgramOptions(baseDir, mountDir, configfile, foreground, unmountAfterIdleMinutes, logfile, cipher, blocksizeBytes, missingBlockIsIntegrityViolation, options.second); } void Parser::_checkValidCipher(const string &cipher, const vector &supportedCiphers) { @@ -124,6 +128,7 @@ void Parser::_addAllowedOptions(po::options_description *desc) { ("foreground,f", "Run CryFS in foreground.") ("cipher", po::value(), "Cipher to use for encryption. See possible values by calling cryfs with --show-ciphers.") ("blocksize", po::value(), "The block size used when storing ciphertext blocks (in bytes).") + ("missing-block-is-integrity-violation", po::value(), "Whether to treat a missing block as an integrity violation. This makes sure you notice if an attacker deleted some of your files, but only works in single-client mode. You will not be able to use the file system on other devices.") ("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..2a8aefa9 100644 --- a/src/cryfs-cli/program_options/ProgramOptions.cpp +++ b/src/cryfs-cli/program_options/ProgramOptions.cpp @@ -12,10 +12,11 @@ ProgramOptions::ProgramOptions(const bf::path &baseDir, const bf::path &mountDir bool foreground, const optional &unmountAfterIdleMinutes, const optional &logFile, const optional &cipher, const optional &blocksizeBytes, + const boost::optional &missingBlockIsIntegrityViolation, const vector &fuseOptions) :_baseDir(baseDir), _mountDir(mountDir), _configFile(configFile), _foreground(foreground), _cipher(cipher), _blocksizeBytes(blocksizeBytes), _unmountAfterIdleMinutes(unmountAfterIdleMinutes), - _logFile(logFile), _fuseOptions(fuseOptions) { + _missingBlockIsIntegrityViolation(missingBlockIsIntegrityViolation), _logFile(logFile), _fuseOptions(fuseOptions) { } const bf::path &ProgramOptions::baseDir() const { @@ -50,6 +51,10 @@ const optional &ProgramOptions::blocksizeBytes() const { return _blocksizeBytes; } +const optional &ProgramOptions::missingBlockIsIntegrityViolation() const { + return _missingBlockIsIntegrityViolation; +} + const vector &ProgramOptions::fuseOptions() const { return _fuseOptions; } diff --git a/src/cryfs-cli/program_options/ProgramOptions.h b/src/cryfs-cli/program_options/ProgramOptions.h index bab474f5..b4dee062 100644 --- a/src/cryfs-cli/program_options/ProgramOptions.h +++ b/src/cryfs-cli/program_options/ProgramOptions.h @@ -18,6 +18,7 @@ namespace cryfs { const boost::optional &logFile, const boost::optional &cipher, const boost::optional &blocksizeBytes, + const boost::optional &missingBlockIsIntegrityViolation, const std::vector &fuseOptions); ProgramOptions(ProgramOptions &&rhs) = default; @@ -28,6 +29,7 @@ namespace cryfs { const boost::optional &cipher() const; const boost::optional &blocksizeBytes() const; const boost::optional &unmountAfterIdleMinutes() const; + const boost::optional &missingBlockIsIntegrityViolation() const; const boost::optional &logFile() const; const std::vector &fuseOptions() const; @@ -39,6 +41,7 @@ namespace cryfs { boost::optional _cipher; boost::optional _blocksizeBytes; boost::optional _unmountAfterIdleMinutes; + boost::optional _missingBlockIsIntegrityViolation; boost::optional _logFile; std::vector _fuseOptions; diff --git a/test/cryfs-cli/program_options/ParserTest.cpp b/test/cryfs-cli/program_options/ParserTest.cpp index eefa4fb2..c2a7876d 100644 --- a/test/cryfs-cli/program_options/ParserTest.cpp +++ b/test/cryfs-cli/program_options/ParserTest.cpp @@ -145,6 +145,21 @@ TEST_F(ProgramOptionsParserTest, BlocksizeNotGiven) { EXPECT_EQ(none, options.blocksizeBytes()); } +TEST_F(ProgramOptionsParserTest, MissingBlockIsIntegrityViolationGiven_True) { + ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "--missing-block-is-integrity-violation", "true", "/home/user/mountDir"}); + EXPECT_TRUE(options.missingBlockIsIntegrityViolation().value()); +} + +TEST_F(ProgramOptionsParserTest, MissingBlockIsIntegrityViolationGiven_False) { + ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "--missing-block-is-integrity-violation", "false", "/home/user/mountDir"}); + EXPECT_FALSE(options.missingBlockIsIntegrityViolation().value()); +} + +TEST_F(ProgramOptionsParserTest, MissingBlockIsIntegrityViolationNotGiven) { + ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir"}); + EXPECT_EQ(none, options.missingBlockIsIntegrityViolation()); +} + TEST_F(ProgramOptionsParserTest, FuseOptionGiven) { ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir", "--", "-f"}); EXPECT_EQ("/home/user/baseDir", options.baseDir()); diff --git a/test/cryfs-cli/program_options/ProgramOptionsTest.cpp b/test/cryfs-cli/program_options/ProgramOptionsTest.cpp index 6e910b2c..db8580a7 100644 --- a/test/cryfs-cli/program_options/ProgramOptionsTest.cpp +++ b/test/cryfs-cli/program_options/ProgramOptionsTest.cpp @@ -23,83 +23,98 @@ namespace boost { class ProgramOptionsTest: public ProgramOptionsTestBase {}; TEST_F(ProgramOptionsTest, BaseDir) { - ProgramOptions testobj("/home/user/mydir", "", none, false, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("/home/user/mydir", "", none, false, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ("/home/user/mydir", testobj.baseDir()); } TEST_F(ProgramOptionsTest, MountDir) { - ProgramOptions testobj("", "/home/user/mydir", none, false, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "/home/user/mydir", none, false, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ("/home/user/mydir", testobj.mountDir()); } TEST_F(ProgramOptionsTest, ConfigfileNone) { - ProgramOptions testobj("", "", none, true, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ(none, testobj.configFile()); } TEST_F(ProgramOptionsTest, ConfigfileSome) { - ProgramOptions testobj("", "", bf::path("/home/user/configfile"), true, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", bf::path("/home/user/configfile"), true, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ("/home/user/configfile", testobj.configFile().get()); } TEST_F(ProgramOptionsTest, ForegroundFalse) { - ProgramOptions testobj("", "", none, false, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, false, none, none, none, none, none, {"./myExecutable"}); EXPECT_FALSE(testobj.foreground()); } TEST_F(ProgramOptionsTest, ForegroundTrue) { - ProgramOptions testobj("", "", none, true, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, none, none, none, none, none, {"./myExecutable"}); EXPECT_TRUE(testobj.foreground()); } TEST_F(ProgramOptionsTest, LogfileNone) { - ProgramOptions testobj("", "", none, true, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ(none, testobj.logFile()); } TEST_F(ProgramOptionsTest, LogfileSome) { - ProgramOptions testobj("", "", none, true, none, bf::path("logfile"), none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, none, bf::path("logfile"), none, none, none, {"./myExecutable"}); EXPECT_EQ("logfile", testobj.logFile().get()); } TEST_F(ProgramOptionsTest, UnmountAfterIdleMinutesNone) { -ProgramOptions testobj("", "", none, true, none, none, none, none, {"./myExecutable"}); +ProgramOptions testobj("", "", none, true, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ(none, testobj.unmountAfterIdleMinutes()); } TEST_F(ProgramOptionsTest, UnmountAfterIdleMinutesSome) { - ProgramOptions testobj("", "", none, true, 10, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, 10, none, none, none, none, {"./myExecutable"}); EXPECT_EQ(10, testobj.unmountAfterIdleMinutes().get()); } TEST_F(ProgramOptionsTest, CipherNone) { - ProgramOptions testobj("", "", none, true, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ(none, testobj.cipher()); } TEST_F(ProgramOptionsTest, CipherSome) { - ProgramOptions testobj("", "", none, true, none, none, string("aes-256-gcm"), none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, none, none, string("aes-256-gcm"), none, none, {"./myExecutable"}); EXPECT_EQ("aes-256-gcm", testobj.cipher().get()); } TEST_F(ProgramOptionsTest, BlocksizeBytesNone) { - ProgramOptions testobj("", "", none, true, none, none, none, none, {"./myExecutable"}); + ProgramOptions testobj("", "", none, true, none, none, none, none, none, {"./myExecutable"}); EXPECT_EQ(none, testobj.blocksizeBytes()); } -TEST_F(ProgramOptionsTest, BlocksizeSome) { - ProgramOptions testobj("", "", none, true, none, none, none, 10*1024, {"./myExecutable"}); +TEST_F(ProgramOptionsTest, BlocksizeBytesSome) { + ProgramOptions testobj("", "", none, true, none, none, none, 10*1024, none, {"./myExecutable"}); EXPECT_EQ(10*1024u, testobj.blocksizeBytes().get()); } +TEST_F(ProgramOptionsTest, MissingBlockIsIntegrityViolationTrue) { + ProgramOptions testobj("", "", none, true, none, none, none, none, true, {"./myExecutable"}); + EXPECT_TRUE(testobj.missingBlockIsIntegrityViolation().value()); +} + +TEST_F(ProgramOptionsTest, MissingBlockIsIntegrityViolationFalse) { + ProgramOptions testobj("", "", none, true, none, none, none, none, false, {"./myExecutable"}); + EXPECT_FALSE(testobj.missingBlockIsIntegrityViolation().value()); +} + +TEST_F(ProgramOptionsTest, MissingBlockIsIntegrityViolationNone) { + ProgramOptions testobj("", "", none, true, none, none, none, none, none, {"./myExecutable"}); + EXPECT_EQ(none, testobj.missingBlockIsIntegrityViolation()); +} + TEST_F(ProgramOptionsTest, EmptyFuseOptions) { - ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, none, none, none, {}); + ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, none, none, none, none, {}); //Fuse should have the mount dir as first parameter EXPECT_VECTOR_EQ({}, testobj.fuseOptions()); } TEST_F(ProgramOptionsTest, SomeFuseOptions) { - ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, none, none, none, {"-f", "--longoption"}); + ProgramOptions testobj("/rootDir", "/home/user/mydir", none, false, none, none, none, none, none, {"-f", "--longoption"}); //Fuse should have the mount dir as first parameter EXPECT_VECTOR_EQ({"-f", "--longoption"}, testobj.fuseOptions()); }