Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remember authentication for a set period of time #472

Open
jedenastka opened this issue Jul 2, 2024 · 8 comments · May be fixed by #533
Open

Remember authentication for a set period of time #472

jedenastka opened this issue Jul 2, 2024 · 8 comments · May be fixed by #533

Comments

@jedenastka
Copy link

jedenastka commented Jul 2, 2024

Is your feature request related to a problem? Please describe.
When running security-sensitive actions such as managing services via systemctl, Polkit asks me to authenticate, which is not a bad thing, but I will often run many such actions in a row, requiring me to retype the password over and over (remember that a secure password should consist of multiple words).

The well-known utility sudo also deals with a security-sensitive action (running as root), but it remembers the password for a configurable amount of time (15 minutes by default), for a given session (a different session will be asked for the password even in that period; not sure how a session is determined by sudo, but the important part is that a single shell process is counted as a single session). Ironically, this makes me often run systemctl as sudo systemctl, since root is not prompted for a password by Polkit (I assume this is the upstream configuration, though I use the Debian package). This is a pretty stupid workaround, but seems like many do it anyways just because of this usability issue.

This is even more important with the addition of a run0 utility to the systemd suite, which is meant to be a cleaner, safer alternative to sudo based on the existing underlying systemd security system, including Polkit. While it does a quite good job, run0 will now ask you for the password every time you run something as root, because that's what Polkit does. Since sudo offered the capacity to remember the password, this is a roadblock to run0 adoption, at least in my case, and I imagine many others.

Describe the solution you'd like
Add a way to configure a period of time during which Polkit will remember the entered password for this session, default to 15 minutes like sudo. A session in CLI should encompass still using the same shell process, in whatever way this is done, in GUI it should mean using the same desktop session. This could still require confirmation, as described in #463.

With this, there are a few issues with the CLI authentication prompt itself:

  • If there's more than one user that can do the action, it will first ask for the user to authenticate as, which is inconvenient, but I'm not sure how it should be resolved (the GUI prompt has the advantage of being able to just leave the selection as default; maybe a keyboard shortcut could be used to explicitly change the user from the default?).
  • Using the utility run0, which only purpose is to run things as other users (which is security sensitive) probably should be considered enough confirmation by itself (entering y and enter every time would still be pointless, though better than the current situation). This seems problematic to do properly with Polkit, and it has no analogue in the GUI world.
  • The GUI prompt is launched even in CLI contexts, when the initial shell is launched from a GUI terminal.

Those would probably better be explored in separate issues, however.

Describe alternatives you've considered

  • The status quo: password authentication every time (as explained previously: assuming a secure password - a PITA).
  • Biometric authentication? I don't know if/how that works on Linux/Polkit/PAM/anything, I don't have the hardware for it (most people don't) and I don't even know if I trust that technology fundamentally.
  • Authorization solely based on being a certain user/in a certain group, which is already possible with Polkit, or confirmation-only authorization, not yet possible - see Feature request: confirmation without authentication #463, where I left a comment.

Additional context
I think the utility of admin passwords should really be reconsidered, as described by my comment in #463. Still, it would be good to see this as an option for people that prefer having them, or just simply if having confirmation-only authorization be the default is not currently (or ever) considered desirable.

@poettering Curious about your thoughts, since you seemed excited for run0 to take over the world ;) and probably have a better idea about how this should be done to benefit systemd tooling. Seems risky to ping, but pinging the entire systemd project would be worse, especially considering my previous issue...

@jrybar-rh
Copy link
Member

Polkit already has this feature and you can experience it e.g. when giving password to gnome-control-center for e.g. printers.
It's called auth_admin_keep (see man polkit, section DECLARING ACTIONS). Each action specified by a package vendor in appropriate .policy file (located usually in /usr/share/polkit-1/actions/) can be defined as auth_admin_keep, so that you don't have to write down your password every time. This decision is on the vendor of the package that defines the actions (systemd in your case).
@poettering, any comments?

@jedenastka
Copy link
Author

jedenastka commented Jul 3, 2024

Doesn't that only work for a single process requesting multiple actions? I tried editing my configuration to use that before, and it didn't work - ArchWiki states that is the reason for it. run0 or systemctl run only once, and then exit, as they are CLI tools. The next request comes from a new process.

