diff --git a/doc/manual/rl-next/interactive-nix.conf-overrides.md b/doc/manual/rl-next/interactive-nix.conf-overrides.md new file mode 100644 index 000000000..d311a899f --- /dev/null +++ b/doc/manual/rl-next/interactive-nix.conf-overrides.md @@ -0,0 +1,13 @@ +--- +synopsis: "Improvements to interactive flake config" +cls: [2066] +category: Improvements +credits: ma27 +--- + +If `accept-flake-config` is set to `ask` and a `flake.nix` defines `nixConfig`, +Lix will ask on the CLI which of these settings should be used for the command. + +Now, it's possible to answer with `N` (as opposed to `n` to only reject the setting +that is asked for) to reject _all untrusted_ entries from the flake's `nixConf` +section. diff --git a/src/libexpr/flake/config.cc b/src/libexpr/flake/config.cc index 558b3e9b9..7a321f3ae 100644 --- a/src/libexpr/flake/config.cc +++ b/src/libexpr/flake/config.cc @@ -30,10 +30,44 @@ static void writeTrustedList(const TrustedList & trustedList) writeFile(path, nlohmann::json(trustedList).dump()); } +static bool askForSetting( + bool & negativeTrustOverride, + TrustedList & trustedList, + const std::string & name, + const std::string & valueS) +{ + bool trusted = false; + + // FIXME: filter ANSI escapes, newlines, \r, etc. + auto reply = logger->ask(fmt("Do you want to allow configuration setting '%s' to be set to '" ANSI_RED "%s" ANSI_NORMAL "'?\nThis may allow the flake to gain root, see the nix.conf manual page (" ANSI_BOLD "y" ANSI_NORMAL "es/" ANSI_BOLD "n" ANSI_NORMAL "o/" ANSI_BOLD "N" ANSI_NORMAL "o to all) ", name, valueS)).value_or('n'); + + if (reply == 'N') { + warn("Rejecting all untrusted nix.conf entries"); + warn("you can set '%s' to '%b' to automatically reject configuration options supplied by flakes", "accept-flake-config", false); + negativeTrustOverride = true; + } else { + if (std::tolower(reply) == '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 (in %s) mark this value as %s? (y/N) ", trustedListPath(), trusted ? "trusted": "untrusted" )).value_or('n')) == 'y') { + trustedList[name][valueS] = trusted; + writeTrustedList(trustedList); + } + } + + return trusted; +} + void ConfigFile::apply() { std::set whitelist{"bash-prompt", "bash-prompt-prefix", "bash-prompt-suffix", "flake-registry", "commit-lockfile-summary"}; + // Allows to ignore all subsequent settings from this file. + bool negativeTrustOverride = false; + for (auto & [name, value] : settings) { auto baseName = name.starts_with("extra-") ? std::string(name, 6) : name; @@ -65,15 +99,10 @@ void ConfigFile::apply() 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; + if (negativeTrustOverride) { + trusted = false; } 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); + trusted = askForSetting(negativeTrustOverride, trustedList, name, valueS); } } break;