Check that base directory is not inside mount directory

This commit is contained in:
Sebastian Messmer 2015-10-30 17:23:08 +01:00
parent b7af7ca2f2
commit a37c1af761
6 changed files with 84 additions and 16 deletions

View File

@ -25,6 +25,8 @@
#error The used libc implementation has a maximal password size for getpass(). We cannot use it to ask for passwords.
#endif
//TODO Many functions accessing the ProgramOptions object. Factor out into class that stores it as a member.
using namespace cryfs;
namespace bf = boost::filesystem;
@ -144,9 +146,40 @@ namespace cryfs {
}
void Cli::_sanityChecks(const ProgramOptions &options) {
if (bf::path(options.baseDir()) == bf::path(options.mountDir())) {
throw std::runtime_error("Can't mount into base directory");
_checkBasedirAccessible(options);
//TODO Check MountdirAccessible (incl. Permissions)
_checkMountdirDoesntContainBasedir(options);
}
void Cli::_checkBasedirAccessible(const ProgramOptions &options) {
if (!bf::exists(options.baseDir())) {
throw std::runtime_error("Base directory not found.");
}
//TODO Check permissions
}
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.");
}
}
bool Cli::_pathContains(const bf::path &parent, const bf::path &child) {
bf::path absParent = bf::canonical(parent);
bf::path current = bf::canonical(child);
if (absParent.empty() && current.empty()) {
return true;
}
while(!current.empty()) {
std::cout << absParent.c_str() << " cmp " << current.c_str() << std::endl;
if (bf::equivalent(current, absParent)) {
std::cout << "equals" << std::endl;
return true;
}
std::cout << "not equals" << std::endl;
current = current.parent_path();
}
return false;
}
int Cli::main(int argc, char *argv[]) {

View File

@ -21,6 +21,9 @@ namespace cryfs {
static void _showVersion();
static void _initLogfile(const program_options::ProgramOptions &options);
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);
};
}

View File

@ -6,24 +6,24 @@ using cpputils::TempFile;
using CliTest_Setup = CliTest;
TEST_F(CliTest_Setup, NoSpecialOptions) {
EXPECT_RUN_SUCCESS({basedir->path().c_str(), mountdir->path().c_str()});
EXPECT_RUN_SUCCESS({basedir.c_str(), mountdir.c_str()});
}
TEST_F(CliTest_Setup, NotexistingLogfileGiven) {
TempFile notexisting_logfile(false);
EXPECT_RUN_SUCCESS({basedir->path().c_str(), mountdir->path().c_str(), "--logfile", notexisting_logfile.path().c_str()});
EXPECT_RUN_SUCCESS({basedir.c_str(), mountdir.c_str(), "--logfile", notexisting_logfile.path().c_str()});
//TODO Expect logfile is used (check logfile content)
}
TEST_F(CliTest_Setup, ExistingLogfileGiven) {
EXPECT_RUN_SUCCESS({basedir->path().c_str(), mountdir->path().c_str(), "--logfile", logfile.path().c_str()});
EXPECT_RUN_SUCCESS({basedir.c_str(), mountdir.c_str(), "--logfile", logfile.path().c_str()});
//TODO Expect logfile is used (check logfile content)
}
TEST_F(CliTest_Setup, ConfigfileGiven) {
EXPECT_RUN_SUCCESS({"/home/user/baseDir", "--config", configfile.path().c_str(), "/home/user/mountDir"});
EXPECT_RUN_SUCCESS({basedir.c_str(), "--config", configfile.path().c_str(), mountdir.c_str()});
}
TEST_F(CliTest_Setup, FuseOptionGiven) {
EXPECT_RUN_SUCCESS({"/home/user/baseDir", "/home/user/mountDir", "--", "-f"});
EXPECT_RUN_SUCCESS({basedir.c_str(), mountdir.c_str(), "--", "-f"});
}

View File

@ -7,7 +7,7 @@ TEST_F(CliTest_ShowingHelp, HelpLongOption) {
}
TEST_F(CliTest_ShowingHelp, HelpLongOptionTogetherWithOtherOptions) {
EXPECT_EXIT_WITH_HELP_MESSAGE({basedir->path().c_str(), mountdir->path().c_str(), "--help"});
EXPECT_EXIT_WITH_HELP_MESSAGE({basedir.c_str(), mountdir.c_str(), "--help"});
}
TEST_F(CliTest_ShowingHelp, HelpShortOption) {
@ -15,7 +15,7 @@ TEST_F(CliTest_ShowingHelp, HelpShortOption) {
}
TEST_F(CliTest_ShowingHelp, HelpShortOptionTogetherWithOtherOptions) {
EXPECT_EXIT_WITH_HELP_MESSAGE({basedir->path().c_str(), mountdir->path().c_str(), "-h"});
EXPECT_EXIT_WITH_HELP_MESSAGE({basedir.c_str(), mountdir.c_str(), "-h"});
}
TEST_F(CliTest_ShowingHelp, MissingAllOptions) {
@ -23,5 +23,5 @@ TEST_F(CliTest_ShowingHelp, MissingAllOptions) {
}
TEST_F(CliTest_ShowingHelp, MissingDir) {
EXPECT_EXIT_WITH_HELP_MESSAGE({basedir->path().c_str()});
EXPECT_EXIT_WITH_HELP_MESSAGE({basedir.c_str()});
}

View File

@ -38,7 +38,7 @@ public:
}
vector<const char*> args() {
vector<const char*> result = {basedir->path().c_str(), mountdir->path().c_str()};
vector<const char*> result = {basedir.c_str(), mountdir.c_str()};
if (GetParam().externalConfigfile) {
result.push_back("--config");
result.push_back(configfile.path().c_str());
@ -70,11 +70,41 @@ TEST_P(CliTest_WrongEnvironment, NoErrorCondition) {
TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir) {
mountdir = basedir;
Test_Run_Error("Error: Can't mount into base directory");
Test_Run_Error("Error: Base directory can't be inside the mount directory");
}
bf::path make_relative(const bf::path &path) {
bf::path result;
bf::path cwd = bf::current_path();
for(auto iter = ++cwd.begin(); iter!=cwd.end(); ++iter) {
result /= "..";
}
result /= path;
return result;
}
TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_MountDirRelative) {
mountdir = make_relative(basedir);
std::cout << basedir.c_str() << " --- " << mountdir.c_str();
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);
std::cout << basedir.c_str() << " --- " << mountdir.c_str();
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;
std::cout << basedir.c_str() << " --- " << mountdir.c_str();
Test_Run_Error("Error: Base directory can't be inside the mount directory");
}
TEST_P(CliTest_WrongEnvironment, BaseDir_DoesntExist) {
basedir->remove();
_basedir.remove();
Test_Run_Error("Error: Base directory not found");
}

View File

@ -9,10 +9,12 @@
class CliTest : public ::testing::Test {
public:
CliTest(): basedir(std::make_shared<cpputils::TempDir>()), mountdir(std::make_shared<cpputils::TempDir>()), logfile(), configfile(false) {}
CliTest(): _basedir(), _mountdir(), basedir(_basedir.path()), mountdir(_mountdir.path()), logfile(), configfile(false) {}
std::shared_ptr<cpputils::TempDir> basedir;
std::shared_ptr<cpputils::TempDir> mountdir;
cpputils::TempDir _basedir;
cpputils::TempDir _mountdir;
boost::filesystem::path basedir;
boost::filesystem::path mountdir;
cpputils::TempFile logfile;
cpputils::TempFile configfile;