lix/src/libstore/store-api.cc
Eelco Dolstra 765bdfe542 * When NIX_REMOTE is set to "slave", fork off nix-worker in slave
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.
2006-11-30 19:54:43 +00:00

116 lines
2.7 KiB
C++

#include "store-api.hh"
#include "globals.hh"
#include "util.hh"
namespace nix {
bool isInStore(const Path & path)
{
return path[0] == '/'
&& string(path, 0, nixStore.size()) == nixStore
&& path.size() >= nixStore.size() + 2
&& path[nixStore.size()] == '/';
}
bool isStorePath(const Path & path)
{
return isInStore(path)
&& path.find('/', nixStore.size() + 1) == Path::npos;
}
void assertStorePath(const Path & path)
{
if (!isStorePath(path))
throw Error(format("path `%1%' is not in the Nix store") % path);
}
Path toStorePath(const Path & path)
{
if (!isInStore(path))
throw Error(format("path `%1%' is not in the Nix store") % path);
Path::size_type slash = path.find('/', nixStore.size() + 1);
if (slash == Path::npos)
return path;
else
return Path(path, 0, slash);
}
void checkStoreName(const string & name)
{
string validChars = "+-._?=";
/* Disallow names starting with a dot for possible security
reasons (e.g., "." and ".."). */
if (string(name, 0, 1) == ".")
throw Error(format("illegal name: `%1%'") % name);
for (string::const_iterator i = name.begin(); i != name.end(); ++i)
if (!((*i >= 'A' && *i <= 'Z') ||
(*i >= 'a' && *i <= 'z') ||
(*i >= '0' && *i <= '9') ||
validChars.find(*i) != string::npos))
{
throw Error(format("invalid character `%1%' in name `%2%'")
% *i % name);
}
}
Path makeStorePath(const string & type,
const Hash & hash, const string & suffix)
{
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
string s = type + ":sha256:" + printHash(hash) + ":"
+ nixStore + ":" + suffix;
checkStoreName(suffix);
return nixStore + "/"
+ printHash32(compressHash(hashString(htSHA256, s), 20))
+ "-" + suffix;
}
Path makeFixedOutputPath(bool recursive,
string hashAlgo, Hash hash, string name)
{
/* !!! copy/paste from primops.cc */
Hash h = hashString(htSHA256, "fixed:out:"
+ (recursive ? (string) "r:" : "") + hashAlgo + ":"
+ printHash(hash) + ":"
+ "");
return makeStorePath("output:out", h, name);
}
}
#include "local-store.hh"
#include "serialise.hh"
#include "remote-store.hh"
namespace nix {
boost::shared_ptr<StoreAPI> store;
boost::shared_ptr<StoreAPI> openStore(bool reserveSpace)
{
string mode = getEnv("NIX_REMOTE");
if (mode == "")
return boost::shared_ptr<StoreAPI>(new LocalStore(reserveSpace));
else if (mode == "slave")
return boost::shared_ptr<StoreAPI>(new RemoteStore());
else throw Error(format("invalid setting for NIX_REMOTE, `%1%'") % mode);
}
}