func (s *Session) HandleChannelRequest(channel ssh.Channel, in <-chan *ssh.Request) { for req := range in { switch req.Type { case "shell": if len(req.Payload) == 0 { if err := req.Reply(true, nil); err != nil { log.Printf("Unable to reply to channel request (%s)", err) continue } go s.HandleNewTerminal(channel) } case "pty-req": termLen := req.Payload[3] w, h := ParseTerminalDims(req.Payload[termLen+4:]) s.WinH = uint16(h) s.WinW = uint16(w) if err := req.Reply(true, nil); err != nil { log.Printf("Unable to reply to channel request (%s)", err) } case "window-change": w := &win.Winsize{ Height: uint16(binary.BigEndian.Uint32(req.Payload[4:])), Width: uint16(binary.BigEndian.Uint32(req.Payload)), } if err := win.SetWinsize(s.pty.Fd(), w); err != nil { log.Printf("Unable to set window-change (%s)", err) } case "close": if err := channel.Close(); err != nil { log.Printf("Unable to close channel (%s)", err) } case "default": log.Printf("Invalid Request Type (%s)", req.Type) } } }
func (s *Session) HandleNewTerminal(channel ssh.Channel) { cmd := exec.Command("/bin/bash") cmd.Dir = "/home/dc0" f, err := pty.Start(cmd) if err != nil { log.Printf("Could not start pty (%s)", err) } s.pty = f w := &win.Winsize{ Height: s.WinH, Width: s.WinH, } if err := win.SetWinsize(s.pty.Fd(), w); err != nil { log.Printf("Unable to set window-change (%s)", err) } // Copy Request go func(in io.ReadCloser, out io.WriteCloser) { defer in.Close() defer out.Close() if _, err := io.Copy(out, in); err != nil { log.Printf("CopyRequest: io.Copy: %s\n", err) } }(channel, s.pty) // Copy Response go func(out io.ReadCloser, in io.WriteCloser) { defer out.Close() defer in.Close() if _, err := io.Copy(in, out); err != nil { log.Printf("CopyResponse: io.Copy: %s\n", err) } }(s.pty, channel) }