Skip to content

Commit 353f287

Browse files
Added an option to create a mountpoint with a missing directory (cryfs#354)
* Added an option to create a mountpoint with a missing directory It skips the normal confirmation message, which makes cryfs easier to use in scripts, or can be aliased for quicker use. * separated basedir and mountpoint autocreate flags, and added tests * Werror and clang-tidy fixes added to the ChangeLog * fixed the bugs that clang-tidy caused never used clang before, so I don't really know what it did and why it caused compile errors
1 parent 4e5ddf3 commit 353f287

17 files changed

Lines changed: 178 additions & 60 deletions

File tree

ChangeLog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ New features:
1717
Noatime reduces the amount of write necessary and with that reduces the probability for synchronization conflicts
1818
or corrupted file systems if a power outage happens while writing.
1919
* Add an --immediate flag to cryfs-unmount that tries to unmount immediately and doesn't wait for processes to release their locks on the file system.
20+
* Add a --create-missing-basedir and --create-missing-mountpoint flag to create the base directory and mount directory respectively, if they don't exist, skipping the confirmation prompt.
2021

2122

2223
Version 0.10.3 (unreleased)

doc/man/cryfs.1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,18 @@ By default, CryFS remembers file systems it has seen in this base directory and
180180
.
181181
.
182182
.TP
183+
\fB\-\-create-missing-basedir\fI
184+
.
185+
Creates the base directory even if there is no directory currently there, skipping the normal confirmation message to create it later.
186+
.
187+
.
188+
.TP
189+
\fB\-\-create-missing-mountpoint\fI
190+
.
191+
Creates the mountpoint even if there is no directory currently there, skipping the normal confirmation message to create it later.
192+
.
193+
.
194+
.TP
183195
\fB\-\-missing-block-is-integrity-violation\fR=true
184196
.
185197
When CryFS encounters a missing ciphertext block, it cannot cannot (yet) know if it was deleted by an unauthorized adversary or by a second authorized client. This is one of the restrictions of the integrity checks currently in place. You can enable this flag to treat missing ciphertext blocks as integrity violations, but then your file system will not be usable by multiple clients anymore. By default, this flag is disabled.

src/blockstore/implementations/compressing/compressors/RunLengthEncoding.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ namespace blockstore {
114114
}
115115

116116
void RunLengthEncoding::_decodeArbitraryWords(istringstream *stream, ostringstream *decompressed) {
117-
uint16_t size;
117+
uint16_t size = 0;
118118
stream->read(reinterpret_cast<char*>(&size), sizeof(uint16_t));
119119
ASSERT(stream->good(), "Premature end of stream");
120120
Data run(size);
@@ -124,10 +124,10 @@ namespace blockstore {
124124
}
125125

126126
void RunLengthEncoding::_decodeIdenticalWords(istringstream *stream, ostringstream *decompressed) {
127-
uint16_t size;
127+
uint16_t size = 0;
128128
stream->read(reinterpret_cast<char*>(&size), sizeof(uint16_t));
129129
ASSERT(stream->good(), "Premature end of stream");
130-
uint8_t value;
130+
uint8_t value = 0;
131131
stream->read(reinterpret_cast<char*>(&value), 1);
132132
ASSERT(stream->good(), "Premature end of stream");
133133
Data run(size);

src/cryfs-cli/Cli.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,10 @@ namespace cryfs_cli {
347347
}
348348

349349
void Cli::_sanityChecks(const ProgramOptions &options) {
350-
_checkDirAccessible(bf::absolute(options.baseDir()), "base directory", ErrorCode::InaccessibleBaseDir);
350+
_checkDirAccessible(bf::absolute(options.baseDir()), "base directory", options.createMissingBasedir(), ErrorCode::InaccessibleBaseDir);
351351

352352
if (!options.mountDirIsDriveLetter()) {
353-
_checkDirAccessible(options.mountDir(), "mount directory", ErrorCode::InaccessibleMountDir);
353+
_checkDirAccessible(options.mountDir(), "mount directory", options.createMissingMountpoint(), ErrorCode::InaccessibleMountDir);
354354
_checkMountdirDoesntContainBasedir(options);
355355
} else {
356356
if (bf::exists(options.mountDir())) {
@@ -359,9 +359,14 @@ namespace cryfs_cli {
359359
}
360360
}
361361

362-
void Cli::_checkDirAccessible(const bf::path &dir, const std::string &name, ErrorCode errorCode) {
362+
void Cli::_checkDirAccessible(const bf::path &dir, const std::string &name, bool createMissingDir, ErrorCode errorCode) {
363363
if (!bf::exists(dir)) {
364-
bool create = _console->askYesNo("Could not find " + name + ". Do you want to create it?", false);
364+
bool create = createMissingDir;
365+
if (create) {
366+
LOG(INFO, "Automatically creating {}", name);
367+
} else {
368+
create = _console->askYesNo("Could not find " + name + ". Do you want to create it?", false);
369+
}
365370
if (create) {
366371
if (!bf::create_directory(dir)) {
367372
throw CryfsException("Error creating "+name, errorCode);

src/cryfs-cli/Cli.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace cryfs_cli {
3737
void _sanityChecks(const program_options::ProgramOptions &options);
3838
void _checkMountdirDoesntContainBasedir(const program_options::ProgramOptions &options);
3939
bool _pathContains(const boost::filesystem::path &parent, const boost::filesystem::path &child);
40-
void _checkDirAccessible(const boost::filesystem::path &dir, const std::string &name, cryfs::ErrorCode errorCode);
40+
void _checkDirAccessible(const boost::filesystem::path &dir, const std::string &name, bool createMissingDir, cryfs::ErrorCode errorCode);
4141
std::shared_ptr<cpputils::TempFile> _checkDirWriteable(const boost::filesystem::path &dir, const std::string &name, cryfs::ErrorCode errorCode);
4242
void _checkDirReadable(const boost::filesystem::path &dir, std::shared_ptr<cpputils::TempFile> tempfile, const std::string &name, cryfs::ErrorCode errorCode);
4343
boost::optional<cpputils::unique_ref<CallAfterTimeout>> _createIdleCallback(boost::optional<double> minutes, std::function<void()> callback);

src/cryfs-cli/program_options/Parser.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
5858
bool foreground = vm.count("foreground");
5959
bool allowFilesystemUpgrade = vm.count("allow-filesystem-upgrade");
6060
bool allowReplacedFilesystem = vm.count("allow-replaced-filesystem");
61+
bool createMissingBasedir = vm.count("create-missing-basedir");
62+
bool createMissingMountpoint = vm.count("create-missing-mountpoint");
6163
optional<double> unmountAfterIdleMinutes = 0.0; // first setting to 0 and then to none is somehow needed to silence a GCC warning from -Wmaybe-uninitialized
6264
unmountAfterIdleMinutes = none;
6365
if (vm.count("unmount-idle")) {
@@ -90,7 +92,7 @@ ProgramOptions Parser::parse(const vector<string> &supportedCiphers) const {
9092
}
9193
}
9294

93-
return ProgramOptions(std::move(baseDir), std::move(mountDir), std::move(configfile), foreground, allowFilesystemUpgrade, allowReplacedFilesystem, std::move(unmountAfterIdleMinutes), std::move(logfile), std::move(cipher), blocksizeBytes, allowIntegrityViolations, std::move(missingBlockIsIntegrityViolation), std::move(fuseOptions));
95+
return ProgramOptions(std::move(baseDir), std::move(mountDir), std::move(configfile), foreground, allowFilesystemUpgrade, allowReplacedFilesystem, createMissingBasedir, createMissingMountpoint, std::move(unmountAfterIdleMinutes), std::move(logfile), std::move(cipher), blocksizeBytes, allowIntegrityViolations, std::move(missingBlockIsIntegrityViolation), std::move(fuseOptions));
9496
}
9597

9698
void Parser::_checkValidCipher(const string &cipher, const vector<string> &supportedCiphers) {
@@ -165,6 +167,8 @@ void Parser::_addAllowedOptions(po::options_description *desc) {
165167
("allow-integrity-violations", "Disable integrity checks. Integrity checks ensure that your file system was not manipulated or rolled back to an earlier version. Disabling them is needed if you want to load an old snapshot of your file system.")
166168
("allow-filesystem-upgrade", "Allow upgrading the file system if it was created with an old CryFS version. After the upgrade, older CryFS versions might not be able to use the file system anymore.")
167169
("allow-replaced-filesystem", "By default, CryFS remembers file systems it has seen in this base directory and checks that it didn't get replaced by an attacker with an entirely different file system since the last time it was loaded. However, if you do want to replace the file system with an entirely new one, you can pass in this option to disable the check.")
170+
("create-missing-basedir", "Creates the base directory even if there is no directory currently there, skipping the normal confirmation message to create it later.")
171+
("create-missing-mountpoint", "Creates the mountpoint even if there is no directory currently there, skipping the normal confirmation message to create it later.")
168172
("show-ciphers", "Show list of supported ciphers.")
169173
("unmount-idle", po::value<double>(), "Automatically unmount after specified number of idle minutes.")
170174
("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.")

src/cryfs-cli/program_options/ProgramOptions.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,24 @@ using boost::optional;
1010
namespace bf = boost::filesystem;
1111

1212
ProgramOptions::ProgramOptions(bf::path baseDir, bf::path mountDir, optional<bf::path> configFile,
13-
bool foreground, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, optional<double> unmountAfterIdleMinutes,
13+
bool foreground, bool allowFilesystemUpgrade, bool allowReplacedFilesystem,
14+
bool createMissingBasedir, bool createMissingMountpoint,
15+
optional<double> unmountAfterIdleMinutes,
1416
optional<bf::path> logFile, optional<string> cipher,
1517
optional<uint32_t> blocksizeBytes,
1618
bool allowIntegrityViolations,
1719
boost::optional<bool> missingBlockIsIntegrityViolation,
1820
vector<string> fuseOptions)
19-
: _configFile(std::move(configFile)), _baseDir(bf::absolute(std::move(baseDir))), _mountDir(std::move(mountDir)),
20-
_mountDirIsDriveLetter(cpputils::path_is_just_drive_letter(_mountDir)),
21+
: _baseDir(bf::absolute(std::move(baseDir))), _mountDir(std::move(mountDir)), _configFile(std::move(configFile)),
2122
_foreground(foreground),
22-
_allowFilesystemUpgrade(allowFilesystemUpgrade), _allowReplacedFilesystem(allowReplacedFilesystem), _allowIntegrityViolations(allowIntegrityViolations),
23-
_cipher(std::move(cipher)), _blocksizeBytes(std::move(blocksizeBytes)), _unmountAfterIdleMinutes(std::move(unmountAfterIdleMinutes)),
24-
_missingBlockIsIntegrityViolation(std::move(missingBlockIsIntegrityViolation)), _logFile(std::move(logFile)),
25-
_fuseOptions(std::move(fuseOptions)) {
23+
_allowFilesystemUpgrade(allowFilesystemUpgrade), _allowReplacedFilesystem(allowReplacedFilesystem),
24+
_createMissingBasedir(createMissingBasedir), _createMissingMountpoint(createMissingMountpoint),
25+
_unmountAfterIdleMinutes(std::move(unmountAfterIdleMinutes)), _logFile(std::move(logFile)),
26+
_cipher(std::move(cipher)), _blocksizeBytes(std::move(blocksizeBytes)),
27+
_allowIntegrityViolations(allowIntegrityViolations),
28+
_missingBlockIsIntegrityViolation(std::move(missingBlockIsIntegrityViolation)),
29+
_fuseOptions(std::move(fuseOptions)),
30+
_mountDirIsDriveLetter(cpputils::path_is_just_drive_letter(_mountDir)) {
2631
if (!_mountDirIsDriveLetter) {
2732
_mountDir = bf::absolute(std::move(_mountDir));
2833
}
@@ -52,6 +57,14 @@ bool ProgramOptions::allowFilesystemUpgrade() const {
5257
return _allowFilesystemUpgrade;
5358
}
5459

60+
bool ProgramOptions::createMissingBasedir() const {
61+
return _createMissingBasedir;
62+
}
63+
64+
bool ProgramOptions::createMissingMountpoint() const {
65+
return _createMissingMountpoint;
66+
}
67+
5568
const optional<double> &ProgramOptions::unmountAfterIdleMinutes() const {
5669
return _unmountAfterIdleMinutes;
5770
}

src/cryfs-cli/program_options/ProgramOptions.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ namespace cryfs_cli {
1414
public:
1515
ProgramOptions(boost::filesystem::path baseDir, boost::filesystem::path mountDir,
1616
boost::optional<boost::filesystem::path> configFile,
17-
bool foreground, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, boost::optional<double> unmountAfterIdleMinutes,
17+
bool foreground, bool allowFilesystemUpgrade, bool allowReplacedFilesystem,
18+
bool createMissingBasedir, bool createMissingMountpoint,
19+
boost::optional<double> unmountAfterIdleMinutes,
1820
boost::optional<boost::filesystem::path> logFile,
1921
boost::optional<std::string> cipher,
2022
boost::optional<uint32_t> blocksizeBytes,
@@ -25,34 +27,38 @@ namespace cryfs_cli {
2527

2628
const boost::filesystem::path &baseDir() const;
2729
const boost::filesystem::path &mountDir() const;
28-
bool mountDirIsDriveLetter() const;
2930
const boost::optional<boost::filesystem::path> &configFile() const;
3031
bool foreground() const;
3132
bool allowFilesystemUpgrade() const;
3233
bool allowReplacedFilesystem() const;
34+
bool createMissingBasedir() const;
35+
bool createMissingMountpoint() const;
36+
const boost::optional<double> &unmountAfterIdleMinutes() const;
37+
const boost::optional<boost::filesystem::path> &logFile() const;
3338
const boost::optional<std::string> &cipher() const;
3439
const boost::optional<uint32_t> &blocksizeBytes() const;
35-
const boost::optional<double> &unmountAfterIdleMinutes() const;
3640
bool allowIntegrityViolations() const;
3741
const boost::optional<bool> &missingBlockIsIntegrityViolation() const;
38-
const boost::optional<boost::filesystem::path> &logFile() const;
3942
const std::vector<std::string> &fuseOptions() const;
43+
bool mountDirIsDriveLetter() const;
4044

4145
private:
42-
boost::optional<boost::filesystem::path> _configFile;
4346
boost::filesystem::path _baseDir; // this is always absolute
4447
boost::filesystem::path _mountDir; // this is absolute iff !_mountDirIsDriveLetter
45-
bool _mountDirIsDriveLetter;
48+
boost::optional<boost::filesystem::path> _configFile;
4649
bool _foreground;
4750
bool _allowFilesystemUpgrade;
4851
bool _allowReplacedFilesystem;
49-
bool _allowIntegrityViolations;
52+
bool _createMissingBasedir;
53+
bool _createMissingMountpoint;
54+
boost::optional<double> _unmountAfterIdleMinutes;
55+
boost::optional<boost::filesystem::path> _logFile;
5056
boost::optional<std::string> _cipher;
5157
boost::optional<uint32_t> _blocksizeBytes;
52-
boost::optional<double> _unmountAfterIdleMinutes;
58+
bool _allowIntegrityViolations;
5359
boost::optional<bool> _missingBlockIsIntegrityViolation;
54-
boost::optional<boost::filesystem::path> _logFile;
5560
std::vector<std::string> _fuseOptions;
61+
bool _mountDirIsDriveLetter;
5662

5763
DISALLOW_COPY_AND_ASSIGN(ProgramOptions);
5864
};

src/cryfs/impl/filesystem/fsblobstore/FsBlobView.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ namespace cryfs {
9595

9696
static uint16_t getFormatVersionHeader(const blobstore::Blob &blob) {
9797
static_assert(sizeof(uint16_t) == sizeof(FORMAT_VERSION_HEADER), "Wrong type used to read format version header");
98-
uint16_t actualFormatVersion;
98+
uint16_t actualFormatVersion = 0;
9999
blob.read(&actualFormatVersion, 0, sizeof(FORMAT_VERSION_HEADER));
100100
return actualFormatVersion;
101101
}
@@ -116,7 +116,7 @@ namespace cryfs {
116116
}
117117

118118
static BlobType _blobType(const blobstore::Blob &blob) {
119-
uint8_t result;
119+
uint8_t result = 0;
120120
blob.read(&result, sizeof(FORMAT_VERSION_HEADER), sizeof(uint8_t));
121121
return static_cast<BlobType>(result);
122122
}

src/cryfs/impl/localstate/LocalStateMetadata.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ void LocalStateMetadata::_save(const bf::path &metadataFilePath) const {
5858

5959
namespace {
6060
uint32_t _generateClientId() {
61-
uint32_t result;
61+
uint32_t result = 0;
6262
do {
6363
result = cpputils::deserialize<uint32_t>(Random::PseudoRandom().getFixedSize<sizeof(uint32_t)>().data());
6464
} while(result == KnownBlockVersions::CLIENT_ID_FOR_DELETED_BLOCK); // Safety check - CLIENT_ID_FOR_DELETED_BLOCK shouldn't be used by any valid client.
@@ -73,7 +73,7 @@ optional<uint32_t> _tryLoadClientIdFromLegacyFile(const bf::path &metadataFilePa
7373
return none;
7474
}
7575

76-
uint32_t value;
76+
uint32_t value = 0;
7777
file >> value;
7878
file.close();
7979
bf::remove(myClientIdFile);

0 commit comments

Comments
 (0)