gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

messages.go (20481B)


      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 	PreferedBits 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 // typeTags returns the possible type bytes for the given reflect.Type, which
    353 // should be a struct. The possible values are separated by a '|' character.
    354 func typeTags(structType reflect.Type) (tags []byte) {
    355 	tagStr := structType.Field(0).Tag.Get("sshtype")
    356 
    357 	for _, tag := range strings.Split(tagStr, "|") {
    358 		i, err := strconv.Atoi(tag)
    359 		if err == nil {
    360 			tags = append(tags, byte(i))
    361 		}
    362 	}
    363 
    364 	return tags
    365 }
    366 
    367 func fieldError(t reflect.Type, field int, problem string) error {
    368 	if problem != "" {
    369 		problem = ": " + problem
    370 	}
    371 	return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem)
    372 }
    373 
    374 var errShortRead = errors.New("ssh: short read")
    375 
    376 // Unmarshal parses data in SSH wire format into a structure. The out
    377 // argument should be a pointer to struct. If the first member of the
    378 // struct has the "sshtype" tag set to a '|'-separated set of numbers
    379 // in decimal, the packet must start with one of those numbers. In
    380 // case of error, Unmarshal returns a ParseError or
    381 // UnexpectedMessageError.
    382 func Unmarshal(data []byte, out interface{}) error {
    383 	v := reflect.ValueOf(out).Elem()
    384 	structType := v.Type()
    385 	expectedTypes := typeTags(structType)
    386 
    387 	var expectedType byte
    388 	if len(expectedTypes) > 0 {
    389 		expectedType = expectedTypes[0]
    390 	}
    391 
    392 	if len(data) == 0 {
    393 		return parseError(expectedType)
    394 	}
    395 
    396 	if len(expectedTypes) > 0 {
    397 		goodType := false
    398 		for _, e := range expectedTypes {
    399 			if e > 0 && data[0] == e {
    400 				goodType = true
    401 				break
    402 			}
    403 		}
    404 		if !goodType {
    405 			return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
    406 		}
    407 		data = data[1:]
    408 	}
    409 
    410 	var ok bool
    411 	for i := 0; i < v.NumField(); i++ {
    412 		field := v.Field(i)
    413 		t := field.Type()
    414 		switch t.Kind() {
    415 		case reflect.Bool:
    416 			if len(data) < 1 {
    417 				return errShortRead
    418 			}
    419 			field.SetBool(data[0] != 0)
    420 			data = data[1:]
    421 		case reflect.Array:
    422 			if t.Elem().Kind() != reflect.Uint8 {
    423 				return fieldError(structType, i, "array of unsupported type")
    424 			}
    425 			if len(data) < t.Len() {
    426 				return errShortRead
    427 			}
    428 			for j, n := 0, t.Len(); j < n; j++ {
    429 				field.Index(j).Set(reflect.ValueOf(data[j]))
    430 			}
    431 			data = data[t.Len():]
    432 		case reflect.Uint64:
    433 			var u64 uint64
    434 			if u64, data, ok = parseUint64(data); !ok {
    435 				return errShortRead
    436 			}
    437 			field.SetUint(u64)
    438 		case reflect.Uint32:
    439 			var u32 uint32
    440 			if u32, data, ok = parseUint32(data); !ok {
    441 				return errShortRead
    442 			}
    443 			field.SetUint(uint64(u32))
    444 		case reflect.Uint8:
    445 			if len(data) < 1 {
    446 				return errShortRead
    447 			}
    448 			field.SetUint(uint64(data[0]))
    449 			data = data[1:]
    450 		case reflect.String:
    451 			var s []byte
    452 			if s, data, ok = parseString(data); !ok {
    453 				return fieldError(structType, i, "")
    454 			}
    455 			field.SetString(string(s))
    456 		case reflect.Slice:
    457 			switch t.Elem().Kind() {
    458 			case reflect.Uint8:
    459 				if structType.Field(i).Tag.Get("ssh") == "rest" {
    460 					field.Set(reflect.ValueOf(data))
    461 					data = nil
    462 				} else {
    463 					var s []byte
    464 					if s, data, ok = parseString(data); !ok {
    465 						return errShortRead
    466 					}
    467 					field.Set(reflect.ValueOf(s))
    468 				}
    469 			case reflect.String:
    470 				var nl []string
    471 				if nl, data, ok = parseNameList(data); !ok {
    472 					return errShortRead
    473 				}
    474 				field.Set(reflect.ValueOf(nl))
    475 			default:
    476 				return fieldError(structType, i, "slice of unsupported type")
    477 			}
    478 		case reflect.Ptr:
    479 			if t == bigIntType {
    480 				var n *big.Int
    481 				if n, data, ok = parseInt(data); !ok {
    482 					return errShortRead
    483 				}
    484 				field.Set(reflect.ValueOf(n))
    485 			} else {
    486 				return fieldError(structType, i, "pointer to unsupported type")
    487 			}
    488 		default:
    489 			return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
    490 		}
    491 	}
    492 
    493 	if len(data) != 0 {
    494 		return parseError(expectedType)
    495 	}
    496 
    497 	return nil
    498 }
    499 
    500 // Marshal serializes the message in msg to SSH wire format.  The msg
    501 // argument should be a struct or pointer to struct. If the first
    502 // member has the "sshtype" tag set to a number in decimal, that
    503 // number is prepended to the result. If the last of member has the
    504 // "ssh" tag set to "rest", its contents are appended to the output.
    505 func Marshal(msg interface{}) []byte {
    506 	out := make([]byte, 0, 64)
    507 	return marshalStruct(out, msg)
    508 }
    509 
    510 func marshalStruct(out []byte, msg interface{}) []byte {
    511 	v := reflect.Indirect(reflect.ValueOf(msg))
    512 	msgTypes := typeTags(v.Type())
    513 	if len(msgTypes) > 0 {
    514 		out = append(out, msgTypes[0])
    515 	}
    516 
    517 	for i, n := 0, v.NumField(); i < n; i++ {
    518 		field := v.Field(i)
    519 		switch t := field.Type(); t.Kind() {
    520 		case reflect.Bool:
    521 			var v uint8
    522 			if field.Bool() {
    523 				v = 1
    524 			}
    525 			out = append(out, v)
    526 		case reflect.Array:
    527 			if t.Elem().Kind() != reflect.Uint8 {
    528 				panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface()))
    529 			}
    530 			for j, l := 0, t.Len(); j < l; j++ {
    531 				out = append(out, uint8(field.Index(j).Uint()))
    532 			}
    533 		case reflect.Uint32:
    534 			out = appendU32(out, uint32(field.Uint()))
    535 		case reflect.Uint64:
    536 			out = appendU64(out, uint64(field.Uint()))
    537 		case reflect.Uint8:
    538 			out = append(out, uint8(field.Uint()))
    539 		case reflect.String:
    540 			s := field.String()
    541 			out = appendInt(out, len(s))
    542 			out = append(out, s...)
    543 		case reflect.Slice:
    544 			switch t.Elem().Kind() {
    545 			case reflect.Uint8:
    546 				if v.Type().Field(i).Tag.Get("ssh") != "rest" {
    547 					out = appendInt(out, field.Len())
    548 				}
    549 				out = append(out, field.Bytes()...)
    550 			case reflect.String:
    551 				offset := len(out)
    552 				out = appendU32(out, 0)
    553 				if n := field.Len(); n > 0 {
    554 					for j := 0; j < n; j++ {
    555 						f := field.Index(j)
    556 						if j != 0 {
    557 							out = append(out, ',')
    558 						}
    559 						out = append(out, f.String()...)
    560 					}
    561 					// overwrite length value
    562 					binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))
    563 				}
    564 			default:
    565 				panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface()))
    566 			}
    567 		case reflect.Ptr:
    568 			if t == bigIntType {
    569 				var n *big.Int
    570 				nValue := reflect.ValueOf(&n)
    571 				nValue.Elem().Set(field)
    572 				needed := intLength(n)
    573 				oldLength := len(out)
    574 
    575 				if cap(out)-len(out) < needed {
    576 					newOut := make([]byte, len(out), 2*(len(out)+needed))
    577 					copy(newOut, out)
    578 					out = newOut
    579 				}
    580 				out = out[:oldLength+needed]
    581 				marshalInt(out[oldLength:], n)
    582 			} else {
    583 				panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface()))
    584 			}
    585 		}
    586 	}
    587 
    588 	return out
    589 }
    590 
    591 var bigOne = big.NewInt(1)
    592 
    593 func parseString(in []byte) (out, rest []byte, ok bool) {
    594 	if len(in) < 4 {
    595 		return
    596 	}
    597 	length := binary.BigEndian.Uint32(in)
    598 	in = in[4:]
    599 	if uint32(len(in)) < length {
    600 		return
    601 	}
    602 	out = in[:length]
    603 	rest = in[length:]
    604 	ok = true
    605 	return
    606 }
    607 
    608 var (
    609 	comma         = []byte{','}
    610 	emptyNameList = []string{}
    611 )
    612 
    613 func parseNameList(in []byte) (out []string, rest []byte, ok bool) {
    614 	contents, rest, ok := parseString(in)
    615 	if !ok {
    616 		return
    617 	}
    618 	if len(contents) == 0 {
    619 		out = emptyNameList
    620 		return
    621 	}
    622 	parts := bytes.Split(contents, comma)
    623 	out = make([]string, len(parts))
    624 	for i, part := range parts {
    625 		out[i] = string(part)
    626 	}
    627 	return
    628 }
    629 
    630 func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {
    631 	contents, rest, ok := parseString(in)
    632 	if !ok {
    633 		return
    634 	}
    635 	out = new(big.Int)
    636 
    637 	if len(contents) > 0 && contents[0]&0x80 == 0x80 {
    638 		// This is a negative number
    639 		notBytes := make([]byte, len(contents))
    640 		for i := range notBytes {
    641 			notBytes[i] = ^contents[i]
    642 		}
    643 		out.SetBytes(notBytes)
    644 		out.Add(out, bigOne)
    645 		out.Neg(out)
    646 	} else {
    647 		// Positive number
    648 		out.SetBytes(contents)
    649 	}
    650 	ok = true
    651 	return
    652 }
    653 
    654 func parseUint32(in []byte) (uint32, []byte, bool) {
    655 	if len(in) < 4 {
    656 		return 0, nil, false
    657 	}
    658 	return binary.BigEndian.Uint32(in), in[4:], true
    659 }
    660 
    661 func parseUint64(in []byte) (uint64, []byte, bool) {
    662 	if len(in) < 8 {
    663 		return 0, nil, false
    664 	}
    665 	return binary.BigEndian.Uint64(in), in[8:], true
    666 }
    667 
    668 func intLength(n *big.Int) int {
    669 	length := 4 /* length bytes */
    670 	if n.Sign() < 0 {
    671 		nMinus1 := new(big.Int).Neg(n)
    672 		nMinus1.Sub(nMinus1, bigOne)
    673 		bitLen := nMinus1.BitLen()
    674 		if bitLen%8 == 0 {
    675 			// The number will need 0xff padding
    676 			length++
    677 		}
    678 		length += (bitLen + 7) / 8
    679 	} else if n.Sign() == 0 {
    680 		// A zero is the zero length string
    681 	} else {
    682 		bitLen := n.BitLen()
    683 		if bitLen%8 == 0 {
    684 			// The number will need 0x00 padding
    685 			length++
    686 		}
    687 		length += (bitLen + 7) / 8
    688 	}
    689 
    690 	return length
    691 }
    692 
    693 func marshalUint32(to []byte, n uint32) []byte {
    694 	binary.BigEndian.PutUint32(to, n)
    695 	return to[4:]
    696 }
    697 
    698 func marshalUint64(to []byte, n uint64) []byte {
    699 	binary.BigEndian.PutUint64(to, n)
    700 	return to[8:]
    701 }
    702 
    703 func marshalInt(to []byte, n *big.Int) []byte {
    704 	lengthBytes := to
    705 	to = to[4:]
    706 	length := 0
    707 
    708 	if n.Sign() < 0 {
    709 		// A negative number has to be converted to two's-complement
    710 		// form. So we'll subtract 1 and invert. If the
    711 		// most-significant-bit isn't set then we'll need to pad the
    712 		// beginning with 0xff in order to keep the number negative.
    713 		nMinus1 := new(big.Int).Neg(n)
    714 		nMinus1.Sub(nMinus1, bigOne)
    715 		bytes := nMinus1.Bytes()
    716 		for i := range bytes {
    717 			bytes[i] ^= 0xff
    718 		}
    719 		if len(bytes) == 0 || bytes[0]&0x80 == 0 {
    720 			to[0] = 0xff
    721 			to = to[1:]
    722 			length++
    723 		}
    724 		nBytes := copy(to, bytes)
    725 		to = to[nBytes:]
    726 		length += nBytes
    727 	} else if n.Sign() == 0 {
    728 		// A zero is the zero length string
    729 	} else {
    730 		bytes := n.Bytes()
    731 		if len(bytes) > 0 && bytes[0]&0x80 != 0 {
    732 			// We'll have to pad this with a 0x00 in order to
    733 			// stop it looking like a negative number.
    734 			to[0] = 0
    735 			to = to[1:]
    736 			length++
    737 		}
    738 		nBytes := copy(to, bytes)
    739 		to = to[nBytes:]
    740 		length += nBytes
    741 	}
    742 
    743 	lengthBytes[0] = byte(length >> 24)
    744 	lengthBytes[1] = byte(length >> 16)
    745 	lengthBytes[2] = byte(length >> 8)
    746 	lengthBytes[3] = byte(length)
    747 	return to
    748 }
    749 
    750 func writeInt(w io.Writer, n *big.Int) {
    751 	length := intLength(n)
    752 	buf := make([]byte, length)
    753 	marshalInt(buf, n)
    754 	w.Write(buf)
    755 }
    756 
    757 func writeString(w io.Writer, s []byte) {
    758 	var lengthBytes [4]byte
    759 	lengthBytes[0] = byte(len(s) >> 24)
    760 	lengthBytes[1] = byte(len(s) >> 16)
    761 	lengthBytes[2] = byte(len(s) >> 8)
    762 	lengthBytes[3] = byte(len(s))
    763 	w.Write(lengthBytes[:])
    764 	w.Write(s)
    765 }
    766 
    767 func stringLength(n int) int {
    768 	return 4 + n
    769 }
    770 
    771 func marshalString(to []byte, s []byte) []byte {
    772 	to[0] = byte(len(s) >> 24)
    773 	to[1] = byte(len(s) >> 16)
    774 	to[2] = byte(len(s) >> 8)
    775 	to[3] = byte(len(s))
    776 	to = to[4:]
    777 	copy(to, s)
    778 	return to[len(s):]
    779 }
    780 
    781 var bigIntType = reflect.TypeOf((*big.Int)(nil))
    782 
    783 // Decode a packet into its corresponding message.
    784 func decode(packet []byte) (interface{}, error) {
    785 	var msg interface{}
    786 	switch packet[0] {
    787 	case msgDisconnect:
    788 		msg = new(disconnectMsg)
    789 	case msgServiceRequest:
    790 		msg = new(serviceRequestMsg)
    791 	case msgServiceAccept:
    792 		msg = new(serviceAcceptMsg)
    793 	case msgExtInfo:
    794 		msg = new(extInfoMsg)
    795 	case msgKexInit:
    796 		msg = new(kexInitMsg)
    797 	case msgKexDHInit:
    798 		msg = new(kexDHInitMsg)
    799 	case msgKexDHReply:
    800 		msg = new(kexDHReplyMsg)
    801 	case msgUserAuthRequest:
    802 		msg = new(userAuthRequestMsg)
    803 	case msgUserAuthSuccess:
    804 		return new(userAuthSuccessMsg), nil
    805 	case msgUserAuthFailure:
    806 		msg = new(userAuthFailureMsg)
    807 	case msgUserAuthPubKeyOk:
    808 		msg = new(userAuthPubKeyOkMsg)
    809 	case msgGlobalRequest:
    810 		msg = new(globalRequestMsg)
    811 	case msgRequestSuccess:
    812 		msg = new(globalRequestSuccessMsg)
    813 	case msgRequestFailure:
    814 		msg = new(globalRequestFailureMsg)
    815 	case msgChannelOpen:
    816 		msg = new(channelOpenMsg)
    817 	case msgChannelData:
    818 		msg = new(channelDataMsg)
    819 	case msgChannelOpenConfirm:
    820 		msg = new(channelOpenConfirmMsg)
    821 	case msgChannelOpenFailure:
    822 		msg = new(channelOpenFailureMsg)
    823 	case msgChannelWindowAdjust:
    824 		msg = new(windowAdjustMsg)
    825 	case msgChannelEOF:
    826 		msg = new(channelEOFMsg)
    827 	case msgChannelClose:
    828 		msg = new(channelCloseMsg)
    829 	case msgChannelRequest:
    830 		msg = new(channelRequestMsg)
    831 	case msgChannelSuccess:
    832 		msg = new(channelRequestSuccessMsg)
    833 	case msgChannelFailure:
    834 		msg = new(channelRequestFailureMsg)
    835 	case msgUserAuthGSSAPIToken:
    836 		msg = new(userAuthGSSAPIToken)
    837 	case msgUserAuthGSSAPIMIC:
    838 		msg = new(userAuthGSSAPIMIC)
    839 	case msgUserAuthGSSAPIErrTok:
    840 		msg = new(userAuthGSSAPIErrTok)
    841 	case msgUserAuthGSSAPIError:
    842 		msg = new(userAuthGSSAPIError)
    843 	default:
    844 		return nil, unexpectedMessageError(0, packet[0])
    845 	}
    846 	if err := Unmarshal(packet, msg); err != nil {
    847 		return nil, err
    848 	}
    849 	return msg, nil
    850 }
    851 
    852 var packetTypeNames = map[byte]string{
    853 	msgDisconnect:          "disconnectMsg",
    854 	msgServiceRequest:      "serviceRequestMsg",
    855 	msgServiceAccept:       "serviceAcceptMsg",
    856 	msgExtInfo:             "extInfoMsg",
    857 	msgKexInit:             "kexInitMsg",
    858 	msgKexDHInit:           "kexDHInitMsg",
    859 	msgKexDHReply:          "kexDHReplyMsg",
    860 	msgUserAuthRequest:     "userAuthRequestMsg",
    861 	msgUserAuthSuccess:     "userAuthSuccessMsg",
    862 	msgUserAuthFailure:     "userAuthFailureMsg",
    863 	msgUserAuthPubKeyOk:    "userAuthPubKeyOkMsg",
    864 	msgGlobalRequest:       "globalRequestMsg",
    865 	msgRequestSuccess:      "globalRequestSuccessMsg",
    866 	msgRequestFailure:      "globalRequestFailureMsg",
    867 	msgChannelOpen:         "channelOpenMsg",
    868 	msgChannelData:         "channelDataMsg",
    869 	msgChannelOpenConfirm:  "channelOpenConfirmMsg",
    870 	msgChannelOpenFailure:  "channelOpenFailureMsg",
    871 	msgChannelWindowAdjust: "windowAdjustMsg",
    872 	msgChannelEOF:          "channelEOFMsg",
    873 	msgChannelClose:        "channelCloseMsg",
    874 	msgChannelRequest:      "channelRequestMsg",
    875 	msgChannelSuccess:      "channelRequestSuccessMsg",
    876 	msgChannelFailure:      "channelRequestFailureMsg",
    877 }