summaryrefslogtreecommitdiffstats
path: root/src/libexpr/flake/flake.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-11-26 13:11:07 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-11-26 13:11:07 +0100
commit9a586e34ac3ae37bfd18f4e82af26df938ab9d96 (patch)
tree799b6974a33a8cf34a26351957ea192143e8d621 /src/libexpr/flake/flake.cc
parent0287f8305790a87b128ce09d7d3fa0de7104673c (diff)
Record trusted/untrusted settings in ~/.local/share/nix
Diffstat (limited to 'src/libexpr/flake/flake.cc')
-rw-r--r--src/libexpr/flake/flake.cc47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index 453d219dc..0eadd94db 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -6,6 +6,8 @@
#include "fetchers.hh"
#include "finally.hh"
+#include <nlohmann/json.hpp>
+
namespace nix {
using namespace flake;
@@ -635,6 +637,27 @@ Fingerprint LockedFlake::getFingerprint() const
Flake::~Flake() { }
+// setting name -> setting value -> allow or ignore.
+typedef std::map<std::string, std::map<std::string, bool>> TrustedList;
+
+Path trustedListPath()
+{
+ return getDataDir() + "/nix/trusted-settings.json";
+}
+
+static TrustedList readTrustedList()
+{
+ auto path = trustedListPath();
+ if (!pathExists(path)) return {};
+ auto json = nlohmann::json::parse(readFile(path));
+ return json;
+}
+
+static void writeTrustedList(const TrustedList & trustedList)
+{
+ writeFile(trustedListPath(), nlohmann::json(trustedList).dump());
+}
+
void ConfigFile::apply()
{
std::set<std::string> whitelist{"bash-prompt", "bash-prompt-suffix"};
@@ -657,8 +680,28 @@ void ConfigFile::apply()
assert(false);
if (!whitelist.count(baseName)) {
- // 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 '%s' (y/N)?", name, valueS)).value_or('n')) != 'y') {
+ auto trustedList = readTrustedList();
+
+ bool trusted = false;
+
+ if (auto saved = get(get(trustedList, name).value_or(std::map<std::string, bool>()), valueS)) {
+ trusted = *saved;
+ } 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') {
+ if (std::tolower(logger->ask("do you want to permanently mark this value as untrusted (y/N)?").value_or('n')) == 'y') {
+ trustedList[name][valueS] = false;
+ writeTrustedList(trustedList);
+ }
+ } else {
+ if (std::tolower(logger->ask("do you want to permanently mark this value as trusted (y/N)?").value_or('n')) == 'y') {
+ trustedList[name][valueS] = trusted = true;
+ writeTrustedList(trustedList);
+ }
+ }
+ }
+
+ if (!trusted) {
warn("ignoring untrusted flake configuration setting '%s'", name);
continue;
}