~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/golang.org/x/crypto/ssh/messages.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
        "math/big"
14
14
        "reflect"
15
15
        "strconv"
 
16
        "strings"
16
17
)
17
18
 
18
19
// These are SSH message type numbers. They are scattered around several
47
48
}
48
49
 
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)
51
52
}
52
53
 
53
54
// See RFC 4253, section 7.1.
124
125
        Payload []byte `ssh:"rest"`
125
126
}
126
127
 
 
128
// Used for debug printouts of packets.
 
129
type userAuthSuccessMsg struct {
 
130
}
 
131
 
127
132
// See RFC 4252, section 5.1
128
133
const msgUserAuthFailure = 51
129
134
 
158
163
const msgChannelExtendedData = 95
159
164
const msgChannelData = 94
160
165
 
 
166
// Used for debug print outs of packets.
 
167
type channelDataMsg struct {
 
168
        PeersId uint32 `sshtype:"94"`
 
169
        Length  uint32
 
170
        Rest    []byte `ssh:"rest"`
 
171
}
 
172
 
161
173
// See RFC 4254, section 5.1.
162
174
const msgChannelOpenConfirm = 91
163
175
 
255
267
        PubKey []byte
256
268
}
257
269
 
258
 
// typeTag returns the type byte for the given type. The type should
259
 
// be struct.
260
 
func typeTag(structType reflect.Type) byte {
261
 
        var tag byte
262
 
        var tagStr string
263
 
        tagStr = structType.Field(0).Tag.Get("sshtype")
264
 
        i, err := strconv.Atoi(tagStr)
265
 
        if err == nil {
266
 
                tag = byte(i)
 
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")
 
274
 
 
275
        for _, tag := range strings.Split(tagStr, "|") {
 
276
                i, err := strconv.Atoi(tag)
 
277
                if err == nil {
 
278
                        tags = append(tags, byte(i))
 
279
                }
267
280
        }
268
 
        return tag
 
281
 
 
282
        return tags
269
283
}
270
284
 
271
285
func fieldError(t reflect.Type, field int, problem string) error {
279
293
 
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)
 
304
 
 
305
        var expectedType byte
 
306
        if len(expectedTypes) > 0 {
 
307
                expectedType = expectedTypes[0]
 
308
        }
 
309
 
289
310
        if len(data) == 0 {
290
311
                return parseError(expectedType)
291
312
        }
292
 
        if expectedType > 0 {
293
 
                if data[0] != expectedType {
294
 
                        return unexpectedMessageError(expectedType, data[0])
 
313
 
 
314
        if len(expectedTypes) > 0 {
 
315
                goodType := false
 
316
                for _, e := range expectedTypes {
 
317
                        if e > 0 && data[0] == e {
 
318
                                goodType = true
 
319
                                break
 
320
                        }
 
321
                }
 
322
                if !goodType {
 
323
                        return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
295
324
                }
296
325
                data = data[1:]
297
326
        }
375
404
                                return fieldError(structType, i, "pointer to unsupported type")
376
405
                        }
377
406
                default:
378
 
                        return fieldError(structType, i, "unsupported type")
 
407
                        return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
379
408
                }
380
409
        }
381
410
 
398
427
 
399
428
func marshalStruct(out []byte, msg interface{}) []byte {
400
429
        v := reflect.Indirect(reflect.ValueOf(msg))
401
 
        msgType := typeTag(v.Type())
402
 
        if msgType > 0 {
403
 
                out = append(out, msgType)
 
430
        msgTypes := typeTags(v.Type())
 
431
        if len(msgTypes) > 0 {
 
432
                out = append(out, msgTypes[0])
404
433
        }
405
434
 
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)
 
733
        case msgChannelData:
 
734
                msg = new(channelDataMsg)
702
735
        case msgChannelOpenConfirm:
703
736
                msg = new(channelOpenConfirmMsg)
704
737
        case msgChannelOpenFailure: