From 1808cc8307afa123925a7c79e032ae4b904ca2b9 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Fri, 4 Feb 2022 12:12:11 -0300 Subject: [PATCH] fix: handle escape sequences properly (#33) * fix: import Signed-off-by: Carlos A Becker * fix: ctrl+d et al * wip Signed-off-by: Carlos A Becker * wip Signed-off-by: Carlos A Becker * fix: windows * fix: simplify Signed-off-by: Carlos A Becker * fix: deps Signed-off-by: Carlos A Becker --- client_auth.go | 2 +- client_local.go | 22 +++++++++++++++++++--- client_remote.go | 5 ++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/client_auth.go b/client_auth.go index ea0d8ac..f7f5e4c 100644 --- a/client_auth.go +++ b/client_auth.go @@ -211,7 +211,7 @@ func parsePrivateKey(path string, password []byte) (gossh.AuthMethod, error) { pwderr := &gossh.PassphraseMissingError{} if errors.As(err, &pwderr) { fmt.Printf("Enter the password for %q: ", path) - password, err = term.ReadPassword(int(os.Stdin.Fd())) + password, err := term.ReadPassword(int(os.Stdin.Fd())) fmt.Println() if err != nil { return nil, fmt.Errorf("failed to read password: %q", err) diff --git a/client_local.go b/client_local.go index 6508fee..1dca980 100644 --- a/client_local.go +++ b/client_local.go @@ -8,7 +8,7 @@ import ( "os/user" "path/filepath" - gossh "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" "golang.org/x/term" ) @@ -30,7 +30,7 @@ func (c *localClient) Connect(e *Endpoint) error { if err != nil { return fmt.Errorf("failed to setup a authentication method: %w", err) } - conf := &gossh.ClientConfig{ + conf := &ssh.ClientConfig{ User: firstNonEmpty(e.User, user.Username), Auth: methods, HostKeyCallback: hostKeyCallback(e, filepath.Join(user.HomeDir, ".ssh/known_hosts")), @@ -64,8 +64,24 @@ func (c *localClient) Connect(e *Endpoint) error { } if e.RequestTTY || e.RemoteCommand == "" { + fd := int(os.Stdout.Fd()) + if !term.IsTerminal(fd) { + return fmt.Errorf("requested a TTY, but current session is not TTY, aborting") + } + log.Println("requesting tty") - w, h, err := term.GetSize(int(os.Stdout.Fd())) + originalState, err := term.MakeRaw(fd) + if err != nil { + return fmt.Errorf("failed get terminal state: %w", err) + } + + defer func() { + if err := term.Restore(fd, originalState); err != nil { + log.Println("couldn't restore terminal state:", err) + } + }() + + w, h, err := term.GetSize(fd) if err != nil { return fmt.Errorf("failed to get term size: %w", err) } diff --git a/client_remote.go b/client_remote.go index a7d5991..22067aa 100644 --- a/client_remote.go +++ b/client_remote.go @@ -58,7 +58,10 @@ func (c *remoteClient) Connect(e *Endpoint) error { if e.RemoteCommand == "" || e.RequestTTY { log.Println("requesting tty") - pty, winch, _ := c.session.Pty() + pty, winch, ok := c.session.Pty() + if !ok { + return fmt.Errorf("requested a tty, but current session doesn't allow one") + } w := pty.Window if err := session.RequestPty(pty.Term, w.Height, w.Width, nil); err != nil { return fmt.Errorf("failed to request pty: %w", err)