| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725 | // 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 sshimport (	"bytes"	"encoding/binary"	"errors"	"fmt"	"io"	"math/big"	"reflect"	"strconv")// 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 = 20type 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-Helmanconst msgKexDHInit = 30type kexDHInitMsg struct {	X *big.Int `sshtype:"30"`}const msgKexECDHInit = 30type kexECDHInitMsg struct {	ClientPubKey []byte `sshtype:"30"`}const msgKexECDHReply = 31type kexECDHReplyMsg struct {	HostKey         []byte `sshtype:"31"`	EphemeralPubKey []byte	Signature       []byte}const msgKexDHReply = 31type kexDHReplyMsg struct {	HostKey   []byte `sshtype:"31"`	Y         *big.Int	Signature []byte}// See RFC 4253, section 10.const msgServiceRequest = 5type serviceRequestMsg struct {	Service string `sshtype:"5"`}// See RFC 4253, section 10.const msgServiceAccept = 6type serviceAcceptMsg struct {	Service string `sshtype:"6"`}// See RFC 4252, section 5.const msgUserAuthRequest = 50type userAuthRequestMsg struct {	User    string `sshtype:"50"`	Service string	Method  string	Payload []byte `ssh:"rest"`}// See RFC 4252, section 5.1const msgUserAuthFailure = 51type userAuthFailureMsg struct {	Methods        []string `sshtype:"51"`	PartialSuccess bool}// See RFC 4256, section 3.2const msgUserAuthInfoRequest = 60const msgUserAuthInfoResponse = 61type userAuthInfoRequestMsg struct {	User               string `sshtype:"60"`	Instruction        string	DeprecatedLanguage string	NumPrompts         uint32	Prompts            []byte `ssh:"rest"`}// See RFC 4254, section 5.1.const msgChannelOpen = 90type channelOpenMsg struct {	ChanType         string `sshtype:"90"`	PeersId          uint32	PeersWindow      uint32	MaxPacketSize    uint32	TypeSpecificData []byte `ssh:"rest"`}const msgChannelExtendedData = 95const msgChannelData = 94// See RFC 4254, section 5.1.const msgChannelOpenConfirm = 91type channelOpenConfirmMsg struct {	PeersId          uint32 `sshtype:"91"`	MyId             uint32	MyWindow         uint32	MaxPacketSize    uint32	TypeSpecificData []byte `ssh:"rest"`}// See RFC 4254, section 5.1.const msgChannelOpenFailure = 92type channelOpenFailureMsg struct {	PeersId  uint32 `sshtype:"92"`	Reason   RejectionReason	Message  string	Language string}const msgChannelRequest = 98type channelRequestMsg struct {	PeersId             uint32 `sshtype:"98"`	Request             string	WantReply           bool	RequestSpecificData []byte `ssh:"rest"`}// See RFC 4254, section 5.4.const msgChannelSuccess = 99type channelRequestSuccessMsg struct {	PeersId uint32 `sshtype:"99"`}// See RFC 4254, section 5.4.const msgChannelFailure = 100type channelRequestFailureMsg struct {	PeersId uint32 `sshtype:"100"`}// See RFC 4254, section 5.3const msgChannelClose = 97type channelCloseMsg struct {	PeersId uint32 `sshtype:"97"`}// See RFC 4254, section 5.3const msgChannelEOF = 96type channelEOFMsg struct {	PeersId uint32 `sshtype:"96"`}// See RFC 4254, section 4const msgGlobalRequest = 80type globalRequestMsg struct {	Type      string `sshtype:"80"`	WantReply bool	Data      []byte `ssh:"rest"`}// See RFC 4254, section 4const msgRequestSuccess = 81type globalRequestSuccessMsg struct {	Data []byte `ssh:"rest" sshtype:"81"`}// See RFC 4254, section 4const msgRequestFailure = 82type globalRequestFailureMsg struct {	Data []byte `ssh:"rest" sshtype:"82"`}// See RFC 4254, section 5.2const msgChannelWindowAdjust = 93type windowAdjustMsg struct {	PeersId         uint32 `sshtype:"93"`	AdditionalBytes uint32}// See RFC 4252, section 7const msgUserAuthPubKeyOk = 60type userAuthPubKeyOkMsg struct {	Algo   string `sshtype:"60"`	PubKey []byte}// typeTag returns the type byte for the given type. The type should// be struct.func typeTag(structType reflect.Type) byte {	var tag byte	var tagStr string	tagStr = structType.Field(0).Tag.Get("sshtype")	i, err := strconv.Atoi(tagStr)	if err == nil {		tag = byte(i)	}	return tag}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 number in decimal, the packet// must start that number.  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()	expectedType := typeTag(structType)	if len(data) == 0 {		return parseError(expectedType)	}	if expectedType > 0 {		if data[0] != expectedType {			return unexpectedMessageError(expectedType, data[0])		}		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, "unsupported type")		}	}	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))	msgType := typeTag(v.Type())	if msgType > 0 {		out = append(out, msgType)	}	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 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 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}
 |