aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/flake/config.cc54
-rw-r--r--src/libfetchers/fetch-settings.cc43
-rw-r--r--src/libfetchers/fetch-settings.hh16
3 files changed, 90 insertions, 23 deletions
diff --git a/src/libexpr/flake/config.cc b/src/libexpr/flake/config.cc
index b330d96f9..adcf7fd10 100644
--- a/src/libexpr/flake/config.cc
+++ b/src/libexpr/flake/config.cc
@@ -51,30 +51,46 @@ void ConfigFile::apply()
else
assert(false);
- if (!whitelist.count(baseName) && !nix::fetchSettings.acceptFlakeConfig) {
- bool trusted = false;
- auto trustedList = readTrustedList();
- auto tlname = get(trustedList, name);
- if (auto saved = tlname ? get(*tlname, valueS) : nullptr) {
- trusted = *saved;
- printInfo("Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json.", name, valueS);
- } else {
- // FIXME: filter ANSI escapes, newlines, \r, etc.
- if (std::tolower(logger->ask(fmt("do you want to allow configuration setting '%s' to be set to '" ANSI_RED "%s" ANSI_NORMAL "' (y/N)?", name, valueS)).value_or('n')) == 'y') {
- trusted = true;
- }
- if (std::tolower(logger->ask(fmt("do you want to permanently mark this value as %s (y/N)?", trusted ? "trusted": "untrusted" )).value_or('n')) == 'y') {
- trustedList[name][valueS] = trusted;
- writeTrustedList(trustedList);
+ bool trusted = whitelist.count(baseName);
+ if (!trusted) {
+ switch (nix::fetchSettings.acceptFlakeConfig) {
+ case AcceptFlakeConfig::True: {
+ trusted = true;
+ break;
+ }
+ case AcceptFlakeConfig::Ask: {
+ auto trustedList = readTrustedList();
+ auto tlname = get(trustedList, name);
+ if (auto saved = tlname ? get(*tlname, valueS) : nullptr) {
+ trusted = *saved;
+ printInfo("Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json.", name, valueS);
+ } else {
+ // FIXME: filter ANSI escapes, newlines, \r, etc.
+ if (std::tolower(logger->ask(fmt("Do you want to allow configuration setting '%s' to be set to '" ANSI_RED "%s" ANSI_NORMAL "' (y/N)? This may allow the flake to gain root, see the nix.conf manual page.", name, valueS)).value_or('n')) == 'y') {
+ trusted = true;
+ } else {
+ warn("you can set '%s' to '%b' to automatically reject configuration options supplied by flakes", "accept-flake-config", false);
+ }
+ if (std::tolower(logger->ask(fmt("do you want to permanently mark this value as %s (y/N)?", trusted ? "trusted": "untrusted" )).value_or('n')) == 'y') {
+ trustedList[name][valueS] = trusted;
+ writeTrustedList(trustedList);
+ }
}
+ break;
}
- if (!trusted) {
- warn("ignoring untrusted flake configuration setting '%s'.\nPass '%s' to trust it", name, "--accept-flake-config");
- continue;
+ case nix::AcceptFlakeConfig::False: {
+ trusted = false;
+ break;
+ };
}
}
- globalConfig.set(name, valueS);
+ if (trusted) {
+ debug("accepting trusted flake configuration setting '%s'", name);
+ globalConfig.set(name, valueS);
+ } else {
+ warn("ignoring untrusted flake configuration setting '%s', pass '%s' to trust it (may allow the flake to gain root, see the nix.conf manual page)", name, "--accept-flake-config");
+ }
}
}
diff --git a/src/libfetchers/fetch-settings.cc b/src/libfetchers/fetch-settings.cc
index e7d5244dc..aeb3c542b 100644
--- a/src/libfetchers/fetch-settings.cc
+++ b/src/libfetchers/fetch-settings.cc
@@ -1,7 +1,50 @@
+#include "abstract-setting-to-json.hh"
+#include "args.hh"
+#include "config-impl.hh"
#include "fetch-settings.hh"
+#include <nlohmann/json.hpp>
+
namespace nix {
+template<> AcceptFlakeConfig BaseSetting<AcceptFlakeConfig>::parse(const std::string & str) const
+{
+ if (str == "true") return AcceptFlakeConfig::True;
+ else if (str == "ask") return AcceptFlakeConfig::Ask;
+ else if (str == "false") return AcceptFlakeConfig::False;
+ else throw UsageError("option '%s' has invalid value '%s'", name, str);
+}
+
+template<> std::string BaseSetting<AcceptFlakeConfig>::to_string() const
+{
+ if (value == AcceptFlakeConfig::True) return "true";
+ else if (value == AcceptFlakeConfig::Ask) return "ask";
+ else if (value == AcceptFlakeConfig::False) return "false";
+ else abort();
+}
+
+template<> void BaseSetting<AcceptFlakeConfig>::convertToArg(Args & args, const std::string & category)
+{
+ args.addFlag({
+ .longName = name,
+ .description = "Accept Lix configuration options from flakes without confirmation. This allows flakes to gain root access to your machine if you are a trusted user; see the nix.conf manual page for more details.",
+ .category = category,
+ .handler = {[this]() { override(AcceptFlakeConfig::True); }}
+ });
+ args.addFlag({
+ .longName = "ask-" + name,
+ .description = "Ask whether to accept Lix configuration options from flakes.",
+ .category = category,
+ .handler = {[this]() { override(AcceptFlakeConfig::Ask); }}
+ });
+ args.addFlag({
+ .longName = "no-" + name,
+ .description = "Reject Lix configuration options from flakes.",
+ .category = category,
+ .handler = {[this]() { override(AcceptFlakeConfig::False); }}
+ });
+}
+
FetchSettings::FetchSettings()
{
}
diff --git a/src/libfetchers/fetch-settings.hh b/src/libfetchers/fetch-settings.hh
index 6fb260c3a..93123463c 100644
--- a/src/libfetchers/fetch-settings.hh
+++ b/src/libfetchers/fetch-settings.hh
@@ -11,6 +11,8 @@
namespace nix {
+enum class AcceptFlakeConfig { False, Ask, True };
+
struct FetchSettings : public Config
{
FetchSettings();
@@ -86,15 +88,21 @@ struct FetchSettings : public Config
"Whether to use flake registries to resolve flake references.",
{}, true, Xp::Flakes};
- Setting<bool> acceptFlakeConfig{this, false, "accept-flake-config",
+ Setting<AcceptFlakeConfig> acceptFlakeConfig{
+ this, AcceptFlakeConfig::Ask, "accept-flake-config",
R"(
Whether to accept Lix configuration from the `nixConfig` attribute of
- a flake without prompting. This is almost always a very bad idea.
-
- Setting this setting as a trusted user allows Nix flakes to gain root
+ a flake. Doing so as a trusted user allows Nix flakes to gain root
access on your machine if they set one of the several
trusted-user-only settings that execute commands as root.
+ If set to `true`, such configuration will be accepted without asking;
+ this is almost always a very bad idea. Setting this to `ask` will
+ prompt the user each time whether to allow a certain configuration
+ option set this way, and offer to optionally remember their choice.
+ When set to `false`, the configuration will be automatically
+ declined.
+
See [multi-user installations](@docroot@/installation/multi-user.md)
for more details on the Lix security model.
)",