a geicko-2 based round robin ranking system designed to test c++ battleship submissions
battleship.dunkirk.sh
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
5package ssh
6
7import (
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].
21const (
22 msgIgnore = 2
23 msgUnimplemented = 3
24 msgDebug = 4
25 msgNewKeys = 21
26)
27
28// SSH messages:
29//
30// These structures mirror the wire format of the corresponding SSH messages.
31// They are marshaled using reflection with the marshal and unmarshal functions
32// in this file. The only wrinkle is that a final member of type []byte with a
33// ssh tag of "rest" receives the remainder of a packet when unmarshaling.
34
35// See RFC 4253, section 11.1.
36const msgDisconnect = 1
37
38// disconnectMsg is the message that signals a disconnect. It is also
39// the error type returned from mux.Wait()
40type disconnectMsg struct {
41 Reason uint32 `sshtype:"1"`
42 Message string
43 Language string
44}
45
46func (d *disconnectMsg) Error() string {
47 return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
48}
49
50// See RFC 4253, section 7.1.
51const msgKexInit = 20
52
53type 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// See RFC 4253, section 8.
70
71// Diffie-Hellman
72const msgKexDHInit = 30
73
74type kexDHInitMsg struct {
75 X *big.Int `sshtype:"30"`
76}
77
78const msgKexECDHInit = 30
79
80type kexECDHInitMsg struct {
81 ClientPubKey []byte `sshtype:"30"`
82}
83
84const msgKexECDHReply = 31
85
86type kexECDHReplyMsg struct {
87 HostKey []byte `sshtype:"31"`
88 EphemeralPubKey []byte
89 Signature []byte
90}
91
92const msgKexDHReply = 31
93
94type kexDHReplyMsg struct {
95 HostKey []byte `sshtype:"31"`
96 Y *big.Int
97 Signature []byte
98}
99
100// See RFC 4419, section 5.
101const msgKexDHGexGroup = 31
102
103type kexDHGexGroupMsg struct {
104 P *big.Int `sshtype:"31"`
105 G *big.Int
106}
107
108const msgKexDHGexInit = 32
109
110type kexDHGexInitMsg struct {
111 X *big.Int `sshtype:"32"`
112}
113
114const msgKexDHGexReply = 33
115
116type kexDHGexReplyMsg struct {
117 HostKey []byte `sshtype:"33"`
118 Y *big.Int
119 Signature []byte
120}
121
122const msgKexDHGexRequest = 34
123
124type kexDHGexRequestMsg struct {
125 MinBits uint32 `sshtype:"34"`
126 PreferredBits uint32
127 MaxBits uint32
128}
129
130// See RFC 4253, section 10.
131const msgServiceRequest = 5
132
133type serviceRequestMsg struct {
134 Service string `sshtype:"5"`
135}
136
137// See RFC 4253, section 10.
138const msgServiceAccept = 6
139
140type serviceAcceptMsg struct {
141 Service string `sshtype:"6"`
142}
143
144// See RFC 8308, section 2.3
145const msgExtInfo = 7
146
147type extInfoMsg struct {
148 NumExtensions uint32 `sshtype:"7"`
149 Payload []byte `ssh:"rest"`
150}
151
152// See RFC 4252, section 5.
153const msgUserAuthRequest = 50
154
155type userAuthRequestMsg struct {
156 User string `sshtype:"50"`
157 Service string
158 Method string
159 Payload []byte `ssh:"rest"`
160}
161
162// Used for debug printouts of packets.
163type userAuthSuccessMsg struct {
164}
165
166// See RFC 4252, section 5.1
167const msgUserAuthFailure = 51
168
169type userAuthFailureMsg struct {
170 Methods []string `sshtype:"51"`
171 PartialSuccess bool
172}
173
174// See RFC 4252, section 5.1
175const msgUserAuthSuccess = 52
176
177// See RFC 4252, section 5.4
178const msgUserAuthBanner = 53
179
180type userAuthBannerMsg struct {
181 Message string `sshtype:"53"`
182 // unused, but required to allow message parsing
183 Language string
184}
185
186// See RFC 4256, section 3.2
187const msgUserAuthInfoRequest = 60
188const msgUserAuthInfoResponse = 61
189
190type userAuthInfoRequestMsg struct {
191 Name string `sshtype:"60"`
192 Instruction string
193 Language string
194 NumPrompts uint32
195 Prompts []byte `ssh:"rest"`
196}
197
198// See RFC 4254, section 5.1.
199const msgChannelOpen = 90
200
201type channelOpenMsg struct {
202 ChanType string `sshtype:"90"`
203 PeersID uint32
204 PeersWindow uint32
205 MaxPacketSize uint32
206 TypeSpecificData []byte `ssh:"rest"`
207}
208
209const msgChannelExtendedData = 95
210const msgChannelData = 94
211
212// Used for debug print outs of packets.
213type channelDataMsg struct {
214 PeersID uint32 `sshtype:"94"`
215 Length uint32
216 Rest []byte `ssh:"rest"`
217}
218
219// See RFC 4254, section 5.1.
220const msgChannelOpenConfirm = 91
221
222type channelOpenConfirmMsg struct {
223 PeersID uint32 `sshtype:"91"`
224 MyID uint32
225 MyWindow uint32
226 MaxPacketSize uint32
227 TypeSpecificData []byte `ssh:"rest"`
228}
229
230// See RFC 4254, section 5.1.
231const msgChannelOpenFailure = 92
232
233type channelOpenFailureMsg struct {
234 PeersID uint32 `sshtype:"92"`
235 Reason RejectionReason
236 Message string
237 Language string
238}
239
240const msgChannelRequest = 98
241
242type channelRequestMsg struct {
243 PeersID uint32 `sshtype:"98"`
244 Request string
245 WantReply bool
246 RequestSpecificData []byte `ssh:"rest"`
247}
248
249// See RFC 4254, section 5.4.
250const msgChannelSuccess = 99
251
252type channelRequestSuccessMsg struct {
253 PeersID uint32 `sshtype:"99"`
254}
255
256// See RFC 4254, section 5.4.
257const msgChannelFailure = 100
258
259type channelRequestFailureMsg struct {
260 PeersID uint32 `sshtype:"100"`
261}
262
263// See RFC 4254, section 5.3
264const msgChannelClose = 97
265
266type channelCloseMsg struct {
267 PeersID uint32 `sshtype:"97"`
268}
269
270// See RFC 4254, section 5.3
271const msgChannelEOF = 96
272
273type channelEOFMsg struct {
274 PeersID uint32 `sshtype:"96"`
275}
276
277// See RFC 4254, section 4
278const msgGlobalRequest = 80
279
280type globalRequestMsg struct {
281 Type string `sshtype:"80"`
282 WantReply bool
283 Data []byte `ssh:"rest"`
284}
285
286// See RFC 4254, section 4
287const msgRequestSuccess = 81
288
289type globalRequestSuccessMsg struct {
290 Data []byte `ssh:"rest" sshtype:"81"`
291}
292
293// See RFC 4254, section 4
294const msgRequestFailure = 82
295
296type globalRequestFailureMsg struct {
297 Data []byte `ssh:"rest" sshtype:"82"`
298}
299
300// See RFC 4254, section 5.2
301const msgChannelWindowAdjust = 93
302
303type windowAdjustMsg struct {
304 PeersID uint32 `sshtype:"93"`
305 AdditionalBytes uint32
306}
307
308// See RFC 4252, section 7
309const msgUserAuthPubKeyOk = 60
310
311type userAuthPubKeyOkMsg struct {
312 Algo string `sshtype:"60"`
313 PubKey []byte
314}
315
316// See RFC 4462, section 3
317const msgUserAuthGSSAPIResponse = 60
318
319type userAuthGSSAPIResponse struct {
320 SupportMech []byte `sshtype:"60"`
321}
322
323const msgUserAuthGSSAPIToken = 61
324
325type userAuthGSSAPIToken struct {
326 Token []byte `sshtype:"61"`
327}
328
329const msgUserAuthGSSAPIMIC = 66
330
331type userAuthGSSAPIMIC struct {
332 MIC []byte `sshtype:"66"`
333}
334
335// See RFC 4462, section 3.9
336const msgUserAuthGSSAPIErrTok = 64
337
338type userAuthGSSAPIErrTok struct {
339 ErrorToken []byte `sshtype:"64"`
340}
341
342// See RFC 4462, section 3.8
343const msgUserAuthGSSAPIError = 65
344
345type userAuthGSSAPIError struct {
346 MajorStatus uint32 `sshtype:"65"`
347 MinorStatus uint32
348 Message string
349 LanguageTag string
350}
351
352// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
353const msgPing = 192
354
355type pingMsg struct {
356 Data string `sshtype:"192"`
357}
358
359// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
360const msgPong = 193
361
362type pongMsg struct {
363 Data string `sshtype:"193"`
364}
365
366// typeTags returns the possible type bytes for the given reflect.Type, which
367// should be a struct. The possible values are separated by a '|' character.
368func 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
381func 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
388var errShortRead = errors.New("ssh: short read")
389
390// Unmarshal parses data in SSH wire format into a structure. The out
391// argument should be a pointer to struct. If the first member of the
392// struct has the "sshtype" tag set to a '|'-separated set of numbers
393// in decimal, the packet must start with one of those numbers. In
394// case of error, Unmarshal returns a ParseError or
395// UnexpectedMessageError.
396func 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// Marshal serializes the message in msg to SSH wire format. The msg
515// argument should be a struct or pointer to struct. If the first
516// member has the "sshtype" tag set to a number in decimal, that
517// number is prepended to the result. If the last of member has the
518// "ssh" tag set to "rest", its contents are appended to the output.
519func Marshal(msg interface{}) []byte {
520 out := make([]byte, 0, 64)
521 return marshalStruct(out, msg)
522}
523
524func 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 // overwrite length value
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
605var bigOne = big.NewInt(1)
606
607func 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
622var (
623 comma = []byte{','}
624 emptyNameList = []string{}
625)
626
627func 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
644func 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 // This is a negative number
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 // Positive number
662 out.SetBytes(contents)
663 }
664 ok = true
665 return
666}
667
668func 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
675func 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
682func intLength(n *big.Int) int {
683 length := 4 /* length bytes */
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 // The number will need 0xff padding
690 length++
691 }
692 length += (bitLen + 7) / 8
693 } else if n.Sign() == 0 {
694 // A zero is the zero length string
695 } else {
696 bitLen := n.BitLen()
697 if bitLen%8 == 0 {
698 // The number will need 0x00 padding
699 length++
700 }
701 length += (bitLen + 7) / 8
702 }
703
704 return length
705}
706
707func marshalUint32(to []byte, n uint32) []byte {
708 binary.BigEndian.PutUint32(to, n)
709 return to[4:]
710}
711
712func marshalUint64(to []byte, n uint64) []byte {
713 binary.BigEndian.PutUint64(to, n)
714 return to[8:]
715}
716
717func marshalInt(to []byte, n *big.Int) []byte {
718 lengthBytes := to
719 to = to[4:]
720 length := 0
721
722 if n.Sign() < 0 {
723 // A negative number has to be converted to two's-complement
724 // form. So we'll subtract 1 and invert. If the
725 // most-significant-bit isn't set then we'll need to pad the
726 // beginning with 0xff in order to keep the number negative.
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 // A zero is the zero length string
743 } else {
744 bytes := n.Bytes()
745 if len(bytes) > 0 && bytes[0]&0x80 != 0 {
746 // We'll have to pad this with a 0x00 in order to
747 // stop it looking like a negative number.
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
764func 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
771func 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
781func stringLength(n int) int {
782 return 4 + n
783}
784
785func 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
795var bigIntType = reflect.TypeOf((*big.Int)(nil))
796
797// Decode a packet into its corresponding message.
798func 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 msgUserAuthBanner:
822 msg = new(userAuthBannerMsg)
823 case msgUserAuthPubKeyOk:
824 msg = new(userAuthPubKeyOkMsg)
825 case msgGlobalRequest:
826 msg = new(globalRequestMsg)
827 case msgRequestSuccess:
828 msg = new(globalRequestSuccessMsg)
829 case msgRequestFailure:
830 msg = new(globalRequestFailureMsg)
831 case msgChannelOpen:
832 msg = new(channelOpenMsg)
833 case msgChannelData:
834 msg = new(channelDataMsg)
835 case msgChannelOpenConfirm:
836 msg = new(channelOpenConfirmMsg)
837 case msgChannelOpenFailure:
838 msg = new(channelOpenFailureMsg)
839 case msgChannelWindowAdjust:
840 msg = new(windowAdjustMsg)
841 case msgChannelEOF:
842 msg = new(channelEOFMsg)
843 case msgChannelClose:
844 msg = new(channelCloseMsg)
845 case msgChannelRequest:
846 msg = new(channelRequestMsg)
847 case msgChannelSuccess:
848 msg = new(channelRequestSuccessMsg)
849 case msgChannelFailure:
850 msg = new(channelRequestFailureMsg)
851 case msgUserAuthGSSAPIToken:
852 msg = new(userAuthGSSAPIToken)
853 case msgUserAuthGSSAPIMIC:
854 msg = new(userAuthGSSAPIMIC)
855 case msgUserAuthGSSAPIErrTok:
856 msg = new(userAuthGSSAPIErrTok)
857 case msgUserAuthGSSAPIError:
858 msg = new(userAuthGSSAPIError)
859 default:
860 return nil, unexpectedMessageError(0, packet[0])
861 }
862 if err := Unmarshal(packet, msg); err != nil {
863 return nil, err
864 }
865 return msg, nil
866}
867
868var packetTypeNames = map[byte]string{
869 msgDisconnect: "disconnectMsg",
870 msgServiceRequest: "serviceRequestMsg",
871 msgServiceAccept: "serviceAcceptMsg",
872 msgExtInfo: "extInfoMsg",
873 msgKexInit: "kexInitMsg",
874 msgKexDHInit: "kexDHInitMsg",
875 msgKexDHReply: "kexDHReplyMsg",
876 msgUserAuthRequest: "userAuthRequestMsg",
877 msgUserAuthSuccess: "userAuthSuccessMsg",
878 msgUserAuthFailure: "userAuthFailureMsg",
879 msgUserAuthPubKeyOk: "userAuthPubKeyOkMsg",
880 msgGlobalRequest: "globalRequestMsg",
881 msgRequestSuccess: "globalRequestSuccessMsg",
882 msgRequestFailure: "globalRequestFailureMsg",
883 msgChannelOpen: "channelOpenMsg",
884 msgChannelData: "channelDataMsg",
885 msgChannelOpenConfirm: "channelOpenConfirmMsg",
886 msgChannelOpenFailure: "channelOpenFailureMsg",
887 msgChannelWindowAdjust: "windowAdjustMsg",
888 msgChannelEOF: "channelEOFMsg",
889 msgChannelClose: "channelCloseMsg",
890 msgChannelRequest: "channelRequestMsg",
891 msgChannelSuccess: "channelRequestSuccessMsg",
892 msgChannelFailure: "channelRequestFailureMsg",
893}