49
50
func (d *disconnectMsg) Error() string {
50
return fmt.Sprintf("ssh: disconnect reason %d: %s", d.Reason, d.Message)
51
return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
53
54
// See RFC 4253, section 7.1.
124
125
Payload []byte `ssh:"rest"`
128
// Used for debug printouts of packets.
129
type userAuthSuccessMsg struct {
127
132
// See RFC 4252, section 5.1
128
133
const msgUserAuthFailure = 51
158
163
const msgChannelExtendedData = 95
159
164
const msgChannelData = 94
166
// Used for debug print outs of packets.
167
type channelDataMsg struct {
168
PeersId uint32 `sshtype:"94"`
170
Rest []byte `ssh:"rest"`
161
173
// See RFC 4254, section 5.1.
162
174
const msgChannelOpenConfirm = 91
258
// typeTag returns the type byte for the given type. The type should
260
func typeTag(structType reflect.Type) byte {
263
tagStr = structType.Field(0).Tag.Get("sshtype")
264
i, err := strconv.Atoi(tagStr)
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")
275
for _, tag := range strings.Split(tagStr, "|") {
276
i, err := strconv.Atoi(tag)
278
tags = append(tags, byte(i))
271
285
func fieldError(t reflect.Type, field int, problem string) error {
280
294
// Unmarshal parses data in SSH wire format into a structure. The out
281
295
// argument should be a pointer to struct. If the first member of the
282
// struct has the "sshtype" tag set to a number in decimal, the packet
283
// must start that number. In case of error, Unmarshal returns a
284
// ParseError or UnexpectedMessageError.
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.
285
300
func Unmarshal(data []byte, out interface{}) error {
286
301
v := reflect.ValueOf(out).Elem()
287
302
structType := v.Type()
288
expectedType := typeTag(structType)
303
expectedTypes := typeTags(structType)
305
var expectedType byte
306
if len(expectedTypes) > 0 {
307
expectedType = expectedTypes[0]
289
310
if len(data) == 0 {
290
311
return parseError(expectedType)
292
if expectedType > 0 {
293
if data[0] != expectedType {
294
return unexpectedMessageError(expectedType, data[0])
314
if len(expectedTypes) > 0 {
316
for _, e := range expectedTypes {
317
if e > 0 && data[0] == e {
323
return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
375
404
return fieldError(structType, i, "pointer to unsupported type")
378
return fieldError(structType, i, "unsupported type")
407
return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
399
428
func marshalStruct(out []byte, msg interface{}) []byte {
400
429
v := reflect.Indirect(reflect.ValueOf(msg))
401
msgType := typeTag(v.Type())
403
out = append(out, msgType)
430
msgTypes := typeTags(v.Type())
431
if len(msgTypes) > 0 {
432
out = append(out, msgTypes[0])
406
435
for i, n := 0, v.NumField(); i < n; i++ {
687
716
msg = new(kexDHReplyMsg)
688
717
case msgUserAuthRequest:
689
718
msg = new(userAuthRequestMsg)
719
case msgUserAuthSuccess:
720
return new(userAuthSuccessMsg), nil
690
721
case msgUserAuthFailure:
691
722
msg = new(userAuthFailureMsg)
692
723
case msgUserAuthPubKeyOk:
699
730
msg = new(globalRequestFailureMsg)
700
731
case msgChannelOpen:
701
732
msg = new(channelOpenMsg)
734
msg = new(channelDataMsg)
702
735
case msgChannelOpenConfirm:
703
736
msg = new(channelOpenConfirmMsg)
704
737
case msgChannelOpenFailure: