Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude #649

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions encfs/DirNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#ifdef __linux__
#include <sys/fsuid.h>
#endif
#include <fnmatch.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
Expand All @@ -52,9 +53,11 @@ class DirDeleter {
};

DirTraverse::DirTraverse(std::shared_ptr<DIR> _dirPtr, uint64_t _iv,
std::shared_ptr<NameIO> _naming, bool _root)
: dir(std::move(_dirPtr)), iv(_iv), naming(std::move(_naming)), root(_root) {}

std::shared_ptr<NameIO> _naming, bool _root,
std::shared_ptr<EncFS_Opts> _opts)
: dir(std::move(_dirPtr)), iv(_iv), naming(std::move(_naming)), root(_root) {
opts = _opts;
}
DirTraverse &DirTraverse::operator=(const DirTraverse &src) = default;

DirTraverse::~DirTraverse() {
Expand Down Expand Up @@ -90,11 +93,27 @@ static bool _nextName(struct dirent *&de, const std::shared_ptr<DIR> &dir,

std::string DirTraverse::nextPlaintextName(int *fileType, ino_t *inode) {
struct dirent *de = nullptr;
bool exclude = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool exclude = false;

while (_nextName(de, dir, fileType, inode)) {
if (root && (strcmp(".encfs6.xml", de->d_name) == 0)) {
VLOG(1) << "skipping filename: " << de->d_name;
continue;
}

// Exclude any files that match our exclude patterns
if (opts->reverseEncryption) {
for (int i=0; i<opts->excludeArgc; i++) {
if (! fnmatch(opts->excludeArgv[i], de->d_name, FNM_PATHNAME)) {
VLOG(1) << "excluding filename: " << de->d_name;
exclude = true;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
exclude = true;
continue;

}
}
if (exclude) {
exclude = false;
continue;
}
Comment on lines +111 to +114
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (exclude) {
exclude = false;
continue;
}

}

try {
uint64_t localIv = iv;
return naming->decodePath(de->d_name, &localIv);
Expand Down Expand Up @@ -364,7 +383,7 @@ DirTraverse DirNode::openDir(const char *plaintextPath) {
if (dir == nullptr) {
int eno = errno;
VLOG(1) << "opendir error " << strerror(eno);
return DirTraverse(shared_ptr<DIR>(), 0, std::shared_ptr<NameIO>(), false);
return DirTraverse(shared_ptr<DIR>(), 0, std::shared_ptr<NameIO>(), false, NULL);
}
std::shared_ptr<DIR> dp(dir, DirDeleter());

Expand All @@ -378,7 +397,7 @@ DirTraverse DirNode::openDir(const char *plaintextPath) {
} catch (encfs::Error &err) {
RLOG(ERROR) << "encode err: " << err.what();
}
return DirTraverse(dp, iv, naming, (strlen(plaintextPath) == 1));
return DirTraverse(dp, iv, naming, (strlen(plaintextPath) == 1), fsConfig->opts);
}

bool DirNode::genRenameList(list<RenameEl> &renameList, const char *fromP,
Expand Down
6 changes: 5 additions & 1 deletion encfs/DirNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ struct RenameEl;
class DirTraverse {
public:
DirTraverse(std::shared_ptr<DIR> dirPtr, uint64_t iv,
std::shared_ptr<NameIO> naming, bool root);
std::shared_ptr<NameIO> naming, bool root,
std::shared_ptr<EncFS_Opts>);
~DirTraverse();

DirTraverse &operator=(const DirTraverse &src);

// pass options through so we can, e.g., get at opts->excludeArgv
std::shared_ptr<EncFS_Opts> opts;

// returns FALSE to indicate an invalid DirTraverse (such as when
// an invalid directory is requested for traversal)
bool valid() const;
Expand Down
10 changes: 10 additions & 0 deletions encfs/FileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ using RootPtr = std::shared_ptr<EncFS_Root>;

enum ConfigMode { Config_Prompt, Config_Standard, Config_Paranoia };

// Maximum number of exclude strings we'll process. If the user
// passes more, we complain and ignore the extra ones.
#if !defined(MaxExcludeArgs)
#define MaxExcludeArgs 64
#endif

/**
* EncFS_Opts stores internal settings
*
Expand Down Expand Up @@ -102,6 +108,9 @@ struct EncFS_Opts {

bool requireMac; // Throw an error if MAC is disabled

const char *excludeArgv[MaxExcludeArgs]; // exclude patterns
int excludeArgc; // number of exclude patterns

ConfigMode configMode;
std::string config; // path to configuration file (or empty)

Expand All @@ -122,6 +131,7 @@ struct EncFS_Opts {
readOnly = false;
insecure = false;
requireMac = false;
excludeArgc = 0;
}
};

Expand Down
28 changes: 26 additions & 2 deletions encfs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ static void usage(const char *name) {
"verbose: output encfs debug messages\n"
" -i, --idle=MINUTES\t"
"Auto unmount after period of inactivity\n"
" --exclude\t\t"
"Exclude glob during reverse (may be specified multiple times)\n"
" --anykey\t\t"
"Do not verify correct key is being used\n"
" --forcedecode\t\t"
Expand Down Expand Up @@ -254,6 +256,7 @@ static bool processArgs(int argc, char *argv[],
{"delaymount", 0, nullptr, 'M'}, // delay initial mount until use
{"public", 0, nullptr, 'P'}, // public mode
{"extpass", 1, nullptr, 'p'}, // external password program
{"exclude", 1, nullptr, 'e'}, // exclude from reverse
// {"single-thread", 0, 0, 's'}, // single-threaded mode
{"stdinpass", 0, nullptr, 'S'}, // read password from stdin
{"syslogtag", 1, nullptr, 't'}, // syslog tag
Expand Down Expand Up @@ -288,8 +291,9 @@ static bool processArgs(int argc, char *argv[],
// 't' : syslog tag
// 'c' : configuration file
// 'u' : unmount
// 'e' : exclude
int res =
getopt_long(argc, argv, "HsSfvdmi:o:t:c:u", long_options, &option_index);
getopt_long(argc, argv, "HsSfvdmi:e:o:t:c:u", long_options, &option_index);

if (res == -1) {
break;
Expand Down Expand Up @@ -321,7 +325,7 @@ static bool processArgs(int argc, char *argv[],
out->opts->insecure = true;
break;
case 'c':
/* Take config file path from command
/* Take config file path from command
* line instead of ENV variable */
out->opts->config.assign(optarg);
break;
Expand All @@ -341,6 +345,21 @@ static bool processArgs(int argc, char *argv[],
case 'd':
PUSHARG("-d");
break;
case 'e':
/* optarg contains a c-style string. Let's save it to an array
of c-style strings in excludeArgv, and count them in
excludeArgc */
if (out->opts->excludeArgc < MaxExcludeArgs) {
out->opts->excludeArgv[out->opts->excludeArgc++] = optarg;
if (out->isVerbose) {
cout << autosprintf(_("Excluding '%s'"), optarg) << "\n";
}
} else {
if (out->isVerbose) {
cout << autosprintf(_("Too many excludes. Omitting '%s'"), optarg) << "\n";
}
}
break;
case 'i':
out->idleTimeout = strtol(optarg, (char **)nullptr, 10);
out->opts->idleTracking = true;
Expand Down Expand Up @@ -463,6 +482,11 @@ static bool processArgs(int argc, char *argv[],
PUSHARG("-s");
}

if (out->opts->excludeArgc != 0 && out->opts->reverseEncryption == false) {
cerr << "Must specify --reverse if patterns are specified with --exclude\n";
return false;
}

// for --unmount, we should have exactly 1 argument - the mount point
if (out->opts->unmount) {
if (optind + 1 == argc) {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.