From 8a87f1b41ff795e5175f5e75cb803c9edaedc48c Mon Sep 17 00:00:00 2001 From: bergyu Date: Mon, 22 Nov 2021 14:50:15 +0800 Subject: [PATCH] opt some --- misc/ssh/service_darwin.go | 85 +++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) mode change 120000 => 100644 misc/ssh/service_darwin.go diff --git a/misc/ssh/service_darwin.go b/misc/ssh/service_darwin.go deleted file mode 120000 index cb5b2c72..00000000 --- a/misc/ssh/service_darwin.go +++ /dev/null @@ -1 +0,0 @@ -service_linux.go \ No newline at end of file diff --git a/misc/ssh/service_darwin.go b/misc/ssh/service_darwin.go new file mode 100644 index 00000000..d6911479 --- /dev/null +++ b/misc/ssh/service_darwin.go @@ -0,0 +1,84 @@ +package ssh + +import ( + "encoding/binary" + "io" + "net" + "os" + "syscall" + "unsafe" + + "github.com/kr/pty" + "golang.org/x/crypto/ssh" + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/tcp" + kit "shylinux.com/x/toolkits" +) + +type Winsize struct{ Height, Width, x, y uint16 } + +func _ssh_size(fd uintptr, b []byte) { + w := binary.BigEndian.Uint32(b) + h := binary.BigEndian.Uint32(b[4:]) + + ws := &Winsize{Width: uint16(w), Height: uint16(h)} + syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws))) +} +func _ssh_sizes(fd uintptr, w, h int) { + ws := &Winsize{Width: uint16(w), Height: uint16(h)} + syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws))) +} +func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh.Channel, requests <-chan *ssh.Request) { + m.Logs(CHANNEL, tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr()) + defer m.Logs("dischan", tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr()) + + shell := kit.Select("bash", os.Getenv("SHELL")) + list := []string{cli.PATH + "=" + os.Getenv(cli.PATH)} + + pty, tty, err := pty.Open() + if m.Warn(err) { + return + } + defer tty.Close() + + h := m.Rich(CHANNEL, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, TTY, tty.Name(), INPUT, pty, OUTPUT, tty, meta)) + meta[CHANNEL] = h + + for request := range requests { + m.Logs(REQUEST, tcp.HOSTPORT, c.RemoteAddr(), kit.MDB_TYPE, request.Type) + + switch request.Type { + case "pty-req": + termLen := request.Payload[3] + termEnv := string(request.Payload[4 : termLen+4]) + _ssh_size(pty.Fd(), request.Payload[termLen+4:]) + list = append(list, "TERM="+termEnv) + + case "window-change": + _ssh_size(pty.Fd(), request.Payload) + + case "env": + var env struct{ Name, Value string } + if err := ssh.Unmarshal(request.Payload, &env); err != nil { + continue + } + list = append(list, env.Name+"="+env.Value) + + case "exec": + _ssh_exec(m, shell, []string{"-c", string(request.Payload[4 : request.Payload[3]+4])}, list, channel, channel, func() { + channel.Close() + }) + case "shell": + _ssh_watch(m, meta, h, channel, pty) + m.Go(func() { io.Copy(channel, pty) }) + + _ssh_exec(m, shell, nil, list, tty, tty, func() { + defer m.Cmd(mdb.MODIFY, CHANNEL, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, tcp.CLOSE) + _ssh_close(m, c, channel) + }) + } + request.Reply(true, nil) + } +}