~ubuntu-branches/ubuntu/saucy/juju-core/saucy-proposed

« back to all changes in this revision

Viewing changes to src/code.google.com/p/go.crypto/ssh/server.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-07-11 17:18:27 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130711171827-vjqkg40r0dlf7ys2
Tags: 1.11.2-0ubuntu1
* New upstream release.
* Make juju-core the default juju (LP: #1190634):
  - d/control: Add virtual package juju -> juju-core.
  - d/juju-core.postinst.in: Bump priority of alternatives over that of
    python juju packages.
* Enable for all architectures (LP: #1172505):
  - d/control: Version BD on golang-go to >= 2:1.1.1 to ensure CGO
    support for non-x86 archs, make juju-core Arch: any.
  - d/README.source: Dropped - no longer required.
* d/watch: Updated for new upstream tarball naming.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
5
package ssh
 
6
 
 
7
import (
 
8
        "bytes"
 
9
        "crypto"
 
10
        "crypto/rand"
 
11
        "crypto/rsa"
 
12
        "crypto/x509"
 
13
        "encoding/binary"
 
14
        "encoding/pem"
 
15
        "errors"
 
16
        "io"
 
17
        "math/big"
 
18
        "net"
 
19
        "sync"
 
20
)
 
21
 
 
22
type ServerConfig struct {
 
23
        rsa           *rsa.PrivateKey
 
24
        rsaSerialized []byte
 
25
 
 
26
        // Rand provides the source of entropy for key exchange. If Rand is
 
27
        // nil, the cryptographic random reader in package crypto/rand will
 
28
        // be used.
 
29
        Rand io.Reader
 
30
 
 
31
        // NoClientAuth is true if clients are allowed to connect without
 
32
        // authenticating.
 
33
        NoClientAuth bool
 
34
 
 
35
        // PasswordCallback, if non-nil, is called when a user attempts to
 
36
        // authenticate using a password. It may be called concurrently from
 
37
        // several goroutines.
 
38
        PasswordCallback func(conn *ServerConn, user, password string) bool
 
39
 
 
40
        // PublicKeyCallback, if non-nil, is called when a client attempts public
 
41
        // key authentication. It must return true iff the given public key is
 
42
        // valid for the given user.
 
43
        PublicKeyCallback func(conn *ServerConn, user, algo string, pubkey []byte) bool
 
44
 
 
45
        // KeyboardInteractiveCallback, if non-nil, is called when
 
46
        // keyboard-interactive authentication is selected (RFC
 
47
        // 4256). The client object's Challenge function should be
 
48
        // used to query the user. The callback may offer multiple
 
49
        // Challenge rounds. To avoid information leaks, the client
 
50
        // should be presented a challenge even if the user is
 
51
        // unknown.
 
52
        KeyboardInteractiveCallback func(conn *ServerConn, user string, client ClientKeyboardInteractive) bool
 
53
 
 
54
        // Cryptographic-related configuration.
 
55
        Crypto CryptoConfig
 
56
}
 
57
 
 
58
func (c *ServerConfig) rand() io.Reader {
 
59
        if c.Rand == nil {
 
60
                return rand.Reader
 
61
        }
 
62
        return c.Rand
 
63
}
 
64
 
 
65
// SetRSAPrivateKey sets the private key for a Server. A Server must have a
 
66
// private key configured in order to accept connections. The private key must
 
67
// be in the form of a PEM encoded, PKCS#1, RSA private key. The file "id_rsa"
 
68
// typically contains such a key.
 
69
func (s *ServerConfig) SetRSAPrivateKey(pemBytes []byte) error {
 
70
        block, _ := pem.Decode(pemBytes)
 
71
        if block == nil {
 
72
                return errors.New("ssh: no key found")
 
73
        }
 
74
        var err error
 
75
        s.rsa, err = x509.ParsePKCS1PrivateKey(block.Bytes)
 
76
        if err != nil {
 
77
                return err
 
78
        }
 
79
 
 
80
        s.rsaSerialized = marshalPrivRSA(s.rsa)
 
81
        return nil
 
82
}
 
83
 
 
84
func parseRSASig(in []byte) (sig []byte, ok bool) {
 
85
        algo, in, ok := parseString(in)
 
86
        if !ok || string(algo) != hostAlgoRSA {
 
87
                return nil, false
 
88
        }
 
89
        sig, in, ok = parseString(in)
 
90
        if len(in) > 0 {
 
91
                ok = false
 
92
        }
 
93
        return
 
94
}
 
95
 
 
96
// cachedPubKey contains the results of querying whether a public key is
 
97
// acceptable for a user. The cache only applies to a single ServerConn.
 
98
type cachedPubKey struct {
 
99
        user, algo string
 
100
        pubKey     []byte
 
101
        result     bool
 
102
}
 
103
 
 
104
const maxCachedPubKeys = 16
 
105
 
 
106
// A ServerConn represents an incoming connection.
 
107
type ServerConn struct {
 
108
        *transport
 
109
        config *ServerConfig
 
110
 
 
111
        channels   map[uint32]*serverChan
 
112
        nextChanId uint32
 
113
 
 
114
        // lock protects err and channels.
 
115
        lock sync.Mutex
 
116
        err  error
 
117
 
 
118
        // cachedPubKeys contains the cache results of tests for public keys.
 
119
        // Since SSH clients will query whether a public key is acceptable
 
120
        // before attempting to authenticate with it, we end up with duplicate
 
121
        // queries for public key validity.
 
122
        cachedPubKeys []cachedPubKey
 
123
 
 
124
        // User holds the successfully authenticated user name.
 
125
        // It is empty if no authentication is used.  It is populated before
 
126
        // any authentication callback is called and not assigned to after that.
 
127
        User string
 
128
 
 
129
        // ClientVersion is the client's version, populated after
 
130
        // Handshake is called. It should not be modified.
 
131
        ClientVersion []byte
 
132
 
 
133
        // Initial H used for the session ID. Once assigned this must not change
 
134
        // even during subsequent key exchanges.
 
135
        sessionId []byte
 
136
}
 
137
 
 
138
// Server returns a new SSH server connection
 
139
// using c as the underlying transport.
 
140
func Server(c net.Conn, config *ServerConfig) *ServerConn {
 
141
        return &ServerConn{
 
142
                transport: newTransport(c, config.rand()),
 
143
                channels:  make(map[uint32]*serverChan),
 
144
                config:    config,
 
145
        }
 
146
}
 
147
 
 
148
// kexDH performs Diffie-Hellman key agreement on a ServerConnection. The
 
149
// returned values are given the same names as in RFC 4253, section 8.
 
150
func (s *ServerConn) kexDH(group *dhGroup, hashFunc crypto.Hash, magics *handshakeMagics, hostKeyAlgo string) (H, K []byte, err error) {
 
151
        packet, err := s.readPacket()
 
152
        if err != nil {
 
153
                return
 
154
        }
 
155
        var kexDHInit kexDHInitMsg
 
156
        if err = unmarshal(&kexDHInit, packet, msgKexDHInit); err != nil {
 
157
                return
 
158
        }
 
159
 
 
160
        y, err := rand.Int(s.config.rand(), group.p)
 
161
        if err != nil {
 
162
                return
 
163
        }
 
164
 
 
165
        Y := new(big.Int).Exp(group.g, y, group.p)
 
166
        kInt, err := group.diffieHellman(kexDHInit.X, y)
 
167
        if err != nil {
 
168
                return nil, nil, err
 
169
        }
 
170
 
 
171
        var serializedHostKey []byte
 
172
        switch hostKeyAlgo {
 
173
        case hostAlgoRSA:
 
174
                serializedHostKey = s.config.rsaSerialized
 
175
        default:
 
176
                return nil, nil, errors.New("ssh: internal error")
 
177
        }
 
178
 
 
179
        h := hashFunc.New()
 
180
        writeString(h, magics.clientVersion)
 
181
        writeString(h, magics.serverVersion)
 
182
        writeString(h, magics.clientKexInit)
 
183
        writeString(h, magics.serverKexInit)
 
184
        writeString(h, serializedHostKey)
 
185
        writeInt(h, kexDHInit.X)
 
186
        writeInt(h, Y)
 
187
        K = make([]byte, intLength(kInt))
 
188
        marshalInt(K, kInt)
 
189
        h.Write(K)
 
190
 
 
191
        H = h.Sum(nil)
 
192
 
 
193
        h.Reset()
 
194
        h.Write(H)
 
195
        hh := h.Sum(nil)
 
196
 
 
197
        var sig []byte
 
198
        switch hostKeyAlgo {
 
199
        case hostAlgoRSA:
 
200
                sig, err = rsa.SignPKCS1v15(s.config.rand(), s.config.rsa, hashFunc, hh)
 
201
                if err != nil {
 
202
                        return
 
203
                }
 
204
        default:
 
205
                return nil, nil, errors.New("ssh: internal error")
 
206
        }
 
207
 
 
208
        serializedSig := serializeSignature(hostKeyAlgo, sig)
 
209
 
 
210
        kexDHReply := kexDHReplyMsg{
 
211
                HostKey:   serializedHostKey,
 
212
                Y:         Y,
 
213
                Signature: serializedSig,
 
214
        }
 
215
        packet = marshal(msgKexDHReply, kexDHReply)
 
216
 
 
217
        err = s.writePacket(packet)
 
218
        return
 
219
}
 
220
 
 
221
// serverVersion is the fixed identification string that Server will use.
 
222
var serverVersion = []byte("SSH-2.0-Go\r\n")
 
223
 
 
224
// Handshake performs an SSH transport and client authentication on the given ServerConn.
 
225
func (s *ServerConn) Handshake() (err error) {
 
226
        if _, err = s.Write(serverVersion); err != nil {
 
227
                return
 
228
        }
 
229
        if err = s.Flush(); err != nil {
 
230
                return
 
231
        }
 
232
 
 
233
        s.ClientVersion, err = readVersion(s)
 
234
        if err != nil {
 
235
                return
 
236
        }
 
237
        if err = s.clientInitHandshake(nil, nil); err != nil {
 
238
                return
 
239
        }
 
240
 
 
241
        var packet []byte
 
242
        if packet, err = s.readPacket(); err != nil {
 
243
                return
 
244
        }
 
245
        var serviceRequest serviceRequestMsg
 
246
        if err = unmarshal(&serviceRequest, packet, msgServiceRequest); err != nil {
 
247
                return
 
248
        }
 
249
        if serviceRequest.Service != serviceUserAuth {
 
250
                return errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating")
 
251
        }
 
252
        serviceAccept := serviceAcceptMsg{
 
253
                Service: serviceUserAuth,
 
254
        }
 
255
        if err = s.writePacket(marshal(msgServiceAccept, serviceAccept)); err != nil {
 
256
                return
 
257
        }
 
258
 
 
259
        if err = s.authenticate(s.sessionId); err != nil {
 
260
                return
 
261
        }
 
262
        return
 
263
}
 
264
 
 
265
func (s *ServerConn) clientInitHandshake(clientKexInit *kexInitMsg, clientKexInitPacket []byte) (err error) {
 
266
        serverKexInit := kexInitMsg{
 
267
                KexAlgos:                supportedKexAlgos,
 
268
                ServerHostKeyAlgos:      supportedHostKeyAlgos,
 
269
                CiphersClientServer:     s.config.Crypto.ciphers(),
 
270
                CiphersServerClient:     s.config.Crypto.ciphers(),
 
271
                MACsClientServer:        s.config.Crypto.macs(),
 
272
                MACsServerClient:        s.config.Crypto.macs(),
 
273
                CompressionClientServer: supportedCompressions,
 
274
                CompressionServerClient: supportedCompressions,
 
275
        }
 
276
        serverKexInitPacket := marshal(msgKexInit, serverKexInit)
 
277
 
 
278
        if err = s.writePacket(serverKexInitPacket); err != nil {
 
279
                return
 
280
        }
 
281
 
 
282
        if clientKexInitPacket == nil {
 
283
                clientKexInit = new(kexInitMsg)
 
284
                if clientKexInitPacket, err = s.readPacket(); err != nil {
 
285
                        return
 
286
                }
 
287
                if err = unmarshal(clientKexInit, clientKexInitPacket, msgKexInit); err != nil {
 
288
                        return
 
289
                }
 
290
        }
 
291
 
 
292
        kexAlgo, hostKeyAlgo, ok := findAgreedAlgorithms(s.transport, clientKexInit, &serverKexInit)
 
293
        if !ok {
 
294
                return errors.New("ssh: no common algorithms")
 
295
        }
 
296
 
 
297
        if clientKexInit.FirstKexFollows && kexAlgo != clientKexInit.KexAlgos[0] {
 
298
                // The client sent a Kex message for the wrong algorithm,
 
299
                // which we have to ignore.
 
300
                if _, err = s.readPacket(); err != nil {
 
301
                        return
 
302
                }
 
303
        }
 
304
 
 
305
        var magics handshakeMagics
 
306
        magics.serverVersion = serverVersion[:len(serverVersion)-2]
 
307
        magics.clientVersion = s.ClientVersion
 
308
        magics.serverKexInit = marshal(msgKexInit, serverKexInit)
 
309
        magics.clientKexInit = clientKexInitPacket
 
310
 
 
311
        var H, K []byte
 
312
        var hashFunc crypto.Hash
 
313
        switch kexAlgo {
 
314
        case kexAlgoDH14SHA1:
 
315
                hashFunc = crypto.SHA1
 
316
                dhGroup14Once.Do(initDHGroup14)
 
317
                H, K, err = s.kexDH(dhGroup14, hashFunc, &magics, hostKeyAlgo)
 
318
        case keyAlgoDH1SHA1:
 
319
                hashFunc = crypto.SHA1
 
320
                dhGroup1Once.Do(initDHGroup1)
 
321
                H, K, err = s.kexDH(dhGroup1, hashFunc, &magics, hostKeyAlgo)
 
322
        default:
 
323
                err = errors.New("ssh: unexpected key exchange algorithm " + kexAlgo)
 
324
        }
 
325
        if err != nil {
 
326
                return
 
327
        }
 
328
        // sessionId must only be assigned during initial handshake.
 
329
        if s.sessionId == nil {
 
330
                s.sessionId = H
 
331
        }
 
332
 
 
333
        var packet []byte
 
334
 
 
335
        if err = s.writePacket([]byte{msgNewKeys}); err != nil {
 
336
                return
 
337
        }
 
338
        if err = s.transport.writer.setupKeys(serverKeys, K, H, s.sessionId, hashFunc); err != nil {
 
339
                return
 
340
        }
 
341
 
 
342
        if packet, err = s.readPacket(); err != nil {
 
343
                return
 
344
        }
 
345
        if packet[0] != msgNewKeys {
 
346
                return UnexpectedMessageError{msgNewKeys, packet[0]}
 
347
        }
 
348
        if err = s.transport.reader.setupKeys(clientKeys, K, H, s.sessionId, hashFunc); err != nil {
 
349
                return
 
350
        }
 
351
 
 
352
        return
 
353
}
 
354
 
 
355
func isAcceptableAlgo(algo string) bool {
 
356
        return algo == hostAlgoRSA
 
357
}
 
358
 
 
359
// testPubKey returns true if the given public key is acceptable for the user.
 
360
func (s *ServerConn) testPubKey(user, algo string, pubKey []byte) bool {
 
361
        if s.config.PublicKeyCallback == nil || !isAcceptableAlgo(algo) {
 
362
                return false
 
363
        }
 
364
 
 
365
        for _, c := range s.cachedPubKeys {
 
366
                if c.user == user && c.algo == algo && bytes.Equal(c.pubKey, pubKey) {
 
367
                        return c.result
 
368
                }
 
369
        }
 
370
 
 
371
        result := s.config.PublicKeyCallback(s, user, algo, pubKey)
 
372
        if len(s.cachedPubKeys) < maxCachedPubKeys {
 
373
                c := cachedPubKey{
 
374
                        user:   user,
 
375
                        algo:   algo,
 
376
                        pubKey: make([]byte, len(pubKey)),
 
377
                        result: result,
 
378
                }
 
379
                copy(c.pubKey, pubKey)
 
380
                s.cachedPubKeys = append(s.cachedPubKeys, c)
 
381
        }
 
382
 
 
383
        return result
 
384
}
 
385
 
 
386
func (s *ServerConn) authenticate(H []byte) error {
 
387
        var userAuthReq userAuthRequestMsg
 
388
        var err error
 
389
        var packet []byte
 
390
 
 
391
userAuthLoop:
 
392
        for {
 
393
                if packet, err = s.readPacket(); err != nil {
 
394
                        return err
 
395
                }
 
396
                if err = unmarshal(&userAuthReq, packet, msgUserAuthRequest); err != nil {
 
397
                        return err
 
398
                }
 
399
 
 
400
                if userAuthReq.Service != serviceSSH {
 
401
                        return errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service)
 
402
                }
 
403
 
 
404
                switch userAuthReq.Method {
 
405
                case "none":
 
406
                        if s.config.NoClientAuth {
 
407
                                break userAuthLoop
 
408
                        }
 
409
                case "password":
 
410
                        if s.config.PasswordCallback == nil {
 
411
                                break
 
412
                        }
 
413
                        payload := userAuthReq.Payload
 
414
                        if len(payload) < 1 || payload[0] != 0 {
 
415
                                return ParseError{msgUserAuthRequest}
 
416
                        }
 
417
                        payload = payload[1:]
 
418
                        password, payload, ok := parseString(payload)
 
419
                        if !ok || len(payload) > 0 {
 
420
                                return ParseError{msgUserAuthRequest}
 
421
                        }
 
422
 
 
423
                        s.User = userAuthReq.User
 
424
                        if s.config.PasswordCallback(s, userAuthReq.User, string(password)) {
 
425
                                break userAuthLoop
 
426
                        }
 
427
                case "keyboard-interactive":
 
428
                        if s.config.KeyboardInteractiveCallback == nil {
 
429
                                break
 
430
                        }
 
431
 
 
432
                        s.User = userAuthReq.User
 
433
                        if s.config.KeyboardInteractiveCallback(s, s.User, &sshClientKeyboardInteractive{s}) {
 
434
                                break userAuthLoop
 
435
                        }
 
436
                case "publickey":
 
437
                        if s.config.PublicKeyCallback == nil {
 
438
                                break
 
439
                        }
 
440
                        payload := userAuthReq.Payload
 
441
                        if len(payload) < 1 {
 
442
                                return ParseError{msgUserAuthRequest}
 
443
                        }
 
444
                        isQuery := payload[0] == 0
 
445
                        payload = payload[1:]
 
446
                        algoBytes, payload, ok := parseString(payload)
 
447
                        if !ok {
 
448
                                return ParseError{msgUserAuthRequest}
 
449
                        }
 
450
                        algo := string(algoBytes)
 
451
 
 
452
                        pubKey, payload, ok := parseString(payload)
 
453
                        if !ok {
 
454
                                return ParseError{msgUserAuthRequest}
 
455
                        }
 
456
                        if isQuery {
 
457
                                // The client can query if the given public key
 
458
                                // would be ok.
 
459
                                if len(payload) > 0 {
 
460
                                        return ParseError{msgUserAuthRequest}
 
461
                                }
 
462
                                if s.testPubKey(userAuthReq.User, algo, pubKey) {
 
463
                                        okMsg := userAuthPubKeyOkMsg{
 
464
                                                Algo:   algo,
 
465
                                                PubKey: string(pubKey),
 
466
                                        }
 
467
                                        if err = s.writePacket(marshal(msgUserAuthPubKeyOk, okMsg)); err != nil {
 
468
                                                return err
 
469
                                        }
 
470
                                        continue userAuthLoop
 
471
                                }
 
472
                        } else {
 
473
                                sig, payload, ok := parseString(payload)
 
474
                                if !ok || len(payload) > 0 {
 
475
                                        return ParseError{msgUserAuthRequest}
 
476
                                }
 
477
                                if !isAcceptableAlgo(algo) {
 
478
                                        break
 
479
                                }
 
480
                                rsaSig, ok := parseRSASig(sig)
 
481
                                if !ok {
 
482
                                        return ParseError{msgUserAuthRequest}
 
483
                                }
 
484
                                signedData := buildDataSignedForAuth(H, userAuthReq, algoBytes, pubKey)
 
485
                                switch algo {
 
486
                                case hostAlgoRSA:
 
487
                                        hashFunc := crypto.SHA1
 
488
                                        h := hashFunc.New()
 
489
                                        h.Write(signedData)
 
490
                                        digest := h.Sum(nil)
 
491
                                        key, _, ok := parsePubKey(pubKey)
 
492
                                        if !ok {
 
493
                                                return ParseError{msgUserAuthRequest}
 
494
                                        }
 
495
                                        rsaKey, ok := key.(*rsa.PublicKey)
 
496
                                        if !ok {
 
497
                                                return ParseError{msgUserAuthRequest}
 
498
                                        }
 
499
                                        if rsa.VerifyPKCS1v15(rsaKey, hashFunc, digest, rsaSig) != nil {
 
500
                                                return ParseError{msgUserAuthRequest}
 
501
                                        }
 
502
                                default:
 
503
                                        return errors.New("ssh: isAcceptableAlgo incorrect")
 
504
                                }
 
505
                                s.User = userAuthReq.User
 
506
                                if s.testPubKey(userAuthReq.User, algo, pubKey) {
 
507
                                        break userAuthLoop
 
508
                                }
 
509
                        }
 
510
                }
 
511
 
 
512
                var failureMsg userAuthFailureMsg
 
513
                if s.config.PasswordCallback != nil {
 
514
                        failureMsg.Methods = append(failureMsg.Methods, "password")
 
515
                }
 
516
                if s.config.PublicKeyCallback != nil {
 
517
                        failureMsg.Methods = append(failureMsg.Methods, "publickey")
 
518
                }
 
519
                if s.config.KeyboardInteractiveCallback != nil {
 
520
                        failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive")
 
521
                }
 
522
 
 
523
                if len(failureMsg.Methods) == 0 {
 
524
                        return errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
 
525
                }
 
526
 
 
527
                if err = s.writePacket(marshal(msgUserAuthFailure, failureMsg)); err != nil {
 
528
                        return err
 
529
                }
 
530
        }
 
531
 
 
532
        packet = []byte{msgUserAuthSuccess}
 
533
        if err = s.writePacket(packet); err != nil {
 
534
                return err
 
535
        }
 
536
 
 
537
        return nil
 
538
}
 
539
 
 
540
// sshClientKeyboardInteractive implements a ClientKeyboardInteractive by
 
541
// asking the client on the other side of a ServerConn.
 
542
type sshClientKeyboardInteractive struct {
 
543
        *ServerConn
 
544
}
 
545
 
 
546
func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
 
547
        if len(questions) != len(echos) {
 
548
                return nil, errors.New("ssh: echos and questions must have equal length")
 
549
        }
 
550
 
 
551
        var prompts []byte
 
552
        for i := range questions {
 
553
                prompts = appendString(prompts, questions[i])
 
554
                prompts = appendBool(prompts, echos[i])
 
555
        }
 
556
 
 
557
        if err := c.writePacket(marshal(msgUserAuthInfoRequest, userAuthInfoRequestMsg{
 
558
                Instruction: instruction,
 
559
                NumPrompts:  uint32(len(questions)),
 
560
                Prompts:     prompts,
 
561
        })); err != nil {
 
562
                return nil, err
 
563
        }
 
564
 
 
565
        packet, err := c.readPacket()
 
566
        if err != nil {
 
567
                return nil, err
 
568
        }
 
569
        if packet[0] != msgUserAuthInfoResponse {
 
570
                return nil, UnexpectedMessageError{msgUserAuthInfoResponse, packet[0]}
 
571
        }
 
572
        packet = packet[1:]
 
573
 
 
574
        n, packet, ok := parseUint32(packet)
 
575
        if !ok || int(n) != len(questions) {
 
576
                return nil, &ParseError{msgUserAuthInfoResponse}
 
577
        }
 
578
 
 
579
        for i := uint32(0); i < n; i++ {
 
580
                ans, rest, ok := parseString(packet)
 
581
                if !ok {
 
582
                        return nil, &ParseError{msgUserAuthInfoResponse}
 
583
                }
 
584
 
 
585
                answers = append(answers, string(ans))
 
586
                packet = rest
 
587
        }
 
588
        if len(packet) != 0 {
 
589
                return nil, errors.New("ssh: junk at end of message")
 
590
        }
 
591
 
 
592
        return answers, nil
 
593
}
 
