Skip to content

Commit 66a3060

Browse files
committed
ssh: close net.Conn on all NewServerConn errors
1 parent 152cdb1 commit 66a3060

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

ssh/server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,15 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
213213
} else {
214214
for _, algo := range fullConf.PublicKeyAuthAlgorithms {
215215
if !contains(supportedPubKeyAuthAlgos, algo) {
216+
c.Close()
216217
return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
217218
}
218219
}
219220
}
220221
// Check if the config contains any unsupported key exchanges
221222
for _, kex := range fullConf.KeyExchanges {
222223
if _, ok := serverForbiddenKexAlgos[kex]; ok {
224+
c.Close()
223225
return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex)
224226
}
225227
}

ssh/server_test.go

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
package ssh
66

77
import (
8+
"io"
9+
"net"
10+
"sync/atomic"
811
"testing"
12+
"time"
913
)
1014

1115
func TestClientAuthRestrictedPublicKeyAlgos(t *testing.T) {
@@ -59,27 +63,70 @@ func TestClientAuthRestrictedPublicKeyAlgos(t *testing.T) {
5963
}
6064

6165
func TestNewServerConnValidationErrors(t *testing.T) {
62-
c1, c2, err := netPipe()
63-
if err != nil {
64-
t.Fatalf("netPipe: %v", err)
65-
}
66-
defer c1.Close()
67-
defer c2.Close()
68-
6966
serverConf := &ServerConfig{
7067
PublicKeyAuthAlgorithms: []string{CertAlgoRSAv01},
7168
}
72-
_, _, _, err = NewServerConn(c1, serverConf)
69+
c := &markerConn{}
70+
_, _, _, err := NewServerConn(c, serverConf)
7371
if err == nil {
7472
t.Fatal("NewServerConn with invalid public key auth algorithms succeeded")
7573
}
74+
if !c.closed.Load() {
75+
t.Fatal("NewServerConn with invalid public key auth algorithms left connection open")
76+
}
77+
if c.used.Load() {
78+
t.Fatal("NewServerConn with invalid public key auth algorithms used connection")
79+
}
80+
7681
serverConf = &ServerConfig{
7782
Config: Config{
7883
KeyExchanges: []string{kexAlgoDHGEXSHA256},
7984
},
8085
}
81-
_, _, _, err = NewServerConn(c1, serverConf)
86+
c = &markerConn{}
87+
_, _, _, err = NewServerConn(c, serverConf)
8288
if err == nil {
8389
t.Fatal("NewServerConn with unsupported key exchange succeeded")
8490
}
91+
if !c.closed.Load() {
92+
t.Fatal("NewServerConn with unsupported key exchange left connection open")
93+
}
94+
if c.used.Load() {
95+
t.Fatal("NewServerConn with unsupported key exchange used connection")
96+
}
8597
}
98+
99+
type markerConn struct {
100+
closed atomic.Bool
101+
used atomic.Bool
102+
}
103+
104+
func (c *markerConn) Close() error {
105+
c.closed.Store(true)
106+
return nil
107+
}
108+
109+
func (c *markerConn) Read(b []byte) (n int, err error) {
110+
c.used.Store(true)
111+
if c.closed.Load() {
112+
return 0, net.ErrClosed
113+
} else {
114+
return 0, io.EOF
115+
}
116+
}
117+
118+
func (c *markerConn) Write(b []byte) (n int, err error) {
119+
c.used.Store(true)
120+
if c.closed.Load() {
121+
return 0, net.ErrClosed
122+
} else {
123+
return 0, io.ErrClosedPipe
124+
}
125+
}
126+
127+
func (*markerConn) LocalAddr() net.Addr { return nil }
128+
func (*markerConn) RemoteAddr() net.Addr { return nil }
129+
130+
func (*markerConn) SetDeadline(t time.Time) error { return nil }
131+
func (*markerConn) SetReadDeadline(t time.Time) error { return nil }
132+
func (*markerConn) SetWriteDeadline(t time.Time) error { return nil }

0 commit comments

Comments
 (0)