From 86eddb9e277a9eb4ec66ad5bc27283bf7daf50ad Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 13 Oct 2024 14:18:22 +0200 Subject: [PATCH] libexpr/flake: (opinionated) changes to interactive flake config So I recently saw it the first time in the wild, I liked that you get interactively asked about the nix.conf settings from the flake, but there were a few minor things that I'd like to see changed: * The `(y/N)` was somewhere in the middle of the line. Moved it to the end. At first I assumed it was a bug because another thread into my terminal while I was answering the question. * I had to say no four times for a single flake with two options. So if you already know you don't want any of the config for _this_ flake, I found a `No to all` switch that ignores the rest of the nix.conf settings a little more ergonomic than having to stop the invocation, looking up the exact wording of `--no-accept-flake-config` and restarting it. Hence, I added it. * Added a note where the choices which settings to trust are persisted. My initial assumption was that this went into `nix.conf` which is not writable on NixOS, so I said no there as well. Change-Id: I0a0d9c403f0662df4707697a77f08e6cd003ec6f --- .../rl-next/interactive-nix.conf-overrides.md | 13 ++++++ src/libexpr/flake/config.cc | 45 +++++++++++++++---- 2 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 doc/manual/rl-next/interactive-nix.conf-overrides.md 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;