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