4dd5818
From 87151a68e59f9fe6e8a161148db75a52892c289e Mon Sep 17 00:00:00 2001
4dd5818
From: Martin Pitt <mpitt@redhat.com>
4dd5818
Date: Sun, 2 Jun 2019 22:47:49 +0200
4dd5818
Subject: [PATCH] session: Circumvent user shell stdout noise
4dd5818
4dd5818
Commit a9375441df7 caused Cockpit logins to fail if the user's ~/.bashrc
4dd5818
or ~/.profile writes anything to stdout. That interferes with the
4dd5818
protocol and causes an error like
4dd5818
4dd5818
    incorrect protocol: received invalid length prefix
4dd5818
4dd5818
To avoid this, route the shell's stdout to stderr (so that we can still
4dd5818
see it in the logs) and pass session's stdout to cockpit-bridge through
4dd5818
fd 3. This assumes that the shell supports `>&3` input redirection,
4dd5818
which is the case for any POSIX shell (ash, bash, ksh, dash, zsh) and at
4dd5818
least tcsh.
4dd5818
4dd5818
https://bugzilla.redhat.com/show_bug.cgi?id=1710604
4dd5818
4dd5818
Closes #11978
4dd5818
---
4dd5818
 src/ws/session.c        | 9 ++++++++-
4dd5818
 test/verify/check-login | 9 +++++++++
4dd5818
 2 files changed, 17 insertions(+), 1 deletion(-)
4dd5818
4dd5818
diff --git a/src/ws/session.c b/src/ws/session.c
4dd5818
index ec37eda16..7b142d80f 100644
4dd5818
--- a/src/ws/session.c
4dd5818
+++ b/src/ws/session.c
4dd5818
@@ -25,6 +25,7 @@
4dd5818
 #include <gssapi/gssapi_generic.h>
4dd5818
 #include <gssapi/gssapi_krb5.h>
4dd5818
 #include <krb5/krb5.h>
4dd5818
+#include <fcntl.h>
4dd5818
 
4dd5818
 static char *last_txt_msg = NULL;
4dd5818
 static char *conversation = NULL;
4dd5818
@@ -525,7 +526,7 @@ out:
4dd5818
 static int
4dd5818
 session (char **env)
4dd5818
 {
4dd5818
-  char *argv[] = { NULL /* user's shell */, "-c", "exec cockpit-bridge", NULL };
4dd5818
+  char *argv[] = { NULL /* user's shell */, "-c", "exec cockpit-bridge >&3", NULL };
4dd5818
   gss_key_value_set_desc store;
4dd5818
   struct gss_key_value_element_struct element;
4dd5818
   OM_uint32 major, minor;
4dd5818
@@ -568,6 +569,12 @@ session (char **env)
4dd5818
 
4dd5818
   debug ("executing cockpit-bridge through user shell %s", pwd->pw_shell);
4dd5818
 
4dd5818
+  /* connect our and cockpit-bridge's stdout via fd 3, to avoid stdout output
4dd5818
+   * from ~/.profile and friends to interfere with the protocol; route shell's
4dd5818
+   * stdout to its stderr, so that we can still see it in the logs */
4dd5818
+  if (dup2 (1, 3) < 0 || dup2 (2, 1) < 0)
4dd5818
+    err (1, "could not redirect user shell stdout");
4dd5818
+
4dd5818
   if (env)
4dd5818
     execvpe (argv[0], argv, env);
4dd5818
   else