Remove OpenSSL-based signing
This commit is contained in:
parent
dfebfc835f
commit
f435f82475
16 changed files with 52 additions and 142 deletions
|
@ -168,10 +168,6 @@ AC_SUBST(storedir)
|
||||||
|
|
||||||
|
|
||||||
# Look for OpenSSL, a required dependency.
|
# Look for OpenSSL, a required dependency.
|
||||||
AC_PATH_PROG(openssl, openssl, openssl) # if not found, call openssl in $PATH
|
|
||||||
AC_SUBST(openssl)
|
|
||||||
AC_DEFINE_UNQUOTED(OPENSSL_PATH, ["$openssl"], [Path of the OpenSSL binary])
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES([OPENSSL], [libcrypto], [CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"])
|
PKG_CHECK_MODULES([OPENSSL], [libcrypto], [CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ $storeDir = $ENV{"NIX_STORE_DIR"} || "@storedir@";
|
||||||
$bzip2 = "@bzip2@";
|
$bzip2 = "@bzip2@";
|
||||||
$xz = "@xz@";
|
$xz = "@xz@";
|
||||||
$curl = "@curl@";
|
$curl = "@curl@";
|
||||||
$openssl = "@openssl@";
|
|
||||||
|
|
||||||
$useBindings = "@perlbindings@" eq "yes";
|
$useBindings = "@perlbindings@" eq "yes";
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use IPC::Open2;
|
||||||
|
|
||||||
|
|
||||||
sub copyToOpen {
|
sub copyToOpen {
|
||||||
my ($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes) = @_;
|
my ($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes) = @_;
|
||||||
|
|
||||||
$useSubstitutes = 0 if $dryRun || !defined $useSubstitutes;
|
$useSubstitutes = 0 if $dryRun || !defined $useSubstitutes;
|
||||||
|
|
||||||
|
@ -41,13 +41,13 @@ sub copyToOpen {
|
||||||
|
|
||||||
# Send the "import paths" command.
|
# Send the "import paths" command.
|
||||||
syswrite($to, pack("L<x4", 4)) or die;
|
syswrite($to, pack("L<x4", 4)) or die;
|
||||||
exportPaths(fileno($to), $sign, @missing);
|
exportPaths(fileno($to), @missing);
|
||||||
readInt($from) == 1 or die "remote machine ‘$sshHost’ failed to import closure\n";
|
readInt($from) == 1 or die "remote machine ‘$sshHost’ failed to import closure\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub copyTo {
|
sub copyTo {
|
||||||
my ($sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes) = @_;
|
my ($sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes) = @_;
|
||||||
|
|
||||||
# Connect to the remote host.
|
# Connect to the remote host.
|
||||||
my ($from, $to);
|
my ($from, $to);
|
||||||
|
@ -61,7 +61,7 @@ sub copyTo {
|
||||||
return oldCopyTo(@_);
|
return oldCopyTo(@_);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyToOpen($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes);
|
copyToOpen($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes);
|
||||||
|
|
||||||
close $to;
|
close $to;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ sub copyTo {
|
||||||
# For backwards compatibility with Nix <= 1.7. Will be removed
|
# For backwards compatibility with Nix <= 1.7. Will be removed
|
||||||
# eventually.
|
# eventually.
|
||||||
sub oldCopyTo {
|
sub oldCopyTo {
|
||||||
my ($sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes) = @_;
|
my ($sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes) = @_;
|
||||||
|
|
||||||
# Get the closure of this path.
|
# Get the closure of this path.
|
||||||
my @closure = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs,
|
my @closure = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs,
|
||||||
|
@ -105,7 +105,7 @@ sub oldCopyTo {
|
||||||
print STDERR "copying ", scalar @missing, " missing paths to ‘$sshHost’...\n";
|
print STDERR "copying ", scalar @missing, " missing paths to ‘$sshHost’...\n";
|
||||||
unless ($dryRun) {
|
unless ($dryRun) {
|
||||||
open SSH, "| ssh $sshHost @globalSshOpts 'nix-store --import' > /dev/null" or die;
|
open SSH, "| ssh $sshHost @globalSshOpts 'nix-store --import' > /dev/null" or die;
|
||||||
exportPaths(fileno(SSH), $sign, @missing);
|
exportPaths(fileno(SSH), @missing);
|
||||||
close SSH or die "copying store paths to remote machine ‘$sshHost’ failed: $?";
|
close SSH or die "copying store paths to remote machine ‘$sshHost’ failed: $?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,13 +169,13 @@ SV * followLinksToStorePath(char * path)
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
|
|
||||||
void exportPaths(int fd, int sign, ...)
|
void exportPaths(int fd, ...)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
Paths paths;
|
Paths paths;
|
||||||
for (int n = 2; n < items; ++n) paths.push_back(SvPV_nolen(ST(n)));
|
for (int n = 2; n < items; ++n) paths.push_back(SvPV_nolen(ST(n)));
|
||||||
FdSink sink(fd);
|
FdSink sink(fd);
|
||||||
store()->exportPaths(paths, sign, sink);
|
store()->exportPaths(paths, sink);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
croak("%s", e.what());
|
croak("%s", e.what());
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ void importPaths(int fd)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
FdSource source(fd);
|
FdSource source(fd);
|
||||||
store()->importPaths(false, source, 0);
|
store()->importPaths(source, 0);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
croak("%s", e.what());
|
croak("%s", e.what());
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,10 +223,6 @@ my @inputs = split /\s/, readline(STDIN);
|
||||||
my @outputs = split /\s/, readline(STDIN);
|
my @outputs = split /\s/, readline(STDIN);
|
||||||
|
|
||||||
|
|
||||||
my $maybeSign = "";
|
|
||||||
$maybeSign = "--sign" if -e "$Nix::Config::confDir/signing-key.sec";
|
|
||||||
|
|
||||||
|
|
||||||
# Copy the derivation and its dependencies to the build machine. This
|
# Copy the derivation and its dependencies to the build machine. This
|
||||||
# is guarded by an exclusive lock per machine to prevent multiple
|
# is guarded by an exclusive lock per machine to prevent multiple
|
||||||
# build-remote instances from copying to a machine simultaneously.
|
# build-remote instances from copying to a machine simultaneously.
|
||||||
|
@ -250,7 +246,7 @@ if ($@) {
|
||||||
print STDERR "somebody is hogging $uploadLock, continuing...\n";
|
print STDERR "somebody is hogging $uploadLock, continuing...\n";
|
||||||
unlink $uploadLock;
|
unlink $uploadLock;
|
||||||
}
|
}
|
||||||
Nix::CopyClosure::copyToOpen($from, $to, $hostName, [ $drvPath, @inputs ], 0, 0, $maybeSign ne "");
|
Nix::CopyClosure::copyToOpen($from, $to, $hostName, [ $drvPath, @inputs ], 0, 0);
|
||||||
close UPLOADLOCK;
|
close UPLOADLOCK;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ binmode STDERR, ":encoding(utf8)";
|
||||||
|
|
||||||
if (scalar @ARGV < 1) {
|
if (scalar @ARGV < 1) {
|
||||||
print STDERR <<EOF
|
print STDERR <<EOF
|
||||||
Usage: nix-copy-closure [--from | --to] HOSTNAME [--sign] [--gzip] [--bzip2] [--xz] PATHS...
|
Usage: nix-copy-closure [--from | --to] HOSTNAME [--gzip] [--bzip2] [--xz] PATHS...
|
||||||
EOF
|
EOF
|
||||||
;
|
;
|
||||||
exit 1;
|
exit 1;
|
||||||
|
@ -21,7 +21,6 @@ EOF
|
||||||
|
|
||||||
# Get the target host.
|
# Get the target host.
|
||||||
my $sshHost;
|
my $sshHost;
|
||||||
my $sign = 0;
|
|
||||||
my $toMode = 1;
|
my $toMode = 1;
|
||||||
my $includeOutputs = 0;
|
my $includeOutputs = 0;
|
||||||
my $dryRun = 0;
|
my $dryRun = 0;
|
||||||
|
@ -38,9 +37,6 @@ while (@ARGV) {
|
||||||
if ($arg eq "--help") {
|
if ($arg eq "--help") {
|
||||||
exec "man nix-copy-closure" or die;
|
exec "man nix-copy-closure" or die;
|
||||||
}
|
}
|
||||||
elsif ($arg eq "--sign") {
|
|
||||||
$sign = 1;
|
|
||||||
}
|
|
||||||
elsif ($arg eq "--gzip" || $arg eq "--bzip2" || $arg eq "--xz") {
|
elsif ($arg eq "--gzip" || $arg eq "--bzip2" || $arg eq "--xz") {
|
||||||
warn "$0: ‘$arg’ is not implemented\n" if $arg ne "--gzip";
|
warn "$0: ‘$arg’ is not implemented\n" if $arg ne "--gzip";
|
||||||
push @globalSshOpts, "-C";
|
push @globalSshOpts, "-C";
|
||||||
|
@ -81,7 +77,7 @@ die "$0: you did not specify a host name\n" unless defined $sshHost;
|
||||||
if ($toMode) { # Copy TO the remote machine.
|
if ($toMode) { # Copy TO the remote machine.
|
||||||
Nix::CopyClosure::copyTo(
|
Nix::CopyClosure::copyTo(
|
||||||
$sshHost, [ @storePaths ],
|
$sshHost, [ @storePaths ],
|
||||||
$includeOutputs, $dryRun, $sign, $useSubstitutes);
|
$includeOutputs, $dryRun, $useSubstitutes);
|
||||||
}
|
}
|
||||||
|
|
||||||
else { # Copy FROM the remote machine.
|
else { # Copy FROM the remote machine.
|
||||||
|
@ -99,7 +95,7 @@ else { # Copy FROM the remote machine.
|
||||||
if (scalar @missing > 0) {
|
if (scalar @missing > 0) {
|
||||||
print STDERR "copying ", scalar @missing, " missing paths from ‘$sshHost’...\n";
|
print STDERR "copying ", scalar @missing, " missing paths from ‘$sshHost’...\n";
|
||||||
writeInt(5, $to); # == cmdExportPaths
|
writeInt(5, $to); # == cmdExportPaths
|
||||||
writeInt($sign ? 1 : 0, $to);
|
writeInt(0, $to); # obsolete
|
||||||
writeStrings(\@missing, $to);
|
writeStrings(\@missing, $to);
|
||||||
importPaths(fileno($from));
|
importPaths(fileno($from));
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,10 +156,8 @@ void BinaryCacheStore::narFromPath(const Path & storePath, Sink & sink)
|
||||||
sink((unsigned char *) nar->c_str(), nar->size());
|
sink((unsigned char *) nar->c_str(), nar->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinaryCacheStore::exportPath(const Path & storePath, bool sign, Sink & sink)
|
void BinaryCacheStore::exportPath(const Path & storePath, Sink & sink)
|
||||||
{
|
{
|
||||||
assert(!sign);
|
|
||||||
|
|
||||||
auto res = queryPathInfo(storePath);
|
auto res = queryPathInfo(storePath);
|
||||||
|
|
||||||
narFromPath(storePath, sink);
|
narFromPath(storePath, sink);
|
||||||
|
@ -169,10 +167,9 @@ void BinaryCacheStore::exportPath(const Path & storePath, bool sign, Sink & sink
|
||||||
sink << exportMagic << storePath << res->references << res->deriver << 0;
|
sink << exportMagic << storePath << res->references << res->deriver << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths BinaryCacheStore::importPaths(bool requireSignature, Source & source,
|
Paths BinaryCacheStore::importPaths(Source & source,
|
||||||
std::shared_ptr<FSAccessor> accessor)
|
std::shared_ptr<FSAccessor> accessor)
|
||||||
{
|
{
|
||||||
assert(!requireSignature);
|
|
||||||
Paths res;
|
Paths res;
|
||||||
while (true) {
|
while (true) {
|
||||||
unsigned long long n = readLongLong(source);
|
unsigned long long n = readLongLong(source);
|
||||||
|
@ -346,7 +343,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor
|
||||||
if (i != nars.end()) return {i->second, restPath};
|
if (i != nars.end()) return {i->second, restPath};
|
||||||
|
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
store->exportPath(storePath, false, sink);
|
store->exportPath(storePath, sink);
|
||||||
|
|
||||||
auto accessor = makeNarAccessor(sink.s);
|
auto accessor = makeNarAccessor(sink.s);
|
||||||
nars.emplace(storePath, accessor);
|
nars.emplace(storePath, accessor);
|
||||||
|
|
|
@ -91,9 +91,9 @@ public:
|
||||||
|
|
||||||
void narFromPath(const Path & path, Sink & sink) override;
|
void narFromPath(const Path & path, Sink & sink) override;
|
||||||
|
|
||||||
void exportPath(const Path & path, bool sign, Sink & sink) override;
|
void exportPath(const Path & path, Sink & sink) override;
|
||||||
|
|
||||||
Paths importPaths(bool requireSignature, Source & source,
|
Paths importPaths(Source & source,
|
||||||
std::shared_ptr<FSAccessor> accessor) override;
|
std::shared_ptr<FSAccessor> accessor) override;
|
||||||
|
|
||||||
Path importPath(Source & source, std::shared_ptr<FSAccessor> accessor);
|
Path importPath(Source & source, std::shared_ptr<FSAccessor> accessor);
|
||||||
|
|
|
@ -1035,18 +1035,7 @@ struct HashAndWriteSink : Sink
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void checkSecrecy(const Path & path)
|
void LocalStore::exportPath(const Path & path, Sink & sink)
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
if (stat(path.c_str(), &st))
|
|
||||||
throw SysError(format("getting status of ‘%1%’") % path);
|
|
||||||
if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0)
|
|
||||||
throw Error(format("file ‘%1%’ should be secret (inaccessible to everybody else)!") % path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LocalStore::exportPath(const Path & path, bool sign,
|
|
||||||
Sink & sink)
|
|
||||||
{
|
{
|
||||||
assertStorePath(path);
|
assertStorePath(path);
|
||||||
|
|
||||||
|
@ -1068,30 +1057,7 @@ void LocalStore::exportPath(const Path & path, bool sign,
|
||||||
|
|
||||||
hashAndWriteSink << exportMagic << path << info->references << info->deriver;
|
hashAndWriteSink << exportMagic << path << info->references << info->deriver;
|
||||||
|
|
||||||
if (sign) {
|
hashAndWriteSink << 0; // backwards compatibility
|
||||||
Hash hash = hashAndWriteSink.currentHash();
|
|
||||||
|
|
||||||
Path tmpDir = createTempDir();
|
|
||||||
AutoDelete delTmp(tmpDir);
|
|
||||||
Path hashFile = tmpDir + "/hash";
|
|
||||||
writeFile(hashFile, printHash(hash));
|
|
||||||
|
|
||||||
Path secretKey = settings.nixConfDir + "/signing-key.sec";
|
|
||||||
checkSecrecy(secretKey);
|
|
||||||
|
|
||||||
Strings args;
|
|
||||||
args.push_back("rsautl");
|
|
||||||
args.push_back("-sign");
|
|
||||||
args.push_back("-inkey");
|
|
||||||
args.push_back(secretKey);
|
|
||||||
args.push_back("-in");
|
|
||||||
args.push_back(hashFile);
|
|
||||||
string signature = runProgram(OPENSSL_PATH, true, args);
|
|
||||||
|
|
||||||
hashAndWriteSink << 1 << signature;
|
|
||||||
|
|
||||||
} else
|
|
||||||
hashAndWriteSink << 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1129,7 +1095,7 @@ Path LocalStore::createTempDirInStore()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path LocalStore::importPath(bool requireSignature, Source & source)
|
Path LocalStore::importPath(Source & source)
|
||||||
{
|
{
|
||||||
HashAndReadSource hashAndReadSource(source);
|
HashAndReadSource hashAndReadSource(source);
|
||||||
|
|
||||||
|
@ -1160,36 +1126,9 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
|
||||||
|
|
||||||
bool haveSignature = readInt(hashAndReadSource) == 1;
|
bool haveSignature = readInt(hashAndReadSource) == 1;
|
||||||
|
|
||||||
if (requireSignature && !haveSignature)
|
if (haveSignature)
|
||||||
throw Error(format("imported archive of ‘%1%’ lacks a signature") % dstPath);
|
// Ignore legacy signature.
|
||||||
|
readString(hashAndReadSource);
|
||||||
if (haveSignature) {
|
|
||||||
string signature = readString(hashAndReadSource);
|
|
||||||
|
|
||||||
if (requireSignature) {
|
|
||||||
Path sigFile = tmpDir + "/sig";
|
|
||||||
writeFile(sigFile, signature);
|
|
||||||
|
|
||||||
Strings args;
|
|
||||||
args.push_back("rsautl");
|
|
||||||
args.push_back("-verify");
|
|
||||||
args.push_back("-inkey");
|
|
||||||
args.push_back(settings.nixConfDir + "/signing-key.pub");
|
|
||||||
args.push_back("-pubin");
|
|
||||||
args.push_back("-in");
|
|
||||||
args.push_back(sigFile);
|
|
||||||
string hash2 = runProgram(OPENSSL_PATH, true, args);
|
|
||||||
|
|
||||||
/* Note: runProgram() throws an exception if the signature
|
|
||||||
is invalid. */
|
|
||||||
|
|
||||||
if (printHash(hash) != hash2)
|
|
||||||
throw Error(
|
|
||||||
"signed hash doesn't match actual contents of imported "
|
|
||||||
"archive; archive could be corrupt, or someone is trying "
|
|
||||||
"to import a Trojan horse");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do the actual import. */
|
/* Do the actual import. */
|
||||||
|
|
||||||
|
@ -1239,7 +1178,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Paths LocalStore::importPaths(bool requireSignature, Source & source,
|
Paths LocalStore::importPaths(Source & source,
|
||||||
std::shared_ptr<FSAccessor> accessor)
|
std::shared_ptr<FSAccessor> accessor)
|
||||||
{
|
{
|
||||||
Paths res;
|
Paths res;
|
||||||
|
@ -1247,7 +1186,7 @@ Paths LocalStore::importPaths(bool requireSignature, Source & source,
|
||||||
unsigned long long n = readLongLong(source);
|
unsigned long long n = readLongLong(source);
|
||||||
if (n == 0) break;
|
if (n == 0) break;
|
||||||
if (n != 1) throw Error("input doesn't look like something created by ‘nix-store --export’");
|
if (n != 1) throw Error("input doesn't look like something created by ‘nix-store --export’");
|
||||||
res.push_back(importPath(requireSignature, source));
|
res.push_back(importPath(source));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,10 +126,9 @@ public:
|
||||||
Path addTextToStore(const string & name, const string & s,
|
Path addTextToStore(const string & name, const string & s,
|
||||||
const PathSet & references, bool repair = false) override;
|
const PathSet & references, bool repair = false) override;
|
||||||
|
|
||||||
void exportPath(const Path & path, bool sign,
|
void exportPath(const Path & path, Sink & sink) override;
|
||||||
Sink & sink) override;
|
|
||||||
|
|
||||||
Paths importPaths(bool requireSignature, Source & source,
|
Paths importPaths(Source & source,
|
||||||
std::shared_ptr<FSAccessor> accessor) override;
|
std::shared_ptr<FSAccessor> accessor) override;
|
||||||
|
|
||||||
void buildPaths(const PathSet & paths, BuildMode buildMode) override;
|
void buildPaths(const PathSet & paths, BuildMode buildMode) override;
|
||||||
|
@ -230,7 +229,7 @@ private:
|
||||||
|
|
||||||
Path createTempDirInStore();
|
Path createTempDirInStore();
|
||||||
|
|
||||||
Path importPath(bool requireSignature, Source & source);
|
Path importPath(Source & source);
|
||||||
|
|
||||||
void checkDerivationOutputs(const Path & drvPath, const Derivation & drv);
|
void checkDerivationOutputs(const Path & drvPath, const Derivation & drv);
|
||||||
|
|
||||||
|
|
|
@ -373,23 +373,20 @@ Path RemoteStore::addTextToStore(const string & name, const string & s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RemoteStore::exportPath(const Path & path, bool sign,
|
void RemoteStore::exportPath(const Path & path, Sink & sink)
|
||||||
Sink & sink)
|
|
||||||
{
|
{
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
conn->to << wopExportPath << path << (sign ? 1 : 0);
|
conn->to << wopExportPath << path << 0;
|
||||||
conn->processStderr(&sink); /* sink receives the actual data */
|
conn->processStderr(&sink); /* sink receives the actual data */
|
||||||
readInt(conn->from);
|
readInt(conn->from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Paths RemoteStore::importPaths(bool requireSignature, Source & source,
|
Paths RemoteStore::importPaths(Source & source,
|
||||||
std::shared_ptr<FSAccessor> accessor)
|
std::shared_ptr<FSAccessor> accessor)
|
||||||
{
|
{
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
conn->to << wopImportPaths;
|
conn->to << wopImportPaths;
|
||||||
/* We ignore requireSignature, since the worker forces it to true
|
|
||||||
anyway. */
|
|
||||||
conn->processStderr(0, &source);
|
conn->processStderr(0, &source);
|
||||||
return readStorePaths<Paths>(conn->from);
|
return readStorePaths<Paths>(conn->from);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,10 +58,9 @@ public:
|
||||||
Path addTextToStore(const string & name, const string & s,
|
Path addTextToStore(const string & name, const string & s,
|
||||||
const PathSet & references, bool repair = false) override;
|
const PathSet & references, bool repair = false) override;
|
||||||
|
|
||||||
void exportPath(const Path & path, bool sign,
|
void exportPath(const Path & path, Sink & sink) override;
|
||||||
Sink & sink) override;
|
|
||||||
|
|
||||||
Paths importPaths(bool requireSignature, Source & source,
|
Paths importPaths(Source & source,
|
||||||
std::shared_ptr<FSAccessor> accessor) override;
|
std::shared_ptr<FSAccessor> accessor) override;
|
||||||
|
|
||||||
void buildPaths(const PathSet & paths, BuildMode buildMode) override;
|
void buildPaths(const PathSet & paths, BuildMode buildMode) override;
|
||||||
|
|
|
@ -363,10 +363,10 @@ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
|
||||||
auto info = srcStore->queryPathInfo(storePath);
|
auto info = srcStore->queryPathInfo(storePath);
|
||||||
|
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
srcStore->exportPaths({storePath}, false, sink);
|
srcStore->exportPaths({storePath}, sink);
|
||||||
|
|
||||||
StringSource source(*sink.s);
|
StringSource source(*sink.s);
|
||||||
dstStore->importPaths(false, source, 0);
|
dstStore->importPaths(source, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -406,12 +406,11 @@ string showPaths(const PathSet & paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Store::exportPaths(const Paths & paths,
|
void Store::exportPaths(const Paths & paths, Sink & sink)
|
||||||
bool sign, Sink & sink)
|
|
||||||
{
|
{
|
||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
sink << 1;
|
sink << 1;
|
||||||
exportPath(i, sign, sink);
|
exportPath(i, sink);
|
||||||
}
|
}
|
||||||
sink << 0;
|
sink << 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,21 +270,18 @@ public:
|
||||||
virtual void narFromPath(const Path & path, Sink & sink) = 0;
|
virtual void narFromPath(const Path & path, Sink & sink) = 0;
|
||||||
|
|
||||||
/* Export a store path, that is, create a NAR dump of the store
|
/* Export a store path, that is, create a NAR dump of the store
|
||||||
path and append its references and its deriver. Optionally, a
|
path and append its references and its deriver. */
|
||||||
cryptographic signature (created by OpenSSL) of the preceding
|
virtual void exportPath(const Path & path, Sink & sink) = 0;
|
||||||
data is attached. */
|
|
||||||
virtual void exportPath(const Path & path, bool sign,
|
|
||||||
Sink & sink) = 0;
|
|
||||||
|
|
||||||
/* Export multiple paths in the format expected by ‘nix-store
|
/* Export multiple paths in the format expected by ‘nix-store
|
||||||
--import’. */
|
--import’. */
|
||||||
void exportPaths(const Paths & paths, bool sign, Sink & sink);
|
void exportPaths(const Paths & paths, Sink & sink);
|
||||||
|
|
||||||
/* Import a sequence of NAR dumps created by exportPaths() into
|
/* Import a sequence of NAR dumps created by exportPaths() into
|
||||||
the Nix store. Optionally, the contents of the NARs are
|
the Nix store. Optionally, the contents of the NARs are
|
||||||
preloaded into the specified FS accessor to speed up subsequent
|
preloaded into the specified FS accessor to speed up subsequent
|
||||||
access. */
|
access. */
|
||||||
virtual Paths importPaths(bool requireSignature, Source & source,
|
virtual Paths importPaths(Source & source,
|
||||||
std::shared_ptr<FSAccessor> accessor) = 0;
|
std::shared_ptr<FSAccessor> accessor) = 0;
|
||||||
|
|
||||||
/* For each path, if it's a derivation, build it. Building a
|
/* For each path, if it's a derivation, build it. Building a
|
||||||
|
|
|
@ -312,10 +312,10 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
|
|
||||||
case wopExportPath: {
|
case wopExportPath: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(from);
|
||||||
bool sign = readInt(from) == 1;
|
readInt(from); // obsolete
|
||||||
startWork();
|
startWork();
|
||||||
TunnelSink sink(to);
|
TunnelSink sink(to);
|
||||||
store->exportPath(path, sign, sink);
|
store->exportPath(path, sink);
|
||||||
stopWork();
|
stopWork();
|
||||||
to << 1;
|
to << 1;
|
||||||
break;
|
break;
|
||||||
|
@ -324,7 +324,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
case wopImportPaths: {
|
case wopImportPaths: {
|
||||||
startWork();
|
startWork();
|
||||||
TunnelSource source(from);
|
TunnelSource source(from);
|
||||||
Paths paths = store->importPaths(!trusted, source, 0);
|
Paths paths = store->importPaths(source, 0);
|
||||||
stopWork();
|
stopWork();
|
||||||
to << paths;
|
to << paths;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -699,29 +699,25 @@ static void opRestore(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
static void opExport(Strings opFlags, Strings opArgs)
|
static void opExport(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
bool sign = false;
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--sign") sign = true;
|
throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
|
||||||
|
|
||||||
FdSink sink(STDOUT_FILENO);
|
FdSink sink(STDOUT_FILENO);
|
||||||
Paths sorted = store->topoSortPaths(PathSet(opArgs.begin(), opArgs.end()));
|
Paths sorted = store->topoSortPaths(PathSet(opArgs.begin(), opArgs.end()));
|
||||||
reverse(sorted.begin(), sorted.end());
|
reverse(sorted.begin(), sorted.end());
|
||||||
store->exportPaths(sorted, sign, sink);
|
store->exportPaths(sorted, sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void opImport(Strings opFlags, Strings opArgs)
|
static void opImport(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
bool requireSignature = false;
|
|
||||||
for (auto & i : opFlags)
|
for (auto & i : opFlags)
|
||||||
if (i == "--require-signature") requireSignature = true;
|
throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
|
||||||
|
|
||||||
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
if (!opArgs.empty()) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
FdSource source(STDIN_FILENO);
|
FdSource source(STDIN_FILENO);
|
||||||
Paths paths = store->importPaths(requireSignature, source, 0);
|
Paths paths = store->importPaths(source, 0);
|
||||||
|
|
||||||
for (auto & i : paths)
|
for (auto & i : paths)
|
||||||
cout << format("%1%\n") % i << std::flush;
|
cout << format("%1%\n") % i << std::flush;
|
||||||
|
@ -909,16 +905,16 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case cmdImportPaths: {
|
case cmdImportPaths: {
|
||||||
if (!writeAllowed) throw Error("importing paths is not allowed");
|
if (!writeAllowed) throw Error("importing paths is not allowed");
|
||||||
store->importPaths(false, in, 0);
|
store->importPaths(in, 0);
|
||||||
out << 1; // indicate success
|
out << 1; // indicate success
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case cmdExportPaths: {
|
case cmdExportPaths: {
|
||||||
bool sign = readInt(in);
|
readInt(in); // obsolete
|
||||||
Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(in));
|
Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(in));
|
||||||
reverse(sorted.begin(), sorted.end());
|
reverse(sorted.begin(), sorted.end());
|
||||||
store->exportPaths(sorted, sign, out);
|
store->exportPaths(sorted, out);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue