On Mon, 4 Jan 2021 at 20:02, Eli Schwartz via pacman-dev <pacman-dev@lists.archlinux.org> wrote:
On 1/4/21 8:47 AM, Emil Velikov via pacman-dev wrote:
Hello everyone,
For a while now I've been wondering about adding privilege elevation to pacman, or if you prefer to libalpm. In particular, one that uses polkit akin to systemd and various other tools.
The reason behind this is a multiple fold, but my main selfish wish is to get rid of yaourt. As you know, it is an "unsafe pacman wrapper" which is capable of a very basic elevation via sudo.
All of this seems like something I'm thoroughly uninterested in.
As you say -- "akin to systemd". The `systemctl` tool, like pacman, has multiple modes of operation, some of which require root. In the event the user neglects to run "sudo systemctl ...", it will essentially say, from a user perspective,
"hi, I notice you forgot to run me as root, but I need root. I will momentarily re-exec myself, using the polkit tool, to get root".
You are spot on.
Then it prompts for root, most likely using a GUI dialog that grabs control of your entire screen.
AFAICT if there is a GUI agent installed and can be used it will. For example; having the gnome agent in a normal session - GUI. In a TTY or over SSH - the TTY agent will be displayed. In other words - it depends on what the user has installed and it's consistent with their overall experience. Wrt grabbing the entire screen - that depends on the agent implementation.
Under the hood, it is actually depending on dbus and a javascript engine in order to pass messages to daemons that do "everything which needs root", which in pacman's case is... essentially everything, once you're in "install and remove packages" mode.
The dbus part is spot on, although there was no JS engine last time I've looked.
But the user experience of using polkit here is pretty simple: it lets you forget to use "sudo" and not need to re-run after an error.
Whether there is a timeout (after a successful or failed attempt) is user configurable IIRC.
I don't even see how this would let you get rid of yaourt, an AUR helper with the purpose of compiling AUR packages with one wrapper call.
I should not have mentioned yaourt, despite my love for yoghourt. The AUR functionality of it is a meh for me - that's why I did not mention it.
The simple solution is to take this code in src/pacman/pacman.c:
/* check if we have sufficient permission for the requested operation */ if(myuid > 0 && needs_root()) { pm_printf(ALPM_LOG_ERROR, _("you cannot perform this operation unless you are root.\n")); cleanup(EXIT_FAILURE); }
and modify it to ALPM_LOG_WARNING:
you cannot perform this operation unless you are root. Rerunning {"sudo", "/proc/self/exe", argv...}
and exec() that for auto-retry-as-root. This then adds a hard dependency on sudo instead of polkit...
One could detect the presence of sudo/pkexec early and opt for each/either one as you pointed out, finally bailing out as originally.
Once that is complete, I have been itching to try and minimise the use/requirement of root, or as it's better known - apply the principle of least privilege.
But indeed we do, as Levente said, want to do separation of privileges. There are a few things that don't *need* root, and operate on untrusted input, e.g. fields in unsigned databases, HTTP headers for http://mirror.randomuser.org/pub/archlinux/ and so on. Quite frankly, I don't believe these should be run as the invoking user either, but as a dedicated system user for privileged-but-not-root tasks. If we move GPGME verification of packages to a non-root user, that user better not be the current login user...
This makes sense. IIRC other distributions are doing something similar.
The solution here is, I believe, to run pacman as root, but drop the EUID to the system account user "libalpm" for a bunch of things before we finally get to extracting package contents to "/".
Not entirely sold that starting as a root is a good idea. I've seen far too many horror stories while looking at Xorg. Will try and dig out some information how other package managers are handling it.
I don't see how polkit helps this goal. It assumes you have any intention of running some code as the login user; alternatively, it's just a very complex execlp("sudo", "sudo", "pacman", argv[1], argv[2], ...)
I was thinking of either `pkexec -u root pacman args` or `pkttyagent` with the smallest/simplest bus impl I could find.
Would either of the above be suitable for inclusion in pacman/libalpm? Having the thumbs-up, before writing and testing the code, would be appreciated. If it involves running the non-root parts as a system (not login) user, then yes. i.e. the goal here is to make pacman more secure by *separation* of privileges.
By personal preference, hopefully not polkit. :p
Automatic *elevation* of privileges is not a goal, but if you implement the former in such a way that it also implements the latter, ok.
...
Merely reimplementing an AUR helper's complimentary "detect whether the command line arguments need root, and choose to invoke pacman using sudo", but not actually making pacman more secure, makes me uneasy...
... and implementing it via polkit gets my NACK because I don't believe it's the job of a CLI tool to display GUI windows for authentication, and I'm not going to bite my tongue and accept it if it doesn't even give us FS#65401 but is solely to implement a yaourt feature.
Ack. If I manage to pull it off I'll make sure that separation is handled as a minimum. Perhaps at that point you'll have a quick play around with the GUI/TTY handling - I've mentioned above. Thanks Emil