Historically, Nix would support copying certificate authorities inside the sandbox so you could use them. In addition to that, the primitives consisting of leaking environment variables via `impureEnvVars` and `extra-sandbox-paths` to render paths external to the sandbox visible to the builder would also constitute a mechanism to expose special inodes which should have no influence on the output result, e.g. interception CAs. Unfortunately, in nixpkgs, `lib.fetchers.proxyImpureEnvVars` set `NIX_SSL_CERT_FILE` as an impure environment variable. A confused user may set `ssl-cert-file` via `NIX_SSL_CERT_FILE` outside the builder believing that this will set magically the right `NIX_SSL_CERT_FILE` inside the sandbox, but this is not true. The combination of impure environment variables and setting `caFile` creates a weird interaction where `NIX_SSL_CERT_FILE` points to an "outside the builder's world" inode *AND* `ssl-cert-file` creates this very same certificate file in /etc/ssl/certs/ca-certificates.crt without rewriting the environment variable. This footgun is closed by making these two features mutually incompatible with a warning and forcibly rewriting the SSL family of environment variables even if it was set via impure environment variables. Users who truly meant to use `impureEnvVars` can obtain the right behavior by setting `ssl-cert-file` to an empty string and will have to use `extra-sandbox-paths`. Users who meant to use `ssl-cert-file` will have everything work automatically with a warning hinting at nixpkgs *fixing its own bug*, i.e. passing `NIX_SSL_CERT_FILE` as an impure environment variable and expecting the Nix interpreter to magically reconcile the diverging values or expecting the user to actually do the work to render the path visible available via `extra-sandbox-paths`. Fixes #885. Change-Id: I32f8b5ce20fe9b6a911768114c92f95fc886cc07 Signed-off-by: Raito Bezarius <raito@lix.systems>
50 lines
1.5 KiB
Nix
50 lines
1.5 KiB
Nix
{ sandbox ? true, mode }:
|
|
|
|
with import ./config.nix;
|
|
|
|
mkDerivation (
|
|
{
|
|
name = "ssl-export";
|
|
buildCommand = ''
|
|
# Add some indirection, otherwise grepping into the debug output finds the string.
|
|
report () { echo CERT_$1_IN_SANDBOX; }
|
|
|
|
${if sandbox then ''
|
|
# This depends on a proper sandbox otherwise the path may be the outside-of-the-builder's one.
|
|
if [ -f /etc/ssl/certs/ca-certificates.crt ]; then
|
|
content=$(</etc/ssl/certs/ca-certificates.crt)
|
|
if [ "$content" == CERT_CONTENT ]; then
|
|
report present
|
|
else
|
|
report corrupted
|
|
# printf "expected: 'CERT_CONTENT', got: '%s'" "$content"
|
|
fi
|
|
else
|
|
report missing
|
|
fi
|
|
'' else ""}
|
|
|
|
if [ -f "$NIX_SSL_CERT_FILE" ]; then
|
|
echo "found $NIX_SSL_CERT_FILE"
|
|
content=$(<$NIX_SSL_CERT_FILE)
|
|
if [ "$content" == CERT_CONTENT ]; then
|
|
report present-env-var
|
|
else
|
|
report corrupted
|
|
# printf "expected: 'CERT_CONTENT', got: '%s'" "$content"
|
|
fi
|
|
else
|
|
report missing
|
|
fi
|
|
|
|
# Always fail, because we do not want to bother with fixed-output
|
|
# derivations being cached, and do not want to compute the right hash.
|
|
false;
|
|
'';
|
|
} // rec {
|
|
fixed-output = { outputHash = "sha256:0000000000000000000000000000000000000000000000000000000000000000"; };
|
|
clobbering-impurities = fixed-output // { impureEnvVars = [ "NIX_SSL_CERT_FILE" ]; };
|
|
normal = { };
|
|
}.${mode}
|
|
)
|