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 }