diff --git a/doc/manual/src/installation/env-variables.md b/doc/manual/src/installation/env-variables.md index db98f52ff..035090421 100644 --- a/doc/manual/src/installation/env-variables.md +++ b/doc/manual/src/installation/env-variables.md @@ -53,7 +53,8 @@ ssl-cert-file = /etc/ssl/my-certificate-bundle.crt The Nix installer has special handling for these proxy-related environment variables: `http_proxy`, `https_proxy`, `ftp_proxy`, -`no_proxy`, `HTTP_PROXY`, `HTTPS_PROXY`, `FTP_PROXY`, `NO_PROXY`. +`all_proxy`, `no_proxy`, `HTTP_PROXY`, `HTTPS_PROXY`, `FTP_PROXY`, +`ALL_PROXY`, `NO_PROXY`. If any of these variables are set when running the Nix installer, then the installer will create an override file at diff --git a/scripts/install-systemd-multi-user.sh b/scripts/install-systemd-multi-user.sh index 202a9bb54..a62ed7e3a 100755 --- a/scripts/install-systemd-multi-user.sh +++ b/scripts/install-systemd-multi-user.sh @@ -35,7 +35,7 @@ escape_systemd_env() { # Gather all non-empty proxy environment variables into a string create_systemd_proxy_env() { - vars="http_proxy https_proxy ftp_proxy no_proxy HTTP_PROXY HTTPS_PROXY FTP_PROXY NO_PROXY" + vars="http_proxy https_proxy ftp_proxy all_proxy no_proxy HTTP_PROXY HTTPS_PROXY FTP_PROXY ALL_PROXY NO_PROXY" for v in $vars; do if [ "x${!v:-}" != "x" ]; then echo "Environment=${v}=$(escape_systemd_env ${!v})" diff --git a/src/libcmd/network-proxy.cc b/src/libcmd/network-proxy.cc new file mode 100644 index 000000000..633b2c005 --- /dev/null +++ b/src/libcmd/network-proxy.cc @@ -0,0 +1,45 @@ +#include "network-proxy.hh" + +#include +#include + +#include "environment-variables.hh" + +namespace nix { + +static const StringSet lowercaseVariables{"http_proxy", "https_proxy", "ftp_proxy", "all_proxy", "no_proxy"}; + +static StringSet getAllVariables() +{ + StringSet variables = lowercaseVariables; + for (const auto & variable : lowercaseVariables) { + variables.insert(boost::to_upper_copy(variable)); + } + return variables; +} + +const StringSet networkProxyVariables = getAllVariables(); + +static StringSet getExcludingNoProxyVariables() +{ + static const StringSet excludeVariables{"no_proxy", "NO_PROXY"}; + StringSet variables; + std::set_difference( + networkProxyVariables.begin(), networkProxyVariables.end(), excludeVariables.begin(), excludeVariables.end(), + std::inserter(variables, variables.begin())); + return variables; +} + +static const StringSet excludingNoProxyVariables = getExcludingNoProxyVariables(); + +bool haveNetworkProxyConnection() +{ + for (const auto & variable : excludingNoProxyVariables) { + if (getEnv(variable).has_value()) { + return true; + } + } + return false; +} + +} diff --git a/src/libcmd/network-proxy.hh b/src/libcmd/network-proxy.hh new file mode 100644 index 000000000..0b6856acb --- /dev/null +++ b/src/libcmd/network-proxy.hh @@ -0,0 +1,22 @@ +#pragma once +///@file + +#include "types.hh" + +namespace nix { + +/** + * Environment variables relating to network proxying. These are used by + * a few misc commands. + * + * See the Environment section of https://curl.se/docs/manpage.html for details. + */ +extern const StringSet networkProxyVariables; + +/** + * Heuristically check if there is a proxy connection by checking for defined + * proxy variables. + */ +bool haveNetworkProxyConnection(); + +} diff --git a/src/libexpr/fetchurl.nix b/src/libexpr/fetchurl.nix index 9d1b61d7f..aef4058fb 100644 --- a/src/libexpr/fetchurl.nix +++ b/src/libexpr/fetchurl.nix @@ -34,6 +34,7 @@ derivation ({ # derivation like fetchurl is allowed to do so since its result is # by definition pure. "http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy" + "HTTP_PROXY" "HTTPS_PROXY" "FTP_PROXY" "ALL_PROXY" "NO_PROXY" ]; # To make "nix-prefetch-url" work. diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 30ebc9498..46533b34b 100644 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -25,6 +25,7 @@ #include "attr-path.hh" #include "legacy.hh" #include "users.hh" +#include "network-proxy.hh" using namespace nix; using namespace std::string_literals; @@ -121,8 +122,8 @@ static void main_nix_build(int argc, char * * argv) "HOME", "XDG_RUNTIME_DIR", "USER", "LOGNAME", "DISPLAY", "WAYLAND_DISPLAY", "WAYLAND_SOCKET", "PATH", "TERM", "IN_NIX_SHELL", "NIX_SHELL_PRESERVE_PROMPT", "TZ", "PAGER", "NIX_BUILD_SHELL", "SHLVL", - "http_proxy", "https_proxy", "ftp_proxy", "all_proxy", "no_proxy" }; + keepVars.insert(networkProxyVariables.begin(), networkProxyVariables.end()); Strings args; for (int i = 1; i < argc; ++i) diff --git a/src/nix/main.cc b/src/nix/main.cc index 8ea2f7748..bc13a4df5 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -17,6 +17,7 @@ #include "memory-source-accessor.hh" #include "terminal.hh" #include "users.hh" +#include "network-proxy.hh" #include #include @@ -41,27 +42,6 @@ void chrootHelper(int argc, char * * argv); namespace nix { -#ifdef _WIN32 -[[maybe_unused]] -#endif -static bool haveProxyEnvironmentVariables() -{ - static const std::vector proxyVariables = { - "http_proxy", - "https_proxy", - "ftp_proxy", - "HTTP_PROXY", - "HTTPS_PROXY", - "FTP_PROXY" - }; - for (auto & proxyVariable: proxyVariables) { - if (getEnv(proxyVariable).has_value()) { - return true; - } - } - return false; -} - /* Check if we have a non-loopback/link-local network interface. */ static bool haveInternet() { @@ -86,7 +66,7 @@ static bool haveInternet() } } - if (haveProxyEnvironmentVariables()) return true; + if (haveNetworkProxyConnection()) return true; return false; #else diff --git a/tests/nixos/nss-preload.nix b/tests/nixos/nss-preload.nix index 00505d114..610769c8d 100644 --- a/tests/nixos/nss-preload.nix +++ b/tests/nixos/nss-preload.nix @@ -32,6 +32,7 @@ let impureEnvVars = [ "http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy" + "HTTP_PROXY" "HTTPS_PROXY" "FTP_PROXY" "ALL_PROXY" "NO_PROXY" ]; urls = [ "http://example.com" ];