FileUtils.cpp (encfs-1.9.4) | : | FileUtils.cpp (encfs-1.9.5) | ||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
#include "easylogging++.h" | #include "easylogging++.h" | |||
#include <cctype> | #include <cctype> | |||
#include <cerrno> | #include <cerrno> | |||
#include <cstdio> | #include <cstdio> | |||
#include <cstdlib> | #include <cstdlib> | |||
#include <cstring> | #include <cstring> | |||
#include <fcntl.h> | #include <fcntl.h> | |||
#include <fstream> | #include <fstream> | |||
#include <iostream> | #include <iostream> | |||
#include <list> | #include <list> | |||
#ifdef __APPLE__ | ||||
#include <sys/mount.h> | ||||
#include <sys/param.h> | ||||
#endif | ||||
#include <sys/socket.h> | #include <sys/socket.h> | |||
#include <sys/stat.h> | #include <sys/stat.h> | |||
#include <sys/wait.h> | #include <sys/wait.h> | |||
#include <tinyxml2.h> | #include <tinyxml2.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <vector> | #include <vector> | |||
#include "BlockNameIO.h" | #include "BlockNameIO.h" | |||
#include "Cipher.h" | #include "Cipher.h" | |||
#include "CipherKey.h" | #include "CipherKey.h" | |||
skipping to change at line 225 | skipping to change at line 229 | |||
// No load function - must be an unsupported type.. | // No load function - must be an unsupported type.. | |||
config->cfgType = nm->type; | config->cfgType = nm->type; | |||
return nm->type; | return nm->type; | |||
} | } | |||
} | } | |||
/** | /** | |||
* Try to locate the config file | * Try to locate the config file | |||
* Tries the most recent format first, then looks for older versions | * Tries the most recent format first, then looks for older versions | |||
*/ | */ | |||
ConfigType readConfig(const string &rootDir, EncFSConfig *config) { | ConfigType readConfig(const string &rootDir, EncFSConfig *config, const string & cmdConfig) { | |||
ConfigInfo *nm = ConfigFileMapping; | ConfigInfo *nm = ConfigFileMapping; | |||
while (nm->fileName != nullptr) { | while (nm->fileName != nullptr) { | |||
// allow environment variable to override default config path | // allow command line argument to override default config path | |||
if (!cmdConfig.empty()) { | ||||
if (!fileExists(cmdConfig.c_str())) { | ||||
RLOG(ERROR) | ||||
<< "fatal: config file specified on command line does not exist: " | ||||
<< cmdConfig; | ||||
exit(1); | ||||
} | ||||
return readConfig_load(nm, cmdConfig.c_str(), config); | ||||
} // allow environment variable to override default config path | ||||
if (nm->environmentOverride != nullptr) { | if (nm->environmentOverride != nullptr) { | |||
char *envFile = getenv(nm->environmentOverride); | char *envFile = getenv(nm->environmentOverride); | |||
if (envFile != nullptr) { | if (envFile != nullptr) { | |||
if (!fileExists(envFile)) { | if (!fileExists(envFile)) { | |||
RLOG(ERROR) | RLOG(ERROR) | |||
<< "fatal: config file specified by environment does not exist: " | << "fatal: config file specified by environment does not exist: " | |||
<< envFile; | << envFile; | |||
exit(1); | exit(1); | |||
} | } | |||
return readConfig_load(nm, envFile, config); | return readConfig_load(nm, envFile, config); | |||
skipping to change at line 309 | skipping to change at line 322 | |||
} | } | |||
VLOG(1) << "subVersion = " << cfg->subVersion; | VLOG(1) << "subVersion = " << cfg->subVersion; | |||
config->read("creator", &cfg->creator); | config->read("creator", &cfg->creator); | |||
config->read("cipherAlg", &cfg->cipherIface); | config->read("cipherAlg", &cfg->cipherIface); | |||
config->read("nameAlg", &cfg->nameIface); | config->read("nameAlg", &cfg->nameIface); | |||
config->read("keySize", &cfg->keySize); | config->read("keySize", &cfg->keySize); | |||
config->read("blockSize", &cfg->blockSize); | config->read("blockSize", &cfg->blockSize); | |||
config->read("plainData", &cfg->plainData); | ||||
config->read("uniqueIV", &cfg->uniqueIV); | config->read("uniqueIV", &cfg->uniqueIV); | |||
config->read("chainedNameIV", &cfg->chainedNameIV); | config->read("chainedNameIV", &cfg->chainedNameIV); | |||
config->read("externalIVChaining", &cfg->externalIVChaining); | config->read("externalIVChaining", &cfg->externalIVChaining); | |||
config->read("blockMACBytes", &cfg->blockMACBytes); | config->read("blockMACBytes", &cfg->blockMACBytes); | |||
config->read("blockMACRandBytes", &cfg->blockMACRandBytes); | config->read("blockMACRandBytes", &cfg->blockMACRandBytes); | |||
config->read("allowHoles", &cfg->allowHoles); | config->read("allowHoles", &cfg->allowHoles); | |||
int encodedSize; | int encodedSize; | |||
config->read("encodedKeySize", &encodedSize); | config->read("encodedKeySize", &encodedSize); | |||
auto *key = new unsigned char[encodedSize]; | auto *key = new unsigned char[encodedSize]; | |||
skipping to change at line 436 | skipping to change at line 450 | |||
RLOG(WARNING) << err.what(); | RLOG(WARNING) << err.what(); | |||
VLOG(1) << "Error parsing config file " << configFile; | VLOG(1) << "Error parsing config file " << configFile; | |||
ok = false; | ok = false; | |||
} | } | |||
} | } | |||
return ok; | return ok; | |||
} | } | |||
bool saveConfig(ConfigType type, const string &rootDir, | bool saveConfig(ConfigType type, const string &rootDir, | |||
const EncFSConfig *config) { | const EncFSConfig *config, const string &cmdConfig) { | |||
bool ok = false; | bool ok = false; | |||
ConfigInfo *nm = ConfigFileMapping; | ConfigInfo *nm = ConfigFileMapping; | |||
while (nm->fileName != nullptr) { | while (nm->fileName != nullptr) { | |||
if (nm->type == type && (nm->saveFunc != nullptr)) { | if (nm->type == type && (nm->saveFunc != nullptr)) { | |||
string path = rootDir + nm->fileName; | string path = rootDir + nm->fileName; | |||
if (nm->environmentOverride != nullptr) { | if (!cmdConfig.empty()) { | |||
// use command line argument if specified | ||||
path.assign(cmdConfig); | ||||
} | ||||
else if (nm->environmentOverride != nullptr) { | ||||
// use environment file if specified.. | // use environment file if specified.. | |||
const char *envFile = getenv(nm->environmentOverride); | const char *envFile = getenv(nm->environmentOverride); | |||
if (envFile != nullptr) { | if (envFile != nullptr) { | |||
path.assign(envFile); | path.assign(envFile); | |||
} | } | |||
} | } | |||
try { | try { | |||
ok = (*nm->saveFunc)(path.c_str(), config); | ok = (*nm->saveFunc)(path.c_str(), config); | |||
} catch (encfs::Error &err) { | } catch (encfs::Error &err) { | |||
skipping to change at line 533 | skipping to change at line 551 | |||
addEl(doc, config, "version", V6SubVersion); | addEl(doc, config, "version", V6SubVersion); | |||
addEl(doc, config, "creator", cfg->creator.c_str()); | addEl(doc, config, "creator", cfg->creator.c_str()); | |||
auto cipherAlg = addEl(doc, config, "cipherAlg", cfg->cipherIface); | auto cipherAlg = addEl(doc, config, "cipherAlg", cfg->cipherIface); | |||
cipherAlg->SetAttribute("class_id", "1"); | cipherAlg->SetAttribute("class_id", "1"); | |||
cipherAlg->SetAttribute("tracking_level", "0"); | cipherAlg->SetAttribute("tracking_level", "0"); | |||
cipherAlg->SetAttribute("version", "0"); | cipherAlg->SetAttribute("version", "0"); | |||
addEl(doc, config, "nameAlg", cfg->nameIface); | addEl(doc, config, "nameAlg", cfg->nameIface); | |||
addEl(doc, config, "keySize", cfg->keySize); | addEl(doc, config, "keySize", cfg->keySize); | |||
addEl(doc, config, "blockSize", cfg->blockSize); | addEl(doc, config, "blockSize", cfg->blockSize); | |||
addEl(doc, config, "plainData", (int)cfg->plainData); | ||||
addEl(doc, config, "uniqueIV", (int)cfg->uniqueIV); | addEl(doc, config, "uniqueIV", (int)cfg->uniqueIV); | |||
addEl(doc, config, "chainedNameIV", (int)cfg->chainedNameIV); | addEl(doc, config, "chainedNameIV", (int)cfg->chainedNameIV); | |||
addEl(doc, config, "externalIVChaining", (int)cfg->externalIVChaining); | addEl(doc, config, "externalIVChaining", (int)cfg->externalIVChaining); | |||
addEl(doc, config, "blockMACBytes", cfg->blockMACBytes); | addEl(doc, config, "blockMACBytes", cfg->blockMACBytes); | |||
addEl(doc, config, "blockMACRandBytes", cfg->blockMACRandBytes); | addEl(doc, config, "blockMACRandBytes", cfg->blockMACRandBytes); | |||
addEl(doc, config, "allowHoles", (int)cfg->allowHoles); | addEl(doc, config, "allowHoles", (int)cfg->allowHoles); | |||
addEl(doc, config, "encodedKeySize", (int)cfg->keyData.size()); | addEl(doc, config, "encodedKeySize", (int)cfg->keyData.size()); | |||
addEl(doc, config, "encodedKeyData", cfg->keyData); | addEl(doc, config, "encodedKeyData", cfg->keyData); | |||
addEl(doc, config, "saltLen", (int)cfg->salt.size()); | addEl(doc, config, "saltLen", (int)cfg->salt.size()); | |||
addEl(doc, config, "saltData", cfg->salt); | addEl(doc, config, "saltData", cfg->salt); | |||
skipping to change at line 862 | skipping to change at line 881 | |||
static bool boolDefaultNo(const char *prompt) { | static bool boolDefaultNo(const char *prompt) { | |||
return boolDefault(prompt, false); | return boolDefault(prompt, false); | |||
} | } | |||
static bool boolDefaultYes(const char *prompt) { | static bool boolDefaultYes(const char *prompt) { | |||
return boolDefault(prompt, true); | return boolDefault(prompt, true); | |||
} | } | |||
/** | /** | |||
* Ask the user to select plain data | ||||
*/ | ||||
static bool selectPlainData(bool insecure) { | ||||
bool plainData = false; | ||||
if (insecure) { | ||||
plainData = boolDefaultNo( | ||||
_("You used --insecure, you can then disable file data encryption\n" | ||||
"which is of course abolutely discouraged.\n" | ||||
"Disable file data encryption?")); | ||||
} | ||||
return plainData; | ||||
} | ||||
/** | ||||
* 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, bool forceMac) { | static void selectBlockMAC(int *macBytes, int *macRandBytes, bool forceMac) { | |||
bool addMAC = false; | bool addMAC = false; | |||
if (!forceMac) { | if (!forceMac) { | |||
// xgroup(setup) | // xgroup(setup) | |||
addMAC = boolDefaultNo( | addMAC = boolDefaultNo( | |||
_("Enable block authentication code headers\n" | _("Enable block authentication code headers\n" | |||
"on every block in a file? This adds about 12 bytes per block\n" | "on every block in a file? This adds about 8 bytes per block\n" | |||
"to the storage requirements for a file, and significantly affects\n" | "to the storage requirements for a file, and significantly affects\n" | |||
"performance but it also means [almost] any modifications or errors\n" | "performance but it also means [almost] any modifications or errors\n" | |||
"within a block will be caught and will cause a read error.")); | "within a block will be caught and will cause a read error.")); | |||
} else { | } else { | |||
cout << "\n\n" | cout << "\n\n" | |||
<< _("You specified --require-macs. " | << _("You specified --require-macs. " | |||
"Enabling block authentication code headers...") | "Enabling block authentication code headers...") | |||
<< "\n\n"; | << "\n\n"; | |||
addMAC = true; | addMAC = true; | |||
} | } | |||
skipping to change at line 1006 | skipping to change at line 1039 | |||
cout << "\n"; | cout << "\n"; | |||
} | } | |||
// documented in ... | // documented in ... | |||
int keySize = 0; // selectKeySize() | int keySize = 0; // selectKeySize() | |||
int blockSize = 0; // selectBlockSize() | int blockSize = 0; // selectBlockSize() | |||
Cipher::CipherAlgorithm alg; // selectCipherAlgorithm() | Cipher::CipherAlgorithm alg; // selectCipherAlgorithm() | |||
Interface nameIOIface; // selectNameCoding() | Interface nameIOIface; // selectNameCoding() | |||
int blockMACBytes = 0; // selectBlockMAC() | int blockMACBytes = 0; // selectBlockMAC() | |||
int blockMACRandBytes = 0; // selectBlockMAC() | int blockMACRandBytes = 0; // selectBlockMAC() | |||
bool plainData = false; // selectPlainData() | ||||
bool uniqueIV = true; // selectUniqueIV() | bool uniqueIV = true; // selectUniqueIV() | |||
bool chainedIV = true; // selectChainedIV() | bool chainedIV = true; // selectChainedIV() | |||
bool externalIV = false; // selectExternalChainedIV() | bool externalIV = false; // selectExternalChainedIV() | |||
bool allowHoles = true; // selectZeroBlockPassThrough() | bool allowHoles = true; // selectZeroBlockPassThrough() | |||
long desiredKDFDuration = NormalKDFDuration; | long desiredKDFDuration = NormalKDFDuration; | |||
if (reverseEncryption) { | if (reverseEncryption) { | |||
chainedIV = false; | chainedIV = false; | |||
externalIV = false; | externalIV = false; | |||
uniqueIV = false; | uniqueIV = false; | |||
skipping to change at line 1058 | skipping to change at line 1092 | |||
} else if (configMode == Config_Standard || answer[0] != 'x') { | } else if (configMode == Config_Standard || answer[0] != 'x') { | |||
// xgroup(setup) | // xgroup(setup) | |||
cout << _("Standard configuration selected.") << "\n"; | cout << _("Standard configuration selected.") << "\n"; | |||
// AES w/ 192 bit key, block name encoding, per-file initialization | // AES w/ 192 bit key, block name encoding, per-file initialization | |||
// vectors are all standard. | // vectors are all standard. | |||
keySize = 192; | keySize = 192; | |||
blockSize = DefaultBlockSize; | blockSize = DefaultBlockSize; | |||
alg = findCipherAlgorithm("AES", keySize); | alg = findCipherAlgorithm("AES", keySize); | |||
// If case-insensitive system, opt for Block32 filename encoding | // If case-insensitive system, opt for Block32 filename encoding | |||
#if defined(__APPLE__) || defined(WIN32) | #if defined(DEFAULT_CASE_INSENSITIVE) | |||
nameIOIface = BlockNameIO::CurrentInterface(true); | nameIOIface = BlockNameIO::CurrentInterface(true); | |||
#else | #else | |||
nameIOIface = BlockNameIO::CurrentInterface(); | nameIOIface = BlockNameIO::CurrentInterface(); | |||
#endif | #endif | |||
if (opts->requireMac) { | if (opts->requireMac) { | |||
blockMACBytes = 8; | blockMACBytes = 8; | |||
} | } | |||
} | } | |||
skipping to change at line 1086 | skipping to change at line 1120 | |||
} else { | } else { | |||
// xgroup(setup) | // xgroup(setup) | |||
cout << _("Manual configuration mode selected."); | cout << _("Manual configuration mode selected."); | |||
} | } | |||
cout << endl; | cout << endl; | |||
// query user for settings.. | // query user for settings.. | |||
alg = selectCipherAlgorithm(); | alg = selectCipherAlgorithm(); | |||
keySize = selectKeySize(alg); | keySize = selectKeySize(alg); | |||
blockSize = selectBlockSize(alg); | blockSize = selectBlockSize(alg); | |||
plainData = selectPlainData(opts->insecure); | ||||
nameIOIface = selectNameCoding(); | nameIOIface = selectNameCoding(); | |||
if (reverseEncryption) { | if (plainData) { | |||
cout << _("reverse encryption - chained IV and MAC disabled") << "\n"; | cout << _("plain data - IV, MAC and file-hole disabled") << "\n"; | |||
uniqueIV = selectUniqueIV(false); | allowHoles = false; | |||
/* If uniqueIV is off, writing can be allowed, because there | chainedIV = false; | |||
* is no header that could be overwritten. | externalIV = false; | |||
* So if it is on, enforce readOnly. */ | uniqueIV = false; | |||
if (uniqueIV) { | blockMACBytes = 0; | |||
opts->readOnly = true; | blockMACRandBytes = 0; | |||
} | } | |||
} else { | else { | |||
chainedIV = selectChainedIV(); | if (reverseEncryption) { | |||
uniqueIV = selectUniqueIV(true); | cout << _("reverse encryption - chained IV and MAC disabled") << "\n"; | |||
if (chainedIV && uniqueIV) { | uniqueIV = selectUniqueIV(false); | |||
externalIV = selectExternalChainedIV(); | /* If uniqueIV is off, writing can be allowed, because there | |||
* is no header that could be overwritten. | ||||
* So if it is on, enforce readOnly. */ | ||||
if (uniqueIV) { | ||||
opts->readOnly = true; | ||||
} | ||||
} else { | } else { | |||
// xgroup(setup) | chainedIV = selectChainedIV(); | |||
cout << _("External chained IV disabled, as both 'IV chaining'\n" | uniqueIV = selectUniqueIV(true); | |||
"and 'unique IV' features are required for this option.") | if (chainedIV && uniqueIV) { | |||
<< "\n"; | externalIV = selectExternalChainedIV(); | |||
externalIV = false; | } else { | |||
// xgroup(setup) | ||||
cout << _("External chained IV disabled, as both 'IV chaining'\n" | ||||
"and 'unique IV' features are required for this option.") | ||||
<< "\n"; | ||||
externalIV = false; | ||||
} | ||||
selectBlockMAC(&blockMACBytes, &blockMACRandBytes, opts->requireMac); | ||||
allowHoles = selectZeroBlockPassThrough(); | ||||
} | } | |||
selectBlockMAC(&blockMACBytes, &blockMACRandBytes, opts->requireMac); | ||||
allowHoles = selectZeroBlockPassThrough(); | ||||
} | } | |||
} | } | |||
std::shared_ptr<Cipher> cipher = Cipher::New(alg.name, keySize); | std::shared_ptr<Cipher> cipher = Cipher::New(alg.name, keySize); | |||
if (!cipher) { | if (!cipher) { | |||
cerr << autosprintf( | cerr << autosprintf( | |||
_("Unable to instanciate cipher %s, key size %i, block size %i"), | _("Unable to instanciate cipher %s, key size %i, block size %i"), | |||
alg.name.c_str(), keySize, blockSize); | alg.name.c_str(), keySize, blockSize); | |||
return rootInfo; | return rootInfo; | |||
} | } | |||
VLOG(1) << "Using cipher " << alg.name << ", key size " << keySize | VLOG(1) << "Using cipher " << alg.name << ", key size " << keySize | |||
<< ", block size " << blockSize; | << ", block size " << blockSize; | |||
std::shared_ptr<EncFSConfig> config(new EncFSConfig); | std::shared_ptr<EncFSConfig> config(new EncFSConfig); | |||
config->cfgType = Config_V6; | config->cfgType = Config_V6; | |||
config->cipherIface = cipher->interface(); | config->cipherIface = cipher->interface(); | |||
config->keySize = keySize; | config->keySize = keySize; | |||
config->blockSize = blockSize; | config->blockSize = blockSize; | |||
config->plainData = plainData; | ||||
config->nameIface = nameIOIface; | config->nameIface = nameIOIface; | |||
config->creator = "EncFS " VERSION; | config->creator = "EncFS " VERSION; | |||
config->subVersion = V6SubVersion; | config->subVersion = V6SubVersion; | |||
config->blockMACBytes = blockMACBytes; | config->blockMACBytes = blockMACBytes; | |||
config->blockMACRandBytes = blockMACRandBytes; | config->blockMACRandBytes = blockMACRandBytes; | |||
config->uniqueIV = uniqueIV; | config->uniqueIV = uniqueIV; | |||
config->chainedNameIV = chainedIV; | config->chainedNameIV = chainedIV; | |||
config->externalIVChaining = externalIV; | config->externalIVChaining = externalIV; | |||
config->allowHoles = allowHoles; | config->allowHoles = allowHoles; | |||
skipping to change at line 1202 | skipping to change at line 1249 | |||
config->assignKeyData(encodedKey, encodedKeySize); | config->assignKeyData(encodedKey, encodedKeySize); | |||
delete[] encodedKey; | delete[] encodedKey; | |||
if (!volumeKey) { | if (!volumeKey) { | |||
cerr << _( | cerr << _( | |||
"Failure generating new volume key! " | "Failure generating new volume key! " | |||
"Please report this error."); | "Please report this error."); | |||
return rootInfo; | return rootInfo; | |||
} | } | |||
if (!saveConfig(Config_V6, rootDir, config.get())) { | if (!saveConfig(Config_V6, rootDir, config.get(), opts->config)) { | |||
return rootInfo; | return rootInfo; | |||
} | } | |||
// fill in config struct | // fill in config struct | |||
std::shared_ptr<NameIO> nameCoder = | std::shared_ptr<NameIO> nameCoder = | |||
NameIO::New(config->nameIface, cipher, volumeKey); | NameIO::New(config->nameIface, cipher, volumeKey); | |||
if (!nameCoder) { | if (!nameCoder) { | |||
cerr << _("Name coding interface not supported"); | cerr << _("Name coding interface not supported"); | |||
cout << _("The filename encoding interface requested is not available") | cout << _("The filename encoding interface requested is not available") | |||
<< endl; | << endl; | |||
return rootInfo; | return rootInfo; | |||
} | } | |||
nameCoder->setChainedNameIV(config->chainedNameIV); | nameCoder->setChainedNameIV(config->chainedNameIV); | |||
nameCoder->setReverseEncryption(reverseEncryption); | nameCoder->setReverseEncryption(reverseEncryption); | |||
FSConfigPtr fsConfig(new FSConfig); | FSConfigPtr fsConfig(new FSConfig); | |||
fsConfig->cipher = cipher; | if (plainData) { | |||
static Interface NullInterface("nullCipher", 1, 0, 0); | ||||
fsConfig->cipher = Cipher::New(NullInterface, 0); | ||||
} | ||||
else { | ||||
fsConfig->cipher = cipher; | ||||
} | ||||
fsConfig->key = volumeKey; | fsConfig->key = volumeKey; | |||
fsConfig->nameCoding = nameCoder; | fsConfig->nameCoding = nameCoder; | |||
fsConfig->config = config; | fsConfig->config = config; | |||
fsConfig->forceDecode = forceDecode; | fsConfig->forceDecode = forceDecode; | |||
fsConfig->reverseEncryption = reverseEncryption; | fsConfig->reverseEncryption = reverseEncryption; | |||
fsConfig->idleTracking = enableIdleTracking; | fsConfig->idleTracking = enableIdleTracking; | |||
fsConfig->opts = opts; | fsConfig->opts = opts; | |||
rootInfo = std::make_shared<encfs::EncFS_Root>(); | rootInfo = std::make_shared<encfs::EncFS_Root>(); | |||
rootInfo->cipher = cipher; | rootInfo->cipher = cipher; | |||
skipping to change at line 1562 | skipping to change at line 1615 | |||
memset(passBuf2, 0, sizeof(passBuf2)); | memset(passBuf2, 0, sizeof(passBuf2)); | |||
} while (!userKey); | } while (!userKey); | |||
return userKey; | return userKey; | |||
} | } | |||
RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr<EncFS_Opts> &opts) { | RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr<EncFS_Opts> &opts) { | |||
RootPtr rootInfo; | RootPtr rootInfo; | |||
std::shared_ptr<EncFSConfig> config(new EncFSConfig); | std::shared_ptr<EncFSConfig> config(new EncFSConfig); | |||
if (readConfig(opts->rootDir, config.get()) != Config_None) { | if (readConfig(opts->rootDir, config.get(), opts->config) != Config_None) { | |||
if (config->blockMACBytes == 0 && opts->requireMac) { | if (config->blockMACBytes == 0 && opts->requireMac) { | |||
cout << _( | cout << _( | |||
"The configuration disabled MAC, but you passed --require-macs\n"); | "The configuration disabled MAC, but you passed --require-macs\n"); | |||
return rootInfo; | 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->chainedNameIV) { | config->externalIVChaining || config->chainedNameIV) { | |||
cout << _( | cout << _( | |||
skipping to change at line 1650 | skipping to change at line 1703 | |||
cout << _( | cout << _( | |||
"The requested filename coding interface is " | "The requested filename coding interface is " | |||
"not available\n"); | "not available\n"); | |||
return rootInfo; | return rootInfo; | |||
} | } | |||
nameCoder->setChainedNameIV(config->chainedNameIV); | nameCoder->setChainedNameIV(config->chainedNameIV); | |||
nameCoder->setReverseEncryption(opts->reverseEncryption); | nameCoder->setReverseEncryption(opts->reverseEncryption); | |||
FSConfigPtr fsConfig(new FSConfig); | FSConfigPtr fsConfig(new FSConfig); | |||
fsConfig->cipher = cipher; | if (config->plainData) { | |||
if (! opts->insecure) { | ||||
cout << _("Configuration use plainData but you did not use --insecure\n" | ||||
); | ||||
return rootInfo; | ||||
} | ||||
static Interface NullInterface("nullCipher", 1, 0, 0); | ||||
fsConfig->cipher = Cipher::New(NullInterface, 0); | ||||
} | ||||
else { | ||||
fsConfig->cipher = cipher; | ||||
} | ||||
fsConfig->key = volumeKey; | fsConfig->key = volumeKey; | |||
fsConfig->nameCoding = nameCoder; | fsConfig->nameCoding = nameCoder; | |||
fsConfig->config = config; | fsConfig->config = config; | |||
fsConfig->forceDecode = opts->forceDecode; | fsConfig->forceDecode = opts->forceDecode; | |||
fsConfig->reverseEncryption = opts->reverseEncryption; | fsConfig->reverseEncryption = opts->reverseEncryption; | |||
fsConfig->opts = opts; | fsConfig->opts = opts; | |||
rootInfo = std::make_shared<encfs::EncFS_Root>(); | rootInfo = std::make_shared<encfs::EncFS_Root>(); | |||
rootInfo->cipher = cipher; | rootInfo->cipher = cipher; | |||
rootInfo->volumeKey = volumeKey; | rootInfo->volumeKey = volumeKey; | |||
skipping to change at line 1672 | skipping to change at line 1735 | |||
} else { | } else { | |||
if (opts->createIfNotFound) { | if (opts->createIfNotFound) { | |||
// creating a new encrypted filesystem | // creating a new encrypted filesystem | |||
rootInfo = createV6Config(ctx, opts); | rootInfo = createV6Config(ctx, opts); | |||
} | } | |||
} | } | |||
return rootInfo; | return rootInfo; | |||
} | } | |||
void unmountFS(const char *mountPoint) { | ||||
// fuse_unmount returns void, is assumed to succeed | ||||
fuse_unmount(mountPoint, nullptr); | ||||
#ifdef __APPLE__ | ||||
// fuse_unmount does not work on Mac OS, see #428 | ||||
// However it makes encfs to hang, so we must unmount | ||||
if (unmount(mountPoint, MNT_FORCE) != 0) { | ||||
int eno = errno; | ||||
if (eno != EINVAL) { //[EINVAL] The requested directory is not in the mount | ||||
table. | ||||
RLOG(ERROR) << "Filesystem unmount failed: " << strerror(eno); | ||||
} | ||||
} | ||||
#endif | ||||
#ifdef __CYGWIN__ | ||||
pid_t pid; | ||||
int status; | ||||
if ((pid = fork()) == 0) { | ||||
execl("/bin/pkill", "/bin/pkill", "-INT", "-if", string("(^|/)encfs .*(/|.:) | ||||
.* ").append(mountPoint).append("( |$)").c_str(), (char *)0); | ||||
int eno = errno; | ||||
RLOG(ERROR) << "Filesystem unmount failed: " << strerror(eno); | ||||
_Exit(127); | ||||
} | ||||
if (pid > 0) { | ||||
waitpid(pid, &status, 0); | ||||
} | ||||
#endif | ||||
} | ||||
int remountFS(EncFS_Context *ctx) { | int remountFS(EncFS_Context *ctx) { | |||
VLOG(1) << "Attempting to reinitialize filesystem"; | VLOG(1) << "Attempting to reinitialize filesystem"; | |||
RootPtr rootInfo = initFS(ctx, ctx->opts); | RootPtr rootInfo = initFS(ctx, ctx->opts); | |||
if (rootInfo) { | if (rootInfo) { | |||
ctx->setRoot(rootInfo->root); | ctx->setRoot(rootInfo->root); | |||
return 0; | return 0; | |||
} | } | |||
RLOG(WARNING) << "Remount failed"; | RLOG(WARNING) << "Remount failed"; | |||
return -EACCES; | return -EACCES; | |||
} | } | |||
bool unmountFS(EncFS_Context *ctx) { | bool unmountFS(EncFS_Context *ctx) { | |||
if (ctx->opts->mountOnDemand) { | if (ctx->opts->mountOnDemand) { | |||
VLOG(1) << "Detaching filesystem due to inactivity: " | VLOG(1) << "Detaching filesystem due to inactivity: " | |||
<< ctx->opts->mountPoint; | << ctx->opts->unmountPoint; | |||
ctx->setRoot(std::shared_ptr<DirNode>()); | ctx->setRoot(std::shared_ptr<DirNode>()); | |||
return false; | return false; | |||
} | } | |||
// Time to unmount! | // Time to unmount! | |||
#if FUSE_USE_VERSION < 30 | RLOG(INFO) << "Filesystem inactive, unmounting: " << ctx->opts->unmountPoint; | |||
fuse_unmount(ctx->opts->mountPoint.c_str(), nullptr); | unmountFS(ctx->opts->unmountPoint.c_str()); | |||
#else | ||||
fuse_unmount(fuse_get_context()->fuse); | ||||
#endif | ||||
// fuse_unmount succeeds and returns void | ||||
RLOG(INFO) << "Filesystem inactive, unmounted: " << ctx->opts->mountPoint; | ||||
return true; | return true; | |||
} | } | |||
} // namespace encfs | } // namespace encfs | |||
End of changes. 23 change blocks. | ||||
40 lines changed or deleted | 129 lines changed or added |