messages.go raw

   1  // Copyright 2011 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package ssh
   6  
   7  import (
   8  	"bytes"
   9  	"encoding/binary"
  10  	"errors"
  11  	"fmt"
  12  	"io"
  13  	"math/big"
  14  	"reflect"
  15  	"strconv"
  16  	"strings"
  17  )
  18  
  19  // These are SSH message type numbers. They are scattered around several
  20  // documents but many were taken from [SSH-PARAMETERS].
  21  const (
  22  	msgIgnore        = 2
  23  	msgUnimplemented = 3
  24  	msgDebug         = 4
  25  	msgNewKeys       = 21
  26  )
  27  
  28  // SSH messages:
  29  //
  30  // These structures mirror the wire format of the corresponding SSH messages.
  31  // They are marshaled using reflection with the marshal and unmarshal functions
  32  // in this file. The only wrinkle is that a final member of type []byte with a
  33  // ssh tag of "rest" receives the remainder of a packet when unmarshaling.
  34  
  35  // See RFC 4253, section 11.1.
  36  const msgDisconnect = 1
  37  
  38  // disconnectMsg is the message that signals a disconnect. It is also
  39  // the error type returned from mux.Wait()
  40  type disconnectMsg struct {
  41  	Reason   uint32 `sshtype:"1"`
  42  	Message  string
  43  	Language string
  44  }
  45  
  46  func (d *disconnectMsg) Error() string {
  47  	return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
  48  }
  49  
  50  // See RFC 4253, section 7.1.
  51  const msgKexInit = 20
  52  
  53  type kexInitMsg struct {
  54  	Cookie                  [16]byte `sshtype:"20"`
  55  	KexAlgos                []string
  56  	ServerHostKeyAlgos      []string
  57  	CiphersClientServer     []string
  58  	CiphersServerClient     []string
  59  	MACsClientServer        []string
  60  	MACsServerClient        []string
  61  	CompressionClientServer []string
  62  	CompressionServerClient []string
  63  	LanguagesClientServer   []string
  64  	LanguagesServerClient   []string
  65  	FirstKexFollows         bool
  66  	Reserved                uint32
  67  }
  68  
  69  // See RFC 4253, section 8.
  70  
  71  // Diffie-Hellman
  72  const msgKexDHInit = 30
  73  
  74  type kexDHInitMsg struct {
  75  	X *big.Int `sshtype:"30"`
  76  }
  77  
  78  const msgKexECDHInit = 30
  79  
  80  type kexECDHInitMsg struct {
  81  	ClientPubKey []byte `sshtype:"30"`
  82  }
  83  
  84  const msgKexECDHReply = 31
  85  
  86  type kexECDHReplyMsg struct {
  87  	HostKey         []byte `sshtype:"31"`
  88  	EphemeralPubKey []byte
  89  	Signature       []byte
  90  }
  91  
  92  const msgKexDHReply = 31
  93  
  94  type kexDHReplyMsg struct {
  95  	HostKey   []byte `sshtype:"31"`
  96  	Y         *big.Int
  97  	Signature []byte
  98  }
  99  
 100  // See RFC 4419, section 5.
 101  const msgKexDHGexGroup = 31
 102  
 103  type kexDHGexGroupMsg struct {
 104  	P *big.Int `sshtype:"31"`
 105  	G *big.Int
 106  }
 107  
 108  const msgKexDHGexInit = 32
 109  
 110  type kexDHGexInitMsg struct {
 111  	X *big.Int `sshtype:"32"`
 112  }
 113  
 114  const msgKexDHGexReply = 33
 115  
 116  type kexDHGexReplyMsg struct {
 117  	HostKey   []byte `sshtype:"33"`
 118  	Y         *big.Int
 119  	Signature []byte
 120  }
 121  
 122  const msgKexDHGexRequest = 34
 123  
 124  type kexDHGexRequestMsg struct {
 125  	MinBits       uint32 `sshtype:"34"`
 126  	PreferredBits uint32
 127  	MaxBits       uint32
 128  }
 129  
 130  // See RFC 4253, section 10.
 131  const msgServiceRequest = 5
 132  
 133  type serviceRequestMsg struct {
 134  	Service string `sshtype:"5"`
 135  }
 136  
 137  // See RFC 4253, section 10.
 138  const msgServiceAccept = 6
 139  
 140  type serviceAcceptMsg struct {
 141  	Service string `sshtype:"6"`
 142  }
 143  
 144  // See RFC 8308, section 2.3
 145  const msgExtInfo = 7
 146  
 147  type extInfoMsg struct {
 148  	NumExtensions uint32 `sshtype:"7"`
 149  	Payload       []byte `ssh:"rest"`
 150  }
 151  
 152  // See RFC 4252, section 5.
 153  const msgUserAuthRequest = 50
 154  
 155  type userAuthRequestMsg struct {
 156  	User    string `sshtype:"50"`
 157  	Service string
 158  	Method  string
 159  	Payload []byte `ssh:"rest"`
 160  }
 161  
 162  // Used for debug printouts of packets.
 163  type userAuthSuccessMsg struct {
 164  }
 165  
 166  // See RFC 4252, section 5.1
 167  const msgUserAuthFailure = 51
 168  
 169  type userAuthFailureMsg struct {
 170  	Methods        []string `sshtype:"51"`
 171  	PartialSuccess bool
 172  }
 173  
 174  // See RFC 4252, section 5.1
 175  const msgUserAuthSuccess = 52
 176  
 177  // See RFC 4252, section 5.4
 178  const msgUserAuthBanner = 53
 179  
 180  type userAuthBannerMsg struct {
 181  	Message string `sshtype:"53"`
 182  	// unused, but required to allow message parsing
 183  	Language string
 184  }
 185  
 186  // See RFC 4256, section 3.2
 187  const msgUserAuthInfoRequest = 60
 188  const msgUserAuthInfoResponse = 61
 189  
 190  type userAuthInfoRequestMsg struct {
 191  	Name        string `sshtype:"60"`
 192  	Instruction string
 193  	Language    string
 194  	NumPrompts  uint32
 195  	Prompts     []byte `ssh:"rest"`
 196  }
 197  
 198  // See RFC 4254, section 5.1.
 199  const msgChannelOpen = 90
 200  
 201  type channelOpenMsg struct {
 202  	ChanType         string `sshtype:"90"`
 203  	PeersID          uint32
 204  	PeersWindow      uint32
 205  	MaxPacketSize    uint32
 206  	TypeSpecificData []byte `ssh:"rest"`
 207  }
 208  
 209  const msgChannelExtendedData = 95
 210  const msgChannelData = 94
 211  
 212  // Used for debug print outs of packets.
 213  type channelDataMsg struct {
 214  	PeersID uint32 `sshtype:"94"`
 215  	Length  uint32
 216  	Rest    []byte `ssh:"rest"`
 217  }
 218  
 219  // See RFC 4254, section 5.1.
 220  const msgChannelOpenConfirm = 91
 221  
 222  type channelOpenConfirmMsg struct {
 223  	PeersID          uint32 `sshtype:"91"`
 224  	MyID             uint32
 225  	MyWindow         uint32
 226  	MaxPacketSize    uint32
 227  	TypeSpecificData []byte `ssh:"rest"`
 228  }
 229  
 230  // See RFC 4254, section 5.1.
 231  const msgChannelOpenFailure = 92
 232  
 233  type channelOpenFailureMsg struct {
 234  	PeersID  uint32 `sshtype:"92"`
 235  	Reason   RejectionReason
 236  	Message  string
 237  	Language string
 238  }
 239  
 240  const msgChannelRequest = 98
 241  
 242  type channelRequestMsg struct {
 243  	PeersID             uint32 `sshtype:"98"`
 244  	Request             string
 245  	WantReply           bool
 246  	RequestSpecificData []byte `ssh:"rest"`
 247  }
 248  
 249  // See RFC 4254, section 5.4.
 250  const msgChannelSuccess = 99
 251  
 252  type channelRequestSuccessMsg struct {
 253  	PeersID uint32 `sshtype:"99"`
 254  }
 255  
 256  // See RFC 4254, section 5.4.
 257  const msgChannelFailure = 100
 258  
 259  type channelRequestFailureMsg struct {
 260  	PeersID uint32 `sshtype:"100"`
 261  }
 262  
 263  // See RFC 4254, section 5.3
 264  const msgChannelClose = 97
 265  
 266  type channelCloseMsg struct {
 267  	PeersID uint32 `sshtype:"97"`
 268  }
 269  
 270  // See RFC 4254, section 5.3
 271  const msgChannelEOF = 96
 272  
 273  type channelEOFMsg struct {
 274  	PeersID uint32 `sshtype:"96"`
 275  }
 276  
 277  // See RFC 4254, section 4
 278  const msgGlobalRequest = 80
 279  
 280  type globalRequestMsg struct {
 281  	Type      string `sshtype:"80"`
 282  	WantReply bool
 283  	Data      []byte `ssh:"rest"`
 284  }
 285  
 286  // See RFC 4254, section 4
 287  const msgRequestSuccess = 81
 288  
 289  type globalRequestSuccessMsg struct {
 290  	Data []byte `ssh:"rest" sshtype:"81"`
 291  }
 292  
 293  // See RFC 4254, section 4
 294  const msgRequestFailure = 82
 295  
 296  type globalRequestFailureMsg struct {
 297  	Data []byte `ssh:"rest" sshtype:"82"`
 298  }
 299  
 300  // See RFC 4254, section 5.2
 301  const msgChannelWindowAdjust = 93
 302  
 303  type windowAdjustMsg struct {
 304  	PeersID         uint32 `sshtype:"93"`
 305  	AdditionalBytes uint32
 306  }
 307  
 308  // See RFC 4252, section 7
 309  const msgUserAuthPubKeyOk = 60
 310  
 311  type userAuthPubKeyOkMsg struct {
 312  	Algo   string `sshtype:"60"`
 313  	PubKey []byte
 314  }
 315  
 316  // See RFC 4462, section 3
 317  const msgUserAuthGSSAPIResponse = 60
 318  
 319  type userAuthGSSAPIResponse struct {
 320  	SupportMech []byte `sshtype:"60"`
 321  }
 322  
 323  const msgUserAuthGSSAPIToken = 61
 324  
 325  type userAuthGSSAPIToken struct {
 326  	Token []byte `sshtype:"61"`
 327  }
 328  
 329  const msgUserAuthGSSAPIMIC = 66
 330  
 331  type userAuthGSSAPIMIC struct {
 332  	MIC []byte `sshtype:"66"`
 333  }
 334  
 335  // See RFC 4462, section 3.9
 336  const msgUserAuthGSSAPIErrTok = 64
 337  
 338  type userAuthGSSAPIErrTok struct {
 339  	ErrorToken []byte `sshtype:"64"`
 340  }
 341  
 342  // See RFC 4462, section 3.8
 343  const msgUserAuthGSSAPIError = 65
 344  
 345  type userAuthGSSAPIError struct {
 346  	MajorStatus uint32 `sshtype:"65"`
 347  	MinorStatus uint32
 348  	Message     string
 349  	LanguageTag string
 350  }
 351  
 352  // Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
 353  const msgPing = 192
 354  
 355  type pingMsg struct {
 356  	Data string `sshtype:"192"`
 357  }
 358  
 359  // Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
 360  const msgPong = 193
 361  
 362  type pongMsg struct {
 363  	Data string `sshtype:"193"`
 364  }
 365  
 366  // typeTags returns the possible type bytes for the given reflect.Type, which
 367  // should be a struct. The possible values are separated by a '|' character.
 368  func typeTags(structType reflect.Type) (tags []byte) {
 369  	tagStr := structType.Field(0).Tag.Get("sshtype")
 370  
 371  	for _, tag := range strings.Split(tagStr, "|") {
 372  		i, err := strconv.Atoi(tag)
 373  		if err == nil {
 374  			tags = append(tags, byte(i))
 375  		}
 376  	}
 377  
 378  	return tags
 379  }
 380  
 381  func fieldError(t reflect.Type, field int, problem string) error {
 382  	if problem != "" {
 383  		problem = ": " + problem
 384  	}
 385  	return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem)
 386  }
 387  
 388  var errShortRead = errors.New("ssh: short read")
 389  
 390  // Unmarshal parses data in SSH wire format into a structure. The out
 391  // argument should be a pointer to struct. If the first member of the
 392  // struct has the "sshtype" tag set to a '|'-separated set of numbers
 393  // in decimal, the packet must start with one of those numbers. In
 394  // case of error, Unmarshal returns a ParseError or
 395  // UnexpectedMessageError.
 396  func Unmarshal(data []byte, out interface{}) error {
 397  	v := reflect.ValueOf(out).Elem()
 398  	structType := v.Type()
 399  	expectedTypes := typeTags(structType)
 400  
 401  	var expectedType byte
 402  	if len(expectedTypes) > 0 {
 403  		expectedType = expectedTypes[0]
 404  	}
 405  
 406  	if len(data) == 0 {
 407  		return parseError(expectedType)
 408  	}
 409  
 410  	if len(expectedTypes) > 0 {
 411  		goodType := false
 412  		for _, e := range expectedTypes {
 413  			if e > 0 && data[0] == e {
 414  				goodType = true
 415  				break
 416  			}
 417  		}
 418  		if !goodType {
 419  			return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
 420  		}
 421  		data = data[1:]
 422  	}
 423  
 424  	var ok bool
 425  	for i := 0; i < v.NumField(); i++ {
 426  		field := v.Field(i)
 427  		t := field.Type()
 428  		switch t.Kind() {
 429  		case reflect.Bool:
 430  			if len(data) < 1 {
 431  				return errShortRead
 432  			}
 433  			field.SetBool(data[0] != 0)
 434  			data = data[1:]
 435  		case reflect.Array:
 436  			if t.Elem().Kind() != reflect.Uint8 {
 437  				return fieldError(structType, i, "array of unsupported type")
 438  			}
 439  			if len(data) < t.Len() {
 440  				return errShortRead
 441  			}
 442  			for j, n := 0, t.Len(); j < n; j++ {
 443  				field.Index(j).Set(reflect.ValueOf(data[j]))
 444  			}
 445  			data = data[t.Len():]
 446  		case reflect.Uint64:
 447  			var u64 uint64
 448  			if u64, data, ok = parseUint64(data); !ok {
 449  				return errShortRead
 450  			}
 451  			field.SetUint(u64)
 452  		case reflect.Uint32:
 453  			var u32 uint32
 454  			if u32, data, ok = parseUint32(data); !ok {
 455  				return errShortRead
 456  			}
 457  			field.SetUint(uint64(u32))
 458  		case reflect.Uint8:
 459  			if len(data) < 1 {
 460  				return errShortRead
 461  			}
 462  			field.SetUint(uint64(data[0]))
 463  			data = data[1:]
 464  		case reflect.String:
 465  			var s []byte
 466  			if s, data, ok = parseString(data); !ok {
 467  				return fieldError(structType, i, "")
 468  			}
 469  			field.SetString(string(s))
 470  		case reflect.Slice:
 471  			switch t.Elem().Kind() {
 472  			case reflect.Uint8:
 473  				if structType.Field(i).Tag.Get("ssh") == "rest" {
 474  					field.Set(reflect.ValueOf(data))
 475  					data = nil
 476  				} else {
 477  					var s []byte
 478  					if s, data, ok = parseString(data); !ok {
 479  						return errShortRead
 480  					}
 481  					field.Set(reflect.ValueOf(s))
 482  				}
 483  			case reflect.String:
 484  				var nl []string
 485  				if nl, data, ok = parseNameList(data); !ok {
 486  					return errShortRead
 487  				}
 488  				field.Set(reflect.ValueOf(nl))
 489  			default:
 490  				return fieldError(structType, i, "slice of unsupported type")
 491  			}
 492  		case reflect.Ptr:
 493  			if t == bigIntType {
 494  				var n *big.Int
 495  				if n, data, ok = parseInt(data); !ok {
 496  					return errShortRead
 497  				}
 498  				field.Set(reflect.ValueOf(n))
 499  			} else {
 500  				return fieldError(structType, i, "pointer to unsupported type")
 501  			}
 502  		default:
 503  			return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
 504  		}
 505  	}
 506  
 507  	if len(data) != 0 {
 508  		return parseError(expectedType)
 509  	}
 510  
 511  	return nil
 512  }
 513  
 514  // Marshal serializes the message in msg to SSH wire format.  The msg
 515  // argument should be a struct or pointer to struct. If the first
 516  // member has the "sshtype" tag set to a number in decimal, that
 517  // number is prepended to the result. If the last of member has the
 518  // "ssh" tag set to "rest", its contents are appended to the output.
 519  func Marshal(msg interface{}) []byte {
 520  	out := make([]byte, 0, 64)
 521  	return marshalStruct(out, msg)
 522  }
 523  
 524  func marshalStruct(out []byte, msg interface{}) []byte {
 525  	v := reflect.Indirect(reflect.ValueOf(msg))
 526  	msgTypes := typeTags(v.Type())
 527  	if len(msgTypes) > 0 {
 528  		out = append(out, msgTypes[0])
 529  	}
 530  
 531  	for i, n := 0, v.NumField(); i < n; i++ {
 532  		field := v.Field(i)
 533  		switch t := field.Type(); t.Kind() {
 534  		case reflect.Bool:
 535  			var v uint8
 536  			if field.Bool() {
 537  				v = 1
 538  			}
 539  			out = append(out, v)
 540  		case reflect.Array:
 541  			if t.Elem().Kind() != reflect.Uint8 {
 542  				panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface()))
 543  			}
 544  			for j, l := 0, t.Len(); j < l; j++ {
 545  				out = append(out, uint8(field.Index(j).Uint()))
 546  			}
 547  		case reflect.Uint32:
 548  			out = appendU32(out, uint32(field.Uint()))
 549  		case reflect.Uint64:
 550  			out = appendU64(out, uint64(field.Uint()))
 551  		case reflect.Uint8:
 552  			out = append(out, uint8(field.Uint()))
 553  		case reflect.String:
 554  			s := field.String()
 555  			out = appendInt(out, len(s))
 556  			out = append(out, s...)
 557  		case reflect.Slice:
 558  			switch t.Elem().Kind() {
 559  			case reflect.Uint8:
 560  				if v.Type().Field(i).Tag.Get("ssh") != "rest" {
 561  					out = appendInt(out, field.Len())
 562  				}
 563  				out = append(out, field.Bytes()...)
 564  			case reflect.String:
 565  				offset := len(out)
 566  				out = appendU32(out, 0)
 567  				if n := field.Len(); n > 0 {
 568  					for j := 0; j < n; j++ {
 569  						f := field.Index(j)
 570  						if j != 0 {
 571  							out = append(out, ',')
 572  						}
 573  						out = append(out, f.String()...)
 574  					}
 575  					// overwrite length value
 576  					binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))
 577  				}
 578  			default:
 579  				panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface()))
 580  			}
 581  		case reflect.Ptr:
 582  			if t == bigIntType {
 583  				var n *big.Int
 584  				nValue := reflect.ValueOf(&n)
 585  				nValue.Elem().Set(field)
 586  				needed := intLength(n)
 587  				oldLength := len(out)
 588  
 589  				if cap(out)-len(out) < needed {
 590  					newOut := make([]byte, len(out), 2*(len(out)+needed))
 591  					copy(newOut, out)
 592  					out = newOut
 593  				}
 594  				out = out[:oldLength+needed]
 595  				marshalInt(out[oldLength:], n)
 596  			} else {
 597  				panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface()))
 598  			}
 599  		}
 600  	}
 601  
 602  	return out
 603  }
 604  
 605  var bigOne = big.NewInt(1)
 606  
 607  func parseString(in []byte) (out, rest []byte, ok bool) {
 608  	if len(in) < 4 {
 609  		return
 610  	}
 611  	length := binary.BigEndian.Uint32(in)
 612  	in = in[4:]
 613  	if uint32(len(in)) < length {
 614  		return
 615  	}
 616  	out = in[:length]
 617  	rest = in[length:]
 618  	ok = true
 619  	return
 620  }
 621  
 622  var (
 623  	comma         = []byte{','}
 624  	emptyNameList = []string{}
 625  )
 626  
 627  func parseNameList(in []byte) (out []string, rest []byte, ok bool) {
 628  	contents, rest, ok := parseString(in)
 629  	if !ok {
 630  		return
 631  	}
 632  	if len(contents) == 0 {
 633  		out = emptyNameList
 634  		return
 635  	}
 636  	parts := bytes.Split(contents, comma)
 637  	out = make([]string, len(parts))
 638  	for i, part := range parts {
 639  		out[i] = string(part)
 640  	}
 641  	return
 642  }
 643  
 644  func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {
 645  	contents, rest, ok := parseString(in)
 646  	if !ok {
 647  		return
 648  	}
 649  	out = new(big.Int)
 650  
 651  	if len(contents) > 0 && contents[0]&0x80 == 0x80 {
 652  		// This is a negative number
 653  		notBytes := make([]byte, len(contents))
 654  		for i := range notBytes {
 655  			notBytes[i] = ^contents[i]
 656  		}
 657  		out.SetBytes(notBytes)
 658  		out.Add(out, bigOne)
 659  		out.Neg(out)
 660  	} else {
 661  		// Positive number
 662  		out.SetBytes(contents)
 663  	}
 664  	ok = true
 665  	return
 666  }
 667  
 668  func parseUint32(in []byte) (uint32, []byte, bool) {
 669  	if len(in) < 4 {
 670  		return 0, nil, false
 671  	}
 672  	return binary.BigEndian.Uint32(in), in[4:], true
 673  }
 674  
 675  func parseUint64(in []byte) (uint64, []byte, bool) {
 676  	if len(in) < 8 {
 677  		return 0, nil, false
 678  	}
 679  	return binary.BigEndian.Uint64(in), in[8:], true
 680  }
 681  
 682  func intLength(n *big.Int) int {
 683  	length := 4 /* length bytes */
 684  	if n.Sign() < 0 {
 685  		nMinus1 := new(big.Int).Neg(n)
 686  		nMinus1.Sub(nMinus1, bigOne)
 687  		bitLen := nMinus1.BitLen()
 688  		if bitLen%8 == 0 {
 689  			// The number will need 0xff padding
 690  			length++
 691  		}
 692  		length += (bitLen + 7) / 8
 693  	} else if n.Sign() == 0 {
 694  		// A zero is the zero length string
 695  	} else {
 696  		bitLen := n.BitLen()
 697  		if bitLen%8 == 0 {
 698  			// The number will need 0x00 padding
 699  			length++
 700  		}
 701  		length += (bitLen + 7) / 8
 702  	}
 703  
 704  	return length
 705  }
 706  
 707  func marshalUint32(to []byte, n uint32) []byte {
 708  	binary.BigEndian.PutUint32(to, n)
 709  	return to[4:]
 710  }
 711  
 712  func marshalUint64(to []byte, n uint64) []byte {
 713  	binary.BigEndian.PutUint64(to, n)
 714  	return to[8:]
 715  }
 716  
 717  func marshalInt(to []byte, n *big.Int) []byte {
 718  	lengthBytes := to
 719  	to = to[4:]
 720  	length := 0
 721  
 722  	if n.Sign() < 0 {
 723  		// A negative number has to be converted to two's-complement
 724  		// form. So we'll subtract 1 and invert. If the
 725  		// most-significant-bit isn't set then we'll need to pad the
 726  		// beginning with 0xff in order to keep the number negative.
 727  		nMinus1 := new(big.Int).Neg(n)
 728  		nMinus1.Sub(nMinus1, bigOne)
 729  		bytes := nMinus1.Bytes()
 730  		for i := range bytes {
 731  			bytes[i] ^= 0xff
 732  		}
 733  		if len(bytes) == 0 || bytes[0]&0x80 == 0 {
 734  			to[0] = 0xff
 735  			to = to[1:]
 736  			length++
 737  		}
 738  		nBytes := copy(to, bytes)
 739  		to = to[nBytes:]
 740  		length += nBytes
 741  	} else if n.Sign() == 0 {
 742  		// A zero is the zero length string
 743  	} else {
 744  		bytes := n.Bytes()
 745  		if len(bytes) > 0 && bytes[0]&0x80 != 0 {
 746  			// We'll have to pad this with a 0x00 in order to
 747  			// stop it looking like a negative number.
 748  			to[0] = 0
 749  			to = to[1:]
 750  			length++
 751  		}
 752  		nBytes := copy(to, bytes)
 753  		to = to[nBytes:]
 754  		length += nBytes
 755  	}
 756  
 757  	lengthBytes[0] = byte(length >> 24)
 758  	lengthBytes[1] = byte(length >> 16)
 759  	lengthBytes[2] = byte(length >> 8)
 760  	lengthBytes[3] = byte(length)
 761  	return to
 762  }
 763  
 764  func writeInt(w io.Writer, n *big.Int) {
 765  	length := intLength(n)
 766  	buf := make([]byte, length)
 767  	marshalInt(buf, n)
 768  	w.Write(buf)
 769  }
 770  
 771  func writeString(w io.Writer, s []byte) {
 772  	var lengthBytes [4]byte
 773  	lengthBytes[0] = byte(len(s) >> 24)
 774  	lengthBytes[1] = byte(len(s) >> 16)
 775  	lengthBytes[2] = byte(len(s) >> 8)
 776  	lengthBytes[3] = byte(len(s))
 777  	w.Write(lengthBytes[:])
 778  	w.Write(s)
 779  }
 780  
 781  func stringLength(n int) int {
 782  	return 4 + n
 783  }
 784  
 785  func marshalString(to []byte, s []byte) []byte {
 786  	to[0] = byte(len(s) >> 24)
 787  	to[1] = byte(len(s) >> 16)
 788  	to[2] = byte(len(s) >> 8)
 789  	to[3] = byte(len(s))
 790  	to = to[4:]
 791  	copy(to, s)
 792  	return to[len(s):]
 793  }
 794  
 795  var bigIntType = reflect.TypeFor[*big.Int]()
 796  
 797  // Decode a packet into its corresponding message.
 798  func decode(packet []byte) (interface{}, error) {
 799  	var msg interface{}
 800  	switch packet[0] {
 801  	case msgDisconnect:
 802  		msg = new(disconnectMsg)
 803  	case msgServiceRequest:
 804  		msg = new(serviceRequestMsg)
 805  	case msgServiceAccept:
 806  		msg = new(serviceAcceptMsg)
 807  	case msgExtInfo:
 808  		msg = new(extInfoMsg)
 809  	case msgKexInit:
 810  		msg = new(kexInitMsg)
 811  	case msgKexDHInit:
 812  		msg = new(kexDHInitMsg)
 813  	case msgKexDHReply:
 814  		msg = new(kexDHReplyMsg)
 815  	case msgUserAuthRequest:
 816  		msg = new(userAuthRequestMsg)
 817  	case msgUserAuthSuccess:
 818  		return new(userAuthSuccessMsg), nil
 819  	case msgUserAuthFailure:
 820  		msg = new(userAuthFailureMsg)
 821  	case msgUserAuthBanner:
 822  		msg = new(userAuthBannerMsg)
 823  	case msgUserAuthPubKeyOk:
 824  		msg = new(userAuthPubKeyOkMsg)
 825  	case msgGlobalRequest:
 826  		msg = new(globalRequestMsg)
 827  	case msgRequestSuccess:
 828  		msg = new(globalRequestSuccessMsg)
 829  	case msgRequestFailure:
 830  		msg = new(globalRequestFailureMsg)
 831  	case msgChannelOpen:
 832  		msg = new(channelOpenMsg)
 833  	case msgChannelData:
 834  		msg = new(channelDataMsg)
 835  	case msgChannelOpenConfirm:
 836  		msg = new(channelOpenConfirmMsg)
 837  	case msgChannelOpenFailure:
 838  		msg = new(channelOpenFailureMsg)
 839  	case msgChannelWindowAdjust:
 840  		msg = new(windowAdjustMsg)
 841  	case msgChannelEOF:
 842  		msg = new(channelEOFMsg)
 843  	case msgChannelClose:
 844  		msg = new(channelCloseMsg)
 845  	case msgChannelRequest:
 846  		msg = new(channelRequestMsg)
 847  	case msgChannelSuccess:
 848  		msg = new(channelRequestSuccessMsg)
 849  	case msgChannelFailure:
 850  		msg = new(channelRequestFailureMsg)
 851  	case msgUserAuthGSSAPIToken:
 852  		msg = new(userAuthGSSAPIToken)
 853  	case msgUserAuthGSSAPIMIC:
 854  		msg = new(userAuthGSSAPIMIC)
 855  	case msgUserAuthGSSAPIErrTok:
 856  		msg = new(userAuthGSSAPIErrTok)
 857  	case msgUserAuthGSSAPIError:
 858  		msg = new(userAuthGSSAPIError)
 859  	default:
 860  		return nil, unexpectedMessageError(0, packet[0])
 861  	}
 862  	if err := Unmarshal(packet, msg); err != nil {
 863  		return nil, err
 864  	}
 865  	return msg, nil
 866  }
 867  
 868  var packetTypeNames = map[byte]string{
 869  	msgDisconnect:          "disconnectMsg",
 870  	msgServiceRequest:      "serviceRequestMsg",
 871  	msgServiceAccept:       "serviceAcceptMsg",
 872  	msgExtInfo:             "extInfoMsg",
 873  	msgKexInit:             "kexInitMsg",
 874  	msgKexDHInit:           "kexDHInitMsg",
 875  	msgKexDHReply:          "kexDHReplyMsg",
 876  	msgUserAuthRequest:     "userAuthRequestMsg",
 877  	msgUserAuthSuccess:     "userAuthSuccessMsg",
 878  	msgUserAuthFailure:     "userAuthFailureMsg",
 879  	msgUserAuthPubKeyOk:    "userAuthPubKeyOkMsg",
 880  	msgGlobalRequest:       "globalRequestMsg",
 881  	msgRequestSuccess:      "globalRequestSuccessMsg",
 882  	msgRequestFailure:      "globalRequestFailureMsg",
 883  	msgChannelOpen:         "channelOpenMsg",
 884  	msgChannelData:         "channelDataMsg",
 885  	msgChannelOpenConfirm:  "channelOpenConfirmMsg",
 886  	msgChannelOpenFailure:  "channelOpenFailureMsg",
 887  	msgChannelWindowAdjust: "windowAdjustMsg",
 888  	msgChannelEOF:          "channelEOFMsg",
 889  	msgChannelClose:        "channelCloseMsg",
 890  	msgChannelRequest:      "channelRequestMsg",
 891  	msgChannelSuccess:      "channelRequestSuccessMsg",
 892  	msgChannelFailure:      "channelRequestFailureMsg",
 893  }
 894