594
 
 
595
const defaultWindowSize = 32768
 
596
 
 
597
// Accept reads and processes messages on a ServerConn. It must be called
 
598
// in order to demultiplex messages to any resulting Channels.
 
599
func (s *ServerConn) Accept() (Channel, error) {
 
600
        // TODO(dfc) s.lock is not held here so visibility of s.err is not guaranteed.
 
601
        if s.err != nil {
 
602
                return nil, s.err
 
603
        }
 
604
 
 
605
        for {
 
606
                packet, err := s.readPacket()
 
607
                if err != nil {
 
608
 
 
609
                        s.lock.Lock()
 
610
                        s.err = err
 
611
                        s.lock.Unlock()
 
612
 
 
613
                        // TODO(dfc) s.lock protects s.channels but isn't being held here.
 
614
                        for _, c := range s.channels {
 
615
                                c.setDead()
 
616
                                c.handleData(nil)
 
617
                        }
 
618
 
 
619
                        return nil, err
 
620
                }
 
621
 
 
622
                switch packet[0] {
 
623
                case msgChannelData:
 
624
                        if len(packet) < 9 {
 
625
                                // malformed data packet
 
626
                                return nil, ParseError{msgChannelData}
 
627
                        }
 
628
                        remoteId := binary.BigEndian.Uint32(packet[1:5])
 
629
                        s.lock.Lock()
 
630
                        c, ok := s.channels[remoteId]
 
631
                        if !ok {
 
632
                                s.lock.Unlock()
 
633
                                continue
 
634
                        }
 
635
                        if length := binary.BigEndian.Uint32(packet[5:9]); length > 0 {
 
636
                                packet = packet[9:]
 
637
                                c.handleData(packet[:length])
 
638
                        }
 
639
                        s.lock.Unlock()
 
640
                default:
 
641
                        decoded, err := decode(packet)
 
642
                        if err != nil {
 
643
                                return nil, err
 
644
                        }
 
645
                        switch msg := decoded.(type) {
 
646
                        case *channelOpenMsg:
 
647
                                if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
 
648
                                        return nil, errors.New("ssh: invalid MaxPacketSize from peer")
 
649
                                }
 
650
                                c := &serverChan{
 
651
                                        channel: channel{
 
652
                                                conn:      s,
 
653
                                                remoteId:  msg.PeersId,
 
654
                                                remoteWin: window{Cond: newCond()},
 
655
                                                maxPacket: msg.MaxPacketSize,
 
656
                                        },
 
657
                                        chanType:    msg.ChanType,
 
658
                                        extraData:   msg.TypeSpecificData,
 
659
                                        myWindow:    defaultWindowSize,
 
660
                                        serverConn:  s,
 
661
                                        cond:        newCond(),
 
662
                                        pendingData: make([]byte, defaultWindowSize),
 
663
                                }
 
664
                                c.remoteWin.add(msg.PeersWindow)
 
665
                                s.lock.Lock()
 
666
                                c.localId = s.nextChanId
 
667
                                s.nextChanId++
 
668
                                s.channels[c.localId] = c
 
669
                                s.lock.Unlock()
 
670
                                return c, nil
 
671
 
 
672
                        case *channelRequestMsg:
 
673
                                s.lock.Lock()
 
674
                                c, ok := s.channels[msg.PeersId]
 
675
                                if !ok {
 
676
                                        s.lock.Unlock()
 
677
                                        continue
 
678
                                }
 
679
                                c.handlePacket(msg)
 
680
                                s.lock.Unlock()
 
681
 
 
682
                        case *windowAdjustMsg:
 
683
                                s.lock.Lock()
 
684
                                c, ok := s.channels[msg.PeersId]
 
685
                                if !ok {
 
686
                                        s.lock.Unlock()
 
687
                                        continue
 
688
                                }
 
689
                                c.handlePacket(msg)
 
690
                                s.lock.Unlock()
 
691
 
 
692
                        case *channelEOFMsg:
 
693
                                s.lock.Lock()
 
694
                                c, ok := s.channels[msg.PeersId]
 
695
                                if !ok {
 
696
                                        s.lock.Unlock()
 
697
                                        continue
 
698
                                }
 
699
                                c.handlePacket(msg)
 
700
                                s.lock.Unlock()
 
701
 
 
702
                        case *channelCloseMsg:
 
703
                                s.lock.Lock()
 
704
                                c, ok := s.channels[msg.PeersId]
 
705
                                if !ok {
 
706
                                        s.lock.Unlock()
 
707
                                        continue
 
708
                                }
 
709
                                c.handlePacket(msg)
 
710
                                s.lock.Unlock()
 
711
 
 
712
                        case *globalRequestMsg:
 
713
                                if msg.WantReply {
 
714
                                        if err := s.writePacket([]byte{msgRequestFailure}); err != nil {
 
715
                                                return nil, err
 
716
                                        }
 
717
                                }
 
718
 
 
719
                        case *kexInitMsg:
 
720
                                s.lock.Lock()
 
721
                                if err := s.clientInitHandshake(msg, packet); err != nil {
 
722
                                        s.lock.Unlock()
 
723
                                        return nil, err
 
724
                                }
 
725
                                s.lock.Unlock()
 
726
                        case *disconnectMsg:
 
727
                                return nil, io.EOF
 
728
                        default:
 
729
                                // Unknown message. Ignore.
 
730
                        }
 
731
                }
 
732
        }
 
