* Allow mounting using system mount tool and /etc/fstab (e.g. mount -t fuse.cryfs basedir mountdir)

* Pass fuse options directly to cryfs (i.e. 'cryfs basedir mountdir -o allow_other' instead of 'cryfs basedir mountdir -- -o allow_other')
This commit is contained in:
Sebastian Messmer 2017-08-23 09:56:03 +01:00
parent ffc0b5195c
commit 679b14a4d8
5 changed files with 47 additions and 6 deletions

View File

@ -2,10 +2,12 @@ Version 0.10.0 (unreleased)
--------------- ---------------
New Features: New Features:
* Integrity checks ensure you notice when someone modifies your file system. * Integrity checks ensure you notice when someone modifies your file system.
* File system nodes (files, directories, symlinks) store a parent pointer to the directory that contains them. This information can be used to resolve synchronization conflicts. * File system nodes (files, directories, symlinks) store a parent pointer to the directory that contains them. This information can be used in later versions to resolve some synchronization conflicts.
* Allow mounting using system mount tool and /etc/fstab (e.g. mount -t fuse.cryfs basedir mountdir)
Improvements: Improvements:
* Performance improvements * Performance improvements
* Pass fuse options directly to cryfs (i.e. 'cryfs basedir mountdir -o allow_other' instead of 'cryfs basedir mountdir -- -o allow_other')
Version 0.9.8 (unreleased) Version 0.9.8 (unreleased)
-------------- --------------

View File

