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.
19 // These are SSH message type numbers. They are scattered around several
20 // documents but many were taken from [SSH-PARAMETERS].
27 // Standard authentication messages
28 msgUserAuthSuccess = 52
29 msgUserAuthBanner = 53
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.
39 // See RFC 4253, section 11.1.
40 const msgDisconnect = 1
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"`
50 func (d *disconnectMsg) Error() string {
51 return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
54 // See RFC 4253, section 7.1.
57 type kexInitMsg struct {
58 Cookie [16]byte `sshtype:"20"`
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
73 // See RFC 4253, section 8.
76 const msgKexDHInit = 30
78 type kexDHInitMsg struct {
79 X *big.Int `sshtype:"30"`
82 const msgKexECDHInit = 30
84 type kexECDHInitMsg struct {
85 ClientPubKey []byte `sshtype:"30"`
88 const msgKexECDHReply = 31
90 type kexECDHReplyMsg struct {
91 HostKey []byte `sshtype:"31"`
92 EphemeralPubKey []byte
96 const msgKexDHReply = 31
98 type kexDHReplyMsg struct {
99 HostKey []byte `sshtype:"31"`
104 // See RFC 4253, section 10.
105 const msgServiceRequest = 5
107 type serviceRequestMsg struct {
108 Service string `sshtype:"5"`
111 // See RFC 4253, section 10.
112 const msgServiceAccept = 6
114 type serviceAcceptMsg struct {
115 Service string `sshtype:"6"`
118 // See RFC 4252, section 5.
119 const msgUserAuthRequest = 50
121 type userAuthRequestMsg struct {
122 User string `sshtype:"50"`
125 Payload []byte `ssh:"rest"`
128 // Used for debug printouts of packets.
129 type userAuthSuccessMsg struct {
132 // See RFC 4252, section 5.1
133 const msgUserAuthFailure = 51
135 type userAuthFailureMsg struct {
136 Methods []string `sshtype:"51"`
140 // See RFC 4256, section 3.2
141 const msgUserAuthInfoRequest = 60
142 const msgUserAuthInfoResponse = 61
144 type userAuthInfoRequestMsg struct {
145 User string `sshtype:"60"`
147 DeprecatedLanguage string
149 Prompts []byte `ssh:"rest"`
152 // See RFC 4254, section 5.1.
153 const msgChannelOpen = 90
155 type channelOpenMsg struct {
156 ChanType string `sshtype:"90"`
160 TypeSpecificData []byte `ssh:"rest"`
163 const msgChannelExtendedData = 95
164 const msgChannelData = 94
166 // Used for debug print outs of packets.
167 type channelDataMsg struct {
168 PeersId uint32 `sshtype:"94"`
170 Rest []byte `ssh:"rest"`
173 // See RFC 4254, section 5.1.
174 const msgChannelOpenConfirm = 91
176 type channelOpenConfirmMsg struct {
177 PeersId uint32 `sshtype:"91"`
181 TypeSpecificData []byte `ssh:"rest"`
184 // See RFC 4254, section 5.1.
185 const msgChannelOpenFailure = 92
187 type channelOpenFailureMsg struct {
188 PeersId uint32 `sshtype:"92"`
189 Reason RejectionReason
194 const msgChannelRequest = 98
196 type channelRequestMsg struct {
197 PeersId uint32 `sshtype:"98"`
200 RequestSpecificData []byte `ssh:"rest"`
203 // See RFC 4254, section 5.4.
204 const msgChannelSuccess = 99
206 type channelRequestSuccessMsg struct {
207 PeersId uint32 `sshtype:"99"`
210 // See RFC 4254, section 5.4.
211 const msgChannelFailure = 100
213 type channelRequestFailureMsg struct {
214 PeersId uint32 `sshtype:"100"`
217 // See RFC 4254, section 5.3
218 const msgChannelClose = 97
220 type channelCloseMsg struct {
221 PeersId uint32 `sshtype:"97"`
224 // See RFC 4254, section 5.3
225 const msgChannelEOF = 96
227 type channelEOFMsg struct {
228 PeersId uint32 `sshtype:"96"`
231 // See RFC 4254, section 4
232 const msgGlobalRequest = 80
234 type globalRequestMsg struct {
235 Type string `sshtype:"80"`
237 Data []byte `ssh:"rest"`
240 // See RFC 4254, section 4
241 const msgRequestSuccess = 81
243 type globalRequestSuccessMsg struct {
244 Data []byte `ssh:"rest" sshtype:"81"`
247 // See RFC 4254, section 4
248 const msgRequestFailure = 82
250 type globalRequestFailureMsg struct {
251 Data []byte `ssh:"rest" sshtype:"82"`
254 // See RFC 4254, section 5.2
255 const msgChannelWindowAdjust = 93
257 type windowAdjustMsg struct {
258 PeersId uint32 `sshtype:"93"`
259 AdditionalBytes uint32
262 // See RFC 4252, section 7
263 const msgUserAuthPubKeyOk = 60
265 type userAuthPubKeyOkMsg struct {
266 Algo string `sshtype:"60"`
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")
275 for _, tag := range strings.Split(tagStr, "|") {
276 i, err := strconv.Atoi(tag)
278 tags = append(tags, byte(i))
285 func fieldError(t reflect.Type, field int, problem string) error {
287 problem = ": " + problem
289 return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem)
292 var errShortRead = errors.New("ssh: short read")
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)
305 var expectedType byte
306 if len(expectedTypes) > 0 {
307 expectedType = expectedTypes[0]
311 return parseError(expectedType)
314 if len(expectedTypes) > 0 {
316 for _, e := range expectedTypes {
317 if e > 0 && data[0] == e {
323 return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
329 for i := 0; i < v.NumField(); i++ {
337 field.SetBool(data[0] != 0)
340 if t.Elem().Kind() != reflect.Uint8 {
341 return fieldError(structType, i, "array of unsupported type")
343 if len(data) < t.Len() {
346 for j, n := 0, t.Len(); j < n; j++ {
347 field.Index(j).Set(reflect.ValueOf(data[j]))
349 data = data[t.Len():]
352 if u64, data, ok = parseUint64(data); !ok {
358 if u32, data, ok = parseUint32(data); !ok {
361 field.SetUint(uint64(u32))
366 field.SetUint(uint64(data[0]))
370 if s, data, ok = parseString(data); !ok {
371 return fieldError(structType, i, "")
373 field.SetString(string(s))
375 switch t.Elem().Kind() {
377 if structType.Field(i).Tag.Get("ssh") == "rest" {
378 field.Set(reflect.ValueOf(data))
382 if s, data, ok = parseString(data); !ok {
385 field.Set(reflect.ValueOf(s))
389 if nl, data, ok = parseNameList(data); !ok {
392 field.Set(reflect.ValueOf(nl))
394 return fieldError(structType, i, "slice of unsupported type")
399 if n, data, ok = parseInt(data); !ok {
402 field.Set(reflect.ValueOf(n))
404 return fieldError(structType, i, "pointer to unsupported type")
407 return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
412 return parseError(expectedType)
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)
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])
435 for i, n := 0, v.NumField(); i < n; i++ {
437 switch t := field.Type(); t.Kind() {
445 if t.Elem().Kind() != reflect.Uint8 {
446 panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface()))
448 for j, l := 0, t.Len(); j < l; j++ {
449 out = append(out, uint8(field.Index(j).Uint()))
452 out = appendU32(out, uint32(field.Uint()))
454 out = appendU64(out, uint64(field.Uint()))
456 out = append(out, uint8(field.Uint()))
459 out = appendInt(out, len(s))
460 out = append(out, s...)
462 switch t.Elem().Kind() {
464 if v.Type().Field(i).Tag.Get("ssh") != "rest" {
465 out = appendInt(out, field.Len())
467 out = append(out, field.Bytes()...)
470 out = appendU32(out, 0)
471 if n := field.Len(); n > 0 {
472 for j := 0; j < n; j++ {
475 out = append(out, ',')
477 out = append(out, f.String()...)
479 // overwrite length value
480 binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))
483 panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface()))
488 nValue := reflect.ValueOf(&n)
489 nValue.Elem().Set(field)
490 needed := intLength(n)
491 oldLength := len(out)
493 if cap(out)-len(out) < needed {
494 newOut := make([]byte, len(out), 2*(len(out)+needed))
498 out = out[:oldLength+needed]
499 marshalInt(out[oldLength:], n)
501 panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface()))
509 var bigOne = big.NewInt(1)
511 func parseString(in []byte) (out, rest []byte, ok bool) {
515 length := binary.BigEndian.Uint32(in)
517 if uint32(len(in)) < length {
528 emptyNameList = []string{}
531 func parseNameList(in []byte) (out []string, rest []byte, ok bool) {
532 contents, rest, ok := parseString(in)
536 if len(contents) == 0 {
540 parts := bytes.Split(contents, comma)
541 out = make([]string, len(parts))
542 for i, part := range parts {
543 out[i] = string(part)
548 func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {
549 contents, rest, ok := parseString(in)
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]
561 out.SetBytes(notBytes)
566 out.SetBytes(contents)
572 func parseUint32(in []byte) (uint32, []byte, bool) {
576 return binary.BigEndian.Uint32(in), in[4:], true
579 func parseUint64(in []byte) (uint64, []byte, bool) {
583 return binary.BigEndian.Uint64(in), in[8:], true
586 func intLength(n *big.Int) int {
587 length := 4 /* length bytes */
589 nMinus1 := new(big.Int).Neg(n)
590 nMinus1.Sub(nMinus1, bigOne)
591 bitLen := nMinus1.BitLen()
593 // The number will need 0xff padding
596 length += (bitLen + 7) / 8
597 } else if n.Sign() == 0 {
598 // A zero is the zero length string
602 // The number will need 0x00 padding
605 length += (bitLen + 7) / 8
611 func marshalUint32(to []byte, n uint32) []byte {
612 binary.BigEndian.PutUint32(to, n)
616 func marshalUint64(to []byte, n uint64) []byte {
617 binary.BigEndian.PutUint64(to, n)
621 func marshalInt(to []byte, n *big.Int) []byte {
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 {
637 if len(bytes) == 0 || bytes[0]&0x80 == 0 {
642 nBytes := copy(to, bytes)
645 } else if n.Sign() == 0 {
646 // A zero is the zero length string
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.
656 nBytes := copy(to, bytes)
661 lengthBytes[0] = byte(length >> 24)
662 lengthBytes[1] = byte(length >> 16)
663 lengthBytes[2] = byte(length >> 8)
664 lengthBytes[3] = byte(length)
668 func writeInt(w io.Writer, n *big.Int) {
669 length := intLength(n)
670 buf := make([]byte, length)
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[:])
685 func stringLength(n int) int {
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)
699 var bigIntType = reflect.TypeOf((*big.Int)(nil))
701 // Decode a packet into its corresponding message.
702 func decode(packet []byte) (interface{}, error) {
706 msg = new(disconnectMsg)
707 case msgServiceRequest:
708 msg = new(serviceRequestMsg)
709 case msgServiceAccept:
710 msg = new(serviceAcceptMsg)
712 msg = new(kexInitMsg)
714 msg = new(kexDHInitMsg)
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)
732 msg = new(channelOpenMsg)
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)
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)
752 return nil, unexpectedMessageError(0, packet[0])
754 if err := Unmarshal(packet, msg); err != nil {