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

session: don't spawn cockpit-bridge with the shell #14375

Merged

Conversation

allisonkarlitskaya
Copy link
Member

@allisonkarlitskaya allisonkarlitskaya commented Jul 20, 2020

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.

Copy link
Member

@martinpitt martinpitt left a 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?

src/ws/session.c Outdated Show resolved Hide resolved
src/ws/session-utils.c Show resolved Hide resolved
allisonkarlitskaya and others added 3 commits August 10, 2020 00:31
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.
@allisonkarlitskaya allisonkarlitskaya dismissed martinpitt’s stale review August 10, 2020 08:43

Most comments related to krb changes (now already merged under separate PR). Reviewer is somewhere far away riding his bike. :)

@mvollmer mvollmer self-requested a review August 10, 2020 09:45
* 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 };
Copy link
Member

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.

Copy link
Member

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")
Copy link
Member

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...

@allisonkarlitskaya allisonkarlitskaya merged commit 5aa4e1f into cockpit-project:master Aug 11, 2020
allisonkarlitskaya added a commit that referenced this pull request Aug 11, 2020
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
@allisonkarlitskaya allisonkarlitskaya deleted the new-tcsh branch January 5, 2021 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants