forked from lix-project/lix
765bdfe542
mode. Presumably nix-worker would be setuid to the Nix store user. The worker performs all operations on the Nix store and database, so the caller can be completely unprivileged. This is already much more secure than the old setuid scheme, since the worker doesn't need to do Nix expression evaluation and so on. Most importantly, this means that it doesn't need to access any user files, with all resulting security risks; it only performs pure store operations. Once this works, it is easy to move to a daemon model that forks off a worker for connections established through a Unix domain socket. That would be even more secure.
135 lines
2.5 KiB
C++
135 lines
2.5 KiB
C++
#include "serialise.hh"
|
|
#include "util.hh"
|
|
#include "remote-store.hh"
|
|
|
|
#include <iostream>
|
|
#include <unistd.h>
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
RemoteStore::RemoteStore()
|
|
{
|
|
toChild.create();
|
|
fromChild.create();
|
|
|
|
|
|
/* Start the worker. */
|
|
string worker = "nix-worker";
|
|
|
|
child = fork();
|
|
|
|
switch (child) {
|
|
|
|
case -1:
|
|
throw SysError("unable to fork");
|
|
|
|
case 0:
|
|
try { /* child */
|
|
|
|
fromChild.readSide.close();
|
|
if (dup2(fromChild.writeSide, STDOUT_FILENO) == -1)
|
|
throw SysError("dupping write side");
|
|
|
|
toChild.writeSide.close();
|
|
if (dup2(toChild.readSide, STDIN_FILENO) == -1)
|
|
throw SysError("dupping read side");
|
|
|
|
execlp(worker.c_str(), worker.c_str(),
|
|
"-vvv", "--slave", NULL);
|
|
|
|
throw SysError(format("executing `%1%'") % worker);
|
|
|
|
} catch (std::exception & e) {
|
|
std::cerr << format("child error: %1%\n") % e.what();
|
|
}
|
|
quickExit(1);
|
|
}
|
|
|
|
fromChild.writeSide.close();
|
|
toChild.readSide.close();
|
|
|
|
from.fd = fromChild.readSide;
|
|
to.fd = toChild.writeSide;
|
|
|
|
|
|
/* Send the magic greeting, check for the reply. */
|
|
writeInt(0x6e697864, to);
|
|
|
|
unsigned int magic = readInt(from);
|
|
if (magic != 0x6478696e) throw Error("protocol mismatch");
|
|
}
|
|
|
|
|
|
RemoteStore::~RemoteStore()
|
|
{
|
|
}
|
|
|
|
|
|
bool RemoteStore::isValidPath(const Path & path)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
Substitutes RemoteStore::querySubstitutes(const Path & srcPath)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
Hash RemoteStore::queryPathHash(const Path & path)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
void RemoteStore::queryReferences(const Path & storePath,
|
|
PathSet & references)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
void RemoteStore::queryReferrers(const Path & storePath,
|
|
PathSet & referrers)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
Path RemoteStore::addToStore(const Path & srcPath)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
Path RemoteStore::addToStoreFixed(bool recursive, string hashAlgo,
|
|
const Path & srcPath)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
Path RemoteStore::addTextToStore(const string & suffix, const string & s,
|
|
const PathSet & references)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
void RemoteStore::buildDerivations(const PathSet & drvPaths)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
void RemoteStore::ensurePath(const Path & storePath)
|
|
{
|
|
throw Error("not implemented");
|
|
}
|
|
|
|
|
|
}
|