douchongbang6011 2016-08-18 12:18
浏览 43

Golang中的交互式安全外壳无法捕获所有键盘

I am trying to start an interactive SSH session with a remote computer using Golang. I was able to get that without any problems, but the pseudo terminal doesn't seem to be capturing all of the keyboard i/o correctly.

For example, if I run a regular SSH command like,

ssh -i ~/.ssh/some-key.pem username@1.1.1.1

I can exit with a simple Ctrl+d, but for some reason when I run the interactive shell started with Golang it's not working and only prints the actual key characters ^D. Same goes for trying to use the arrow keys. If I run a Ctrl+c it exits the original Golang process and kills the interactive shell rather than executing on the remote machine.

Below is my code for setting up the shell,

func StartInteractiveShell(sshConfig *ssh.ClientConfig, network string, host string, port string) error {
    var (
        session *ssh.Session
        conn    *ssh.Client
        err     error
    )    
    if conn, err = getSshConnection(sshConfig, network, host, port); err != nil {
        fmt.Printf("Failed to dial: %s", err)
        return err   
    }

    if session, err = getSshSession(conn); err != nil {
        fmt.Printf("Failed to create session: %s", err)
        return err
    }
    defer session.Close()

    if err = setupPty(session); err != nil {
        fmt.Printf("Failed to set up pseudo terminal: %s", err)
        return err
    }

    session.Stdout = os.Stdout
    session.Stdin  = os.Stdin
    session.Stderr = os.Stderr

    if err = session.Shell(); err != nil {
        fmt.Printf("Failed to start interactive shell: %s", err)
        return err
    }
    return session.Wait()
}

func getSshConnection(config *ssh.ClientConfig, network string, host string, port string) (*ssh.Client, error) {
    addr := host + ":" + port
    return ssh.Dial(network, addr, config)
}

func getSshSession(clientConnection *ssh.Client) (*ssh.Session, error) {
    return clientConnection.NewSession()
}

// pty = pseudo terminal
func setupPty(session *ssh.Session) error {
    modes := ssh.TerminalModes{
        ssh.ECHO:          0,     // disable echoing
        ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }

    if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
        session.Close()
        fmt.Printf("request for pseudo terminal failed: %s", err)
        return err
    }
    return nil
}

Am I missing something there?

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
    • ¥50 我撰写的python爬虫爬不了 要爬的网址有反爬机制
    • ¥15 Centos / PETSc / PETGEM
    • ¥15 centos7.9 IPv6端口telnet和端口监控问题
    • ¥120 计算机网络的新校区组网设计
    • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
    • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
    • ¥20 海浪数据 南海地区海况数据,波浪数据
    • ¥20 软件测试决策法疑问求解答
    • ¥15 win11 23H2删除推荐的项目,支持注册表等