Add --missing-block-is-integrity-violation option. The option doesn't have an effect yet though.

This commit is contained in:
Sebastian Messmer 2016-06-26 22:07:58 -07:00
parent 7bf84b1948
commit 2451a8c46f
5 changed files with 62 additions and 19 deletions

View File

@ -66,8 +66,12 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
if (vm.count("blocksize")) { if (vm.count("blocksize")) {
blocksizeBytes = vm["blocksize"].as<uint32_t>(); blocksizeBytes = vm["blocksize"].as<uint32_t>();
} }
optional<bool> missingBlockIsIntegrityViolation = none;
if (vm.count("missing-block-is-integrity-violation")) {
missingBlockIsIntegrityViolation = vm["missing-block-is-integrity-violation"].as<bool>();
}
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<string> &supportedCiphers) { void Parser::_checkValidCipher(const string &cipher, const vector<string> &supportedCiphers) {
@ -124,6 +128,7 @@ void Parser::_addAllowedOptions(po::options_description *desc) {
("foreground,f", "Run CryFS in foreground.") ("foreground,f", "Run CryFS in foreground.")
("cipher", po::value<string>(), "Cipher to use for encryption. See possible values by calling cryfs with --show-ciphers.") ("cipher", po::value<string>(), "Cipher to use for encryption. See possible values by calling cryfs with --show-ciphers.")
("blocksize", po::value<uint32_t>(), "The block size used when storing ciphertext blocks (in bytes).") ("blocksize", po::value<uint32_t>(), "The block size used when storing ciphertext blocks (in bytes).")
("missing-block-is-integrity-violation", po::value<bool>(), "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.") ("show-ciphers", "Show list of supported ciphers.")
("unmount-idle", po::value<double>(), "Automatically unmount after specified number of idle minutes.") ("unmount-idle", po::value<double>(), "Automatically unmount after specified number of idle minutes.")
("logfile", po::value<string>(), "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.") ("logfile", po::value<string>(), "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.")

View File

@ -12,10 +12,11 @@ ProgramOptions::ProgramOptions(const bf::path &baseDir, const bf::path &mountDir
bool foreground, const optional<double> &unmountAfterIdleMinutes, bool foreground, const optional<double> &unmountAfterIdleMinutes,
const optional<bf::path> &logFile, const optional<string> &cipher, const optional<bf::path> &logFile, const optional<string> &cipher,
const optional<uint32_t> &blocksizeBytes, const optional<uint32_t> &blocksizeBytes,
const boost::optional<bool> &missingBlockIsIntegrityViolation,
const vector<string> &fuseOptions) const vector<string> &fuseOptions)
:_baseDir(baseDir), _mountDir(mountDir), _configFile(configFile), _foreground(foreground), :_baseDir(baseDir), _mountDir(mountDir), _configFile(configFile), _foreground(foreground),
_cipher(cipher), _blocksizeBytes(blocksizeBytes), _unmountAfterIdleMinutes(unmountAfterIdleMinutes), _cipher(cipher), _blocksizeBytes(blocksizeBytes), _unmountAfterIdleMinutes(unmountAfterIdleMinutes),
_logFile(logFile), _fuseOptions(fuseOptions) { _missingBlockIsIntegrityViolation(missingBlockIsIntegrityViolation), _logFile(logFile), _fuseOptions(fuseOptions) {
} }
const bf::path &ProgramOptions::baseDir() const { const bf::path &ProgramOptions::baseDir() const {
@ -50,6 +51,10 @@ const optional<uint32_t> &ProgramOptions::blocksizeBytes() const {
return _blocksizeBytes; return _blocksizeBytes;
} }
const optional<bool> &ProgramOptions::missingBlockIsIntegrityViolation() const {
return _missingBlockIsIntegrityViolation;
}
const vector<string> &ProgramOptions::fuseOptions() const { const vector<string> &ProgramOptions::fuseOptions() const {
return _fuseOptions; return _fuseOptions;
} }

View File

@ -18,6 +18,7 @@ namespace cryfs {
const boost::optional<boost::filesystem::path> &logFile, const boost::optional<boost::filesystem::path> &logFile,
const boost::optional<std::string> &cipher, const boost::optional<std::string> &cipher,
const boost::optional<uint32_t> &blocksizeBytes, const boost::optional<uint32_t> &blocksizeBytes,
const boost::optional<bool> &missingBlockIsIntegrityViolation,
const std::vector<std::string> &fuseOptions); const std::vector<std::string> &fuseOptions);
ProgramOptions(ProgramOptions &&rhs) = default; ProgramOptions(ProgramOptions &&rhs) = default;
@ -28,6 +29,7 @@ namespace cryfs {
const boost::optional<std::string> &cipher() const; const boost::optional<std::string> &cipher() const;
const boost::optional<uint32_t> &blocksizeBytes() const; const boost::optional<uint32_t> &blocksizeBytes() const;
const boost::optional<double> &unmountAfterIdleMinutes() const; const boost::optional<double> &unmountAfterIdleMinutes() const;
const boost::optional<bool> &missingBlockIsIntegrityViolation() const;
const boost::optional<boost::filesystem::path> &logFile() const; const boost::optional<boost::filesystem::path> &logFile() const;
const std::vector<std::string> &fuseOptions() const; const std::vector<std::string> &fuseOptions() const;
@ -39,6 +41,7 @@ namespace cryfs {
boost::optional<std::string> _cipher; boost::optional<std::string> _cipher;
boost::optional<uint32_t> _blocksizeBytes; boost::optional<uint32_t> _blocksizeBytes;
boost::optional<double> _unmountAfterIdleMinutes; boost::optional<double> _unmountAfterIdleMinutes;
boost::optional<bool> _missingBlockIsIntegrityViolation;
boost::optional<boost::filesystem::path> _logFile; boost::optional<boost::filesystem::path> _logFile;
std::vector<std::string> _fuseOptions; std::vector<std::string> _fuseOptions;

View File

@ -145,6 +145,21 @@ TEST_F(ProgramOptionsParserTest, BlocksizeNotGiven) {
EXPECT_EQ(none, options.blocksizeBytes()); 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) { TEST_F(ProgramOptionsParserTest, FuseOptionGiven) {
ProgramOptions options = parse({"./myExecutable", "/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/baseDir", options.baseDir());

View File

@ -23,83 +23,98 @@ namespace boost {
class ProgramOptionsTest: public ProgramOptionsTestBase {}; class ProgramOptionsTest: public ProgramOptionsTestBase {};
TEST_F(ProgramOptionsTest, BaseDir) { 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()); EXPECT_EQ("/home/user/mydir", testobj.baseDir());
} }
TEST_F(ProgramOptionsTest, MountDir) { 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()); EXPECT_EQ("/home/user/mydir", testobj.mountDir());
} }
TEST_F(ProgramOptionsTest, ConfigfileNone) { 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()); EXPECT_EQ(none, testobj.configFile());
} }
TEST_F(ProgramOptionsTest, ConfigfileSome) { 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()); EXPECT_EQ("/home/user/configfile", testobj.configFile().get());
} }
TEST_F(ProgramOptionsTest, ForegroundFalse) { 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()); EXPECT_FALSE(testobj.foreground());
} }
TEST_F(ProgramOptionsTest, ForegroundTrue) { 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()); EXPECT_TRUE(testobj.foreground());
} }
TEST_F(ProgramOptionsTest, LogfileNone) { 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()); EXPECT_EQ(none, testobj.logFile());
} }
TEST_F(ProgramOptionsTest, LogfileSome) { 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()); EXPECT_EQ("logfile", testobj.logFile().get());
} }
TEST_F(ProgramOptionsTest, UnmountAfterIdleMinutesNone) { 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()); EXPECT_EQ(none, testobj.unmountAfterIdleMinutes());
} }
TEST_F(ProgramOptionsTest, UnmountAfterIdleMinutesSome) { 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()); EXPECT_EQ(10, testobj.unmountAfterIdleMinutes().get());
} }
TEST_F(ProgramOptionsTest, CipherNone) { 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()); EXPECT_EQ(none, testobj.cipher());
} }
TEST_F(ProgramOptionsTest, CipherSome) { 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()); EXPECT_EQ("aes-256-gcm", testobj.cipher().get());
} }
TEST_F(ProgramOptionsTest, BlocksizeBytesNone) { 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()); EXPECT_EQ(none, testobj.blocksizeBytes());
} }
TEST_F(ProgramOptionsTest, BlocksizeSome) { TEST_F(ProgramOptionsTest, BlocksizeBytesSome) {
ProgramOptions testobj("", "", none, true, none, none, none, 10*1024, {"./myExecutable"}); ProgramOptions testobj("", "", none, true, none, none, none, 10*1024, none, {"./myExecutable"});
EXPECT_EQ(10*1024u, testobj.blocksizeBytes().get()); 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) { 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 //Fuse should have the mount dir as first parameter
EXPECT_VECTOR_EQ({}, testobj.fuseOptions()); EXPECT_VECTOR_EQ({}, testobj.fuseOptions());
} }
TEST_F(ProgramOptionsTest, SomeFuseOptions) { 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 //Fuse should have the mount dir as first parameter
EXPECT_VECTOR_EQ({"-f", "--longoption"}, testobj.fuseOptions()); EXPECT_VECTOR_EQ({"-f", "--longoption"}, testobj.fuseOptions());
} }