Skip to content

Commit 1419e9a

Browse files
Added a negative test of PROXY enabled
1 parent a949bbe commit 1419e9a

1 file changed

Lines changed: 101 additions & 1 deletion

File tree

server_test.go

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func TestServerClose(t *testing.T) {
133133
}
134134
}
135135

136-
func TestProxyProtocol(t *testing.T) {
136+
func TestProxyProtocolEnabled(t *testing.T) {
137137
const (
138138
CORRECT_IP = "1.1.1.1"
139139
CORRECT_PORT = 55555
@@ -232,3 +232,103 @@ func TestProxyProtocol(t *testing.T) {
232232
t.Fatal(testResult)
233233
}
234234
}
235+
236+
func TestProxyProtocolDisabled(t *testing.T) {
237+
const (
238+
INCORRECT_IP = "1.1.1.1"
239+
INCORRECT_PORT = 55555
240+
)
241+
handlerDone := make(chan struct{})
242+
var testResult error
243+
244+
handler := func(sess Session) {
245+
defer close(handlerDone)
246+
sourceAddress := sess.RemoteAddr()
247+
248+
index := strings.Index(sourceAddress.String(), ":")
249+
ip := sourceAddress.String()[:index]
250+
portStr := sourceAddress.String()[index+1:]
251+
252+
if ip == INCORRECT_IP {
253+
errorMsg := fmt.Sprintf("Expected source address to be anything but '%s' but got '%s'", INCORRECT_IP, ip)
254+
testResult = errors.Join(testResult, fmt.Errorf("%s", errorMsg))
255+
}
256+
port, err := strconv.Atoi(portStr)
257+
if err != nil {
258+
testResult = errors.Join(testResult, fmt.Errorf("%s", err))
259+
} else if port == INCORRECT_PORT {
260+
errorMsg := fmt.Sprintf("Expected source port anything but '%d' but got '%d'", INCORRECT_PORT, port)
261+
testResult = errors.Join(testResult, fmt.Errorf("%s", errorMsg))
262+
}
263+
}
264+
265+
// Bind the port before starting the goroutine so net.Dial never races
266+
// with the server not yet listening.
267+
l := newLocalListener()
268+
srv := &Server{Handler: handler}
269+
270+
serverDone := make(chan error, 1)
271+
272+
go func() {
273+
serverDone <- srv.Serve(l)
274+
}()
275+
276+
defer func() {
277+
srv.Close()
278+
if err := <-serverDone; err != nil && err != ErrServerClosed {
279+
t.Error(err)
280+
}
281+
}()
282+
283+
serverIP, serverPortStr, _ := net.SplitHostPort(l.Addr().String())
284+
serverPort, _ := strconv.Atoi(serverPortStr)
285+
conn, err := net.Dial("tcp", l.Addr().String())
286+
287+
if err != nil {
288+
t.Fatal(err)
289+
}
290+
291+
//Set the PROXY header information. The server should not read it
292+
header := &proxyproto.Header{
293+
Version: 1,
294+
Command: proxyproto.PROXY,
295+
TransportProtocol: proxyproto.TCPv4,
296+
SourceAddr: &net.TCPAddr{
297+
IP: net.ParseIP(INCORRECT_IP),
298+
Port: INCORRECT_PORT,
299+
},
300+
DestinationAddr: &net.TCPAddr{
301+
IP: net.ParseIP(serverIP),
302+
Port: serverPort,
303+
},
304+
}
305+
306+
// Writes the PROXY header to the TCP stream before SSH begins
307+
_, err = header.WriteTo(conn)
308+
if err != nil {
309+
t.Fatal(err)
310+
}
311+
312+
// Hand the same conn to the SSH stack — handshake starts from here.
313+
clientConn, chans, reqs, err := gossh.NewClientConn(conn, l.Addr().String(), &gossh.ClientConfig{
314+
User: "testuser",
315+
HostKeyCallback: gossh.InsecureIgnoreHostKey(),
316+
})
317+
if err != nil {
318+
t.Fatal(err)
319+
}
320+
client := gossh.NewClient(clientConn, chans, reqs)
321+
defer client.Close()
322+
323+
session, err := client.NewSession()
324+
if err != nil {
325+
t.Fatal(err)
326+
}
327+
session.Run("") // triggers the handler; ignore exec error
328+
329+
<-handlerDone
330+
331+
if testResult != nil {
332+
t.Fatal(testResult)
333+
}
334+
}

0 commit comments

Comments
 (0)