aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/crypto/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/crypto/ssh')
-rw-r--r--vendor/golang.org/x/crypto/ssh/buffer.go98
-rw-r--r--vendor/golang.org/x/crypto/ssh/certs.go503
-rw-r--r--vendor/golang.org/x/crypto/ssh/channel.go633
-rw-r--r--vendor/golang.org/x/crypto/ssh/cipher.go627
-rw-r--r--vendor/golang.org/x/crypto/ssh/client.go211
-rw-r--r--vendor/golang.org/x/crypto/ssh/client_auth.go475
-rw-r--r--vendor/golang.org/x/crypto/ssh/common.go371
-rw-r--r--vendor/golang.org/x/crypto/ssh/connection.go143
-rw-r--r--vendor/golang.org/x/crypto/ssh/doc.go18
-rw-r--r--vendor/golang.org/x/crypto/ssh/handshake.go625
-rw-r--r--vendor/golang.org/x/crypto/ssh/kex.go540
-rw-r--r--vendor/golang.org/x/crypto/ssh/keys.go905
-rw-r--r--vendor/golang.org/x/crypto/ssh/mac.go61
-rw-r--r--vendor/golang.org/x/crypto/ssh/messages.go758
-rw-r--r--vendor/golang.org/x/crypto/ssh/mux.go330
-rw-r--r--vendor/golang.org/x/crypto/ssh/server.go491
-rw-r--r--vendor/golang.org/x/crypto/ssh/session.go627
-rw-r--r--vendor/golang.org/x/crypto/ssh/tcpip.go407
-rw-r--r--vendor/golang.org/x/crypto/ssh/transport.go375
19 files changed, 0 insertions, 8198 deletions
diff --git a/vendor/golang.org/x/crypto/ssh/buffer.go b/vendor/golang.org/x/crypto/ssh/buffer.go
deleted file mode 100644
index 6931b51..0000000
--- a/vendor/golang.org/x/crypto/ssh/buffer.go
+++ /dev/null
@@ -1,98 +0,0 @@
1// Copyright 2012 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
5package ssh
6
7import (
8 "io"
9 "sync"
10)
11
12// buffer provides a linked list buffer for data exchange
13// between producer and consumer. Theoretically the buffer is
14// of unlimited capacity as it does no allocation of its own.
15type buffer struct {
16 // protects concurrent access to head, tail and closed
17 *sync.Cond
18
19 head *element // the buffer that will be read first
20 tail *element // the buffer that will be read last
21
22 closed bool
23}
24
25// An element represents a single link in a linked list.
26type element struct {
27 buf []byte
28 next *element
29}
30
31// newBuffer returns an empty buffer that is not closed.
32func newBuffer() *buffer {
33 e := new(element)
34 b := &buffer{
35 Cond: newCond(),
36 head: e,
37 tail: e,
38 }
39 return b
40}
41
42// write makes buf available for Read to receive.
43// buf must not be modified after the call to write.
44func (b *buffer) write(buf []byte) {
45 b.Cond.L.Lock()
46 e := &element{buf: buf}
47 b.tail.next = e
48 b.tail = e
49 b.Cond.Signal()
50 b.Cond.L.Unlock()
51}
52
53// eof closes the buffer. Reads from the buffer once all
54// the data has been consumed will receive os.EOF.
55func (b *buffer) eof() error {
56 b.Cond.L.Lock()
57 b.closed = true
58 b.Cond.Signal()
59 b.Cond.L.Unlock()
60 return nil
61}
62
63// Read reads data from the internal buffer in buf. Reads will block
64// if no data is available, or until the buffer is closed.
65func (b *buffer) Read(buf []byte) (n int, err error) {
66 b.Cond.L.Lock()
67 defer b.Cond.L.Unlock()
68
69 for len(buf) > 0 {
70 // if there is data in b.head, copy it
71 if len(b.head.buf) > 0 {
72 r := copy(buf, b.head.buf)
73 buf, b.head.buf = buf[r:], b.head.buf[r:]
74 n += r
75 continue
76 }
77 // if there is a next buffer, make it the head
78 if len(b.head.buf) == 0 && b.head != b.tail {
79 b.head = b.head.next
80 continue
81 }
82
83 // if at least one byte has been copied, return
84 if n > 0 {
85 break
86 }
87
88 // if nothing was read, and there is nothing outstanding
89 // check to see if the buffer is closed.
90 if b.closed {
91 err = io.EOF
92 break
93 }
94 // out of buffers, wait for producer
95 b.Cond.Wait()
96 }
97 return
98}
diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go
deleted file mode 100644
index 6331c94..0000000
--- a/vendor/golang.org/x/crypto/ssh/certs.go
+++ /dev/null
@@ -1,503 +0,0 @@
1// Copyright 2012 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
5package ssh
6
7import (
8 "bytes"
9 "errors"
10 "fmt"
11 "io"
12 "net"
13 "sort"
14 "time"
15)
16
17// These constants from [PROTOCOL.certkeys] represent the algorithm names
18// for certificate types supported by this package.
19const (
20 CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
21 CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
22 CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
23 CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
24 CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
25 CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
26)
27
28// Certificate types distinguish between host and user
29// certificates. The values can be set in the CertType field of
30// Certificate.
31const (
32 UserCert = 1
33 HostCert = 2
34)
35
36// Signature represents a cryptographic signature.
37type Signature struct {
38 Format string
39 Blob []byte
40}
41
42// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
43// a certificate does not expire.
44const CertTimeInfinity = 1<<64 - 1
45
46// An Certificate represents an OpenSSH certificate as defined in
47// [PROTOCOL.certkeys]?rev=1.8.
48type Certificate struct {
49 Nonce []byte
50 Key PublicKey
51 Serial uint64
52 CertType uint32
53 KeyId string
54 ValidPrincipals []string
55 ValidAfter uint64
56 ValidBefore uint64
57 Permissions
58 Reserved []byte
59 SignatureKey PublicKey
60 Signature *Signature
61}
62
63// genericCertData holds the key-independent part of the certificate data.
64// Overall, certificates contain an nonce, public key fields and
65// key-independent fields.
66type genericCertData struct {
67 Serial uint64
68 CertType uint32
69 KeyId string
70 ValidPrincipals []byte
71 ValidAfter uint64
72 ValidBefore uint64
73 CriticalOptions []byte
74 Extensions []byte
75 Reserved []byte
76 SignatureKey []byte
77 Signature []byte
78}
79
80func marshalStringList(namelist []string) []byte {
81 var to []byte
82 for _, name := range namelist {
83 s := struct{ N string }{name}
84 to = append(to, Marshal(&s)...)
85 }
86 return to
87}
88
89type optionsTuple struct {
90 Key string
91 Value []byte
92}
93
94type optionsTupleValue struct {
95 Value string
96}
97
98// serialize a map of critical options or extensions
99// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
100// we need two length prefixes for a non-empty string value
101func marshalTuples(tups map[string]string) []byte {
102 keys := make([]string, 0, len(tups))
103 for key := range tups {
104 keys = append(keys, key)
105 }
106 sort.Strings(keys)
107
108 var ret []byte
109 for _, key := range keys {
110 s := optionsTuple{Key: key}
111 if value := tups[key]; len(value) > 0 {
112 s.Value = Marshal(&optionsTupleValue{value})
113 }
114 ret = append(ret, Marshal(&s)...)
115 }
116 return ret
117}
118
119// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
120// we need two length prefixes for a non-empty option value
121func parseTuples(in []byte) (map[string]string, error) {
122 tups := map[string]string{}
123 var lastKey string
124 var haveLastKey bool
125
126 for len(in) > 0 {
127 var key, val, extra []byte
128 var ok bool
129
130 if key, in, ok = parseString(in); !ok {
131 return nil, errShortRead
132 }
133 keyStr := string(key)
134 // according to [PROTOCOL.certkeys], the names must be in
135 // lexical order.
136 if haveLastKey && keyStr <= lastKey {
137 return nil, fmt.Errorf("ssh: certificate options are not in lexical order")
138 }
139 lastKey, haveLastKey = keyStr, true
140 // the next field is a data field, which if non-empty has a string embedded
141 if val, in, ok = parseString(in); !ok {
142 return nil, errShortRead
143 }
144 if len(val) > 0 {
145 val, extra, ok = parseString(val)
146 if !ok {
147 return nil, errShortRead
148 }
149 if len(extra) > 0 {
150 return nil, fmt.Errorf("ssh: unexpected trailing data after certificate option value")
151 }
152 tups[keyStr] = string(val)
153 } else {
154 tups[keyStr] = ""
155 }
156 }
157 return tups, nil
158}
159
160func parseCert(in []byte, privAlgo string) (*Certificate, error) {
161 nonce, rest, ok := parseString(in)
162 if !ok {
163 return nil, errShortRead
164 }
165
166 key, rest, err := parsePubKey(rest, privAlgo)
167 if err != nil {
168 return nil, err
169 }
170
171 var g genericCertData
172 if err := Unmarshal(rest, &g); err != nil {
173 return nil, err
174 }
175
176 c := &Certificate{
177 Nonce: nonce,
178 Key: key,
179 Serial: g.Serial,
180 CertType: g.CertType,
181 KeyId: g.KeyId,
182 ValidAfter: g.ValidAfter,
183 ValidBefore: g.ValidBefore,
184 }
185
186 for principals := g.ValidPrincipals; len(principals) > 0; {
187 principal, rest, ok := parseString(principals)
188 if !ok {
189 return nil, errShortRead
190 }
191 c.ValidPrincipals = append(c.ValidPrincipals, string(principal))
192 principals = rest
193 }
194
195 c.CriticalOptions, err = parseTuples(g.CriticalOptions)
196 if err != nil {
197 return nil, err
198 }
199 c.Extensions, err = parseTuples(g.Extensions)
200 if err != nil {
201 return nil, err
202 }
203 c.Reserved = g.Reserved
204 k, err := ParsePublicKey(g.SignatureKey)
205 if err != nil {
206 return nil, err
207 }
208
209 c.SignatureKey = k
210 c.Signature, rest, ok = parseSignatureBody(g.Signature)
211 if !ok || len(rest) > 0 {
212 return nil, errors.New("ssh: signature parse error")
213 }
214
215 return c, nil
216}
217
218type openSSHCertSigner struct {
219 pub *Certificate
220 signer Signer
221}
222
223// NewCertSigner returns a Signer that signs with the given Certificate, whose
224// private key is held by signer. It returns an error if the public key in cert
225// doesn't match the key used by signer.
226func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
227 if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
228 return nil, errors.New("ssh: signer and cert have different public key")
229 }
230
231 return &openSSHCertSigner{cert, signer}, nil
232}
233
234func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
235 return s.signer.Sign(rand, data)
236}
237
238func (s *openSSHCertSigner) PublicKey() PublicKey {
239 return s.pub
240}
241
242const sourceAddressCriticalOption = "source-address"
243
244// CertChecker does the work of verifying a certificate. Its methods
245// can be plugged into ClientConfig.HostKeyCallback and
246// ServerConfig.PublicKeyCallback. For the CertChecker to work,
247// minimally, the IsAuthority callback should be set.
248type CertChecker struct {
249 // SupportedCriticalOptions lists the CriticalOptions that the
250 // server application layer understands. These are only used
251 // for user certificates.
252 SupportedCriticalOptions []string
253
254 // IsAuthority should return true if the key is recognized as
255 // an authority. This allows for certificates to be signed by other
256 // certificates.
257 IsAuthority func(auth PublicKey) bool
258
259 // Clock is used for verifying time stamps. If nil, time.Now
260 // is used.
261 Clock func() time.Time
262
263 // UserKeyFallback is called when CertChecker.Authenticate encounters a
264 // public key that is not a certificate. It must implement validation
265 // of user keys or else, if nil, all such keys are rejected.
266 UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
267
268 // HostKeyFallback is called when CertChecker.CheckHostKey encounters a
269 // public key that is not a certificate. It must implement host key
270 // validation or else, if nil, all such keys are rejected.
271 HostKeyFallback func(addr string, remote net.Addr, key PublicKey) error
272
273 // IsRevoked is called for each certificate so that revocation checking
274 // can be implemented. It should return true if the given certificate
275 // is revoked and false otherwise. If nil, no certificates are
276 // considered to have been revoked.
277 IsRevoked func(cert *Certificate) bool
278}
279
280// CheckHostKey checks a host key certificate. This method can be
281// plugged into ClientConfig.HostKeyCallback.
282func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error {
283 cert, ok := key.(*Certificate)
284 if !ok {
285 if c.HostKeyFallback != nil {
286 return c.HostKeyFallback(addr, remote, key)
287 }
288 return errors.New("ssh: non-certificate host key")
289 }
290 if cert.CertType != HostCert {
291 return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType)
292 }
293
294 return c.CheckCert(addr, cert)
295}
296
297// Authenticate checks a user certificate. Authenticate can be used as
298// a value for ServerConfig.PublicKeyCallback.
299func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) {
300 cert, ok := pubKey.(*Certificate)
301 if !ok {
302 if c.UserKeyFallback != nil {
303 return c.UserKeyFallback(conn, pubKey)
304 }
305 return nil, errors.New("ssh: normal key pairs not accepted")
306 }
307
308 if cert.CertType != UserCert {
309 return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType)
310 }
311
312 if err := c.CheckCert(conn.User(), cert); err != nil {
313 return nil, err
314 }
315
316 return &cert.Permissions, nil
317}
318
319// CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and
320// the signature of the certificate.
321func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
322 if c.IsRevoked != nil && c.IsRevoked(cert) {
323 return fmt.Errorf("ssh: certicate serial %d revoked", cert.Serial)
324 }
325
326 for opt, _ := range cert.CriticalOptions {
327 // sourceAddressCriticalOption will be enforced by
328 // serverAuthenticate
329 if opt == sourceAddressCriticalOption {
330 continue
331 }
332
333 found := false
334 for _, supp := range c.SupportedCriticalOptions {
335 if supp == opt {
336 found = true
337 break
338 }
339 }
340 if !found {
341 return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt)
342 }
343 }
344
345 if len(cert.ValidPrincipals) > 0 {
346 // By default, certs are valid for all users/hosts.
347 found := false
348 for _, p := range cert.ValidPrincipals {
349 if p == principal {
350 found = true
351 break
352 }
353 }
354 if !found {
355 return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals)
356 }
357 }
358
359 if !c.IsAuthority(cert.SignatureKey) {
360 return fmt.Errorf("ssh: certificate signed by unrecognized authority")
361 }
362
363 clock := c.Clock
364 if clock == nil {
365 clock = time.Now
366 }
367
368 unixNow := clock().Unix()
369 if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) {
370 return fmt.Errorf("ssh: cert is not yet valid")
371 }
372 if before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) {
373 return fmt.Errorf("ssh: cert has expired")
374 }
375 if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil {
376 return fmt.Errorf("ssh: certificate signature does not verify")
377 }
378
379 return nil
380}
381
382// SignCert sets c.SignatureKey to the authority's public key and stores a
383// Signature, by authority, in the certificate.
384func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
385 c.Nonce = make([]byte, 32)
386 if _, err := io.ReadFull(rand, c.Nonce); err != nil {
387 return err
388 }
389 c.SignatureKey = authority.PublicKey()
390
391 sig, err := authority.Sign(rand, c.bytesForSigning())
392 if err != nil {
393 return err
394 }
395 c.Signature = sig
396 return nil
397}
398
399var certAlgoNames = map[string]string{
400 KeyAlgoRSA: CertAlgoRSAv01,
401 KeyAlgoDSA: CertAlgoDSAv01,
402 KeyAlgoECDSA256: CertAlgoECDSA256v01,
403 KeyAlgoECDSA384: CertAlgoECDSA384v01,
404 KeyAlgoECDSA521: CertAlgoECDSA521v01,
405 KeyAlgoED25519: CertAlgoED25519v01,
406}
407
408// certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
409// Panics if a non-certificate algorithm is passed.
410func certToPrivAlgo(algo string) string {
411 for privAlgo, pubAlgo := range certAlgoNames {
412 if pubAlgo == algo {
413 return privAlgo
414 }
415 }
416 panic("unknown cert algorithm")
417}
418
419func (cert *Certificate) bytesForSigning() []byte {
420 c2 := *cert
421 c2.Signature = nil
422 out := c2.Marshal()
423 // Drop trailing signature length.
424 return out[:len(out)-4]
425}
426
427// Marshal serializes c into OpenSSH's wire format. It is part of the
428// PublicKey interface.
429func (c *Certificate) Marshal() []byte {
430 generic := genericCertData{
431 Serial: c.Serial,
432 CertType: c.CertType,
433 KeyId: c.KeyId,
434 ValidPrincipals: marshalStringList(c.ValidPrincipals),
435 ValidAfter: uint64(c.ValidAfter),
436 ValidBefore: uint64(c.ValidBefore),
437 CriticalOptions: marshalTuples(c.CriticalOptions),
438 Extensions: marshalTuples(c.Extensions),
439 Reserved: c.Reserved,
440 SignatureKey: c.SignatureKey.Marshal(),
441 }
442 if c.Signature != nil {
443 generic.Signature = Marshal(c.Signature)
444 }
445 genericBytes := Marshal(&generic)
446 keyBytes := c.Key.Marshal()
447 _, keyBytes, _ = parseString(keyBytes)
448 prefix := Marshal(&struct {
449 Name string
450 Nonce []byte
451 Key []byte `ssh:"rest"`
452 }{c.Type(), c.Nonce, keyBytes})
453
454 result := make([]byte, 0, len(prefix)+len(genericBytes))
455 result = append(result, prefix...)
456 result = append(result, genericBytes...)
457 return result
458}
459
460// Type returns the key name. It is part of the PublicKey interface.
461func (c *Certificate) Type() string {
462 algo, ok := certAlgoNames[c.Key.Type()]
463 if !ok {
464 panic("unknown cert key type " + c.Key.Type())
465 }
466 return algo
467}
468
469// Verify verifies a signature against the certificate's public
470// key. It is part of the PublicKey interface.
471func (c *Certificate) Verify(data []byte, sig *Signature) error {
472 return c.Key.Verify(data, sig)
473}
474
475func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {
476 format, in, ok := parseString(in)
477 if !ok {
478 return
479 }
480
481 out = &Signature{
482 Format: string(format),
483 }
484
485 if out.Blob, in, ok = parseString(in); !ok {
486 return
487 }
488
489 return out, in, ok
490}
491
492func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) {
493 sigBytes, rest, ok := parseString(in)
494 if !ok {
495 return
496 }
497
498 out, trailing, ok := parseSignatureBody(sigBytes)
499 if !ok || len(trailing) > 0 {
500 return nil, nil, false
501 }
502 return
503}
diff --git a/vendor/golang.org/x/crypto/ssh/channel.go b/vendor/golang.org/x/crypto/ssh/channel.go
deleted file mode 100644
index 195530e..0000000
--- a/vendor/golang.org/x/crypto/ssh/channel.go
+++ /dev/null
@@ -1,633 +0,0 @@
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
5package ssh
6
7import (
8 "encoding/binary"
9 "errors"
10 "fmt"
11 "io"
12 "log"
13 "sync"
14)
15
16const (
17 minPacketLength = 9
18 // channelMaxPacket contains the maximum number of bytes that will be
19 // sent in a single packet. As per RFC 4253, section 6.1, 32k is also
20 // the minimum.
21 channelMaxPacket = 1 << 15
22 // We follow OpenSSH here.
23 channelWindowSize = 64 * channelMaxPacket
24)
25
26// NewChannel represents an incoming request to a channel. It must either be
27// accepted for use by calling Accept, or rejected by calling Reject.
28type NewChannel interface {
29 // Accept accepts the channel creation request. It returns the Channel
30 // and a Go channel containing SSH requests. The Go channel must be
31 // serviced otherwise the Channel will hang.
32 Accept() (Channel, <-chan *Request, error)
33
34 // Reject rejects the channel creation request. After calling
35 // this, no other methods on the Channel may be called.
36 Reject(reason RejectionReason, message string) error
37
38 // ChannelType returns the type of the channel, as supplied by the
39 // client.
40 ChannelType() string
41
42 // ExtraData returns the arbitrary payload for this channel, as supplied
43 // by the client. This data is specific to the channel type.
44 ExtraData() []byte
45}
46
47// A Channel is an ordered, reliable, flow-controlled, duplex stream
48// that is multiplexed over an SSH connection.
49type Channel interface {
50 // Read reads up to len(data) bytes from the channel.
51 Read(data []byte) (int, error)
52
53 // Write writes len(data) bytes to the channel.
54 Write(data []byte) (int, error)
55
56 // Close signals end of channel use. No data may be sent after this
57 // call.
58 Close() error
59
60 // CloseWrite signals the end of sending in-band
61 // data. Requests may still be sent, and the other side may
62 // still send data
63 CloseWrite() error
64
65 // SendRequest sends a channel request. If wantReply is true,
66 // it will wait for a reply and return the result as a
67 // boolean, otherwise the return value will be false. Channel
68 // requests are out-of-band messages so they may be sent even
69 // if the data stream is closed or blocked by flow control.
70 // If the channel is closed before a reply is returned, io.EOF
71 // is returned.
72 SendRequest(name string, wantReply bool, payload []byte) (bool, error)
73
74 // Stderr returns an io.ReadWriter that writes to this channel
75 // with the extended data type set to stderr. Stderr may
76 // safely be read and written from a different goroutine than
77 // Read and Write respectively.
78 Stderr() io.ReadWriter
79}
80
81// Request is a request sent outside of the normal stream of
82// data. Requests can either be specific to an SSH channel, or they
83// can be global.
84type Request struct {
85 Type string
86 WantReply bool
87 Payload []byte
88
89 ch *channel
90 mux *mux
91}
92
93// Reply sends a response to a request. It must be called for all requests
94// where WantReply is true and is a no-op otherwise. The payload argument is
95// ignored for replies to channel-specific requests.
96func (r *Request) Reply(ok bool, payload []byte) error {
97 if !r.WantReply {
98 return nil
99 }
100
101 if r.ch == nil {
102 return r.mux.ackRequest(ok, payload)
103 }
104
105 return r.ch.ackRequest(ok)
106}
107
108// RejectionReason is an enumeration used when rejecting channel creation
109// requests. See RFC 4254, section 5.1.
110type RejectionReason uint32
111
112const (
113 Prohibited RejectionReason = iota + 1
114 ConnectionFailed
115 UnknownChannelType
116 ResourceShortage
117)
118
119// String converts the rejection reason to human readable form.
120func (r RejectionReason) String() string {
121 switch r {
122 case Prohibited:
123 return "administratively prohibited"
124 case ConnectionFailed:
125 return "connect failed"
126 case UnknownChannelType:
127 return "unknown channel type"
128 case ResourceShortage:
129 return "resource shortage"
130 }
131 return fmt.Sprintf("unknown reason %d", int(r))
132}
133
134func min(a uint32, b int) uint32 {
135 if a < uint32(b) {
136 return a
137 }
138 return uint32(b)
139}
140
141type channelDirection uint8
142
143const (
144 channelInbound channelDirection = iota
145 channelOutbound
146)
147
148// channel is an implementation of the Channel interface that works
149// with the mux class.
150type channel struct {
151 // R/O after creation
152 chanType string
153 extraData []byte
154 localId, remoteId uint32
155
156 // maxIncomingPayload and maxRemotePayload are the maximum
157 // payload sizes of normal and extended data packets for
158 // receiving and sending, respectively. The wire packet will
159 // be 9 or 13 bytes larger (excluding encryption overhead).
160 maxIncomingPayload uint32
161 maxRemotePayload uint32
162
163 mux *mux
164
165 // decided is set to true if an accept or reject message has been sent
166 // (for outbound channels) or received (for inbound channels).
167 decided bool
168
169 // direction contains either channelOutbound, for channels created
170 // locally, or channelInbound, for channels created by the peer.
171 direction channelDirection
172
173 // Pending internal channel messages.
174 msg chan interface{}
175
176 // Since requests have no ID, there can be only one request
177 // with WantReply=true outstanding. This lock is held by a
178 // goroutine that has such an outgoing request pending.
179 sentRequestMu sync.Mutex
180
181 incomingRequests chan *Request
182
183 sentEOF bool
184
185 // thread-safe data
186 remoteWin window
187 pending *buffer
188 extPending *buffer
189
190 // windowMu protects myWindow, the flow-control window.
191 windowMu sync.Mutex
192 myWindow uint32
193
194 // writeMu serializes calls to mux.conn.writePacket() and
195 // protects sentClose and packetPool. This mutex must be
196 // different from windowMu, as writePacket can block if there
197 // is a key exchange pending.
198 writeMu sync.Mutex
199 sentClose bool
200
201 // packetPool has a buffer for each extended channel ID to
202 // save allocations during writes.
203 packetPool map[uint32][]byte
204}
205
206// writePacket sends a packet. If the packet is a channel close, it updates
207// sentClose. This method takes the lock c.writeMu.
208func (c *channel) writePacket(packet []byte) error {
209 c.writeMu.Lock()
210 if c.sentClose {
211 c.writeMu.Unlock()
212 return io.EOF
213 }
214 c.sentClose = (packet[0] == msgChannelClose)
215 err := c.mux.conn.writePacket(packet)
216 c.writeMu.Unlock()
217 return err
218}
219
220func (c *channel) sendMessage(msg interface{}) error {
221 if debugMux {
222 log.Printf("send(%d): %#v", c.mux.chanList.offset, msg)
223 }
224
225 p := Marshal(msg)
226 binary.BigEndian.PutUint32(p[1:], c.remoteId)
227 return c.writePacket(p)
228}
229
230// WriteExtended writes data to a specific extended stream. These streams are
231// used, for example, for stderr.
232func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) {
233 if c.sentEOF {
234 return 0, io.EOF
235 }
236 // 1 byte message type, 4 bytes remoteId, 4 bytes data length
237 opCode := byte(msgChannelData)
238 headerLength := uint32(9)
239 if extendedCode > 0 {
240 headerLength += 4
241 opCode = msgChannelExtendedData
242 }
243
244 c.writeMu.Lock()
245 packet := c.packetPool[extendedCode]
246 // We don't remove the buffer from packetPool, so
247 // WriteExtended calls from different goroutines will be
248 // flagged as errors by the race detector.
249 c.writeMu.Unlock()
250
251 for len(data) > 0 {
252 space := min(c.maxRemotePayload, len(data))
253 if space, err = c.remoteWin.reserve(space); err != nil {
254 return n, err
255 }
256 if want := headerLength + space; uint32(cap(packet)) < want {
257 packet = make([]byte, want)
258 } else {
259 packet = packet[:want]
260 }
261
262 todo := data[:space]
263
264 packet[0] = opCode
265 binary.BigEndian.PutUint32(packet[1:], c.remoteId)
266 if extendedCode > 0 {
267 binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode))
268 }
269 binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo)))
270 copy(packet[headerLength:], todo)
271 if err = c.writePacket(packet); err != nil {
272 return n, err
273 }
274
275 n += len(todo)
276 data = data[len(todo):]
277 }
278
279 c.writeMu.Lock()
280 c.packetPool[extendedCode] = packet
281 c.writeMu.Unlock()
282
283 return n, err
284}
285
286func (c *channel) handleData(packet []byte) error {
287 headerLen := 9
288 isExtendedData := packet[0] == msgChannelExtendedData
289 if isExtendedData {
290 headerLen = 13
291 }
292 if len(packet) < headerLen {
293 // malformed data packet
294 return parseError(packet[0])
295 }
296
297 var extended uint32
298 if isExtendedData {
299 extended = binary.BigEndian.Uint32(packet[5:])
300 }
301
302 length := binary.BigEndian.Uint32(packet[headerLen-4 : headerLen])
303 if length == 0 {
304 return nil
305 }
306 if length > c.maxIncomingPayload {
307 // TODO(hanwen): should send Disconnect?
308 return errors.New("ssh: incoming packet exceeds maximum payload size")
309 }
310
311 data := packet[headerLen:]
312 if length != uint32(len(data)) {
313 return errors.New("ssh: wrong packet length")
314 }
315
316 c.windowMu.Lock()
317 if c.myWindow < length {
318 c.windowMu.Unlock()
319 // TODO(hanwen): should send Disconnect with reason?
320 return errors.New("ssh: remote side wrote too much")
321 }
322 c.myWindow -= length
323 c.windowMu.Unlock()
324
325 if extended == 1 {
326 c.extPending.write(data)
327 } else if extended > 0 {
328 // discard other extended data.
329 } else {
330 c.pending.write(data)
331 }
332 return nil
333}
334
335func (c *channel) adjustWindow(n uint32) error {
336 c.windowMu.Lock()
337 // Since myWindow is managed on our side, and can never exceed
338 // the initial window setting, we don't worry about overflow.
339 c.myWindow += uint32(n)
340 c.windowMu.Unlock()
341 return c.sendMessage(windowAdjustMsg{
342 AdditionalBytes: uint32(n),
343 })
344}
345
346func (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) {
347 switch extended {
348 case 1:
349 n, err = c.extPending.Read(data)
350 case 0:
351 n, err = c.pending.Read(data)
352 default:
353 return 0, fmt.Errorf("ssh: extended code %d unimplemented", extended)
354 }
355
356 if n > 0 {
357 err = c.adjustWindow(uint32(n))
358 // sendWindowAdjust can return io.EOF if the remote
359 // peer has closed the connection, however we want to
360 // defer forwarding io.EOF to the caller of Read until
361 // the buffer has been drained.
362 if n > 0 && err == io.EOF {
363 err = nil
364 }
365 }
366
367 return n, err
368}
369
370func (c *channel) close() {
371 c.pending.eof()
372 c.extPending.eof()
373 close(c.msg)
374 close(c.incomingRequests)
375 c.writeMu.Lock()
376 // This is not necessary for a normal channel teardown, but if
377 // there was another error, it is.
378 c.sentClose = true
379 c.writeMu.Unlock()
380 // Unblock writers.
381 c.remoteWin.close()
382}
383
384// responseMessageReceived is called when a success or failure message is
385// received on a channel to check that such a message is reasonable for the
386// given channel.
387func (c *channel) responseMessageReceived() error {
388 if c.direction == channelInbound {
389 return errors.New("ssh: channel response message received on inbound channel")
390 }
391 if c.decided {
392 return errors.New("ssh: duplicate response received for channel")
393 }
394 c.decided = true
395 return nil
396}
397
398func (c *channel) handlePacket(packet []byte) error {
399 switch packet[0] {
400 case msgChannelData, msgChannelExtendedData:
401 return c.handleData(packet)
402 case msgChannelClose:
403 c.sendMessage(channelCloseMsg{PeersId: c.remoteId})
404 c.mux.chanList.remove(c.localId)
405 c.close()
406 return nil
407 case msgChannelEOF:
408 // RFC 4254 is mute on how EOF affects dataExt messages but
409 // it is logical to signal EOF at the same time.
410 c.extPending.eof()
411 c.pending.eof()
412 return nil
413 }
414
415 decoded, err := decode(packet)
416 if err != nil {
417 return err
418 }
419
420 switch msg := decoded.(type) {
421 case *channelOpenFailureMsg:
422 if err := c.responseMessageReceived(); err != nil {
423 return err
424 }
425 c.mux.chanList.remove(msg.PeersId)
426 c.msg <- msg
427 case *channelOpenConfirmMsg:
428 if err := c.responseMessageReceived(); err != nil {
429 return err
430 }
431 if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
432 return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize)
433 }
434 c.remoteId = msg.MyId
435 c.maxRemotePayload = msg.MaxPacketSize
436 c.remoteWin.add(msg.MyWindow)
437 c.msg <- msg
438 case *windowAdjustMsg:
439 if !c.remoteWin.add(msg.AdditionalBytes) {
440 return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes)
441 }
442 case *channelRequestMsg:
443 req := Request{
444 Type: msg.Request,
445 WantReply: msg.WantReply,
446 Payload: msg.RequestSpecificData,
447 ch: c,
448 }
449
450 c.incomingRequests <- &req
451 default:
452 c.msg <- msg
453 }
454 return nil
455}
456
457func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel {
458 ch := &channel{
459 remoteWin: window{Cond: newCond()},
460 myWindow: channelWindowSize,
461 pending: newBuffer(),
462 extPending: newBuffer(),
463 direction: direction,
464 incomingRequests: make(chan *Request, chanSize),
465 msg: make(chan interface{}, chanSize),
466 chanType: chanType,
467 extraData: extraData,
468 mux: m,
469 packetPool: make(map[uint32][]byte),
470 }
471 ch.localId = m.chanList.add(ch)
472 return ch
473}
474
475var errUndecided = errors.New("ssh: must Accept or Reject channel")
476var errDecidedAlready = errors.New("ssh: can call Accept or Reject only once")
477
478type extChannel struct {
479 code uint32
480 ch *channel
481}
482
483func (e *extChannel) Write(data []byte) (n int, err error) {
484 return e.ch.WriteExtended(data, e.code)
485}
486
487func (e *extChannel) Read(data []byte) (n int, err error) {
488 return e.ch.ReadExtended(data, e.code)
489}
490
491func (c *channel) Accept() (Channel, <-chan *Request, error) {
492 if c.decided {
493 return nil, nil, errDecidedAlready
494 }
495 c.maxIncomingPayload = channelMaxPacket
496 confirm := channelOpenConfirmMsg{
497 PeersId: c.remoteId,
498 MyId: c.localId,
499 MyWindow: c.myWindow,
500 MaxPacketSize: c.maxIncomingPayload,
501 }
502 c.decided = true
503 if err := c.sendMessage(confirm); err != nil {
504 return nil, nil, err
505 }
506
507 return c, c.incomingRequests, nil
508}
509
510func (ch *channel) Reject(reason RejectionReason, message string) error {
511 if ch.decided {
512 return errDecidedAlready
513 }
514 reject := channelOpenFailureMsg{
515 PeersId: ch.remoteId,
516 Reason: reason,
517 Message: message,
518 Language: "en",
519 }
520 ch.decided = true
521 return ch.sendMessage(reject)
522}
523
524func (ch *channel) Read(data []byte) (int, error) {
525 if !ch.decided {
526 return 0, errUndecided
527 }
528 return ch.ReadExtended(data, 0)
529}
530
531func (ch *channel) Write(data []byte) (int, error) {
532 if !ch.decided {
533 return 0, errUndecided
534 }
535 return ch.WriteExtended(data, 0)
536}
537
538func (ch *channel) CloseWrite() error {
539 if !ch.decided {
540 return errUndecided
541 }
542 ch.sentEOF = true
543 return ch.sendMessage(channelEOFMsg{
544 PeersId: ch.remoteId})
545}
546
547func (ch *channel) Close() error {
548 if !ch.decided {
549 return errUndecided
550 }
551
552 return ch.sendMessage(channelCloseMsg{
553 PeersId: ch.remoteId})
554}
555
556// Extended returns an io.ReadWriter that sends and receives data on the given,
557// SSH extended stream. Such streams are used, for example, for stderr.
558func (ch *channel) Extended(code uint32) io.ReadWriter {
559 if !ch.decided {
560 return nil
561 }
562 return &extChannel{code, ch}
563}
564
565func (ch *channel) Stderr() io.ReadWriter {
566 return ch.Extended(1)
567}
568
569func (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {
570 if !ch.decided {
571 return false, errUndecided
572 }
573
574 if wantReply {
575 ch.sentRequestMu.Lock()
576 defer ch.sentRequestMu.Unlock()
577 }
578
579 msg := channelRequestMsg{
580 PeersId: ch.remoteId,
581 Request: name,
582 WantReply: wantReply,
583 RequestSpecificData: payload,
584 }
585
586 if err := ch.sendMessage(msg); err != nil {
587 return false, err
588 }
589
590 if wantReply {
591 m, ok := (<-ch.msg)
592 if !ok {
593 return false, io.EOF
594 }
595 switch m.(type) {
596 case *channelRequestFailureMsg:
597 return false, nil
598 case *channelRequestSuccessMsg:
599 return true, nil
600 default:
601 return false, fmt.Errorf("ssh: unexpected response to channel request: %#v", m)
602 }
603 }
604
605 return false, nil
606}
607
608// ackRequest either sends an ack or nack to the channel request.
609func (ch *channel) ackRequest(ok bool) error {
610 if !ch.decided {
611 return errUndecided
612 }
613
614 var msg interface{}
615 if !ok {
616 msg = channelRequestFailureMsg{
617 PeersId: ch.remoteId,
618 }
619 } else {
620 msg = channelRequestSuccessMsg{
621 PeersId: ch.remoteId,
622 }
623 }
624 return ch.sendMessage(msg)
625}
626
627func (ch *channel) ChannelType() string {
628 return ch.chanType
629}
630
631func (ch *channel) ExtraData() []byte {
632 return ch.extraData
633}
diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go
deleted file mode 100644
index 13484ab..0000000
--- a/vendor/golang.org/x/crypto/ssh/cipher.go
+++ /dev/null
@@ -1,627 +0,0 @@
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
5package ssh
6
7import (
8 "crypto/aes"
9 "crypto/cipher"
10 "crypto/des"
11 "crypto/rc4"
12 "crypto/subtle"
13 "encoding/binary"
14 "errors"
15 "fmt"
16 "hash"
17 "io"
18 "io/ioutil"
19)
20
21const (
22 packetSizeMultiple = 16 // TODO(huin) this should be determined by the cipher.
23
24 // RFC 4253 section 6.1 defines a minimum packet size of 32768 that implementations
25 // MUST be able to process (plus a few more kilobytes for padding and mac). The RFC
26 // indicates implementations SHOULD be able to handle larger packet sizes, but then
27 // waffles on about reasonable limits.
28 //
29 // OpenSSH caps their maxPacket at 256kB so we choose to do
30 // the same. maxPacket is also used to ensure that uint32
31 // length fields do not overflow, so it should remain well
32 // below 4G.
33 maxPacket = 256 * 1024
34)
35
36// noneCipher implements cipher.Stream and provides no encryption. It is used
37// by the transport before the first key-exchange.
38type noneCipher struct{}
39
40func (c noneCipher) XORKeyStream(dst, src []byte) {
41 copy(dst, src)
42}
43
44func newAESCTR(key, iv []byte) (cipher.Stream, error) {
45 c, err := aes.NewCipher(key)
46 if err != nil {
47 return nil, err
48 }
49 return cipher.NewCTR(c, iv), nil
50}
51
52func newRC4(key, iv []byte) (cipher.Stream, error) {
53 return rc4.NewCipher(key)
54}
55
56type streamCipherMode struct {
57 keySize int
58 ivSize int
59 skip int
60 createFunc func(key, iv []byte) (cipher.Stream, error)
61}
62
63func (c *streamCipherMode) createStream(key, iv []byte) (cipher.Stream, error) {
64 if len(key) < c.keySize {
65 panic("ssh: key length too small for cipher")
66 }
67 if len(iv) < c.ivSize {
68 panic("ssh: iv too small for cipher")
69 }
70
71 stream, err := c.createFunc(key[:c.keySize], iv[:c.ivSize])
72 if err != nil {
73 return nil, err
74 }
75
76 var streamDump []byte
77 if c.skip > 0 {
78 streamDump = make([]byte, 512)
79 }
80
81 for remainingToDump := c.skip; remainingToDump > 0; {
82 dumpThisTime := remainingToDump
83 if dumpThisTime > len(streamDump) {
84 dumpThisTime = len(streamDump)
85 }
86 stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
87 remainingToDump -= dumpThisTime
88 }
89
90 return stream, nil
91}
92
93// cipherModes documents properties of supported ciphers. Ciphers not included
94// are not supported and will not be negotiated, even if explicitly requested in
95// ClientConfig.Crypto.Ciphers.
96var cipherModes = map[string]*streamCipherMode{
97 // Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
98 // are defined in the order specified in the RFC.
99 "aes128-ctr": {16, aes.BlockSize, 0, newAESCTR},
100 "aes192-ctr": {24, aes.BlockSize, 0, newAESCTR},
101 "aes256-ctr": {32, aes.BlockSize, 0, newAESCTR},
102
103 // Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
104 // They are defined in the order specified in the RFC.
105 "arcfour128": {16, 0, 1536, newRC4},
106 "arcfour256": {32, 0, 1536, newRC4},
107
108 // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
109 // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
110 // RC4) has problems with weak keys, and should be used with caution."
111 // RFC4345 introduces improved versions of Arcfour.
112 "arcfour": {16, 0, 0, newRC4},
113
114 // AES-GCM is not a stream cipher, so it is constructed with a
115 // special case. If we add any more non-stream ciphers, we
116 // should invest a cleaner way to do this.
117 gcmCipherID: {16, 12, 0, nil},
118
119 // CBC mode is insecure and so is not included in the default config.
120 // (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely
121 // needed, it's possible to specify a custom Config to enable it.
122 // You should expect that an active attacker can recover plaintext if
123 // you do.
124 aes128cbcID: {16, aes.BlockSize, 0, nil},
125
126 // 3des-cbc is insecure and is disabled by default.
127 tripledescbcID: {24, des.BlockSize, 0, nil},
128}
129
130// prefixLen is the length of the packet prefix that contains the packet length
131// and number of padding bytes.
132const prefixLen = 5
133
134// streamPacketCipher is a packetCipher using a stream cipher.
135type streamPacketCipher struct {
136 mac hash.Hash
137 cipher cipher.Stream
138 etm bool
139
140 // The following members are to avoid per-packet allocations.
141 prefix [prefixLen]byte
142 seqNumBytes [4]byte
143 padding [2 * packetSizeMultiple]byte
144 packetData []byte
145 macResult []byte
146}
147
148// readPacket reads and decrypt a single packet from the reader argument.
149func (s *streamPacketCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
150 if _, err := io.ReadFull(r, s.prefix[:]); err != nil {
151 return nil, err
152 }
153
154 var encryptedPaddingLength [1]byte
155 if s.mac != nil && s.etm {
156 copy(encryptedPaddingLength[:], s.prefix[4:5])
157 s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
158 } else {
159 s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
160 }
161
162 length := binary.BigEndian.Uint32(s.prefix[0:4])
163 paddingLength := uint32(s.prefix[4])
164
165 var macSize uint32
166 if s.mac != nil {
167 s.mac.Reset()
168 binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
169 s.mac.Write(s.seqNumBytes[:])
170 if s.etm {
171 s.mac.Write(s.prefix[:4])
172 s.mac.Write(encryptedPaddingLength[:])
173 } else {
174 s.mac.Write(s.prefix[:])
175 }
176 macSize = uint32(s.mac.Size())
177 }
178
179 if length <= paddingLength+1 {
180 return nil, errors.New("ssh: invalid packet length, packet too small")
181 }
182
183 if length > maxPacket {
184 return nil, errors.New("ssh: invalid packet length, packet too large")
185 }
186
187 // the maxPacket check above ensures that length-1+macSize
188 // does not overflow.
189 if uint32(cap(s.packetData)) < length-1+macSize {
190 s.packetData = make([]byte, length-1+macSize)
191 } else {
192 s.packetData = s.packetData[:length-1+macSize]
193 }
194
195 if _, err := io.ReadFull(r, s.packetData); err != nil {
196 return nil, err
197 }
198 mac := s.packetData[length-1:]
199 data := s.packetData[:length-1]
200
201 if s.mac != nil && s.etm {
202 s.mac.Write(data)
203 }
204
205 s.cipher.XORKeyStream(data, data)
206
207 if s.mac != nil {
208 if !s.etm {
209 s.mac.Write(data)
210 }
211 s.macResult = s.mac.Sum(s.macResult[:0])
212 if subtle.ConstantTimeCompare(s.macResult, mac) != 1 {
213 return nil, errors.New("ssh: MAC failure")
214 }
215 }
216
217 return s.packetData[:length-paddingLength-1], nil
218}
219
220// writePacket encrypts and sends a packet of data to the writer argument
221func (s *streamPacketCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
222 if len(packet) > maxPacket {
223 return errors.New("ssh: packet too large")
224 }
225
226 aadlen := 0
227 if s.mac != nil && s.etm {
228 // packet length is not encrypted for EtM modes
229 aadlen = 4
230 }
231
232 paddingLength := packetSizeMultiple - (prefixLen+len(packet)-aadlen)%packetSizeMultiple
233 if paddingLength < 4 {
234 paddingLength += packetSizeMultiple
235 }
236
237 length := len(packet) + 1 + paddingLength
238 binary.BigEndian.PutUint32(s.prefix[:], uint32(length))
239 s.prefix[4] = byte(paddingLength)
240 padding := s.padding[:paddingLength]
241 if _, err := io.ReadFull(rand, padding); err != nil {
242 return err
243 }
244
245 if s.mac != nil {
246 s.mac.Reset()
247 binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
248 s.mac.Write(s.seqNumBytes[:])
249
250 if s.etm {
251 // For EtM algorithms, the packet length must stay unencrypted,
252 // but the following data (padding length) must be encrypted
253 s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
254 }
255
256 s.mac.Write(s.prefix[:])
257
258 if !s.etm {
259 // For non-EtM algorithms, the algorithm is applied on unencrypted data
260 s.mac.Write(packet)
261 s.mac.Write(padding)
262 }
263 }
264
265 if !(s.mac != nil && s.etm) {
266 // For EtM algorithms, the padding length has already been encrypted
267 // and the packet length must remain unencrypted
268 s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
269 }
270
271 s.cipher.XORKeyStream(packet, packet)
272 s.cipher.XORKeyStream(padding, padding)
273
274 if s.mac != nil && s.etm {
275 // For EtM algorithms, packet and padding must be encrypted
276 s.mac.Write(packet)
277 s.mac.Write(padding)
278 }
279
280 if _, err := w.Write(s.prefix[:]); err != nil {
281 return err
282 }
283 if _, err := w.Write(packet); err != nil {
284 return err
285 }
286 if _, err := w.Write(padding); err != nil {
287 return err
288 }
289
290 if s.mac != nil {
291 s.macResult = s.mac.Sum(s.macResult[:0])
292 if _, err := w.Write(s.macResult); err != nil {
293 return err
294 }
295 }
296
297 return nil
298}
299
300type gcmCipher struct {
301 aead cipher.AEAD
302 prefix [4]byte
303 iv []byte
304 buf []byte
305}
306
307func newGCMCipher(iv, key, macKey []byte) (packetCipher, error) {
308 c, err := aes.NewCipher(key)
309 if err != nil {
310 return nil, err
311 }
312
313 aead, err := cipher.NewGCM(c)
314 if err != nil {
315 return nil, err
316 }
317
318 return &gcmCipher{
319 aead: aead,
320 iv: iv,
321 }, nil
322}
323
324const gcmTagSize = 16
325
326func (c *gcmCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
327 // Pad out to multiple of 16 bytes. This is different from the
328 // stream cipher because that encrypts the length too.
329 padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple)
330 if padding < 4 {
331 padding += packetSizeMultiple
332 }
333
334 length := uint32(len(packet) + int(padding) + 1)
335 binary.BigEndian.PutUint32(c.prefix[:], length)
336 if _, err := w.Write(c.prefix[:]); err != nil {
337 return err
338 }
339
340 if cap(c.buf) < int(length) {
341 c.buf = make([]byte, length)
342 } else {
343 c.buf = c.buf[:length]
344 }
345
346 c.buf[0] = padding
347 copy(c.buf[1:], packet)
348 if _, err := io.ReadFull(rand, c.buf[1+len(packet):]); err != nil {
349 return err
350 }
351 c.buf = c.aead.Seal(c.buf[:0], c.iv, c.buf, c.prefix[:])
352 if _, err := w.Write(c.buf); err != nil {
353 return err
354 }
355 c.incIV()
356
357 return nil
358}
359
360func (c *gcmCipher) incIV() {
361 for i := 4 + 7; i >= 4; i-- {
362 c.iv[i]++
363 if c.iv[i] != 0 {
364 break
365 }
366 }
367}
368
369func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
370 if _, err := io.ReadFull(r, c.prefix[:]); err != nil {
371 return nil, err
372 }
373 length := binary.BigEndian.Uint32(c.prefix[:])
374 if length > maxPacket {
375 return nil, errors.New("ssh: max packet length exceeded.")
376 }
377
378 if cap(c.buf) < int(length+gcmTagSize) {
379 c.buf = make([]byte, length+gcmTagSize)
380 } else {
381 c.buf = c.buf[:length+gcmTagSize]
382 }
383
384 if _, err := io.ReadFull(r, c.buf); err != nil {
385 return nil, err
386 }
387
388 plain, err := c.aead.Open(c.buf[:0], c.iv, c.buf, c.prefix[:])
389 if err != nil {
390 return nil, err
391 }
392 c.incIV()
393
394 padding := plain[0]
395 if padding < 4 || padding >= 20 {
396 return nil, fmt.Errorf("ssh: illegal padding %d", padding)
397 }
398
399 if int(padding+1) >= len(plain) {
400 return nil, fmt.Errorf("ssh: padding %d too large", padding)
401 }
402 plain = plain[1 : length-uint32(padding)]
403 return plain, nil
404}
405
406// cbcCipher implements aes128-cbc cipher defined in RFC 4253 section 6.1
407type cbcCipher struct {
408 mac hash.Hash
409 macSize uint32
410 decrypter cipher.BlockMode
411 encrypter cipher.BlockMode
412
413 // The following members are to avoid per-packet allocations.
414 seqNumBytes [4]byte
415 packetData []byte
416 macResult []byte
417
418 // Amount of data we should still read to hide which
419 // verification error triggered.
420 oracleCamouflage uint32
421}
422
423func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
424 cbc := &cbcCipher{
425 mac: macModes[algs.MAC].new(macKey),
426 decrypter: cipher.NewCBCDecrypter(c, iv),
427 encrypter: cipher.NewCBCEncrypter(c, iv),
428 packetData: make([]byte, 1024),
429 }
430 if cbc.mac != nil {
431 cbc.macSize = uint32(cbc.mac.Size())
432 }
433
434 return cbc, nil
435}
436
437func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
438 c, err := aes.NewCipher(key)
439 if err != nil {
440 return nil, err
441 }
442
443 cbc, err := newCBCCipher(c, iv, key, macKey, algs)
444 if err != nil {
445 return nil, err
446 }
447
448 return cbc, nil
449}
450
451func newTripleDESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
452 c, err := des.NewTripleDESCipher(key)
453 if err != nil {
454 return nil, err
455 }
456
457 cbc, err := newCBCCipher(c, iv, key, macKey, algs)
458 if err != nil {
459 return nil, err
460 }
461
462 return cbc, nil
463}
464
465func maxUInt32(a, b int) uint32 {
466 if a > b {
467 return uint32(a)
468 }
469 return uint32(b)
470}
471
472const (
473 cbcMinPacketSizeMultiple = 8
474 cbcMinPacketSize = 16
475 cbcMinPaddingSize = 4
476)
477
478// cbcError represents a verification error that may leak information.
479type cbcError string
480
481func (e cbcError) Error() string { return string(e) }
482
483func (c *cbcCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
484 p, err := c.readPacketLeaky(seqNum, r)
485 if err != nil {
486 if _, ok := err.(cbcError); ok {
487 // Verification error: read a fixed amount of
488 // data, to make distinguishing between
489 // failing MAC and failing length check more
490 // difficult.
491 io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage))
492 }
493 }
494 return p, err
495}
496
497func (c *cbcCipher) readPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) {
498 blockSize := c.decrypter.BlockSize()
499
500 // Read the header, which will include some of the subsequent data in the
501 // case of block ciphers - this is copied back to the payload later.
502 // How many bytes of payload/padding will be read with this first read.
503 firstBlockLength := uint32((prefixLen + blockSize - 1) / blockSize * blockSize)
504 firstBlock := c.packetData[:firstBlockLength]
505 if _, err := io.ReadFull(r, firstBlock); err != nil {
506 return nil, err
507 }
508
509 c.oracleCamouflage = maxPacket + 4 + c.macSize - firstBlockLength
510
511 c.decrypter.CryptBlocks(firstBlock, firstBlock)
512 length := binary.BigEndian.Uint32(firstBlock[:4])
513 if length > maxPacket {
514 return nil, cbcError("ssh: packet too large")
515 }
516 if length+4 < maxUInt32(cbcMinPacketSize, blockSize) {
517 // The minimum size of a packet is 16 (or the cipher block size, whichever
518 // is larger) bytes.
519 return nil, cbcError("ssh: packet too small")
520 }
521 // The length of the packet (including the length field but not the MAC) must
522 // be a multiple of the block size or 8, whichever is larger.
523 if (length+4)%maxUInt32(cbcMinPacketSizeMultiple, blockSize) != 0 {
524 return nil, cbcError("ssh: invalid packet length multiple")
525 }
526
527 paddingLength := uint32(firstBlock[4])
528 if paddingLength < cbcMinPaddingSize || length <= paddingLength+1 {
529 return nil, cbcError("ssh: invalid packet length")
530 }
531
532 // Positions within the c.packetData buffer:
533 macStart := 4 + length
534 paddingStart := macStart - paddingLength
535
536 // Entire packet size, starting before length, ending at end of mac.
537 entirePacketSize := macStart + c.macSize
538
539 // Ensure c.packetData is large enough for the entire packet data.
540 if uint32(cap(c.packetData)) < entirePacketSize {
541 // Still need to upsize and copy, but this should be rare at runtime, only
542 // on upsizing the packetData buffer.
543 c.packetData = make([]byte, entirePacketSize)
544 copy(c.packetData, firstBlock)
545 } else {
546 c.packetData = c.packetData[:entirePacketSize]
547 }
548
549 if n, err := io.ReadFull(r, c.packetData[firstBlockLength:]); err != nil {
550 return nil, err
551 } else {
552 c.oracleCamouflage -= uint32(n)
553 }
554
555 remainingCrypted := c.packetData[firstBlockLength:macStart]
556 c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)
557
558 mac := c.packetData[macStart:]
559 if c.mac != nil {
560 c.mac.Reset()
561 binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
562 c.mac.Write(c.seqNumBytes[:])
563 c.mac.Write(c.packetData[:macStart])
564 c.macResult = c.mac.Sum(c.macResult[:0])
565 if subtle.ConstantTimeCompare(c.macResult, mac) != 1 {
566 return nil, cbcError("ssh: MAC failure")
567 }
568 }
569
570 return c.packetData[prefixLen:paddingStart], nil
571}
572
573func (c *cbcCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
574 effectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize())
575
576 // Length of encrypted portion of the packet (header, payload, padding).
577 // Enforce minimum padding and packet size.
578 encLength := maxUInt32(prefixLen+len(packet)+cbcMinPaddingSize, cbcMinPaddingSize)
579 // Enforce block size.
580 encLength = (encLength + effectiveBlockSize - 1) / effectiveBlockSize * effectiveBlockSize
581
582 length := encLength - 4
583 paddingLength := int(length) - (1 + len(packet))
584
585 // Overall buffer contains: header, payload, padding, mac.
586 // Space for the MAC is reserved in the capacity but not the slice length.
587 bufferSize := encLength + c.macSize
588 if uint32(cap(c.packetData)) < bufferSize {
589 c.packetData = make([]byte, encLength, bufferSize)
590 } else {
591 c.packetData = c.packetData[:encLength]
592 }
593
594 p := c.packetData
595
596 // Packet header.
597 binary.BigEndian.PutUint32(p, length)
598 p = p[4:]
599 p[0] = byte(paddingLength)
600
601 // Payload.
602 p = p[1:]
603 copy(p, packet)
604
605 // Padding.
606 p = p[len(packet):]
607 if _, err := io.ReadFull(rand, p); err != nil {
608 return err
609 }
610
611 if c.mac != nil {
612 c.mac.Reset()
613 binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
614 c.mac.Write(c.seqNumBytes[:])
615 c.mac.Write(c.packetData)
616 // The MAC is now appended into the capacity reserved for it earlier.
617 c.packetData = c.mac.Sum(c.packetData)
618 }
619
620 c.encrypter.CryptBlocks(c.packetData[:encLength], c.packetData[:encLength])
621
622 if _, err := w.Write(c.packetData); err != nil {
623 return err
624 }
625
626 return nil
627}
diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go
deleted file mode 100644
index c97f297..0000000
--- a/vendor/golang.org/x/crypto/ssh/client.go
+++ /dev/null
@@ -1,211 +0,0 @@
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
5package ssh
6
7import (
8 "errors"
9 "fmt"
10 "net"
11 "sync"
12 "time"
13)
14
15// Client implements a traditional SSH client that supports shells,
16// subprocesses, port forwarding and tunneled dialing.
17type Client struct {
18 Conn
19
20 forwards forwardList // forwarded tcpip connections from the remote side
21 mu sync.Mutex
22 channelHandlers map[string]chan NewChannel
23}
24
25// HandleChannelOpen returns a channel on which NewChannel requests
26// for the given type are sent. If the type already is being handled,
27// nil is returned. The channel is closed when the connection is closed.
28func (c *Client) HandleChannelOpen(channelType string) <-chan NewChannel {
29 c.mu.Lock()
30 defer c.mu.Unlock()
31 if c.channelHandlers == nil {
32 // The SSH channel has been closed.
33 c := make(chan NewChannel)
34 close(c)
35 return c
36 }
37
38 ch := c.channelHandlers[channelType]
39 if ch != nil {
40 return nil
41 }
42
43 ch = make(chan NewChannel, chanSize)
44 c.channelHandlers[channelType] = ch
45 return ch
46}
47
48// NewClient creates a Client on top of the given connection.
49func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {
50 conn := &Client{
51 Conn: c,
52 channelHandlers: make(map[string]chan NewChannel, 1),
53 }
54
55 go conn.handleGlobalRequests(reqs)
56 go conn.handleChannelOpens(chans)
57 go func() {
58 conn.Wait()
59 conn.forwards.closeAll()
60 }()
61 go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-tcpip"))
62 return conn
63}
64
65// NewClientConn establishes an authenticated SSH connection using c
66// as the underlying transport. The Request and NewChannel channels
67// must be serviced or the connection will hang.
68func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) {
69 fullConf := *config
70 fullConf.SetDefaults()
71 conn := &connection{
72 sshConn: sshConn{conn: c},
73 }
74
75 if err := conn.clientHandshake(addr, &fullConf); err != nil {
76 c.Close()
77 return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err)
78 }
79 conn.mux = newMux(conn.transport)
80 return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
81}
82
83// clientHandshake performs the client side key exchange. See RFC 4253 Section
84// 7.
85func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error {
86 if config.ClientVersion != "" {
87 c.clientVersion = []byte(config.ClientVersion)
88 } else {
89 c.clientVersion = []byte(packageVersion)
90 }
91 var err error
92 c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion)
93 if err != nil {
94 return err
95 }
96
97 c.transport = newClientTransport(
98 newTransport(c.sshConn.conn, config.Rand, true /* is client */),
99 c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr())
100 if err := c.transport.waitSession(); err != nil {
101 return err
102 }
103
104 c.sessionID = c.transport.getSessionID()
105 return c.clientAuthenticate(config)
106}
107
108// verifyHostKeySignature verifies the host key obtained in the key
109// exchange.
110func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error {
111 sig, rest, ok := parseSignatureBody(result.Signature)
112 if len(rest) > 0 || !ok {
113 return errors.New("ssh: signature parse error")
114 }
115
116 return hostKey.Verify(result.H, sig)
117}
118
119// NewSession opens a new Session for this client. (A session is a remote
120// execution of a program.)
121func (c *Client) NewSession() (*Session, error) {
122 ch, in, err := c.OpenChannel("session", nil)
123 if err != nil {
124 return nil, err
125 }
126 return newSession(ch, in)
127}
128
129func (c *Client) handleGlobalRequests(incoming <-chan *Request) {
130 for r := range incoming {
131 // This handles keepalive messages and matches
132 // the behaviour of OpenSSH.
133 r.Reply(false, nil)
134 }
135}
136
137// handleChannelOpens channel open messages from the remote side.
138func (c *Client) handleChannelOpens(in <-chan NewChannel) {
139 for ch := range in {
140 c.mu.Lock()
141 handler := c.channelHandlers[ch.ChannelType()]
142 c.mu.Unlock()
143
144 if handler != nil {
145 handler <- ch
146 } else {
147 ch.Reject(UnknownChannelType, fmt.Sprintf("unknown channel type: %v", ch.ChannelType()))
148 }
149 }
150
151 c.mu.Lock()
152 for _, ch := range c.channelHandlers {
153 close(ch)
154 }
155 c.channelHandlers = nil
156 c.mu.Unlock()
157}
158
159// Dial starts a client connection to the given SSH server. It is a
160// convenience function that connects to the given network address,
161// initiates the SSH handshake, and then sets up a Client. For access
162// to incoming channels and requests, use net.Dial with NewClientConn
163// instead.
164func Dial(network, addr string, config *ClientConfig) (*Client, error) {
165 conn, err := net.DialTimeout(network, addr, config.Timeout)
166 if err != nil {
167 return nil, err
168 }
169 c, chans, reqs, err := NewClientConn(conn, addr, config)
170 if err != nil {
171 return nil, err
172 }
173 return NewClient(c, chans, reqs), nil
174}
175
176// A ClientConfig structure is used to configure a Client. It must not be
177// modified after having been passed to an SSH function.
178type ClientConfig struct {
179 // Config contains configuration that is shared between clients and
180 // servers.
181 Config
182
183 // User contains the username to authenticate as.
184 User string
185
186 // Auth contains possible authentication methods to use with the
187 // server. Only the first instance of a particular RFC 4252 method will
188 // be used during authentication.
189 Auth []AuthMethod
190
191 // HostKeyCallback, if not nil, is called during the cryptographic
192 // handshake to validate the server's host key. A nil HostKeyCallback
193 // implies that all host keys are accepted.
194 HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error
195
196 // ClientVersion contains the version identification string that will
197 // be used for the connection. If empty, a reasonable default is used.
198 ClientVersion string
199
200 // HostKeyAlgorithms lists the key types that the client will
201 // accept from the server as host key, in order of
202 // preference. If empty, a reasonable default is used. Any
203 // string returned from PublicKey.Type method may be used, or
204 // any of the CertAlgoXxxx and KeyAlgoXxxx constants.
205 HostKeyAlgorithms []string
206
207 // Timeout is the maximum amount of time for the TCP connection to establish.
208 //
209 // A Timeout of zero means no timeout.
210 Timeout time.Duration
211}
diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go
deleted file mode 100644
index fd1ec5d..0000000
--- a/vendor/golang.org/x/crypto/ssh/client_auth.go
+++ /dev/null
@@ -1,475 +0,0 @@
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
5package ssh
6
7import (
8 "bytes"
9 "errors"
10 "fmt"
11 "io"
12)
13
14// clientAuthenticate authenticates with the remote server. See RFC 4252.
15func (c *connection) clientAuthenticate(config *ClientConfig) error {
16 // initiate user auth session
17 if err := c.transport.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})); err != nil {
18 return err
19 }
20 packet, err := c.transport.readPacket()
21 if err != nil {
22 return err
23 }
24 var serviceAccept serviceAcceptMsg
25 if err := Unmarshal(packet, &serviceAccept); err != nil {
26 return err
27 }
28
29 // during the authentication phase the client first attempts the "none" method
30 // then any untried methods suggested by the server.
31 tried := make(map[string]bool)
32 var lastMethods []string
33
34 sessionID := c.transport.getSessionID()
35 for auth := AuthMethod(new(noneAuth)); auth != nil; {
36 ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand)
37 if err != nil {
38 return err
39 }
40 if ok {
41 // success
42 return nil
43 }
44 tried[auth.method()] = true
45 if methods == nil {
46 methods = lastMethods
47 }
48 lastMethods = methods
49
50 auth = nil
51
52 findNext:
53 for _, a := range config.Auth {
54 candidateMethod := a.method()
55 if tried[candidateMethod] {
56 continue
57 }
58 for _, meth := range methods {
59 if meth == candidateMethod {
60 auth = a
61 break findNext
62 }
63 }
64 }
65 }
66 return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried))
67}
68
69func keys(m map[string]bool) []string {
70 s := make([]string, 0, len(m))
71
72 for key := range m {
73 s = append(s, key)
74 }
75 return s
76}
77
78// An AuthMethod represents an instance of an RFC 4252 authentication method.
79type AuthMethod interface {
80 // auth authenticates user over transport t.
81 // Returns true if authentication is successful.
82 // If authentication is not successful, a []string of alternative
83 // method names is returned. If the slice is nil, it will be ignored
84 // and the previous set of possible methods will be reused.
85 auth(session []byte, user string, p packetConn, rand io.Reader) (bool, []string, error)
86
87 // method returns the RFC 4252 method name.
88 method() string
89}
90
91// "none" authentication, RFC 4252 section 5.2.
92type noneAuth int
93
94func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
95 if err := c.writePacket(Marshal(&userAuthRequestMsg{
96 User: user,
97 Service: serviceSSH,
98 Method: "none",
99 })); err != nil {
100 return false, nil, err
101 }
102
103 return handleAuthResponse(c)
104}
105
106func (n *noneAuth) method() string {
107 return "none"
108}
109
110// passwordCallback is an AuthMethod that fetches the password through
111// a function call, e.g. by prompting the user.
112type passwordCallback func() (password string, err error)
113
114func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
115 type passwordAuthMsg struct {
116 User string `sshtype:"50"`
117 Service string
118 Method string
119 Reply bool
120 Password string
121 }
122
123 pw, err := cb()
124 // REVIEW NOTE: is there a need to support skipping a password attempt?
125 // The program may only find out that the user doesn't have a password
126 // when prompting.
127 if err != nil {
128 return false, nil, err
129 }
130
131 if err := c.writePacket(Marshal(&passwordAuthMsg{
132 User: user,
133 Service: serviceSSH,
134 Method: cb.method(),
135 Reply: false,
136 Password: pw,
137 })); err != nil {
138 return false, nil, err
139 }
140
141 return handleAuthResponse(c)
142}
143
144func (cb passwordCallback) method() string {
145 return "password"
146}
147
148// Password returns an AuthMethod using the given password.
149func Password(secret string) AuthMethod {
150 return passwordCallback(func() (string, error) { return secret, nil })
151}
152
153// PasswordCallback returns an AuthMethod that uses a callback for
154// fetching a password.
155func PasswordCallback(prompt func() (secret string, err error)) AuthMethod {
156 return passwordCallback(prompt)
157}
158
159type publickeyAuthMsg struct {
160 User string `sshtype:"50"`
161 Service string
162 Method string
163 // HasSig indicates to the receiver packet that the auth request is signed and
164 // should be used for authentication of the request.
165 HasSig bool
166 Algoname string
167 PubKey []byte
168 // Sig is tagged with "rest" so Marshal will exclude it during
169 // validateKey
170 Sig []byte `ssh:"rest"`
171}
172
173// publicKeyCallback is an AuthMethod that uses a set of key
174// pairs for authentication.
175type publicKeyCallback func() ([]Signer, error)
176
177func (cb publicKeyCallback) method() string {
178 return "publickey"
179}
180
181func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
182 // Authentication is performed in two stages. The first stage sends an
183 // enquiry to test if each key is acceptable to the remote. The second
184 // stage attempts to authenticate with the valid keys obtained in the
185 // first stage.
186
187 signers, err := cb()
188 if err != nil {
189 return false, nil, err
190 }
191 var validKeys []Signer
192 for _, signer := range signers {
193 if ok, err := validateKey(signer.PublicKey(), user, c); ok {
194 validKeys = append(validKeys, signer)
195 } else {
196 if err != nil {
197 return false, nil, err
198 }
199 }
200 }
201
202 // methods that may continue if this auth is not successful.
203 var methods []string
204 for _, signer := range validKeys {
205 pub := signer.PublicKey()
206
207 pubKey := pub.Marshal()
208 sign, err := signer.Sign(rand, buildDataSignedForAuth(session, userAuthRequestMsg{
209 User: user,
210 Service: serviceSSH,
211 Method: cb.method(),
212 }, []byte(pub.Type()), pubKey))
213 if err != nil {
214 return false, nil, err
215 }
216
217 // manually wrap the serialized signature in a string
218 s := Marshal(sign)
219 sig := make([]byte, stringLength(len(s)))
220 marshalString(sig, s)
221 msg := publickeyAuthMsg{
222 User: user,
223 Service: serviceSSH,
224 Method: cb.method(),
225 HasSig: true,
226 Algoname: pub.Type(),
227 PubKey: pubKey,
228 Sig: sig,
229 }
230 p := Marshal(&msg)
231 if err := c.writePacket(p); err != nil {
232 return false, nil, err
233 }
234 var success bool
235 success, methods, err = handleAuthResponse(c)
236 if err != nil {
237 return false, nil, err
238 }
239 if success {
240 return success, methods, err
241 }
242 }
243 return false, methods, nil
244}
245
246// validateKey validates the key provided is acceptable to the server.
247func validateKey(key PublicKey, user string, c packetConn) (bool, error) {
248 pubKey := key.Marshal()
249 msg := publickeyAuthMsg{
250 User: user,
251 Service: serviceSSH,
252 Method: "publickey",
253 HasSig: false,
254 Algoname: key.Type(),
255 PubKey: pubKey,
256 }
257 if err := c.writePacket(Marshal(&msg)); err != nil {
258 return false, err
259 }
260
261 return confirmKeyAck(key, c)
262}
263
264func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
265 pubKey := key.Marshal()
266 algoname := key.Type()
267
268 for {
269 packet, err := c.readPacket()
270 if err != nil {
271 return false, err
272 }
273 switch packet[0] {
274 case msgUserAuthBanner:
275 // TODO(gpaul): add callback to present the banner to the user
276 case msgUserAuthPubKeyOk:
277 var msg userAuthPubKeyOkMsg
278 if err := Unmarshal(packet, &msg); err != nil {
279 return false, err
280 }
281 if msg.Algo != algoname || !bytes.Equal(msg.PubKey, pubKey) {
282 return false, nil
283 }
284 return true, nil
285 case msgUserAuthFailure:
286 return false, nil
287 default:
288 return false, unexpectedMessageError(msgUserAuthSuccess, packet[0])
289 }
290 }
291}
292
293// PublicKeys returns an AuthMethod that uses the given key
294// pairs.
295func PublicKeys(signers ...Signer) AuthMethod {
296 return publicKeyCallback(func() ([]Signer, error) { return signers, nil })
297}
298
299// PublicKeysCallback returns an AuthMethod that runs the given
300// function to obtain a list of key pairs.
301func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod {
302 return publicKeyCallback(getSigners)
303}
304
305// handleAuthResponse returns whether the preceding authentication request succeeded
306// along with a list of remaining authentication methods to try next and
307// an error if an unexpected response was received.
308func handleAuthResponse(c packetConn) (bool, []string, error) {
309 for {
310 packet, err := c.readPacket()
311 if err != nil {
312 return false, nil, err
313 }
314
315 switch packet[0] {
316 case msgUserAuthBanner:
317 // TODO: add callback to present the banner to the user
318 case msgUserAuthFailure:
319 var msg userAuthFailureMsg
320 if err := Unmarshal(packet, &msg); err != nil {
321 return false, nil, err
322 }
323 return false, msg.Methods, nil
324 case msgUserAuthSuccess:
325 return true, nil, nil
326 default:
327 return false, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
328 }
329 }
330}
331
332// KeyboardInteractiveChallenge should print questions, optionally
333// disabling echoing (e.g. for passwords), and return all the answers.
334// Challenge may be called multiple times in a single session. After
335// successful authentication, the server may send a challenge with no
336// questions, for which the user and instruction messages should be
337// printed. RFC 4256 section 3.3 details how the UI should behave for
338// both CLI and GUI environments.
339type KeyboardInteractiveChallenge func(user, instruction string, questions []string, echos []bool) (answers []string, err error)
340
341// KeyboardInteractive returns a AuthMethod using a prompt/response
342// sequence controlled by the server.
343func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod {
344 return challenge
345}
346
347func (cb KeyboardInteractiveChallenge) method() string {
348 return "keyboard-interactive"
349}
350
351func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
352 type initiateMsg struct {
353 User string `sshtype:"50"`
354 Service string
355 Method string
356 Language string
357 Submethods string
358 }
359
360 if err := c.writePacket(Marshal(&initiateMsg{
361 User: user,
362 Service: serviceSSH,
363 Method: "keyboard-interactive",
364 })); err != nil {
365 return false, nil, err
366 }
367
368 for {
369 packet, err := c.readPacket()
370 if err != nil {
371 return false, nil, err
372 }
373
374 // like handleAuthResponse, but with less options.
375 switch packet[0] {
376 case msgUserAuthBanner:
377 // TODO: Print banners during userauth.
378 continue
379 case msgUserAuthInfoRequest:
380 // OK
381 case msgUserAuthFailure:
382 var msg userAuthFailureMsg
383 if err := Unmarshal(packet, &msg); err != nil {
384 return false, nil, err
385 }
386 return false, msg.Methods, nil
387 case msgUserAuthSuccess:
388 return true, nil, nil
389 default:
390 return false, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
391 }
392
393 var msg userAuthInfoRequestMsg
394 if err := Unmarshal(packet, &msg); err != nil {
395 return false, nil, err
396 }
397
398 // Manually unpack the prompt/echo pairs.
399 rest := msg.Prompts
400 var prompts []string
401 var echos []bool
402 for i := 0; i < int(msg.NumPrompts); i++ {
403 prompt, r, ok := parseString(rest)
404 if !ok || len(r) == 0 {
405 return false, nil, errors.New("ssh: prompt format error")
406 }
407 prompts = append(prompts, string(prompt))
408 echos = append(echos, r[0] != 0)
409 rest = r[1:]
410 }
411
412 if len(rest) != 0 {
413 return false, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
414 }
415
416 answers, err := cb(msg.User, msg.Instruction, prompts, echos)
417 if err != nil {
418 return false, nil, err
419 }
420
421 if len(answers) != len(prompts) {
422 return false, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
423 }
424 responseLength := 1 + 4
425 for _, a := range answers {
426 responseLength += stringLength(len(a))
427 }
428 serialized := make([]byte, responseLength)
429 p := serialized
430 p[0] = msgUserAuthInfoResponse
431 p = p[1:]
432 p = marshalUint32(p, uint32(len(answers)))
433 for _, a := range answers {
434 p = marshalString(p, []byte(a))
435 }
436
437 if err := c.writePacket(serialized); err != nil {
438 return false, nil, err
439 }
440 }
441}
442
443type retryableAuthMethod struct {
444 authMethod AuthMethod
445 maxTries int
446}
447
448func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok bool, methods []string, err error) {
449 for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
450 ok, methods, err = r.authMethod.auth(session, user, c, rand)
451 if ok || err != nil { // either success or error terminate
452 return ok, methods, err
453 }
454 }
455 return ok, methods, err
456}
457
458func (r *retryableAuthMethod) method() string {
459 return r.authMethod.method()
460}
461
462// RetryableAuthMethod is a decorator for other auth methods enabling them to
463// be retried up to maxTries before considering that AuthMethod itself failed.
464// If maxTries is <= 0, will retry indefinitely
465//
466// This is useful for interactive clients using challenge/response type
467// authentication (e.g. Keyboard-Interactive, Password, etc) where the user
468// could mistype their response resulting in the server issuing a
469// SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4
470// [keyboard-interactive]); Without this decorator, the non-retryable
471// AuthMethod would be removed from future consideration, and never tried again
472// (and so the user would never be able to retry their entry).
473func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {
474 return &retryableAuthMethod{authMethod: auth, maxTries: maxTries}
475}
diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go
deleted file mode 100644
index 8656d0f..0000000
--- a/vendor/golang.org/x/crypto/ssh/common.go
+++ /dev/null
@@ -1,371 +0,0 @@
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
5package ssh
6
7import (
8 "crypto"
9 "crypto/rand"
10 "fmt"
11 "io"
12 "sync"
13
14 _ "crypto/sha1"
15 _ "crypto/sha256"
16 _ "crypto/sha512"
17)
18
19// These are string constants in the SSH protocol.
20const (
21 compressionNone = "none"
22 serviceUserAuth = "ssh-userauth"
23 serviceSSH = "ssh-connection"
24)
25
26// supportedCiphers specifies the supported ciphers in preference order.
27var supportedCiphers = []string{
28 "aes128-ctr", "aes192-ctr", "aes256-ctr",
29 "aes128-gcm@openssh.com",
30 "arcfour256", "arcfour128",
31}
32
33// supportedKexAlgos specifies the supported key-exchange algorithms in
34// preference order.
35var supportedKexAlgos = []string{
36 kexAlgoCurve25519SHA256,
37 // P384 and P521 are not constant-time yet, but since we don't
38 // reuse ephemeral keys, using them for ECDH should be OK.
39 kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
40 kexAlgoDH14SHA1, kexAlgoDH1SHA1,
41}
42
43// supportedKexAlgos specifies the supported host-key algorithms (i.e. methods
44// of authenticating servers) in preference order.
45var supportedHostKeyAlgos = []string{
46 CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
47 CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
48
49 KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
50 KeyAlgoRSA, KeyAlgoDSA,
51
52 KeyAlgoED25519,
53}
54
55// supportedMACs specifies a default set of MAC algorithms in preference order.
56// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed
57// because they have reached the end of their useful life.
58var supportedMACs = []string{
59 "hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96",
60}
61
62var supportedCompressions = []string{compressionNone}
63
64// hashFuncs keeps the mapping of supported algorithms to their respective
65// hashes needed for signature verification.
66var hashFuncs = map[string]crypto.Hash{
67 KeyAlgoRSA: crypto.SHA1,
68 KeyAlgoDSA: crypto.SHA1,
69 KeyAlgoECDSA256: crypto.SHA256,
70 KeyAlgoECDSA384: crypto.SHA384,
71 KeyAlgoECDSA521: crypto.SHA512,
72 CertAlgoRSAv01: crypto.SHA1,
73 CertAlgoDSAv01: crypto.SHA1,
74 CertAlgoECDSA256v01: crypto.SHA256,
75 CertAlgoECDSA384v01: crypto.SHA384,
76 CertAlgoECDSA521v01: crypto.SHA512,
77}
78
79// unexpectedMessageError results when the SSH message that we received didn't
80// match what we wanted.
81func unexpectedMessageError(expected, got uint8) error {
82 return fmt.Errorf("ssh: unexpected message type %d (expected %d)", got, expected)
83}
84
85// parseError results from a malformed SSH message.
86func parseError(tag uint8) error {
87 return fmt.Errorf("ssh: parse error in message type %d", tag)
88}
89
90func findCommon(what string, client []string, server []string) (common string, err error) {
91 for _, c := range client {
92 for _, s := range server {
93 if c == s {
94 return c, nil
95 }
96 }
97 }
98 return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server)
99}
100
101type directionAlgorithms struct {
102 Cipher string
103 MAC string
104 Compression string
105}
106
107// rekeyBytes returns a rekeying intervals in bytes.
108func (a *directionAlgorithms) rekeyBytes() int64 {
109 // According to RFC4344 block ciphers should rekey after
110 // 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
111 // 128.
112 switch a.Cipher {
113 case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcmCipherID, aes128cbcID:
114 return 16 * (1 << 32)
115
116 }
117
118 // For others, stick with RFC4253 recommendation to rekey after 1 Gb of data.
119 return 1 << 30
120}
121
122type algorithms struct {
123 kex string
124 hostKey string
125 w directionAlgorithms
126 r directionAlgorithms
127}
128
129func findAgreedAlgorithms(clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) {
130 result := &algorithms{}
131
132 result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos)
133 if err != nil {
134 return
135 }
136
137 result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos)
138 if err != nil {
139 return
140 }
141
142 result.w.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer)
143 if err != nil {
144 return
145 }
146
147 result.r.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient)
148 if err != nil {
149 return
150 }
151
152 result.w.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
153 if err != nil {
154 return
155 }
156
157 result.r.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
158 if err != nil {
159 return
160 }
161
162 result.w.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
163 if err != nil {
164 return
165 }
166
167 result.r.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
168 if err != nil {
169 return
170 }
171
172 return result, nil
173}
174
175// If rekeythreshold is too small, we can't make any progress sending
176// stuff.
177const minRekeyThreshold uint64 = 256
178
179// Config contains configuration data common to both ServerConfig and
180// ClientConfig.
181type Config struct {
182 // Rand provides the source of entropy for cryptographic
183 // primitives. If Rand is nil, the cryptographic random reader
184 // in package crypto/rand will be used.
185 Rand io.Reader
186
187 // The maximum number of bytes sent or received after which a
188 // new key is negotiated. It must be at least 256. If
189 // unspecified, 1 gigabyte is used.
190 RekeyThreshold uint64
191
192 // The allowed key exchanges algorithms. If unspecified then a
193 // default set of algorithms is used.
194 KeyExchanges []string
195
196 // The allowed cipher algorithms. If unspecified then a sensible
197 // default is used.
198 Ciphers []string
199
200 // The allowed MAC algorithms. If unspecified then a sensible default
201 // is used.
202 MACs []string
203}
204
205// SetDefaults sets sensible values for unset fields in config. This is
206// exported for testing: Configs passed to SSH functions are copied and have
207// default values set automatically.
208func (c *Config) SetDefaults() {
209 if c.Rand == nil {
210 c.Rand = rand.Reader
211 }
212 if c.Ciphers == nil {
213 c.Ciphers = supportedCiphers
214 }
215 var ciphers []string
216 for _, c := range c.Ciphers {
217 if cipherModes[c] != nil {
218 // reject the cipher if we have no cipherModes definition
219 ciphers = append(ciphers, c)
220 }
221 }
222 c.Ciphers = ciphers
223
224 if c.KeyExchanges == nil {
225 c.KeyExchanges = supportedKexAlgos
226 }
227
228 if c.MACs == nil {
229 c.MACs = supportedMACs
230 }
231
232 if c.RekeyThreshold == 0 {
233 // RFC 4253, section 9 suggests rekeying after 1G.
234 c.RekeyThreshold = 1 << 30
235 }
236 if c.RekeyThreshold < minRekeyThreshold {
237 c.RekeyThreshold = minRekeyThreshold
238 }
239}
240
241// buildDataSignedForAuth returns the data that is signed in order to prove
242// possession of a private key. See RFC 4252, section 7.
243func buildDataSignedForAuth(sessionId []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte {
244 data := struct {
245 Session []byte
246 Type byte
247 User string
248 Service string
249 Method string
250 Sign bool
251 Algo []byte
252 PubKey []byte
253 }{
254 sessionId,
255 msgUserAuthRequest,
256 req.User,
257 req.Service,
258 req.Method,
259 true,
260 algo,
261 pubKey,
262 }
263 return Marshal(data)
264}
265
266func appendU16(buf []byte, n uint16) []byte {
267 return append(buf, byte(n>>8), byte(n))
268}
269
270func appendU32(buf []byte, n uint32) []byte {
271 return append(buf, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
272}
273
274func appendU64(buf []byte, n uint64) []byte {
275 return append(buf,
276 byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32),
277 byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
278}
279
280func appendInt(buf []byte, n int) []byte {
281 return appendU32(buf, uint32(n))
282}
283
284func appendString(buf []byte, s string) []byte {
285 buf = appendU32(buf, uint32(len(s)))
286 buf = append(buf, s...)
287 return buf
288}
289
290func appendBool(buf []byte, b bool) []byte {
291 if b {
292 return append(buf, 1)
293 }
294 return append(buf, 0)
295}
296
297// newCond is a helper to hide the fact that there is no usable zero
298// value for sync.Cond.
299func newCond() *sync.Cond { return sync.NewCond(new(sync.Mutex)) }
300
301// window represents the buffer available to clients
302// wishing to write to a channel.
303type window struct {
304 *sync.Cond
305 win uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1
306 writeWaiters int
307 closed bool
308}
309
310// add adds win to the amount of window available
311// for consumers.
312func (w *window) add(win uint32) bool {
313 // a zero sized window adjust is a noop.
314 if win == 0 {
315 return true
316 }
317 w.L.Lock()
318 if w.win+win < win {
319 w.L.Unlock()
320 return false
321 }
322 w.win += win
323 // It is unusual that multiple goroutines would be attempting to reserve
324 // window space, but not guaranteed. Use broadcast to notify all waiters
325 // that additional window is available.
326 w.Broadcast()
327 w.L.Unlock()
328 return true
329}
330
331// close sets the window to closed, so all reservations fail
332// immediately.
333func (w *window) close() {
334 w.L.Lock()
335 w.closed = true
336 w.Broadcast()
337 w.L.Unlock()
338}
339
340// reserve reserves win from the available window capacity.
341// If no capacity remains, reserve will block. reserve may
342// return less than requested.
343func (w *window) reserve(win uint32) (uint32, error) {
344 var err error
345 w.L.Lock()
346 w.writeWaiters++
347 w.Broadcast()
348 for w.win == 0 && !w.closed {
349 w.Wait()
350 }
351 w.writeWaiters--
352 if w.win < win {
353 win = w.win
354 }
355 w.win -= win
356 if w.closed {
357 err = io.EOF
358 }
359 w.L.Unlock()
360 return win, err
361}
362
363// waitWriterBlocked waits until some goroutine is blocked for further
364// writes. It is used in tests only.
365func (w *window) waitWriterBlocked() {
366 w.Cond.L.Lock()
367 for w.writeWaiters == 0 {
368 w.Cond.Wait()
369 }
370 w.Cond.L.Unlock()
371}
diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go
deleted file mode 100644
index e786f2f..0000000
--- a/vendor/golang.org/x/crypto/ssh/connection.go
+++ /dev/null
@@ -1,143 +0,0 @@
1// Copyright 2013 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
5package ssh
6
7import (
8 "fmt"
9 "net"
10)
11
12// OpenChannelError is returned if the other side rejects an
13// OpenChannel request.
14type OpenChannelError struct {
15 Reason RejectionReason
16 Message string
17}
18
19func (e *OpenChannelError) Error() string {
20 return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message)
21}
22
23// ConnMetadata holds metadata for the connection.
24type ConnMetadata interface {
25 // User returns the user ID for this connection.
26 User() string
27
28 // SessionID returns the sesson hash, also denoted by H.
29 SessionID() []byte
30
31 // ClientVersion returns the client's version string as hashed
32 // into the session ID.
33 ClientVersion() []byte
34
35 // ServerVersion returns the server's version string as hashed
36 // into the session ID.
37 ServerVersion() []byte
38
39 // RemoteAddr returns the remote address for this connection.
40 RemoteAddr() net.Addr
41
42 // LocalAddr returns the local address for this connection.
43 LocalAddr() net.Addr
44}
45
46// Conn represents an SSH connection for both server and client roles.
47// Conn is the basis for implementing an application layer, such
48// as ClientConn, which implements the traditional shell access for
49// clients.
50type Conn interface {
51 ConnMetadata
52
53 // SendRequest sends a global request, and returns the
54 // reply. If wantReply is true, it returns the response status
55 // and payload. See also RFC4254, section 4.
56 SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
57
58 // OpenChannel tries to open an channel. If the request is
59 // rejected, it returns *OpenChannelError. On success it returns
60 // the SSH Channel and a Go channel for incoming, out-of-band
61 // requests. The Go channel must be serviced, or the
62 // connection will hang.
63 OpenChannel(name string, data []byte) (Channel, <-chan *Request, error)
64
65 // Close closes the underlying network connection
66 Close() error
67
68 // Wait blocks until the connection has shut down, and returns the
69 // error causing the shutdown.
70 Wait() error
71
72 // TODO(hanwen): consider exposing:
73 // RequestKeyChange
74 // Disconnect
75}
76
77// DiscardRequests consumes and rejects all requests from the
78// passed-in channel.
79func DiscardRequests(in <-chan *Request) {
80 for req := range in {
81 if req.WantReply {
82 req.Reply(false, nil)
83 }
84 }
85}
86
87// A connection represents an incoming connection.
88type connection struct {
89 transport *handshakeTransport
90 sshConn
91
92 // The connection protocol.
93 *mux
94}
95
96func (c *connection) Close() error {
97 return c.sshConn.conn.Close()
98}
99
100// sshconn provides net.Conn metadata, but disallows direct reads and
101// writes.
102type sshConn struct {
103 conn net.Conn
104
105 user string
106 sessionID []byte
107 clientVersion []byte
108 serverVersion []byte
109}
110
111func dup(src []byte) []byte {
112 dst := make([]byte, len(src))
113 copy(dst, src)
114 return dst
115}
116
117func (c *sshConn) User() string {
118 return c.user
119}
120
121func (c *sshConn) RemoteAddr() net.Addr {
122 return c.conn.RemoteAddr()
123}
124
125func (c *sshConn) Close() error {
126 return c.conn.Close()
127}
128
129func (c *sshConn) LocalAddr() net.Addr {
130 return c.conn.LocalAddr()
131}
132
133func (c *sshConn) SessionID() []byte {
134 return dup(c.sessionID)
135}
136
137func (c *sshConn) ClientVersion() []byte {
138 return dup(c.clientVersion)
139}
140
141func (c *sshConn) ServerVersion() []byte {
142 return dup(c.serverVersion)
143}
diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go
deleted file mode 100644
index d6be894..0000000
--- a/vendor/golang.org/x/crypto/ssh/doc.go
+++ /dev/null
@@ -1,18 +0,0 @@
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/*
6Package ssh implements an SSH client and server.
7
8SSH is a transport security protocol, an authentication protocol and a
9family of application protocols. The most typical application level
10protocol is a remote shell and this is specifically implemented. However,
11the multiplexed nature of SSH is exposed to users that wish to support
12others.
13
14References:
15 [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
16 [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
17*/
18package ssh // import "golang.org/x/crypto/ssh"
diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go
deleted file mode 100644
index 8de6506..0000000
--- a/vendor/golang.org/x/crypto/ssh/handshake.go
+++ /dev/null
@@ -1,625 +0,0 @@
1// Copyright 2013 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
5package ssh
6
7import (
8 "crypto/rand"
9 "errors"
10 "fmt"
11 "io"
12 "log"
13 "net"
14 "sync"
15)
16
17// debugHandshake, if set, prints messages sent and received. Key
18// exchange messages are printed as if DH were used, so the debug
19// messages are wrong when using ECDH.
20const debugHandshake = false
21
22// chanSize sets the amount of buffering SSH connections. This is
23// primarily for testing: setting chanSize=0 uncovers deadlocks more
24// quickly.
25const chanSize = 16
26
27// keyingTransport is a packet based transport that supports key
28// changes. It need not be thread-safe. It should pass through
29// msgNewKeys in both directions.
30type keyingTransport interface {
31 packetConn
32
33 // prepareKeyChange sets up a key change. The key change for a
34 // direction will be effected if a msgNewKeys message is sent
35 // or received.
36 prepareKeyChange(*algorithms, *kexResult) error
37}
38
39// handshakeTransport implements rekeying on top of a keyingTransport
40// and offers a thread-safe writePacket() interface.
41type handshakeTransport struct {
42 conn keyingTransport
43 config *Config
44
45 serverVersion []byte
46 clientVersion []byte
47
48 // hostKeys is non-empty if we are the server. In that case,
49 // it contains all host keys that can be used to sign the
50 // connection.
51 hostKeys []Signer
52
53 // hostKeyAlgorithms is non-empty if we are the client. In that case,
54 // we accept these key types from the server as host key.
55 hostKeyAlgorithms []string
56
57 // On read error, incoming is closed, and readError is set.
58 incoming chan []byte
59 readError error
60
61 mu sync.Mutex
62 writeError error
63 sentInitPacket []byte
64 sentInitMsg *kexInitMsg
65 pendingPackets [][]byte // Used when a key exchange is in progress.
66
67 // If the read loop wants to schedule a kex, it pings this
68 // channel, and the write loop will send out a kex
69 // message.
70 requestKex chan struct{}
71
72 // If the other side requests or confirms a kex, its kexInit
73 // packet is sent here for the write loop to find it.
74 startKex chan *pendingKex
75
76 // data for host key checking
77 hostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error
78 dialAddress string
79 remoteAddr net.Addr
80
81 // Algorithms agreed in the last key exchange.
82 algorithms *algorithms
83
84 readPacketsLeft uint32
85 readBytesLeft int64
86
87 writePacketsLeft uint32
88 writeBytesLeft int64
89
90 // The session ID or nil if first kex did not complete yet.
91 sessionID []byte
92}
93
94type pendingKex struct {
95 otherInit []byte
96 done chan error
97}
98
99func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport {
100 t := &handshakeTransport{
101 conn: conn,
102 serverVersion: serverVersion,
103 clientVersion: clientVersion,
104 incoming: make(chan []byte, chanSize),
105 requestKex: make(chan struct{}, 1),
106 startKex: make(chan *pendingKex, 1),
107
108 config: config,
109 }
110
111 // We always start with a mandatory key exchange.
112 t.requestKex <- struct{}{}
113 return t
114}
115
116func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport {
117 t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
118 t.dialAddress = dialAddr
119 t.remoteAddr = addr
120 t.hostKeyCallback = config.HostKeyCallback
121 if config.HostKeyAlgorithms != nil {
122 t.hostKeyAlgorithms = config.HostKeyAlgorithms
123 } else {
124 t.hostKeyAlgorithms = supportedHostKeyAlgos
125 }
126 go t.readLoop()
127 go t.kexLoop()
128 return t
129}
130
131func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport {
132 t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
133 t.hostKeys = config.hostKeys
134 go t.readLoop()
135 go t.kexLoop()
136 return t
137}
138
139func (t *handshakeTransport) getSessionID() []byte {
140 return t.sessionID
141}
142
143// waitSession waits for the session to be established. This should be
144// the first thing to call after instantiating handshakeTransport.
145func (t *handshakeTransport) waitSession() error {
146 p, err := t.readPacket()
147 if err != nil {
148 return err
149 }
150 if p[0] != msgNewKeys {
151 return fmt.Errorf("ssh: first packet should be msgNewKeys")
152 }
153
154 return nil
155}
156
157func (t *handshakeTransport) id() string {
158 if len(t.hostKeys) > 0 {
159 return "server"
160 }
161 return "client"
162}
163
164func (t *handshakeTransport) printPacket(p []byte, write bool) {
165 action := "got"
166 if write {
167 action = "sent"
168 }
169
170 if p[0] == msgChannelData || p[0] == msgChannelExtendedData {
171 log.Printf("%s %s data (packet %d bytes)", t.id(), action, len(p))
172 } else {
173 msg, err := decode(p)
174 log.Printf("%s %s %T %v (%v)", t.id(), action, msg, msg, err)
175 }
176}
177
178func (t *handshakeTransport) readPacket() ([]byte, error) {
179 p, ok := <-t.incoming
180 if !ok {
181 return nil, t.readError
182 }
183 return p, nil
184}
185
186func (t *handshakeTransport) readLoop() {
187 first := true
188 for {
189 p, err := t.readOnePacket(first)
190 first = false
191 if err != nil {
192 t.readError = err
193 close(t.incoming)
194 break
195 }
196 if p[0] == msgIgnore || p[0] == msgDebug {
197 continue
198 }
199 t.incoming <- p
200 }
201
202 // Stop writers too.
203 t.recordWriteError(t.readError)
204
205 // Unblock the writer should it wait for this.
206 close(t.startKex)
207
208 // Don't close t.requestKex; it's also written to from writePacket.
209}
210
211func (t *handshakeTransport) pushPacket(p []byte) error {
212 if debugHandshake {
213 t.printPacket(p, true)
214 }
215 return t.conn.writePacket(p)
216}
217
218func (t *handshakeTransport) getWriteError() error {
219 t.mu.Lock()
220 defer t.mu.Unlock()
221 return t.writeError
222}
223
224func (t *handshakeTransport) recordWriteError(err error) {
225 t.mu.Lock()
226 defer t.mu.Unlock()
227 if t.writeError == nil && err != nil {
228 t.writeError = err
229 }
230}
231
232func (t *handshakeTransport) requestKeyExchange() {
233 select {
234 case t.requestKex <- struct{}{}:
235 default:
236 // something already requested a kex, so do nothing.
237 }
238}
239
240func (t *handshakeTransport) kexLoop() {
241
242write:
243 for t.getWriteError() == nil {
244 var request *pendingKex
245 var sent bool
246
247 for request == nil || !sent {
248 var ok bool
249 select {
250 case request, ok = <-t.startKex:
251 if !ok {
252 break write
253 }
254 case <-t.requestKex:
255 break
256 }
257
258 if !sent {
259 if err := t.sendKexInit(); err != nil {
260 t.recordWriteError(err)
261 break
262 }
263 sent = true
264 }
265 }
266
267 if err := t.getWriteError(); err != nil {
268 if request != nil {
269 request.done <- err
270 }
271 break
272 }
273
274 // We're not servicing t.requestKex, but that is OK:
275 // we never block on sending to t.requestKex.
276
277 // We're not servicing t.startKex, but the remote end
278 // has just sent us a kexInitMsg, so it can't send
279 // another key change request, until we close the done
280 // channel on the pendingKex request.
281
282 err := t.enterKeyExchange(request.otherInit)
283
284 t.mu.Lock()
285 t.writeError = err
286 t.sentInitPacket = nil
287 t.sentInitMsg = nil
288 t.writePacketsLeft = packetRekeyThreshold
289 if t.config.RekeyThreshold > 0 {
290 t.writeBytesLeft = int64(t.config.RekeyThreshold)
291 } else if t.algorithms != nil {
292 t.writeBytesLeft = t.algorithms.w.rekeyBytes()
293 }
294
295 // we have completed the key exchange. Since the
296 // reader is still blocked, it is safe to clear out
297 // the requestKex channel. This avoids the situation
298 // where: 1) we consumed our own request for the
299 // initial kex, and 2) the kex from the remote side
300 // caused another send on the requestKex channel,
301 clear:
302 for {
303 select {
304 case <-t.requestKex:
305 //
306 default:
307 break clear
308 }
309 }
310
311 request.done <- t.writeError
312
313 // kex finished. Push packets that we received while
314 // the kex was in progress. Don't look at t.startKex
315 // and don't increment writtenSinceKex: if we trigger
316 // another kex while we are still busy with the last
317 // one, things will become very confusing.
318 for _, p := range t.pendingPackets {
319 t.writeError = t.pushPacket(p)
320 if t.writeError != nil {
321 break
322 }
323 }
324 t.pendingPackets = t.pendingPackets[:0]
325 t.mu.Unlock()
326 }
327
328 // drain startKex channel. We don't service t.requestKex
329 // because nobody does blocking sends there.
330 go func() {
331 for init := range t.startKex {
332 init.done <- t.writeError
333 }
334 }()
335
336 // Unblock reader.
337 t.conn.Close()
338}
339
340// The protocol uses uint32 for packet counters, so we can't let them
341// reach 1<<32. We will actually read and write more packets than
342// this, though: the other side may send more packets, and after we
343// hit this limit on writing we will send a few more packets for the
344// key exchange itself.
345const packetRekeyThreshold = (1 << 31)
346
347func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
348 p, err := t.conn.readPacket()
349 if err != nil {
350 return nil, err
351 }
352
353 if t.readPacketsLeft > 0 {
354 t.readPacketsLeft--
355 } else {
356 t.requestKeyExchange()
357 }
358
359 if t.readBytesLeft > 0 {
360 t.readBytesLeft -= int64(len(p))
361 } else {
362 t.requestKeyExchange()
363 }
364
365 if debugHandshake {
366 t.printPacket(p, false)
367 }
368
369 if first && p[0] != msgKexInit {
370 return nil, fmt.Errorf("ssh: first packet should be msgKexInit")
371 }
372
373 if p[0] != msgKexInit {
374 return p, nil
375 }
376
377 firstKex := t.sessionID == nil
378
379 kex := pendingKex{
380 done: make(chan error, 1),
381 otherInit: p,
382 }
383 t.startKex <- &kex
384 err = <-kex.done
385
386 if debugHandshake {
387 log.Printf("%s exited key exchange (first %v), err %v", t.id(), firstKex, err)
388 }
389
390 if err != nil {
391 return nil, err
392 }
393
394 t.readPacketsLeft = packetRekeyThreshold
395 if t.config.RekeyThreshold > 0 {
396 t.readBytesLeft = int64(t.config.RekeyThreshold)
397 } else {
398 t.readBytesLeft = t.algorithms.r.rekeyBytes()
399 }
400
401 // By default, a key exchange is hidden from higher layers by
402 // translating it into msgIgnore.
403 successPacket := []byte{msgIgnore}
404 if firstKex {
405 // sendKexInit() for the first kex waits for
406 // msgNewKeys so the authentication process is
407 // guaranteed to happen over an encrypted transport.
408 successPacket = []byte{msgNewKeys}
409 }
410
411 return successPacket, nil
412}
413
414// sendKexInit sends a key change message.
415func (t *handshakeTransport) sendKexInit() error {
416 t.mu.Lock()
417 defer t.mu.Unlock()
418 if t.sentInitMsg != nil {
419 // kexInits may be sent either in response to the other side,
420 // or because our side wants to initiate a key change, so we
421 // may have already sent a kexInit. In that case, don't send a
422 // second kexInit.
423 return nil
424 }
425
426 msg := &kexInitMsg{
427 KexAlgos: t.config.KeyExchanges,
428 CiphersClientServer: t.config.Ciphers,
429 CiphersServerClient: t.config.Ciphers,
430 MACsClientServer: t.config.MACs,
431 MACsServerClient: t.config.MACs,
432 CompressionClientServer: supportedCompressions,
433 CompressionServerClient: supportedCompressions,
434 }
435 io.ReadFull(rand.Reader, msg.Cookie[:])
436
437 if len(t.hostKeys) > 0 {
438 for _, k := range t.hostKeys {
439 msg.ServerHostKeyAlgos = append(
440 msg.ServerHostKeyAlgos, k.PublicKey().Type())
441 }
442 } else {
443 msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
444 }
445 packet := Marshal(msg)
446
447 // writePacket destroys the contents, so save a copy.
448 packetCopy := make([]byte, len(packet))
449 copy(packetCopy, packet)
450
451 if err := t.pushPacket(packetCopy); err != nil {
452 return err
453 }
454
455 t.sentInitMsg = msg
456 t.sentInitPacket = packet
457
458 return nil
459}
460
461func (t *handshakeTransport) writePacket(p []byte) error {
462 switch p[0] {
463 case msgKexInit:
464 return errors.New("ssh: only handshakeTransport can send kexInit")
465 case msgNewKeys:
466 return errors.New("ssh: only handshakeTransport can send newKeys")
467 }
468
469 t.mu.Lock()
470 defer t.mu.Unlock()
471 if t.writeError != nil {
472 return t.writeError
473 }
474
475 if t.sentInitMsg != nil {
476 // Copy the packet so the writer can reuse the buffer.
477 cp := make([]byte, len(p))
478 copy(cp, p)
479 t.pendingPackets = append(t.pendingPackets, cp)
480 return nil
481 }
482
483 if t.writeBytesLeft > 0 {
484 t.writeBytesLeft -= int64(len(p))
485 } else {
486 t.requestKeyExchange()
487 }
488
489 if t.writePacketsLeft > 0 {
490 t.writePacketsLeft--
491 } else {
492 t.requestKeyExchange()
493 }
494
495 if err := t.pushPacket(p); err != nil {
496 t.writeError = err
497 }
498
499 return nil
500}
501
502func (t *handshakeTransport) Close() error {
503 return t.conn.Close()
504}
505
506func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
507 if debugHandshake {
508 log.Printf("%s entered key exchange", t.id())
509 }
510
511 otherInit := &kexInitMsg{}
512 if err := Unmarshal(otherInitPacket, otherInit); err != nil {
513 return err
514 }
515
516 magics := handshakeMagics{
517 clientVersion: t.clientVersion,
518 serverVersion: t.serverVersion,
519 clientKexInit: otherInitPacket,
520 serverKexInit: t.sentInitPacket,
521 }
522
523 clientInit := otherInit
524 serverInit := t.sentInitMsg
525 if len(t.hostKeys) == 0 {
526 clientInit, serverInit = serverInit, clientInit
527
528 magics.clientKexInit = t.sentInitPacket
529 magics.serverKexInit = otherInitPacket
530 }
531
532 var err error
533 t.algorithms, err = findAgreedAlgorithms(clientInit, serverInit)
534 if err != nil {
535 return err
536 }
537
538 // We don't send FirstKexFollows, but we handle receiving it.
539 //
540 // RFC 4253 section 7 defines the kex and the agreement method for
541 // first_kex_packet_follows. It states that the guessed packet
542 // should be ignored if the "kex algorithm and/or the host
543 // key algorithm is guessed wrong (server and client have
544 // different preferred algorithm), or if any of the other
545 // algorithms cannot be agreed upon". The other algorithms have
546 // already been checked above so the kex algorithm and host key
547 // algorithm are checked here.
548 if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) {
549 // other side sent a kex message for the wrong algorithm,
550 // which we have to ignore.
551 if _, err := t.conn.readPacket(); err != nil {
552 return err
553 }
554 }
555
556 kex, ok := kexAlgoMap[t.algorithms.kex]
557 if !ok {
558 return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex)
559 }
560
561 var result *kexResult
562 if len(t.hostKeys) > 0 {
563 result, err = t.server(kex, t.algorithms, &magics)
564 } else {
565 result, err = t.client(kex, t.algorithms, &magics)
566 }
567
568 if err != nil {
569 return err
570 }
571
572 if t.sessionID == nil {
573 t.sessionID = result.H
574 }
575 result.SessionID = t.sessionID
576
577 t.conn.prepareKeyChange(t.algorithms, result)
578 if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {
579 return err
580 }
581 if packet, err := t.conn.readPacket(); err != nil {
582 return err
583 } else if packet[0] != msgNewKeys {
584 return unexpectedMessageError(msgNewKeys, packet[0])
585 }
586
587 return nil
588}
589
590func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
591 var hostKey Signer
592 for _, k := range t.hostKeys {
593 if algs.hostKey == k.PublicKey().Type() {
594 hostKey = k
595 }
596 }
597
598 r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey)
599 return r, err
600}
601
602func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
603 result, err := kex.Client(t.conn, t.config.Rand, magics)
604 if err != nil {
605 return nil, err
606 }
607
608 hostKey, err := ParsePublicKey(result.HostKey)
609 if err != nil {
610 return nil, err
611 }
612
613 if err := verifyHostKeySignature(hostKey, result); err != nil {
614 return nil, err
615 }
616
617 if t.hostKeyCallback != nil {
618 err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey)
619 if err != nil {
620 return nil, err
621 }
622 }
623
624 return result, nil
625}
diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go
deleted file mode 100644
index c87fbeb..0000000
--- a/vendor/golang.org/x/crypto/ssh/kex.go
+++ /dev/null
@@ -1,540 +0,0 @@
1// Copyright 2013 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
5package ssh
6
7import (
8 "crypto"
9 "crypto/ecdsa"
10 "crypto/elliptic"
11 "crypto/rand"
12 "crypto/subtle"
13 "errors"
14 "io"
15 "math/big"
16
17 "golang.org/x/crypto/curve25519"
18)
19
20const (
21 kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1"
22 kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
23 kexAlgoECDH256 = "ecdh-sha2-nistp256"
24 kexAlgoECDH384 = "ecdh-sha2-nistp384"
25 kexAlgoECDH521 = "ecdh-sha2-nistp521"
26 kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
27)
28
29// kexResult captures the outcome of a key exchange.
30type kexResult struct {
31 // Session hash. See also RFC 4253, section 8.
32 H []byte
33
34 // Shared secret. See also RFC 4253, section 8.
35 K []byte
36
37 // Host key as hashed into H.
38 HostKey []byte
39
40 // Signature of H.
41 Signature []byte
42
43 // A cryptographic hash function that matches the security
44 // level of the key exchange algorithm. It is used for
45 // calculating H, and for deriving keys from H and K.
46 Hash crypto.Hash
47
48 // The session ID, which is the first H computed. This is used
49 // to derive key material inside the transport.
50 SessionID []byte
51}
52
53// handshakeMagics contains data that is always included in the
54// session hash.
55type handshakeMagics struct {
56 clientVersion, serverVersion []byte
57 clientKexInit, serverKexInit []byte
58}
59
60func (m *handshakeMagics) write(w io.Writer) {
61 writeString(w, m.clientVersion)
62 writeString(w, m.serverVersion)
63 writeString(w, m.clientKexInit)
64 writeString(w, m.serverKexInit)
65}
66
67// kexAlgorithm abstracts different key exchange algorithms.
68type kexAlgorithm interface {
69 // Server runs server-side key agreement, signing the result
70 // with a hostkey.
71 Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error)
72
73 // Client runs the client-side key agreement. Caller is
74 // responsible for verifying the host key signature.
75 Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error)
76}
77
78// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
79type dhGroup struct {
80 g, p, pMinus1 *big.Int
81}
82
83func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
84 if theirPublic.Cmp(bigOne) <= 0 || theirPublic.Cmp(group.pMinus1) >= 0 {
85 return nil, errors.New("ssh: DH parameter out of bounds")
86 }
87 return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil
88}
89
90func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
91 hashFunc := crypto.SHA1
92
93 var x *big.Int
94 for {
95 var err error
96 if x, err = rand.Int(randSource, group.pMinus1); err != nil {
97 return nil, err
98 }
99 if x.Sign() > 0 {
100 break
101 }
102 }
103
104 X := new(big.Int).Exp(group.g, x, group.p)
105 kexDHInit := kexDHInitMsg{
106 X: X,
107 }
108 if err := c.writePacket(Marshal(&kexDHInit)); err != nil {
109 return nil, err
110 }
111
112 packet, err := c.readPacket()
113 if err != nil {
114 return nil, err
115 }
116
117 var kexDHReply kexDHReplyMsg
118 if err = Unmarshal(packet, &kexDHReply); err != nil {
119 return nil, err
120 }
121
122 kInt, err := group.diffieHellman(kexDHReply.Y, x)
123 if err != nil {
124 return nil, err
125 }
126
127 h := hashFunc.New()
128 magics.write(h)
129 writeString(h, kexDHReply.HostKey)
130 writeInt(h, X)
131 writeInt(h, kexDHReply.Y)
132 K := make([]byte, intLength(kInt))
133 marshalInt(K, kInt)
134 h.Write(K)
135
136 return &kexResult{
137 H: h.Sum(nil),
138 K: K,
139 HostKey: kexDHReply.HostKey,
140 Signature: kexDHReply.Signature,
141 Hash: crypto.SHA1,
142 }, nil
143}
144
145func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
146 hashFunc := crypto.SHA1
147 packet, err := c.readPacket()
148 if err != nil {
149 return
150 }
151 var kexDHInit kexDHInitMsg
152 if err = Unmarshal(packet, &kexDHInit); err != nil {
153 return
154 }
155
156 var y *big.Int
157 for {
158 if y, err = rand.Int(randSource, group.pMinus1); err != nil {
159 return
160 }
161 if y.Sign() > 0 {
162 break
163 }
164 }
165
166 Y := new(big.Int).Exp(group.g, y, group.p)
167 kInt, err := group.diffieHellman(kexDHInit.X, y)
168 if err != nil {
169 return nil, err
170 }
171
172 hostKeyBytes := priv.PublicKey().Marshal()
173
174 h := hashFunc.New()
175 magics.write(h)
176 writeString(h, hostKeyBytes)
177 writeInt(h, kexDHInit.X)
178 writeInt(h, Y)
179
180 K := make([]byte, intLength(kInt))
181 marshalInt(K, kInt)
182 h.Write(K)
183
184 H := h.Sum(nil)
185
186 // H is already a hash, but the hostkey signing will apply its
187 // own key-specific hash algorithm.
188 sig, err := signAndMarshal(priv, randSource, H)
189 if err != nil {
190 return nil, err
191 }
192
193 kexDHReply := kexDHReplyMsg{
194 HostKey: hostKeyBytes,
195 Y: Y,
196 Signature: sig,
197 }
198 packet = Marshal(&kexDHReply)
199
200 err = c.writePacket(packet)
201 return &kexResult{
202 H: H,
203 K: K,
204 HostKey: hostKeyBytes,
205 Signature: sig,
206 Hash: crypto.SHA1,
207 }, nil
208}
209
210// ecdh performs Elliptic Curve Diffie-Hellman key exchange as
211// described in RFC 5656, section 4.
212type ecdh struct {
213 curve elliptic.Curve
214}
215
216func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
217 ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
218 if err != nil {
219 return nil, err
220 }
221
222 kexInit := kexECDHInitMsg{
223 ClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y),
224 }
225
226 serialized := Marshal(&kexInit)
227 if err := c.writePacket(serialized); err != nil {
228 return nil, err
229 }
230
231 packet, err := c.readPacket()
232 if err != nil {
233 return nil, err
234 }
235
236 var reply kexECDHReplyMsg
237 if err = Unmarshal(packet, &reply); err != nil {
238 return nil, err
239 }
240
241 x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey)
242 if err != nil {
243 return nil, err
244 }
245
246 // generate shared secret
247 secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes())
248
249 h := ecHash(kex.curve).New()
250 magics.write(h)
251 writeString(h, reply.HostKey)
252 writeString(h, kexInit.ClientPubKey)
253 writeString(h, reply.EphemeralPubKey)
254 K := make([]byte, intLength(secret))
255 marshalInt(K, secret)
256 h.Write(K)
257
258 return &kexResult{
259 H: h.Sum(nil),
260 K: K,
261 HostKey: reply.HostKey,
262 Signature: reply.Signature,
263 Hash: ecHash(kex.curve),
264 }, nil
265}
266
267// unmarshalECKey parses and checks an EC key.
268func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) {
269 x, y = elliptic.Unmarshal(curve, pubkey)
270 if x == nil {
271 return nil, nil, errors.New("ssh: elliptic.Unmarshal failure")
272 }
273 if !validateECPublicKey(curve, x, y) {
274 return nil, nil, errors.New("ssh: public key not on curve")
275 }
276 return x, y, nil
277}
278
279// validateECPublicKey checks that the point is a valid public key for
280// the given curve. See [SEC1], 3.2.2
281func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
282 if x.Sign() == 0 && y.Sign() == 0 {
283 return false
284 }
285
286 if x.Cmp(curve.Params().P) >= 0 {
287 return false
288 }
289
290 if y.Cmp(curve.Params().P) >= 0 {
291 return false
292 }
293
294 if !curve.IsOnCurve(x, y) {
295 return false
296 }
297
298 // We don't check if N * PubKey == 0, since
299 //
300 // - the NIST curves have cofactor = 1, so this is implicit.
301 // (We don't foresee an implementation that supports non NIST
302 // curves)
303 //
304 // - for ephemeral keys, we don't need to worry about small
305 // subgroup attacks.
306 return true
307}
308
309func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
310 packet, err := c.readPacket()
311 if err != nil {
312 return nil, err
313 }
314
315 var kexECDHInit kexECDHInitMsg
316 if err = Unmarshal(packet, &kexECDHInit); err != nil {
317 return nil, err
318 }
319
320 clientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey)
321 if err != nil {
322 return nil, err
323 }
324
325 // We could cache this key across multiple users/multiple
326 // connection attempts, but the benefit is small. OpenSSH
327 // generates a new key for each incoming connection.
328 ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
329 if err != nil {
330 return nil, err
331 }
332
333 hostKeyBytes := priv.PublicKey().Marshal()
334
335 serializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y)
336
337 // generate shared secret
338 secret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes())
339
340 h := ecHash(kex.curve).New()
341 magics.write(h)
342 writeString(h, hostKeyBytes)
343 writeString(h, kexECDHInit.ClientPubKey)
344 writeString(h, serializedEphKey)
345
346 K := make([]byte, intLength(secret))
347 marshalInt(K, secret)
348 h.Write(K)
349
350 H := h.Sum(nil)
351
352 // H is already a hash, but the hostkey signing will apply its
353 // own key-specific hash algorithm.
354 sig, err := signAndMarshal(priv, rand, H)
355 if err != nil {
356 return nil, err
357 }
358
359 reply := kexECDHReplyMsg{
360 EphemeralPubKey: serializedEphKey,
361 HostKey: hostKeyBytes,
362 Signature: sig,
363 }
364
365 serialized := Marshal(&reply)
366 if err := c.writePacket(serialized); err != nil {
367 return nil, err
368 }
369
370 return &kexResult{
371 H: H,
372 K: K,
373 HostKey: reply.HostKey,
374 Signature: sig,
375 Hash: ecHash(kex.curve),
376 }, nil
377}
378
379var kexAlgoMap = map[string]kexAlgorithm{}
380
381func init() {
382 // This is the group called diffie-hellman-group1-sha1 in RFC
383 // 4253 and Oakley Group 2 in RFC 2409.
384 p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16)
385 kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
386 g: new(big.Int).SetInt64(2),
387 p: p,
388 pMinus1: new(big.Int).Sub(p, bigOne),
389 }
390
391 // This is the group called diffie-hellman-group14-sha1 in RFC
392 // 4253 and Oakley Group 14 in RFC 3526.
393 p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
394
395 kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
396 g: new(big.Int).SetInt64(2),
397 p: p,
398 pMinus1: new(big.Int).Sub(p, bigOne),
399 }
400
401 kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
402 kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
403 kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
404 kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
405}
406
407// curve25519sha256 implements the curve25519-sha256@libssh.org key
408// agreement protocol, as described in
409// https://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt
410type curve25519sha256 struct{}
411
412type curve25519KeyPair struct {
413 priv [32]byte
414 pub [32]byte
415}
416
417func (kp *curve25519KeyPair) generate(rand io.Reader) error {
418 if _, err := io.ReadFull(rand, kp.priv[:]); err != nil {
419 return err
420 }
421 curve25519.ScalarBaseMult(&kp.pub, &kp.priv)
422 return nil
423}
424
425// curve25519Zeros is just an array of 32 zero bytes so that we have something
426// convenient to compare against in order to reject curve25519 points with the
427// wrong order.
428var curve25519Zeros [32]byte
429
430func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
431 var kp curve25519KeyPair
432 if err := kp.generate(rand); err != nil {
433 return nil, err
434 }
435 if err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil {
436 return nil, err
437 }
438
439 packet, err := c.readPacket()
440 if err != nil {
441 return nil, err
442 }
443
444 var reply kexECDHReplyMsg
445 if err = Unmarshal(packet, &reply); err != nil {
446 return nil, err
447 }
448 if len(reply.EphemeralPubKey) != 32 {
449 return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
450 }
451
452 var servPub, secret [32]byte
453 copy(servPub[:], reply.EphemeralPubKey)
454 curve25519.ScalarMult(&secret, &kp.priv, &servPub)
455 if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
456 return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
457 }
458
459 h := crypto.SHA256.New()
460 magics.write(h)
461 writeString(h, reply.HostKey)
462 writeString(h, kp.pub[:])
463 writeString(h, reply.EphemeralPubKey)
464
465 kInt := new(big.Int).SetBytes(secret[:])
466 K := make([]byte, intLength(kInt))
467 marshalInt(K, kInt)
468 h.Write(K)
469
470 return &kexResult{
471 H: h.Sum(nil),
472 K: K,
473 HostKey: reply.HostKey,
474 Signature: reply.Signature,
475 Hash: crypto.SHA256,
476 }, nil
477}
478
479func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
480 packet, err := c.readPacket()
481 if err != nil {
482 return
483 }
484 var kexInit kexECDHInitMsg
485 if err = Unmarshal(packet, &kexInit); err != nil {
486 return
487 }
488
489 if len(kexInit.ClientPubKey) != 32 {
490 return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
491 }
492
493 var kp curve25519KeyPair
494 if err := kp.generate(rand); err != nil {
495 return nil, err
496 }
497
498 var clientPub, secret [32]byte
499 copy(clientPub[:], kexInit.ClientPubKey)
500 curve25519.ScalarMult(&secret, &kp.priv, &clientPub)
501 if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
502 return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
503 }
504
505 hostKeyBytes := priv.PublicKey().Marshal()
506
507 h := crypto.SHA256.New()
508 magics.write(h)
509 writeString(h, hostKeyBytes)
510 writeString(h, kexInit.ClientPubKey)
511 writeString(h, kp.pub[:])
512
513 kInt := new(big.Int).SetBytes(secret[:])
514 K := make([]byte, intLength(kInt))
515 marshalInt(K, kInt)
516 h.Write(K)
517
518 H := h.Sum(nil)
519
520 sig, err := signAndMarshal(priv, rand, H)
521 if err != nil {
522 return nil, err
523 }
524
525 reply := kexECDHReplyMsg{
526 EphemeralPubKey: kp.pub[:],
527 HostKey: hostKeyBytes,
528 Signature: sig,
529 }
530 if err := c.writePacket(Marshal(&reply)); err != nil {
531 return nil, err
532 }
533 return &kexResult{
534 H: H,
535 K: K,
536 HostKey: hostKeyBytes,
537 Signature: sig,
538 Hash: crypto.SHA256,
539 }, nil
540}
diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go
deleted file mode 100644
index f38de98..0000000
--- a/vendor/golang.org/x/crypto/ssh/keys.go
+++ /dev/null
@@ -1,905 +0,0 @@
1// Copyright 2012 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
5package ssh
6
7import (
8 "bytes"
9 "crypto"
10 "crypto/dsa"
11 "crypto/ecdsa"
12 "crypto/elliptic"
13 "crypto/md5"
14 "crypto/rsa"
15 "crypto/sha256"
16 "crypto/x509"
17 "encoding/asn1"
18 "encoding/base64"
19 "encoding/hex"
20 "encoding/pem"
21 "errors"
22 "fmt"
23 "io"
24 "math/big"
25 "strings"
26
27 "golang.org/x/crypto/ed25519"
28)
29
30// These constants represent the algorithm names for key types supported by this
31// package.
32const (
33 KeyAlgoRSA = "ssh-rsa"
34 KeyAlgoDSA = "ssh-dss"
35 KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
36 KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
37 KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
38 KeyAlgoED25519 = "ssh-ed25519"
39)
40
41// parsePubKey parses a public key of the given algorithm.
42// Use ParsePublicKey for keys with prepended algorithm.
43func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {
44 switch algo {
45 case KeyAlgoRSA:
46 return parseRSA(in)
47 case KeyAlgoDSA:
48 return parseDSA(in)
49 case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
50 return parseECDSA(in)
51 case KeyAlgoED25519:
52 return parseED25519(in)
53 case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01:
54 cert, err := parseCert(in, certToPrivAlgo(algo))
55 if err != nil {
56 return nil, nil, err
57 }
58 return cert, nil, nil
59 }
60 return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo)
61}
62
63// parseAuthorizedKey parses a public key in OpenSSH authorized_keys format
64// (see sshd(8) manual page) once the options and key type fields have been
65// removed.
66func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
67 in = bytes.TrimSpace(in)
68
69 i := bytes.IndexAny(in, " \t")
70 if i == -1 {
71 i = len(in)
72 }
73 base64Key := in[:i]
74
75 key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))
76 n, err := base64.StdEncoding.Decode(key, base64Key)
77 if err != nil {
78 return nil, "", err
79 }
80 key = key[:n]
81 out, err = ParsePublicKey(key)
82 if err != nil {
83 return nil, "", err
84 }
85 comment = string(bytes.TrimSpace(in[i:]))
86 return out, comment, nil
87}
88
89// ParseKnownHosts parses an entry in the format of the known_hosts file.
90//
91// The known_hosts format is documented in the sshd(8) manual page. This
92// function will parse a single entry from in. On successful return, marker
93// will contain the optional marker value (i.e. "cert-authority" or "revoked")
94// or else be empty, hosts will contain the hosts that this entry matches,
95// pubKey will contain the public key and comment will contain any trailing
96// comment at the end of the line. See the sshd(8) manual page for the various
97// forms that a host string can take.
98//
99// The unparsed remainder of the input will be returned in rest. This function
100// can be called repeatedly to parse multiple entries.
101//
102// If no entries were found in the input then err will be io.EOF. Otherwise a
103// non-nil err value indicates a parse error.
104func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) {
105 for len(in) > 0 {
106 end := bytes.IndexByte(in, '\n')
107 if end != -1 {
108 rest = in[end+1:]
109 in = in[:end]
110 } else {
111 rest = nil
112 }
113
114 end = bytes.IndexByte(in, '\r')
115 if end != -1 {
116 in = in[:end]
117 }
118
119 in = bytes.TrimSpace(in)
120 if len(in) == 0 || in[0] == '#' {
121 in = rest
122 continue
123 }
124
125 i := bytes.IndexAny(in, " \t")
126 if i == -1 {
127 in = rest
128 continue
129 }
130
131 // Strip out the beginning of the known_host key.
132 // This is either an optional marker or a (set of) hostname(s).
133 keyFields := bytes.Fields(in)
134 if len(keyFields) < 3 || len(keyFields) > 5 {
135 return "", nil, nil, "", nil, errors.New("ssh: invalid entry in known_hosts data")
136 }
137
138 // keyFields[0] is either "@cert-authority", "@revoked" or a comma separated
139 // list of hosts
140 marker := ""
141 if keyFields[0][0] == '@' {
142 marker = string(keyFields[0][1:])
143 keyFields = keyFields[1:]
144 }
145
146 hosts := string(keyFields[0])
147 // keyFields[1] contains the key type (e.g. “ssh-rsa”).
148 // However, that information is duplicated inside the
149 // base64-encoded key and so is ignored here.
150
151 key := bytes.Join(keyFields[2:], []byte(" "))
152 if pubKey, comment, err = parseAuthorizedKey(key); err != nil {
153 return "", nil, nil, "", nil, err
154 }
155
156 return marker, strings.Split(hosts, ","), pubKey, comment, rest, nil
157 }
158
159 return "", nil, nil, "", nil, io.EOF
160}
161
162// ParseAuthorizedKeys parses a public key from an authorized_keys
163// file used in OpenSSH according to the sshd(8) manual page.
164func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
165 for len(in) > 0 {
166 end := bytes.IndexByte(in, '\n')
167 if end != -1 {
168 rest = in[end+1:]
169 in = in[:end]
170 } else {
171 rest = nil
172 }
173
174 end = bytes.IndexByte(in, '\r')
175 if end != -1 {
176 in = in[:end]
177 }
178
179 in = bytes.TrimSpace(in)
180 if len(in) == 0 || in[0] == '#' {
181 in = rest
182 continue
183 }
184
185 i := bytes.IndexAny(in, " \t")
186 if i == -1 {
187 in = rest
188 continue
189 }
190
191 if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
192 return out, comment, options, rest, nil
193 }
194
195 // No key type recognised. Maybe there's an options field at
196 // the beginning.
197 var b byte
198 inQuote := false
199 var candidateOptions []string
200 optionStart := 0
201 for i, b = range in {
202 isEnd := !inQuote && (b == ' ' || b == '\t')
203 if (b == ',' && !inQuote) || isEnd {
204 if i-optionStart > 0 {
205 candidateOptions = append(candidateOptions, string(in[optionStart:i]))
206 }
207 optionStart = i + 1
208 }
209 if isEnd {
210 break
211 }
212 if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) {
213 inQuote = !inQuote
214 }
215 }
216 for i < len(in) && (in[i] == ' ' || in[i] == '\t') {
217 i++
218 }
219 if i == len(in) {
220 // Invalid line: unmatched quote
221 in = rest
222 continue
223 }
224
225 in = in[i:]
226 i = bytes.IndexAny(in, " \t")
227 if i == -1 {
228 in = rest
229 continue
230 }
231
232 if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
233 options = candidateOptions
234 return out, comment, options, rest, nil
235 }
236
237 in = rest
238 continue
239 }
240
241 return nil, "", nil, nil, errors.New("ssh: no key found")
242}
243
244// ParsePublicKey parses an SSH public key formatted for use in
245// the SSH wire protocol according to RFC 4253, section 6.6.
246func ParsePublicKey(in []byte) (out PublicKey, err error) {
247 algo, in, ok := parseString(in)
248 if !ok {
249 return nil, errShortRead
250 }
251 var rest []byte
252 out, rest, err = parsePubKey(in, string(algo))
253 if len(rest) > 0 {
254 return nil, errors.New("ssh: trailing junk in public key")
255 }
256
257 return out, err
258}
259
260// MarshalAuthorizedKey serializes key for inclusion in an OpenSSH
261// authorized_keys file. The return value ends with newline.
262func MarshalAuthorizedKey(key PublicKey) []byte {
263 b := &bytes.Buffer{}
264 b.WriteString(key.Type())
265 b.WriteByte(' ')
266 e := base64.NewEncoder(base64.StdEncoding, b)
267 e.Write(key.Marshal())
268 e.Close()
269 b.WriteByte('\n')
270 return b.Bytes()
271}
272
273// PublicKey is an abstraction of different types of public keys.
274type PublicKey interface {
275 // Type returns the key's type, e.g. "ssh-rsa".
276 Type() string
277
278 // Marshal returns the serialized key data in SSH wire format,
279 // with the name prefix.
280 Marshal() []byte
281
282 // Verify that sig is a signature on the given data using this
283 // key. This function will hash the data appropriately first.
284 Verify(data []byte, sig *Signature) error
285}
286
287// CryptoPublicKey, if implemented by a PublicKey,
288// returns the underlying crypto.PublicKey form of the key.
289type CryptoPublicKey interface {
290 CryptoPublicKey() crypto.PublicKey
291}
292
293// A Signer can create signatures that verify against a public key.
294type Signer interface {
295 // PublicKey returns an associated PublicKey instance.
296 PublicKey() PublicKey
297
298 // Sign returns raw signature for the given data. This method
299 // will apply the hash specified for the keytype to the data.
300 Sign(rand io.Reader, data []byte) (*Signature, error)
301}
302
303type rsaPublicKey rsa.PublicKey
304
305func (r *rsaPublicKey) Type() string {
306 return "ssh-rsa"
307}
308
309// parseRSA parses an RSA key according to RFC 4253, section 6.6.
310func parseRSA(in []byte) (out PublicKey, rest []byte, err error) {
311 var w struct {
312 E *big.Int
313 N *big.Int
314 Rest []byte `ssh:"rest"`
315 }
316 if err := Unmarshal(in, &w); err != nil {
317 return nil, nil, err
318 }
319
320 if w.E.BitLen() > 24 {
321 return nil, nil, errors.New("ssh: exponent too large")
322 }
323 e := w.E.Int64()
324 if e < 3 || e&1 == 0 {
325 return nil, nil, errors.New("ssh: incorrect exponent")
326 }
327
328 var key rsa.PublicKey
329 key.E = int(e)
330 key.N = w.N
331 return (*rsaPublicKey)(&key), w.Rest, nil
332}
333
334func (r *rsaPublicKey) Marshal() []byte {
335 e := new(big.Int).SetInt64(int64(r.E))
336 // RSA publickey struct layout should match the struct used by
337 // parseRSACert in the x/crypto/ssh/agent package.
338 wirekey := struct {
339 Name string
340 E *big.Int
341 N *big.Int
342 }{
343 KeyAlgoRSA,
344 e,
345 r.N,
346 }
347 return Marshal(&wirekey)
348}
349
350func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
351 if sig.Format != r.Type() {
352 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
353 }
354 h := crypto.SHA1.New()
355 h.Write(data)
356 digest := h.Sum(nil)
357 return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob)
358}
359
360func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
361 return (*rsa.PublicKey)(r)
362}
363
364type dsaPublicKey dsa.PublicKey
365
366func (r *dsaPublicKey) Type() string {
367 return "ssh-dss"
368}
369
370// parseDSA parses an DSA key according to RFC 4253, section 6.6.
371func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
372 var w struct {
373 P, Q, G, Y *big.Int
374 Rest []byte `ssh:"rest"`
375 }
376 if err := Unmarshal(in, &w); err != nil {
377 return nil, nil, err
378 }
379
380 key := &dsaPublicKey{
381 Parameters: dsa.Parameters{
382 P: w.P,
383 Q: w.Q,
384 G: w.G,
385 },
386 Y: w.Y,
387 }
388 return key, w.Rest, nil
389}
390
391func (k *dsaPublicKey) Marshal() []byte {
392 // DSA publickey struct layout should match the struct used by
393 // parseDSACert in the x/crypto/ssh/agent package.
394 w := struct {
395 Name string
396 P, Q, G, Y *big.Int
397 }{
398 k.Type(),
399 k.P,
400 k.Q,
401 k.G,
402 k.Y,
403 }
404
405 return Marshal(&w)
406}
407
408func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
409 if sig.Format != k.Type() {
410 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
411 }
412 h := crypto.SHA1.New()
413 h.Write(data)
414 digest := h.Sum(nil)
415
416 // Per RFC 4253, section 6.6,
417 // The value for 'dss_signature_blob' is encoded as a string containing
418 // r, followed by s (which are 160-bit integers, without lengths or
419 // padding, unsigned, and in network byte order).
420 // For DSS purposes, sig.Blob should be exactly 40 bytes in length.
421 if len(sig.Blob) != 40 {
422 return errors.New("ssh: DSA signature parse error")
423 }
424 r := new(big.Int).SetBytes(sig.Blob[:20])
425 s := new(big.Int).SetBytes(sig.Blob[20:])
426 if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {
427 return nil
428 }
429 return errors.New("ssh: signature did not verify")
430}
431
432func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {
433 return (*dsa.PublicKey)(k)
434}
435
436type dsaPrivateKey struct {
437 *dsa.PrivateKey
438}
439
440func (k *dsaPrivateKey) PublicKey() PublicKey {
441 return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
442}
443
444func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
445 h := crypto.SHA1.New()
446 h.Write(data)
447 digest := h.Sum(nil)
448 r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
449 if err != nil {
450 return nil, err
451 }
452
453 sig := make([]byte, 40)
454 rb := r.Bytes()
455 sb := s.Bytes()
456
457 copy(sig[20-len(rb):20], rb)
458 copy(sig[40-len(sb):], sb)
459
460 return &Signature{
461 Format: k.PublicKey().Type(),
462 Blob: sig,
463 }, nil
464}
465
466type ecdsaPublicKey ecdsa.PublicKey
467
468func (key *ecdsaPublicKey) Type() string {
469 return "ecdsa-sha2-" + key.nistID()
470}
471
472func (key *ecdsaPublicKey) nistID() string {
473 switch key.Params().BitSize {
474 case 256:
475 return "nistp256"
476 case 384:
477 return "nistp384"
478 case 521:
479 return "nistp521"
480 }
481 panic("ssh: unsupported ecdsa key size")
482}
483
484type ed25519PublicKey ed25519.PublicKey
485
486func (key ed25519PublicKey) Type() string {
487 return KeyAlgoED25519
488}
489
490func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
491 var w struct {
492 KeyBytes []byte
493 Rest []byte `ssh:"rest"`
494 }
495
496 if err := Unmarshal(in, &w); err != nil {
497 return nil, nil, err
498 }
499
500 key := ed25519.PublicKey(w.KeyBytes)
501
502 return (ed25519PublicKey)(key), w.Rest, nil
503}
504
505func (key ed25519PublicKey) Marshal() []byte {
506 w := struct {
507 Name string
508 KeyBytes []byte
509 }{
510 KeyAlgoED25519,
511 []byte(key),
512 }
513 return Marshal(&w)
514}
515
516func (key ed25519PublicKey) Verify(b []byte, sig *Signature) error {
517 if sig.Format != key.Type() {
518 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type())
519 }
520
521 edKey := (ed25519.PublicKey)(key)
522 if ok := ed25519.Verify(edKey, b, sig.Blob); !ok {
523 return errors.New("ssh: signature did not verify")
524 }
525
526 return nil
527}
528
529func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {
530 return ed25519.PublicKey(k)
531}
532
533func supportedEllipticCurve(curve elliptic.Curve) bool {
534 return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
535}
536
537// ecHash returns the hash to match the given elliptic curve, see RFC
538// 5656, section 6.2.1
539func ecHash(curve elliptic.Curve) crypto.Hash {
540 bitSize := curve.Params().BitSize
541 switch {
542 case bitSize <= 256:
543 return crypto.SHA256
544 case bitSize <= 384:
545 return crypto.SHA384
546 }
547 return crypto.SHA512
548}
549
550// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
551func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
552 var w struct {
553 Curve string
554 KeyBytes []byte
555 Rest []byte `ssh:"rest"`
556 }
557
558 if err := Unmarshal(in, &w); err != nil {
559 return nil, nil, err
560 }
561
562 key := new(ecdsa.PublicKey)
563
564 switch w.Curve {
565 case "nistp256":
566 key.Curve = elliptic.P256()
567 case "nistp384":
568 key.Curve = elliptic.P384()
569 case "nistp521":
570 key.Curve = elliptic.P521()
571 default:
572 return nil, nil, errors.New("ssh: unsupported curve")
573 }
574
575 key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
576 if key.X == nil || key.Y == nil {
577 return nil, nil, errors.New("ssh: invalid curve point")
578 }
579 return (*ecdsaPublicKey)(key), w.Rest, nil
580}
581
582func (key *ecdsaPublicKey) Marshal() []byte {
583 // See RFC 5656, section 3.1.
584 keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y)
585 // ECDSA publickey struct layout should match the struct used by
586 // parseECDSACert in the x/crypto/ssh/agent package.
587 w := struct {
588 Name string
589 ID string
590 Key []byte
591 }{
592 key.Type(),
593 key.nistID(),
594 keyBytes,
595 }
596
597 return Marshal(&w)
598}
599
600func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
601 if sig.Format != key.Type() {
602 return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type())
603 }
604
605 h := ecHash(key.Curve).New()
606 h.Write(data)
607 digest := h.Sum(nil)
608
609 // Per RFC 5656, section 3.1.2,
610 // The ecdsa_signature_blob value has the following specific encoding:
611 // mpint r
612 // mpint s
613 var ecSig struct {
614 R *big.Int
615 S *big.Int
616 }
617
618 if err := Unmarshal(sig.Blob, &ecSig); err != nil {
619 return err
620 }
621
622 if ecdsa.Verify((*ecdsa.PublicKey)(key), digest, ecSig.R, ecSig.S) {
623 return nil
624 }
625 return errors.New("ssh: signature did not verify")
626}
627
628func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
629 return (*ecdsa.PublicKey)(k)
630}
631
632// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
633// *ecdsa.PrivateKey or any other crypto.Signer and returns a corresponding
634// Signer instance. ECDSA keys must use P-256, P-384 or P-521.
635func NewSignerFromKey(key interface{}) (Signer, error) {
636 switch key := key.(type) {
637 case crypto.Signer:
638 return NewSignerFromSigner(key)
639 case *dsa.PrivateKey:
640 return &dsaPrivateKey{key}, nil
641 default:
642 return nil, fmt.Errorf("ssh: unsupported key type %T", key)
643 }
644}
645
646type wrappedSigner struct {
647 signer crypto.Signer
648 pubKey PublicKey
649}
650
651// NewSignerFromSigner takes any crypto.Signer implementation and
652// returns a corresponding Signer interface. This can be used, for
653// example, with keys kept in hardware modules.
654func NewSignerFromSigner(signer crypto.Signer) (Signer, error) {
655 pubKey, err := NewPublicKey(signer.Public())
656 if err != nil {
657 return nil, err
658 }
659
660 return &wrappedSigner{signer, pubKey}, nil
661}
662
663func (s *wrappedSigner) PublicKey() PublicKey {
664 return s.pubKey
665}
666
667func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
668 var hashFunc crypto.Hash
669
670 switch key := s.pubKey.(type) {
671 case *rsaPublicKey, *dsaPublicKey:
672 hashFunc = crypto.SHA1
673 case *ecdsaPublicKey:
674 hashFunc = ecHash(key.Curve)
675 case ed25519PublicKey:
676 default:
677 return nil, fmt.Errorf("ssh: unsupported key type %T", key)
678 }
679
680 var digest []byte
681 if hashFunc != 0 {
682 h := hashFunc.New()
683 h.Write(data)
684 digest = h.Sum(nil)
685 } else {
686 digest = data
687 }
688
689 signature, err := s.signer.Sign(rand, digest, hashFunc)
690 if err != nil {
691 return nil, err
692 }
693
694 // crypto.Signer.Sign is expected to return an ASN.1-encoded signature
695 // for ECDSA and DSA, but that's not the encoding expected by SSH, so
696 // re-encode.
697 switch s.pubKey.(type) {
698 case *ecdsaPublicKey, *dsaPublicKey:
699 type asn1Signature struct {
700 R, S *big.Int
701 }
702 asn1Sig := new(asn1Signature)
703 _, err := asn1.Unmarshal(signature, asn1Sig)
704 if err != nil {
705 return nil, err
706 }
707
708 switch s.pubKey.(type) {
709 case *ecdsaPublicKey:
710 signature = Marshal(asn1Sig)
711
712 case *dsaPublicKey:
713 signature = make([]byte, 40)
714 r := asn1Sig.R.Bytes()
715 s := asn1Sig.S.Bytes()
716 copy(signature[20-len(r):20], r)
717 copy(signature[40-len(s):40], s)
718 }
719 }
720
721 return &Signature{
722 Format: s.pubKey.Type(),
723 Blob: signature,
724 }, nil
725}
726
727// NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
728// or ed25519.PublicKey returns a corresponding PublicKey instance.
729// ECDSA keys must use P-256, P-384 or P-521.
730func NewPublicKey(key interface{}) (PublicKey, error) {
731 switch key := key.(type) {
732 case *rsa.PublicKey:
733 return (*rsaPublicKey)(key), nil
734 case *ecdsa.PublicKey:
735 if !supportedEllipticCurve(key.Curve) {
736 return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported.")
737 }
738 return (*ecdsaPublicKey)(key), nil
739 case *dsa.PublicKey:
740 return (*dsaPublicKey)(key), nil
741 case ed25519.PublicKey:
742 return (ed25519PublicKey)(key), nil
743 default:
744 return nil, fmt.Errorf("ssh: unsupported key type %T", key)
745 }
746}
747
748// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
749// the same keys as ParseRawPrivateKey.
750func ParsePrivateKey(pemBytes []byte) (Signer, error) {
751 key, err := ParseRawPrivateKey(pemBytes)
752 if err != nil {
753 return nil, err
754 }
755
756 return NewSignerFromKey(key)
757}
758
759// encryptedBlock tells whether a private key is
760// encrypted by examining its Proc-Type header
761// for a mention of ENCRYPTED
762// according to RFC 1421 Section 4.6.1.1.
763func encryptedBlock(block *pem.Block) bool {
764 return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
765}
766
767// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
768// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
769func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
770 block, _ := pem.Decode(pemBytes)
771 if block == nil {
772 return nil, errors.New("ssh: no key found")
773 }
774
775 if encryptedBlock(block) {
776 return nil, errors.New("ssh: cannot decode encrypted private keys")
777 }
778
779 switch block.Type {
780 case "RSA PRIVATE KEY":
781 return x509.ParsePKCS1PrivateKey(block.Bytes)
782 case "EC PRIVATE KEY":
783 return x509.ParseECPrivateKey(block.Bytes)
784 case "DSA PRIVATE KEY":
785 return ParseDSAPrivateKey(block.Bytes)
786 case "OPENSSH PRIVATE KEY":
787 return parseOpenSSHPrivateKey(block.Bytes)
788 default:
789 return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
790 }
791}
792
793// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
794// specified by the OpenSSL DSA man page.
795func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
796 var k struct {
797 Version int
798 P *big.Int
799 Q *big.Int
800 G *big.Int
801 Pub *big.Int
802 Priv *big.Int
803 }
804 rest, err := asn1.Unmarshal(der, &k)
805 if err != nil {
806 return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
807 }
808 if len(rest) > 0 {
809 return nil, errors.New("ssh: garbage after DSA key")
810 }
811
812 return &dsa.PrivateKey{
813 PublicKey: dsa.PublicKey{
814 Parameters: dsa.Parameters{
815 P: k.P,
816 Q: k.Q,
817 G: k.G,
818 },
819 Y: k.Pub,
820 },
821 X: k.Priv,
822 }, nil
823}
824
825// Implemented based on the documentation at
826// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
827func parseOpenSSHPrivateKey(key []byte) (*ed25519.PrivateKey, error) {
828 magic := append([]byte("openssh-key-v1"), 0)
829 if !bytes.Equal(magic, key[0:len(magic)]) {
830 return nil, errors.New("ssh: invalid openssh private key format")
831 }
832 remaining := key[len(magic):]
833
834 var w struct {
835 CipherName string
836 KdfName string
837 KdfOpts string
838 NumKeys uint32
839 PubKey []byte
840 PrivKeyBlock []byte
841 }
842
843 if err := Unmarshal(remaining, &w); err != nil {
844 return nil, err
845 }
846
847 pk1 := struct {
848 Check1 uint32
849 Check2 uint32
850 Keytype string
851 Pub []byte
852 Priv []byte
853 Comment string
854 Pad []byte `ssh:"rest"`
855 }{}
856
857 if err := Unmarshal(w.PrivKeyBlock, &pk1); err != nil {
858 return nil, err
859 }
860
861 if pk1.Check1 != pk1.Check2 {
862 return nil, errors.New("ssh: checkint mismatch")
863 }
864
865 // we only handle ed25519 keys currently
866 if pk1.Keytype != KeyAlgoED25519 {
867 return nil, errors.New("ssh: unhandled key type")
868 }
869
870 for i, b := range pk1.Pad {
871 if int(b) != i+1 {
872 return nil, errors.New("ssh: padding not as expected")
873 }
874 }
875
876 if len(pk1.Priv) != ed25519.PrivateKeySize {
877 return nil, errors.New("ssh: private key unexpected length")
878 }
879
880 pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
881 copy(pk, pk1.Priv)
882 return &pk, nil
883}
884
885// FingerprintLegacyMD5 returns the user presentation of the key's
886// fingerprint as described by RFC 4716 section 4.
887func FingerprintLegacyMD5(pubKey PublicKey) string {
888 md5sum := md5.Sum(pubKey.Marshal())
889 hexarray := make([]string, len(md5sum))
890 for i, c := range md5sum {
891 hexarray[i] = hex.EncodeToString([]byte{c})
892 }
893 return strings.Join(hexarray, ":")
894}
895
896// FingerprintSHA256 returns the user presentation of the key's
897// fingerprint as unpadded base64 encoded sha256 hash.
898// This format was introduced from OpenSSH 6.8.
899// https://www.openssh.com/txt/release-6.8
900// https://tools.ietf.org/html/rfc4648#section-3.2 (unpadded base64 encoding)
901func FingerprintSHA256(pubKey PublicKey) string {
902 sha256sum := sha256.Sum256(pubKey.Marshal())
903 hash := base64.RawStdEncoding.EncodeToString(sha256sum[:])
904 return "SHA256:" + hash
905}
diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go
deleted file mode 100644
index c07a062..0000000
--- a/vendor/golang.org/x/crypto/ssh/mac.go
+++ /dev/null
@@ -1,61 +0,0 @@
1// Copyright 2012 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
5package ssh
6
7// Message authentication support
8
9import (
10 "crypto/hmac"
11 "crypto/sha1"
12 "crypto/sha256"
13 "hash"
14)
15
16type macMode struct {
17 keySize int
18 etm bool
19 new func(key []byte) hash.Hash
20}
21
22// truncatingMAC wraps around a hash.Hash and truncates the output digest to
23// a given size.
24type truncatingMAC struct {
25 length int
26 hmac hash.Hash
27}
28
29func (t truncatingMAC) Write(data []byte) (int, error) {
30 return t.hmac.Write(data)
31}
32
33func (t truncatingMAC) Sum(in []byte) []byte {
34 out := t.hmac.Sum(in)
35 return out[:len(in)+t.length]
36}
37
38func (t truncatingMAC) Reset() {
39 t.hmac.Reset()
40}
41
42func (t truncatingMAC) Size() int {
43 return t.length
44}
45
46func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() }
47
48var macModes = map[string]*macMode{
49 "hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash {
50 return hmac.New(sha256.New, key)
51 }},
52 "hmac-sha2-256": {32, false, func(key []byte) hash.Hash {
53 return hmac.New(sha256.New, key)
54 }},
55 "hmac-sha1": {20, false, func(key []byte) hash.Hash {
56 return hmac.New(sha1.New, key)
57 }},
58 "hmac-sha1-96": {20, false, func(key []byte) hash.Hash {
59 return truncatingMAC{12, hmac.New(sha1.New, key)}
60 }},
61}
diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go
deleted file mode 100644
index e6ecd3a..0000000
--- a/vendor/golang.org/x/crypto/ssh/messages.go
+++ /dev/null
@@ -1,758 +0,0 @@
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
5package ssh
6
7import (
8 "bytes"
9 "encoding/binary"
10 "errors"
11 "fmt"
12 "io"
13 "math/big"
14 "reflect"
15 "strconv"
16 "strings"
17)
18
19// These are SSH message type numbers. They are scattered around several
20// documents but many were taken from [SSH-PARAMETERS].
21const (
22 msgIgnore = 2
23 msgUnimplemented = 3
24 msgDebug = 4
25 msgNewKeys = 21
26
27 // Standard authentication messages
28 msgUserAuthSuccess = 52
29 msgUserAuthBanner = 53
30)
31
32// SSH messages:
33//
34// These structures mirror the wire format of the corresponding SSH messages.
35// They are marshaled using reflection with the marshal and unmarshal functions
36// in this file. The only wrinkle is that a final member of type []byte with a
37// ssh tag of "rest" receives the remainder of a packet when unmarshaling.
38
39// See RFC 4253, section 11.1.
40const msgDisconnect = 1
41
42// disconnectMsg is the message that signals a disconnect. It is also
43// the error type returned from mux.Wait()
44type disconnectMsg struct {
45 Reason uint32 `sshtype:"1"`
46 Message string
47 Language string
48}
49
50func (d *disconnectMsg) Error() string {
51 return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
52}
53
54// See RFC 4253, section 7.1.
55const msgKexInit = 20
56
57type kexInitMsg struct {
58 Cookie [16]byte `sshtype:"20"`
59 KexAlgos []string
60 ServerHostKeyAlgos []string
61 CiphersClientServer []string
62 CiphersServerClient []string
63 MACsClientServer []string
64 MACsServerClient []string
65 CompressionClientServer []string
66 CompressionServerClient []string
67 LanguagesClientServer []string
68 LanguagesServerClient []string
69 FirstKexFollows bool
70 Reserved uint32
71}
72
73// See RFC 4253, section 8.
74
75// Diffie-Helman
76const msgKexDHInit = 30
77
78type kexDHInitMsg struct {
79 X *big.Int `sshtype:"30"`
80}
81
82const msgKexECDHInit = 30
83
84type kexECDHInitMsg struct {
85 ClientPubKey []byte `sshtype:"30"`
86}
87
88const msgKexECDHReply = 31
89
90type kexECDHReplyMsg struct {
91 HostKey []byte `sshtype:"31"`
92 EphemeralPubKey []byte
93 Signature []byte
94}
95
96const msgKexDHReply = 31
97
98type kexDHReplyMsg struct {
99 HostKey []byte `sshtype:"31"`
100 Y *big.Int
101 Signature []byte
102}
103
104// See RFC 4253, section 10.
105const msgServiceRequest = 5
106
107type serviceRequestMsg struct {
108 Service string `sshtype:"5"`
109}
110
111// See RFC 4253, section 10.
112const msgServiceAccept = 6
113
114type serviceAcceptMsg struct {
115 Service string `sshtype:"6"`
116}
117
118// See RFC 4252, section 5.
119const msgUserAuthRequest = 50
120
121type userAuthRequestMsg struct {
122 User string `sshtype:"50"`
123 Service string
124 Method string
125 Payload []byte `ssh:"rest"`
126}
127
128// Used for debug printouts of packets.
129type userAuthSuccessMsg struct {
130}
131
132// See RFC 4252, section 5.1
133const msgUserAuthFailure = 51
134
135type userAuthFailureMsg struct {
136 Methods []string `sshtype:"51"`
137 PartialSuccess bool
138}
139
140// See RFC 4256, section 3.2
141const msgUserAuthInfoRequest = 60
142const msgUserAuthInfoResponse = 61
143
144type userAuthInfoRequestMsg struct {
145 User string `sshtype:"60"`
146 Instruction string
147 DeprecatedLanguage string
148 NumPrompts uint32
149 Prompts []byte `ssh:"rest"`
150}
151
152// See RFC 4254, section 5.1.
153const msgChannelOpen = 90
154
155type channelOpenMsg struct {
156 ChanType string `sshtype:"90"`
157 PeersId uint32
158 PeersWindow uint32
159 MaxPacketSize uint32
160 TypeSpecificData []byte `ssh:"rest"`
161}
162
163const msgChannelExtendedData = 95
164const msgChannelData = 94
165
166// Used for debug print outs of packets.
167type channelDataMsg struct {
168 PeersId uint32 `sshtype:"94"`
169 Length uint32
170 Rest []byte `ssh:"rest"`
171}
172
173// See RFC 4254, section 5.1.
174const msgChannelOpenConfirm = 91
175
176type channelOpenConfirmMsg struct {
177 PeersId uint32 `sshtype:"91"`
178 MyId uint32
179 MyWindow uint32
180 MaxPacketSize uint32
181 TypeSpecificData []byte `ssh:"rest"`
182}
183
184// See RFC 4254, section 5.1.
185const msgChannelOpenFailure = 92
186
187type channelOpenFailureMsg struct {
188 PeersId uint32 `sshtype:"92"`
189 Reason RejectionReason
190 Message string
191 Language string
192}
193
194const msgChannelRequest = 98
195
196type channelRequestMsg struct {
197 PeersId uint32 `sshtype:"98"`
198 Request string
199 WantReply bool
200 RequestSpecificData []byte `ssh:"rest"`
201}
202
203// See RFC 4254, section 5.4.
204const msgChannelSuccess = 99
205
206type channelRequestSuccessMsg struct {
207 PeersId uint32 `sshtype:"99"`
208}
209
210// See RFC 4254, section 5.4.
211const msgChannelFailure = 100
212
213type channelRequestFailureMsg struct {
214 PeersId uint32 `sshtype:"100"`
215}
216
217// See RFC 4254, section 5.3
218const msgChannelClose = 97
219
220type channelCloseMsg struct {
221 PeersId uint32 `sshtype:"97"`
222}
223
224// See RFC 4254, section 5.3
225const msgChannelEOF = 96
226
227type channelEOFMsg struct {
228 PeersId uint32 `sshtype:"96"`
229}
230
231// See RFC 4254, section 4
232const msgGlobalRequest = 80
233
234type globalRequestMsg struct {
235 Type string `sshtype:"80"`
236 WantReply bool
237 Data []byte `ssh:"rest"`
238}
239
240// See RFC 4254, section 4
241const msgRequestSuccess = 81
242
243type globalRequestSuccessMsg struct {
244 Data []byte `ssh:"rest" sshtype:"81"`
245}
246
247// See RFC 4254, section 4
248const msgRequestFailure = 82
249
250type globalRequestFailureMsg struct {
251 Data []byte `ssh:"rest" sshtype:"82"`
252}
253
254// See RFC 4254, section 5.2
255const msgChannelWindowAdjust = 93
256
257type windowAdjustMsg struct {
258 PeersId uint32 `sshtype:"93"`
259 AdditionalBytes uint32
260}
261
262// See RFC 4252, section 7
263const msgUserAuthPubKeyOk = 60
264
265type userAuthPubKeyOkMsg struct {
266 Algo string `sshtype:"60"`
267 PubKey []byte
268}
269
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.
272func 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 }
280 }
281
282 return tags
283}
284
285func fieldError(t reflect.Type, field int, problem string) error {
286 if problem != "" {
287 problem = ": " + problem
288 }
289 return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem)
290}
291
292var errShortRead = errors.New("ssh: short read")
293
294// Unmarshal parses data in SSH wire format into a structure. The out
295// argument should be a pointer to struct. If the first member of the
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.
300func Unmarshal(data []byte, out interface{}) error {
301 v := reflect.ValueOf(out).Elem()
302 structType := v.Type()
303 expectedTypes := typeTags(structType)
304
305 var expectedType byte
306 if len(expectedTypes) > 0 {
307 expectedType = expectedTypes[0]
308 }
309
310 if len(data) == 0 {
311 return parseError(expectedType)
312 }
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)
324 }
325 data = data[1:]
326 }
327
328 var ok bool
329 for i := 0; i < v.NumField(); i++ {
330 field := v.Field(i)
331 t := field.Type()
332 switch t.Kind() {
333 case reflect.Bool:
334 if len(data) < 1 {
335 return errShortRead
336 }
337 field.SetBool(data[0] != 0)
338 data = data[1:]
339 case reflect.Array:
340 if t.Elem().Kind() != reflect.Uint8 {
341 return fieldError(structType, i, "array of unsupported type")
342 }
343 if len(data) < t.Len() {
344 return errShortRead
345 }
346 for j, n := 0, t.Len(); j < n; j++ {
347 field.Index(j).Set(reflect.ValueOf(data[j]))
348 }
349 data = data[t.Len():]
350 case reflect.Uint64:
351 var u64 uint64
352 if u64, data, ok = parseUint64(data); !ok {
353 return errShortRead
354 }
355 field.SetUint(u64)
356 case reflect.Uint32:
357 var u32 uint32
358 if u32, data, ok = parseUint32(data); !ok {
359 return errShortRead
360 }
361 field.SetUint(uint64(u32))
362 case reflect.Uint8:
363 if len(data) < 1 {
364 return errShortRead
365 }
366 field.SetUint(uint64(data[0]))
367 data = data[1:]
368 case reflect.String:
369 var s []byte
370 if s, data, ok = parseString(data); !ok {
371 return fieldError(structType, i, "")
372 }
373 field.SetString(string(s))
374 case reflect.Slice:
375 switch t.Elem().Kind() {
376 case reflect.Uint8:
377 if structType.Field(i).Tag.Get("ssh") == "rest" {
378 field.Set(reflect.ValueOf(data))
379 data = nil
380 } else {
381 var s []byte
382 if s, data, ok = parseString(data); !ok {
383 return errShortRead
384 }
385 field.Set(reflect.ValueOf(s))
386 }
387 case reflect.String:
388 var nl []string
389 if nl, data, ok = parseNameList(data); !ok {
390 return errShortRead
391 }
392 field.Set(reflect.ValueOf(nl))
393 default:
394 return fieldError(structType, i, "slice of unsupported type")
395 }
396 case reflect.Ptr:
397 if t == bigIntType {
398 var n *big.Int
399 if n, data, ok = parseInt(data); !ok {
400 return errShortRead
401 }
402 field.Set(reflect.ValueOf(n))
403 } else {
404 return fieldError(structType, i, "pointer to unsupported type")
405 }
406 default:
407 return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
408 }
409 }
410
411 if len(data) != 0 {
412 return parseError(expectedType)
413 }
414
415 return nil
416}
417
418// Marshal serializes the message in msg to SSH wire format. The msg
419// argument should be a struct or pointer to struct. If the first
420// member has the "sshtype" tag set to a number in decimal, that
421// number is prepended to the result. If the last of member has the
422// "ssh" tag set to "rest", its contents are appended to the output.
423func Marshal(msg interface{}) []byte {
424 out := make([]byte, 0, 64)
425 return marshalStruct(out, msg)
426}
427
428func marshalStruct(out []byte, msg interface{}) []byte {
429 v := reflect.Indirect(reflect.ValueOf(msg))
430 msgTypes := typeTags(v.Type())
431 if len(msgTypes) > 0 {
432 out = append(out, msgTypes[0])
433 }
434
435 for i, n := 0, v.NumField(); i < n; i++ {
436 field := v.Field(i)
437 switch t := field.Type(); t.Kind() {
438 case reflect.Bool:
439 var v uint8
440 if field.Bool() {
441 v = 1
442 }
443 out = append(out, v)
444 case reflect.Array:
445 if t.Elem().Kind() != reflect.Uint8 {
446 panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface()))
447 }
448 for j, l := 0, t.Len(); j < l; j++ {
449 out = append(out, uint8(field.Index(j).Uint()))
450 }
451 case reflect.Uint32:
452 out = appendU32(out, uint32(field.Uint()))
453 case reflect.Uint64:
454 out = appendU64(out, uint64(field.Uint()))
455 case reflect.Uint8:
456 out = append(out, uint8(field.Uint()))
457 case reflect.String:
458 s := field.String()
459 out = appendInt(out, len(s))
460 out = append(out, s...)
461 case reflect.Slice:
462 switch t.Elem().Kind() {
463 case reflect.Uint8:
464 if v.Type().Field(i).Tag.Get("ssh") != "rest" {
465 out = appendInt(out, field.Len())
466 }
467 out = append(out, field.Bytes()...)
468 case reflect.String:
469 offset := len(out)
470 out = appendU32(out, 0)
471 if n := field.Len(); n > 0 {
472 for j := 0; j < n; j++ {
473 f := field.Index(j)
474 if j != 0 {
475 out = append(out, ',')
476 }
477 out = append(out, f.String()...)
478 }
479 // overwrite length value
480 binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))
481 }
482 default:
483 panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface()))
484 }
485 case reflect.Ptr:
486 if t == bigIntType {
487 var n *big.Int
488 nValue := reflect.ValueOf(&n)
489 nValue.Elem().Set(field)
490 needed := intLength(n)
491 oldLength := len(out)
492
493 if cap(out)-len(out) < needed {
494 newOut := make([]byte, len(out), 2*(len(out)+needed))
495 copy(newOut, out)
496 out = newOut
497 }
498 out = out[:oldLength+needed]
499 marshalInt(out[oldLength:], n)
500 } else {
501 panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface()))
502 }
503 }
504 }
505
506 return out
507}
508
509var bigOne = big.NewInt(1)
510
511func parseString(in []byte) (out, rest []byte, ok bool) {
512 if len(in) < 4 {
513 return
514 }
515 length := binary.BigEndian.Uint32(in)
516 in = in[4:]
517 if uint32(len(in)) < length {
518 return
519 }
520 out = in[:length]
521 rest = in[length:]
522 ok = true
523 return
524}
525
526var (
527 comma = []byte{','}
528 emptyNameList = []string{}
529)
530
531func parseNameList(in []byte) (out []string, rest []byte, ok bool) {
532 contents, rest, ok := parseString(in)
533 if !ok {
534 return
535 }
536 if len(contents) == 0 {
537 out = emptyNameList
538 return
539 }
540 parts := bytes.Split(contents, comma)
541 out = make([]string, len(parts))
542 for i, part := range parts {
543 out[i] = string(part)
544 }
545 return
546}
547
548func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {
549 contents, rest, ok := parseString(in)
550 if !ok {
551 return
552 }
553 out = new(big.Int)
554
555 if len(contents) > 0 && contents[0]&0x80 == 0x80 {
556 // This is a negative number
557 notBytes := make([]byte, len(contents))
558 for i := range notBytes {
559 notBytes[i] = ^contents[i]
560 }
561 out.SetBytes(notBytes)
562 out.Add(out, bigOne)
563 out.Neg(out)
564 } else {
565 // Positive number
566 out.SetBytes(contents)
567 }
568 ok = true
569 return
570}
571
572func parseUint32(in []byte) (uint32, []byte, bool) {
573 if len(in) < 4 {
574 return 0, nil, false
575 }
576 return binary.BigEndian.Uint32(in), in[4:], true
577}
578
579func parseUint64(in []byte) (uint64, []byte, bool) {
580 if len(in) < 8 {
581 return 0, nil, false
582 }
583 return binary.BigEndian.Uint64(in), in[8:], true
584}
585
586func intLength(n *big.Int) int {
587 length := 4 /* length bytes */
588 if n.Sign() < 0 {
589 nMinus1 := new(big.Int).Neg(n)
590 nMinus1.Sub(nMinus1, bigOne)
591 bitLen := nMinus1.BitLen()
592 if bitLen%8 == 0 {
593 // The number will need 0xff padding
594 length++
595 }
596 length += (bitLen + 7) / 8
597 } else if n.Sign() == 0 {
598 // A zero is the zero length string
599 } else {
600 bitLen := n.BitLen()
601 if bitLen%8 == 0 {
602 // The number will need 0x00 padding
603 length++
604 }
605 length += (bitLen + 7) / 8
606 }
607
608 return length
609}
610
611func marshalUint32(to []byte, n uint32) []byte {
612 binary.BigEndian.PutUint32(to, n)
613 return to[4:]
614}
615
616func marshalUint64(to []byte, n uint64) []byte {
617 binary.BigEndian.PutUint64(to, n)
618 return to[8:]
619}
620
621func marshalInt(to []byte, n *big.Int) []byte {
622 lengthBytes := to
623 to = to[4:]
624 length := 0
625
626 if n.Sign() < 0 {
627 // A negative number has to be converted to two's-complement
628 // form. So we'll subtract 1 and invert. If the
629 // most-significant-bit isn't set then we'll need to pad the
630 // beginning with 0xff in order to keep the number negative.
631 nMinus1 := new(big.Int).Neg(n)
632 nMinus1.Sub(nMinus1, bigOne)
633 bytes := nMinus1.Bytes()
634 for i := range bytes {
635 bytes[i] ^= 0xff
636 }
637 if len(bytes) == 0 || bytes[0]&0x80 == 0 {
638 to[0] = 0xff
639 to = to[1:]
640 length++
641 }
642 nBytes := copy(to, bytes)
643 to = to[nBytes:]
644 length += nBytes
645 } else if n.Sign() == 0 {
646 // A zero is the zero length string
647 } else {
648 bytes := n.Bytes()
649 if len(bytes) > 0 && bytes[0]&0x80 != 0 {
650 // We'll have to pad this with a 0x00 in order to
651 // stop it looking like a negative number.
652 to[0] = 0
653 to = to[1:]
654 length++
655 }
656 nBytes := copy(to, bytes)
657 to = to[nBytes:]
658 length += nBytes
659 }
660
661 lengthBytes[0] = byte(length >> 24)
662 lengthBytes[1] = byte(length >> 16)
663 lengthBytes[2] = byte(length >> 8)
664 lengthBytes[3] = byte(length)
665 return to
666}
667
668func writeInt(w io.Writer, n *big.Int) {
669 length := intLength(n)
670 buf := make([]byte, length)
671 marshalInt(buf, n)
672 w.Write(buf)
673}
674
675func writeString(w io.Writer, s []byte) {
676 var lengthBytes [4]byte
677 lengthBytes[0] = byte(len(s) >> 24)
678 lengthBytes[1] = byte(len(s) >> 16)
679 lengthBytes[2] = byte(len(s) >> 8)
680 lengthBytes[3] = byte(len(s))
681 w.Write(lengthBytes[:])
682 w.Write(s)
683}
684
685func stringLength(n int) int {
686 return 4 + n
687}
688
689func marshalString(to []byte, s []byte) []byte {
690 to[0] = byte(len(s) >> 24)
691 to[1] = byte(len(s) >> 16)
692 to[2] = byte(len(s) >> 8)
693 to[3] = byte(len(s))
694 to = to[4:]
695 copy(to, s)
696 return to[len(s):]
697}
698
699var bigIntType = reflect.TypeOf((*big.Int)(nil))
700
701// Decode a packet into its corresponding message.
702func decode(packet []byte) (interface{}, error) {
703 var msg interface{}
704 switch packet[0] {
705 case msgDisconnect:
706 msg = new(disconnectMsg)
707 case msgServiceRequest:
708 msg = new(serviceRequestMsg)
709 case msgServiceAccept:
710 msg = new(serviceAcceptMsg)
711 case msgKexInit:
712 msg = new(kexInitMsg)
713 case msgKexDHInit:
714 msg = new(kexDHInitMsg)
715 case msgKexDHReply:
716 msg = new(kexDHReplyMsg)
717 case msgUserAuthRequest:
718 msg = new(userAuthRequestMsg)
719 case msgUserAuthSuccess:
720 return new(userAuthSuccessMsg), nil
721 case msgUserAuthFailure:
722 msg = new(userAuthFailureMsg)
723 case msgUserAuthPubKeyOk:
724 msg = new(userAuthPubKeyOkMsg)
725 case msgGlobalRequest:
726 msg = new(globalRequestMsg)
727 case msgRequestSuccess:
728 msg = new(globalRequestSuccessMsg)
729 case msgRequestFailure:
730 msg = new(globalRequestFailureMsg)
731 case msgChannelOpen:
732 msg = new(channelOpenMsg)
733 case msgChannelData:
734 msg = new(channelDataMsg)
735 case msgChannelOpenConfirm:
736 msg = new(channelOpenConfirmMsg)
737 case msgChannelOpenFailure:
738 msg = new(channelOpenFailureMsg)
739 case msgChannelWindowAdjust:
740 msg = new(windowAdjustMsg)
741 case msgChannelEOF:
742 msg = new(channelEOFMsg)
743 case msgChannelClose:
744 msg = new(channelCloseMsg)
745 case msgChannelRequest:
746 msg = new(channelRequestMsg)
747 case msgChannelSuccess:
748 msg = new(channelRequestSuccessMsg)
749 case msgChannelFailure:
750 msg = new(channelRequestFailureMsg)
751 default:
752 return nil, unexpectedMessageError(0, packet[0])
753 }
754 if err := Unmarshal(packet, msg); err != nil {
755 return nil, err
756 }
757 return msg, nil
758}
diff --git a/vendor/golang.org/x/crypto/ssh/mux.go b/vendor/golang.org/x/crypto/ssh/mux.go
deleted file mode 100644
index 27a527c..0000000
--- a/vendor/golang.org/x/crypto/ssh/mux.go
+++ /dev/null
@@ -1,330 +0,0 @@
1// Copyright 2013 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
5package ssh
6
7import (
8 "encoding/binary"
9 "fmt"
10 "io"
11 "log"
12 "sync"
13 "sync/atomic"
14)
15
16// debugMux, if set, causes messages in the connection protocol to be
17// logged.
18const debugMux = false
19
20// chanList is a thread safe channel list.
21type chanList struct {
22 // protects concurrent access to chans
23 sync.Mutex
24
25 // chans are indexed by the local id of the channel, which the
26 // other side should send in the PeersId field.
27 chans []*channel
28
29 // This is a debugging aid: it offsets all IDs by this
30 // amount. This helps distinguish otherwise identical
31 // server/client muxes
32 offset uint32
33}
34
35// Assigns a channel ID to the given channel.
36func (c *chanList) add(ch *channel) uint32 {
37 c.Lock()
38 defer c.Unlock()
39 for i := range c.chans {
40 if c.chans[i] == nil {
41 c.chans[i] = ch
42 return uint32(i) + c.offset
43 }
44 }
45 c.chans = append(c.chans, ch)
46 return uint32(len(c.chans)-1) + c.offset
47}
48
49// getChan returns the channel for the given ID.
50func (c *chanList) getChan(id uint32) *channel {
51 id -= c.offset
52
53 c.Lock()
54 defer c.Unlock()
55 if id < uint32(len(c.chans)) {
56 return c.chans[id]
57 }
58 return nil
59}
60
61func (c *chanList) remove(id uint32) {
62 id -= c.offset
63 c.Lock()
64 if id < uint32(len(c.chans)) {
65 c.chans[id] = nil
66 }
67 c.Unlock()
68}
69
70// dropAll forgets all channels it knows, returning them in a slice.
71func (c *chanList) dropAll() []*channel {
72 c.Lock()
73 defer c.Unlock()
74 var r []*channel
75
76 for _, ch := range c.chans {
77 if ch == nil {
78 continue
79 }
80 r = append(r, ch)
81 }
82 c.chans = nil
83 return r
84}
85
86// mux represents the state for the SSH connection protocol, which
87// multiplexes many channels onto a single packet transport.
88type mux struct {
89 conn packetConn
90 chanList chanList
91
92 incomingChannels chan NewChannel
93
94 globalSentMu sync.Mutex
95 globalResponses chan interface{}
96 incomingRequests chan *Request
97
98 errCond *sync.Cond
99 err error
100}
101
102// When debugging, each new chanList instantiation has a different
103// offset.
104var globalOff uint32
105
106func (m *mux) Wait() error {
107 m.errCond.L.Lock()
108 defer m.errCond.L.Unlock()
109 for m.err == nil {
110 m.errCond.Wait()
111 }
112 return m.err
113}
114
115// newMux returns a mux that runs over the given connection.
116func newMux(p packetConn) *mux {
117 m := &mux{
118 conn: p,
119 incomingChannels: make(chan NewChannel, chanSize),
120 globalResponses: make(chan interface{}, 1),
121 incomingRequests: make(chan *Request, chanSize),
122 errCond: newCond(),
123 }
124 if debugMux {
125 m.chanList.offset = atomic.AddUint32(&globalOff, 1)
126 }
127
128 go m.loop()
129 return m
130}
131
132func (m *mux) sendMessage(msg interface{}) error {
133 p := Marshal(msg)
134 if debugMux {
135 log.Printf("send global(%d): %#v", m.chanList.offset, msg)
136 }
137 return m.conn.writePacket(p)
138}
139
140func (m *mux) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) {
141 if wantReply {
142 m.globalSentMu.Lock()
143 defer m.globalSentMu.Unlock()
144 }
145
146 if err := m.sendMessage(globalRequestMsg{
147 Type: name,
148 WantReply: wantReply,
149 Data: payload,
150 }); err != nil {
151 return false, nil, err
152 }
153
154 if !wantReply {
155 return false, nil, nil
156 }
157
158 msg, ok := <-m.globalResponses
159 if !ok {
160 return false, nil, io.EOF
161 }
162 switch msg := msg.(type) {
163 case *globalRequestFailureMsg:
164 return false, msg.Data, nil
165 case *globalRequestSuccessMsg:
166 return true, msg.Data, nil
167 default:
168 return false, nil, fmt.Errorf("ssh: unexpected response to request: %#v", msg)
169 }
170}
171
172// ackRequest must be called after processing a global request that
173// has WantReply set.
174func (m *mux) ackRequest(ok bool, data []byte) error {
175 if ok {
176 return m.sendMessage(globalRequestSuccessMsg{Data: data})
177 }
178 return m.sendMessage(globalRequestFailureMsg{Data: data})
179}
180
181func (m *mux) Close() error {
182 return m.conn.Close()
183}
184
185// loop runs the connection machine. It will process packets until an
186// error is encountered. To synchronize on loop exit, use mux.Wait.
187func (m *mux) loop() {
188 var err error
189 for err == nil {
190 err = m.onePacket()
191 }
192
193 for _, ch := range m.chanList.dropAll() {
194 ch.close()
195 }
196
197 close(m.incomingChannels)
198 close(m.incomingRequests)
199 close(m.globalResponses)
200
201 m.conn.Close()
202
203 m.errCond.L.Lock()
204 m.err = err
205 m.errCond.Broadcast()
206 m.errCond.L.Unlock()
207
208 if debugMux {
209 log.Println("loop exit", err)
210 }
211}
212
213// onePacket reads and processes one packet.
214func (m *mux) onePacket() error {
215 packet, err := m.conn.readPacket()
216 if err != nil {
217 return err
218 }
219
220 if debugMux {
221 if packet[0] == msgChannelData || packet[0] == msgChannelExtendedData {
222 log.Printf("decoding(%d): data packet - %d bytes", m.chanList.offset, len(packet))
223 } else {
224 p, _ := decode(packet)
225 log.Printf("decoding(%d): %d %#v - %d bytes", m.chanList.offset, packet[0], p, len(packet))
226 }
227 }
228
229 switch packet[0] {
230 case msgChannelOpen:
231 return m.handleChannelOpen(packet)
232 case msgGlobalRequest, msgRequestSuccess, msgRequestFailure:
233 return m.handleGlobalPacket(packet)
234 }
235
236 // assume a channel packet.
237 if len(packet) < 5 {
238 return parseError(packet[0])
239 }
240 id := binary.BigEndian.Uint32(packet[1:])
241 ch := m.chanList.getChan(id)
242 if ch == nil {
243 return fmt.Errorf("ssh: invalid channel %d", id)
244 }
245
246 return ch.handlePacket(packet)
247}
248
249func (m *mux) handleGlobalPacket(packet []byte) error {
250 msg, err := decode(packet)
251 if err != nil {
252 return err
253 }
254
255 switch msg := msg.(type) {
256 case *globalRequestMsg:
257 m.incomingRequests <- &Request{
258 Type: msg.Type,
259 WantReply: msg.WantReply,
260 Payload: msg.Data,
261 mux: m,
262 }
263 case *globalRequestSuccessMsg, *globalRequestFailureMsg:
264 m.globalResponses <- msg
265 default:
266 panic(fmt.Sprintf("not a global message %#v", msg))
267 }
268
269 return nil
270}
271
272// handleChannelOpen schedules a channel to be Accept()ed.
273func (m *mux) handleChannelOpen(packet []byte) error {
274 var msg channelOpenMsg
275 if err := Unmarshal(packet, &msg); err != nil {
276 return err
277 }
278
279 if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
280 failMsg := channelOpenFailureMsg{
281 PeersId: msg.PeersId,
282 Reason: ConnectionFailed,
283 Message: "invalid request",
284 Language: "en_US.UTF-8",
285 }
286 return m.sendMessage(failMsg)
287 }
288
289 c := m.newChannel(msg.ChanType, channelInbound, msg.TypeSpecificData)
290 c.remoteId = msg.PeersId
291 c.maxRemotePayload = msg.MaxPacketSize
292 c.remoteWin.add(msg.PeersWindow)
293 m.incomingChannels <- c
294 return nil
295}
296
297func (m *mux) OpenChannel(chanType string, extra []byte) (Channel, <-chan *Request, error) {
298 ch, err := m.openChannel(chanType, extra)
299 if err != nil {
300 return nil, nil, err
301 }
302
303 return ch, ch.incomingRequests, nil
304}
305
306func (m *mux) openChannel(chanType string, extra []byte) (*channel, error) {
307 ch := m.newChannel(chanType, channelOutbound, extra)
308
309 ch.maxIncomingPayload = channelMaxPacket
310
311 open := channelOpenMsg{
312 ChanType: chanType,
313 PeersWindow: ch.myWindow,
314 MaxPacketSize: ch.maxIncomingPayload,
315 TypeSpecificData: extra,
316 PeersId: ch.localId,
317 }
318 if err := m.sendMessage(open); err != nil {
319 return nil, err
320 }
321
322 switch msg := (<-ch.msg).(type) {
323 case *channelOpenConfirmMsg:
324 return ch, nil
325 case *channelOpenFailureMsg:
326 return nil, &OpenChannelError{msg.Reason, msg.Message}
327 default:
328 return nil, fmt.Errorf("ssh: unexpected packet in response to channel open: %T", msg)
329 }
330}
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
deleted file mode 100644
index 77c84d1..0000000
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ /dev/null
@@ -1,491 +0,0 @@
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
5package ssh
6
7import (
8 "bytes"
9 "errors"
10 "fmt"
11 "io"
12 "net"
13 "strings"
14)
15
16// The Permissions type holds fine-grained permissions that are
17// specific to a user or a specific authentication method for a
18// user. Permissions, except for "source-address", must be enforced in
19// the server application layer, after successful authentication. The
20// Permissions are passed on in ServerConn so a server implementation
21// can honor them.
22type Permissions struct {
23 // Critical options restrict default permissions. Common
24 // restrictions are "source-address" and "force-command". If
25 // the server cannot enforce the restriction, or does not
26 // recognize it, the user should not authenticate.
27 CriticalOptions map[string]string
28
29 // Extensions are extra functionality that the server may
30 // offer on authenticated connections. Common extensions are
31 // "permit-agent-forwarding", "permit-X11-forwarding". Lack of
32 // support for an extension does not preclude authenticating a
33 // user.
34 Extensions map[string]string
35}
36
37// ServerConfig holds server specific configuration data.
38type ServerConfig struct {
39 // Config contains configuration shared between client and server.
40 Config
41
42 hostKeys []Signer
43
44 // NoClientAuth is true if clients are allowed to connect without
45 // authenticating.
46 NoClientAuth bool
47
48 // PasswordCallback, if non-nil, is called when a user
49 // attempts to authenticate using a password.
50 PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)
51
52 // PublicKeyCallback, if non-nil, is called when a client attempts public
53 // key authentication. It must return true if the given public key is
54 // valid for the given user. For example, see CertChecker.Authenticate.
55 PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
56
57 // KeyboardInteractiveCallback, if non-nil, is called when
58 // keyboard-interactive authentication is selected (RFC
59 // 4256). The client object's Challenge function should be
60 // used to query the user. The callback may offer multiple
61 // Challenge rounds. To avoid information leaks, the client
62 // should be presented a challenge even if the user is
63 // unknown.
64 KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error)
65
66 // AuthLogCallback, if non-nil, is called to log all authentication
67 // attempts.
68 AuthLogCallback func(conn ConnMetadata, method string, err error)
69
70 // ServerVersion is the version identification string to announce in
71 // the public handshake.
72 // If empty, a reasonable default is used.
73 // Note that RFC 4253 section 4.2 requires that this string start with
74 // "SSH-2.0-".
75 ServerVersion string
76}
77
78// AddHostKey adds a private key as a host key. If an existing host
79// key exists with the same algorithm, it is overwritten. Each server
80// config must have at least one host key.
81func (s *ServerConfig) AddHostKey(key Signer) {
82 for i, k := range s.hostKeys {
83 if k.PublicKey().Type() == key.PublicKey().Type() {
84 s.hostKeys[i] = key
85 return
86 }
87 }
88
89 s.hostKeys = append(s.hostKeys, key)
90}
91
92// cachedPubKey contains the results of querying whether a public key is
93// acceptable for a user.
94type cachedPubKey struct {
95 user string
96 pubKeyData []byte
97 result error
98 perms *Permissions
99}
100
101const maxCachedPubKeys = 16
102
103// pubKeyCache caches tests for public keys. Since SSH clients
104// will query whether a public key is acceptable before attempting to
105// authenticate with it, we end up with duplicate queries for public
106// key validity. The cache only applies to a single ServerConn.
107type pubKeyCache struct {
108 keys []cachedPubKey
109}
110
111// get returns the result for a given user/algo/key tuple.
112func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) {
113 for _, k := range c.keys {
114 if k.user == user && bytes.Equal(k.pubKeyData, pubKeyData) {
115 return k, true
116 }
117 }
118 return cachedPubKey{}, false
119}
120
121// add adds the given tuple to the cache.
122func (c *pubKeyCache) add(candidate cachedPubKey) {
123 if len(c.keys) < maxCachedPubKeys {
124 c.keys = append(c.keys, candidate)
125 }
126}
127
128// ServerConn is an authenticated SSH connection, as seen from the
129// server
130type ServerConn struct {
131 Conn
132
133 // If the succeeding authentication callback returned a
134 // non-nil Permissions pointer, it is stored here.
135 Permissions *Permissions
136}
137
138// NewServerConn starts a new SSH server with c as the underlying
139// transport. It starts with a handshake and, if the handshake is
140// unsuccessful, it closes the connection and returns an error. The
141// Request and NewChannel channels must be serviced, or the connection
142// will hang.
143func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) {
144 fullConf := *config
145 fullConf.SetDefaults()
146 s := &connection{
147 sshConn: sshConn{conn: c},
148 }
149 perms, err := s.serverHandshake(&fullConf)
150 if err != nil {
151 c.Close()
152 return nil, nil, nil, err
153 }
154 return &ServerConn{s, perms}, s.mux.incomingChannels, s.mux.incomingRequests, nil
155}
156
157// signAndMarshal signs the data with the appropriate algorithm,
158// and serializes the result in SSH wire format.
159func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) {
160 sig, err := k.Sign(rand, data)
161 if err != nil {
162 return nil, err
163 }
164
165 return Marshal(sig), nil
166}
167
168// handshake performs key exchange and user authentication.
169func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) {
170 if len(config.hostKeys) == 0 {
171 return nil, errors.New("ssh: server has no host keys")
172 }
173
174 if !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil && config.KeyboardInteractiveCallback == nil {
175 return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
176 }
177
178 if config.ServerVersion != "" {
179 s.serverVersion = []byte(config.ServerVersion)
180 } else {
181 s.serverVersion = []byte(packageVersion)
182 }
183 var err error
184 s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion)
185 if err != nil {
186 return nil, err
187 }
188
189 tr := newTransport(s.sshConn.conn, config.Rand, false /* not client */)
190 s.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config)
191
192 if err := s.transport.waitSession(); err != nil {
193 return nil, err
194 }
195
196 // We just did the key change, so the session ID is established.
197 s.sessionID = s.transport.getSessionID()
198
199 var packet []byte
200 if packet, err = s.transport.readPacket(); err != nil {
201 return nil, err
202 }
203
204 var serviceRequest serviceRequestMsg
205 if err = Unmarshal(packet, &serviceRequest); err != nil {
206 return nil, err
207 }
208 if serviceRequest.Service != serviceUserAuth {
209 return nil, errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating")
210 }
211 serviceAccept := serviceAcceptMsg{
212 Service: serviceUserAuth,
213 }
214 if err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil {
215 return nil, err
216 }
217
218 perms, err := s.serverAuthenticate(config)
219 if err != nil {
220 return nil, err
221 }
222 s.mux = newMux(s.transport)
223 return perms, err
224}
225
226func isAcceptableAlgo(algo string) bool {
227 switch algo {
228 case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoED25519,
229 CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01:
230 return true
231 }
232 return false
233}
234
235func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
236 if addr == nil {
237 return errors.New("ssh: no address known for client, but source-address match required")
238 }
239
240 tcpAddr, ok := addr.(*net.TCPAddr)
241 if !ok {
242 return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr)
243 }
244
245 for _, sourceAddr := range strings.Split(sourceAddrs, ",") {
246 if allowedIP := net.ParseIP(sourceAddr); allowedIP != nil {
247 if allowedIP.Equal(tcpAddr.IP) {
248 return nil
249 }
250 } else {
251 _, ipNet, err := net.ParseCIDR(sourceAddr)
252 if err != nil {
253 return fmt.Errorf("ssh: error parsing source-address restriction %q: %v", sourceAddr, err)
254 }
255
256 if ipNet.Contains(tcpAddr.IP) {
257 return nil
258 }
259 }
260 }
261
262 return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
263}
264
265func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
266 sessionID := s.transport.getSessionID()
267 var cache pubKeyCache
268 var perms *Permissions
269
270userAuthLoop:
271 for {
272 var userAuthReq userAuthRequestMsg
273 if packet, err := s.transport.readPacket(); err != nil {
274 return nil, err
275 } else if err = Unmarshal(packet, &userAuthReq); err != nil {
276 return nil, err
277 }
278
279 if userAuthReq.Service != serviceSSH {
280 return nil, errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service)
281 }
282
283 s.user = userAuthReq.User
284 perms = nil
285 authErr := errors.New("no auth passed yet")
286
287 switch userAuthReq.Method {
288 case "none":
289 if config.NoClientAuth {
290 authErr = nil
291 }
292 case "password":
293 if config.PasswordCallback == nil {
294 authErr = errors.New("ssh: password auth not configured")
295 break
296 }
297 payload := userAuthReq.Payload
298 if len(payload) < 1 || payload[0] != 0 {
299 return nil, parseError(msgUserAuthRequest)
300 }
301 payload = payload[1:]
302 password, payload, ok := parseString(payload)
303 if !ok || len(payload) > 0 {
304 return nil, parseError(msgUserAuthRequest)
305 }
306
307 perms, authErr = config.PasswordCallback(s, password)
308 case "keyboard-interactive":
309 if config.KeyboardInteractiveCallback == nil {
310 authErr = errors.New("ssh: keyboard-interactive auth not configubred")
311 break
312 }
313
314 prompter := &sshClientKeyboardInteractive{s}
315 perms, authErr = config.KeyboardInteractiveCallback(s, prompter.Challenge)
316 case "publickey":
317 if config.PublicKeyCallback == nil {
318 authErr = errors.New("ssh: publickey auth not configured")
319 break
320 }
321 payload := userAuthReq.Payload
322 if len(payload) < 1 {
323 return nil, parseError(msgUserAuthRequest)
324 }
325 isQuery := payload[0] == 0
326 payload = payload[1:]
327 algoBytes, payload, ok := parseString(payload)
328 if !ok {
329 return nil, parseError(msgUserAuthRequest)
330 }
331 algo := string(algoBytes)
332 if !isAcceptableAlgo(algo) {
333 authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo)
334 break
335 }
336
337 pubKeyData, payload, ok := parseString(payload)
338 if !ok {
339 return nil, parseError(msgUserAuthRequest)
340 }
341
342 pubKey, err := ParsePublicKey(pubKeyData)
343 if err != nil {
344 return nil, err
345 }
346
347 candidate, ok := cache.get(s.user, pubKeyData)
348 if !ok {
349 candidate.user = s.user
350 candidate.pubKeyData = pubKeyData
351 candidate.perms, candidate.result = config.PublicKeyCallback(s, pubKey)
352 if candidate.result == nil && candidate.perms != nil && candidate.perms.CriticalOptions != nil && candidate.perms.CriticalOptions[sourceAddressCriticalOption] != "" {
353 candidate.result = checkSourceAddress(
354 s.RemoteAddr(),
355 candidate.perms.CriticalOptions[sourceAddressCriticalOption])
356 }
357 cache.add(candidate)
358 }
359
360 if isQuery {
361 // The client can query if the given public key
362 // would be okay.
363 if len(payload) > 0 {
364 return nil, parseError(msgUserAuthRequest)
365 }
366
367 if candidate.result == nil {
368 okMsg := userAuthPubKeyOkMsg{
369 Algo: algo,
370 PubKey: pubKeyData,
371 }
372 if err = s.transport.writePacket(Marshal(&okMsg)); err != nil {
373 return nil, err
374 }
375 continue userAuthLoop
376 }
377 authErr = candidate.result
378 } else {
379 sig, payload, ok := parseSignature(payload)
380 if !ok || len(payload) > 0 {
381 return nil, parseError(msgUserAuthRequest)
382 }
383 // Ensure the public key algo and signature algo
384 // are supported. Compare the private key
385 // algorithm name that corresponds to algo with
386 // sig.Format. This is usually the same, but
387 // for certs, the names differ.
388 if !isAcceptableAlgo(sig.Format) {
389 break
390 }
391 signedData := buildDataSignedForAuth(sessionID, userAuthReq, algoBytes, pubKeyData)
392
393 if err := pubKey.Verify(signedData, sig); err != nil {
394 return nil, err
395 }
396
397 authErr = candidate.result
398 perms = candidate.perms
399 }
400 default:
401 authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method)
402 }
403
404 if config.AuthLogCallback != nil {
405 config.AuthLogCallback(s, userAuthReq.Method, authErr)
406 }
407
408 if authErr == nil {
409 break userAuthLoop
410 }
411
412 var failureMsg userAuthFailureMsg
413 if config.PasswordCallback != nil {
414 failureMsg.Methods = append(failureMsg.Methods, "password")
415 }
416 if config.PublicKeyCallback != nil {
417 failureMsg.Methods = append(failureMsg.Methods, "publickey")
418 }
419 if config.KeyboardInteractiveCallback != nil {
420 failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive")
421 }
422
423 if len(failureMsg.Methods) == 0 {
424 return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
425 }
426
427 if err := s.transport.writePacket(Marshal(&failureMsg)); err != nil {
428 return nil, err
429 }
430 }
431
432 if err := s.transport.writePacket([]byte{msgUserAuthSuccess}); err != nil {
433 return nil, err
434 }
435 return perms, nil
436}
437
438// sshClientKeyboardInteractive implements a ClientKeyboardInteractive by
439// asking the client on the other side of a ServerConn.
440type sshClientKeyboardInteractive struct {
441 *connection
442}
443
444func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
445 if len(questions) != len(echos) {
446 return nil, errors.New("ssh: echos and questions must have equal length")
447 }
448
449 var prompts []byte
450 for i := range questions {
451 prompts = appendString(prompts, questions[i])
452 prompts = appendBool(prompts, echos[i])
453 }
454
455 if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{
456 Instruction: instruction,
457 NumPrompts: uint32(len(questions)),
458 Prompts: prompts,
459 })); err != nil {
460 return nil, err
461 }
462
463 packet, err := c.transport.readPacket()
464 if err != nil {
465 return nil, err
466 }
467 if packet[0] != msgUserAuthInfoResponse {
468 return nil, unexpectedMessageError(msgUserAuthInfoResponse, packet[0])
469 }
470 packet = packet[1:]
471
472 n, packet, ok := parseUint32(packet)
473 if !ok || int(n) != len(questions) {
474 return nil, parseError(msgUserAuthInfoResponse)
475 }
476
477 for i := uint32(0); i < n; i++ {
478 ans, rest, ok := parseString(packet)
479 if !ok {
480 return nil, parseError(msgUserAuthInfoResponse)
481 }
482
483 answers = append(answers, string(ans))
484 packet = rest
485 }
486 if len(packet) != 0 {
487 return nil, errors.New("ssh: junk at end of message")
488 }
489
490 return answers, nil
491}
diff --git a/vendor/golang.org/x/crypto/ssh/session.go b/vendor/golang.org/x/crypto/ssh/session.go
deleted file mode 100644
index 17e2aa8..0000000
--- a/vendor/golang.org/x/crypto/ssh/session.go
+++ /dev/null
@@ -1,627 +0,0 @@
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
5package ssh
6
7// Session implements an interactive session described in
8// "RFC 4254, section 6".
9
10import (
11 "bytes"
12 "encoding/binary"
13 "errors"
14 "fmt"
15 "io"
16 "io/ioutil"
17 "sync"
18)
19
20type Signal string
21
22// POSIX signals as listed in RFC 4254 Section 6.10.
23const (
24 SIGABRT Signal = "ABRT"
25 SIGALRM Signal = "ALRM"
26 SIGFPE Signal = "FPE"
27 SIGHUP Signal = "HUP"
28 SIGILL Signal = "ILL"
29 SIGINT Signal = "INT"
30 SIGKILL Signal = "KILL"
31 SIGPIPE Signal = "PIPE"
32 SIGQUIT Signal = "QUIT"
33 SIGSEGV Signal = "SEGV"
34 SIGTERM Signal = "TERM"
35 SIGUSR1 Signal = "USR1"
36 SIGUSR2 Signal = "USR2"
37)
38
39var signals = map[Signal]int{
40 SIGABRT: 6,
41 SIGALRM: 14,
42 SIGFPE: 8,
43 SIGHUP: 1,
44 SIGILL: 4,
45 SIGINT: 2,
46 SIGKILL: 9,
47 SIGPIPE: 13,
48 SIGQUIT: 3,
49 SIGSEGV: 11,
50 SIGTERM: 15,
51}
52
53type TerminalModes map[uint8]uint32
54
55// POSIX terminal mode flags as listed in RFC 4254 Section 8.
56const (
57 tty_OP_END = 0
58 VINTR = 1
59 VQUIT = 2
60 VERASE = 3
61 VKILL = 4
62 VEOF = 5
63 VEOL = 6
64 VEOL2 = 7
65 VSTART = 8
66 VSTOP = 9
67 VSUSP = 10
68 VDSUSP = 11
69 VREPRINT = 12
70 VWERASE = 13
71 VLNEXT = 14
72 VFLUSH = 15
73 VSWTCH = 16
74 VSTATUS = 17
75 VDISCARD = 18
76 IGNPAR = 30
77 PARMRK = 31
78 INPCK = 32
79 ISTRIP = 33
80 INLCR = 34
81 IGNCR = 35
82 ICRNL = 36
83 IUCLC = 37
84 IXON = 38
85 IXANY = 39
86 IXOFF = 40
87 IMAXBEL = 41
88 ISIG = 50
89 ICANON = 51
90 XCASE = 52
91 ECHO = 53
92 ECHOE = 54
93 ECHOK = 55
94 ECHONL = 56
95 NOFLSH = 57
96 TOSTOP = 58
97 IEXTEN = 59
98 ECHOCTL = 60
99 ECHOKE = 61
100 PENDIN = 62
101 OPOST = 70
102 OLCUC = 71
103 ONLCR = 72
104 OCRNL = 73
105 ONOCR = 74
106 ONLRET = 75
107 CS7 = 90
108 CS8 = 91
109 PARENB = 92
110 PARODD = 93
111 TTY_OP_ISPEED = 128
112 TTY_OP_OSPEED = 129
113)
114
115// A Session represents a connection to a remote command or shell.
116type Session struct {
117 // Stdin specifies the remote process's standard input.
118 // If Stdin is nil, the remote process reads from an empty
119 // bytes.Buffer.
120 Stdin io.Reader
121
122 // Stdout and Stderr specify the remote process's standard
123 // output and error.
124 //
125 // If either is nil, Run connects the corresponding file
126 // descriptor to an instance of ioutil.Discard. There is a
127 // fixed amount of buffering that is shared for the two streams.
128 // If either blocks it may eventually cause the remote
129 // command to block.
130 Stdout io.Writer
131 Stderr io.Writer
132
133 ch Channel // the channel backing this session
134 started bool // true once Start, Run or Shell is invoked.
135 copyFuncs []func() error
136 errors chan error // one send per copyFunc
137
138 // true if pipe method is active
139 stdinpipe, stdoutpipe, stderrpipe bool
140
141 // stdinPipeWriter is non-nil if StdinPipe has not been called
142 // and Stdin was specified by the user; it is the write end of
143 // a pipe connecting Session.Stdin to the stdin channel.
144 stdinPipeWriter io.WriteCloser
145
146 exitStatus chan error
147}
148
149// SendRequest sends an out-of-band channel request on the SSH channel
150// underlying the session.
151func (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {
152 return s.ch.SendRequest(name, wantReply, payload)
153}
154
155func (s *Session) Close() error {
156 return s.ch.Close()
157}
158
159// RFC 4254 Section 6.4.
160type setenvRequest struct {
161 Name string
162 Value string
163}
164
165// Setenv sets an environment variable that will be applied to any
166// command executed by Shell or Run.
167func (s *Session) Setenv(name, value string) error {
168 msg := setenvRequest{
169 Name: name,
170 Value: value,
171 }
172 ok, err := s.ch.SendRequest("env", true, Marshal(&msg))
173 if err == nil && !ok {
174 err = errors.New("ssh: setenv failed")
175 }
176 return err
177}
178
179// RFC 4254 Section 6.2.
180type ptyRequestMsg struct {
181 Term string
182 Columns uint32
183 Rows uint32
184 Width uint32
185 Height uint32
186 Modelist string
187}
188
189// RequestPty requests the association of a pty with the session on the remote host.
190func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error {
191 var tm []byte
192 for k, v := range termmodes {
193 kv := struct {
194 Key byte
195 Val uint32
196 }{k, v}
197
198 tm = append(tm, Marshal(&kv)...)
199 }
200 tm = append(tm, tty_OP_END)
201 req := ptyRequestMsg{
202 Term: term,
203 Columns: uint32(w),
204 Rows: uint32(h),
205 Width: uint32(w * 8),
206 Height: uint32(h * 8),
207 Modelist: string(tm),
208 }
209 ok, err := s.ch.SendRequest("pty-req", true, Marshal(&req))
210 if err == nil && !ok {
211 err = errors.New("ssh: pty-req failed")
212 }
213 return err
214}
215
216// RFC 4254 Section 6.5.
217type subsystemRequestMsg struct {
218 Subsystem string
219}
220
221// RequestSubsystem requests the association of a subsystem with the session on the remote host.
222// A subsystem is a predefined command that runs in the background when the ssh session is initiated
223func (s *Session) RequestSubsystem(subsystem string) error {
224 msg := subsystemRequestMsg{
225 Subsystem: subsystem,
226 }
227 ok, err := s.ch.SendRequest("subsystem", true, Marshal(&msg))
228 if err == nil && !ok {
229 err = errors.New("ssh: subsystem request failed")
230 }
231 return err
232}
233
234// RFC 4254 Section 6.9.
235type signalMsg struct {
236 Signal string
237}
238
239// Signal sends the given signal to the remote process.
240// sig is one of the SIG* constants.
241func (s *Session) Signal(sig Signal) error {
242 msg := signalMsg{
243 Signal: string(sig),
244 }
245
246 _, err := s.ch.SendRequest("signal", false, Marshal(&msg))
247 return err
248}
249
250// RFC 4254 Section 6.5.
251type execMsg struct {
252 Command string
253}
254
255// Start runs cmd on the remote host. Typically, the remote
256// server passes cmd to the shell for interpretation.
257// A Session only accepts one call to Run, Start or Shell.
258func (s *Session) Start(cmd string) error {
259 if s.started {
260 return errors.New("ssh: session already started")
261 }
262 req := execMsg{
263 Command: cmd,
264 }
265
266 ok, err := s.ch.SendRequest("exec", true, Marshal(&req))
267 if err == nil && !ok {
268 err = fmt.Errorf("ssh: command %v failed", cmd)
269 }
270 if err != nil {
271 return err
272 }
273 return s.start()
274}
275
276// Run runs cmd on the remote host. Typically, the remote
277// server passes cmd to the shell for interpretation.
278// A Session only accepts one call to Run, Start, Shell, Output,
279// or CombinedOutput.
280//
281// The returned error is nil if the command runs, has no problems
282// copying stdin, stdout, and stderr, and exits with a zero exit
283// status.
284//
285// If the remote server does not send an exit status, an error of type
286// *ExitMissingError is returned. If the command completes
287// unsuccessfully or is interrupted by a signal, the error is of type
288// *ExitError. Other error types may be returned for I/O problems.
289func (s *Session) Run(cmd string) error {
290 err := s.Start(cmd)
291 if err != nil {
292 return err
293 }
294 return s.Wait()
295}
296
297// Output runs cmd on the remote host and returns its standard output.
298func (s *Session) Output(cmd string) ([]byte, error) {
299 if s.Stdout != nil {
300 return nil, errors.New("ssh: Stdout already set")
301 }
302 var b bytes.Buffer
303 s.Stdout = &b
304 err := s.Run(cmd)
305 return b.Bytes(), err
306}
307
308type singleWriter struct {
309 b bytes.Buffer
310 mu sync.Mutex
311}
312
313func (w *singleWriter) Write(p []byte) (int, error) {
314 w.mu.Lock()
315 defer w.mu.Unlock()
316 return w.b.Write(p)
317}
318
319// CombinedOutput runs cmd on the remote host and returns its combined
320// standard output and standard error.
321func (s *Session) CombinedOutput(cmd string) ([]byte, error) {
322 if s.Stdout != nil {
323 return nil, errors.New("ssh: Stdout already set")
324 }
325 if s.Stderr != nil {
326 return nil, errors.New("ssh: Stderr already set")
327 }
328 var b singleWriter
329 s.Stdout = &b
330 s.Stderr = &b
331 err := s.Run(cmd)
332 return b.b.Bytes(), err
333}
334
335// Shell starts a login shell on the remote host. A Session only
336// accepts one call to Run, Start, Shell, Output, or CombinedOutput.
337func (s *Session) Shell() error {
338 if s.started {
339 return errors.New("ssh: session already started")
340 }
341
342 ok, err := s.ch.SendRequest("shell", true, nil)
343 if err == nil && !ok {
344 return errors.New("ssh: could not start shell")
345 }
346 if err != nil {
347 return err
348 }
349 return s.start()
350}
351
352func (s *Session) start() error {
353 s.started = true
354
355 type F func(*Session)
356 for _, setupFd := range []F{(*Session).stdin, (*Session).stdout, (*Session).stderr} {
357 setupFd(s)
358 }
359
360 s.errors = make(chan error, len(s.copyFuncs))
361 for _, fn := range s.copyFuncs {
362 go func(fn func() error) {
363 s.errors <- fn()
364 }(fn)
365 }
366 return nil
367}
368
369// Wait waits for the remote command to exit.
370//
371// The returned error is nil if the command runs, has no problems
372// copying stdin, stdout, and stderr, and exits with a zero exit
373// status.
374//
375// If the remote server does not send an exit status, an error of type
376// *ExitMissingError is returned. If the command completes
377// unsuccessfully or is interrupted by a signal, the error is of type
378// *ExitError. Other error types may be returned for I/O problems.
379func (s *Session) Wait() error {
380 if !s.started {
381 return errors.New("ssh: session not started")
382 }
383 waitErr := <-s.exitStatus
384
385 if s.stdinPipeWriter != nil {
386 s.stdinPipeWriter.Close()
387 }
388 var copyError error
389 for _ = range s.copyFuncs {
390 if err := <-s.errors; err != nil && copyError == nil {
391 copyError = err
392 }
393 }
394 if waitErr != nil {
395 return waitErr
396 }
397 return copyError
398}
399
400func (s *Session) wait(reqs <-chan *Request) error {
401 wm := Waitmsg{status: -1}
402 // Wait for msg channel to be closed before returning.
403 for msg := range reqs {
404 switch msg.Type {
405 case "exit-status":
406 wm.status = int(binary.BigEndian.Uint32(msg.Payload))
407 case "exit-signal":
408 var sigval struct {
409 Signal string
410 CoreDumped bool
411 Error string
412 Lang string
413 }
414 if err := Unmarshal(msg.Payload, &sigval); err != nil {
415 return err
416 }
417
418 // Must sanitize strings?
419 wm.signal = sigval.Signal
420 wm.msg = sigval.Error
421 wm.lang = sigval.Lang
422 default:
423 // This handles keepalives and matches
424 // OpenSSH's behaviour.
425 if msg.WantReply {
426 msg.Reply(false, nil)
427 }
428 }
429 }
430 if wm.status == 0 {
431 return nil
432 }
433 if wm.status == -1 {
434 // exit-status was never sent from server
435 if wm.signal == "" {
436 // signal was not sent either. RFC 4254
437 // section 6.10 recommends against this
438 // behavior, but it is allowed, so we let
439 // clients handle it.
440 return &ExitMissingError{}
441 }
442 wm.status = 128
443 if _, ok := signals[Signal(wm.signal)]; ok {
444 wm.status += signals[Signal(wm.signal)]
445 }
446 }
447
448 return &ExitError{wm}
449}
450
451// ExitMissingError is returned if a session is torn down cleanly, but
452// the server sends no confirmation of the exit status.
453type ExitMissingError struct{}
454
455func (e *ExitMissingError) Error() string {
456 return "wait: remote command exited without exit status or exit signal"
457}
458
459func (s *Session) stdin() {
460 if s.stdinpipe {
461 return
462 }
463 var stdin io.Reader
464 if s.Stdin == nil {
465 stdin = new(bytes.Buffer)
466 } else {
467 r, w := io.Pipe()
468 go func() {
469 _, err := io.Copy(w, s.Stdin)
470 w.CloseWithError(err)
471 }()
472 stdin, s.stdinPipeWriter = r, w
473 }
474 s.copyFuncs = append(s.copyFuncs, func() error {
475 _, err := io.Copy(s.ch, stdin)
476 if err1 := s.ch.CloseWrite(); err == nil && err1 != io.EOF {
477 err = err1
478 }
479 return err
480 })
481}
482
483func (s *Session) stdout() {
484 if s.stdoutpipe {
485 return
486 }
487 if s.Stdout == nil {
488 s.Stdout = ioutil.Discard
489 }
490 s.copyFuncs = append(s.copyFuncs, func() error {
491 _, err := io.Copy(s.Stdout, s.ch)
492 return err
493 })
494}
495
496func (s *Session) stderr() {
497 if s.stderrpipe {
498 return
499 }
500 if s.Stderr == nil {
501 s.Stderr = ioutil.Discard
502 }
503 s.copyFuncs = append(s.copyFuncs, func() error {
504 _, err := io.Copy(s.Stderr, s.ch.Stderr())
505 return err
506 })
507}
508
509// sessionStdin reroutes Close to CloseWrite.
510type sessionStdin struct {
511 io.Writer
512 ch Channel
513}
514
515func (s *sessionStdin) Close() error {
516 return s.ch.CloseWrite()
517}
518
519// StdinPipe returns a pipe that will be connected to the
520// remote command's standard input when the command starts.
521func (s *Session) StdinPipe() (io.WriteCloser, error) {
522 if s.Stdin != nil {
523 return nil, errors.New("ssh: Stdin already set")
524 }
525 if s.started {
526 return nil, errors.New("ssh: StdinPipe after process started")
527 }
528 s.stdinpipe = true
529 return &sessionStdin{s.ch, s.ch}, nil
530}
531
532// StdoutPipe returns a pipe that will be connected to the
533// remote command's standard output when the command starts.
534// There is a fixed amount of buffering that is shared between
535// stdout and stderr streams. If the StdoutPipe reader is
536// not serviced fast enough it may eventually cause the
537// remote command to block.
538func (s *Session) StdoutPipe() (io.Reader, error) {
539 if s.Stdout != nil {
540 return nil, errors.New("ssh: Stdout already set")
541 }
542 if s.started {
543 return nil, errors.New("ssh: StdoutPipe after process started")
544 }
545 s.stdoutpipe = true
546 return s.ch, nil
547}
548
549// StderrPipe returns a pipe that will be connected to the
550// remote command's standard error when the command starts.
551// There is a fixed amount of buffering that is shared between
552// stdout and stderr streams. If the StderrPipe reader is
553// not serviced fast enough it may eventually cause the
554// remote command to block.
555func (s *Session) StderrPipe() (io.Reader, error) {
556 if s.Stderr != nil {
557 return nil, errors.New("ssh: Stderr already set")
558 }
559 if s.started {
560 return nil, errors.New("ssh: StderrPipe after process started")
561 }
562 s.stderrpipe = true
563 return s.ch.Stderr(), nil
564}
565
566// newSession returns a new interactive session on the remote host.
567func newSession(ch Channel, reqs <-chan *Request) (*Session, error) {
568 s := &Session{
569 ch: ch,
570 }
571 s.exitStatus = make(chan error, 1)
572 go func() {
573 s.exitStatus <- s.wait(reqs)
574 }()
575
576 return s, nil
577}
578
579// An ExitError reports unsuccessful completion of a remote command.
580type ExitError struct {
581 Waitmsg
582}
583
584func (e *ExitError) Error() string {
585 return e.Waitmsg.String()
586}
587
588// Waitmsg stores the information about an exited remote command
589// as reported by Wait.
590type Waitmsg struct {
591 status int
592 signal string
593 msg string
594 lang string
595}
596
597// ExitStatus returns the exit status of the remote command.
598func (w Waitmsg) ExitStatus() int {
599 return w.status
600}
601
602// Signal returns the exit signal of the remote command if
603// it was terminated violently.
604func (w Waitmsg) Signal() string {
605 return w.signal
606}
607
608// Msg returns the exit message given by the remote command
609func (w Waitmsg) Msg() string {
610 return w.msg
611}
612
613// Lang returns the language tag. See RFC 3066
614func (w Waitmsg) Lang() string {
615 return w.lang
616}
617
618func (w Waitmsg) String() string {
619 str := fmt.Sprintf("Process exited with status %v", w.status)
620 if w.signal != "" {
621 str += fmt.Sprintf(" from signal %v", w.signal)
622 }
623 if w.msg != "" {
624 str += fmt.Sprintf(". Reason was: %v", w.msg)
625 }
626 return str
627}
diff --git a/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go
deleted file mode 100644
index 6151241..0000000
--- a/vendor/golang.org/x/crypto/ssh/tcpip.go
+++ /dev/null
@@ -1,407 +0,0 @@
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
5package ssh
6
7import (
8 "errors"
9 "fmt"
10 "io"
11 "math/rand"
12 "net"
13 "strconv"
14 "strings"
15 "sync"
16 "time"
17)
18
19// Listen requests the remote peer open a listening socket on
20// addr. Incoming connections will be available by calling Accept on
21// the returned net.Listener. The listener must be serviced, or the
22// SSH connection may hang.
23func (c *Client) Listen(n, addr string) (net.Listener, error) {
24 laddr, err := net.ResolveTCPAddr(n, addr)
25 if err != nil {
26 return nil, err
27 }
28 return c.ListenTCP(laddr)
29}
30
31// Automatic port allocation is broken with OpenSSH before 6.0. See
32// also https://bugzilla.mindrot.org/show_bug.cgi?id=2017. In
33// particular, OpenSSH 5.9 sends a channelOpenMsg with port number 0,
34// rather than the actual port number. This means you can never open
35// two different listeners with auto allocated ports. We work around
36// this by trying explicit ports until we succeed.
37
38const openSSHPrefix = "OpenSSH_"
39
40var portRandomizer = rand.New(rand.NewSource(time.Now().UnixNano()))
41
42// isBrokenOpenSSHVersion returns true if the given version string
43// specifies a version of OpenSSH that is known to have a bug in port
44// forwarding.
45func isBrokenOpenSSHVersion(versionStr string) bool {
46 i := strings.Index(versionStr, openSSHPrefix)
47 if i < 0 {
48 return false
49 }
50 i += len(openSSHPrefix)
51 j := i
52 for ; j < len(versionStr); j++ {
53 if versionStr[j] < '0' || versionStr[j] > '9' {
54 break
55 }
56 }
57 version, _ := strconv.Atoi(versionStr[i:j])
58 return version < 6
59}
60
61// autoPortListenWorkaround simulates automatic port allocation by
62// trying random ports repeatedly.
63func (c *Client) autoPortListenWorkaround(laddr *net.TCPAddr) (net.Listener, error) {
64 var sshListener net.Listener
65 var err error
66 const tries = 10
67 for i := 0; i < tries; i++ {
68 addr := *laddr
69 addr.Port = 1024 + portRandomizer.Intn(60000)
70 sshListener, err = c.ListenTCP(&addr)
71 if err == nil {
72 laddr.Port = addr.Port
73 return sshListener, err
74 }
75 }
76 return nil, fmt.Errorf("ssh: listen on random port failed after %d tries: %v", tries, err)
77}
78
79// RFC 4254 7.1
80type channelForwardMsg struct {
81 addr string
82 rport uint32
83}
84
85// ListenTCP requests the remote peer open a listening socket
86// on laddr. Incoming connections will be available by calling
87// Accept on the returned net.Listener.
88func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
89 if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
90 return c.autoPortListenWorkaround(laddr)
91 }
92
93 m := channelForwardMsg{
94 laddr.IP.String(),
95 uint32(laddr.Port),
96 }
97 // send message
98 ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m))
99 if err != nil {
100 return nil, err
101 }
102 if !ok {
103 return nil, errors.New("ssh: tcpip-forward request denied by peer")
104 }
105
106 // If the original port was 0, then the remote side will
107 // supply a real port number in the response.
108 if laddr.Port == 0 {
109 var p struct {
110 Port uint32
111 }
112 if err := Unmarshal(resp, &p); err != nil {
113 return nil, err
114 }
115 laddr.Port = int(p.Port)
116 }
117
118 // Register this forward, using the port number we obtained.
119 ch := c.forwards.add(*laddr)
120
121 return &tcpListener{laddr, c, ch}, nil
122}
123
124// forwardList stores a mapping between remote
125// forward requests and the tcpListeners.
126type forwardList struct {
127 sync.Mutex
128 entries []forwardEntry
129}
130
131// forwardEntry represents an established mapping of a laddr on a
132// remote ssh server to a channel connected to a tcpListener.
133type forwardEntry struct {
134 laddr net.TCPAddr
135 c chan forward
136}
137
138// forward represents an incoming forwarded tcpip connection. The
139// arguments to add/remove/lookup should be address as specified in
140// the original forward-request.
141type forward struct {
142 newCh NewChannel // the ssh client channel underlying this forward
143 raddr *net.TCPAddr // the raddr of the incoming connection
144}
145
146func (l *forwardList) add(addr net.TCPAddr) chan forward {
147 l.Lock()
148 defer l.Unlock()
149 f := forwardEntry{
150 addr,
151 make(chan forward, 1),
152 }
153 l.entries = append(l.entries, f)
154 return f.c
155}
156
157// See RFC 4254, section 7.2
158type forwardedTCPPayload struct {
159 Addr string
160 Port uint32
161 OriginAddr string
162 OriginPort uint32
163}
164
165// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr.
166func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) {
167 if port == 0 || port > 65535 {
168 return nil, fmt.Errorf("ssh: port number out of range: %d", port)
169 }
170 ip := net.ParseIP(string(addr))
171 if ip == nil {
172 return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr)
173 }
174 return &net.TCPAddr{IP: ip, Port: int(port)}, nil
175}
176
177func (l *forwardList) handleChannels(in <-chan NewChannel) {
178 for ch := range in {
179 var payload forwardedTCPPayload
180 if err := Unmarshal(ch.ExtraData(), &payload); err != nil {
181 ch.Reject(ConnectionFailed, "could not parse forwarded-tcpip payload: "+err.Error())
182 continue
183 }
184
185 // RFC 4254 section 7.2 specifies that incoming
186 // addresses should list the address, in string
187 // format. It is implied that this should be an IP
188 // address, as it would be impossible to connect to it
189 // otherwise.
190 laddr, err := parseTCPAddr(payload.Addr, payload.Port)
191 if err != nil {
192 ch.Reject(ConnectionFailed, err.Error())
193 continue
194 }
195 raddr, err := parseTCPAddr(payload.OriginAddr, payload.OriginPort)
196 if err != nil {
197 ch.Reject(ConnectionFailed, err.Error())
198 continue
199 }
200
201 if ok := l.forward(*laddr, *raddr, ch); !ok {
202 // Section 7.2, implementations MUST reject spurious incoming
203 // connections.
204 ch.Reject(Prohibited, "no forward for address")
205 continue
206 }
207 }
208}
209
210// remove removes the forward entry, and the channel feeding its
211// listener.
212func (l *forwardList) remove(addr net.TCPAddr) {
213 l.Lock()
214 defer l.Unlock()
215 for i, f := range l.entries {
216 if addr.IP.Equal(f.laddr.IP) && addr.Port == f.laddr.Port {
217 l.entries = append(l.entries[:i], l.entries[i+1:]...)
218 close(f.c)
219 return
220 }
221 }
222}
223
224// closeAll closes and clears all forwards.
225func (l *forwardList) closeAll() {
226 l.Lock()
227 defer l.Unlock()
228 for _, f := range l.entries {
229 close(f.c)
230 }
231 l.entries = nil
232}
233
234func (l *forwardList) forward(laddr, raddr net.TCPAddr, ch NewChannel) bool {
235 l.Lock()
236 defer l.Unlock()
237 for _, f := range l.entries {
238 if laddr.IP.Equal(f.laddr.IP) && laddr.Port == f.laddr.Port {
239 f.c <- forward{ch, &raddr}
240 return true
241 }
242 }
243 return false
244}
245
246type tcpListener struct {
247 laddr *net.TCPAddr
248
249 conn *Client
250 in <-chan forward
251}
252
253// Accept waits for and returns the next connection to the listener.
254func (l *tcpListener) Accept() (net.Conn, error) {
255 s, ok := <-l.in
256 if !ok {
257 return nil, io.EOF
258 }
259 ch, incoming, err := s.newCh.Accept()
260 if err != nil {
261 return nil, err
262 }
263 go DiscardRequests(incoming)
264
265 return &tcpChanConn{
266 Channel: ch,
267 laddr: l.laddr,
268 raddr: s.raddr,
269 }, nil
270}
271
272// Close closes the listener.
273func (l *tcpListener) Close() error {
274 m := channelForwardMsg{
275 l.laddr.IP.String(),
276 uint32(l.laddr.Port),
277 }
278
279 // this also closes the listener.
280 l.conn.forwards.remove(*l.laddr)
281 ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m))
282 if err == nil && !ok {
283 err = errors.New("ssh: cancel-tcpip-forward failed")
284 }
285 return err
286}
287
288// Addr returns the listener's network address.
289func (l *tcpListener) Addr() net.Addr {
290 return l.laddr
291}
292
293// Dial initiates a connection to the addr from the remote host.
294// The resulting connection has a zero LocalAddr() and RemoteAddr().
295func (c *Client) Dial(n, addr string) (net.Conn, error) {
296 // Parse the address into host and numeric port.
297 host, portString, err := net.SplitHostPort(addr)
298 if err != nil {
299 return nil, err
300 }
301 port, err := strconv.ParseUint(portString, 10, 16)
302 if err != nil {
303 return nil, err
304 }
305 // Use a zero address for local and remote address.
306 zeroAddr := &net.TCPAddr{
307 IP: net.IPv4zero,
308 Port: 0,
309 }
310 ch, err := c.dial(net.IPv4zero.String(), 0, host, int(port))
311 if err != nil {
312 return nil, err
313 }
314 return &tcpChanConn{
315 Channel: ch,
316 laddr: zeroAddr,
317 raddr: zeroAddr,
318 }, nil
319}
320
321// DialTCP connects to the remote address raddr on the network net,
322// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used
323// as the local address for the connection.
324func (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error) {
325 if laddr == nil {
326 laddr = &net.TCPAddr{
327 IP: net.IPv4zero,
328 Port: 0,
329 }
330 }
331 ch, err := c.dial(laddr.IP.String(), laddr.Port, raddr.IP.String(), raddr.Port)
332 if err != nil {
333 return nil, err
334 }
335 return &tcpChanConn{
336 Channel: ch,
337 laddr: laddr,
338 raddr: raddr,
339 }, nil
340}
341
342// RFC 4254 7.2
343type channelOpenDirectMsg struct {
344 raddr string
345 rport uint32
346 laddr string
347 lport uint32
348}
349
350func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel, error) {
351 msg := channelOpenDirectMsg{
352 raddr: raddr,
353 rport: uint32(rport),
354 laddr: laddr,
355 lport: uint32(lport),
356 }
357 ch, in, err := c.OpenChannel("direct-tcpip", Marshal(&msg))
358 if err != nil {
359 return nil, err
360 }
361 go DiscardRequests(in)
362 return ch, err
363}
364
365type tcpChan struct {
366 Channel // the backing channel
367}
368
369// tcpChanConn fulfills the net.Conn interface without
370// the tcpChan having to hold laddr or raddr directly.
371type tcpChanConn struct {
372 Channel
373 laddr, raddr net.Addr
374}
375
376// LocalAddr returns the local network address.
377func (t *tcpChanConn) LocalAddr() net.Addr {
378 return t.laddr
379}
380
381// RemoteAddr returns the remote network address.
382func (t *tcpChanConn) RemoteAddr() net.Addr {
383 return t.raddr
384}
385
386// SetDeadline sets the read and write deadlines associated
387// with the connection.
388func (t *tcpChanConn) SetDeadline(deadline time.Time) error {
389 if err := t.SetReadDeadline(deadline); err != nil {
390 return err
391 }
392 return t.SetWriteDeadline(deadline)
393}
394
395// SetReadDeadline sets the read deadline.
396// A zero value for t means Read will not time out.
397// After the deadline, the error from Read will implement net.Error
398// with Timeout() == true.
399func (t *tcpChanConn) SetReadDeadline(deadline time.Time) error {
400 return errors.New("ssh: tcpChan: deadline not supported")
401}
402
403// SetWriteDeadline exists to satisfy the net.Conn interface
404// but is not implemented by this type. It always returns an error.
405func (t *tcpChanConn) SetWriteDeadline(deadline time.Time) error {
406 return errors.New("ssh: tcpChan: deadline not supported")
407}
diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go
deleted file mode 100644
index f9780e0..0000000
--- a/vendor/golang.org/x/crypto/ssh/transport.go
+++ /dev/null
@@ -1,375 +0,0 @@
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
5package ssh
6
7import (
8 "bufio"
9 "errors"
10 "io"
11 "log"
12)
13
14// debugTransport if set, will print packet types as they go over the
15// wire. No message decoding is done, to minimize the impact on timing.
16const debugTransport = false
17
18const (
19 gcmCipherID = "aes128-gcm@openssh.com"
20 aes128cbcID = "aes128-cbc"
21 tripledescbcID = "3des-cbc"
22)
23
24// packetConn represents a transport that implements packet based
25// operations.
26type packetConn interface {
27 // Encrypt and send a packet of data to the remote peer.
28 writePacket(packet []byte) error
29
30 // Read a packet from the connection. The read is blocking,
31 // i.e. if error is nil, then the returned byte slice is
32 // always non-empty.
33 readPacket() ([]byte, error)
34
35 // Close closes the write-side of the connection.
36 Close() error
37}
38
39// transport is the keyingTransport that implements the SSH packet
40// protocol.
41type transport struct {
42 reader connectionState
43 writer connectionState
44
45 bufReader *bufio.Reader
46 bufWriter *bufio.Writer
47 rand io.Reader
48 isClient bool
49 io.Closer
50}
51
52// packetCipher represents a combination of SSH encryption/MAC
53// protocol. A single instance should be used for one direction only.
54type packetCipher interface {
55 // writePacket encrypts the packet and writes it to w. The
56 // contents of the packet are generally scrambled.
57 writePacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error
58
59 // readPacket reads and decrypts a packet of data. The
60 // returned packet may be overwritten by future calls of
61 // readPacket.
62 readPacket(seqnum uint32, r io.Reader) ([]byte, error)
63}
64
65// connectionState represents one side (read or write) of the
66// connection. This is necessary because each direction has its own
67// keys, and can even have its own algorithms
68type connectionState struct {
69 packetCipher
70 seqNum uint32
71 dir direction
72 pendingKeyChange chan packetCipher
73}
74
75// prepareKeyChange sets up key material for a keychange. The key changes in
76// both directions are triggered by reading and writing a msgNewKey packet
77// respectively.
78func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {
79 if ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult); err != nil {
80 return err
81 } else {
82 t.reader.pendingKeyChange <- ciph
83 }
84
85 if ciph, err := newPacketCipher(t.writer.dir, algs.w, kexResult); err != nil {
86 return err
87 } else {
88 t.writer.pendingKeyChange <- ciph
89 }
90
91 return nil
92}
93
94func (t *transport) printPacket(p []byte, write bool) {
95 if len(p) == 0 {
96 return
97 }
98 who := "server"
99 if t.isClient {
100 who = "client"
101 }
102 what := "read"
103 if write {
104 what = "write"
105 }
106
107 log.Println(what, who, p[0])
108}
109
110// Read and decrypt next packet.
111func (t *transport) readPacket() (p []byte, err error) {
112 for {
113 p, err = t.reader.readPacket(t.bufReader)
114 if err != nil {
115 break
116 }
117 if len(p) == 0 || (p[0] != msgIgnore && p[0] != msgDebug) {
118 break
119 }
120 }
121 if debugTransport {
122 t.printPacket(p, false)
123 }
124
125 return p, err
126}
127
128func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
129 packet, err := s.packetCipher.readPacket(s.seqNum, r)
130 s.seqNum++
131 if err == nil && len(packet) == 0 {
132 err = errors.New("ssh: zero length packet")
133 }
134
135 if len(packet) > 0 {
136 switch packet[0] {
137 case msgNewKeys:
138 select {
139 case cipher := <-s.pendingKeyChange:
140 s.packetCipher = cipher
141 default:
142 return nil, errors.New("ssh: got bogus newkeys message.")
143 }
144
145 case msgDisconnect:
146 // Transform a disconnect message into an
147 // error. Since this is lowest level at which
148 // we interpret message types, doing it here
149 // ensures that we don't have to handle it
150 // elsewhere.
151 var msg disconnectMsg
152 if err := Unmarshal(packet, &msg); err != nil {
153 return nil, err
154 }
155 return nil, &msg
156 }
157 }
158
159 // The packet may point to an internal buffer, so copy the
160 // packet out here.
161 fresh := make([]byte, len(packet))
162 copy(fresh, packet)
163
164 return fresh, err
165}
166
167func (t *transport) writePacket(packet []byte) error {
168 if debugTransport {
169 t.printPacket(packet, true)
170 }
171 return t.writer.writePacket(t.bufWriter, t.rand, packet)
172}
173
174func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error {
175 changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
176
177 err := s.packetCipher.writePacket(s.seqNum, w, rand, packet)
178 if err != nil {
179 return err
180 }
181 if err = w.Flush(); err != nil {
182 return err
183 }
184 s.seqNum++
185 if changeKeys {
186 select {
187 case cipher := <-s.pendingKeyChange:
188 s.packetCipher = cipher
189 default:
190 panic("ssh: no key material for msgNewKeys")
191 }
192 }
193 return err
194}
195
196func newTransport(rwc io.ReadWriteCloser, rand io.Reader, isClient bool) *transport {
197 t := &transport{
198 bufReader: bufio.NewReader(rwc),
199 bufWriter: bufio.NewWriter(rwc),
200 rand: rand,
201 reader: connectionState{
202 packetCipher: &streamPacketCipher{cipher: noneCipher{}},
203 pendingKeyChange: make(chan packetCipher, 1),
204 },
205 writer: connectionState{
206 packetCipher: &streamPacketCipher{cipher: noneCipher{}},
207 pendingKeyChange: make(chan packetCipher, 1),
208 },
209 Closer: rwc,
210 }
211 t.isClient = isClient
212
213 if isClient {
214 t.reader.dir = serverKeys
215 t.writer.dir = clientKeys
216 } else {
217 t.reader.dir = clientKeys
218 t.writer.dir = serverKeys
219 }
220
221 return t
222}
223
224type direction struct {
225 ivTag []byte
226 keyTag []byte
227 macKeyTag []byte
228}
229
230var (
231 serverKeys = direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}}
232 clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}
233)
234
235// generateKeys generates key material for IV, MAC and encryption.
236func generateKeys(d direction, algs directionAlgorithms, kex *kexResult) (iv, key, macKey []byte) {
237 cipherMode := cipherModes[algs.Cipher]
238 macMode := macModes[algs.MAC]
239
240 iv = make([]byte, cipherMode.ivSize)
241 key = make([]byte, cipherMode.keySize)
242 macKey = make([]byte, macMode.keySize)
243
244 generateKeyMaterial(iv, d.ivTag, kex)
245 generateKeyMaterial(key, d.keyTag, kex)
246 generateKeyMaterial(macKey, d.macKeyTag, kex)
247 return
248}
249
250// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
251// described in RFC 4253, section 6.4. direction should either be serverKeys
252// (to setup server->client keys) or clientKeys (for client->server keys).
253func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
254 iv, key, macKey := generateKeys(d, algs, kex)
255
256 if algs.Cipher == gcmCipherID {
257 return newGCMCipher(iv, key, macKey)
258 }
259
260 if algs.Cipher == aes128cbcID {
261 return newAESCBCCipher(iv, key, macKey, algs)
262 }
263
264 if algs.Cipher == tripledescbcID {
265 return newTripleDESCBCCipher(iv, key, macKey, algs)
266 }
267
268 c := &streamPacketCipher{
269 mac: macModes[algs.MAC].new(macKey),
270 etm: macModes[algs.MAC].etm,
271 }
272 c.macResult = make([]byte, c.mac.Size())
273
274 var err error
275 c.cipher, err = cipherModes[algs.Cipher].createStream(key, iv)
276 if err != nil {
277 return nil, err
278 }
279
280 return c, nil
281}
282
283// generateKeyMaterial fills out with key material generated from tag, K, H
284// and sessionId, as specified in RFC 4253, section 7.2.
285func generateKeyMaterial(out, tag []byte, r *kexResult) {
286 var digestsSoFar []byte
287
288 h := r.Hash.New()
289 for len(out) > 0 {
290 h.Reset()
291 h.Write(r.K)
292 h.Write(r.H)
293
294 if len(digestsSoFar) == 0 {
295 h.Write(tag)
296 h.Write(r.SessionID)
297 } else {
298 h.Write(digestsSoFar)
299 }
300
301 digest := h.Sum(nil)
302 n := copy(out, digest)
303 out = out[n:]
304 if len(out) > 0 {
305 digestsSoFar = append(digestsSoFar, digest...)
306 }
307 }
308}
309
310const packageVersion = "SSH-2.0-Go"
311
312// Sends and receives a version line. The versionLine string should
313// be US ASCII, start with "SSH-2.0-", and should not include a
314// newline. exchangeVersions returns the other side's version line.
315func exchangeVersions(rw io.ReadWriter, versionLine []byte) (them []byte, err error) {
316 // Contrary to the RFC, we do not ignore lines that don't
317 // start with "SSH-2.0-" to make the library usable with
318 // nonconforming servers.
319 for _, c := range versionLine {
320 // The spec disallows non US-ASCII chars, and
321 // specifically forbids null chars.
322 if c < 32 {
323 return nil, errors.New("ssh: junk character in version line")
324 }
325 }
326 if _, err = rw.Write(append(versionLine, '\r', '\n')); err != nil {
327 return
328 }
329
330 them, err = readVersion(rw)
331 return them, err
332}
333
334// maxVersionStringBytes is the maximum number of bytes that we'll
335// accept as a version string. RFC 4253 section 4.2 limits this at 255
336// chars
337const maxVersionStringBytes = 255
338
339// Read version string as specified by RFC 4253, section 4.2.
340func readVersion(r io.Reader) ([]byte, error) {
341 versionString := make([]byte, 0, 64)
342 var ok bool
343 var buf [1]byte
344
345 for len(versionString) < maxVersionStringBytes {
346 _, err := io.ReadFull(r, buf[:])
347 if err != nil {
348 return nil, err
349 }
350 // The RFC says that the version should be terminated with \r\n
351 // but several SSH servers actually only send a \n.
352 if buf[0] == '\n' {
353 ok = true
354 break
355 }
356
357 // non ASCII chars are disallowed, but we are lenient,
358 // since Go doesn't use null-terminated strings.
359
360 // The RFC allows a comment after a space, however,
361 // all of it (version and comments) goes into the
362 // session hash.
363 versionString = append(versionString, buf[0])
364 }
365
366 if !ok {
367 return nil, errors.New("ssh: overflow reading version string")
368 }
369
370 // There might be a '\r' on the end which we should remove.
371 if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' {
372 versionString = versionString[:len(versionString)-1]
373 }
374 return versionString, nil
375}