github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/Godeps/_workspace/src/golang.org/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 if uint32(len(in)) < 4+length { 488 return 489 } 490 out = in[4 : 4+length] 491 rest = in[4+length:] 492 ok = true 493 return 494 } 495 496 var ( 497 comma = []byte{','} 498 emptyNameList = []string{} 499 ) 500 501 func parseNameList(in []byte) (out []string, rest []byte, ok bool) { 502 contents, rest, ok := parseString(in) 503 if !ok { 504 return 505 } 506 if len(contents) == 0 { 507 out = emptyNameList 508 return 509 } 510 parts := bytes.Split(contents, comma) 511 out = make([]string, len(parts)) 512 for i, part := range parts { 513 out[i] = string(part) 514 } 515 return 516 } 517 518 func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) { 519 contents, rest, ok := parseString(in) 520 if !ok { 521 return 522 } 523 out = new(big.Int) 524 525 if len(contents) > 0 && contents[0]&0x80 == 0x80 { 526 // This is a negative number 527 notBytes := make([]byte, len(contents)) 528 for i := range notBytes { 529 notBytes[i] = ^contents[i] 530 } 531 out.SetBytes(notBytes) 532 out.Add(out, bigOne) 533 out.Neg(out) 534 } else { 535 // Positive number 536 out.SetBytes(contents) 537 } 538 ok = true 539 return 540 } 541 542 func parseUint32(in []byte) (uint32, []byte, bool) { 543 if len(in) < 4 { 544 return 0, nil, false 545 } 546 return binary.BigEndian.Uint32(in), in[4:], true 547 } 548 549 func parseUint64(in []byte) (uint64, []byte, bool) { 550 if len(in) < 8 { 551 return 0, nil, false 552 } 553 return binary.BigEndian.Uint64(in), in[8:], true 554 } 555 556 func intLength(n *big.Int) int { 557 length := 4 /* length bytes */ 558 if n.Sign() < 0 { 559 nMinus1 := new(big.Int).Neg(n) 560 nMinus1.Sub(nMinus1, bigOne) 561 bitLen := nMinus1.BitLen() 562 if bitLen%8 == 0 { 563 // The number will need 0xff padding 564 length++ 565 } 566 length += (bitLen + 7) / 8 567 } else if n.Sign() == 0 { 568 // A zero is the zero length string 569 } else { 570 bitLen := n.BitLen() 571 if bitLen%8 == 0 { 572 // The number will need 0x00 padding 573 length++ 574 } 575 length += (bitLen + 7) / 8 576 } 577 578 return length 579 } 580 581 func marshalUint32(to []byte, n uint32) []byte { 582 binary.BigEndian.PutUint32(to, n) 583 return to[4:] 584 } 585 586 func marshalUint64(to []byte, n uint64) []byte { 587 binary.BigEndian.PutUint64(to, n) 588 return to[8:] 589 } 590 591 func marshalInt(to []byte, n *big.Int) []byte { 592 lengthBytes := to 593 to = to[4:] 594 length := 0 595 596 if n.Sign() < 0 { 597 // A negative number has to be converted to two's-complement 598 // form. So we'll subtract 1 and invert. If the 599 // most-significant-bit isn't set then we'll need to pad the 600 // beginning with 0xff in order to keep the number negative. 601 nMinus1 := new(big.Int).Neg(n) 602 nMinus1.Sub(nMinus1, bigOne) 603 bytes := nMinus1.Bytes() 604 for i := range bytes { 605 bytes[i] ^= 0xff 606 } 607 if len(bytes) == 0 || bytes[0]&0x80 == 0 { 608 to[0] = 0xff 609 to = to[1:] 610 length++ 611 } 612 nBytes := copy(to, bytes) 613 to = to[nBytes:] 614 length += nBytes 615 } else if n.Sign() == 0 { 616 // A zero is the zero length string 617 } else { 618 bytes := n.Bytes() 619 if len(bytes) > 0 && bytes[0]&0x80 != 0 { 620 // We'll have to pad this with a 0x00 in order to 621 // stop it looking like a negative number. 622 to[0] = 0 623 to = to[1:] 624 length++ 625 } 626 nBytes := copy(to, bytes) 627 to = to[nBytes:] 628 length += nBytes 629 } 630 631 lengthBytes[0] = byte(length >> 24) 632 lengthBytes[1] = byte(length >> 16) 633 lengthBytes[2] = byte(length >> 8) 634 lengthBytes[3] = byte(length) 635 return to 636 } 637 638 func writeInt(w io.Writer, n *big.Int) { 639 length := intLength(n) 640 buf := make([]byte, length) 641 marshalInt(buf, n) 642 w.Write(buf) 643 } 644 645 func writeString(w io.Writer, s []byte) { 646 var lengthBytes [4]byte 647 lengthBytes[0] = byte(len(s) >> 24) 648 lengthBytes[1] = byte(len(s) >> 16) 649 lengthBytes[2] = byte(len(s) >> 8) 650 lengthBytes[3] = byte(len(s)) 651 w.Write(lengthBytes[:]) 652 w.Write(s) 653 } 654 655 func stringLength(n int) int { 656 return 4 + n 657 } 658 659 func marshalString(to []byte, s []byte) []byte { 660 to[0] = byte(len(s) >> 24) 661 to[1] = byte(len(s) >> 16) 662 to[2] = byte(len(s) >> 8) 663 to[3] = byte(len(s)) 664 to = to[4:] 665 copy(to, s) 666 return to[len(s):] 667 } 668 669 var bigIntType = reflect.TypeOf((*big.Int)(nil)) 670 671 // Decode a packet into its corresponding message. 672 func decode(packet []byte) (interface{}, error) { 673 var msg interface{} 674 switch packet[0] { 675 case msgDisconnect: 676 msg = new(disconnectMsg) 677 case msgServiceRequest: 678 msg = new(serviceRequestMsg) 679 case msgServiceAccept: 680 msg = new(serviceAcceptMsg) 681 case msgKexInit: 682 msg = new(kexInitMsg) 683 case msgKexDHInit: 684 msg = new(kexDHInitMsg) 685 case msgKexDHReply: 686 msg = new(kexDHReplyMsg) 687 case msgUserAuthRequest: 688 msg = new(userAuthRequestMsg) 689 case msgUserAuthFailure: 690 msg = new(userAuthFailureMsg) 691 case msgUserAuthPubKeyOk: 692 msg = new(userAuthPubKeyOkMsg) 693 case msgGlobalRequest: 694 msg = new(globalRequestMsg) 695 case msgRequestSuccess: 696 msg = new(globalRequestSuccessMsg) 697 case msgRequestFailure: 698 msg = new(globalRequestFailureMsg) 699 case msgChannelOpen: 700 msg = new(channelOpenMsg) 701 case msgChannelOpenConfirm: 702 msg = new(channelOpenConfirmMsg) 703 case msgChannelOpenFailure: 704 msg = new(channelOpenFailureMsg) 705 case msgChannelWindowAdjust: 706 msg = new(windowAdjustMsg) 707 case msgChannelEOF: 708 msg = new(channelEOFMsg) 709 case msgChannelClose: 710 msg = new(channelCloseMsg) 711 case msgChannelRequest: 712 msg = new(channelRequestMsg) 713 case msgChannelSuccess: 714 msg = new(channelRequestSuccessMsg) 715 case msgChannelFailure: 716 msg = new(channelRequestFailureMsg) 717 default: 718 return nil, unexpectedMessageError(0, packet[0]) 719 } 720 if err := Unmarshal(packet, msg); err != nil { 721 return nil, err 722 } 723 return msg, nil 724 }