snapd
snapd copied to clipboard
interfaces: add a polkit-agent interface
This is a first go at an interface to allow a snap to register as a Polkit agent. The primary use case is for the Ubuntu Core Desktop system we're building. The implicit slot is not available on classic systems, since there is no reasonable way to implement it given the variability in the PAM and NSS configurations found on those systems.
Here's a brief description of how a Polkit agent operates:
- The agent registers with polkitd by calling the
RegisterAgent
D-Bus method. In general, it will register as an agent for all processes that belong to a particular logind session. - When a system daemon makes a
CheckAuthorization
call to polkitd for a subject that is covered by the agent, polkitd will make aBeginAuthentication
call to the agent. This includes the requested action ID, a message to show the user, and a cookie string to identify the authentication request. - The agent runs the setuid
polkit-agent-helper-1
executable as a sub-process. The helper begins the PAM authentication process, and delegates any prompts to the agent via messages on stdin/stdout. - On completion of the authentication process (either success or failure), the helper makes an
AuthenticationAgentResponse2
method call to polkitd, using the cookie to identify the request. Polkitd trusts the response because the D-Bus connection credentials show that the helper is running as root. - Polkitd responds to the system daemon with this result, allowing it to decide how to respond to its client.
This poses a number of difficulties for a snap based system:
- The snap needs to be able to execute a setuid binary.
- The setuid binary is going to inherit some security config from its parent process, including:
- mount name space: it will be running in the snap's sandbox, so the sandbox will need to provide all the PAM modules referenced by the system's configuration, and have access to all data files and services those modules use.
- seccomp filters: the parent's seccomp filter will need to allow all access the setuid helper requires. One obvious case that has come up is access to the kernel audit subsystem.
The need to support the host system's PAM config mostly rules out getting this to work on Classic systems. On Core systems though, things will generally work if the snap uses the same base as the boot file system (or something sufficiently similar).
The interface makes use of AppArmor's ability to switch profiles on exec()
. Currently it switches to unconfined when executing the helper, but it should probably switch to a special purpose sub-profile tailored to the needs of the helper.
The interface is locked down with allow-installation: false
on the plug side, since it allows running a privileged process in a mount namespace under the control of the snap. Through the use of layouts, it's possible that the snap could replace shared libraries loaded by the helper. Even if that helper is locked down through an AppArmor sub-profile, it seems reasonable to vet snaps that request this access.