Access Check

Usage

 1#pragma once
 2
 3#include <erbsland/conf/AccessCheck.hpp>
 4#include <erbsland/conf/Error.hpp>
 5
 6#include <filesystem>
 7#include <memory>
 8
 9using el::conf::AccessSources;
10using el::conf::AccessCheckResult;
11using el::conf::Error;
12using el::conf::ErrorCategory;
13
14class MyAccessCheck final : public el::conf::AccessCheck {
15public:
16    explicit MyAccessCheck(std::filesystem::path sandbox) : _sandbox{std::move(sandbox)} {};
17    ~MyAccessCheck() override = default;
18    static auto create(std::filesystem::path sandbox) -> std::shared_ptr<MyAccessCheck> {
19        return std::make_shared<MyAccessCheck>(std::move(sandbox));
20    }
21
22public:
23    auto check(const AccessSources &sources) -> AccessCheckResult override {
24        try {
25            if (sources.source == nullptr || sources.source->name() != u8"text") {}
26            auto sourcePath = std::filesystem::path{sources.source->path().toCharString()};
27            auto canonicalSource = canonical(sourcePath).string();
28            auto canonicalSandbox = canonical(_sandbox).string();
29            if (!canonicalSource.starts_with(canonicalSandbox)) {
30                return AccessCheckResult::Denied;
31            }
32            return AccessCheckResult::Granted;
33        } catch (const std::system_error &error) {
34            throw Error(ErrorCategory::Access, u8"System error", error.code());
35        }
36    }
37
38private:
39    std::filesystem::path _sandbox;
40};

Interface

class AccessCheck

The interface to access check implementations.

Subclassed by erbsland::conf::FileAccessCheck

Public Functions

virtual ~AccessCheck() = default

Default destructor.

virtual AccessCheckResult check(const AccessSources &sources) = 0

The check function is called for every source, including the initial source that is passed to the parse() function call. You can either grant or deny access to this source. If you deny the access to the source, the parser will throw an Error with ErrorCategory::Access.

Instead of returning AccessResult::Denied, you can also throw an Error with ErrorCategory::Access.

Not Tested:

This is part of Parser

Parameters:

sources – The sources that are verified.

Throws:

Error – Alternatively, throw an Error with the ErrorCategory::Access.

Returns:

Return either AccessResult::Granted or AccessResult::Denied.

struct AccessSources

The source identifiers to verify in the access function.

This structure names the individual source elements for the access function.

Not Tested:

This is part of Parser

Public Members

SourceIdentifierPtr source

The source to verify.

SourceIdentifierPtr parent

The parent source that resolved this new source or nullptr if source is the root document.

SourceIdentifierPtr root

The root document. The root document is always present.

enum class erbsland::conf::AccessCheckResult : uint8_t

The result of an access check.

Not Tested:

This is part of Parser

Values:

enumerator Granted

If the access is granted.

enumerator Denied

If the access is denied.

using erbsland::conf::AccessCheckPtr = std::shared_ptr<AccessCheck>
class FileAccessCheck : public erbsland::conf::AccessCheck

A basic file access check.

By default, the CanonicalizePath, SameDirectory, Subdirectories features are activated.

  • If neither SameDirectory, Subdirectories or AnyDirectory is set, all file sources are rejected.

  • If a file is included from a non-file source and AnyDirectory is not set, the source is rejected.

Public Types

enum Feature

The feature flags controlling file access restrictions.

Values:

enumerator SameDirectory

Allow included sources to be in the same directory as the including document (recommended, default).

    Example: If the including document has the path `config/main.elcl` documents that are in the directory
    `config`, like `config/other.elcl` are accepted.

    If this feature is disabled, documents in the same directory as the including document are rejected.

enumerator Subdirectories

Allow included sources in subdirectories of the parent document (recommended, default).

    Example: If the including document has the path `config/main.elcl` documents that are in subdirectories of
    `config`, like `config/sub/other.elcl` are accepted.

    If this feature is disabled, documents in subdirectories of the including document are rejected.

enumerator AnyDirectory

Not Recommended: Allow included sources in any directory.

    Included sources can be anywhere in the filesystem and on shares. Paths can point anywhere.

enumerator OnlyFileSources

Only allow file sources and reject everything else.

    If this feature is enabled, this access check only accepts file sources. Sources of any other type
    e.g. "text" sources are rejected. If this feature is disabled, which is the default, this check only
    focuses on "file" sources and grants access to any other sources.

    Granting non-file source is designed to allow chaining multiple checks.

enumerator LimitSize

Limit the maximum size of a file to 100MB (recommended, default).

enumerator RequireSuffix

Only allow file sources with an .elcl suffix.

    If this feature is set, this access check only accepts file sources with an `.elcl` suffix.

enumerator _featureCount

Public Functions

FileAccessCheck() = default

Default constructor.

~FileAccessCheck() override = default

Default destructor.

void enable(Feature feature)

Enable a feature.

void disable(Feature feature)

Disable a feature

bool isEnabled(Feature feature) const noexcept

Test if a feature is enabled.

virtual AccessCheckResult check(const AccessSources &sources) override

The check function is called for every source, including the initial source that is passed to the parse() function call. You can either grant or deny access to this source. If you deny the access to the source, the parser will throw an Error with ErrorCategory::Access.

Instead of returning AccessResult::Denied, you can also throw an Error with ErrorCategory::Access.

Not Tested:

This is part of Parser

Parameters:

sources – The sources that are verified.

Throws:

Error – Alternatively, throw an Error with the ErrorCategory::Access.

Returns:

Return either AccessResult::Granted or AccessResult::Denied.

Public Static Functions

static inline FileAccessCheckPtr create()

Create a custom file access check instance.

using erbsland::conf::FileAccessCheckPtr = std::shared_ptr<FileAccessCheck>