update-systemd-resolved
update-systemd-resolved copied to clipboard
Draft/RFC: polkit rules generation
This is a draft pull request that introduces the ability to dynamically generate polkit rules that allow update-systemd-resolved
to perform its various DBus calls when run as an unprivileged user.
Motivation
- Make it easier for folks who run their OpenVPN client under unprivileged users to create appropriate polkit rules, minimizing the amount of hand-editing required. On the happiest path, the generated rules can be used without any edits at all.
- Make it easier to update polkit rules in the future, if (for instance)
update-systemd-resolved
adds or removesorg.freedesktop.resolve1
DBus call types. - Support automated/on-demand rules generation for use-cases like creating appropriate polkit rules as part of building a NixOS system configuration.
Summary of changes
- Add the action
update-systemd-resolved print-polkit-rules
, with various options as documented in theREADME.md
changes. - Add NixOS-based tests intended to exercise the generated polkit ruleset by attempting to perform certain actions that should succeed only if the generated rules work as intended. Note that I implemented the tests using NixOS's test framework because (a) I'm familiar with it and (b) it's the easiest option I know of for performing systems-level testing that requires multiple machines and nontrivial setup steps. I'd be happy to re-implement the tests using whatever tooling the
update-systemd-resolved
maintainers prefer.
Caveats
- My facility with JavaScript is basic, at best. The generated polkit rules work (on my machine ;)), but I am not confident they are free of glaring style gaffes or other problems.
- The rules generation process involves printing the contents of an argument vector (
"$@"
) as a JSON array.jq
is used for this, if available, falling back to a pure-shell implementation on systems wherejq
is absent. This fallback implementation is, to put it kindly, dodgy in the extreme: it escapes"
characters and passes everything else through untouched. This is a potential security hole, if a bad actor can somehow influence the list of arguments passed to the JSON-generating function. I could implement other fallback functions (e.g., using Python and thejson
orsimplejson
module, if available, using Perl andJSON::PP
,JSON::XS
, etc., if available, and so on). WDYT?
TODO
- Help text. Omitted for the time being because
update-systemd-resolved
does not yet implement--help
for existing options. - Developer documentation. For example, how to use
niv
to update the locked Nix dependencies innix/sources.{json,nix}
. Would appreciate guidance here -- could be something as simple as addingdoc/HACKING.md
and linking to it somewhere inREADME.md
. - Reconsider certain diagnostics. With the current changeset,
update-systemd-resolved
dumps a polkit rules definition to the system journal when certain operations fail (to let the user know that how they may need to update their polkit rules to allowupdate-systemd-resolved
to do its thing). Instead, maybeupdate-systemd-resolved
could print the polkit rules generation command to the journal -- e.g.,update-system-resolved --polkit-allowed-user <uid> --polkit-allowed-group <gid>
.
Thanks in advance for your consideration!
Also: having trouble with my personal Travis CI account, so here's a link to a passing build on builds.sr.ht.
@piotr-dobrogost -- since you gave this PR a :+1: a while back, any chance I could impose upon you for a review? Please and thank you :smiley: .
The rules generation process involves printing the contents of an argument vector ("$@") as a JSON array. jq is used for this, if available, falling back to a pure-shell implementation on systems where jq is absent. This fallback implementation is, to put it kindly, dodgy in the extreme: it escapes " characters and passes everything else through untouched. This is a potential security hole, if a bad actor can somehow influence the list of arguments passed to the JSON-generating function. I could implement other fallback functions (e.g., using Python and the json or simplejson module, if available, using Perl and JSON::PP, JSON::XS, etc., if available, and so on). WDYT?
I have implemented JSON serialization using Perl and Python.