// makeSession initializes a gossh.Session connected to the invoking process's stdout/stderr/stdout. // If the invoking session is a terminal, a TTY will be requested for the SSH session. // It returns a gossh.Session, a finalizing function used to clean up after the session terminates, // and any error encountered in setting up the session. func makeSession(client *SSHForwardingClient) (session *gossh.Session, finalize func(), err error) { session, err = client.NewSession() if err != nil { return } if err = client.ForwardAgentAuthentication(session); err != nil { return } session.Stdout = os.Stdout session.Stderr = os.Stderr session.Stdin = os.Stdin modes := gossh.TerminalModes{ gossh.ECHO: 1, // enable echoing gossh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud gossh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } fd := int(os.Stdin.Fd()) if terminal.IsTerminal(fd) { var termWidth, termHeight int var oldState *terminal.State oldState, err = terminal.MakeRaw(fd) if err != nil { return } finalize = func() { session.Close() terminal.Restore(fd, oldState) } termWidth, termHeight, err = terminal.GetSize(fd) if err != nil { return } err = session.RequestPty("xterm-256color", termHeight, termWidth, modes) } else { finalize = func() { session.Close() } } return }
func Shell(client *SSHForwardingClient) error { session, err := client.NewSession() if err != nil { return err } defer session.Close() if err = client.ForwardAgentAuthentication(session); err != nil { return err } modes := gossh.TerminalModes{ gossh.ECHO: 1, // enable echoing gossh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud gossh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud } fd := int(os.Stdin.Fd()) oldState, err := terminal.MakeRaw(fd) defer terminal.Restore(fd, oldState) termWidth, termHeight, err := terminal.GetSize(fd) if err != nil { return err } session.Stdout = os.Stdout session.Stderr = os.Stderr session.Stdin = os.Stdin if err := session.RequestPty("xterm-256color", termHeight, termWidth, modes); err != nil { return err } if err = session.Shell(); err != nil { return err } session.Wait() return nil }