This is a follow-up to the 'execution as another user' email. TL;DR; This is a summary of our requirements for running stuff as another user.
== R1 == We need to be able to switch to another user ID. This is pretty easy but it has some non-obvious complexities. Remember that we are talking about a *framework*. We may be used multiple different contexts 1) in a command line program 2) in a graphical application on classic desktop 3) in a touch application in a sandboxed/constrained environment 4) in a headless application running remotely (no tty) somewhere. Having said that we have the following options: 1) We can write a non-interpreted (e.g. compiled) setuid executable 2) We can write a system-wide DBus service 3) We can use pkexec to start a non-setuid program 4) We can use sudo to start a non-setuid program I will discuss each option later on. For now just keep in mind that they have different failure and interaction modes. We need to know if something works, didn't work or is still waiting for user input. Ideally we should also be able to know if it can be used in the first place (without asking). == R2 == We need to stay secure. This basically means that we cannot lessen the security of a system that has our tools installed. Neither sudo nor pkexec lessen system security because they don't grant, automatically, any permissions out of the box. They are also well-known and easy to administer (local system configuration can enforce any extra constraints and privileges). For us security can be defined, I think, by the following two rules: I) The part of PlainBox that runs as root will never run arbitrary shell commands without tracing their root of trust first. II) The part of PlainBox that runs as root will carefully sanitize the execution environment not to allow exploiting trusted commands by passing malicious environment variables. Rule I is currently implemented by disallowing the user to specify the command to execute. Instead, the trusted component picks the command based on the checksum of the job that the user has requested. This prevents several kinds of forgery that are traditionally possible. Since the checksum is cryptographically secure it can be used as a form of content signature, the user cannot perform any race attacks by requesting a shell command from a particular job while rewriting the definition of the job. Rule II is currently *not* implemented because the default settings will prevent running any commands as root without first asking for the password of an administrative user account. It is listed here in case we want to change that and allow password-less security elevation to be allowed. In practice this most likely affects things like: PATH and all the environment variables starting with the string LD_ (see ld.so(8) for details). It can also affect any additional environment variable that may be consumed by any command used in all the jobs that need to run as root. I suspect it requires additional research though, and that we should not enable this without labelling it "insecure". == R3 == We need to be able to run all the jobs that can be started as a non-root user. This means that the mechanism should allow us to see generated jobs (local and template jobs). This may also mean that some of the jobs are loaded from insecure locations (writeable by untrusted user accounts). The last requirement is clearly evident when testing development code or working on providers (when PROVIDERPATH is set to something in $HOME, $TMP or elsewhere) and the user is working on a job definition that requires root. Note that this cannot compromise the security specification of R2. This is currently unspecified (how it should work) but the requirement is worth mentioning since the only reason we have the sudo execution controller (aka run jobs via sudo) is for handling cases where the trusted launcher cannot be used (because it doesn't read jobs from insecure locations). == R4 == We need to be able to terminate processes that were started this way. This is currently *not* implemented but we've learned the hard way that we need to have this feature. The part that runs as another user needs to stick around long enough to allow us to tell it to stop the processes it has started. Alternatively we need a helper that we can ask to kill any process that we've started ourselves (securely, so that we can't use it to DOS the system by killing init, for example). It is closely tied to the implementation of R1 but it is a separate requirement IMHO. I think rules R1-R4 accurately capture everything that we need to do, that we know of. If you know about something else please reply and comment. That's it. I will summarize what we can do in the next email. Thanks ZK -- Mailing list: https://launchpad.net/~checkbox-dev Post to : [email protected] Unsubscribe : https://launchpad.net/~checkbox-dev More help : https://help.launchpad.net/ListHelp

