Skip to content

Commit

Permalink
ssh: add server side support for ping@openssh.com protocol extension
Browse files Browse the repository at this point in the history
Fixes golang/go#62390

Change-Id: Ie4dc577fb55b45a0c26a9e2dc5903af2bd382e00
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/524775
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
  • Loading branch information
drakkan authored and FiloSottile committed Oct 4, 2023
1 parent ec07f4e commit 833695f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
1 change: 1 addition & 0 deletions ssh/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ others.
References:
[PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
Expand Down
10 changes: 7 additions & 3 deletions ssh/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,16 +647,20 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {

// On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
// message with the server-sig-algs extension if the client supports it. See
// RFC 8308, Sections 2.4 and 3.1.
// RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9.
if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
extInfo := &extInfoMsg{
NumExtensions: 1,
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)),
NumExtensions: 2,
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1),
}
extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs"))
extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...)
extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))
extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)
extInfo.Payload = appendInt(extInfo.Payload, len("ping@openssh.com"))
extInfo.Payload = append(extInfo.Payload, "ping@openssh.com"...)
extInfo.Payload = appendInt(extInfo.Payload, 1)
extInfo.Payload = append(extInfo.Payload, "0"...)
if err := t.conn.writePacket(Marshal(extInfo)); err != nil {
return err
}
Expand Down
14 changes: 14 additions & 0 deletions ssh/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,20 @@ type userAuthGSSAPIError struct {
LanguageTag string
}

// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
const msgPing = 192

type pingMsg struct {
Data string `sshtype:"192"`
}

// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
const msgPong = 193

type pongMsg struct {
Data string `sshtype:"193"`
}

// typeTags returns the possible type bytes for the given reflect.Type, which
// should be a struct. The possible values are separated by a '|' character.
func typeTags(structType reflect.Type) (tags []byte) {
Expand Down
6 changes: 6 additions & 0 deletions ssh/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,12 @@ func (m *mux) onePacket() error {
return m.handleChannelOpen(packet)
case msgGlobalRequest, msgRequestSuccess, msgRequestFailure:
return m.handleGlobalPacket(packet)
case msgPing:
var msg pingMsg
if err := Unmarshal(packet, &msg); err != nil {
return fmt.Errorf("failed to unmarshal ping@openssh.com message: %w", err)
}
return m.sendMessage(pongMsg(msg))
}

// assume a channel packet.
Expand Down

0 comments on commit 833695f

Please sign in to comment.