733
 
 
734
        panic("unreachable")
 
735
}
 
736
 
 
737
// A Listener implements a network listener (net.Listener) for SSH connections.
 
738
type Listener struct {
 
739
        listener net.Listener
 
740
        config   *ServerConfig
 
741
}
 
742
 
 
743
// Addr returns the listener's network address.
 
744
func (l *Listener) Addr() net.Addr {
 
745
        return l.listener.Addr()
 
746
}
 
747
 
 
748
// Close closes the listener.
 
749
func (l *Listener) Close() error {
 
750
        return l.listener.Close()
 
751
}
 
752
 
 
753
// Accept waits for and returns the next incoming SSH connection.
 
754
// The receiver should call Handshake() in another goroutine
 
755
// to avoid blocking the accepter.
 
756
func (l *Listener) Accept() (*ServerConn, error) {
 
757
        c, err := l.listener.Accept()
 
758
        if err != nil {
 
759
                return nil, err
 
760
        }
 
761
        return Server(c, l.config), nil
 
762
}
 
763
 
 
764
// Listen creates an SSH listener accepting connections on
 
765
// the given network address using net.Listen.
 
766
func Listen(network, addr string, config *ServerConfig) (*Listener, error) {
 
767
        l, err := net.Listen(network, addr)
 
768
        if err != nil {
 
769
                return nil, err
 
770
        }
 
771
        return &Listener{
 
772
                l,
 
773
                config,
 
774
        }, nil
 
775
}