mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-06 08:15:49 +00:00
more plan9 ssh work
Change-Id: I7049b5b4f6c0f9902693e00ab6d12ac00bc554bc Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
dd3d4e3fe9
commit
6a3f589f53
@ -182,6 +182,10 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "plan9" && os.Getenv("_NETSHELL_CHILD_") != "" {
|
||||||
|
os.Args = []string{"tailscaled", "be-child", "plan9-netshell"}
|
||||||
|
}
|
||||||
|
|
||||||
if len(os.Args) > 1 {
|
if len(os.Args) > 1 {
|
||||||
sub := os.Args[1]
|
sub := os.Args[1]
|
||||||
if fp, ok := subCommands[sub]; ok {
|
if fp, ok := subCommands[sub]; ok {
|
||||||
|
1
go.mod
1
go.mod
@ -3,6 +3,7 @@ module tailscale.com
|
|||||||
go 1.24.0
|
go 1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f
|
||||||
filippo.io/mkcert v1.4.4
|
filippo.io/mkcert v1.4.4
|
||||||
fyne.io/systray v1.11.0
|
fyne.io/systray v1.11.0
|
||||||
github.com/akutz/memconn v0.1.0
|
github.com/akutz/memconn v0.1.0
|
||||||
|
2
go.sum
2
go.sum
@ -2,6 +2,8 @@
|
|||||||
4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
|
4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
|
||||||
4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc=
|
4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc=
|
||||||
4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU=
|
4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU=
|
||||||
|
9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f h1:1C7nZuxUMNz7eiQALRfiqNOm04+m3edWlRff/BYHf0Q=
|
||||||
|
9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f/go.mod h1:hHyrZRryGqVdqrknjq5OWDLGCTJ2NeEvtrpR96mjraM=
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||||
|
@ -22,28 +22,18 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/pkg/sftp"
|
"github.com/pkg/sftp"
|
||||||
"tailscale.com/cmd/tailscaled/childproc"
|
"tailscale.com/cmd/tailscaled/childproc"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
|
"tailscale.com/tempfork/netshell"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
childproc.Add("ssh", beIncubator)
|
childproc.Add("ssh", beIncubator)
|
||||||
childproc.Add("sftp", beSFTP)
|
childproc.Add("sftp", beSFTP)
|
||||||
}
|
childproc.Add("plan9-netshell", beNetshell)
|
||||||
|
|
||||||
// maybeStartLoginSession informs the system that we are about to log someone
|
|
||||||
// in. On success, it may return a non-nil close func which must be closed to
|
|
||||||
// release the session.
|
|
||||||
// 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 sessions, e.g. darwin.
|
|
||||||
// See maybeStartLoginSessionLinux.
|
|
||||||
var maybeStartLoginSession = func(dlogf logger.Logf, ia incubatorArgs) (close func() error) {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newIncubatorCommand returns a new exec.Cmd configured with
|
// newIncubatorCommand returns a new exec.Cmd configured with
|
||||||
@ -85,7 +75,6 @@ func (ss *sshSession) newIncubatorCommand(logf logger.Logf) (cmd *exec.Cmd, err
|
|||||||
|
|
||||||
lu := ss.conn.localUser
|
lu := ss.conn.localUser
|
||||||
ci := ss.conn.info
|
ci := ss.conn.info
|
||||||
groups := strings.Join(ss.conn.userGroupIDs, ",")
|
|
||||||
remoteUser := ci.uprof.LoginName
|
remoteUser := ci.uprof.LoginName
|
||||||
if ci.node.IsTagged() {
|
if ci.node.IsTagged() {
|
||||||
remoteUser = strings.Join(ci.node.Tags().AsSlice(), ",")
|
remoteUser = strings.Join(ci.node.Tags().AsSlice(), ",")
|
||||||
@ -94,10 +83,9 @@ func (ss *sshSession) newIncubatorCommand(logf logger.Logf) (cmd *exec.Cmd, err
|
|||||||
incubatorArgs := []string{
|
incubatorArgs := []string{
|
||||||
"be-child",
|
"be-child",
|
||||||
"ssh",
|
"ssh",
|
||||||
"--login-shell=" + lu.LoginShell(),
|
// "--login-shell=" + lu.LoginShell(),
|
||||||
"--uid=" + lu.Uid,
|
// "--uid=" + lu.Uid,
|
||||||
"--gid=" + lu.Gid,
|
// "--gid=" + lu.Gid,
|
||||||
"--groups=" + groups,
|
|
||||||
"--local-user=" + lu.Username,
|
"--local-user=" + lu.Username,
|
||||||
"--home-dir=" + lu.HomeDir,
|
"--home-dir=" + lu.HomeDir,
|
||||||
"--remote-user=" + remoteUser,
|
"--remote-user=" + remoteUser,
|
||||||
@ -212,6 +200,9 @@ func parseIncubatorArgs(args []string) (incubatorArgs, error) {
|
|||||||
flags.Parse(args)
|
flags.Parse(args)
|
||||||
|
|
||||||
for _, g := range strings.Split(groups, ",") {
|
for _, g := range strings.Split(groups, ",") {
|
||||||
|
if g == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
gid, err := strconv.Atoi(g)
|
gid, err := strconv.Atoi(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ia, fmt.Errorf("unable to parse group id %q: %w", g, err)
|
return ia, fmt.Errorf("unable to parse group id %q: %w", g, err)
|
||||||
@ -250,6 +241,11 @@ func (ia incubatorArgs) forwadedEnviron() ([]string, string, error) {
|
|||||||
return environ, allowListKeys, nil
|
return environ, allowListKeys, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func beNetshell(args []string) error {
|
||||||
|
netshell.Main()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// beIncubator is the entrypoint to the `tailscaled be-child ssh` subcommand.
|
// beIncubator is the entrypoint to the `tailscaled be-child ssh` subcommand.
|
||||||
// It is responsible for informing the system of a new login session for the
|
// It is responsible for informing the system of a new login session for the
|
||||||
// user. This is sometimes necessary for mounting home directories and
|
// user. This is sometimes necessary for mounting home directories and
|
||||||
@ -275,6 +271,11 @@ func beIncubator(args []string) error {
|
|||||||
return fmt.Errorf("--sftp and --shell are mutually exclusive")
|
return fmt.Errorf("--sftp and --shell are mutually exclusive")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ia.isShell {
|
||||||
|
netshell.Main()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
dlogf := logger.Discard
|
dlogf := logger.Discard
|
||||||
if ia.debugTest {
|
if ia.debugTest {
|
||||||
// In testing, we don't always have syslog, so log to a temp file.
|
// In testing, we don't always have syslog, so log to a temp file.
|
||||||
@ -301,11 +302,6 @@ func handleInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
|||||||
func handleSFTPInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
func handleSFTPInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
||||||
dlogf("handling sftp")
|
dlogf("handling sftp")
|
||||||
|
|
||||||
sessionCloser := maybeStartLoginSession(dlogf, ia)
|
|
||||||
if sessionCloser != nil {
|
|
||||||
defer sessionCloser()
|
|
||||||
}
|
|
||||||
|
|
||||||
return serveSFTP()
|
return serveSFTP()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,10 +328,6 @@ func serveSFTP() error {
|
|||||||
// specified values, and then launches the requested `--cmd` in the user's
|
// specified values, and then launches the requested `--cmd` in the user's
|
||||||
// login shell.
|
// login shell.
|
||||||
func handleSSHInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
func handleSSHInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
||||||
sessionCloser := maybeStartLoginSession(dlogf, ia)
|
|
||||||
if sessionCloser != nil {
|
|
||||||
defer sessionCloser()
|
|
||||||
}
|
|
||||||
|
|
||||||
environ, _, err := ia.forwadedEnviron()
|
environ, _, err := ia.forwadedEnviron()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -344,7 +336,7 @@ func handleSSHInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
|||||||
|
|
||||||
args := shellArgs(ia.isShell, ia.cmd)
|
args := shellArgs(ia.isShell, ia.cmd)
|
||||||
dlogf("running %s %q", ia.loginShell, args)
|
dlogf("running %s %q", ia.loginShell, args)
|
||||||
cmd := newCommand(ia.hasTTY, ia.loginShell, environ, args)
|
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
|
||||||
@ -361,23 +353,13 @@ func handleSSHInProcess(dlogf logger.Logf, ia incubatorArgs) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCommand(hasTTY bool, cmdPath string, cmdEnviron []string, cmdArgs []string) *exec.Cmd {
|
func newCommand(cmdPath string, cmdEnviron []string, cmdArgs []string) *exec.Cmd {
|
||||||
cmd := exec.Command(cmdPath, cmdArgs...)
|
cmd := exec.Command(cmdPath, cmdArgs...)
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
cmd.Env = cmdEnviron
|
cmd.Env = cmdEnviron
|
||||||
|
|
||||||
if hasTTY {
|
|
||||||
// If we were launched with a tty then we should mark that as the ctty
|
|
||||||
// of the child. However, as the ctty is being passed from the parent
|
|
||||||
// we set the child to foreground instead which also passes the ctty.
|
|
||||||
// However, we can not do this if never had a tty to begin with.
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
||||||
// XXX TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user