mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-24 14:56:15 +02:00
Move FSInputAccessor into a separate file
This commit is contained in:
parent
55c63c9b89
commit
48012603b3
17 changed files with 183 additions and 159 deletions
|
@ -8,6 +8,7 @@
|
|||
#include "flake/flakeref.hh"
|
||||
#include "store-api.hh"
|
||||
#include "command.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "filetransfer.hh"
|
||||
#include "json.hh"
|
||||
#include "function-trace.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
|
|
@ -22,6 +22,7 @@ class EvalState;
|
|||
class StorePath;
|
||||
struct SourcePath;
|
||||
enum RepairFlag : bool;
|
||||
struct FSInputAccessor;
|
||||
|
||||
|
||||
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
||||
|
|
|
@ -639,6 +639,7 @@ formal
|
|||
#include "eval.hh"
|
||||
#include "filetransfer.hh"
|
||||
#include "fetchers.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "eval.hh"
|
||||
#include "util.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "value-to-json.hh"
|
||||
#include "value-to-xml.hh"
|
||||
#include "primops.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "fetchers.hh"
|
||||
#include "store-api.hh"
|
||||
#include "input-accessor.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
#include "types.hh"
|
||||
#include "hash.hh"
|
||||
#include "path.hh"
|
||||
#include "canon-path.hh"
|
||||
#include "attrs.hh"
|
||||
#include "url.hh"
|
||||
#include "input-accessor.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace nix { class Store; }
|
||||
namespace nix { class Store; class InputAccessor; }
|
||||
|
||||
namespace nix::fetchers {
|
||||
|
||||
|
|
140
src/libfetchers/fs-input-accessor.cc
Normal file
140
src/libfetchers/fs-input-accessor.cc
Normal file
|
@ -0,0 +1,140 @@
|
|||
#include "fs-input-accessor.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct FSInputAccessorImpl : FSInputAccessor
|
||||
{
|
||||
CanonPath root;
|
||||
std::optional<std::set<CanonPath>> allowedPaths;
|
||||
MakeNotAllowedError makeNotAllowedError;
|
||||
|
||||
FSInputAccessorImpl(
|
||||
const CanonPath & root,
|
||||
std::optional<std::set<CanonPath>> && allowedPaths,
|
||||
MakeNotAllowedError && makeNotAllowedError)
|
||||
: root(root)
|
||||
, allowedPaths(std::move(allowedPaths))
|
||||
, makeNotAllowedError(std::move(makeNotAllowedError))
|
||||
{
|
||||
displayPrefix = root.isRoot() ? "" : root.abs();
|
||||
}
|
||||
|
||||
std::string readFile(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
return nix::readFile(absPath.abs());
|
||||
}
|
||||
|
||||
bool pathExists(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
return isAllowed(absPath) && nix::pathExists(absPath.abs());
|
||||
}
|
||||
|
||||
Stat lstat(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
auto st = nix::lstat(absPath.abs());
|
||||
return Stat {
|
||||
.type =
|
||||
S_ISREG(st.st_mode) ? tRegular :
|
||||
S_ISDIR(st.st_mode) ? tDirectory :
|
||||
S_ISLNK(st.st_mode) ? tSymlink :
|
||||
tMisc,
|
||||
.isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR
|
||||
};
|
||||
}
|
||||
|
||||
DirEntries readDirectory(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
DirEntries res;
|
||||
for (auto & entry : nix::readDirectory(absPath.abs())) {
|
||||
std::optional<Type> type;
|
||||
switch (entry.type) {
|
||||
case DT_REG: type = Type::tRegular; break;
|
||||
case DT_LNK: type = Type::tSymlink; break;
|
||||
case DT_DIR: type = Type::tDirectory; break;
|
||||
}
|
||||
if (isAllowed(absPath + entry.name))
|
||||
res.emplace(entry.name, type);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string readLink(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
return nix::readLink(absPath.abs());
|
||||
}
|
||||
|
||||
CanonPath makeAbsPath(const CanonPath & path)
|
||||
{
|
||||
return root + path;
|
||||
}
|
||||
|
||||
void checkAllowed(const CanonPath & absPath) override
|
||||
{
|
||||
if (!isAllowed(absPath))
|
||||
throw makeNotAllowedError
|
||||
? makeNotAllowedError(absPath)
|
||||
: RestrictedPathError("access to path '%s' is forbidden", absPath);
|
||||
}
|
||||
|
||||
bool isAllowed(const CanonPath & absPath)
|
||||
{
|
||||
if (!absPath.isWithin(root))
|
||||
return false;
|
||||
|
||||
if (allowedPaths) {
|
||||
auto p = absPath.removePrefix(root);
|
||||
if (!p.isAllowed(*allowedPaths))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void allowPath(CanonPath path) override
|
||||
{
|
||||
if (allowedPaths)
|
||||
allowedPaths->insert(std::move(path));
|
||||
}
|
||||
|
||||
bool hasAccessControl() override
|
||||
{
|
||||
return (bool) allowedPaths;
|
||||
}
|
||||
|
||||
std::optional<CanonPath> getPhysicalPath(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
if (isAllowed(absPath))
|
||||
return absPath;
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
ref<FSInputAccessor> makeFSInputAccessor(
|
||||
const CanonPath & root,
|
||||
std::optional<std::set<CanonPath>> && allowedPaths,
|
||||
MakeNotAllowedError && makeNotAllowedError)
|
||||
{
|
||||
return make_ref<FSInputAccessorImpl>(root, std::move(allowedPaths), std::move(makeNotAllowedError));
|
||||
}
|
||||
|
||||
ref<FSInputAccessor> makeStorePathAccessor(
|
||||
ref<Store> store,
|
||||
const StorePath & storePath,
|
||||
MakeNotAllowedError && makeNotAllowedError)
|
||||
{
|
||||
return makeFSInputAccessor(CanonPath(store->toRealPath(storePath)), {}, std::move(makeNotAllowedError));
|
||||
}
|
||||
|
||||
}
|
29
src/libfetchers/fs-input-accessor.hh
Normal file
29
src/libfetchers/fs-input-accessor.hh
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include "input-accessor.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
class StorePath;
|
||||
class Store;
|
||||
|
||||
struct FSInputAccessor : InputAccessor
|
||||
{
|
||||
virtual void checkAllowed(const CanonPath & absPath) = 0;
|
||||
|
||||
virtual void allowPath(CanonPath path) = 0;
|
||||
|
||||
virtual bool hasAccessControl() = 0;
|
||||
};
|
||||
|
||||
ref<FSInputAccessor> makeFSInputAccessor(
|
||||
const CanonPath & root,
|
||||
std::optional<std::set<CanonPath>> && allowedPaths = {},
|
||||
MakeNotAllowedError && makeNotAllowedError = {});
|
||||
|
||||
ref<FSInputAccessor> makeStorePathAccessor(
|
||||
ref<Store> store,
|
||||
const StorePath & storePath,
|
||||
MakeNotAllowedError && makeNotAllowedError = {});
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
#include "pathlocks.hh"
|
||||
#include "util.hh"
|
||||
#include "git.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
#include "fetch-settings.hh"
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "git.hh"
|
||||
#include "fetchers.hh"
|
||||
#include "fetch-settings.hh"
|
||||
#include "input-accessor.hh"
|
||||
|
||||
#include <optional>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "input-accessor.hh"
|
||||
#include "util.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
|
@ -110,140 +109,6 @@ SourcePath InputAccessor::root()
|
|||
return {ref(shared_from_this()), CanonPath::root};
|
||||
}
|
||||
|
||||
struct FSInputAccessorImpl : FSInputAccessor
|
||||
{
|
||||
CanonPath root;
|
||||
std::optional<std::set<CanonPath>> allowedPaths;
|
||||
MakeNotAllowedError makeNotAllowedError;
|
||||
|
||||
FSInputAccessorImpl(
|
||||
const CanonPath & root,
|
||||
std::optional<std::set<CanonPath>> && allowedPaths,
|
||||
MakeNotAllowedError && makeNotAllowedError)
|
||||
: root(root)
|
||||
, allowedPaths(std::move(allowedPaths))
|
||||
, makeNotAllowedError(std::move(makeNotAllowedError))
|
||||
{
|
||||
displayPrefix = root.isRoot() ? "" : root.abs();
|
||||
}
|
||||
|
||||
std::string readFile(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
return nix::readFile(absPath.abs());
|
||||
}
|
||||
|
||||
bool pathExists(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
return isAllowed(absPath) && nix::pathExists(absPath.abs());
|
||||
}
|
||||
|
||||
Stat lstat(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
auto st = nix::lstat(absPath.abs());
|
||||
return Stat {
|
||||
.type =
|
||||
S_ISREG(st.st_mode) ? tRegular :
|
||||
S_ISDIR(st.st_mode) ? tDirectory :
|
||||
S_ISLNK(st.st_mode) ? tSymlink :
|
||||
tMisc,
|
||||
.isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR
|
||||
};
|
||||
}
|
||||
|
||||
DirEntries readDirectory(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
DirEntries res;
|
||||
for (auto & entry : nix::readDirectory(absPath.abs())) {
|
||||
std::optional<Type> type;
|
||||
switch (entry.type) {
|
||||
case DT_REG: type = Type::tRegular; break;
|
||||
case DT_LNK: type = Type::tSymlink; break;
|
||||
case DT_DIR: type = Type::tDirectory; break;
|
||||
}
|
||||
if (isAllowed(absPath + entry.name))
|
||||
res.emplace(entry.name, type);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string readLink(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
checkAllowed(absPath);
|
||||
return nix::readLink(absPath.abs());
|
||||
}
|
||||
|
||||
CanonPath makeAbsPath(const CanonPath & path)
|
||||
{
|
||||
return root + path;
|
||||
}
|
||||
|
||||
void checkAllowed(const CanonPath & absPath) override
|
||||
{
|
||||
if (!isAllowed(absPath))
|
||||
throw makeNotAllowedError
|
||||
? makeNotAllowedError(absPath)
|
||||
: RestrictedPathError("access to path '%s' is forbidden", absPath);
|
||||
}
|
||||
|
||||
bool isAllowed(const CanonPath & absPath)
|
||||
{
|
||||
if (!absPath.isWithin(root))
|
||||
return false;
|
||||
|
||||
if (allowedPaths) {
|
||||
auto p = absPath.removePrefix(root);
|
||||
if (!p.isAllowed(*allowedPaths))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void allowPath(CanonPath path) override
|
||||
{
|
||||
if (allowedPaths)
|
||||
allowedPaths->insert(std::move(path));
|
||||
}
|
||||
|
||||
bool hasAccessControl() override
|
||||
{
|
||||
return (bool) allowedPaths;
|
||||
}
|
||||
|
||||
std::optional<CanonPath> getPhysicalPath(const CanonPath & path) override
|
||||
{
|
||||
auto absPath = makeAbsPath(path);
|
||||
if (isAllowed(absPath))
|
||||
return absPath;
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
ref<FSInputAccessor> makeFSInputAccessor(
|
||||
const CanonPath & root,
|
||||
std::optional<std::set<CanonPath>> && allowedPaths,
|
||||
MakeNotAllowedError && makeNotAllowedError)
|
||||
{
|
||||
return make_ref<FSInputAccessorImpl>(root, std::move(allowedPaths), std::move(makeNotAllowedError));
|
||||
}
|
||||
|
||||
ref<FSInputAccessor> makeStorePathAccessor(
|
||||
ref<Store> store,
|
||||
const StorePath & storePath,
|
||||
MakeNotAllowedError && makeNotAllowedError)
|
||||
{
|
||||
return makeFSInputAccessor(CanonPath(store->toRealPath(storePath)), {}, std::move(makeNotAllowedError));
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
||||
{
|
||||
str << path.to_string();
|
||||
|
|
|
@ -10,8 +10,6 @@ namespace nix {
|
|||
MakeError(RestrictedPathError, Error);
|
||||
|
||||
struct SourcePath;
|
||||
class StorePath;
|
||||
class Store;
|
||||
|
||||
struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
||||
{
|
||||
|
@ -77,27 +75,8 @@ struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
|||
SourcePath root();
|
||||
};
|
||||
|
||||
struct FSInputAccessor : InputAccessor
|
||||
{
|
||||
virtual void checkAllowed(const CanonPath & absPath) = 0;
|
||||
|
||||
virtual void allowPath(CanonPath path) = 0;
|
||||
|
||||
virtual bool hasAccessControl() = 0;
|
||||
};
|
||||
|
||||
typedef std::function<RestrictedPathError(const CanonPath & path)> MakeNotAllowedError;
|
||||
|
||||
ref<FSInputAccessor> makeFSInputAccessor(
|
||||
const CanonPath & root,
|
||||
std::optional<std::set<CanonPath>> && allowedPaths = {},
|
||||
MakeNotAllowedError && makeNotAllowedError = {});
|
||||
|
||||
ref<FSInputAccessor> makeStorePathAccessor(
|
||||
ref<Store> store,
|
||||
const StorePath & storePath,
|
||||
MakeNotAllowedError && makeNotAllowedError = {});
|
||||
|
||||
struct SourcePath;
|
||||
|
||||
struct MemoryInputAccessor : InputAccessor
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "tarfile.hh"
|
||||
#include "store-api.hh"
|
||||
#include "url-parts.hh"
|
||||
|
||||
#include "fs-input-accessor.hh"
|
||||
#include "fetch-settings.hh"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "fetchers.hh"
|
||||
#include "store-api.hh"
|
||||
#include "archive.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
namespace nix::fetchers {
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "tarfile.hh"
|
||||
#include "types.hh"
|
||||
#include "split.hh"
|
||||
#include "fs-input-accessor.hh"
|
||||
|
||||
namespace nix::fetchers {
|
||||
|
||||
|
|
Loading…
Reference in a new issue