Created an SSH connection using ssh.Dial, and opened a Listener to listen on a port without specifying a host address. Then connected to that port (i.e. using telnet).
This program demonstrates the issue:
package main
import (
"io/ioutil"
"log"
"os"
"path"
"golang.org/x/crypto/ssh"
)
func buildSshConfig(user, keyfile string) (conf *ssh.ClientConfig) {
key, err := ioutil.ReadFile(keyfile)
if err != nil {
log.Fatal("unable to build ssh config: ", err)
}
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
log.Fatal("unable to build ssh config: ", err)
}
conf = &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
// Use the PublicKeys method for remote authentication.
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
return
}
func main() {
config := buildSshConfig(os.Getenv("USER"),
path.Join(os.Getenv("HOME"), ".ssh/id_rsa"))
conn, err := ssh.Dial("tcp", "localhost:22", config)
if err != nil {
log.Fatal("unable to connect: ", err)
}
defer conn.Close()
// Request the remote side to open port 8080
l, err := conn.Listen("tcp", ":8080")
if err != nil {
log.Fatal("unable to register tcp forward: ", err)
}
defer l.Close()
log.Println("Calling Accept")
l.Accept()
log.Println("Accept returned")
}
What did you expect to see?
Calling Accept
Accept Returned
What did you see instead?
Calling Accept
Additional Info
It seems that if the local address is not specified in ssh.Client.Listen, the Accept call blocks indefinitely. For example this line fails in the above program:
l, err := conn.Listen("tcp", ":8080")
But when changed to this it succeeds:
l, err := conn.Listen("tcp", "127.0.0.1:8080")
The host may be omitted in net.Listen, so there is precedent for using no host. From net.Listen: "For TCP networks, if the host in the address parameter is empty or a literal unspecified IP address, Listen listens on all available unicast and anycast IP addresses of the local system."
I think at a minimum if host may not be omitted, the documentation should mention that it is not supported, and the Listen call should return an error.
What version of Go are you using (
go version
)?What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Created an SSH connection using ssh.Dial, and opened a Listener to listen on a port without specifying a host address. Then connected to that port (i.e. using telnet).
This program demonstrates the issue:
What did you expect to see?
What did you see instead?
Additional Info
It seems that if the local address is not specified in ssh.Client.Listen, the Accept call blocks indefinitely. For example this line fails in the above program:
But when changed to this it succeeds:
The host may be omitted in net.Listen, so there is precedent for using no host. From net.Listen: "For TCP networks, if the host in the address parameter is empty or a literal unspecified IP address, Listen listens on all available unicast and anycast IP addresses of the local system."
I think at a minimum if host may not be omitted, the documentation should mention that it is not supported, and the Listen call should return an error.