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