encfsctl.cpp (encfs-1.9.4) | : | encfsctl.cpp (encfs-1.9.5) | ||
---|---|---|---|---|
skipping to change at line 37 | skipping to change at line 37 | |||
#include <sys/stat.h> | #include <sys/stat.h> | |||
#include <time.h> | #include <time.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <vector> | #include <vector> | |||
#define NO_DES | #define NO_DES | |||
#include <openssl/ssl.h> | #include <openssl/ssl.h> | |||
#include "Cipher.h" | #include "Cipher.h" | |||
#include "CipherKey.h" | #include "CipherKey.h" | |||
#include "Context.h" | ||||
#include "DirNode.h" | #include "DirNode.h" | |||
#include "Error.h" | #include "Error.h" | |||
#include "FSConfig.h" | #include "FSConfig.h" | |||
#include "FileNode.h" | #include "FileNode.h" | |||
#include "FileUtils.h" | #include "FileUtils.h" | |||
#include "Interface.h" | #include "Interface.h" | |||
#include "autosprintf.h" | #include "autosprintf.h" | |||
#include "config.h" | #include "config.h" | |||
#include "i18n.h" | #include "i18n.h" | |||
#include "intl/gettext.h" | #include "intl/gettext.h" | |||
skipping to change at line 98 | skipping to change at line 99 | |||
gettext_noop(" -- change password for volume, taking password" | gettext_noop(" -- change password for volume, taking password" | |||
" from standard input.\n\tNo prompts are issued.")}, | " from standard input.\n\tNo prompts are issued.")}, | |||
{"autocheckpasswd", 1, 1, ckpasswdAutomaticly, "(root dir)", | {"autocheckpasswd", 1, 1, ckpasswdAutomaticly, "(root dir)", | |||
// xgroup(usage) | // xgroup(usage) | |||
gettext_noop(" -- check password for volume, taking password" | gettext_noop(" -- check password for volume, taking password" | |||
" from standard input.\n\tNo prompts are issued.")}, | " from standard input.\n\tNo prompts are issued.")}, | |||
{"ls", 1, 2, cmd_ls, 0, 0}, | {"ls", 1, 2, cmd_ls, 0, 0}, | |||
{"showcruft", 1, 1, cmd_showcruft, "(root dir)", | {"showcruft", 1, 1, cmd_showcruft, "(root dir)", | |||
// xgroup(usage) | // xgroup(usage) | |||
gettext_noop(" -- show undecodable filenames in the volume")}, | gettext_noop(" -- show undecodable filenames in the volume")}, | |||
{"cat", 2, 3, cmd_cat, "[--extpass=prog] (root dir) path", | {"cat", 2, 4, cmd_cat, "[--extpass=prog] [--reverse] (root dir) path", | |||
// xgroup(usage) | // xgroup(usage) | |||
gettext_noop(" -- decodes the file and cats it to standard out")}, | gettext_noop(" -- decodes the file and cats it to standard out")}, | |||
{"decode", 1, 100, cmd_decode, | {"decode", 1, 100, cmd_decode, | |||
"[--extpass=prog] (root dir) [encoded-name ...]", | "[--extpass=prog] (root dir) [encoded-name ...]", | |||
// xgroup(usage) | // xgroup(usage) | |||
gettext_noop(" -- decodes name and prints plaintext version")}, | gettext_noop(" -- decodes name and prints plaintext version")}, | |||
{"encode", 1, 100, cmd_encode, | {"encode", 1, 100, cmd_encode, | |||
"[--extpass=prog] (root dir) [plaintext-name ...]", | "[--extpass=prog] (root dir) [plaintext-name ...]", | |||
// xgroup(usage) | // xgroup(usage) | |||
gettext_noop(" -- encodes a filename and print result")}, | gettext_noop(" -- encodes a filename and print result")}, | |||
{"export", 2, 2, cmd_export, "(root dir) path", | {"export", 2, 2, cmd_export, "(root dir) path", | |||
// xgroup(usage) | // xgroup(usage) | |||
gettext_noop(" -- decrypts a volume and writes results to path")}, | gettext_noop(" -- decrypts a volume and writes results to path")}, | |||
{"--version", 0, 0, showVersion, "", | {"--version", 0, 0, showVersion, "", | |||
// xgroup(usage) | // xgroup(usage) | |||
gettext_noop(" -- print version number and exit")}, | gettext_noop(" -- print version number and exit")}, | |||
{0, 0, 0, 0, 0, 0}}; | {0, 0, 0, 0, 0, 0}}; | |||
auto ctx = std::make_shared<EncFS_Context>(); | ||||
static void usage(const char *name) { | static void usage(const char *name) { | |||
cerr << autosprintf(_("encfsctl version %s"), VERSION) << "\n" | cerr << autosprintf(_("encfsctl version %s"), VERSION) << "\n" | |||
<< _("Usage:\n") | << _("Usage:\n") | |||
// displays usage commands, eg "./encfs (root dir) ..." | // displays usage commands, eg "./encfs (root dir) ..." | |||
// xgroup(usage) | // xgroup(usage) | |||
<< autosprintf( | << autosprintf( | |||
_("%s (root dir)\n" | _("%s (root dir)\n" | |||
" -- displays information about the filesystem, or \n"), | " -- displays information about the filesystem, or \n"), | |||
name); | name); | |||
skipping to change at line 167 | skipping to change at line 170 | |||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
static int showInfo(int argc, char **argv) { | static int showInfo(int argc, char **argv) { | |||
(void)argc; | (void)argc; | |||
string rootDir = argv[1]; | string rootDir = argv[1]; | |||
if (!checkDir(rootDir)) return EXIT_FAILURE; | if (!checkDir(rootDir)) return EXIT_FAILURE; | |||
std::shared_ptr<EncFSConfig> config(new EncFSConfig); | std::shared_ptr<EncFSConfig> config(new EncFSConfig); | |||
ConfigType type = readConfig(rootDir, config.get()); | ConfigType type = readConfig(rootDir, config.get(), ""); | |||
// show information stored in config.. | // show information stored in config.. | |||
switch (type) { | switch (type) { | |||
case Config_None: | case Config_None: | |||
// xgroup(diag) | // xgroup(diag) | |||
cout << _("Unable to load or parse config file\n"); | cout << _("Unable to load or parse config file\n"); | |||
return EXIT_FAILURE; | return EXIT_FAILURE; | |||
case Config_Prehistoric: | case Config_Prehistoric: | |||
// xgroup(diag) | // xgroup(diag) | |||
cout << _( | cout << _( | |||
skipping to change at line 222 | skipping to change at line 225 | |||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
static RootPtr initRootInfo(int &argc, char **&argv) { | static RootPtr initRootInfo(int &argc, char **&argv) { | |||
RootPtr result; | RootPtr result; | |||
std::shared_ptr<EncFS_Opts> opts(new EncFS_Opts()); | std::shared_ptr<EncFS_Opts> opts(new EncFS_Opts()); | |||
opts->createIfNotFound = false; | opts->createIfNotFound = false; | |||
opts->checkKey = false; | opts->checkKey = false; | |||
static struct option long_options[] = {{"extpass", 1, 0, 'p'}, {0, 0, 0, 0}}; | static struct option long_options[] = {{"extpass", 1, 0, 'p'}, {"reverse", 0, nullptr, 'r'}, {0, 0, 0, 0}}; | |||
for (;;) { | for (;;) { | |||
int option_index = 0; | int option_index = 0; | |||
int res = getopt_long(argc, argv, "", long_options, &option_index); | int res = getopt_long(argc, argv, "", long_options, &option_index); | |||
if (res == -1) break; | if (res == -1) break; | |||
switch (res) { | switch (res) { | |||
case 'p': | case 'p': | |||
opts->passwordProgram.assign(optarg); | opts->passwordProgram.assign(optarg); | |||
break; | break; | |||
case 'r': | ||||
opts->reverseEncryption = true; | ||||
break; | ||||
default: | default: | |||
RLOG(WARNING) << "getopt error: " << res; | RLOG(WARNING) << "getopt error: " << res; | |||
break; | break; | |||
} | } | |||
} | } | |||
argc -= optind; | argc -= optind; | |||
argv += optind; | argv += optind; | |||
if (argc == 0) { | if (argc == 0) { | |||
cerr << _("Incorrect number of arguments") << "\n"; | cerr << _("Incorrect number of arguments") << "\n"; | |||
} else { | } else { | |||
opts->rootDir = string(argv[0]); | opts->rootDir = string(argv[0]); | |||
--argc; | --argc; | |||
++argv; | ++argv; | |||
if (checkDir(opts->rootDir)) result = initFS(NULL, opts); | ctx->publicFilesystem = opts->ownerCreate; | |||
if (checkDir(opts->rootDir)) result = initFS(ctx.get(), opts); | ||||
if (!result) | if (!result) | |||
cerr << _("Unable to initialize encrypted filesystem - check path.\n"); | cerr << _("Unable to initialize encrypted filesystem - check path.\n"); | |||
} | } | |||
return result; | return result; | |||
} | } | |||
static RootPtr initRootInfo(const char *crootDir) { | static RootPtr initRootInfo(const char *crootDir) { | |||
string rootDir(crootDir); | string rootDir(crootDir); | |||
RootPtr result; | RootPtr result; | |||
if (checkDir(rootDir)) { | if (checkDir(rootDir)) { | |||
std::shared_ptr<EncFS_Opts> opts(new EncFS_Opts()); | std::shared_ptr<EncFS_Opts> opts(new EncFS_Opts()); | |||
opts->rootDir = rootDir; | opts->rootDir = rootDir; | |||
opts->createIfNotFound = false; | opts->createIfNotFound = false; | |||
opts->checkKey = false; | opts->checkKey = false; | |||
result = initFS(NULL, opts); | ||||
ctx->publicFilesystem = opts->ownerCreate; | ||||
result = initFS(ctx.get(), opts); | ||||
} | } | |||
if (!result) | if (!result) | |||
cerr << _("Unable to initialize encrypted filesystem - check path.\n"); | cerr << _("Unable to initialize encrypted filesystem - check path.\n"); | |||
return result; | return result; | |||
} | } | |||
static int cmd_showKey(int argc, char **argv) { | static int cmd_showKey(int argc, char **argv) { | |||
(void)argc; | (void)argc; | |||
skipping to change at line 370 | skipping to change at line 379 | |||
} | } | |||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
// apply an operation to every block in the file | // apply an operation to every block in the file | |||
template <typename T> | template <typename T> | |||
int processContents(const std::shared_ptr<EncFS_Root> &rootInfo, | int processContents(const std::shared_ptr<EncFS_Root> &rootInfo, | |||
const char *path, T &op) { | const char *path, T &op) { | |||
int errCode = 0; | int errCode = 0; | |||
std::shared_ptr<FileNode> node = | std::shared_ptr<FileNode> node; | |||
rootInfo->root->openNode(path, "encfsctl", O_RDONLY, &errCode); | ||||
try { | ||||
node = rootInfo->root->openNode(path, "encfsctl", O_RDONLY, &errCode); | ||||
} | ||||
catch(...) {} | ||||
if (!node) { | if (!node) { | |||
// try treating filename as an enciphered path | // try treating filename as an enciphered path | |||
string plainName = rootInfo->root->plainPath(path); | string plainName = rootInfo->root->plainPath(path); | |||
node = rootInfo->root->lookupNode(plainName.c_str(), "encfsctl"); | if (plainName.length() > 0) { | |||
node = rootInfo->root->lookupNode(plainName.c_str(), "encfsctl"); | ||||
} | ||||
if (node) { | if (node) { | |||
errCode = node->open(O_RDONLY); | errCode = node->open(O_RDONLY); | |||
if (errCode < 0) node.reset(); | if (errCode < 0) node.reset(); | |||
} | } | |||
} | } | |||
if (!node) { | if (!node) { | |||
cerr << "unable to open " << path << "\n"; | cerr << "unable to open " << path << "\n"; | |||
return errCode; | return errCode; | |||
} else { | } else { | |||
skipping to change at line 417 | skipping to change at line 432 | |||
return (int)write(_fd, buf, count); | return (int)write(_fd, buf, count); | |||
} | } | |||
}; | }; | |||
static int cmd_cat(int argc, char **argv) { | static int cmd_cat(int argc, char **argv) { | |||
RootPtr rootInfo = initRootInfo(argc, argv); | RootPtr rootInfo = initRootInfo(argc, argv); | |||
if (!rootInfo) return EXIT_FAILURE; | if (!rootInfo) return EXIT_FAILURE; | |||
const char *path = argv[0]; | const char *path = argv[0]; | |||
// If user provides a leading slash, in reverse mode, it will be converted | ||||
// to "+" by plainpath, and will fail to decode... Workaround below then... | ||||
if (path[0] == '/') { | ||||
path++; | ||||
} | ||||
WriteOutput output(STDOUT_FILENO); | WriteOutput output(STDOUT_FILENO); | |||
int errCode = processContents(rootInfo, path, output); | int errCode = processContents(rootInfo, path, output); | |||
return errCode; | return errCode; | |||
} | } | |||
static int copyLink(const struct stat &stBuf, | static int copyLink(const struct stat &stBuf, | |||
const std::shared_ptr<EncFS_Root> &rootInfo, | const std::shared_ptr<EncFS_Root> &rootInfo, | |||
const string &cpath, const string &destName) { | const string &cpath, const string &destName) { | |||
std::vector<char> buf(stBuf.st_size + 1, '\0'); | std::vector<char> buf(stBuf.st_size + 1, '\0'); | |||
skipping to change at line 625 | skipping to change at line 645 | |||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
static int do_chpasswd(bool useStdin, bool annotate, bool checkOnly, int argc, | static int do_chpasswd(bool useStdin, bool annotate, bool checkOnly, int argc, | |||
char **argv) { | char **argv) { | |||
(void)argc; | (void)argc; | |||
string rootDir = argv[1]; | string rootDir = argv[1]; | |||
if (!checkDir(rootDir)) return EXIT_FAILURE; | if (!checkDir(rootDir)) return EXIT_FAILURE; | |||
EncFSConfig *config = new EncFSConfig; | EncFSConfig *config = new EncFSConfig; | |||
ConfigType cfgType = readConfig(rootDir, config); | ConfigType cfgType = readConfig(rootDir, config, ""); | |||
if (cfgType == Config_None) { | if (cfgType == Config_None) { | |||
cout << _("Unable to load or parse config file\n"); | cout << _("Unable to load or parse config file\n"); | |||
return EXIT_FAILURE; | return EXIT_FAILURE; | |||
} | } | |||
// instanciate proper cipher | // instanciate proper cipher | |||
std::shared_ptr<Cipher> cipher = | std::shared_ptr<Cipher> cipher = | |||
Cipher::New(config->cipherIface, config->keySize); | Cipher::New(config->cipherIface, config->keySize); | |||
if (!cipher) { | if (!cipher) { | |||
skipping to change at line 686 | skipping to change at line 706 | |||
int encodedKeySize = cipher->encodedKeySize(); | int encodedKeySize = cipher->encodedKeySize(); | |||
unsigned char *keyBuf = new unsigned char[encodedKeySize]; | unsigned char *keyBuf = new unsigned char[encodedKeySize]; | |||
// encode volume key with new user key | // encode volume key with new user key | |||
cipher->writeKey(volumeKey, keyBuf, userKey); | cipher->writeKey(volumeKey, keyBuf, userKey); | |||
userKey.reset(); | userKey.reset(); | |||
config->assignKeyData(keyBuf, encodedKeySize); | config->assignKeyData(keyBuf, encodedKeySize); | |||
delete[] keyBuf; | delete[] keyBuf; | |||
if (saveConfig(cfgType, rootDir, config)) { | if (saveConfig(cfgType, rootDir, config, "")) { | |||
// password modified -- changes volume key of filesystem.. | // password modified -- changes volume key of filesystem.. | |||
cout << _("Volume Key successfully updated.\n"); | cout << _("Volume Key successfully updated.\n"); | |||
result = EXIT_SUCCESS; | result = EXIT_SUCCESS; | |||
} else { | } else { | |||
cout << _("Error saving modified config file.\n"); | cout << _("Error saving modified config file.\n"); | |||
} | } | |||
} else { | } else { | |||
cout << _("Error creating key\n"); | cout << _("Error creating key\n"); | |||
} | } | |||
End of changes. 13 change blocks. | ||||
10 lines changed or deleted | 30 lines changed or added |