go.crypto/ssh: support OpenSSH keepalives
Fixes golang/go#4552. R=minux.ma, agl CC=golang-dev https://golang.org/cl/6948059
This commit is contained in:
committed by
Adam Langley
parent
d95b28330d
commit
61ab4d36df
@@ -309,6 +309,12 @@ func (c *ClientConn) mainLoop() {
|
||||
// invalid window update
|
||||
return
|
||||
}
|
||||
case *globalRequestMsg:
|
||||
// This handles keepalive messages and matches
|
||||
// the behaviour of OpenSSH.
|
||||
if msg.WantReply {
|
||||
c.writePacket(marshal(msgRequestFailure, globalRequestFailureMsg{}))
|
||||
}
|
||||
case *globalRequestSuccessMsg, *globalRequestFailureMsg:
|
||||
c.globalRequest.response <- msg
|
||||
case *disconnectMsg:
|
||||
|
||||
+7
-1
@@ -404,7 +404,13 @@ func (s *Session) wait() error {
|
||||
}
|
||||
wm.lang = safeString(string(lang))
|
||||
default:
|
||||
return fmt.Errorf("wait: unexpected channel request: %v", msg)
|
||||
// This handles keepalives and matches
|
||||
// OpenSSH's behaviour.
|
||||
if msg.WantReply {
|
||||
s.writePacket(marshal(msgChannelFailure, channelRequestFailureMsg{
|
||||
PeersId: s.remoteId,
|
||||
}))
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("wait: unexpected packet %T received: %v", msg, msg)
|
||||
|
||||
@@ -498,6 +498,24 @@ func TestServerWindow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the client can handle a keepalive packet from the server.
|
||||
func TestClientHandlesKeepalives(t *testing.T) {
|
||||
conn := dial(channelKeepaliveSender, t)
|
||||
defer conn.Close()
|
||||
session, err := conn.NewSession()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer session.Close()
|
||||
if err := session.Shell(); err != nil {
|
||||
t.Fatalf("Unable to execute command: %v", err)
|
||||
}
|
||||
err = session.Wait()
|
||||
if err != nil {
|
||||
t.Fatalf("expected nil but got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type exitStatusMsg struct {
|
||||
PeersId uint32
|
||||
Request string
|
||||
@@ -687,3 +705,18 @@ func copyNRandomly(title string, dst io.Writer, src io.Reader, n int) (int, erro
|
||||
}
|
||||
return written, nil
|
||||
}
|
||||
|
||||
func channelKeepaliveSender(ch *serverChan, t *testing.T) {
|
||||
defer ch.Close()
|
||||
shell := newServerShell(ch, "> ")
|
||||
readLine(shell, t)
|
||||
msg := channelRequestMsg{
|
||||
PeersId: ch.remoteId,
|
||||
Request: "keepalive@openssh.com",
|
||||
WantReply: true,
|
||||
}
|
||||
if err := ch.writePacket(marshal(msgChannelRequest, msg)); err != nil {
|
||||
t.Errorf("unable to send channel keepalive request: %v", err)
|
||||
}
|
||||
sendStatus(0, ch, t)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user