Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/crypto/ssh: connection.session.Close() returns a EOF as error instead of nil #38115

Open
harshathulasi opened this issue Mar 27, 2020 · 7 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@harshathulasi
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.14.1 darwin/amd64
$ 

Does this issue reproduce with the latest release?

Yes, I believe I am using the latest stable release.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/my_username/Library/Caches/go-build"
GOENV="/Users/my_username/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/my_username/Learn/go_learn"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/my_username/Learn/go_learn/src/my_stuff/ssh_test/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/17/vmjmghsj28d4lzrx7mqshr9r0000gp/T/go-build681325874=/tmp/go-build -gno-record-gcc-switches -fno-common"
$ 

What did you do?

My program connects to a ssh server (just my laptop in this case) and issues an ssh command closes the SSH session, and connection:

package main

import (
    "bytes"
    "fmt"
    "strings"

    "golang.org/x/crypto/ssh"
)

func main() {
    sshConfig := &ssh.ClientConfig{
        User: “my_username”,
        Auth: []ssh.AuthMethod{
            ssh.Password(“my password”),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    connection, err := ssh.Dial("tcp", "localhost:22", sshConfig)
    if err != nil {
        fmt.Printf("Failed to dial: %s\n", err)
        return
    }

    defer func() {
        if err := connection.Close(); err != nil {
            fmt.Println("Received an error closing the ssh connection: ", err)
        } else {
            fmt.Println("No error found closing ssh connection")
        }
    }()

    session, err := connection.NewSession()
    if err != nil {
        fmt.Printf("Failed to create session: %s\n", err)
        return
    }

    defer func() {
        if err := session.Close(); err != nil {
            fmt.Println("Received an error closing the ssh session: ", err)
        } else {
            fmt.Println("No error found closing ssh session")
        }
    }()
    fmt.Println("created session")
    var stdOut bytes.Buffer
    var stdErr bytes.Buffer

    session.Stdout = &stdOut
    session.Stderr = &stdErr
    err = session.Run("pwd")
    fmt.Println("Executed command")

    fmt.Println("Command stdOut is:", strings.TrimRight(stdOut.String(), "\n"), " --- stdError is:", strings.TrimRight(stdErr.String(), "\n"))
}

What did you expect to see?

At session.close(), I was expecting to see 'nil' as the output instead of any error.

What did you see instead?

I'm getting an EOF error in session.Close(). Looking at other raised issues in this forum (#16194) it sounds reasonable to get the EOF at end of Run(). However, for Close() this seems odd to have it return as an error instead the return as nil.
It could be that Im not handling something properly in terms managing the buffer or executing command or closing it. But the code I pasted above is from examples online and it looks like the working model.
EOF at close is something I can handle but to be very clear and precise I believe Close() should return nil. And EOF doesn't seem like an error either.

@gopherbot gopherbot added this to the Unreleased milestone Mar 27, 2020
@harshathulasi harshathulasi changed the title x/crypto: ssh.connection.session.Close() returns a EOF as error x/crypto: ssh.connection.session.Close() returns a EOF as error instead of nil Mar 27, 2020
@andybons andybons changed the title x/crypto: ssh.connection.session.Close() returns a EOF as error instead of nil x/crypto/ssh: connection.session.Close() returns a EOF as error instead of nil Mar 27, 2020
@andybons
Copy link
Member

Hi there,

This seems like a question rather than a report about a bug in the implementation (at least yet).

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For asking questions, see:

Please ask the question on one of the above forums.

(Quoted from https://golang.org/wiki/Questions)

@harshathulasi
Copy link
Author

Hi,
I did raise a question on stackoverflow: https://stackoverflow.com/questions/60879023/getting-eof-as-error-in-golang-ssh-session-close

However, this was recognized as a bug.

@andybons
Copy link
Member

Sounds good. Re-opening.

@FiloSottile @hanwen

@andybons andybons reopened this Mar 28, 2020
@andybons andybons added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 28, 2020
@hanwen
Copy link
Contributor

hanwen commented Mar 30, 2020

it looks like this happens when running against OpenSSH. Can you provide a repro of Go SSH running against itself?

I'm asking because there might be some configuration that on SSH server that tears down the connection if a Session is finished.

@harshathulasi
Copy link
Author

Is there an example of the Go SSH server I can try to run or that might help debug for you? I never ran a SSH server, usually test against another host that I can ssh to (which I guess normally run OpenSSH).
I tried this one https://gist.github.com/jpillora/b480fde82bff51a06238 but its having trouble opening a bash session on my pc. Not sure if its a permissions issue or something else.

@4mig4
Copy link

4mig4 commented Aug 5, 2021

I am having the same problem

go version go1.16.6 linux/amd64

@adonovan
Copy link
Member

adonovan commented Sep 3, 2021

I notice a similar problem (nonsensical io.EOF returned by Close) from the Close method of the *ssh.channel data type too.

The likely cause is channel.Close -> channel.sendMessage-> channel.writePacket, which returns EOF if a close has already occurred, suggesting an application bug, but nonetheless, EOF is the wrong error in that situation.

https://cs.opensource.google/go/x/crypto/+/32db7946:ssh/channel.go;l=208;drc=32db794688a5a24a23a43f2a984cecd5b3d8da58

[Update: on further investigation, the sentClose field was true because the ssh mux loop received a close packet from the peer, and handled it by sending a close packet in response, then calling ch.close, which sets sentClose. The application only called Close once on the result of OpenChannel.]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants