about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/globals.hh4
-rw-r--r--src/nix-daemon/nix-daemon.cc48
2 files changed, 46 insertions, 6 deletions
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 72863920de99..a5d5a3f5057d 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -239,6 +239,10 @@ public:
         "Additional URIs of substituters.",
         {"extra-binary-caches"}};
 
+    Setting<StringSet> trustedSubstituters{this, {}, "trusted-substituters",
+        "Disabled substituters that may be enabled via the substituters option by untrusted users.",
+        {"trusted-binary-caches"}};
+
     Setting<Strings> trustedUsers{this, {"root"}, "trusted-users",
         "Which users or groups are trusted to ask the daemon to do unsafe things."};
 
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index 1389353bb5d8..5c2641eac6ff 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -448,20 +448,56 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
         readInt(from); // obsolete printBuildTrace
         settings.buildCores = readInt(from);
         settings.useSubstitutes  = readInt(from);
+
+        StringMap overrides;
         if (GET_PROTOCOL_MINOR(clientVersion) >= 12) {
             unsigned int n = readInt(from);
             for (unsigned int i = 0; i < n; i++) {
                 string name = readString(from);
                 string value = readString(from);
-                try {
-                    if (trusted || name == "build-timeout")
-                        settings.set(name, value);
-                } catch (UsageError & e) {
-                    warn(e.what());
-                }
+                overrides.emplace(name, value);
             }
         }
+
         startWork();
+
+        for (auto & i : overrides) {
+            auto & name(i.first);
+            auto & value(i.second);
+
+            auto setSubstituters = [&](Setting<Strings> & res) {
+                if (name != res.name && res.aliases.count(name) == 0)
+                    return false;
+                StringSet trusted = settings.trustedSubstituters;
+                for (auto & s : settings.substituters.get())
+                    trusted.insert(s);
+                Strings subs;
+                auto ss = tokenizeString<Strings>(value);
+                for (auto & s : ss)
+                    if (trusted.count(s))
+                        subs.push_back(s);
+                    else
+                        warn("ignoring untrusted substituter '%s'", s);
+                res = subs;
+                return true;
+            };
+
+            try {
+                if (trusted
+                    || name == settings.buildTimeout.name
+                    || name == settings.connectTimeout.name)
+                    settings.set(name, value);
+                else if (setSubstituters(settings.substituters))
+                    ;
+                else if (setSubstituters(settings.extraSubstituters))
+                    ;
+                else
+                    debug("ignoring untrusted setting '%s'", name);
+            } catch (UsageError & e) {
+                warn(e.what());
+            }
+        }
+
         stopWork();
         break;
     }