mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-08 17:24:57 +00:00
Merge a79da6ca31880428f0be7c7139bdfc4b8bd46e73 into b3455fa99a5e8d07133d5140017ec7c49f032a07
This commit is contained in:
commit
4ffccfcd5f
@ -12,11 +12,13 @@
|
|||||||
package tailssh
|
package tailssh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
"os"
|
"os"
|
||||||
@ -29,6 +31,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/creack/pty"
|
"github.com/creack/pty"
|
||||||
"github.com/pkg/sftp"
|
"github.com/pkg/sftp"
|
||||||
@ -70,6 +73,27 @@ var maybeStartLoginSession = func(dlogf logger.Logf, ia incubatorArgs) (close fu
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tryExecInDir tries to run a command in dir and returns nil if it succeeds.
|
||||||
|
// Otherwise, it returns a filesystem error or a timeout error if the command
|
||||||
|
// took too long.
|
||||||
|
func tryExecInDir(ctx context.Context, dir string) error {
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Assume that the following executables are executable over SSH.
|
||||||
|
var name string
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
name = "doskey"
|
||||||
|
default:
|
||||||
|
name = "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, name)
|
||||||
|
cmd.Dir = dir
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
// newIncubatorCommand returns a new exec.Cmd configured with
|
// newIncubatorCommand returns a new exec.Cmd configured with
|
||||||
// `tailscaled be-child ssh` as the entrypoint.
|
// `tailscaled be-child ssh` as the entrypoint.
|
||||||
//
|
//
|
||||||
@ -104,7 +128,23 @@ 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())
|
args := shellArgs(isShell, ss.RawCommand())
|
||||||
logf("directly running %s %q", loginShell, args)
|
logf("directly running %s %q", loginShell, args)
|
||||||
return exec.CommandContext(ss.ctx, loginShell, args...), nil
|
cmd = exec.CommandContext(ss.ctx, loginShell, args...)
|
||||||
|
|
||||||
|
// While running directly instead of using `tailscaled be-child`,
|
||||||
|
// do what sshd does by running inside the home directory.
|
||||||
|
cmd.Dir = ss.conn.localUser.HomeDir
|
||||||
|
if err := tryExecInDir(ss.ctx, cmd.Dir); err != nil {
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, fs.ErrPermission) || errors.Is(err, fs.ErrNotExist):
|
||||||
|
// If we cannot run loginShell in localUser.HomeDir,
|
||||||
|
// we will try to run this command in the root directory.
|
||||||
|
cmd.Dir = "/"
|
||||||
|
case err != nil:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
lu := ss.conn.localUser
|
lu := ss.conn.localUser
|
||||||
@ -178,7 +218,10 @@ func (ss *sshSession) newIncubatorCommand(logf logger.Logf) (cmd *exec.Cmd, err
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return exec.CommandContext(ss.ctx, ss.conn.srv.tailscaledPath, incubatorArgs...), nil
|
cmd = exec.CommandContext(ss.ctx, ss.conn.srv.tailscaledPath, incubatorArgs...)
|
||||||
|
// The incubator will chdir into the home directory after it drops privileges.
|
||||||
|
cmd.Dir = "/"
|
||||||
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var debugIncubator bool
|
var debugIncubator bool
|
||||||
@ -777,7 +820,6 @@ func (ss *sshSession) launchProcess() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd := ss.cmd
|
cmd := ss.cmd
|
||||||
cmd.Dir = "/"
|
|
||||||
cmd.Env = envForUser(ss.conn.localUser)
|
cmd.Env = envForUser(ss.conn.localUser)
|
||||||
for _, kv := range ss.Environ() {
|
for _, kv := range ss.Environ() {
|
||||||
if acceptEnvPair(kv) {
|
if acceptEnvPair(kv) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user