@poettering
Copy link

Polkit already has this feature and you can experience it e.g. when giving password to gnome-control-center for e.g. printers.
It's called auth_admin_keep (see man polkit, section DECLARING ACTIONS). Each action specified by a package vendor in appropriate .policy file (located usually in /usr/share/polkit-1/actions/) can be defined as auth_admin_keep, so that you don't have to write down your password every time. This decision is on the vendor of the package that defines the actions (systemd in your case).
@poettering, any comments?

We already set auth_admin_keep for the action run0 uses. Alas it doesn't work, PK seems to invalidate the cache whenever a process exits and run0 is pretty short-lived.

Any chance this can be relaxed? if you don#t want to drop the flushing of the permission cache entirely, then maybe bind it to the inode of the binary of the process rather than the PID?

or in other words, allow cached permissions if either:

  1. uid/gid/pid of the client didn't change
  2. or uid/gid didn't change, and the device and inode number as reported by .st_ino/.st_dev from stat() on /proc/$PID/exe didn't change.

Would that make sense?

btw, polkit's "pkexec" tool is in the same boat here as run0, it's also short-lived and thus currently cut out of any caching of permissions.

@poettering
Copy link

poettering commented Jul 4, 2024

(of course, reading /proc/$PID/exe is a bit racy, since pids might be recycled asynchronously. if pk has a pidfd of the client this can be dealt with nicely: simply check if after reading the stat() data the pidfd still points to the same pid (and not 0), and you verified that the process didn't exit in the meantime and the pid hence didn't possibly get recycled yet, and the stat() data you read of that file definitely is still correct.)

@bluca
Copy link
Member

bluca commented Jul 18, 2024

Checking the invoked binary would be a poor man's setuid though. We already know that tying privilege to binaries on disk leads to bad outcomes.
We do have a concept already that we can use: user sessions. If a user, belonging/owning a user session, is authorized, and another request comes from the same user and the same session, for the same action-id, then that sounds like a possible avenue for returning a cached response?

@poettering
Copy link

i think cgroup is better than session though

@bluca
Copy link
Member

bluca commented Jul 19, 2024

Whichever is closer to "the thing that a desktop user authenticates into" would fit best I think

@bluca
Copy link
Member

bluca commented Dec 15, 2024

Whichever is closer to "the thing that a desktop user authenticates into" would fit best I think

Actually, this was completely wrong. The session is too lax (eg: a browser tab would get permission if you get it in a terminal window). Cgroup is also too lax, as while modern desktops like GNOME run each terminal tab in a separate scope, many older desktops don't, so basically you have everything running in a session under the same cgroup, which is again too lax.

I had a look, and what sudo does is keeping a database in /run, recording either the originating TTY or parent process of a successful auth, and re-auths automatically if either matches (depending on config, everyone ships with TTY matching by default).

I've started a POC to re-auth by matching on a common parent process in polkit, and seems to work nicely with run0. Once again we can do this safely if and only if we track stuff via pid fds, but that's a given nowadays.
But I think we should go further than sudo, at least initially, and be more restrictive. Hence I'll try to also add originating TTY matching, so that they all have to match: local logind session (already checked), parent process, TTY. The use-case after all is running commands in a terminal.

bluca added a commit to bluca/polkit that referenced this issue Dec 16, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime).

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 16, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 16, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 16, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 17, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 18, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 18, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 18, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 18, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
bluca added a commit to bluca/polkit that referenced this issue Dec 19, 2024
…t/cgroup/tty

sudo keeps a record of authenticated processes via either the controlling
TTY (default) or the parent process id.

Implement the same caching behaviour, but stricter: if a process
is authenticated for auth_keep, do not expunge it when it exits
if it was tracked via PID FD (to make it safe against reuse attacks).

Then, if another process comes along, skip re-auth and allow it
if it shared the same UID, parent process id, cgroup id and
controlling terminal (and all processes are newer than the controlling
terminal ctime). PID FDs must be used all the way through,
otherwise there's no caching.

This is much stricter than sudo, as all conditions must be met.
But it still allows to fulfill the main use case, which is to
run multiple commands on the same terminal without being asked
for the password again and again.

Unlike sudo, we also do not refresh the countdown on each use.

Fixes polkit-org#472
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants