Add sanity checks for mount directory

This commit is contained in:
Sebastian Messmer 2015-10-30 22:01:42 +01:00
parent fdf866a562
commit 6bbdc1be3d
3 changed files with 64 additions and 34 deletions

View File

@ -149,53 +149,53 @@ namespace cryfs {
}
void Cli::_sanityChecks(const ProgramOptions &options) {
_checkBasedirAccessible(options);
//TODO Check MountdirAccessible (incl. Permissions)
_checkDirAccessible(options.baseDir(), "base directory");
_checkDirAccessible(options.mountDir(), "mount directory");
_checkMountdirDoesntContainBasedir(options);
}
void Cli::_checkBasedirAccessible(const ProgramOptions &options) {
if (!bf::exists(options.baseDir())) {
throw std::runtime_error("Base directory not found.");
void Cli::_checkDirAccessible(const bf::path &dir, const std::string &name) {
if (!bf::exists(dir)) {
throw std::runtime_error(name+" not found.");
}
if (!bf::is_directory(options.baseDir())) {
throw std::runtime_error("Base directory is not a directory.");
if (!bf::is_directory(dir)) {
throw std::runtime_error(name+" is not a directory.");
}
auto file = _checkBasedirWriteable(options);
_checkBasedirReadable(options, file);
auto file = _checkDirWriteable(dir, name);
_checkDirReadable(dir, file, name);
}
shared_ptr<TempFile> Cli::_checkBasedirWriteable(const ProgramOptions &options) {
auto path = bf::path(options.baseDir()) / "tempfile";
shared_ptr<TempFile> Cli::_checkDirWriteable(const bf::path &dir, const std::string &name) {
auto path = dir / "tempfile";
try {
return make_shared<TempFile>(path);
} catch (const std::runtime_error &e) {
throw std::runtime_error("Could not write to base directory.");
throw std::runtime_error("Could not write to "+name+".");
}
}
void Cli::_checkBasedirReadable(const ProgramOptions &options, shared_ptr<TempFile> tempfile) {
ASSERT(bf::equivalent(bf::path(options.baseDir()), tempfile->path().parent_path()), "This function should be called with a file inside the base directory");
void Cli::_checkDirReadable(const bf::path &dir, shared_ptr<TempFile> tempfile, const std::string &name) {
ASSERT(bf::equivalent(dir, tempfile->path().parent_path()), "This function should be called with a file inside the directory");
try {
bool found = false;
bf::directory_iterator end;
for (auto iter = bf::directory_iterator(options.baseDir()); iter != end; ++iter) {
for (auto iter = bf::directory_iterator(dir); iter != end; ++iter) {
if (bf::equivalent(*iter, tempfile->path())) {
found = true;
}
}
if (!found) {
//This should not happen. Can only happen if the written temp file got deleted inbetween or maybe was not written at all.
throw std::runtime_error("Error accessing base directory.");
throw std::runtime_error("Error accessing "+name+".");
}
} catch (const boost::filesystem::filesystem_error &e) {
throw std::runtime_error("Could not read from base directory.");
throw std::runtime_error("Could not read from "+name+".");
}
}
void Cli::_checkMountdirDoesntContainBasedir(const ProgramOptions &options) {
if (_pathContains(options.mountDir(), options.baseDir())) {
throw std::runtime_error("Base directory can't be inside the mount directory.");
throw std::runtime_error("base directory can't be inside the mount directory.");
}
}

View File

@ -23,9 +23,9 @@ namespace cryfs {
static void _sanityChecks(const program_options::ProgramOptions &options);
static void _checkMountdirDoesntContainBasedir(const program_options::ProgramOptions &options);
static bool _pathContains(const boost::filesystem::path &parent, const boost::filesystem::path &child);
static void _checkBasedirAccessible(const program_options::ProgramOptions &options);
static std::shared_ptr<cpputils::TempFile> _checkBasedirWriteable(const program_options::ProgramOptions &options);
static void _checkBasedirReadable(const program_options::ProgramOptions &options, std::shared_ptr<cpputils::TempFile> tempfile);
static void _checkDirAccessible(const boost::filesystem::path &dir, const std::string &name);
static std::shared_ptr<cpputils::TempFile> _checkDirWriteable(const boost::filesystem::path &dir, const std::string &name);
static void _checkDirReadable(const boost::filesystem::path &dir, std::shared_ptr<cpputils::TempFile> tempfile, const std::string &name);
};
}

View File

@ -1,12 +1,5 @@
#include "testutils/CliTest.h"
//TODO Test CLI ends with error message (before daemonization), if
// - mountdir does not exist
// - mountdir exists but belongs to other user
// - mountdir exists but is missing permissions
// - TODO when else is libfuse failing? What requirements are there for the mountdir?)
namespace bf = boost::filesystem;
using ::testing::Values;
using ::testing::WithParamInterface;
@ -86,7 +79,7 @@ TEST_P(CliTest_WrongEnvironment, NoErrorCondition) {
TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir) {
mountdir = basedir;
Test_Run_Error("Error: Base directory can't be inside the mount directory");
Test_Run_Error("Error: base directory can't be inside the mount directory");
}
bf::path make_relative(const bf::path &path) {
@ -101,30 +94,30 @@ bf::path make_relative(const bf::path &path) {
TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_MountDirRelative) {
mountdir = make_relative(basedir);
Test_Run_Error("Error: Base directory can't be inside the mount directory");
Test_Run_Error("Error: base directory can't be inside the mount directory");
}
TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_BaseDirRelative) {
mountdir = basedir;
basedir = make_relative(basedir);
Test_Run_Error("Error: Base directory can't be inside the mount directory");
Test_Run_Error("Error: base directory can't be inside the mount directory");
}
TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_BothRelative) {
basedir = make_relative(basedir);
mountdir = basedir;
Test_Run_Error("Error: Base directory can't be inside the mount directory");
Test_Run_Error("Error: base directory can't be inside the mount directory");
}
TEST_P(CliTest_WrongEnvironment, BaseDir_DoesntExist) {
_basedir.remove();
Test_Run_Error("Error: Base directory not found");
Test_Run_Error("Error: base directory not found");
}
TEST_P(CliTest_WrongEnvironment, BaseDir_IsNotDirectory) {
TempFile basedirfile;
basedir = basedirfile.path();
Test_Run_Error("Error: Base directory is not a directory");
Test_Run_Error("Error: base directory is not a directory");
}
TEST_P(CliTest_WrongEnvironment, BaseDir_AllPermissions) {
@ -152,3 +145,40 @@ TEST_P(CliTest_WrongEnvironment, BaseDir_NoPermission) {
SetNoPermission(basedir);
Test_Run_Error("Error: Could not write to base directory");
}
TEST_P(CliTest_WrongEnvironment, MountDir_DoesntExist) {
_mountdir.remove();
Test_Run_Error("Error: mount directory not found");
}
TEST_P(CliTest_WrongEnvironment, MountDir_IsNotDirectory) {
TempFile mountdirfile;
mountdir = mountdirfile.path();
Test_Run_Error("Error: mount directory is not a directory");
}
TEST_P(CliTest_WrongEnvironment, MountDir_AllPermissions) {
//Counter-Test. Test it doesn't fail if permissions are there.
SetAllPermissions(mountdir);
Test_Run_Success();
}
TEST_P(CliTest_WrongEnvironment, MountDir_NoReadPermission) {
SetNoReadPermission(mountdir);
Test_Run_Error("Error: Could not read from mount directory");
}
TEST_P(CliTest_WrongEnvironment, MountDir_NoWritePermission) {
SetNoWritePermission(mountdir);
Test_Run_Error("Error: Could not write to mount directory");
}
TEST_P(CliTest_WrongEnvironment, MountDir_NoExePermission) {
SetNoExePermission(mountdir);
Test_Run_Error("Error: Could not write to mount directory");
}
TEST_P(CliTest_WrongEnvironment, MountDir_NoPermission) {
SetNoPermission(mountdir);
Test_Run_Error("Error: Could not write to mount directory");
}