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
session: don't spawn cockpit-bridge with the shell #14375
session: don't spawn cockpit-bridge with the shell #14375
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Are the session and kerberos changes really related? It almost seems like the last two commit (which could be squashed -- code changes and test) could be its own PR, plus PR #14372 as a prerequisite?
76a2f8d
to
4c9baec
Compare
Replace our session() and fork_session() functions with a pure "spawn" utility function which handles all of the things we need it to (fd remapping, changing uid/gid, etc). This mostly removes all of the unsafe things we were doing after fork() but before exec(). It also allows a cleanup of a global variable. The biggest remaining TODO is to replace fdwalk with something based only on "safe" functions.
Spawning cockpit-bridge under the shell has caused quite a lot of annoying problems over time, mostly to do with file descriptors: - the user's shell rc scripts can write messages to stdout, which would be interpreted as cockpit frames - some shells (csh) don't support the redirection syntax we've been trying to use to solve the above problem - some shells (tcsh) seem to close all fds >= 3 - some shells (tlog-rec-session) open a new pseudoterminal, running the session command with stdin/out/err attached to it, and writing the results to stdout, regardless of which fds they were written on The above problems make it pretty difficult to come up with a mechanism to get a clean fd through to cockpit-bridge which we can reliably speak cockpit protocol on. Let's give up on trying. Instead, we use our fancy new spawn helper to spawn the user's shell with a simple command: 'exit 71'. We use this randomly-chosen number to check if the given shell is a valid login shell or not. If the shell exits with the expected status, we allow the login to continue, spawning cockpit-bridge directly. Otherwise, we give a permissions error. Closes cockpit-project#14375
It should now be possible to log in with tcsh set as the user's shell.
4c9baec
to
e87f31a
Compare
Most comments related to krb changes (now already merged under separate PR). Reviewer is somewhere far away riding his bike. :)
* from ~/.profile and friends to interfere with the protocol; route shell's | ||
* stdout to its stderr, so that we can still see it in the logs */ | ||
const int remap_fds[] = { -1, 2, -1, 1, login_messages_fd }; | ||
const int remap_fds[] = { -1, -1, -1, login_messages_fd }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a comment re what it does, I'd say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe not, fdremap is actually much simpler than I thought.
m.execute("sed -r -i.bak '/^admin:/ s_:[^:]+$_:/bin/tcsh_' /etc/passwd") | ||
b.login_and_go() | ||
b.logout() | ||
m.execute("mv /etc/passwd.bak /etc/passwd") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this is tricky. This is a @nondestructive test, so it needs to restore /etc/passwd also on failure, but it actually does since all non-destructive tests explicitly restore /etc/passwd, as one of a number of special cases. So this is exactly correct, and I guess I am just not enough used to non-destructive tests...
Spawning cockpit-bridge under the shell has caused quite a lot of annoying problems over time, mostly to do with file descriptors: - the user's shell rc scripts can write messages to stdout, which would be interpreted as cockpit frames - some shells (csh) don't support the redirection syntax we've been trying to use to solve the above problem - some shells (tcsh) seem to close all fds >= 3 - some shells (tlog-rec-session) open a new pseudoterminal, running the session command with stdin/out/err attached to it, and writing the results to stdout, regardless of which fds they were written on The above problems make it pretty difficult to come up with a mechanism to get a clean fd through to cockpit-bridge which we can reliably speak cockpit protocol on. Let's give up on trying. Instead, we use our fancy new spawn helper to spawn the user's shell with a simple command: 'exit 71'. We use this randomly-chosen number to check if the given shell is a valid login shell or not. If the shell exits with the expected status, we allow the login to continue, spawning cockpit-bridge directly. Otherwise, we give a permissions error. Closes #14375
Spawning cockpit-bridge under the shell has caused quite a lot of
annoying problems over time, mostly to do with file descriptors:
the user's shell rc scripts can write messages to stdout, which would
be interpreted as cockpit frames
some shells (csh) don't support the redirection syntax we've been
trying to use to solve the above problem
some shells (tcsh) seem to close all fds >= 3
some shells (tlog-rec-session) open a new pseudoterminal, running the
session command with stdin/out/err attached to it, and writing the
results to stdout, regardless of which fds they were written on
The above problems make it pretty difficult to come up with a mechanism
to get a clean fd through to cockpit-bridge which we can reliably speak
cockpit protocol on. Let's give up on trying.
Instead, we use our fancy new spawn helper to spawn the user's shell
with a simple command: 'exit 71'. We use this randomly-chosen number to
check if the given shell is a valid login shell or not. If the shell
exits with the expected status, we allow the login to continue, spawning
cockpit-bridge directly. Otherwise, we give a permissions error.