diff --git a/ssh/tailssh/incubator.go b/ssh/tailssh/incubator.go index 539526b6b..a213246c5 100644 --- a/ssh/tailssh/incubator.go +++ b/ssh/tailssh/incubator.go @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This file contains the code for the incubator process. -// Taiscaled launches the incubator as the same user as it was launched as. -// The incbuator then registers a new session with the OS, sets its own UID to -// the specified `--uid`` and then lauches the requested `--cmd`. +// This file contains the code for the incubator process. Taiscaled +// launches the incubator as the same user as it was launched as. The +// incubator then registers a new session with the OS, sets its UID +// and groups to the specified `--uid`, `--gid` and `--groups`, and +// then lauches the requested `--cmd`. //go:build linux || (darwin && !ios) // +build linux darwin,!ios @@ -137,9 +138,10 @@ func (stdRWC) Close() error { // This is sometimes necessary for mounting home directories and decrypting file // systems. // -// Taiscaled launches the incubator as the same user as it was launched as. -// The incbuator then registers a new session with the OS, sets its own UID to -// the specified `--uid`` and then lauches the requested `--cmd`. +// Tailscaled launches the incubator as the same user as it was +// launched as. The incubator then registers a new session with the +// OS, sets its UID and groups to the specified `--uid`, `--gid` and +// `--groups` and then launches the requested `--cmd`. func beIncubator(args []string) error { var ( flags = flag.NewFlagSet("", flag.ExitOnError) @@ -171,7 +173,7 @@ func beIncubator(args []string) error { // Inform the system that we are about to log someone in. // We can only do this if we are running as root. // This is best effort to still allow running on machines where - // we don't support starting session, e.g. darwin. + // we don't support starting sessions, e.g. darwin. sessionCloser, err := maybeStartLoginSession(logf, uint32(*uid), *localUser, *remoteUser, *remoteIP, *ttyName) if err == nil && sessionCloser != nil { defer sessionCloser() @@ -285,7 +287,7 @@ func resizeWindow(f *os.File, winCh <-chan ssh.Window) { } // opcodeShortName is a mapping of SSH opcode -// to mnemonic names expected by the termios packaage. +// to mnemonic names expected by the termios package. // These are meant to be platform independent. var opcodeShortName = map[uint8]string{ gossh.VINTR: "intr", @@ -498,7 +500,7 @@ func loginShell(uid string) string { if e := os.Getenv("SHELL"); e != "" { return e } - return "/bin/bash" + return "/bin/sh" } func envForUser(u *user.User) []string { diff --git a/ssh/tailssh/tailssh.go b/ssh/tailssh/tailssh.go index 5456e0151..a53f67970 100644 --- a/ssh/tailssh/tailssh.go +++ b/ssh/tailssh/tailssh.go @@ -367,10 +367,8 @@ func (c *conn) setInfo(cm gossh.ConnMetadata) error { return nil } -// evaluatePolicy returns the SSHAction, sshConnInfo and localUser after -// evaluating the sshUser and remoteAddr against the SSHPolicy. The remoteAddr -// and localAddr params must be Tailscale IPs. The pubKey may be nil for "none" -// auth. +// evaluatePolicy returns the SSHAction and localUser after evaluating +// the SSHPolicy for this conn. The pubKey may be nil for "none" auth. func (c *conn) evaluatePolicy(pubKey gossh.PublicKey) (_ *tailcfg.SSHAction, localUser string, _ error) { pol, ok := c.sshPolicy() if !ok { @@ -692,7 +690,7 @@ func (c *conn) fetchSSHAction(ctx context.Context, url string) (*tailcfg.SSHActi // unless the process has already exited. func (ss *sshSession) killProcessOnContextDone() { <-ss.ctx.Done() - // Either the process has already existed, in which case this does nothing. + // Either the process has already exited, in which case this does nothing. // Or, the process is still running in which case this will kill it. ss.exitOnce.Do(func() { err := ss.ctx.Err() @@ -703,6 +701,8 @@ func (ss *sshSession) killProcessOnContextDone() { } } ss.logf("terminating SSH session from %v: %v", ss.conn.info.src.IP(), err) + // We don't need to Process.Wait here, sshSession.run() does + // the waiting regardless of termination reason. ss.cmd.Process.Kill() }) } @@ -746,7 +746,7 @@ func (srv *server) endSession(ss *sshSession) { var errSessionDone = errors.New("session is done") // handleSSHAgentForwarding starts a Unix socket listener and in the background -// forwards agent connections between the listenr and the ssh.Session. +// forwards agent connections between the listener and the ssh.Session. // On success, it assigns ss.agentListener. func (ss *sshSession) handleSSHAgentForwarding(s ssh.Session, lu *user.User) error { if !ssh.AgentRequested(ss) || !ss.action.AllowAgentForwarding { @@ -896,7 +896,6 @@ func (ss *sshSession) run() { ss.exitOnce.Do(func() {}) if err == nil { - ss.logf("Wait: ok") ss.Exit(0) return } @@ -1214,7 +1213,7 @@ func (w loggingWriter) Write(p []byte) (n int, err error) { } j = append(j, '\n') if err := w.writeCastLine(j); err != nil { - return 0, nil + return 0, err } return w.w.Write(p) }