OSDN Git Service

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