mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-04 15:26:00 +00:00
ssh/tailssh: fix non-interactive ssh commands on plan9
Change-Id: Ic026db0548aa1ed8d25619cd98a85f031e987a33 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
a193323479
commit
391edc4712
@ -68,9 +68,8 @@ func (ss *sshSession) newIncubatorCommand(logf logger.Logf) (cmd *exec.Cmd, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
loginShell := ss.conn.localUser.LoginShell()
|
loginShell := ss.conn.localUser.LoginShell()
|
||||||
args := shellArgs(isShell, ss.RawCommand())
|
logf("directly running /bin/rc -c %q", ss.RawCommand())
|
||||||
logf("directly running %s %q", loginShell, args)
|
return exec.CommandContext(ss.ctx, loginShell, "-c", ss.RawCommand()), nil
|
||||||
return exec.CommandContext(ss.ctx, loginShell, args...), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lu := ss.conn.localUser
|
lu := ss.conn.localUser
|
||||||
@ -155,10 +154,6 @@ func (stdRWC) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type incubatorArgs struct {
|
type incubatorArgs struct {
|
||||||
loginShell string
|
|
||||||
uid int
|
|
||||||
gid int
|
|
||||||
gids []int
|
|
||||||
localUser string
|
localUser string
|
||||||
homeDir string
|
homeDir string
|
||||||
remoteUser string
|
remoteUser string
|
||||||
@ -176,13 +171,8 @@ type incubatorArgs struct {
|
|||||||
|
|
||||||
func parseIncubatorArgs(args []string) (incubatorArgs, error) {
|
func parseIncubatorArgs(args []string) (incubatorArgs, error) {
|
||||||
var ia incubatorArgs
|
var ia incubatorArgs
|
||||||
var groups string
|
|
||||||
|
|
||||||
flags := flag.NewFlagSet("", flag.ExitOnError)
|
flags := flag.NewFlagSet("", flag.ExitOnError)
|
||||||
flags.StringVar(&ia.loginShell, "login-shell", "", "path to the user's preferred login shell")
|
|
||||||
flags.IntVar(&ia.uid, "uid", 0, "the uid of local-user")
|
|
||||||
flags.IntVar(&ia.gid, "gid", 0, "the gid of local-user")
|
|
||||||
flags.StringVar(&groups, "groups", "", "comma-separated list of gids of local-user")
|
|
||||||
flags.StringVar(&ia.localUser, "local-user", "", "the user to run as")
|
flags.StringVar(&ia.localUser, "local-user", "", "the user to run as")
|
||||||
flags.StringVar(&ia.homeDir, "home-dir", "/", "the user's home directory")
|
flags.StringVar(&ia.homeDir, "home-dir", "/", "the user's home directory")
|
||||||
flags.StringVar(&ia.remoteUser, "remote-user", "", "the remote user/tags")
|
flags.StringVar(&ia.remoteUser, "remote-user", "", "the remote user/tags")
|
||||||
@ -197,22 +187,10 @@ func parseIncubatorArgs(args []string) (incubatorArgs, error) {
|
|||||||
flags.BoolVar(&ia.isSELinuxEnforcing, "is-selinux-enforcing", false, "whether SELinux is in enforcing mode")
|
flags.BoolVar(&ia.isSELinuxEnforcing, "is-selinux-enforcing", false, "whether SELinux is in enforcing mode")
|
||||||
flags.StringVar(&ia.encodedEnv, "encoded-env", "", "JSON encoded array of environment variables in '['key=value']' format")
|
flags.StringVar(&ia.encodedEnv, "encoded-env", "", "JSON encoded array of environment variables in '['key=value']' format")
|
||||||
flags.Parse(args)
|
flags.Parse(args)
|
||||||
|
|
||||||
for _, g := range strings.Split(groups, ",") {
|
|
||||||
if g == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
gid, err := strconv.Atoi(g)
|
|
||||||
if err != nil {
|
|
||||||
return ia, fmt.Errorf("unable to parse group id %q: %w", g, err)
|
|
||||||
}
|
|
||||||
ia.gids = append(ia.gids, gid)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ia, nil
|
return ia, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ia incubatorArgs) forwadedEnviron() ([]string, string, error) {
|
func (ia incubatorArgs) forwardedEnviron() ([]string, string, error) {
|
||||||
environ := os.Environ()
|
environ := os.Environ()
|
||||||
// pass through SSH_AUTH_SOCK environment variable to support ssh agent forwarding
|
// pass through SSH_AUTH_SOCK environment variable to support ssh agent forwarding
|
||||||
allowListKeys := "SSH_AUTH_SOCK"
|
allowListKeys := "SSH_AUTH_SOCK"
|
||||||
@ -328,14 +306,13 @@ func serveSFTP() error {
|
|||||||
// login shell.
|
// login shell.
|
||||||
func handleSSHInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
func handleSSHInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
||||||
|
|
||||||
environ, _, err := ia.forwadedEnviron()
|
environ, _, err := ia.forwardedEnviron()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
args := shellArgs(ia.isShell, ia.cmd)
|
dlogf("running /bin/rc -c %q", ia.cmd)
|
||||||
dlogf("running %s %q", ia.loginShell, args)
|
cmd := newCommand("/bin/rc", environ, []string{"-c", ia.cmd})
|
||||||
cmd := newCommand(ia.loginShell, environ, args)
|
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if ee, ok := err.(*exec.ExitError); ok {
|
if ee, ok := err.(*exec.ExitError); ok {
|
||||||
ps := ee.ProcessState
|
ps := ee.ProcessState
|
||||||
@ -442,11 +419,3 @@ func acceptEnvPair(kv string) bool {
|
|||||||
_ = k
|
_ = k
|
||||||
return true // permit anything on plan9 during bringup, for debugging at least
|
return true // permit anything on plan9 during bringup, for debugging at least
|
||||||
}
|
}
|
||||||
|
|
||||||
func shellArgs(isShell bool, cmd string) []string {
|
|
||||||
if isShell {
|
|
||||||
return []string{"-l"}
|
|
||||||
} else {
|
|
||||||
return []string{"-c", cmd}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -48,6 +48,9 @@ func userLookup(username string) (*userMeta, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userMeta) LoginShell() string {
|
func (u *userMeta) LoginShell() string {
|
||||||
|
if runtime.GOOS == "plan9" {
|
||||||
|
return "/bin/rc"
|
||||||
|
}
|
||||||
if u.loginShellCached != "" {
|
if u.loginShellCached != "" {
|
||||||
// This field should be populated on Linux, at least, because
|
// This field should be populated on Linux, at least, because
|
||||||
// func userLookup on Linux uses "getent" to look up the user
|
// func userLookup on Linux uses "getent" to look up the user
|
||||||
|
Loading…
x
Reference in New Issue
Block a user