|
|
@ -10,7 +10,7 @@ import (
|
|
|
|
"syscall"
|
|
|
|
"syscall"
|
|
|
|
"time"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/creack/pty"
|
|
|
|
"github.com/containerd/console"
|
|
|
|
"github.com/fangdingjun/go-log"
|
|
|
|
"github.com/fangdingjun/go-log"
|
|
|
|
"github.com/pkg/sftp"
|
|
|
|
"github.com/pkg/sftp"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
|
|
"golang.org/x/crypto/ssh"
|
|
|
@ -178,7 +178,8 @@ func (sc *Server) handleSession(newch ssh.NewChannel) {
|
|
|
|
var env []string
|
|
|
|
var env []string
|
|
|
|
var _ptyReq ptyReq
|
|
|
|
var _ptyReq ptyReq
|
|
|
|
var _windowChange windowChange
|
|
|
|
var _windowChange windowChange
|
|
|
|
var _pty, _tty *os.File
|
|
|
|
var _console console.Console
|
|
|
|
|
|
|
|
var ptsname string
|
|
|
|
|
|
|
|
|
|
|
|
for r := range req {
|
|
|
|
for r := range req {
|
|
|
|
switch r.Type {
|
|
|
|
switch r.Type {
|
|
|
@ -204,7 +205,7 @@ func (sc *Server) handleSession(newch ssh.NewChannel) {
|
|
|
|
cmd = exec.Command("bash", "-l")
|
|
|
|
cmd = exec.Command("bash", "-l")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cmd.Env = env
|
|
|
|
cmd.Env = env
|
|
|
|
go handleShell(cmd, ch, _pty, _tty)
|
|
|
|
go handleShell(cmd, ch, _console, ptsname)
|
|
|
|
case "signal":
|
|
|
|
case "signal":
|
|
|
|
log.Debugln("got signal")
|
|
|
|
log.Debugln("got signal")
|
|
|
|
ret = true
|
|
|
|
ret = true
|
|
|
@ -233,28 +234,25 @@ func (sc *Server) handleSession(newch ssh.NewChannel) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Debugf("pty req %+v", _ptyReq)
|
|
|
|
log.Debugf("pty req %+v", _ptyReq)
|
|
|
|
if err == nil && (runtime.GOOS == "unix" || runtime.GOOS == "linux") {
|
|
|
|
if err == nil && (runtime.GOOS == "unix" || runtime.GOOS == "linux") {
|
|
|
|
_pty, _tty, err = pty.Open()
|
|
|
|
_console, ptsname, err = console.NewPty()
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
|
|
|
|
log.Debugf("allocate pty %s", ptsname)
|
|
|
|
|
|
|
|
env = append(env, fmt.Sprintf("SSH_TTY=%s", ptsname))
|
|
|
|
|
|
|
|
ws, err := _console.Size()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Errorln(err)
|
|
|
|
log.Errorln(err)
|
|
|
|
ret = false
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
env = append(env, fmt.Sprintf("TERM=%s", _ptyReq.Term))
|
|
|
|
log.Debugf("current console %+v", ws)
|
|
|
|
size, err := pty.GetsizeFull(_pty)
|
|
|
|
ws.Height = uint16(_ptyReq.Rows)
|
|
|
|
if err == nil {
|
|
|
|
ws.Width = uint16(_ptyReq.Columns)
|
|
|
|
log.Debugf("term size %+v", size)
|
|
|
|
if err = _console.Resize(ws); err != nil {
|
|
|
|
size.Rows = uint16(_ptyReq.Rows)
|
|
|
|
|
|
|
|
size.Cols = uint16(_ptyReq.Columns)
|
|
|
|
|
|
|
|
if err = pty.Setsize(_pty, size); err != nil {
|
|
|
|
|
|
|
|
log.Errorln(err)
|
|
|
|
log.Errorln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err = pty.Setsize(_tty, size); err != nil {
|
|
|
|
|
|
|
|
log.Errorln(err)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
log.Errorln(err)
|
|
|
|
log.Errorln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case "env":
|
|
|
|
case "env":
|
|
|
|
var arg envArgs
|
|
|
|
var arg envArgs
|
|
|
|
ret = true
|
|
|
|
ret = true
|
|
|
@ -272,22 +270,19 @@ func (sc *Server) handleSession(newch ssh.NewChannel) {
|
|
|
|
ret = false
|
|
|
|
ret = false
|
|
|
|
log.Errorln(err)
|
|
|
|
log.Errorln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err == nil && _pty != nil {
|
|
|
|
if err == nil && _console != nil {
|
|
|
|
size, err := pty.GetsizeFull(_pty)
|
|
|
|
ws, err := _console.Size()
|
|
|
|
if err == nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Debugf("term size %+v", size)
|
|
|
|
|
|
|
|
size.Rows = uint16(_ptyReq.Rows)
|
|
|
|
|
|
|
|
size.Cols = uint16(_ptyReq.Columns)
|
|
|
|
|
|
|
|
if err = pty.Setsize(_pty, size); err != nil {
|
|
|
|
|
|
|
|
log.Errorln(err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = pty.Setsize(_tty, size); err != nil {
|
|
|
|
|
|
|
|
log.Errorln(err)
|
|
|
|
log.Errorln(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
log.Debugf("current console %+v", ws)
|
|
|
|
|
|
|
|
ws.Height = uint16(_windowChange.Rows)
|
|
|
|
|
|
|
|
ws.Width = uint16(_windowChange.Columns)
|
|
|
|
|
|
|
|
if err = _console.Resize(ws); err != nil {
|
|
|
|
log.Errorln(err)
|
|
|
|
log.Errorln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
log.Debugf("window change %+v", _windowChange)
|
|
|
|
log.Debugf("window change %+v", _windowChange)
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
ret = false
|
|
|
|
ret = false
|
|
|
@ -301,12 +296,11 @@ func (sc *Server) handleSession(newch ssh.NewChannel) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func handleShell(cmd *exec.Cmd, ch ssh.Channel, _pty, _tty *os.File) {
|
|
|
|
func handleShell(cmd *exec.Cmd, ch ssh.Channel, _console console.Console, ptsname string) {
|
|
|
|
defer func() {
|
|
|
|
defer func() {
|
|
|
|
ch.Close()
|
|
|
|
ch.Close()
|
|
|
|
if _pty != nil {
|
|
|
|
if _console != nil {
|
|
|
|
_pty.Close()
|
|
|
|
_console.Close()
|
|
|
|
_tty.Close()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
@ -314,7 +308,13 @@ func handleShell(cmd *exec.Cmd, ch ssh.Channel, _pty, _tty *os.File) {
|
|
|
|
|
|
|
|
|
|
|
|
log.Infoln("start shell")
|
|
|
|
log.Infoln("start shell")
|
|
|
|
|
|
|
|
|
|
|
|
if _tty != nil {
|
|
|
|
if _console != nil {
|
|
|
|
|
|
|
|
_tty, err := os.OpenFile(ptsname, syscall.O_RDWR|syscall.O_NOCTTY, 0600)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
log.Errorln(err)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
defer _tty.Close()
|
|
|
|
cmd.Stderr = _tty
|
|
|
|
cmd.Stderr = _tty
|
|
|
|
cmd.Stdout = _tty
|
|
|
|
cmd.Stdout = _tty
|
|
|
|
cmd.Stdin = _tty
|
|
|
|
cmd.Stdin = _tty
|
|
|
@ -323,10 +323,10 @@ func handleShell(cmd *exec.Cmd, ch ssh.Channel, _pty, _tty *os.File) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cmd.SysProcAttr.Setsid = true
|
|
|
|
cmd.SysProcAttr.Setsid = true
|
|
|
|
cmd.SysProcAttr.Setctty = true
|
|
|
|
cmd.SysProcAttr.Setctty = true
|
|
|
|
cmd.SysProcAttr.Ctty = int(_tty.Fd())
|
|
|
|
// cmd.SysProcAttr.Ctty = int(_tty.Fd())
|
|
|
|
|
|
|
|
|
|
|
|
go io.Copy(ch, _pty)
|
|
|
|
go io.Copy(ch, _console)
|
|
|
|
go io.Copy(_pty, ch)
|
|
|
|
go io.Copy(_console, ch)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
cmd.Stderr = ch
|
|
|
|
cmd.Stderr = ch
|
|
|
|
cmd.Stdout = ch
|
|
|
|
cmd.Stdout = ch
|
|
|
|