From dcf8435d4c3d1926e65bcac7f07a7aaa6ca0a6ea Mon Sep 17 00:00:00 2001 From: Ben RUBSON Date: Sun, 18 Mar 2018 00:01:05 +0100 Subject: [PATCH] Corrects encfsctl cat and add reverse cat (#483) Correct encfsctl cat and add --reverse --- encfs/encfsctl.cpp | 29 ++++++++++++++++++++++------- encfs/encfsctl.pod | 12 +++++++++--- integration/reverse.t.pl | 17 ++++++++++++++++- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/encfs/encfsctl.cpp b/encfs/encfsctl.cpp index 26b82da..2af8c46 100644 --- a/encfs/encfsctl.cpp +++ b/encfs/encfsctl.cpp @@ -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(); + 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(); + ctx->publicFilesystem = opts->ownerCreate; + result = initFS(ctx.get(), opts); } if (!result) @@ -367,13 +376,19 @@ template int processContents(const std::shared_ptr &rootInfo, const char *path, T &op) { int errCode = 0; - std::shared_ptr node = - rootInfo->root->openNode(path, "encfsctl", O_RDONLY, &errCode); + std::shared_ptr 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); - node = rootInfo->root->lookupNode(plainName.c_str(), "encfsctl"); + if (plainName.length() > 0) { + node = rootInfo->root->lookupNode(plainName.c_str(), "encfsctl"); + } if (node) { errCode = node->open(O_RDONLY); if (errCode < 0) node.reset(); diff --git a/encfs/encfsctl.pod b/encfs/encfsctl.pod index e0b1e24..c7b7058 100644 --- a/encfs/encfsctl.pod +++ b/encfs/encfsctl.pod @@ -18,9 +18,7 @@ encfsctl - administrative tool for working with EncFS filesystems B [I I] -B I - -B info I +B [info] I B passwd I @@ -30,6 +28,8 @@ B decode [--extpass=prog] I [encoded name ...] B encode [--extpass=prog] I [plaintext name ...] +B cat [--extpass=prog] [--reverse] I <(cipher|plain) filename> + =head1 DESCRIPTION B 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 + +Decodes and Bs 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 diff --git a/integration/reverse.t.pl b/integration/reverse.t.pl index bb37162..b527aa7 100755 --- a/integration/reverse.t.pl +++ b/integration/reverse.t.pl @@ -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