40    ifstream 
file(file_name, ios::in);
 
   41    if (!
file.is_open()) {
 
 
   52    return (::stat(path.c_str(), &statbuf) == 0);
 
 
   58    if (::stat(path.c_str(), &statbuf) < 0) {
 
   62    return (statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
 
 
   73    if (::stat(path.c_str(), &statbuf) < 0) {
 
   76    return ((statbuf.st_mode & S_IFMT) == S_IFDIR);
 
 
   82    if (::stat(path.c_str(), &statbuf) < 0) {
 
   85    return ((statbuf.st_mode & S_IFMT) == S_IFREG);
 
 
   91    if (::stat(path.c_str(), &statbuf) < 0) {
 
   94    return ((statbuf.st_mode & S_IFMT) == S_IFSOCK);
 
 
  100    mode_t mask(S_IWGRP | S_IRWXO);
 
  101    mode_t orig = umask(mask);
 
  103    if ((orig | mask) != mask) {
 
  104        static_cast<void>(umask(orig | mask));
 
 
  109    return (getuid() == 0 || geteuid() == 0);
 
 
  113    dir_present_ = 
false;
 
  114    if (!full_name.empty()) {
 
  116        size_t last_slash = full_name.find_last_of(
'/');
 
  117        if (last_slash != string::npos) {
 
  123            parent_path_ = full_name.substr(0, last_slash);
 
  124            if (last_slash == full_name.size()) {
 
  132        size_t last_dot = full_name.find_last_of(
'.');
 
  133        if ((last_dot == string::npos) || (dir_present_ && (last_dot < last_slash))) {
 
  138            stem_ = full_name.substr(last_slash + 1);
 
  144        extension_ = full_name.substr(last_dot);
 
  147        if ((last_dot - last_slash) > 1) {
 
  148            stem_ = full_name.substr(last_slash + 1, last_dot - last_slash - 1);
 
 
  155    return (parent_path_ + (dir_present_ ? 
"/" : 
"") + stem_ + extension_);
 
 
  160    return (parent_path_);
 
 
  165    return (parent_path_ + (dir_present_ ? 
"/" : 
""));
 
 
  180    return (stem_ + extension_);
 
 
  185    string const trimmed_replacement(
trim(replacement));
 
  186    if (trimmed_replacement.empty()) {
 
  187        extension_ = string();
 
  189        size_t const last_dot(trimmed_replacement.find_last_of(
'.'));
 
  190        if (last_dot == string::npos) {
 
  191            extension_ = 
"." + trimmed_replacement;
 
  193            extension_ = trimmed_replacement.substr(last_dot);
 
 
  201    string const trimmed_replacement(
trim(replacement));
 
  202    dir_present_ = (trimmed_replacement.find_last_of(
'/') != string::npos);
 
  203    if (trimmed_replacement.empty() || (trimmed_replacement == 
"/")) {
 
  204        parent_path_ = string();
 
  205    } 
else if (trimmed_replacement.at(trimmed_replacement.size() - 1) == 
'/') {
 
  206        parent_path_ = trimmed_replacement.substr(0, trimmed_replacement.size() - 1);
 
  208        parent_path_ = trimmed_replacement;
 
 
  214    char dir[](
"/tmp/kea-tmpdir-XXXXXX");
 
  215    char const* dir_name = mkdtemp(dir);
 
  219    dir_name_ = string(dir_name);
 
 
  223    DIR *dir(opendir(dir_name_.c_str()));
 
  228    std::unique_ptr<DIR, void(*)(DIR*)> defer(dir, [](DIR* d) { closedir(d); });
 
  232    while ((i = readdir(dir))) {
 
  233        if (strcmp(i->d_name, 
".") == 0 || strcmp(i->d_name, 
"..") == 0) {
 
  237        filepath = dir_name_ + 
'/' + i->d_name;
 
  238        remove(filepath.c_str());
 
  241    rmdir(dir_name_.c_str());
 
 
  249                             const std::string env_name )
 
  250    : default_path_(default_path), env_name_(env_name),
 
  251      default_overridden_(false) {
 
 
  257                     const std::string explicit_path ) {
 
  259        if (!explicit_path.empty()) {
 
  260            path_ = explicit_path;
 
  261        } 
else if (!env_name_.empty()) {
 
  262            path_ = std::string(std::getenv(env_name_.c_str()) ?
 
  263                                std::getenv(env_name_.c_str()) : default_path_);
 
  265            path_ = default_path_;
 
  270        while (!path_.empty() && path_.back() == 
'/') {
 
  274        default_overridden_ = (path_ != default_path_);
 
 
  282                          bool enforce_path )
 const {
 
  283    Path input_path(
trim(input_path_str));
 
  284    auto filename = input_path.
filename();
 
  285    if (filename.empty()) {
 
  291    if (!parent_dir.empty()) {
 
  293        if ((parent_path != path_) || (parent_dir == 
"/")) {
 
  294            std::ostringstream oss;
 
  295            oss << 
"invalid path specified: '" 
  296                << (parent_path.empty() ? 
"/" : parent_path)
 
  297                << 
"', supported path is '" 
  308    std::string valid_path(path_ + 
"/" +  filename);
 
 
  314                               bool enforce_path )
 const {
 
  315    std::string input_copy = 
trim(input_path_str);
 
  317    if (!input_path_str.empty()) {
 
  318        std::string input_copy = input_path_str;
 
  319        while (!input_copy.empty() && input_copy.back() == 
'/') {
 
  320               input_copy.pop_back();
 
  323        if (input_copy != path_) {
 
  324            std::ostringstream oss;
 
  325            oss << 
"invalid path specified: '" 
  326                << input_path_str << 
"', supported path is '" 
 
  348    return (default_overridden_);
 
 
  352    return (enforce_security_);
 
 
  356    enforce_security_ = enable;
 
 
  359bool PathChecker::enforce_security_ = 
true;
 
 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when an unexpected error condition occurs.
std::string getPath(bool reset=false, const std::string explicit_path="")
Fetches the supported path.
static bool shouldEnforceSecurity()
Indicates security checks should be enforced.
PathChecker(const std::string default_path, const std::string env_name="")
Constructor.
bool isDefaultOverridden()
Indicates if the default path has been overridden.
static void enableEnforcement(bool enable)
Enables or disables security enforcment checks.
std::string validateDirectory(const std::string input_path_str, bool enforce_path=shouldEnforceSecurity()) const
Validates a directory against a supported path.
bool pathHasPermissions(mode_t permissions, bool enforce_perms=shouldEnforceSecurity()) const
Check if the path has expected permissions.
std::string validatePath(const std::string input_path_str, bool enforce_path=shouldEnforceSecurity()) const
Validates a file path against a supported path.
A generic exception that is thrown if a parameter given violates security and enforcement is true.
A generic exception that is thrown if a parameter given violates security check but enforcement is la...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
bool amRunningAsRoot()
Indicates if current user is root.
bool isSocket(string const &path)
Check if there is a socket at the given path.
string getContent(string const &file_name)
Get the content of a regular file.
bool isFile(string const &path)
Check if there is a file at the given path.
bool exists(string const &path)
Check if there is a file or directory at the given path.
bool isDir(string const &path)
Check if there is a directory at the given path.
mode_t getPermissions(const std::string path)
Fetches the file permissions mask.
bool hasPermissions(const std::string path, const mode_t &permissions)
Check if there if file or directory has the given permissions.
void setUmask()
Set umask (at least 0027 i.e. no group write and no other access).
string trim(const string &input)
Trim leading and trailing spaces.
Defines the logger used by the top-level component of kea-lfc.
Path(std::string const &path)
Constructor.
Path & replaceParentPath(std::string const &replacement=std::string())
Trims {replacement} and replaces this instance's parent path with it.
std::string parentDirectory() const
Get the parent directory.
std::string extension() const
Get the extension of the file.
Path & replaceExtension(std::string const &replacement=std::string())
Identifies the extension in {replacement}, trims it, and replaces this instance's extension with it.
std::string stem() const
Get the base name of the file without the extension.
std::string parentPath() const
Get the parent path.
std::string filename() const
Get the name of the file, extension included.
std::string str() const
Get the path in textual format.