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