mirror of
https://github.com/vgough/encfs.git
synced 2025-01-09 15:38:15 +01:00
Work around #14 (Editing Configuration File Disables MACs) with "--require-macs"
This patch implements the workaround proposed by https://defuse.ca/audits/encfs.htm to create a --require-macs command line argument. If this argument is passed, encfs will refuse to mount with MACs disabled. When creating a filesystem, encfs will force MACs to be enabled. Addressed CR comments, and added docs.
This commit is contained in:
parent
82ceb88998
commit
9d06412f1c
@ -855,14 +855,21 @@ static bool boolDefaultYes(const char *prompt) {
|
|||||||
/**
|
/**
|
||||||
* Ask the user whether to enable block MAC and random header bytes
|
* Ask the user whether to enable block MAC and random header bytes
|
||||||
*/
|
*/
|
||||||
static void selectBlockMAC(int *macBytes, int *macRandBytes) {
|
static void selectBlockMAC(int *macBytes, int *macRandBytes, bool forceMac) {
|
||||||
// xgroup(setup)
|
bool addMAC = false;
|
||||||
bool addMAC = boolDefaultNo(
|
if (!forceMac) {
|
||||||
_("Enable block authentication code headers\n"
|
// xgroup(setup)
|
||||||
"on every block in a file? This adds about 12 bytes per block\n"
|
addMAC = boolDefaultNo(
|
||||||
"to the storage requirements for a file, and significantly affects\n"
|
_("Enable block authentication code headers\n"
|
||||||
"performance but it also means [almost] any modifications or errors\n"
|
"on every block in a file? This adds about 12 bytes per block\n"
|
||||||
"within a block will be caught and will cause a read error."));
|
"to the storage requirements for a file, and significantly affects\n"
|
||||||
|
"performance but it also means [almost] any modifications or errors\n"
|
||||||
|
"within a block will be caught and will cause a read error."));
|
||||||
|
} else {
|
||||||
|
cout << _("\n\nYou specified --require-macs. "
|
||||||
|
"Enabling block authentication code headers...\n\n");
|
||||||
|
addMAC = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (addMAC)
|
if (addMAC)
|
||||||
*macBytes = 8;
|
*macBytes = 8;
|
||||||
@ -1021,6 +1028,10 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
|||||||
blockSize = DefaultBlockSize;
|
blockSize = DefaultBlockSize;
|
||||||
alg = findCipherAlgorithm("AES", keySize);
|
alg = findCipherAlgorithm("AES", keySize);
|
||||||
nameIOIface = BlockNameIO::CurrentInterface();
|
nameIOIface = BlockNameIO::CurrentInterface();
|
||||||
|
|
||||||
|
if (opts->requireMac) {
|
||||||
|
blockMACBytes = 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (answer[0] == 'x' || alg.name.empty()) {
|
if (answer[0] == 'x' || alg.name.empty()) {
|
||||||
@ -1060,7 +1071,7 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
|||||||
<< "\n";
|
<< "\n";
|
||||||
externalIV = false;
|
externalIV = false;
|
||||||
}
|
}
|
||||||
selectBlockMAC(&blockMACBytes, &blockMACRandBytes);
|
selectBlockMAC(&blockMACBytes, &blockMACRandBytes, opts->requireMac);
|
||||||
allowHoles = selectZeroBlockPassThrough();
|
allowHoles = selectZeroBlockPassThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1490,6 +1501,12 @@ RootPtr initFS(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
|||||||
shared_ptr<EncFSConfig> config(new EncFSConfig);
|
shared_ptr<EncFSConfig> config(new EncFSConfig);
|
||||||
|
|
||||||
if (readConfig(opts->rootDir, config) != Config_None) {
|
if (readConfig(opts->rootDir, config) != Config_None) {
|
||||||
|
if (config->blockMACBytes == 0 && opts->requireMac) {
|
||||||
|
cout
|
||||||
|
<< _("The configuration disabled MAC, but you passed --require-macs\n");
|
||||||
|
return rootInfo;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts->reverseEncryption) {
|
if (opts->reverseEncryption) {
|
||||||
if (config->blockMACBytes != 0 || config->blockMACRandBytes != 0 ||
|
if (config->blockMACBytes != 0 || config->blockMACRandBytes != 0 ||
|
||||||
config->externalIVChaining ||
|
config->externalIVChaining ||
|
||||||
|
@ -88,6 +88,8 @@ struct EncFS_Opts {
|
|||||||
|
|
||||||
bool readOnly; // Mount read-only
|
bool readOnly; // Mount read-only
|
||||||
|
|
||||||
|
bool requireMac; // Throw an error if MAC is disabled
|
||||||
|
|
||||||
ConfigMode configMode;
|
ConfigMode configMode;
|
||||||
|
|
||||||
EncFS_Opts() {
|
EncFS_Opts() {
|
||||||
@ -104,6 +106,7 @@ struct EncFS_Opts {
|
|||||||
configMode = Config_Prompt;
|
configMode = Config_Prompt;
|
||||||
noCache = false;
|
noCache = false;
|
||||||
readOnly = false;
|
readOnly = false;
|
||||||
|
requireMac = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,6 +121,15 @@ password. If this succeeds, then the filesystem becomes available again.
|
|||||||
Do not mount the filesystem when encfs starts; instead, delay mounting until
|
Do not mount the filesystem when encfs starts; instead, delay mounting until
|
||||||
first use. This option only makes sense with B<--ondemand>.
|
first use. This option only makes sense with B<--ondemand>.
|
||||||
|
|
||||||
|
=item B<--require-macs>
|
||||||
|
|
||||||
|
If creating a new filesystem, this forces block authentication code headers to
|
||||||
|
be enabled. When mounting an existing filesystem, this causes encfs to exit
|
||||||
|
if block authentication code headers are not enabled.
|
||||||
|
|
||||||
|
This can be used to improve security in case the ciphertext is vulnerable to
|
||||||
|
tampering, by preventing an attacker from disabling MACs in the config file.
|
||||||
|
|
||||||
=item B<--reverse>
|
=item B<--reverse>
|
||||||
|
|
||||||
Normally B<EncFS> provides a plaintext view of data on demand. Normally it
|
Normally B<EncFS> provides a plaintext view of data on demand. Normally it
|
||||||
|
@ -61,6 +61,7 @@ extern "C" void fuse_unmount_compat22(const char *mountpoint);
|
|||||||
* not have a short version */
|
* not have a short version */
|
||||||
#define LONG_OPT_ANNOTATE 513
|
#define LONG_OPT_ANNOTATE 513
|
||||||
#define LONG_OPT_NOCACHE 514
|
#define LONG_OPT_NOCACHE 514
|
||||||
|
#define LONG_OPT_REQUIRE_MAC 515
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
@ -195,6 +196,7 @@ static bool processArgs(int argc, char *argv[],
|
|||||||
out->opts->useStdin = false;
|
out->opts->useStdin = false;
|
||||||
out->opts->annotate = false;
|
out->opts->annotate = false;
|
||||||
out->opts->reverseEncryption = false;
|
out->opts->reverseEncryption = false;
|
||||||
|
out->opts->requireMac = false;
|
||||||
|
|
||||||
bool useDefaultFlags = true;
|
bool useDefaultFlags = true;
|
||||||
|
|
||||||
@ -229,6 +231,7 @@ static bool processArgs(int argc, char *argv[],
|
|||||||
{"reverse", 0, 0, 'r'}, // reverse encryption
|
{"reverse", 0, 0, 'r'}, // reverse encryption
|
||||||
{"standard", 0, 0, '1'}, // standard configuration
|
{"standard", 0, 0, '1'}, // standard configuration
|
||||||
{"paranoia", 0, 0, '2'}, // standard configuration
|
{"paranoia", 0, 0, '2'}, // standard configuration
|
||||||
|
{"require-macs", 0, 0, LONG_OPT_REQUIRE_MAC}, // require MACs
|
||||||
{0, 0, 0, 0}};
|
{0, 0, 0, 0}};
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -263,6 +266,9 @@ static bool processArgs(int argc, char *argv[],
|
|||||||
case LONG_OPT_ANNOTATE:
|
case LONG_OPT_ANNOTATE:
|
||||||
out->opts->annotate = true;
|
out->opts->annotate = true;
|
||||||
break;
|
break;
|
||||||
|
case LONG_OPT_REQUIRE_MAC:
|
||||||
|
out->opts->requireMac = true;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
out->isDaemon = false;
|
out->isDaemon = false;
|
||||||
// this option was added in fuse 2.x
|
// this option was added in fuse 2.x
|
||||||
|
Loading…
Reference in New Issue
Block a user