@@ -154,19 +154,47 @@ func (l *forwardList) add(addr net.TCPAddr) chan forward {
154154 return f .c
155155}
156156
157+ // See RFC 4254, section 7.2
158+ type forwardedTCPPayload struct {
159+ Addr string
160+ Port uint32
161+ OriginAddr string
162+ OriginPort uint32
163+ }
164+
165+ // parseTCPAddr parses the originating address from the remote into a *net.TCPAddr.
166+ func parseTCPAddr (addr string , port uint32 ) (* net.TCPAddr , error ) {
167+ if port == 0 || port > 65535 {
168+ return nil , fmt .Errorf ("ssh: port number out of range: %d" , port )
169+ }
170+ ip := net .ParseIP (string (addr ))
171+ if ip == nil {
172+ return nil , fmt .Errorf ("ssh: cannot parse IP address %q" , addr )
173+ }
174+ return & net.TCPAddr {IP : ip , Port : int (port )}, nil
175+ }
176+
157177func (l * forwardList ) handleChannels (in <- chan NewChannel ) {
158178 for ch := range in {
159- laddr , rest , ok := parseTCPAddr (ch .ExtraData ())
160- if ! ok {
161- // invalid request
162- ch .Reject (ConnectionFailed , "could not parse TCP address" )
179+ var payload forwardedTCPPayload
180+ if err := Unmarshal (ch .ExtraData (), & payload ); err != nil {
181+ ch .Reject (ConnectionFailed , "could not parse forwarded-tcpip payload: " + err .Error ())
163182 continue
164183 }
165184
166- raddr , rest , ok := parseTCPAddr (rest )
167- if ! ok {
168- // invalid request
169- ch .Reject (ConnectionFailed , "could not parse TCP address" )
185+ // RFC 4254 section 7.2 specifies that incoming
186+ // addresses should list the address, in string
187+ // format. It is implied that this should be an IP
188+ // address, as it would be impossible to connect to it
189+ // otherwise.
190+ laddr , err := parseTCPAddr (payload .Addr , payload .Port )
191+ if err != nil {
192+ ch .Reject (ConnectionFailed , err .Error ())
193+ continue
194+ }
195+ raddr , err := parseTCPAddr (payload .OriginAddr , payload .OriginPort )
196+ if err != nil {
197+ ch .Reject (ConnectionFailed , err .Error ())
170198 continue
171199 }
172200
0 commit comments