1
2
3
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
20
21 const (
22 msgIgnore = 2
23 msgUnimplemented = 3
24 msgDebug = 4
25 msgNewKeys = 21
26 )
27
28
29
30
31
32
33
34
35
36 const msgDisconnect = 1
37
38
39
40 type disconnectMsg struct {
41 Reason uint32 `sshtype:"1"`
42 Message string
43 Language string
44 }
45
46 func (d *disconnectMsg) Error() string {
47 return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
48 }
49
50
51 const msgKexInit = 20
52
53 type kexInitMsg struct {
54 Cookie [16]byte `sshtype:"20"`
55 KexAlgos []string
56 ServerHostKeyAlgos []string
57 CiphersClientServer []string
58 CiphersServerClient []string
59 MACsClientServer []string
60 MACsServerClient []string
61 CompressionClientServer []string
62 CompressionServerClient []string
63 LanguagesClientServer []string
64 LanguagesServerClient []string
65 FirstKexFollows bool
66 Reserved uint32
67 }
68
69
70
71
72 const msgKexDHInit = 30
73
74 type kexDHInitMsg struct {
75 X *big.Int `sshtype:"30"`
76 }
77
78 const msgKexECDHInit = 30
79
80 type kexECDHInitMsg struct {
81 ClientPubKey []byte `sshtype:"30"`
82 }
83
84 const msgKexECDHReply = 31
85
86 type kexECDHReplyMsg struct {
87 HostKey []byte `sshtype:"31"`
88 EphemeralPubKey []byte
89 Signature []byte
90 }
91
92 const msgKexDHReply = 31
93
94 type kexDHReplyMsg struct {
95 HostKey []byte `sshtype:"31"`
96 Y *big.Int
97 Signature []byte
98 }
99
100
101 const msgKexDHGexGroup = 31
102
103 type kexDHGexGroupMsg struct {
104 P *big.Int `sshtype:"31"`
105 G *big.Int
106 }
107
108 const msgKexDHGexInit = 32
109
110 type kexDHGexInitMsg struct {
111 X *big.Int `sshtype:"32"`
112 }
113
114 const msgKexDHGexReply = 33
115
116 type kexDHGexReplyMsg struct {
117 HostKey []byte `sshtype:"33"`
118 Y *big.Int
119 Signature []byte
120 }
121
122 const msgKexDHGexRequest = 34
123
124 type kexDHGexRequestMsg struct {
125 MinBits uint32 `sshtype:"34"`
126 PreferedBits uint32
127 MaxBits uint32
128 }
129
130
131 const msgServiceRequest = 5
132
133 type serviceRequestMsg struct {
134 Service string `sshtype:"5"`
135 }
136
137
138 const msgServiceAccept = 6
139
140 type serviceAcceptMsg struct {
141 Service string `sshtype:"6"`
142 }
143
144
145 const msgExtInfo = 7
146
147 type extInfoMsg struct {
148 NumExtensions uint32 `sshtype:"7"`
149 Payload []byte `ssh:"rest"`
150 }
151
152
153 const msgUserAuthRequest = 50
154
155 type userAuthRequestMsg struct {
156 User string `sshtype:"50"`
157 Service string
158 Method string
159 Payload []byte `ssh:"rest"`
160 }
161
162
163 type userAuthSuccessMsg struct {
164 }
165
166
167 const msgUserAuthFailure = 51
168
169 type userAuthFailureMsg struct {
170 Methods []string `sshtype:"51"`
171 PartialSuccess bool
172 }
173
174
175 const msgUserAuthSuccess = 52
176
177
178 const msgUserAuthBanner = 53
179
180 type userAuthBannerMsg struct {
181 Message string `sshtype:"53"`
182
183 Language string
184 }
185
186
187 const msgUserAuthInfoRequest = 60
188 const msgUserAuthInfoResponse = 61
189
190 type userAuthInfoRequestMsg struct {
191 Name string `sshtype:"60"`
192 Instruction string
193 Language string
194 NumPrompts uint32
195 Prompts []byte `ssh:"rest"`
196 }
197
198
199 const msgChannelOpen = 90
200
201 type channelOpenMsg struct {
202 ChanType string `sshtype:"90"`
203 PeersID uint32
204 PeersWindow uint32
205 MaxPacketSize uint32
206 TypeSpecificData []byte `ssh:"rest"`
207 }
208
209 const msgChannelExtendedData = 95
210 const msgChannelData = 94
211
212
213 type channelDataMsg struct {
214 PeersID uint32 `sshtype:"94"`
215 Length uint32
216 Rest []byte `ssh:"rest"`
217 }
218
219
220 const msgChannelOpenConfirm = 91
221
222 type channelOpenConfirmMsg struct {
223 PeersID uint32 `sshtype:"91"`
224 MyID uint32
225 MyWindow uint32
226 MaxPacketSize uint32
227 TypeSpecificData []byte `ssh:"rest"`
228 }
229
230
231 const msgChannelOpenFailure = 92
232
233 type channelOpenFailureMsg struct {
234 PeersID uint32 `sshtype:"92"`
235 Reason RejectionReason
236 Message string
237 Language string
238 }
239
240 const msgChannelRequest = 98
241
242 type channelRequestMsg struct {
243 PeersID uint32 `sshtype:"98"`
244 Request string
245 WantReply bool
246 RequestSpecificData []byte `ssh:"rest"`
247 }
248
249
250 const msgChannelSuccess = 99
251
252 type channelRequestSuccessMsg struct {
253 PeersID uint32 `sshtype:"99"`
254 }
255
256
257 const msgChannelFailure = 100
258
259 type channelRequestFailureMsg struct {
260 PeersID uint32 `sshtype:"100"`
261 }
262
263
264 const msgChannelClose = 97
265
266 type channelCloseMsg struct {
267 PeersID uint32 `sshtype:"97"`
268 }
269
270
271 const msgChannelEOF = 96
272
273 type channelEOFMsg struct {
274 PeersID uint32 `sshtype:"96"`
275 }
276
277
278 const msgGlobalRequest = 80
279
280 type globalRequestMsg struct {
281 Type string `sshtype:"80"`
282 WantReply bool
283 Data []byte `ssh:"rest"`
284 }
285
286
287 const msgRequestSuccess = 81
288
289 type globalRequestSuccessMsg struct {
290 Data []byte `ssh:"rest" sshtype:"81"`
291 }
292
293
294 const msgRequestFailure = 82
295
296 type globalRequestFailureMsg struct {
297 Data []byte `ssh:"rest" sshtype:"82"`
298 }
299
300
301 const msgChannelWindowAdjust = 93
302
303 type windowAdjustMsg struct {
304 PeersID uint32 `sshtype:"93"`
305 AdditionalBytes uint32
306 }
307
308
309 const msgUserAuthPubKeyOk = 60
310
311 type userAuthPubKeyOkMsg struct {
312 Algo string `sshtype:"60"`
313 PubKey []byte
314 }
315
316
317 const msgUserAuthGSSAPIResponse = 60
318
319 type userAuthGSSAPIResponse struct {
320 SupportMech []byte `sshtype:"60"`
321 }
322
323 const msgUserAuthGSSAPIToken = 61
324
325 type userAuthGSSAPIToken struct {
326 Token []byte `sshtype:"61"`
327 }
328
329 const msgUserAuthGSSAPIMIC = 66
330
331 type userAuthGSSAPIMIC struct {
332 MIC []byte `sshtype:"66"`
333 }
334
335
336 const msgUserAuthGSSAPIErrTok = 64
337
338 type userAuthGSSAPIErrTok struct {
339 ErrorToken []byte `sshtype:"64"`
340 }
341
342
343 const msgUserAuthGSSAPIError = 65
344
345 type userAuthGSSAPIError struct {
346 MajorStatus uint32 `sshtype:"65"`
347 MinorStatus uint32
348 Message string
349 LanguageTag string
350 }
351
352
353 const msgPing = 192
354
355 type pingMsg struct {
356 Data string `sshtype:"192"`
357 }
358
359
360 const msgPong = 193
361
362 type pongMsg struct {
363 Data string `sshtype:"193"`
364 }
365
366
367
368 func typeTags(structType reflect.Type) (tags []byte) {
369 tagStr := structType.Field(0).Tag.Get("sshtype")
370
371 for _, tag := range strings.Split(tagStr, "|") {
372 i, err := strconv.Atoi(tag)
373 if err == nil {
374 tags = append(tags, byte(i))
375 }
376 }
377
378 return tags
379 }
380
381 func fieldError(t reflect.Type, field int, problem string) error {
382 if problem != "" {
383 problem = ": " + problem
384 }
385 return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem)
386 }
387
388 var errShortRead = errors.New("ssh: short read")
389
390
391
392
393
394
395
396 func Unmarshal(data []byte, out interface{}) error {
397 v := reflect.ValueOf(out).Elem()
398 structType := v.Type()
399 expectedTypes := typeTags(structType)
400
401 var expectedType byte
402 if len(expectedTypes) > 0 {
403 expectedType = expectedTypes[0]
404 }
405
406 if len(data) == 0 {
407 return parseError(expectedType)
408 }
409
410 if len(expectedTypes) > 0 {
411 goodType := false
412 for _, e := range expectedTypes {
413 if e > 0 && data[0] == e {
414 goodType = true
415 break
416 }
417 }
418 if !goodType {
419 return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
420 }
421 data = data[1:]
422 }
423
424 var ok bool
425 for i := 0; i < v.NumField(); i++ {
426 field := v.Field(i)
427 t := field.Type()
428 switch t.Kind() {
429 case reflect.Bool:
430 if len(data) < 1 {
431 return errShortRead
432 }
433 field.SetBool(data[0] != 0)
434 data = data[1:]
435 case reflect.Array:
436 if t.Elem().Kind() != reflect.Uint8 {
437 return fieldError(structType, i, "array of unsupported type")
438 }
439 if len(data) < t.Len() {
440 return errShortRead
441 }
442 for j, n := 0, t.Len(); j < n; j++ {
443 field.Index(j).Set(reflect.ValueOf(data[j]))
444 }
445 data = data[t.Len():]
446 case reflect.Uint64:
447 var u64 uint64
448 if u64, data, ok = parseUint64(data); !ok {
449 return errShortRead
450 }
451 field.SetUint(u64)
452 case reflect.Uint32:
453 var u32 uint32
454 if u32, data, ok = parseUint32(data); !ok {
455 return errShortRead
456 }
457 field.SetUint(uint64(u32))
458 case reflect.Uint8:
459 if len(data) < 1 {
460 return errShortRead
461 }
462 field.SetUint(uint64(data[0]))
463 data = data[1:]
464 case reflect.String:
465 var s []byte
466 if s, data, ok = parseString(data); !ok {
467 return fieldError(structType, i, "")
468 }
469 field.SetString(string(s))
470 case reflect.Slice:
471 switch t.Elem().Kind() {
472 case reflect.Uint8:
473 if structType.Field(i).Tag.Get("ssh") == "rest" {
474 field.Set(reflect.ValueOf(data))
475 data = nil
476 } else {
477 var s []byte
478 if s, data, ok = parseString(data); !ok {
479 return errShortRead
480 }
481 field.Set(reflect.ValueOf(s))
482 }
483 case reflect.String:
484 var nl []string
485 if nl, data, ok = parseNameList(data); !ok {
486 return errShortRead
487 }
488 field.Set(reflect.ValueOf(nl))
489 default:
490 return fieldError(structType, i, "slice of unsupported type")
491 }
492 case reflect.Ptr:
493 if t == bigIntType {
494 var n *big.Int
495 if n, data, ok = parseInt(data); !ok {
496 return errShortRead
497 }
498 field.Set(reflect.ValueOf(n))
499 } else {
500 return fieldError(structType, i, "pointer to unsupported type")
501 }
502 default:
503 return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
504 }
505 }
506
507 if len(data) != 0 {
508 return parseError(expectedType)
509 }
510
511 return nil
512 }
513
514
515
516
517
518
519 func Marshal(msg interface{}) []byte {
520 out := make([]byte, 0, 64)
521 return marshalStruct(out, msg)
522 }
523
524 func marshalStruct(out []byte, msg interface{}) []byte {
525 v := reflect.Indirect(reflect.ValueOf(msg))
526 msgTypes := typeTags(v.Type())
527 if len(msgTypes) > 0 {
528 out = append(out, msgTypes[0])
529 }
530
531 for i, n := 0, v.NumField(); i < n; i++ {
532 field := v.Field(i)
533 switch t := field.Type(); t.Kind() {
534 case reflect.Bool:
535 var v uint8
536 if field.Bool() {
537 v = 1
538 }
539 out = append(out, v)
540 case reflect.Array:
541 if t.Elem().Kind() != reflect.Uint8 {
542 panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface()))
543 }
544 for j, l := 0, t.Len(); j < l; j++ {
545 out = append(out, uint8(field.Index(j).Uint()))
546 }
547 case reflect.Uint32:
548 out = appendU32(out, uint32(field.Uint()))
549 case reflect.Uint64:
550 out = appendU64(out, uint64(field.Uint()))
551 case reflect.Uint8:
552 out = append(out, uint8(field.Uint()))
553 case reflect.String:
554 s := field.String()
555 out = appendInt(out, len(s))
556 out = append(out, s...)
557 case reflect.Slice:
558 switch t.Elem().Kind() {
559 case reflect.Uint8:
560 if v.Type().Field(i).Tag.Get("ssh") != "rest" {
561 out = appendInt(out, field.Len())
562 }
563 out = append(out, field.Bytes()...)
564 case reflect.String:
565 offset := len(out)
566 out = appendU32(out, 0)
567 if n := field.Len(); n > 0 {
568 for j := 0; j < n; j++ {
569 f := field.Index(j)
570 if j != 0 {
571 out = append(out, ',')
572 }
573 out = append(out, f.String()...)
574 }
575
576 binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))
577 }
578 default:
579 panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface()))
580 }
581 case reflect.Ptr:
582 if t == bigIntType {
583 var n *big.Int
584 nValue := reflect.ValueOf(&n)
585 nValue.Elem().Set(field)
586 needed := intLength(n)
587 oldLength := len(out)
588
589 if cap(out)-len(out) < needed {
590 newOut := make([]byte, len(out), 2*(len(out)+needed))
591 copy(newOut, out)
592 out = newOut
593 }
594 out = out[:oldLength+needed]
595 marshalInt(out[oldLength:], n)
596 } else {
597 panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface()))
598 }
599 }
600 }
601
602 return out
603 }
604
605 var bigOne = big.NewInt(1)
606
607 func parseString(in []byte) (out, rest []byte, ok bool) {
608 if len(in) < 4 {
609 return
610 }
611 length := binary.BigEndian.Uint32(in)
612 in = in[4:]
613 if uint32(len(in)) < length {
614 return
615 }
616 out = in[:length]
617 rest = in[length:]
618 ok = true
619 return
620 }
621
622 var (
623 comma = []byte{','}
624 emptyNameList = []string{}
625 )
626
627 func parseNameList(in []byte) (out []string, rest []byte, ok bool) {
628 contents, rest, ok := parseString(in)
629 if !ok {
630 return
631 }
632 if len(contents) == 0 {
633 out = emptyNameList
634 return
635 }
636 parts := bytes.Split(contents, comma)
637 out = make([]string, len(parts))
638 for i, part := range parts {
639 out[i] = string(part)
640 }
641 return
642 }
643
644 func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {
645 contents, rest, ok := parseString(in)
646 if !ok {
647 return
648 }
649 out = new(big.Int)
650
651 if len(contents) > 0 && contents[0]&0x80 == 0x80 {
652
653 notBytes := make([]byte, len(contents))
654 for i := range notBytes {
655 notBytes[i] = ^contents[i]
656 }
657 out.SetBytes(notBytes)
658 out.Add(out, bigOne)
659 out.Neg(out)
660 } else {
661
662 out.SetBytes(contents)
663 }
664 ok = true
665 return
666 }
667
668 func parseUint32(in []byte) (uint32, []byte, bool) {
669 if len(in) < 4 {
670 return 0, nil, false
671 }
672 return binary.BigEndian.Uint32(in), in[4:], true
673 }
674
675 func parseUint64(in []byte) (uint64, []byte, bool) {
676 if len(in) < 8 {
677 return 0, nil, false
678 }
679 return binary.BigEndian.Uint64(in), in[8:], true
680 }
681
682 func intLength(n *big.Int) int {
683 length := 4
684 if n.Sign() < 0 {
685 nMinus1 := new(big.Int).Neg(n)
686 nMinus1.Sub(nMinus1, bigOne)
687 bitLen := nMinus1.BitLen()
688 if bitLen%8 == 0 {
689
690 length++
691 }
692 length += (bitLen + 7) / 8
693 } else if n.Sign() == 0 {
694
695 } else {
696 bitLen := n.BitLen()
697 if bitLen%8 == 0 {
698
699 length++
700 }
701 length += (bitLen + 7) / 8
702 }
703
704 return length
705 }
706
707 func marshalUint32(to []byte, n uint32) []byte {
708 binary.BigEndian.PutUint32(to, n)
709 return to[4:]
710 }
711
712 func marshalUint64(to []byte, n uint64) []byte {
713 binary.BigEndian.PutUint64(to, n)
714 return to[8:]
715 }
716
717 func marshalInt(to []byte, n *big.Int) []byte {
718 lengthBytes := to
719 to = to[4:]
720 length := 0
721
722 if n.Sign() < 0 {
723
724
725
726
727 nMinus1 := new(big.Int).Neg(n)
728 nMinus1.Sub(nMinus1, bigOne)
729 bytes := nMinus1.Bytes()
730 for i := range bytes {
731 bytes[i] ^= 0xff
732 }
733 if len(bytes) == 0 || bytes[0]&0x80 == 0 {
734 to[0] = 0xff
735 to = to[1:]
736 length++
737 }
738 nBytes := copy(to, bytes)
739 to = to[nBytes:]
740 length += nBytes
741 } else if n.Sign() == 0 {
742
743 } else {
744 bytes := n.Bytes()
745 if len(bytes) > 0 && bytes[0]&0x80 != 0 {
746
747
748 to[0] = 0
749 to = to[1:]
750 length++
751 }
752 nBytes := copy(to, bytes)
753 to = to[nBytes:]
754 length += nBytes
755 }
756
757 lengthBytes[0] = byte(length >> 24)
758 lengthBytes[1] = byte(length >> 16)
759 lengthBytes[2] = byte(length >> 8)
760 lengthBytes[3] = byte(length)
761 return to
762 }
763
764 func writeInt(w io.Writer, n *big.Int) {
765 length := intLength(n)
766 buf := make([]byte, length)
767 marshalInt(buf, n)
768 w.Write(buf)
769 }
770
771 func writeString(w io.Writer, s []byte) {
772 var lengthBytes [4]byte
773 lengthBytes[0] = byte(len(s) >> 24)
774 lengthBytes[1] = byte(len(s) >> 16)
775 lengthBytes[2] = byte(len(s) >> 8)
776 lengthBytes[3] = byte(len(s))
777 w.Write(lengthBytes[:])
778 w.Write(s)
779 }
780
781 func stringLength(n int) int {
782 return 4 + n
783 }
784
785 func marshalString(to []byte, s []byte) []byte {
786 to[0] = byte(len(s) >> 24)
787 to[1] = byte(len(s) >> 16)
788 to[2] = byte(len(s) >> 8)
789 to[3] = byte(len(s))
790 to = to[4:]
791 copy(to, s)
792 return to[len(s):]
793 }
794
795 var bigIntType = reflect.TypeOf((*big.Int)(nil))
796
797
798 func decode(packet []byte) (interface{}, error) {
799 var msg interface{}
800 switch packet[0] {
801 case msgDisconnect:
802 msg = new(disconnectMsg)
803 case msgServiceRequest:
804 msg = new(serviceRequestMsg)
805 case msgServiceAccept:
806 msg = new(serviceAcceptMsg)
807 case msgExtInfo:
808 msg = new(extInfoMsg)
809 case msgKexInit:
810 msg = new(kexInitMsg)
811 case msgKexDHInit:
812 msg = new(kexDHInitMsg)
813 case msgKexDHReply:
814 msg = new(kexDHReplyMsg)
815 case msgUserAuthRequest:
816 msg = new(userAuthRequestMsg)
817 case msgUserAuthSuccess:
818 return new(userAuthSuccessMsg), nil
819 case msgUserAuthFailure:
820 msg = new(userAuthFailureMsg)
821 case msgUserAuthPubKeyOk:
822 msg = new(userAuthPubKeyOkMsg)
823 case msgGlobalRequest:
824 msg = new(globalRequestMsg)
825 case msgRequestSuccess:
826 msg = new(globalRequestSuccessMsg)
827 case msgRequestFailure:
828 msg = new(globalRequestFailureMsg)
829 case msgChannelOpen:
830 msg = new(channelOpenMsg)
831 case msgChannelData:
832 msg = new(channelDataMsg)
833 case msgChannelOpenConfirm:
834 msg = new(channelOpenConfirmMsg)
835 case msgChannelOpenFailure:
836 msg = new(channelOpenFailureMsg)
837 case msgChannelWindowAdjust:
838 msg = new(windowAdjustMsg)
839 case msgChannelEOF:
840 msg = new(channelEOFMsg)
841 case msgChannelClose:
842 msg = new(channelCloseMsg)
843 case msgChannelRequest:
844 msg = new(channelRequestMsg)
845 case msgChannelSuccess:
846 msg = new(channelRequestSuccessMsg)
847 case msgChannelFailure:
848 msg = new(channelRequestFailureMsg)
849 case msgUserAuthGSSAPIToken:
850 msg = new(userAuthGSSAPIToken)
851 case msgUserAuthGSSAPIMIC:
852 msg = new(userAuthGSSAPIMIC)
853 case msgUserAuthGSSAPIErrTok:
854 msg = new(userAuthGSSAPIErrTok)
855 case msgUserAuthGSSAPIError:
856 msg = new(userAuthGSSAPIError)
857 default:
858 return nil, unexpectedMessageError(0, packet[0])
859 }
860 if err := Unmarshal(packet, msg); err != nil {
861 return nil, err
862 }
863 return msg, nil
864 }
865
866 var packetTypeNames = map[byte]string{
867 msgDisconnect: "disconnectMsg",
868 msgServiceRequest: "serviceRequestMsg",
869 msgServiceAccept: "serviceAcceptMsg",
870 msgExtInfo: "extInfoMsg",
871 msgKexInit: "kexInitMsg",
872 msgKexDHInit: "kexDHInitMsg",
873 msgKexDHReply: "kexDHReplyMsg",
874 msgUserAuthRequest: "userAuthRequestMsg",
875 msgUserAuthSuccess: "userAuthSuccessMsg",
876 msgUserAuthFailure: "userAuthFailureMsg",
877 msgUserAuthPubKeyOk: "userAuthPubKeyOkMsg",
878 msgGlobalRequest: "globalRequestMsg",
879 msgRequestSuccess: "globalRequestSuccessMsg",
880 msgRequestFailure: "globalRequestFailureMsg",
881 msgChannelOpen: "channelOpenMsg",
882 msgChannelData: "channelDataMsg",
883 msgChannelOpenConfirm: "channelOpenConfirmMsg",
884 msgChannelOpenFailure: "channelOpenFailureMsg",
885 msgChannelWindowAdjust: "windowAdjustMsg",
886 msgChannelEOF: "channelEOFMsg",
887 msgChannelClose: "channelCloseMsg",
888 msgChannelRequest: "channelRequestMsg",
889 msgChannelSuccess: "channelRequestSuccessMsg",
890 msgChannelFailure: "channelRequestFailureMsg",
891 }
892
View as plain text