OSDN Git Service

versoin1.1.9 (#594)
[bytom/vapor.git] / vendor / golang.org / x / crypto / ssh / messages.go
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 }