mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-06-29 04:01:23 +00:00
100 lines
2.5 KiB
Go
100 lines
2.5 KiB
Go
//go:build with_gvisor && !windows
|
|
|
|
package tailssh
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"syscall"
|
|
|
|
gliderssh "github.com/sagernet/gliderssh"
|
|
"github.com/sagernet/sing-box/adapter"
|
|
)
|
|
|
|
func isPrivilegedUser() bool {
|
|
return os.Getuid() == 0
|
|
}
|
|
|
|
func requestedUserMatchesProcess(localUser *adapter.PlatformUser) (bool, error) {
|
|
return localUser.Uid == os.Getuid() && localUser.Gid == os.Getgid(), nil
|
|
}
|
|
|
|
// verifyShellIdentity is a no-op on Unix: spawned shells and sftp-server drop to the
|
|
// requested user via setCredential, so the child already runs as that user.
|
|
func verifyShellIdentity(_ *adapter.PlatformUser) error {
|
|
return nil
|
|
}
|
|
|
|
func systemHostKeyPath() string {
|
|
return "/etc/ssh/ssh_host_ed25519_key"
|
|
}
|
|
|
|
func defaultPathEnv() string {
|
|
return "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
}
|
|
|
|
func userSocketDirectories(localUser *adapter.PlatformUser) []string {
|
|
return gliderssh.UserSocketDirectories(localUser.HomeDir, strconv.Itoa(localUser.Uid))
|
|
}
|
|
|
|
// prepareAgentSocket hands the agent-forwarding socket to the target user so
|
|
// SSH_AUTH_SOCK stays reachable after the shell drops privileges. No-op when the
|
|
// shell runs as the server identity.
|
|
func prepareAgentSocket(socketPath string, uid, gid int) error {
|
|
if uid < 0 || uid == os.Getuid() {
|
|
return nil
|
|
}
|
|
err := os.Chown(socketPath, uid, gid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.Chmod(socketPath, 0o600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Make the MkdirTemp parent traversable so the dropped-privilege child can
|
|
// reach the socket.
|
|
return os.Chmod(filepath.Dir(socketPath), 0o755)
|
|
}
|
|
|
|
func platformEnvironment(_ *adapter.PlatformUser) []string {
|
|
return nil
|
|
}
|
|
|
|
func sftpCommand(sftpPath string) string {
|
|
return sftpPath + " 2>/dev/null"
|
|
}
|
|
|
|
func sshSignalToSyscall(sig gliderssh.Signal) int {
|
|
switch sig {
|
|
case gliderssh.SIGABRT:
|
|
return int(syscall.SIGABRT)
|
|
case gliderssh.SIGALRM:
|
|
return int(syscall.SIGALRM)
|
|
case gliderssh.SIGFPE:
|
|
return int(syscall.SIGFPE)
|
|
case gliderssh.SIGHUP:
|
|
return int(syscall.SIGHUP)
|
|
case gliderssh.SIGILL:
|
|
return int(syscall.SIGILL)
|
|
case gliderssh.SIGINT:
|
|
return int(syscall.SIGINT)
|
|
case gliderssh.SIGKILL:
|
|
return int(syscall.SIGKILL)
|
|
case gliderssh.SIGPIPE:
|
|
return int(syscall.SIGPIPE)
|
|
case gliderssh.SIGQUIT:
|
|
return int(syscall.SIGQUIT)
|
|
case gliderssh.SIGSEGV:
|
|
return int(syscall.SIGSEGV)
|
|
case gliderssh.SIGTERM:
|
|
return int(syscall.SIGTERM)
|
|
case gliderssh.SIGUSR1:
|
|
return int(syscall.SIGUSR1)
|
|
case gliderssh.SIGUSR2:
|
|
return int(syscall.SIGUSR2)
|
|
default:
|
|
return 0
|
|
}
|
|
}
|