mirror of
https://github.com/cloudflare/cloudflared.git
synced 2026-08-07 07:14:57 +00:00
fix: Bump golang.org/x/text and its dependencies to fix CVE
This commit is contained in:
+155
@@ -0,0 +1,155 @@
|
||||
// Copyright 2026 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
)
|
||||
|
||||
const (
|
||||
muxProtocolVersion = 4
|
||||
|
||||
muxMsgHello = 0x00000001
|
||||
muxCProxy = 0x1000000f
|
||||
muxSProxy = 0x8000000f
|
||||
)
|
||||
|
||||
const controlProxyRequestID = 0
|
||||
|
||||
// handshakeControlProxy attempts to establish a transport connection with an
|
||||
// OpenSSH ControlMaster socket in proxy mode. For details see:
|
||||
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.mux
|
||||
func handshakeControlProxy(rw io.ReadWriteCloser) (connTransport, error) {
|
||||
if err := controlProxyWritePacket(rw, func(b *cryptobyte.Builder) {
|
||||
b.AddUint32(muxMsgHello)
|
||||
b.AddUint32(muxProtocolVersion)
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("mux hello write failed: %w", err)
|
||||
}
|
||||
if err := controlProxyWritePacket(rw, func(b *cryptobyte.Builder) {
|
||||
b.AddUint32(muxCProxy)
|
||||
b.AddUint32(controlProxyRequestID)
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("mux client proxy write failed: %w", err)
|
||||
}
|
||||
|
||||
messageType, body, err := controlProxyReadMessage(rw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("mux hello read failed: %w", err)
|
||||
}
|
||||
if messageType != muxMsgHello {
|
||||
return nil, fmt.Errorf("expected hello response, got %v", messageType)
|
||||
}
|
||||
var v uint32
|
||||
if !body.ReadUint32(&v) {
|
||||
return nil, errors.New("EOF reading mux protocol version")
|
||||
}
|
||||
if v != muxProtocolVersion {
|
||||
return nil, fmt.Errorf("mux server has unsupported version %v", v)
|
||||
}
|
||||
messageType, body, err = controlProxyReadMessage(rw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("mux server proxy read failed: %w", err)
|
||||
}
|
||||
if messageType != muxSProxy {
|
||||
return nil, fmt.Errorf("expected server proxy response, got %v", messageType)
|
||||
}
|
||||
var reqID uint32
|
||||
if !body.ReadUint32(&reqID) {
|
||||
return nil, errors.New("EOF reading request id")
|
||||
}
|
||||
if reqID != controlProxyRequestID {
|
||||
return nil, fmt.Errorf("expected request id %v, got %v", controlProxyRequestID, reqID)
|
||||
}
|
||||
return &controlProxyTransport{rw}, nil
|
||||
}
|
||||
|
||||
// controlProxyTransport implements the connTransport interface for
|
||||
// ControlMaster connections. Each controlMessage has zero length padding and
|
||||
// no MAC.
|
||||
type controlProxyTransport struct {
|
||||
rw io.ReadWriteCloser
|
||||
}
|
||||
|
||||
func (p *controlProxyTransport) Close() error {
|
||||
return p.rw.Close()
|
||||
}
|
||||
|
||||
func (p *controlProxyTransport) writePacket(controlMessage []byte) error {
|
||||
return controlProxyWritePacket(p.rw, func(b *cryptobyte.Builder) {
|
||||
b.AddUint8(0) // Padding length.
|
||||
b.AddBytes(controlMessage)
|
||||
})
|
||||
}
|
||||
|
||||
func (p *controlProxyTransport) readPacket() ([]byte, error) {
|
||||
buf, err := controlProxyReadPacket(p.rw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ssh: error reading control message: %w", err)
|
||||
}
|
||||
// Discard the padding length.
|
||||
if len(buf) < 1 {
|
||||
return nil, errors.New("ssh: EOF reading padding length")
|
||||
}
|
||||
if buf[0] != 0 {
|
||||
return nil, errors.New("ssh: unexpected non-zero padding in control message")
|
||||
}
|
||||
return buf[1:], nil
|
||||
}
|
||||
|
||||
func (p *controlProxyTransport) getAlgorithms() NegotiatedAlgorithms {
|
||||
return NegotiatedAlgorithms{}
|
||||
}
|
||||
|
||||
func (p *controlProxyTransport) getSessionID() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *controlProxyTransport) waitSession() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func controlProxyWritePacket(w io.Writer, f cryptobyte.BuilderContinuation) error {
|
||||
var buf []byte
|
||||
b := cryptobyte.NewBuilder(buf)
|
||||
b.AddUint32LengthPrefixed(f)
|
||||
out, err := b.Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(out)
|
||||
return err
|
||||
}
|
||||
|
||||
func controlProxyReadPacket(r io.Reader) (cryptobyte.String, error) {
|
||||
var l uint32
|
||||
if err := binary.Read(r, binary.BigEndian, &l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if l > maxPacket {
|
||||
return nil, fmt.Errorf("message length %v exceeds maximum %v", l, maxPacket)
|
||||
}
|
||||
buf := make([]byte, l)
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func controlProxyReadMessage(r io.Reader) (messageType uint32, body cryptobyte.String, err error) {
|
||||
body, err = controlProxyReadPacket(r)
|
||||
if err != nil {
|
||||
return 0, nil, fmt.Errorf("error reading message body: %w", err)
|
||||
}
|
||||
if !body.ReadUint32(&messageType) {
|
||||
return 0, nil, errors.New("EOF reading message type")
|
||||
}
|
||||
return messageType, body, nil
|
||||
}
|
||||
Reference in New Issue
Block a user