@ -16,6 +16,7 @@ using std::endl;
using std::string; using std::string;
using boost::optional; using boost::optional;
using boost::none; using boost::none;
using namespace cpputils::logging;
Parser::Parser(int argc, const char *argv[]) Parser::Parser(int argc, const char *argv[])
:_options(_argsToVector(argc, argv)) { :_options(_argsToVector(argc, argv)) {
@ -30,8 +31,15 @@ vector<string> Parser::_argsToVector(int argc, const char *argv[]) {
} }
ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const { ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
pair<vector<string>, vector<string>> options = splitAtDoubleDash(_options); vector<string> cryfsOptions;
po::variables_map vm = _parseOptionsOrShowHelp(options.first, supportedCiphers); vector<string> fuseOptions;
std::tie(cryfsOptions, fuseOptions) = splitAtDoubleDash(_options);
if (fuseOptions.size() != 0) {
LOG(WARN, "Passing fuse mount options after a double dash '--' is deprecated. Please pass them directly (e.g. 'cryfs basedir mountdir -o allow_other'");
}
po::variables_map vm = _parseOptionsOrShowHelp(cryfsOptions, supportedCiphers);
if (!vm.count("base-dir")) { if (!vm.count("base-dir")) {
std::cerr << "Please specify a base directory.\n"; std::cerr << "Please specify a base directory.\n";
@ -49,7 +57,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
} }
bool foreground = vm.count("foreground"); bool foreground = vm.count("foreground");
if (foreground) { if (foreground) {
options.second.push_back(const_cast<char*>("-f")); fuseOptions.push_back(const_cast<char*>("-f"));
} }
optional<double> unmountAfterIdleMinutes = none; optional<double> unmountAfterIdleMinutes = none;
if (vm.count("unmount-idle")) { if (vm.count("unmount-idle")) {
@ -72,8 +80,15 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
if (vm.count("missing-block-is-integrity-violation")) { if (vm.count("missing-block-is-integrity-violation")) {
missingBlockIsIntegrityViolation = vm["missing-block-is-integrity-violation"].as<bool>(); missingBlockIsIntegrityViolation = vm["missing-block-is-integrity-violation"].as<bool>();
} }
if (vm.count("fuse-option")) {
auto options = vm["fuse-option"].as<vector<string>>();
for (const auto& option: options) {
fuseOptions.push_back("-o");
fuseOptions.push_back(option);
}
}
return ProgramOptions(baseDir, mountDir, configfile, foreground, unmountAfterIdleMinutes, logfile, cipher, blocksizeBytes, missingBlockIsIntegrityViolation, options.second); return ProgramOptions(baseDir, mountDir, configfile, foreground, unmountAfterIdleMinutes, logfile, cipher, blocksizeBytes, missingBlockIsIntegrityViolation, fuseOptions);
} }
void Parser::_checkValidCipher(const string &cipher, const vector<string> &supportedCiphers) { void Parser::_checkValidCipher(const string &cipher, const vector<string> &supportedCiphers) {
@ -132,6 +147,7 @@ void Parser::_addAllowedOptions(po::options_description *desc) {
("help,h", "show help message") ("help,h", "show help message")
("config,c", po::value<string>(), "Configuration file") ("config,c", po::value<string>(), "Configuration file")
("foreground,f", "Run CryFS in foreground.") ("foreground,f", "Run CryFS in foreground.")
("fuse-option,o", po::value<vector<string>>(), "Add a fuse mount option. Example: atime or noatime.")
("cipher", po::value<string>(), cipher_description.c_str()) ("cipher", po::value<string>(), cipher_description.c_str())
("blocksize", po::value<uint32_t>(), blocksize_description.c_str()) ("blocksize", po::value<uint32_t>(), blocksize_description.c_str())
("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.") ("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.")

View File

@ -9,6 +9,7 @@
#include <cpp-utils/pointer/cast.h> #include <cpp-utils/pointer/cast.h>
#include <cpp-utils/system/clock_gettime.h> #include <cpp-utils/system/clock_gettime.h>
#include <cpp-utils/system/stat.h> #include <cpp-utils/system/stat.h>
#include <cpp-utils/logging/logging.h>
namespace bf = boost::filesystem; namespace bf = boost::filesystem;
@ -21,6 +22,7 @@ using boost::none;
using std::shared_ptr; using std::shared_ptr;
using cryfs::parallelaccessfsblobstore::FsBlobRef; using cryfs::parallelaccessfsblobstore::FsBlobRef;
using cryfs::parallelaccessfsblobstore::DirBlobRef; using cryfs::parallelaccessfsblobstore::DirBlobRef;
using namespace cpputils::logging;
//TODO Get rid of this in favor of an exception hierarchy //TODO Get rid of this in favor of an exception hierarchy
using fspp::fuse::CHECK_RETVAL; using fspp::fuse::CHECK_RETVAL;
@ -121,6 +123,7 @@ void CryNode::_updateTargetDirModificationTimestamp(const DirBlobRef &targetDir,
} }
void CryNode::utimens(timespec lastAccessTime, timespec lastModificationTime) { void CryNode::utimens(timespec lastAccessTime, timespec lastModificationTime) {
// LOG(WARN, "---utimens called---");
device()->callFsActionCallbacks(); device()->callFsActionCallbacks();
if (_parent == none) { if (_parent == none) {
//We are the root direcory. //We are the root direcory.

View File

@ -47,7 +47,7 @@ void CryOpenFile::truncate(off_t size) const {
size_t CryOpenFile::read(void *buf, size_t count, off_t offset) const { size_t CryOpenFile::read(void *buf, size_t count, off_t offset) const {
_device->callFsActionCallbacks(); _device->callFsActionCallbacks();
_parent->updateAccessTimestampForChild(_fileBlob->key()); //_parent->updateAccessTimestampForChild(_fileBlob->key());
return _fileBlob->read(buf, offset, count); return _fileBlob->read(buf, offset, count);
} }

View File

@ -181,3 +181,23 @@ TEST_F(ProgramOptionsParserTest, FuseOptionNotGiven) {
EXPECT_EQ("/home/user/mountDir", options.mountDir()); EXPECT_EQ("/home/user/mountDir", options.mountDir());
EXPECT_VECTOR_EQ({}, options.fuseOptions()); EXPECT_VECTOR_EQ({}, options.fuseOptions());
} }
TEST_F(ProgramOptionsParserTest, DirectFuseOptionsGiven_AfterPositionalOptions) {
ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir", "-o", "my_opt"});
EXPECT_VECTOR_EQ({"-o", "my_opt"}, options.fuseOptions());
}
TEST_F(ProgramOptionsParserTest, DirectFuseOptionsGiven_BeforePositionalOptions) {
ProgramOptions options = parse({"./myExecutable", "-o", "my_opt", "/home/user/baseDir", "/home/user/mountDir"});
EXPECT_VECTOR_EQ({"-o", "my_opt"}, options.fuseOptions());
}
TEST_F(ProgramOptionsParserTest, DirectFuseOptionsGiven_BeforeAndAfterPositionalOptions) {
ProgramOptions options = parse({"./myExecutable", "-o", "first", "-o", "second", "/home/user/baseDir", "-o", "third", "-o", "fourth", "/home/user/mountDir", "-o", "fifth", "-o", "sixth"});
EXPECT_VECTOR_EQ({"-o", "first", "-o", "second", "-o", "third", "-o", "fourth", "-o", "fifth", "-o", "sixth"}, options.fuseOptions());
}
TEST_F(ProgramOptionsParserTest, DirectAndIndirectFuseOptionsGiven) {
ProgramOptions options = parse({"./myExecutable", "/home/user/baseDir", "/home/user/mountDir", "-o", "my_opt", "--", "-o", "other_opt"});
EXPECT_VECTOR_EQ({"-o", "other_opt", "-o", "my_opt"}, options.fuseOptions());
}