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 "flake/flakeref.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "command.hh"
|
#include "command.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "json.hh"
|
#include "json.hh"
|
||||||
#include "function-trace.hh"
|
#include "function-trace.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
|
@ -22,6 +22,7 @@ class EvalState;
|
||||||
class StorePath;
|
class StorePath;
|
||||||
struct SourcePath;
|
struct SourcePath;
|
||||||
enum RepairFlag : bool;
|
enum RepairFlag : bool;
|
||||||
|
struct FSInputAccessor;
|
||||||
|
|
||||||
|
|
||||||
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
||||||
|
|
|
@ -639,6 +639,7 @@ formal
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "value-to-json.hh"
|
#include "value-to-json.hh"
|
||||||
#include "value-to-xml.hh"
|
#include "value-to-xml.hh"
|
||||||
#include "primops.hh"
|
#include "primops.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "input-accessor.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "hash.hh"
|
#include "hash.hh"
|
||||||
#include "path.hh"
|
#include "path.hh"
|
||||||
|
#include "canon-path.hh"
|
||||||
#include "attrs.hh"
|
#include "attrs.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
#include "input-accessor.hh"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace nix { class Store; }
|
namespace nix { class Store; class InputAccessor; }
|
||||||
|
|
||||||
namespace nix::fetchers {
|
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 "pathlocks.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "git.hh"
|
#include "git.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
|
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "git.hh"
|
#include "git.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
|
#include "input-accessor.hh"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "input-accessor.hh"
|
#include "input-accessor.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "store-api.hh"
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
@ -110,140 +109,6 @@ SourcePath InputAccessor::root()
|
||||||
return {ref(shared_from_this()), CanonPath::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)
|
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
||||||
{
|
{
|
||||||
str << path.to_string();
|
str << path.to_string();
|
||||||
|
|
|
@ -10,8 +10,6 @@ namespace nix {
|
||||||
MakeError(RestrictedPathError, Error);
|
MakeError(RestrictedPathError, Error);
|
||||||
|
|
||||||
struct SourcePath;
|
struct SourcePath;
|
||||||
class StorePath;
|
|
||||||
class Store;
|
|
||||||
|
|
||||||
struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
||||||
{
|
{
|
||||||
|
@ -77,27 +75,8 @@ struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
||||||
SourcePath root();
|
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;
|
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 SourcePath;
|
||||||
|
|
||||||
struct MemoryInputAccessor : InputAccessor
|
struct MemoryInputAccessor : InputAccessor
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "tarfile.hh"
|
#include "tarfile.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "url-parts.hh"
|
#include "url-parts.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
|
|
||||||
namespace nix::fetchers {
|
namespace nix::fetchers {
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "tarfile.hh"
|
#include "tarfile.hh"
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "split.hh"
|
#include "split.hh"
|
||||||
|
#include "fs-input-accessor.hh"
|
||||||
|
|
||||||
namespace nix::fetchers {
|
namespace nix::fetchers {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue