On startup, check read/write permissions for base directory and fail if permissions missing

This commit is contained in:
Sebastian Messmer 2015-10-30 18:28:33 +01:00
parent cdbbad8878
commit d731ecf6a6
3 changed files with 80 additions and 19 deletions

View File

@ -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<TempFile> Cli::_checkBasedirWriteable(const ProgramOptions &options) {
auto path = bf::path(options.baseDir()) / "tempfile";
try {
return make_shared<TempFile>(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> 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;
}
}
}

View File

@ -5,6 +5,7 @@
#include "program_options/ProgramOptions.h"
#include "config/CryConfigFile.h"
#include <boost/filesystem/path.hpp>
#include <messmer/cpp-utils/tempfile/TempFile.h>
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<cpputils::TempFile> _checkBasedirWriteable(const program_options::ProgramOptions &options);
static void _checkBasedirReadable(const program_options::ProgramOptions &options, std::shared_ptr<cpputils::TempFile> tempfile);
};
}

View File

@ -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<TestConfig> {
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");
}
*/