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) { void Cli::_sanityChecks(const ProgramOptions &options) {
_checkBasedirAccessible(options); _checkDirAccessible(options.baseDir(), "base directory");
//TODO Check MountdirAccessible (incl. Permissions) _checkDirAccessible(options.mountDir(), "mount directory");
_checkMountdirDoesntContainBasedir(options); _checkMountdirDoesntContainBasedir(options);
} }
void Cli::_checkBasedirAccessible(const ProgramOptions &options) { void Cli::_checkDirAccessible(const bf::path &dir, const std::string &name) {
if (!bf::exists(options.baseDir())) { if (!bf::exists(dir)) {
throw std::runtime_error("Base directory not found."); throw std::runtime_error(name+" not found.");
} }
if (!bf::is_directory(options.baseDir())) { if (!bf::is_directory(dir)) {
throw std::runtime_error("Base directory is not a directory."); throw std::runtime_error(name+" is not a directory.");
} }
auto file = _checkBasedirWriteable(options); auto file = _checkDirWriteable(dir, name);
_checkBasedirReadable(options, file); _checkDirReadable(dir, file, name);
} }
shared_ptr<TempFile> Cli::_checkBasedirWriteable(const ProgramOptions &options) { shared_ptr<TempFile> Cli::_checkDirWriteable(const bf::path &dir, const std::string &name) {
auto path = bf::path(options.baseDir()) / "tempfile"; auto path = dir / "tempfile";
try { try {
return make_shared<TempFile>(path); return make_shared<TempFile>(path);
} catch (const std::runtime_error &e) { } 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) { void Cli::_checkDirReadable(const bf::path &dir, shared_ptr<TempFile> tempfile, const std::string &name) {
ASSERT(bf::equivalent(bf::path(options.baseDir()), tempfile->path().parent_path()), "This function should be called with a file inside the base directory"); ASSERT(bf::equivalent(dir, tempfile->path().parent_path()), "This function should be called with a file inside the directory");
try { try {
bool found = false; bool found = false;
bf::directory_iterator end; 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())) { if (bf::equivalent(*iter, tempfile->path())) {
found = true; found = true;
} }
} }
if (!found) { if (!found) {
//This should not happen. Can only happen if the written temp file got deleted inbetween or maybe was not written at all. //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) { } 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) { void Cli::_checkMountdirDoesntContainBasedir(const ProgramOptions &options) {
if (_pathContains(options.mountDir(), options.baseDir())) { 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 _sanityChecks(const program_options::ProgramOptions &options);
static void _checkMountdirDoesntContainBasedir(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 bool _pathContains(const boost::filesystem::path &parent, const boost::filesystem::path &child);
static void _checkBasedirAccessible(const program_options::ProgramOptions &options); static void _checkDirAccessible(const boost::filesystem::path &dir, const std::string &name);
static std::shared_ptr<cpputils::TempFile> _checkBasedirWriteable(const program_options::ProgramOptions &options); static std::shared_ptr<cpputils::TempFile> _checkDirWriteable(const boost::filesystem::path &dir, const std::string &name);
static void _checkBasedirReadable(const program_options::ProgramOptions &options, std::shared_ptr<cpputils::TempFile> tempfile); 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" #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; namespace bf = boost::filesystem;
using ::testing::Values; using ::testing::Values;
using ::testing::WithParamInterface; using ::testing::WithParamInterface;
@ -86,7 +79,7 @@ TEST_P(CliTest_WrongEnvironment, NoErrorCondition) {
TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir) { TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir) {
mountdir = 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");
} }
bf::path make_relative(const bf::path &path) { 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) { TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_MountDirRelative) {
mountdir = make_relative(basedir); 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) { TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_BaseDirRelative) {
mountdir = basedir; mountdir = basedir;
basedir = make_relative(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) { TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_BothRelative) {
basedir = make_relative(basedir); basedir = make_relative(basedir);
mountdir = 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) { TEST_P(CliTest_WrongEnvironment, BaseDir_DoesntExist) {
_basedir.remove(); _basedir.remove();
Test_Run_Error("Error: Base directory not found"); Test_Run_Error("Error: base directory not found");
} }
TEST_P(CliTest_WrongEnvironment, BaseDir_IsNotDirectory) { TEST_P(CliTest_WrongEnvironment, BaseDir_IsNotDirectory) {
TempFile basedirfile; TempFile basedirfile;
basedir = basedirfile.path(); 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) { TEST_P(CliTest_WrongEnvironment, BaseDir_AllPermissions) {
@ -152,3 +145,40 @@ TEST_P(CliTest_WrongEnvironment, BaseDir_NoPermission) {
SetNoPermission(basedir); SetNoPermission(basedir);
Test_Run_Error("Error: Could not write to base directory"); 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");
}