aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-11-26 12:34:43 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-11-26 12:37:23 +0100
commit0287f8305790a87b128ce09d7d3fa0de7104673c (patch)
tree2797e8ced31d95780bcb60735095c1746cde5f80 /src/libexpr
parent605bacdc929db4d820b8d5866450de7d1ec6e6cf (diff)
Ask for confirmation before allowing flake Nix configuration settings
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/flake/flake.cc69
-rw-r--r--src/libexpr/flake/flake.hh2
2 files changed, 39 insertions, 32 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index bdcf63c21..453d219dc 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -233,28 +233,28 @@ static Flake getFlake(
if (auto nixConfig = vInfo.attrs->get(sNixConfig)) {
expectType(state, tAttrs, *nixConfig->value, *nixConfig->pos);
- for (auto & option : *nixConfig->value->attrs) {
- forceTrivialValue(state, *option.value, *option.pos);
- if (option.value->type == tString)
- flake.config.options.insert({option.name, state.forceStringNoCtx(*option.value, *option.pos)});
- else if (option.value->type == tInt)
- flake.config.options.insert({option.name, state.forceInt(*option.value, *option.pos)});
- else if (option.value->type == tBool)
- flake.config.options.insert({option.name, state.forceBool(*option.value, *option.pos)});
- else if (option.value->isList()) {
+ for (auto & setting : *nixConfig->value->attrs) {
+ forceTrivialValue(state, *setting.value, *setting.pos);
+ if (setting.value->type == tString)
+ flake.config.settings.insert({setting.name, state.forceStringNoCtx(*setting.value, *setting.pos)});
+ else if (setting.value->type == tInt)
+ flake.config.settings.insert({setting.name, state.forceInt(*setting.value, *setting.pos)});
+ else if (setting.value->type == tBool)
+ flake.config.settings.insert({setting.name, state.forceBool(*setting.value, *setting.pos)});
+ else if (setting.value->isList()) {
std::vector<std::string> ss;
- for (unsigned int n = 0; n < option.value->listSize(); ++n) {
- auto elem = option.value->listElems()[n];
+ for (unsigned int n = 0; n < setting.value->listSize(); ++n) {
+ auto elem = setting.value->listElems()[n];
if (elem->type != tString)
- throw TypeError("list element in flake configuration option '%s' is %s while a string is expected",
- option.name, showType(*option.value));
- ss.push_back(state.forceStringNoCtx(*elem, *option.pos));
+ throw TypeError("list element in flake configuration setting '%s' is %s while a string is expected",
+ setting.name, showType(*setting.value));
+ ss.push_back(state.forceStringNoCtx(*elem, *setting.pos));
}
- flake.config.options.insert({option.name, ss});
+ flake.config.settings.insert({setting.name, ss});
}
else
- throw TypeError("flake configuration option '%s' is %s",
- option.name, showType(*option.value));
+ throw TypeError("flake configuration setting '%s' is %s",
+ setting.name, showType(*setting.value));
}
}
@@ -637,27 +637,34 @@ Flake::~Flake() { }
void ConfigFile::apply()
{
- for (auto & [name, value] : options) {
- // FIXME: support 'trusted-public-keys' (and other options), but make it TOFU.
- if (name != "bash-prompt-suffix" &&
- name != "bash-prompt" &&
- name != "substituters" &&
- name != "extra-substituters")
- {
- warn("ignoring untrusted flake configuration option '%s'", name);
- continue;
- }
+ std::set<std::string> whitelist{"bash-prompt", "bash-prompt-suffix"};
+
+ for (auto & [name, value] : settings) {
+
+ auto baseName = hasPrefix(name, "extra-") ? std::string(name, 6) : name;
+
// FIXME: Move into libutil/config.cc.
+ std::string valueS;
if (auto s = std::get_if<std::string>(&value))
- globalConfig.set(name, *s);
+ valueS = *s;
else if (auto n = std::get_if<int64_t>(&value))
- globalConfig.set(name, fmt("%d", n));
+ valueS = fmt("%d", n);
else if (auto b = std::get_if<Explicit<bool>>(&value))
- globalConfig.set(name, b->t ? "true" : "false");
+ valueS = b->t ? "true" : "false";
else if (auto ss = std::get_if<std::vector<std::string>>(&value))
- globalConfig.set(name, concatStringsSep(" ", *ss)); // FIXME: evil
+ valueS = concatStringsSep(" ", *ss); // FIXME: evil
else
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') {
+ warn("ignoring untrusted flake configuration setting '%s'", name);
+ continue;
+ }
+ }
+
+ globalConfig.set(name, valueS);
}
}
diff --git a/src/libexpr/flake/flake.hh b/src/libexpr/flake/flake.hh
index 7eebd9044..65ed1ad0a 100644
--- a/src/libexpr/flake/flake.hh
+++ b/src/libexpr/flake/flake.hh
@@ -51,7 +51,7 @@ struct ConfigFile
{
using ConfigValue = std::variant<std::string, int64_t, Explicit<bool>, std::vector<std::string>>;
- std::map<std::string, ConfigValue> options;
+ std::map<std::string, ConfigValue> settings;
void apply();
};