mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Added all required dependencies
This commit is contained in:
		
							
								
								
									
										758
									
								
								vendor/golang.org/x/crypto/ssh/messages.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										758
									
								
								vendor/golang.org/x/crypto/ssh/messages.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,758 @@ | ||||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package ssh | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"math/big" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // These are SSH message type numbers. They are scattered around several | ||||
| // documents but many were taken from [SSH-PARAMETERS]. | ||||
| const ( | ||||
| 	msgIgnore        = 2 | ||||
| 	msgUnimplemented = 3 | ||||
| 	msgDebug         = 4 | ||||
| 	msgNewKeys       = 21 | ||||
|  | ||||
| 	// Standard authentication messages | ||||
| 	msgUserAuthSuccess = 52 | ||||
| 	msgUserAuthBanner  = 53 | ||||
| ) | ||||
|  | ||||
| // SSH messages: | ||||
| // | ||||
| // These structures mirror the wire format of the corresponding SSH messages. | ||||
| // They are marshaled using reflection with the marshal and unmarshal functions | ||||
| // in this file. The only wrinkle is that a final member of type []byte with a | ||||
| // ssh tag of "rest" receives the remainder of a packet when unmarshaling. | ||||
|  | ||||
| // See RFC 4253, section 11.1. | ||||
| const msgDisconnect = 1 | ||||
|  | ||||
| // disconnectMsg is the message that signals a disconnect. It is also | ||||
| // the error type returned from mux.Wait() | ||||
| type disconnectMsg struct { | ||||
| 	Reason   uint32 `sshtype:"1"` | ||||
| 	Message  string | ||||
| 	Language string | ||||
| } | ||||
|  | ||||
| func (d *disconnectMsg) Error() string { | ||||
| 	return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message) | ||||
| } | ||||
|  | ||||
| // See RFC 4253, section 7.1. | ||||
| const msgKexInit = 20 | ||||
|  | ||||
| type kexInitMsg struct { | ||||
| 	Cookie                  [16]byte `sshtype:"20"` | ||||
| 	KexAlgos                []string | ||||
| 	ServerHostKeyAlgos      []string | ||||
| 	CiphersClientServer     []string | ||||
| 	CiphersServerClient     []string | ||||
| 	MACsClientServer        []string | ||||
| 	MACsServerClient        []string | ||||
| 	CompressionClientServer []string | ||||
| 	CompressionServerClient []string | ||||
| 	LanguagesClientServer   []string | ||||
| 	LanguagesServerClient   []string | ||||
| 	FirstKexFollows         bool | ||||
| 	Reserved                uint32 | ||||
| } | ||||
|  | ||||
| // See RFC 4253, section 8. | ||||
|  | ||||
| // Diffie-Helman | ||||
| const msgKexDHInit = 30 | ||||
|  | ||||
| type kexDHInitMsg struct { | ||||
| 	X *big.Int `sshtype:"30"` | ||||
| } | ||||
|  | ||||
| const msgKexECDHInit = 30 | ||||
|  | ||||
| type kexECDHInitMsg struct { | ||||
| 	ClientPubKey []byte `sshtype:"30"` | ||||
| } | ||||
|  | ||||
| const msgKexECDHReply = 31 | ||||
|  | ||||
| type kexECDHReplyMsg struct { | ||||
| 	HostKey         []byte `sshtype:"31"` | ||||
| 	EphemeralPubKey []byte | ||||
| 	Signature       []byte | ||||
| } | ||||
|  | ||||
| const msgKexDHReply = 31 | ||||
|  | ||||
| type kexDHReplyMsg struct { | ||||
| 	HostKey   []byte `sshtype:"31"` | ||||
| 	Y         *big.Int | ||||
| 	Signature []byte | ||||
| } | ||||
|  | ||||
| // See RFC 4253, section 10. | ||||
| const msgServiceRequest = 5 | ||||
|  | ||||
| type serviceRequestMsg struct { | ||||
| 	Service string `sshtype:"5"` | ||||
| } | ||||
|  | ||||
| // See RFC 4253, section 10. | ||||
| const msgServiceAccept = 6 | ||||
|  | ||||
| type serviceAcceptMsg struct { | ||||
| 	Service string `sshtype:"6"` | ||||
| } | ||||
|  | ||||
| // See RFC 4252, section 5. | ||||
| const msgUserAuthRequest = 50 | ||||
|  | ||||
| type userAuthRequestMsg struct { | ||||
| 	User    string `sshtype:"50"` | ||||
| 	Service string | ||||
| 	Method  string | ||||
| 	Payload []byte `ssh:"rest"` | ||||
| } | ||||
|  | ||||
| // Used for debug printouts of packets. | ||||
| type userAuthSuccessMsg struct { | ||||
| } | ||||
|  | ||||
| // See RFC 4252, section 5.1 | ||||
| const msgUserAuthFailure = 51 | ||||
|  | ||||
| type userAuthFailureMsg struct { | ||||
| 	Methods        []string `sshtype:"51"` | ||||
| 	PartialSuccess bool | ||||
| } | ||||
|  | ||||
| // See RFC 4256, section 3.2 | ||||
| const msgUserAuthInfoRequest = 60 | ||||
| const msgUserAuthInfoResponse = 61 | ||||
|  | ||||
| type userAuthInfoRequestMsg struct { | ||||
| 	User               string `sshtype:"60"` | ||||
| 	Instruction        string | ||||
| 	DeprecatedLanguage string | ||||
| 	NumPrompts         uint32 | ||||
| 	Prompts            []byte `ssh:"rest"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.1. | ||||
| const msgChannelOpen = 90 | ||||
|  | ||||
| type channelOpenMsg struct { | ||||
| 	ChanType         string `sshtype:"90"` | ||||
| 	PeersId          uint32 | ||||
| 	PeersWindow      uint32 | ||||
| 	MaxPacketSize    uint32 | ||||
| 	TypeSpecificData []byte `ssh:"rest"` | ||||
| } | ||||
|  | ||||
| const msgChannelExtendedData = 95 | ||||
| const msgChannelData = 94 | ||||
|  | ||||
| // Used for debug print outs of packets. | ||||
| type channelDataMsg struct { | ||||
| 	PeersId uint32 `sshtype:"94"` | ||||
| 	Length  uint32 | ||||
| 	Rest    []byte `ssh:"rest"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.1. | ||||
| const msgChannelOpenConfirm = 91 | ||||
|  | ||||
| type channelOpenConfirmMsg struct { | ||||
| 	PeersId          uint32 `sshtype:"91"` | ||||
| 	MyId             uint32 | ||||
| 	MyWindow         uint32 | ||||
| 	MaxPacketSize    uint32 | ||||
| 	TypeSpecificData []byte `ssh:"rest"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.1. | ||||
| const msgChannelOpenFailure = 92 | ||||
|  | ||||
| type channelOpenFailureMsg struct { | ||||
| 	PeersId  uint32 `sshtype:"92"` | ||||
| 	Reason   RejectionReason | ||||
| 	Message  string | ||||
| 	Language string | ||||
| } | ||||
|  | ||||
| const msgChannelRequest = 98 | ||||
|  | ||||
| type channelRequestMsg struct { | ||||
| 	PeersId             uint32 `sshtype:"98"` | ||||
| 	Request             string | ||||
| 	WantReply           bool | ||||
| 	RequestSpecificData []byte `ssh:"rest"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.4. | ||||
| const msgChannelSuccess = 99 | ||||
|  | ||||
| type channelRequestSuccessMsg struct { | ||||
| 	PeersId uint32 `sshtype:"99"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.4. | ||||
| const msgChannelFailure = 100 | ||||
|  | ||||
| type channelRequestFailureMsg struct { | ||||
| 	PeersId uint32 `sshtype:"100"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.3 | ||||
| const msgChannelClose = 97 | ||||
|  | ||||
| type channelCloseMsg struct { | ||||
| 	PeersId uint32 `sshtype:"97"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.3 | ||||
| const msgChannelEOF = 96 | ||||
|  | ||||
| type channelEOFMsg struct { | ||||
| 	PeersId uint32 `sshtype:"96"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 4 | ||||
| const msgGlobalRequest = 80 | ||||
|  | ||||
| type globalRequestMsg struct { | ||||
| 	Type      string `sshtype:"80"` | ||||
| 	WantReply bool | ||||
| 	Data      []byte `ssh:"rest"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 4 | ||||
| const msgRequestSuccess = 81 | ||||
|  | ||||
| type globalRequestSuccessMsg struct { | ||||
| 	Data []byte `ssh:"rest" sshtype:"81"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 4 | ||||
| const msgRequestFailure = 82 | ||||
|  | ||||
| type globalRequestFailureMsg struct { | ||||
| 	Data []byte `ssh:"rest" sshtype:"82"` | ||||
| } | ||||
|  | ||||
| // See RFC 4254, section 5.2 | ||||
| const msgChannelWindowAdjust = 93 | ||||
|  | ||||
| type windowAdjustMsg struct { | ||||
| 	PeersId         uint32 `sshtype:"93"` | ||||
| 	AdditionalBytes uint32 | ||||
| } | ||||
|  | ||||
| // See RFC 4252, section 7 | ||||
| const msgUserAuthPubKeyOk = 60 | ||||
|  | ||||
| type userAuthPubKeyOkMsg struct { | ||||
| 	Algo   string `sshtype:"60"` | ||||
| 	PubKey []byte | ||||
| } | ||||
|  | ||||
| // typeTags returns the possible type bytes for the given reflect.Type, which | ||||
| // should be a struct. The possible values are separated by a '|' character. | ||||
| func typeTags(structType reflect.Type) (tags []byte) { | ||||
| 	tagStr := structType.Field(0).Tag.Get("sshtype") | ||||
|  | ||||
| 	for _, tag := range strings.Split(tagStr, "|") { | ||||
| 		i, err := strconv.Atoi(tag) | ||||
| 		if err == nil { | ||||
| 			tags = append(tags, byte(i)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return tags | ||||
| } | ||||
|  | ||||
| func fieldError(t reflect.Type, field int, problem string) error { | ||||
| 	if problem != "" { | ||||
| 		problem = ": " + problem | ||||
| 	} | ||||
| 	return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem) | ||||
| } | ||||
|  | ||||
| var errShortRead = errors.New("ssh: short read") | ||||
|  | ||||
| // Unmarshal parses data in SSH wire format into a structure. The out | ||||
| // argument should be a pointer to struct. If the first member of the | ||||
| // struct has the "sshtype" tag set to a '|'-separated set of numbers | ||||
| // in decimal, the packet must start with one of those numbers. In | ||||
| // case of error, Unmarshal returns a ParseError or | ||||
| // UnexpectedMessageError. | ||||
| func Unmarshal(data []byte, out interface{}) error { | ||||
| 	v := reflect.ValueOf(out).Elem() | ||||
| 	structType := v.Type() | ||||
| 	expectedTypes := typeTags(structType) | ||||
|  | ||||
| 	var expectedType byte | ||||
| 	if len(expectedTypes) > 0 { | ||||
| 		expectedType = expectedTypes[0] | ||||
| 	} | ||||
|  | ||||
| 	if len(data) == 0 { | ||||
| 		return parseError(expectedType) | ||||
| 	} | ||||
|  | ||||
| 	if len(expectedTypes) > 0 { | ||||
| 		goodType := false | ||||
| 		for _, e := range expectedTypes { | ||||
| 			if e > 0 && data[0] == e { | ||||
| 				goodType = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		if !goodType { | ||||
| 			return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes) | ||||
| 		} | ||||
| 		data = data[1:] | ||||
| 	} | ||||
|  | ||||
| 	var ok bool | ||||
| 	for i := 0; i < v.NumField(); i++ { | ||||
| 		field := v.Field(i) | ||||
| 		t := field.Type() | ||||
| 		switch t.Kind() { | ||||
| 		case reflect.Bool: | ||||
| 			if len(data) < 1 { | ||||
| 				return errShortRead | ||||
| 			} | ||||
| 			field.SetBool(data[0] != 0) | ||||
| 			data = data[1:] | ||||
| 		case reflect.Array: | ||||
| 			if t.Elem().Kind() != reflect.Uint8 { | ||||
| 				return fieldError(structType, i, "array of unsupported type") | ||||
| 			} | ||||
| 			if len(data) < t.Len() { | ||||
| 				return errShortRead | ||||
| 			} | ||||
| 			for j, n := 0, t.Len(); j < n; j++ { | ||||
| 				field.Index(j).Set(reflect.ValueOf(data[j])) | ||||
| 			} | ||||
| 			data = data[t.Len():] | ||||
| 		case reflect.Uint64: | ||||
| 			var u64 uint64 | ||||
| 			if u64, data, ok = parseUint64(data); !ok { | ||||
| 				return errShortRead | ||||
| 			} | ||||
| 			field.SetUint(u64) | ||||
| 		case reflect.Uint32: | ||||
| 			var u32 uint32 | ||||
| 			if u32, data, ok = parseUint32(data); !ok { | ||||
| 				return errShortRead | ||||
| 			} | ||||
| 			field.SetUint(uint64(u32)) | ||||
| 		case reflect.Uint8: | ||||
| 			if len(data) < 1 { | ||||
| 				return errShortRead | ||||
| 			} | ||||
| 			field.SetUint(uint64(data[0])) | ||||
| 			data = data[1:] | ||||
| 		case reflect.String: | ||||
| 			var s []byte | ||||
| 			if s, data, ok = parseString(data); !ok { | ||||
| 				return fieldError(structType, i, "") | ||||
| 			} | ||||
| 			field.SetString(string(s)) | ||||
| 		case reflect.Slice: | ||||
| 			switch t.Elem().Kind() { | ||||
| 			case reflect.Uint8: | ||||
| 				if structType.Field(i).Tag.Get("ssh") == "rest" { | ||||
| 					field.Set(reflect.ValueOf(data)) | ||||
| 					data = nil | ||||
| 				} else { | ||||
| 					var s []byte | ||||
| 					if s, data, ok = parseString(data); !ok { | ||||
| 						return errShortRead | ||||
| 					} | ||||
| 					field.Set(reflect.ValueOf(s)) | ||||
| 				} | ||||
| 			case reflect.String: | ||||
| 				var nl []string | ||||
| 				if nl, data, ok = parseNameList(data); !ok { | ||||
| 					return errShortRead | ||||
| 				} | ||||
| 				field.Set(reflect.ValueOf(nl)) | ||||
| 			default: | ||||
| 				return fieldError(structType, i, "slice of unsupported type") | ||||
| 			} | ||||
| 		case reflect.Ptr: | ||||
| 			if t == bigIntType { | ||||
| 				var n *big.Int | ||||
| 				if n, data, ok = parseInt(data); !ok { | ||||
| 					return errShortRead | ||||
| 				} | ||||
| 				field.Set(reflect.ValueOf(n)) | ||||
| 			} else { | ||||
| 				return fieldError(structType, i, "pointer to unsupported type") | ||||
| 			} | ||||
| 		default: | ||||
| 			return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(data) != 0 { | ||||
| 		return parseError(expectedType) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Marshal serializes the message in msg to SSH wire format.  The msg | ||||
| // argument should be a struct or pointer to struct. If the first | ||||
| // member has the "sshtype" tag set to a number in decimal, that | ||||
| // number is prepended to the result. If the last of member has the | ||||
| // "ssh" tag set to "rest", its contents are appended to the output. | ||||
| func Marshal(msg interface{}) []byte { | ||||
| 	out := make([]byte, 0, 64) | ||||
| 	return marshalStruct(out, msg) | ||||
| } | ||||
|  | ||||
| func marshalStruct(out []byte, msg interface{}) []byte { | ||||
| 	v := reflect.Indirect(reflect.ValueOf(msg)) | ||||
| 	msgTypes := typeTags(v.Type()) | ||||
| 	if len(msgTypes) > 0 { | ||||
| 		out = append(out, msgTypes[0]) | ||||
| 	} | ||||
|  | ||||
| 	for i, n := 0, v.NumField(); i < n; i++ { | ||||
| 		field := v.Field(i) | ||||
| 		switch t := field.Type(); t.Kind() { | ||||
| 		case reflect.Bool: | ||||
| 			var v uint8 | ||||
| 			if field.Bool() { | ||||
| 				v = 1 | ||||
| 			} | ||||
| 			out = append(out, v) | ||||
| 		case reflect.Array: | ||||
| 			if t.Elem().Kind() != reflect.Uint8 { | ||||
| 				panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface())) | ||||
| 			} | ||||
| 			for j, l := 0, t.Len(); j < l; j++ { | ||||
| 				out = append(out, uint8(field.Index(j).Uint())) | ||||
| 			} | ||||
| 		case reflect.Uint32: | ||||
| 			out = appendU32(out, uint32(field.Uint())) | ||||
| 		case reflect.Uint64: | ||||
| 			out = appendU64(out, uint64(field.Uint())) | ||||
| 		case reflect.Uint8: | ||||
| 			out = append(out, uint8(field.Uint())) | ||||
| 		case reflect.String: | ||||
| 			s := field.String() | ||||
| 			out = appendInt(out, len(s)) | ||||
| 			out = append(out, s...) | ||||
| 		case reflect.Slice: | ||||
| 			switch t.Elem().Kind() { | ||||
| 			case reflect.Uint8: | ||||
| 				if v.Type().Field(i).Tag.Get("ssh") != "rest" { | ||||
| 					out = appendInt(out, field.Len()) | ||||
| 				} | ||||
| 				out = append(out, field.Bytes()...) | ||||
| 			case reflect.String: | ||||
| 				offset := len(out) | ||||
| 				out = appendU32(out, 0) | ||||
| 				if n := field.Len(); n > 0 { | ||||
| 					for j := 0; j < n; j++ { | ||||
| 						f := field.Index(j) | ||||
| 						if j != 0 { | ||||
| 							out = append(out, ',') | ||||
| 						} | ||||
| 						out = append(out, f.String()...) | ||||
| 					} | ||||
| 					// overwrite length value | ||||
| 					binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4)) | ||||
| 				} | ||||
| 			default: | ||||
| 				panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface())) | ||||
| 			} | ||||
| 		case reflect.Ptr: | ||||
| 			if t == bigIntType { | ||||
| 				var n *big.Int | ||||
| 				nValue := reflect.ValueOf(&n) | ||||
| 				nValue.Elem().Set(field) | ||||
| 				needed := intLength(n) | ||||
| 				oldLength := len(out) | ||||
|  | ||||
| 				if cap(out)-len(out) < needed { | ||||
| 					newOut := make([]byte, len(out), 2*(len(out)+needed)) | ||||
| 					copy(newOut, out) | ||||
| 					out = newOut | ||||
| 				} | ||||
| 				out = out[:oldLength+needed] | ||||
| 				marshalInt(out[oldLength:], n) | ||||
| 			} else { | ||||
| 				panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface())) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| var bigOne = big.NewInt(1) | ||||
|  | ||||
| func parseString(in []byte) (out, rest []byte, ok bool) { | ||||
| 	if len(in) < 4 { | ||||
| 		return | ||||
| 	} | ||||
| 	length := binary.BigEndian.Uint32(in) | ||||
| 	in = in[4:] | ||||
| 	if uint32(len(in)) < length { | ||||
| 		return | ||||
| 	} | ||||
| 	out = in[:length] | ||||
| 	rest = in[length:] | ||||
| 	ok = true | ||||
| 	return | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	comma         = []byte{','} | ||||
| 	emptyNameList = []string{} | ||||
| ) | ||||
|  | ||||
| func parseNameList(in []byte) (out []string, rest []byte, ok bool) { | ||||
| 	contents, rest, ok := parseString(in) | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
| 	if len(contents) == 0 { | ||||
| 		out = emptyNameList | ||||
| 		return | ||||
| 	} | ||||
| 	parts := bytes.Split(contents, comma) | ||||
| 	out = make([]string, len(parts)) | ||||
| 	for i, part := range parts { | ||||
| 		out[i] = string(part) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) { | ||||
| 	contents, rest, ok := parseString(in) | ||||
| 	if !ok { | ||||
| 		return | ||||
| 	} | ||||
| 	out = new(big.Int) | ||||
|  | ||||
| 	if len(contents) > 0 && contents[0]&0x80 == 0x80 { | ||||
| 		// This is a negative number | ||||
| 		notBytes := make([]byte, len(contents)) | ||||
| 		for i := range notBytes { | ||||
| 			notBytes[i] = ^contents[i] | ||||
| 		} | ||||
| 		out.SetBytes(notBytes) | ||||
| 		out.Add(out, bigOne) | ||||
| 		out.Neg(out) | ||||
| 	} else { | ||||
| 		// Positive number | ||||
| 		out.SetBytes(contents) | ||||
| 	} | ||||
| 	ok = true | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func parseUint32(in []byte) (uint32, []byte, bool) { | ||||
| 	if len(in) < 4 { | ||||
| 		return 0, nil, false | ||||
| 	} | ||||
| 	return binary.BigEndian.Uint32(in), in[4:], true | ||||
| } | ||||
|  | ||||
| func parseUint64(in []byte) (uint64, []byte, bool) { | ||||
| 	if len(in) < 8 { | ||||
| 		return 0, nil, false | ||||
| 	} | ||||
| 	return binary.BigEndian.Uint64(in), in[8:], true | ||||
| } | ||||
|  | ||||
| func intLength(n *big.Int) int { | ||||
| 	length := 4 /* length bytes */ | ||||
| 	if n.Sign() < 0 { | ||||
| 		nMinus1 := new(big.Int).Neg(n) | ||||
| 		nMinus1.Sub(nMinus1, bigOne) | ||||
| 		bitLen := nMinus1.BitLen() | ||||
| 		if bitLen%8 == 0 { | ||||
| 			// The number will need 0xff padding | ||||
| 			length++ | ||||
| 		} | ||||
| 		length += (bitLen + 7) / 8 | ||||
| 	} else if n.Sign() == 0 { | ||||
| 		// A zero is the zero length string | ||||
| 	} else { | ||||
| 		bitLen := n.BitLen() | ||||
| 		if bitLen%8 == 0 { | ||||
| 			// The number will need 0x00 padding | ||||
| 			length++ | ||||
| 		} | ||||
| 		length += (bitLen + 7) / 8 | ||||
| 	} | ||||
|  | ||||
| 	return length | ||||
| } | ||||
|  | ||||
| func marshalUint32(to []byte, n uint32) []byte { | ||||
| 	binary.BigEndian.PutUint32(to, n) | ||||
| 	return to[4:] | ||||
| } | ||||
|  | ||||
| func marshalUint64(to []byte, n uint64) []byte { | ||||
| 	binary.BigEndian.PutUint64(to, n) | ||||
| 	return to[8:] | ||||
| } | ||||
|  | ||||
| func marshalInt(to []byte, n *big.Int) []byte { | ||||
| 	lengthBytes := to | ||||
| 	to = to[4:] | ||||
| 	length := 0 | ||||
|  | ||||
| 	if n.Sign() < 0 { | ||||
| 		// A negative number has to be converted to two's-complement | ||||
| 		// form. So we'll subtract 1 and invert. If the | ||||
| 		// most-significant-bit isn't set then we'll need to pad the | ||||
| 		// beginning with 0xff in order to keep the number negative. | ||||
| 		nMinus1 := new(big.Int).Neg(n) | ||||
| 		nMinus1.Sub(nMinus1, bigOne) | ||||
| 		bytes := nMinus1.Bytes() | ||||
| 		for i := range bytes { | ||||
| 			bytes[i] ^= 0xff | ||||
| 		} | ||||
| 		if len(bytes) == 0 || bytes[0]&0x80 == 0 { | ||||
| 			to[0] = 0xff | ||||
| 			to = to[1:] | ||||
| 			length++ | ||||
| 		} | ||||
| 		nBytes := copy(to, bytes) | ||||
| 		to = to[nBytes:] | ||||
| 		length += nBytes | ||||
| 	} else if n.Sign() == 0 { | ||||
| 		// A zero is the zero length string | ||||
| 	} else { | ||||
| 		bytes := n.Bytes() | ||||
| 		if len(bytes) > 0 && bytes[0]&0x80 != 0 { | ||||
| 			// We'll have to pad this with a 0x00 in order to | ||||
| 			// stop it looking like a negative number. | ||||
| 			to[0] = 0 | ||||
| 			to = to[1:] | ||||
| 			length++ | ||||
| 		} | ||||
| 		nBytes := copy(to, bytes) | ||||
| 		to = to[nBytes:] | ||||
| 		length += nBytes | ||||
| 	} | ||||
|  | ||||
| 	lengthBytes[0] = byte(length >> 24) | ||||
| 	lengthBytes[1] = byte(length >> 16) | ||||
| 	lengthBytes[2] = byte(length >> 8) | ||||
| 	lengthBytes[3] = byte(length) | ||||
| 	return to | ||||
| } | ||||
|  | ||||
| func writeInt(w io.Writer, n *big.Int) { | ||||
| 	length := intLength(n) | ||||
| 	buf := make([]byte, length) | ||||
| 	marshalInt(buf, n) | ||||
| 	w.Write(buf) | ||||
| } | ||||
|  | ||||
| func writeString(w io.Writer, s []byte) { | ||||
| 	var lengthBytes [4]byte | ||||
| 	lengthBytes[0] = byte(len(s) >> 24) | ||||
| 	lengthBytes[1] = byte(len(s) >> 16) | ||||
| 	lengthBytes[2] = byte(len(s) >> 8) | ||||
| 	lengthBytes[3] = byte(len(s)) | ||||
| 	w.Write(lengthBytes[:]) | ||||
| 	w.Write(s) | ||||
| } | ||||
|  | ||||
| func stringLength(n int) int { | ||||
| 	return 4 + n | ||||
| } | ||||
|  | ||||
| func marshalString(to []byte, s []byte) []byte { | ||||
| 	to[0] = byte(len(s) >> 24) | ||||
| 	to[1] = byte(len(s) >> 16) | ||||
| 	to[2] = byte(len(s) >> 8) | ||||
| 	to[3] = byte(len(s)) | ||||
| 	to = to[4:] | ||||
| 	copy(to, s) | ||||
| 	return to[len(s):] | ||||
| } | ||||
|  | ||||
| var bigIntType = reflect.TypeOf((*big.Int)(nil)) | ||||
|  | ||||
| // Decode a packet into its corresponding message. | ||||
| func decode(packet []byte) (interface{}, error) { | ||||
| 	var msg interface{} | ||||
| 	switch packet[0] { | ||||
| 	case msgDisconnect: | ||||
| 		msg = new(disconnectMsg) | ||||
| 	case msgServiceRequest: | ||||
| 		msg = new(serviceRequestMsg) | ||||
| 	case msgServiceAccept: | ||||
| 		msg = new(serviceAcceptMsg) | ||||
| 	case msgKexInit: | ||||
| 		msg = new(kexInitMsg) | ||||
| 	case msgKexDHInit: | ||||
| 		msg = new(kexDHInitMsg) | ||||
| 	case msgKexDHReply: | ||||
| 		msg = new(kexDHReplyMsg) | ||||
| 	case msgUserAuthRequest: | ||||
| 		msg = new(userAuthRequestMsg) | ||||
| 	case msgUserAuthSuccess: | ||||
| 		return new(userAuthSuccessMsg), nil | ||||
| 	case msgUserAuthFailure: | ||||
| 		msg = new(userAuthFailureMsg) | ||||
| 	case msgUserAuthPubKeyOk: | ||||
| 		msg = new(userAuthPubKeyOkMsg) | ||||
| 	case msgGlobalRequest: | ||||
| 		msg = new(globalRequestMsg) | ||||
| 	case msgRequestSuccess: | ||||
| 		msg = new(globalRequestSuccessMsg) | ||||
| 	case msgRequestFailure: | ||||
| 		msg = new(globalRequestFailureMsg) | ||||
| 	case msgChannelOpen: | ||||
| 		msg = new(channelOpenMsg) | ||||
| 	case msgChannelData: | ||||
| 		msg = new(channelDataMsg) | ||||
| 	case msgChannelOpenConfirm: | ||||
| 		msg = new(channelOpenConfirmMsg) | ||||
| 	case msgChannelOpenFailure: | ||||
| 		msg = new(channelOpenFailureMsg) | ||||
| 	case msgChannelWindowAdjust: | ||||
| 		msg = new(windowAdjustMsg) | ||||
| 	case msgChannelEOF: | ||||
| 		msg = new(channelEOFMsg) | ||||
| 	case msgChannelClose: | ||||
| 		msg = new(channelCloseMsg) | ||||
| 	case msgChannelRequest: | ||||
| 		msg = new(channelRequestMsg) | ||||
| 	case msgChannelSuccess: | ||||
| 		msg = new(channelRequestSuccessMsg) | ||||
| 	case msgChannelFailure: | ||||
| 		msg = new(channelRequestFailureMsg) | ||||
| 	default: | ||||
| 		return nil, unexpectedMessageError(0, packet[0]) | ||||
| 	} | ||||
| 	if err := Unmarshal(packet, msg); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return msg, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user