go.crypto/ssh: clean up address parsing in forward code.
LGTM=agl R=agl, dave, jpsugar CC=golang-codereviews https://golang.org/cl/134700043
This commit is contained in:
Родитель
fc84ae5437
Коммит
72116d5c17
|
@ -159,25 +159,6 @@ func (c *Client) handleChannelOpens(in <-chan NewChannel) {
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr.
|
|
||||||
// RFC 4254 section 7.2 is mute on what to do if parsing fails but the forwardlist
|
|
||||||
// requires a valid *net.TCPAddr to operate, so we enforce that restriction here.
|
|
||||||
func parseTCPAddr(b []byte) (*net.TCPAddr, []byte, bool) {
|
|
||||||
addr, b, ok := parseString(b)
|
|
||||||
if !ok {
|
|
||||||
return nil, b, false
|
|
||||||
}
|
|
||||||
port, b, ok := parseUint32(b)
|
|
||||||
if !ok || port == 0 || port > 65535 {
|
|
||||||
return nil, b, false
|
|
||||||
}
|
|
||||||
ip := net.ParseIP(string(addr))
|
|
||||||
if ip == nil {
|
|
||||||
return nil, b, false
|
|
||||||
}
|
|
||||||
return &net.TCPAddr{IP: ip, Port: int(port)}, b, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial starts a client connection to the given SSH server. It is a
|
// Dial starts a client connection to the given SSH server. It is a
|
||||||
// convenience function that connects to the given network address,
|
// convenience function that connects to the given network address,
|
||||||
// initiates the SSH handshake, and then sets up a Client. For access
|
// initiates the SSH handshake, and then sets up a Client. For access
|
||||||
|
|
44
ssh/tcpip.go
44
ssh/tcpip.go
|
@ -154,19 +154,47 @@ func (l *forwardList) add(addr net.TCPAddr) chan forward {
|
||||||
return f.c
|
return f.c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See RFC 4254, section 7.2
|
||||||
|
type forwardedTCPPayload struct {
|
||||||
|
Addr string
|
||||||
|
Port uint32
|
||||||
|
OriginAddr string
|
||||||
|
OriginPort uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr.
|
||||||
|
func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) {
|
||||||
|
if port == 0 || port > 65535 {
|
||||||
|
return nil, fmt.Errorf("ssh: port number out of range: %d", port)
|
||||||
|
}
|
||||||
|
ip := net.ParseIP(string(addr))
|
||||||
|
if ip == nil {
|
||||||
|
return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr)
|
||||||
|
}
|
||||||
|
return &net.TCPAddr{IP: ip, Port: int(port)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (l *forwardList) handleChannels(in <-chan NewChannel) {
|
func (l *forwardList) handleChannels(in <-chan NewChannel) {
|
||||||
for ch := range in {
|
for ch := range in {
|
||||||
laddr, rest, ok := parseTCPAddr(ch.ExtraData())
|
var payload forwardedTCPPayload
|
||||||
if !ok {
|
if err := Unmarshal(ch.ExtraData(), &payload); err != nil {
|
||||||
// invalid request
|
ch.Reject(ConnectionFailed, "could not parse forwarded-tcpip payload: "+err.Error())
|
||||||
ch.Reject(ConnectionFailed, "could not parse TCP address")
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
raddr, rest, ok := parseTCPAddr(rest)
|
// RFC 4254 section 7.2 specifies that incoming
|
||||||
if !ok {
|
// addresses should list the address, in string
|
||||||
// invalid request
|
// format. It is implied that this should be an IP
|
||||||
ch.Reject(ConnectionFailed, "could not parse TCP address")
|
// address, as it would be impossible to connect to it
|
||||||
|
// otherwise.
|
||||||
|
laddr, err := parseTCPAddr(payload.Addr, payload.Port)
|
||||||
|
if err != nil {
|
||||||
|
ch.Reject(ConnectionFailed, err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
raddr, err := parseTCPAddr(payload.OriginAddr, payload.OriginPort)
|
||||||
|
if err != nil {
|
||||||
|
ch.Reject(ConnectionFailed, err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче