]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/golang.org/x/crypto/ssh/messages.go
Merge branch 'master' of /Users/jake/terraform
[github/fretlink/terraform-provider-statuscake.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 }