mirror of
https://github.com/NixOS/nix.git
synced 2024-11-21 22:32:26 +00:00
Merge pull request #11694 from NixOS/backport-11610-to-2.18-maintenance
Backport #11610 to 2.18 maintenance
This commit is contained in:
commit
5f20e42764
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
@ -20,18 +20,36 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: cachix/install-nix-action@v23
|
- uses: cachix/install-nix-action@v30
|
||||||
with:
|
with:
|
||||||
# The sandbox would otherwise be disabled by default on Darwin
|
# The sandbox would otherwise be disabled by default on Darwin
|
||||||
extra_nix_config: "sandbox = true"
|
extra_nix_config: "sandbox = true"
|
||||||
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
- run: echo CACHIX_NAME="$(echo $GITHUB_REPOSITORY-install-tests | tr "[A-Z]/" "[a-z]-")" >> $GITHUB_ENV
|
||||||
- uses: cachix/cachix-action@v12
|
- uses: cachix/cachix-action@v15
|
||||||
if: needs.check_secrets.outputs.cachix == 'true'
|
if: needs.check_secrets.outputs.cachix == 'true'
|
||||||
with:
|
with:
|
||||||
name: '${{ env.CACHIX_NAME }}'
|
name: '${{ env.CACHIX_NAME }}'
|
||||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||||
|
- if: matrix.os == 'ubuntu-latest'
|
||||||
|
run: |
|
||||||
|
free -h
|
||||||
|
swapon --show
|
||||||
|
swap=$(swapon --show --noheadings | head -n 1 | awk '{print $1}')
|
||||||
|
echo "Found swap: $swap"
|
||||||
|
sudo swapoff $swap
|
||||||
|
# resize it (fallocate)
|
||||||
|
sudo fallocate -l 10G $swap
|
||||||
|
sudo mkswap $swap
|
||||||
|
sudo swapon $swap
|
||||||
|
free -h
|
||||||
|
(
|
||||||
|
while sleep 60; do
|
||||||
|
free -h
|
||||||
|
done
|
||||||
|
) &
|
||||||
- run: nix --experimental-features 'nix-command flakes' flake check -L
|
- run: nix --experimental-features 'nix-command flakes' flake check -L
|
||||||
|
- run: nix --experimental-features 'nix-command flakes' flake show --all-systems --json
|
||||||
|
|
||||||
check_secrets:
|
check_secrets:
|
||||||
permissions:
|
permissions:
|
||||||
|
@ -620,6 +620,8 @@
|
|||||||
# System tests.
|
# System tests.
|
||||||
tests.authorization = runNixOSTestFor "x86_64-linux" ./tests/nixos/authorization.nix;
|
tests.authorization = runNixOSTestFor "x86_64-linux" ./tests/nixos/authorization.nix;
|
||||||
|
|
||||||
|
tests.fetchurl = runNixOSTestFor "x86_64-linux" ./tests/nixos/fetchurl.nix;
|
||||||
|
|
||||||
tests.remoteBuilds = runNixOSTestFor "x86_64-linux" ./tests/nixos/remote-builds.nix;
|
tests.remoteBuilds = runNixOSTestFor "x86_64-linux" ./tests/nixos/remote-builds.nix;
|
||||||
|
|
||||||
tests.nix-copy-closure = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy-closure.nix;
|
tests.nix-copy-closure = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy-closure.nix;
|
||||||
|
@ -1731,13 +1731,20 @@ void LocalDerivationGoal::runChild()
|
|||||||
|
|
||||||
bool setUser = true;
|
bool setUser = true;
|
||||||
|
|
||||||
/* Make the contents of netrc available to builtin:fetchurl
|
/* Make the contents of netrc and the CA certificate bundle
|
||||||
(which may run under a different uid and/or in a sandbox). */
|
available to builtin:fetchurl (which may run under a
|
||||||
|
different uid and/or in a sandbox). */
|
||||||
std::string netrcData;
|
std::string netrcData;
|
||||||
try {
|
std::string caFileData;
|
||||||
if (drv->isBuiltin() && drv->builder == "builtin:fetchurl")
|
if (drv->isBuiltin() && drv->builder == "builtin:fetchurl") {
|
||||||
netrcData = readFile(settings.netrcFile);
|
try {
|
||||||
} catch (SysError &) { }
|
netrcData = readFile(settings.netrcFile);
|
||||||
|
} catch (SysError &) { }
|
||||||
|
|
||||||
|
try {
|
||||||
|
caFileData = readFile(settings.caFile);
|
||||||
|
} catch (SysError &) { }
|
||||||
|
}
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
if (useChroot) {
|
if (useChroot) {
|
||||||
@ -2185,7 +2192,7 @@ void LocalDerivationGoal::runChild()
|
|||||||
e.second = rewriteStrings(e.second, inputRewrites);
|
e.second = rewriteStrings(e.second, inputRewrites);
|
||||||
|
|
||||||
if (drv->builder == "builtin:fetchurl")
|
if (drv->builder == "builtin:fetchurl")
|
||||||
builtinFetchurl(drv2, netrcData);
|
builtinFetchurl(drv2, netrcData, caFileData);
|
||||||
else if (drv->builder == "builtin:buildenv")
|
else if (drv->builder == "builtin:buildenv")
|
||||||
builtinBuildenv(drv2);
|
builtinBuildenv(drv2);
|
||||||
else if (drv->builder == "builtin:unpack-channel")
|
else if (drv->builder == "builtin:unpack-channel")
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
// TODO: make pluggable.
|
// TODO: make pluggable.
|
||||||
void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData);
|
void builtinFetchurl(const BasicDerivation & drv,
|
||||||
|
const std::string & netrcData,
|
||||||
|
const std::string & caFileData);
|
||||||
void builtinUnpackChannel(const BasicDerivation & drv);
|
void builtinUnpackChannel(const BasicDerivation & drv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
|
void builtinFetchurl(
|
||||||
|
const BasicDerivation & drv,
|
||||||
|
const std::string & netrcData,
|
||||||
|
const std::string & caFileData)
|
||||||
{
|
{
|
||||||
/* Make the host's netrc data available. Too bad curl requires
|
/* Make the host's netrc data available. Too bad curl requires
|
||||||
this to be stored in a file. It would be nice if we could just
|
this to be stored in a file. It would be nice if we could just
|
||||||
@ -16,6 +19,9 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
|
|||||||
writeFile(settings.netrcFile, netrcData, 0600);
|
writeFile(settings.netrcFile, netrcData, 0600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settings.caFile = "ca-certificates.crt";
|
||||||
|
writeFile(settings.caFile, caFileData, 0600);
|
||||||
|
|
||||||
auto getAttr = [&](const std::string & name) {
|
auto getAttr = [&](const std::string & name) {
|
||||||
auto i = drv.env.find(name);
|
auto i = drv.env.find(name);
|
||||||
if (i == drv.env.end()) throw Error("attribute '%s' missing", name);
|
if (i == drv.env.end()) throw Error("attribute '%s' missing", name);
|
||||||
|
@ -49,6 +49,8 @@ struct curlFileTransfer : public FileTransfer
|
|||||||
bool done = false; // whether either the success or failure function has been called
|
bool done = false; // whether either the success or failure function has been called
|
||||||
Callback<FileTransferResult> callback;
|
Callback<FileTransferResult> callback;
|
||||||
CURL * req = 0;
|
CURL * req = 0;
|
||||||
|
// buffer to accompany the `req` above
|
||||||
|
char errbuf[CURL_ERROR_SIZE];
|
||||||
bool active = false; // whether the handle has been added to the multi object
|
bool active = false; // whether the handle has been added to the multi object
|
||||||
std::string statusMsg;
|
std::string statusMsg;
|
||||||
|
|
||||||
@ -351,6 +353,9 @@ struct curlFileTransfer : public FileTransfer
|
|||||||
if (writtenToSink)
|
if (writtenToSink)
|
||||||
curl_easy_setopt(req, CURLOPT_RESUME_FROM_LARGE, writtenToSink);
|
curl_easy_setopt(req, CURLOPT_RESUME_FROM_LARGE, writtenToSink);
|
||||||
|
|
||||||
|
curl_easy_setopt(req, CURLOPT_ERRORBUFFER, errbuf);
|
||||||
|
errbuf[0] = 0;
|
||||||
|
|
||||||
result.data.clear();
|
result.data.clear();
|
||||||
result.bodySize = 0;
|
result.bodySize = 0;
|
||||||
}
|
}
|
||||||
@ -464,8 +469,8 @@ struct curlFileTransfer : public FileTransfer
|
|||||||
code == CURLE_OK ? "" : fmt(" (curl error: %s)", curl_easy_strerror(code)))
|
code == CURLE_OK ? "" : fmt(" (curl error: %s)", curl_easy_strerror(code)))
|
||||||
: FileTransferError(err,
|
: FileTransferError(err,
|
||||||
std::move(response),
|
std::move(response),
|
||||||
"unable to %s '%s': %s (%d)",
|
"unable to %s '%s': %s (%d) %s",
|
||||||
request.verb(), request.uri, curl_easy_strerror(code), code);
|
request.verb(), request.uri, curl_easy_strerror(code), code, errbuf);
|
||||||
|
|
||||||
/* If this is a transient error, then maybe retry the
|
/* If this is a transient error, then maybe retry the
|
||||||
download after a while. If we're writing to a
|
download after a while. If we're writing to a
|
||||||
|
@ -26,7 +26,7 @@ rm -rf $TEST_ROOT/machine* || true
|
|||||||
# Note: ssh://localhost bypasses ssh, directly invoking nix-store as a
|
# Note: ssh://localhost bypasses ssh, directly invoking nix-store as a
|
||||||
# child process. This allows us to test LegacySSHStore::buildDerivation().
|
# child process. This allows us to test LegacySSHStore::buildDerivation().
|
||||||
# ssh-ng://... likewise allows us to test RemoteStore::buildDerivation().
|
# ssh-ng://... likewise allows us to test RemoteStore::buildDerivation().
|
||||||
nix build -L -v -f $file -o $TEST_ROOT/result --max-jobs 0 \
|
nix build -L -vvv -f $file -o $TEST_ROOT/result --max-jobs 0 \
|
||||||
--arg busybox $busybox \
|
--arg busybox $busybox \
|
||||||
--store $TEST_ROOT/machine0 \
|
--store $TEST_ROOT/machine0 \
|
||||||
--builders "$(join_by '; ' "${builders[@]}")"
|
--builders "$(join_by '; ' "${builders[@]}")"
|
||||||
|
84
tests/nixos/fetchurl.nix
Normal file
84
tests/nixos/fetchurl.nix
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Test whether builtin:fetchurl properly performs TLS certificate
|
||||||
|
# checks on HTTPS servers.
|
||||||
|
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
makeTlsCert = name: pkgs.runCommand name {
|
||||||
|
nativeBuildInputs = with pkgs; [ openssl ];
|
||||||
|
} ''
|
||||||
|
mkdir -p $out
|
||||||
|
openssl req -x509 \
|
||||||
|
-subj '/CN=${name}/' -days 49710 \
|
||||||
|
-addext 'subjectAltName = DNS:${name}' \
|
||||||
|
-keyout "$out/key.pem" -newkey ed25519 \
|
||||||
|
-out "$out/cert.pem" -noenc
|
||||||
|
'';
|
||||||
|
|
||||||
|
goodCert = makeTlsCert "good";
|
||||||
|
badCert = makeTlsCert "bad";
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
name = "nss-preload";
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
machine = { pkgs, ... }: {
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
virtualHosts."good" = {
|
||||||
|
addSSL = true;
|
||||||
|
sslCertificate = "${goodCert}/cert.pem";
|
||||||
|
sslCertificateKey = "${goodCert}/key.pem";
|
||||||
|
root = pkgs.runCommand "nginx-root" {} ''
|
||||||
|
mkdir "$out"
|
||||||
|
echo 'hello world' > "$out/index.html"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualHosts."bad" = {
|
||||||
|
addSSL = true;
|
||||||
|
sslCertificate = "${badCert}/cert.pem";
|
||||||
|
sslCertificateKey = "${badCert}/key.pem";
|
||||||
|
root = pkgs.runCommand "nginx-root" {} ''
|
||||||
|
mkdir "$out"
|
||||||
|
echo 'foobar' > "$out/index.html"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
security.pki.certificateFiles = [ "${goodCert}/cert.pem" ];
|
||||||
|
|
||||||
|
networking.hosts."127.0.0.1" = [ "good" "bad" ];
|
||||||
|
|
||||||
|
virtualisation.writableStore = true;
|
||||||
|
|
||||||
|
nix.settings.experimental-features = "nix-command";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
machine.wait_for_unit("nginx")
|
||||||
|
machine.wait_for_open_port(443)
|
||||||
|
|
||||||
|
out = machine.succeed("curl https://good/index.html")
|
||||||
|
assert out == "hello world\n"
|
||||||
|
|
||||||
|
out = machine.succeed("cat ${badCert}/cert.pem > /tmp/cafile.pem; curl --cacert /tmp/cafile.pem https://bad/index.html")
|
||||||
|
assert out == "foobar\n"
|
||||||
|
|
||||||
|
# Fetching from a server with a trusted cert should work.
|
||||||
|
machine.succeed("nix build --no-substitute --expr 'import <nix/fetchurl.nix> { url = \"https://good/index.html\"; hash = \"sha256-qUiQTy8PR5uPgZdpSzAYSw0u0cHNKh7A+4XSmaGSpEc=\"; }'")
|
||||||
|
|
||||||
|
# Fetching from a server with an untrusted cert should fail.
|
||||||
|
err = machine.fail("nix build --no-substitute --expr 'import <nix/fetchurl.nix> { url = \"https://bad/index.html\"; hash = \"sha256-rsBwZF/lPuOzdjBZN2E08FjMM3JHyXit0Xi2zN+wAZ8=\"; }' 2>&1")
|
||||||
|
print(err)
|
||||||
|
assert "SSL certificate problem: self-signed certificate" in err
|
||||||
|
|
||||||
|
# Fetching from a server with a trusted cert should work via environment variable override.
|
||||||
|
machine.succeed("NIX_SSL_CERT_FILE=/tmp/cafile.pem nix build --no-substitute --expr 'import <nix/fetchurl.nix> { url = \"https://bad/index.html\"; hash = \"sha256-rsBwZF/lPuOzdjBZN2E08FjMM3JHyXit0Xi2zN+wAZ8=\"; }'")
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user