diff --git a/src/Cli.cpp b/src/Cli.cpp index c26e7fff..dd5e9278 100644 --- a/src/Cli.cpp +++ b/src/Cli.cpp @@ -37,10 +37,13 @@ using program_options::ProgramOptions; using cpputils::make_unique_ref; using cpputils::Random; using cpputils::IOStreamConsole; +using cpputils::TempFile; using std::cout; using std::string; using std::endl; using std::vector; +using std::shared_ptr; +using std::make_shared; using boost::none; //TODO Support files > 4GB @@ -155,7 +158,39 @@ namespace cryfs { if (!bf::exists(options.baseDir())) { throw std::runtime_error("Base directory not found."); } - //TODO Check permissions + if (!bf::is_directory(options.baseDir())) { + throw std::runtime_error("Base directory is not a directory."); + } + auto file = _checkBasedirWriteable(options); + _checkBasedirReadable(options, file); + } + + shared_ptr Cli::_checkBasedirWriteable(const ProgramOptions &options) { + auto path = bf::path(options.baseDir()) / "tempfile"; + try { + return make_shared(path); + } catch (const std::runtime_error &e) { + throw std::runtime_error("Could not write to base directory."); + } + } + + void Cli::_checkBasedirReadable(const ProgramOptions &options, shared_ptr tempfile) { + ASSERT(bf::path(options.baseDir()) == tempfile->path().parent_path(), "This function should be called with a file inside the base directory"); + try { + bool found = false; + bf::directory_iterator end; + for (auto iter = bf::directory_iterator(options.baseDir()); 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."); + } + } catch (const boost::filesystem::filesystem_error &e) { + throw std::runtime_error("Could not read from base directory."); + } } void Cli::_checkMountdirDoesntContainBasedir(const ProgramOptions &options) { @@ -194,5 +229,4 @@ namespace cryfs { } return 0; } - -} \ No newline at end of file +} diff --git a/src/Cli.h b/src/Cli.h index fed0d3d4..f32a2600 100644 --- a/src/Cli.h +++ b/src/Cli.h @@ -5,6 +5,7 @@ #include "program_options/ProgramOptions.h" #include "config/CryConfigFile.h" #include +#include namespace cryfs { class Cli final { @@ -24,6 +25,8 @@ namespace cryfs { 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 _checkBasedirWriteable(const program_options::ProgramOptions &options); + static void _checkBasedirReadable(const program_options::ProgramOptions &options, std::shared_ptr tempfile); }; } diff --git a/test/cli/CliTest_WrongEnvironment.cpp b/test/cli/CliTest_WrongEnvironment.cpp index 2e8791e0..87a02995 100644 --- a/test/cli/CliTest_WrongEnvironment.cpp +++ b/test/cli/CliTest_WrongEnvironment.cpp @@ -11,6 +11,7 @@ namespace bf = boost::filesystem; using ::testing::Values; using ::testing::WithParamInterface; using std::vector; +using cpputils::TempFile; struct TestConfig { bool externalConfigfile; @@ -21,9 +22,24 @@ struct TestConfig { //Tests what happens if cryfs is run in the wrong environment, i.e. with a base directory that doesn't exist or similar class CliTest_WrongEnvironment: public CliTest, public WithParamInterface { public: - void RemoveReadPermission(const bf::path &dir) { - //TODO Take read permission from basedir in a better way - system((std::string("chmod -rwx ")+dir.c_str()).c_str()); + void SetAllPermissions(const bf::path &dir) { + bf::permissions(dir, bf::owner_write|bf::owner_read|bf::owner_exe); + } + + void SetNoReadPermission(const bf::path &dir) { + bf::permissions(dir, bf::owner_write|bf::owner_exe); + } + + void SetNoWritePermission(const bf::path &dir) { + bf::permissions(dir, bf::owner_read|bf::owner_exe); + } + + void SetNoExePermission(const bf::path &dir) { + bf::permissions(dir, bf::owner_read|bf::owner_write); + } + + void SetNoPermission(const bf::path &dir) { + bf::permissions(dir, bf::no_perms); } void Test_Run_Success() { @@ -105,26 +121,34 @@ TEST_P(CliTest_WrongEnvironment, BaseDir_DoesntExist) { Test_Run_Error("Error: Base directory not found"); } -//TODO finish the following test cases -/* +TEST_P(CliTest_WrongEnvironment, BaseDir_IsNotDirectory) { + TempFile basedirfile; + basedir = basedirfile.path(); + Test_Run_Error("Error: Base directory is not a directory"); +} + +TEST_P(CliTest_WrongEnvironment, BaseDir_AllPermissions) { + //Counter-Test. Test it doesn't fail if permissions are there. + SetAllPermissions(basedir); + Test_Run_Success(); +} + TEST_P(CliTest_WrongEnvironment, BaseDir_NoReadPermission) { - RemoveReadPermission(basedir); - Test_Run_Error("Error: Base directory not readable"); + SetNoReadPermission(basedir); + Test_Run_Error("Error: Could not read from base directory"); } TEST_P(CliTest_WrongEnvironment, BaseDir_NoWritePermission) { - RemoveWritePermission(basedir); - Test_Run_Error("Error: Base directory not writeable"); + SetNoWritePermission(basedir); + Test_Run_Error("Error: Could not write to base directory"); } -TEST_P(CliTest_WrongEnvironment, BaseDir_NoAccessPermission) { - RemoveAccessPermission(basedir); - Test_Run_Error("Error: Base directory not accessable"); +TEST_P(CliTest_WrongEnvironment, BaseDir_NoExePermission) { + SetNoExePermission(basedir); + Test_Run_Error("Error: Could not write to base directory"); } TEST_P(CliTest_WrongEnvironment, BaseDir_NoPermission) { - RemoveAllPermissions(basedir); - Test_Run_Error("Error: Base directory not accessable"); + SetNoPermission(basedir); + Test_Run_Error("Error: Could not write to base directory"); } - -*/