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::make_unique_ref;
using cpputils::Random; using cpputils::Random;
using cpputils::IOStreamConsole; using cpputils::IOStreamConsole;
using cpputils::TempFile;
using std::cout; using std::cout;
using std::string; using std::string;
using std::endl; using std::endl;
using std::vector; using std::vector;
using std::shared_ptr;
using std::make_shared;
using boost::none; using boost::none;
//TODO Support files > 4GB //TODO Support files > 4GB
@ -155,7 +158,39 @@ namespace cryfs {
if (!bf::exists(options.baseDir())) { if (!bf::exists(options.baseDir())) {
throw std::runtime_error("Base directory not found."); 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) { void Cli::_checkMountdirDoesntContainBasedir(const ProgramOptions &options) {
@ -194,5 +229,4 @@ namespace cryfs {
} }
return 0; return 0;
} }
} }

View File

@ -5,6 +5,7 @@
#include "program_options/ProgramOptions.h" #include "program_options/ProgramOptions.h"
#include "config/CryConfigFile.h" #include "config/CryConfigFile.h"
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <messmer/cpp-utils/tempfile/TempFile.h>
namespace cryfs { namespace cryfs {
class Cli final { class Cli final {
@ -24,6 +25,8 @@ namespace cryfs {
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 _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::Values;
using ::testing::WithParamInterface; using ::testing::WithParamInterface;
using std::vector; using std::vector;
using cpputils::TempFile;
struct TestConfig { struct TestConfig {
bool externalConfigfile; 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 //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> { class CliTest_WrongEnvironment: public CliTest, public WithParamInterface<TestConfig> {
public: public:
void RemoveReadPermission(const bf::path &dir) { void SetAllPermissions(const bf::path &dir) {
//TODO Take read permission from basedir in a better way bf::permissions(dir, bf::owner_write|bf::owner_read|bf::owner_exe);
system((std::string("chmod -rwx ")+dir.c_str()).c_str()); }
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() { void Test_Run_Success() {
@ -105,26 +121,34 @@ TEST_P(CliTest_WrongEnvironment, BaseDir_DoesntExist) {
Test_Run_Error("Error: Base directory not found"); 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) { TEST_P(CliTest_WrongEnvironment, BaseDir_NoReadPermission) {
RemoveReadPermission(basedir); SetNoReadPermission(basedir);
Test_Run_Error("Error: Base directory not readable"); Test_Run_Error("Error: Could not read from base directory");
} }
TEST_P(CliTest_WrongEnvironment, BaseDir_NoWritePermission) { TEST_P(CliTest_WrongEnvironment, BaseDir_NoWritePermission) {
RemoveWritePermission(basedir); SetNoWritePermission(basedir);
Test_Run_Error("Error: Base directory not writeable"); Test_Run_Error("Error: Could not write to base directory");
} }
TEST_P(CliTest_WrongEnvironment, BaseDir_NoAccessPermission) { TEST_P(CliTest_WrongEnvironment, BaseDir_NoExePermission) {
RemoveAccessPermission(basedir); SetNoExePermission(basedir);
Test_Run_Error("Error: Base directory not accessable"); Test_Run_Error("Error: Could not write to base directory");
} }
TEST_P(CliTest_WrongEnvironment, BaseDir_NoPermission) { TEST_P(CliTest_WrongEnvironment, BaseDir_NoPermission) {
RemoveAllPermissions(basedir); SetNoPermission(basedir);
Test_Run_Error("Error: Base directory not accessable"); Test_Run_Error("Error: Could not write to base directory");
} }
*/