tailscale: Add tailssh server
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
//go:build with_gvisor && !windows
|
||||
|
||||
package tailssh
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing/common"
|
||||
)
|
||||
|
||||
type platformShellBackend struct {
|
||||
platform adapter.PlatformInterface
|
||||
}
|
||||
|
||||
func (b *platformShellBackend) OpenSession(request shellRequest) (shellSession, error) {
|
||||
session, err := b.platform.OpenShellSession(request.User, request.Command, request.Env, request.Term, int32(request.Rows), int32(request.Cols))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dupFd, err := syscall.Dup(int(session.MasterFD()))
|
||||
if err != nil {
|
||||
session.Close()
|
||||
return nil, err
|
||||
}
|
||||
master := os.NewFile(uintptr(dupFd), "pty-master")
|
||||
return &platformShellSession{
|
||||
session: session,
|
||||
master: master,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *platformShellBackend) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type platformShellSession struct {
|
||||
session adapter.ShellSession
|
||||
master *os.File
|
||||
}
|
||||
|
||||
func (s *platformShellSession) Read(p []byte) (int, error) {
|
||||
return s.master.Read(p)
|
||||
}
|
||||
|
||||
func (s *platformShellSession) Write(p []byte) (int, error) {
|
||||
return s.master.Write(p)
|
||||
}
|
||||
|
||||
func (s *platformShellSession) Close() error {
|
||||
return common.Close(s.master, s.session)
|
||||
}
|
||||
|
||||
func (s *platformShellSession) CloseWrite() error {
|
||||
// The platform owns the master fd lifecycle; rely on Close for teardown.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *platformShellSession) Resize(rows, cols uint16) error {
|
||||
return s.session.Resize(int32(rows), int32(cols))
|
||||
}
|
||||
|
||||
func (s *platformShellSession) Signal(sig int) error {
|
||||
return s.session.Signal(int32(sig))
|
||||
}
|
||||
|
||||
func (s *platformShellSession) Wait() (uint32, error) {
|
||||
exitStatus, err := s.session.WaitExit()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(exitStatus), nil
|
||||
}
|
||||
Reference in New Issue
Block a user