Corrects encfsctl cat and add reverse cat (#483)

Correct encfsctl cat and add --reverse
This commit is contained in:
Ben RUBSON 2018-03-18 00:01:05 +01:00 committed by rfjakob
parent e963664cae
commit dcf8435d4c
3 changed files with 47 additions and 11 deletions

View File

@ -34,6 +34,7 @@
#include "Cipher.h"
#include "CipherKey.h"
#include "Context.h"
#include "DirNode.h"
#include "Error.h"
#include "FSConfig.h"
@ -95,7 +96,7 @@ struct CommandOpts {
{"showcruft", 1, 1, cmd_showcruft, "(root dir)",
// xgroup(usage)
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)
gettext_noop(" -- decodes the file and cats it to standard out")},
{"decode", 1, 100, cmd_decode,
@ -219,7 +220,7 @@ static RootPtr initRootInfo(int &argc, char **&argv) {
opts->createIfNotFound = 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 (;;) {
int option_index = 0;
@ -231,6 +232,9 @@ static RootPtr initRootInfo(int &argc, char **&argv) {
case 'p':
opts->passwordProgram.assign(optarg);
break;
case 'r':
opts->reverseEncryption = true;
break;
default:
RLOG(WARNING) << "getopt error: " << res;
break;
@ -248,7 +252,9 @@ static RootPtr initRootInfo(int &argc, char **&argv) {
--argc;
++argv;
if (checkDir(opts->rootDir)) result = initFS(NULL, opts);
auto ctx = std::make_shared<EncFS_Context>();
ctx->publicFilesystem = opts->ownerCreate;
if (checkDir(opts->rootDir)) result = initFS(ctx.get(), opts);
if (!result)
cerr << _("Unable to initialize encrypted filesystem - check path.\n");
@ -266,7 +272,10 @@ static RootPtr initRootInfo(const char *crootDir) {
opts->rootDir = rootDir;
opts->createIfNotFound = false;
opts->checkKey = false;
result = initFS(NULL, opts);
auto ctx = std::make_shared<EncFS_Context>();
ctx->publicFilesystem = opts->ownerCreate;
result = initFS(ctx.get(), opts);
}
if (!result)
@ -367,13 +376,19 @@ template <typename T>
int processContents(const std::shared_ptr<EncFS_Root> &rootInfo,
const char *path, T &op) {
int errCode = 0;
std::shared_ptr<FileNode> node =
rootInfo->root->openNode(path, "encfsctl", O_RDONLY, &errCode);
std::shared_ptr<FileNode> node;
try {
node = rootInfo->root->openNode(path, "encfsctl", O_RDONLY, &errCode);
}
catch(...) {}
if (!node) {
// try treating filename as an enciphered path
string plainName = rootInfo->root->plainPath(path);
if (plainName.length() > 0) {
node = rootInfo->root->lookupNode(plainName.c_str(), "encfsctl");
}
if (node) {
errCode = node->open(O_RDONLY);
if (errCode < 0) node.reset();

View File

@ -18,9 +18,7 @@ encfsctl - administrative tool for working with EncFS filesystems
B<encfsctl> [I<command> I<command_args>]
B<encfsctl> I<rootdir>
B<encfsctl> info I<rootdir>
B<encfsctl> [info] I<rootdir>
B<encfsctl> passwd I<rootdir>
@ -30,6 +28,8 @@ B<encfsctl> decode [--extpass=prog] I<rootdir> [encoded name ...]
B<encfsctl> encode [--extpass=prog] I<rootdir> [plaintext name ...]
B<encfsctl> cat [--extpass=prog] [--reverse] I<rootdir> <(cipher|plain) filename>
=head1 DESCRIPTION
B<encfsctl> is an administrative tool for working with EncFS filesystems. It
@ -84,6 +84,12 @@ password - just like with encfs.
If no names are specified on the command line, then a list of filenames
will be read from stdin and encoded.
=item B<cat>
Decodes and B<cat>s the content of an encrypted file. The filename can be
given in a plain or ciphered form. With B<--reverse> The file content will
instead be encrypted.
=back
=head1 EXAMPLES

View File

@ -3,7 +3,7 @@
# Test EncFS --reverse mode
use warnings;
use Test::More tests => 31;
use Test::More tests => 34;
use File::Path;
use File::Temp;
use IO::Handle;
@ -101,6 +101,20 @@ sub copy_test
ok(! -f "$decrypted/encfs.cpp", "file deleted");
}
# Encfsctl cat test
sub encfsctl_cat_test
{
my $contents = "hello world\n";
ok( open(OUT, "> $plain/hello.txt"), "create file for encfsctl cat test" );
print OUT $contents;
close OUT;
qx(ENCFS6_CONFIG=$plain/.encfs6.xml ./build/encfsctl cat --extpass="echo test" $ciphertext hello.txt > $plain/hellodec.txt);
qx(ENCFS6_CONFIG=$plain/.encfs6.xml ./build/encfsctl cat --extpass="echo test" --reverse $plain hello.txt > $plain/helloenc.txt);
my $cname = encName("hello.txt");
ok(system("diff -q $plain/helloenc.txt $ciphertext/$cname")==0, "encfsctl correctly encrypts");
ok(system("diff -q $plain/hello.txt $plain/hellodec.txt")==0, "encfsctl correctly decrypts");
}
# Create symlinks and verify they are correctly decrypted
# Parameter: symlink target
sub symlink_test
@ -207,6 +221,7 @@ mount();
grow();
largeRead();
copy_test();
encfsctl_cat_test();
symlink_test("/"); # absolute
symlink_test("foo"); # relative
symlink_test("/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/15/17/18"); # long