Browse Source

vendor: regenerate with latest "dep"

Better pruning

Signed-off-by: Gyuho Lee <gyuhox@gmail.com>
Gyuho Lee 7 years ago
parent
commit
d598af104d
42 changed files with 10881 additions and 1535 deletions
  1. 20 0
      vendor/github.com/coreos/go-semver/example.go
  2. 51 0
      vendor/github.com/cpuguy83/go-md2man/md2man.go
  3. 51 0
      vendor/github.com/gogo/protobuf/protoc-gen-gogo/doc.go
  4. 57 0
      vendor/github.com/gogo/protobuf/protoc-gen-gogo/main.go
  5. 160 0
      vendor/github.com/golang/groupcache/byteview.go
  6. 489 0
      vendor/github.com/golang/groupcache/groupcache.go
  7. 227 0
      vendor/github.com/golang/groupcache/http.go
  8. 71 0
      vendor/github.com/golang/groupcache/peers.go
  9. 322 0
      vendor/github.com/golang/groupcache/sinks.go
  10. 0 201
      vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/LICENSE
  11. 0 201
      vendor/github.com/prometheus/client_model/ruby/LICENSE
  12. 0 1133
      vendor/github.com/spf13/cobra/cobra/cmd/licenses.go
  13. 97 0
      vendor/golang.org/x/crypto/ssh/buffer.go
  14. 519 0
      vendor/golang.org/x/crypto/ssh/certs.go
  15. 633 0
      vendor/golang.org/x/crypto/ssh/channel.go
  16. 629 0
      vendor/golang.org/x/crypto/ssh/cipher.go
  17. 257 0
      vendor/golang.org/x/crypto/ssh/client.go
  18. 486 0
      vendor/golang.org/x/crypto/ssh/client_auth.go
  19. 373 0
      vendor/golang.org/x/crypto/ssh/common.go
  20. 143 0
      vendor/golang.org/x/crypto/ssh/connection.go
  21. 21 0
      vendor/golang.org/x/crypto/ssh/doc.go
  22. 640 0
      vendor/golang.org/x/crypto/ssh/handshake.go
  23. 540 0
      vendor/golang.org/x/crypto/ssh/kex.go
  24. 1031 0
      vendor/golang.org/x/crypto/ssh/keys.go
  25. 61 0
      vendor/golang.org/x/crypto/ssh/mac.go
  26. 758 0
      vendor/golang.org/x/crypto/ssh/messages.go
  27. 330 0
      vendor/golang.org/x/crypto/ssh/mux.go
  28. 563 0
      vendor/golang.org/x/crypto/ssh/server.go
  29. 647 0
      vendor/golang.org/x/crypto/ssh/session.go
  30. 115 0
      vendor/golang.org/x/crypto/ssh/streamlocal.go
  31. 465 0
      vendor/golang.org/x/crypto/ssh/tcpip.go
  32. 375 0
      vendor/golang.org/x/crypto/ssh/transport.go
  33. 13 0
      vendor/golang.org/x/text/doc.go
  34. 292 0
      vendor/golang.org/x/text/gen.go
  35. 52 0
      vendor/golang.org/x/text/internal/gen.go
  36. 51 0
      vendor/golang.org/x/text/internal/internal.go
  37. 67 0
      vendor/golang.org/x/text/internal/match.go
  38. 117 0
      vendor/golang.org/x/text/internal/tables.go
  39. 6 0
      vendor/golang.org/x/text/secure/doc.go
  40. 8 0
      vendor/golang.org/x/text/unicode/doc.go
  41. 123 0
      vendor/google.golang.org/genproto/regen.go
  42. 21 0
      vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/doc.go

+ 20 - 0
vendor/github.com/coreos/go-semver/example.go

@@ -0,0 +1,20 @@
+package main
+
+import (
+	"fmt"
+	"github.com/coreos/go-semver/semver"
+	"os"
+)
+
+func main() {
+	vA, err := semver.NewVersion(os.Args[1])
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+	vB, err := semver.NewVersion(os.Args[2])
+	if err != nil {
+		fmt.Println(err.Error())
+	}
+
+	fmt.Printf("%s < %s == %t\n", vA, vB, vA.LessThan(*vB))
+}

+ 51 - 0
vendor/github.com/cpuguy83/go-md2man/md2man.go

@@ -0,0 +1,51 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+
+	"github.com/cpuguy83/go-md2man/md2man"
+)
+
+var inFilePath = flag.String("in", "", "Path to file to be processed (default: stdin)")
+var outFilePath = flag.String("out", "", "Path to output processed file (default: stdout)")
+
+func main() {
+	var err error
+	flag.Parse()
+
+	inFile := os.Stdin
+	if *inFilePath != "" {
+		inFile, err = os.Open(*inFilePath)
+		if err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+	}
+	defer inFile.Close()
+
+	doc, err := ioutil.ReadAll(inFile)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	out := md2man.Render(doc)
+
+	outFile := os.Stdout
+	if *outFilePath != "" {
+		outFile, err = os.Create(*outFilePath)
+		if err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+		defer outFile.Close()
+	}
+	_, err = outFile.Write(out)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+}

+ 51 - 0
vendor/github.com/gogo/protobuf/protoc-gen-gogo/doc.go

@@ -0,0 +1,51 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+	A plugin for the Google protocol buffer compiler to generate Go code.
+	Run it by building this program and putting it in your path with the name
+		protoc-gen-gogo
+	That word 'gogo' at the end becomes part of the option string set for the
+	protocol compiler, so once the protocol compiler (protoc) is installed
+	you can run
+		protoc --gogo_out=output_directory input_directory/file.proto
+	to generate Go bindings for the protocol defined by file.proto.
+	With that input, the output will be written to
+		output_directory/go_package/file.pb.go
+
+	The generated code is documented in the package comment for
+	the library.
+
+	See the README and documentation for protocol buffers to learn more:
+		https://developers.google.com/protocol-buffers/
+
+*/
+package documentation

+ 57 - 0
vendor/github.com/gogo/protobuf/protoc-gen-gogo/main.go

@@ -0,0 +1,57 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate
+// Go code.  Run it by building this program and putting it in your path with
+// the name
+// 	protoc-gen-gogo
+// That word 'gogo' at the end becomes part of the option string set for the
+// protocol compiler, so once the protocol compiler (protoc) is installed
+// you can run
+// 	protoc --gogo_out=output_directory input_directory/file.proto
+// to generate Go bindings for the protocol defined by file.proto.
+// With that input, the output will be written to
+// 	output_directory/file.pb.go
+//
+// The generated code is documented in the package comment for
+// the library.
+//
+// See the README and documentation for protocol buffers to learn more:
+// 	https://developers.google.com/protocol-buffers/
+package main
+
+import (
+	"github.com/gogo/protobuf/vanity/command"
+)
+
+func main() {
+	command.Write(command.Generate(command.Read()))
+}

+ 160 - 0
vendor/github.com/golang/groupcache/byteview.go

@@ -0,0 +1,160 @@
+/*
+Copyright 2012 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package groupcache
+
+import (
+	"bytes"
+	"errors"
+	"io"
+	"strings"
+)
+
+// A ByteView holds an immutable view of bytes.
+// Internally it wraps either a []byte or a string,
+// but that detail is invisible to callers.
+//
+// A ByteView is meant to be used as a value type, not
+// a pointer (like a time.Time).
+type ByteView struct {
+	// If b is non-nil, b is used, else s is used.
+	b []byte
+	s string
+}
+
+// Len returns the view's length.
+func (v ByteView) Len() int {
+	if v.b != nil {
+		return len(v.b)
+	}
+	return len(v.s)
+}
+
+// ByteSlice returns a copy of the data as a byte slice.
+func (v ByteView) ByteSlice() []byte {
+	if v.b != nil {
+		return cloneBytes(v.b)
+	}
+	return []byte(v.s)
+}
+
+// String returns the data as a string, making a copy if necessary.
+func (v ByteView) String() string {
+	if v.b != nil {
+		return string(v.b)
+	}
+	return v.s
+}
+
+// At returns the byte at index i.
+func (v ByteView) At(i int) byte {
+	if v.b != nil {
+		return v.b[i]
+	}
+	return v.s[i]
+}
+
+// Slice slices the view between the provided from and to indices.
+func (v ByteView) Slice(from, to int) ByteView {
+	if v.b != nil {
+		return ByteView{b: v.b[from:to]}
+	}
+	return ByteView{s: v.s[from:to]}
+}
+
+// SliceFrom slices the view from the provided index until the end.
+func (v ByteView) SliceFrom(from int) ByteView {
+	if v.b != nil {
+		return ByteView{b: v.b[from:]}
+	}
+	return ByteView{s: v.s[from:]}
+}
+
+// Copy copies b into dest and returns the number of bytes copied.
+func (v ByteView) Copy(dest []byte) int {
+	if v.b != nil {
+		return copy(dest, v.b)
+	}
+	return copy(dest, v.s)
+}
+
+// Equal returns whether the bytes in b are the same as the bytes in
+// b2.
+func (v ByteView) Equal(b2 ByteView) bool {
+	if b2.b == nil {
+		return v.EqualString(b2.s)
+	}
+	return v.EqualBytes(b2.b)
+}
+
+// EqualString returns whether the bytes in b are the same as the bytes
+// in s.
+func (v ByteView) EqualString(s string) bool {
+	if v.b == nil {
+		return v.s == s
+	}
+	l := v.Len()
+	if len(s) != l {
+		return false
+	}
+	for i, bi := range v.b {
+		if bi != s[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// EqualBytes returns whether the bytes in b are the same as the bytes
+// in b2.
+func (v ByteView) EqualBytes(b2 []byte) bool {
+	if v.b != nil {
+		return bytes.Equal(v.b, b2)
+	}
+	l := v.Len()
+	if len(b2) != l {
+		return false
+	}
+	for i, bi := range b2 {
+		if bi != v.s[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// Reader returns an io.ReadSeeker for the bytes in v.
+func (v ByteView) Reader() io.ReadSeeker {
+	if v.b != nil {
+		return bytes.NewReader(v.b)
+	}
+	return strings.NewReader(v.s)
+}
+
+// ReadAt implements io.ReaderAt on the bytes in v.
+func (v ByteView) ReadAt(p []byte, off int64) (n int, err error) {
+	if off < 0 {
+		return 0, errors.New("view: invalid offset")
+	}
+	if off >= int64(v.Len()) {
+		return 0, io.EOF
+	}
+	n = v.SliceFrom(int(off)).Copy(p)
+	if n < len(p) {
+		err = io.EOF
+	}
+	return
+}

+ 489 - 0
vendor/github.com/golang/groupcache/groupcache.go

@@ -0,0 +1,489 @@
+/*
+Copyright 2012 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package groupcache provides a data loading mechanism with caching
+// and de-duplication that works across a set of peer processes.
+//
+// Each data Get first consults its local cache, otherwise delegates
+// to the requested key's canonical owner, which then checks its cache
+// or finally gets the data.  In the common case, many concurrent
+// cache misses across a set of peers for the same key result in just
+// one cache fill.
+package groupcache
+
+import (
+	"errors"
+	"math/rand"
+	"strconv"
+	"sync"
+	"sync/atomic"
+
+	pb "github.com/golang/groupcache/groupcachepb"
+	"github.com/golang/groupcache/lru"
+	"github.com/golang/groupcache/singleflight"
+)
+
+// A Getter loads data for a key.
+type Getter interface {
+	// Get returns the value identified by key, populating dest.
+	//
+	// The returned data must be unversioned. That is, key must
+	// uniquely describe the loaded data, without an implicit
+	// current time, and without relying on cache expiration
+	// mechanisms.
+	Get(ctx Context, key string, dest Sink) error
+}
+
+// A GetterFunc implements Getter with a function.
+type GetterFunc func(ctx Context, key string, dest Sink) error
+
+func (f GetterFunc) Get(ctx Context, key string, dest Sink) error {
+	return f(ctx, key, dest)
+}
+
+var (
+	mu     sync.RWMutex
+	groups = make(map[string]*Group)
+
+	initPeerServerOnce sync.Once
+	initPeerServer     func()
+)
+
+// GetGroup returns the named group previously created with NewGroup, or
+// nil if there's no such group.
+func GetGroup(name string) *Group {
+	mu.RLock()
+	g := groups[name]
+	mu.RUnlock()
+	return g
+}
+
+// NewGroup creates a coordinated group-aware Getter from a Getter.
+//
+// The returned Getter tries (but does not guarantee) to run only one
+// Get call at once for a given key across an entire set of peer
+// processes. Concurrent callers both in the local process and in
+// other processes receive copies of the answer once the original Get
+// completes.
+//
+// The group name must be unique for each getter.
+func NewGroup(name string, cacheBytes int64, getter Getter) *Group {
+	return newGroup(name, cacheBytes, getter, nil)
+}
+
+// If peers is nil, the peerPicker is called via a sync.Once to initialize it.
+func newGroup(name string, cacheBytes int64, getter Getter, peers PeerPicker) *Group {
+	if getter == nil {
+		panic("nil Getter")
+	}
+	mu.Lock()
+	defer mu.Unlock()
+	initPeerServerOnce.Do(callInitPeerServer)
+	if _, dup := groups[name]; dup {
+		panic("duplicate registration of group " + name)
+	}
+	g := &Group{
+		name:       name,
+		getter:     getter,
+		peers:      peers,
+		cacheBytes: cacheBytes,
+		loadGroup:  &singleflight.Group{},
+	}
+	if fn := newGroupHook; fn != nil {
+		fn(g)
+	}
+	groups[name] = g
+	return g
+}
+
+// newGroupHook, if non-nil, is called right after a new group is created.
+var newGroupHook func(*Group)
+
+// RegisterNewGroupHook registers a hook that is run each time
+// a group is created.
+func RegisterNewGroupHook(fn func(*Group)) {
+	if newGroupHook != nil {
+		panic("RegisterNewGroupHook called more than once")
+	}
+	newGroupHook = fn
+}
+
+// RegisterServerStart registers a hook that is run when the first
+// group is created.
+func RegisterServerStart(fn func()) {
+	if initPeerServer != nil {
+		panic("RegisterServerStart called more than once")
+	}
+	initPeerServer = fn
+}
+
+func callInitPeerServer() {
+	if initPeerServer != nil {
+		initPeerServer()
+	}
+}
+
+// A Group is a cache namespace and associated data loaded spread over
+// a group of 1 or more machines.
+type Group struct {
+	name       string
+	getter     Getter
+	peersOnce  sync.Once
+	peers      PeerPicker
+	cacheBytes int64 // limit for sum of mainCache and hotCache size
+
+	// mainCache is a cache of the keys for which this process
+	// (amongst its peers) is authoritative. That is, this cache
+	// contains keys which consistent hash on to this process's
+	// peer number.
+	mainCache cache
+
+	// hotCache contains keys/values for which this peer is not
+	// authoritative (otherwise they would be in mainCache), but
+	// are popular enough to warrant mirroring in this process to
+	// avoid going over the network to fetch from a peer.  Having
+	// a hotCache avoids network hotspotting, where a peer's
+	// network card could become the bottleneck on a popular key.
+	// This cache is used sparingly to maximize the total number
+	// of key/value pairs that can be stored globally.
+	hotCache cache
+
+	// loadGroup ensures that each key is only fetched once
+	// (either locally or remotely), regardless of the number of
+	// concurrent callers.
+	loadGroup flightGroup
+
+	// Stats are statistics on the group.
+	Stats Stats
+}
+
+// flightGroup is defined as an interface which flightgroup.Group
+// satisfies.  We define this so that we may test with an alternate
+// implementation.
+type flightGroup interface {
+	// Done is called when Do is done.
+	Do(key string, fn func() (interface{}, error)) (interface{}, error)
+}
+
+// Stats are per-group statistics.
+type Stats struct {
+	Gets           AtomicInt // any Get request, including from peers
+	CacheHits      AtomicInt // either cache was good
+	PeerLoads      AtomicInt // either remote load or remote cache hit (not an error)
+	PeerErrors     AtomicInt
+	Loads          AtomicInt // (gets - cacheHits)
+	LoadsDeduped   AtomicInt // after singleflight
+	LocalLoads     AtomicInt // total good local loads
+	LocalLoadErrs  AtomicInt // total bad local loads
+	ServerRequests AtomicInt // gets that came over the network from peers
+}
+
+// Name returns the name of the group.
+func (g *Group) Name() string {
+	return g.name
+}
+
+func (g *Group) initPeers() {
+	if g.peers == nil {
+		g.peers = getPeers()
+	}
+}
+
+func (g *Group) Get(ctx Context, key string, dest Sink) error {
+	g.peersOnce.Do(g.initPeers)
+	g.Stats.Gets.Add(1)
+	if dest == nil {
+		return errors.New("groupcache: nil dest Sink")
+	}
+	value, cacheHit := g.lookupCache(key)
+
+	if cacheHit {
+		g.Stats.CacheHits.Add(1)
+		return setSinkView(dest, value)
+	}
+
+	// Optimization to avoid double unmarshalling or copying: keep
+	// track of whether the dest was already populated. One caller
+	// (if local) will set this; the losers will not. The common
+	// case will likely be one caller.
+	destPopulated := false
+	value, destPopulated, err := g.load(ctx, key, dest)
+	if err != nil {
+		return err
+	}
+	if destPopulated {
+		return nil
+	}
+	return setSinkView(dest, value)
+}
+
+// load loads key either by invoking the getter locally or by sending it to another machine.
+func (g *Group) load(ctx Context, key string, dest Sink) (value ByteView, destPopulated bool, err error) {
+	g.Stats.Loads.Add(1)
+	viewi, err := g.loadGroup.Do(key, func() (interface{}, error) {
+		// Check the cache again because singleflight can only dedup calls
+		// that overlap concurrently.  It's possible for 2 concurrent
+		// requests to miss the cache, resulting in 2 load() calls.  An
+		// unfortunate goroutine scheduling would result in this callback
+		// being run twice, serially.  If we don't check the cache again,
+		// cache.nbytes would be incremented below even though there will
+		// be only one entry for this key.
+		//
+		// Consider the following serialized event ordering for two
+		// goroutines in which this callback gets called twice for hte
+		// same key:
+		// 1: Get("key")
+		// 2: Get("key")
+		// 1: lookupCache("key")
+		// 2: lookupCache("key")
+		// 1: load("key")
+		// 2: load("key")
+		// 1: loadGroup.Do("key", fn)
+		// 1: fn()
+		// 2: loadGroup.Do("key", fn)
+		// 2: fn()
+		if value, cacheHit := g.lookupCache(key); cacheHit {
+			g.Stats.CacheHits.Add(1)
+			return value, nil
+		}
+		g.Stats.LoadsDeduped.Add(1)
+		var value ByteView
+		var err error
+		if peer, ok := g.peers.PickPeer(key); ok {
+			value, err = g.getFromPeer(ctx, peer, key)
+			if err == nil {
+				g.Stats.PeerLoads.Add(1)
+				return value, nil
+			}
+			g.Stats.PeerErrors.Add(1)
+			// TODO(bradfitz): log the peer's error? keep
+			// log of the past few for /groupcachez?  It's
+			// probably boring (normal task movement), so not
+			// worth logging I imagine.
+		}
+		value, err = g.getLocally(ctx, key, dest)
+		if err != nil {
+			g.Stats.LocalLoadErrs.Add(1)
+			return nil, err
+		}
+		g.Stats.LocalLoads.Add(1)
+		destPopulated = true // only one caller of load gets this return value
+		g.populateCache(key, value, &g.mainCache)
+		return value, nil
+	})
+	if err == nil {
+		value = viewi.(ByteView)
+	}
+	return
+}
+
+func (g *Group) getLocally(ctx Context, key string, dest Sink) (ByteView, error) {
+	err := g.getter.Get(ctx, key, dest)
+	if err != nil {
+		return ByteView{}, err
+	}
+	return dest.view()
+}
+
+func (g *Group) getFromPeer(ctx Context, peer ProtoGetter, key string) (ByteView, error) {
+	req := &pb.GetRequest{
+		Group: &g.name,
+		Key:   &key,
+	}
+	res := &pb.GetResponse{}
+	err := peer.Get(ctx, req, res)
+	if err != nil {
+		return ByteView{}, err
+	}
+	value := ByteView{b: res.Value}
+	// TODO(bradfitz): use res.MinuteQps or something smart to
+	// conditionally populate hotCache.  For now just do it some
+	// percentage of the time.
+	if rand.Intn(10) == 0 {
+		g.populateCache(key, value, &g.hotCache)
+	}
+	return value, nil
+}
+
+func (g *Group) lookupCache(key string) (value ByteView, ok bool) {
+	if g.cacheBytes <= 0 {
+		return
+	}
+	value, ok = g.mainCache.get(key)
+	if ok {
+		return
+	}
+	value, ok = g.hotCache.get(key)
+	return
+}
+
+func (g *Group) populateCache(key string, value ByteView, cache *cache) {
+	if g.cacheBytes <= 0 {
+		return
+	}
+	cache.add(key, value)
+
+	// Evict items from cache(s) if necessary.
+	for {
+		mainBytes := g.mainCache.bytes()
+		hotBytes := g.hotCache.bytes()
+		if mainBytes+hotBytes <= g.cacheBytes {
+			return
+		}
+
+		// TODO(bradfitz): this is good-enough-for-now logic.
+		// It should be something based on measurements and/or
+		// respecting the costs of different resources.
+		victim := &g.mainCache
+		if hotBytes > mainBytes/8 {
+			victim = &g.hotCache
+		}
+		victim.removeOldest()
+	}
+}
+
+// CacheType represents a type of cache.
+type CacheType int
+
+const (
+	// The MainCache is the cache for items that this peer is the
+	// owner for.
+	MainCache CacheType = iota + 1
+
+	// The HotCache is the cache for items that seem popular
+	// enough to replicate to this node, even though it's not the
+	// owner.
+	HotCache
+)
+
+// CacheStats returns stats about the provided cache within the group.
+func (g *Group) CacheStats(which CacheType) CacheStats {
+	switch which {
+	case MainCache:
+		return g.mainCache.stats()
+	case HotCache:
+		return g.hotCache.stats()
+	default:
+		return CacheStats{}
+	}
+}
+
+// cache is a wrapper around an *lru.Cache that adds synchronization,
+// makes values always be ByteView, and counts the size of all keys and
+// values.
+type cache struct {
+	mu         sync.RWMutex
+	nbytes     int64 // of all keys and values
+	lru        *lru.Cache
+	nhit, nget int64
+	nevict     int64 // number of evictions
+}
+
+func (c *cache) stats() CacheStats {
+	c.mu.RLock()
+	defer c.mu.RUnlock()
+	return CacheStats{
+		Bytes:     c.nbytes,
+		Items:     c.itemsLocked(),
+		Gets:      c.nget,
+		Hits:      c.nhit,
+		Evictions: c.nevict,
+	}
+}
+
+func (c *cache) add(key string, value ByteView) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.lru == nil {
+		c.lru = &lru.Cache{
+			OnEvicted: func(key lru.Key, value interface{}) {
+				val := value.(ByteView)
+				c.nbytes -= int64(len(key.(string))) + int64(val.Len())
+				c.nevict++
+			},
+		}
+	}
+	c.lru.Add(key, value)
+	c.nbytes += int64(len(key)) + int64(value.Len())
+}
+
+func (c *cache) get(key string) (value ByteView, ok bool) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	c.nget++
+	if c.lru == nil {
+		return
+	}
+	vi, ok := c.lru.Get(key)
+	if !ok {
+		return
+	}
+	c.nhit++
+	return vi.(ByteView), true
+}
+
+func (c *cache) removeOldest() {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.lru != nil {
+		c.lru.RemoveOldest()
+	}
+}
+
+func (c *cache) bytes() int64 {
+	c.mu.RLock()
+	defer c.mu.RUnlock()
+	return c.nbytes
+}
+
+func (c *cache) items() int64 {
+	c.mu.RLock()
+	defer c.mu.RUnlock()
+	return c.itemsLocked()
+}
+
+func (c *cache) itemsLocked() int64 {
+	if c.lru == nil {
+		return 0
+	}
+	return int64(c.lru.Len())
+}
+
+// An AtomicInt is an int64 to be accessed atomically.
+type AtomicInt int64
+
+// Add atomically adds n to i.
+func (i *AtomicInt) Add(n int64) {
+	atomic.AddInt64((*int64)(i), n)
+}
+
+// Get atomically gets the value of i.
+func (i *AtomicInt) Get() int64 {
+	return atomic.LoadInt64((*int64)(i))
+}
+
+func (i *AtomicInt) String() string {
+	return strconv.FormatInt(i.Get(), 10)
+}
+
+// CacheStats are returned by stats accessors on Group.
+type CacheStats struct {
+	Bytes     int64
+	Items     int64
+	Gets      int64
+	Hits      int64
+	Evictions int64
+}

+ 227 - 0
vendor/github.com/golang/groupcache/http.go

@@ -0,0 +1,227 @@
+/*
+Copyright 2013 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package groupcache
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+	"sync"
+
+	"github.com/golang/groupcache/consistenthash"
+	pb "github.com/golang/groupcache/groupcachepb"
+	"github.com/golang/protobuf/proto"
+)
+
+const defaultBasePath = "/_groupcache/"
+
+const defaultReplicas = 50
+
+// HTTPPool implements PeerPicker for a pool of HTTP peers.
+type HTTPPool struct {
+	// Context optionally specifies a context for the server to use when it
+	// receives a request.
+	// If nil, the server uses a nil Context.
+	Context func(*http.Request) Context
+
+	// Transport optionally specifies an http.RoundTripper for the client
+	// to use when it makes a request.
+	// If nil, the client uses http.DefaultTransport.
+	Transport func(Context) http.RoundTripper
+
+	// this peer's base URL, e.g. "https://example.net:8000"
+	self string
+
+	// opts specifies the options.
+	opts HTTPPoolOptions
+
+	mu          sync.Mutex // guards peers and httpGetters
+	peers       *consistenthash.Map
+	httpGetters map[string]*httpGetter // keyed by e.g. "http://10.0.0.2:8008"
+}
+
+// HTTPPoolOptions are the configurations of a HTTPPool.
+type HTTPPoolOptions struct {
+	// BasePath specifies the HTTP path that will serve groupcache requests.
+	// If blank, it defaults to "/_groupcache/".
+	BasePath string
+
+	// Replicas specifies the number of key replicas on the consistent hash.
+	// If blank, it defaults to 50.
+	Replicas int
+
+	// HashFn specifies the hash function of the consistent hash.
+	// If blank, it defaults to crc32.ChecksumIEEE.
+	HashFn consistenthash.Hash
+}
+
+// NewHTTPPool initializes an HTTP pool of peers, and registers itself as a PeerPicker.
+// For convenience, it also registers itself as an http.Handler with http.DefaultServeMux.
+// The self argument be a valid base URL that points to the current server,
+// for example "http://example.net:8000".
+func NewHTTPPool(self string) *HTTPPool {
+	p := NewHTTPPoolOpts(self, nil)
+	http.Handle(p.opts.BasePath, p)
+	return p
+}
+
+var httpPoolMade bool
+
+// NewHTTPPoolOpts initializes an HTTP pool of peers with the given options.
+// Unlike NewHTTPPool, this function does not register the created pool as an HTTP handler.
+// The returned *HTTPPool implements http.Handler and must be registered using http.Handle.
+func NewHTTPPoolOpts(self string, o *HTTPPoolOptions) *HTTPPool {
+	if httpPoolMade {
+		panic("groupcache: NewHTTPPool must be called only once")
+	}
+	httpPoolMade = true
+
+	p := &HTTPPool{
+		self:        self,
+		httpGetters: make(map[string]*httpGetter),
+	}
+	if o != nil {
+		p.opts = *o
+	}
+	if p.opts.BasePath == "" {
+		p.opts.BasePath = defaultBasePath
+	}
+	if p.opts.Replicas == 0 {
+		p.opts.Replicas = defaultReplicas
+	}
+	p.peers = consistenthash.New(p.opts.Replicas, p.opts.HashFn)
+
+	RegisterPeerPicker(func() PeerPicker { return p })
+	return p
+}
+
+// Set updates the pool's list of peers.
+// Each peer value should be a valid base URL,
+// for example "http://example.net:8000".
+func (p *HTTPPool) Set(peers ...string) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	p.peers = consistenthash.New(p.opts.Replicas, p.opts.HashFn)
+	p.peers.Add(peers...)
+	p.httpGetters = make(map[string]*httpGetter, len(peers))
+	for _, peer := range peers {
+		p.httpGetters[peer] = &httpGetter{transport: p.Transport, baseURL: peer + p.opts.BasePath}
+	}
+}
+
+func (p *HTTPPool) PickPeer(key string) (ProtoGetter, bool) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	if p.peers.IsEmpty() {
+		return nil, false
+	}
+	if peer := p.peers.Get(key); peer != p.self {
+		return p.httpGetters[peer], true
+	}
+	return nil, false
+}
+
+func (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	// Parse request.
+	if !strings.HasPrefix(r.URL.Path, p.opts.BasePath) {
+		panic("HTTPPool serving unexpected path: " + r.URL.Path)
+	}
+	parts := strings.SplitN(r.URL.Path[len(p.opts.BasePath):], "/", 2)
+	if len(parts) != 2 {
+		http.Error(w, "bad request", http.StatusBadRequest)
+		return
+	}
+	groupName := parts[0]
+	key := parts[1]
+
+	// Fetch the value for this group/key.
+	group := GetGroup(groupName)
+	if group == nil {
+		http.Error(w, "no such group: "+groupName, http.StatusNotFound)
+		return
+	}
+	var ctx Context
+	if p.Context != nil {
+		ctx = p.Context(r)
+	}
+
+	group.Stats.ServerRequests.Add(1)
+	var value []byte
+	err := group.Get(ctx, key, AllocatingByteSliceSink(&value))
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	// Write the value to the response body as a proto message.
+	body, err := proto.Marshal(&pb.GetResponse{Value: value})
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	w.Header().Set("Content-Type", "application/x-protobuf")
+	w.Write(body)
+}
+
+type httpGetter struct {
+	transport func(Context) http.RoundTripper
+	baseURL   string
+}
+
+var bufferPool = sync.Pool{
+	New: func() interface{} { return new(bytes.Buffer) },
+}
+
+func (h *httpGetter) Get(context Context, in *pb.GetRequest, out *pb.GetResponse) error {
+	u := fmt.Sprintf(
+		"%v%v/%v",
+		h.baseURL,
+		url.QueryEscape(in.GetGroup()),
+		url.QueryEscape(in.GetKey()),
+	)
+	req, err := http.NewRequest("GET", u, nil)
+	if err != nil {
+		return err
+	}
+	tr := http.DefaultTransport
+	if h.transport != nil {
+		tr = h.transport(context)
+	}
+	res, err := tr.RoundTrip(req)
+	if err != nil {
+		return err
+	}
+	defer res.Body.Close()
+	if res.StatusCode != http.StatusOK {
+		return fmt.Errorf("server returned: %v", res.Status)
+	}
+	b := bufferPool.Get().(*bytes.Buffer)
+	b.Reset()
+	defer bufferPool.Put(b)
+	_, err = io.Copy(b, res.Body)
+	if err != nil {
+		return fmt.Errorf("reading response body: %v", err)
+	}
+	err = proto.Unmarshal(b.Bytes(), out)
+	if err != nil {
+		return fmt.Errorf("decoding response body: %v", err)
+	}
+	return nil
+}

+ 71 - 0
vendor/github.com/golang/groupcache/peers.go

@@ -0,0 +1,71 @@
+/*
+Copyright 2012 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// peers.go defines how processes find and communicate with their peers.
+
+package groupcache
+
+import (
+	pb "github.com/golang/groupcache/groupcachepb"
+)
+
+// Context is an opaque value passed through calls to the
+// ProtoGetter. It may be nil if your ProtoGetter implementation does
+// not require a context.
+type Context interface{}
+
+// ProtoGetter is the interface that must be implemented by a peer.
+type ProtoGetter interface {
+	Get(context Context, in *pb.GetRequest, out *pb.GetResponse) error
+}
+
+// PeerPicker is the interface that must be implemented to locate
+// the peer that owns a specific key.
+type PeerPicker interface {
+	// PickPeer returns the peer that owns the specific key
+	// and true to indicate that a remote peer was nominated.
+	// It returns nil, false if the key owner is the current peer.
+	PickPeer(key string) (peer ProtoGetter, ok bool)
+}
+
+// NoPeers is an implementation of PeerPicker that never finds a peer.
+type NoPeers struct{}
+
+func (NoPeers) PickPeer(key string) (peer ProtoGetter, ok bool) { return }
+
+var (
+	portPicker func() PeerPicker
+)
+
+// RegisterPeerPicker registers the peer initialization function.
+// It is called once, when the first group is created.
+func RegisterPeerPicker(fn func() PeerPicker) {
+	if portPicker != nil {
+		panic("RegisterPeerPicker called more than once")
+	}
+	portPicker = fn
+}
+
+func getPeers() PeerPicker {
+	if portPicker == nil {
+		return NoPeers{}
+	}
+	pk := portPicker()
+	if pk == nil {
+		pk = NoPeers{}
+	}
+	return pk
+}

+ 322 - 0
vendor/github.com/golang/groupcache/sinks.go

@@ -0,0 +1,322 @@
+/*
+Copyright 2012 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package groupcache
+
+import (
+	"errors"
+
+	"github.com/golang/protobuf/proto"
+)
+
+// A Sink receives data from a Get call.
+//
+// Implementation of Getter must call exactly one of the Set methods
+// on success.
+type Sink interface {
+	// SetString sets the value to s.
+	SetString(s string) error
+
+	// SetBytes sets the value to the contents of v.
+	// The caller retains ownership of v.
+	SetBytes(v []byte) error
+
+	// SetProto sets the value to the encoded version of m.
+	// The caller retains ownership of m.
+	SetProto(m proto.Message) error
+
+	// view returns a frozen view of the bytes for caching.
+	view() (ByteView, error)
+}
+
+func cloneBytes(b []byte) []byte {
+	c := make([]byte, len(b))
+	copy(c, b)
+	return c
+}
+
+func setSinkView(s Sink, v ByteView) error {
+	// A viewSetter is a Sink that can also receive its value from
+	// a ByteView. This is a fast path to minimize copies when the
+	// item was already cached locally in memory (where it's
+	// cached as a ByteView)
+	type viewSetter interface {
+		setView(v ByteView) error
+	}
+	if vs, ok := s.(viewSetter); ok {
+		return vs.setView(v)
+	}
+	if v.b != nil {
+		return s.SetBytes(v.b)
+	}
+	return s.SetString(v.s)
+}
+
+// StringSink returns a Sink that populates the provided string pointer.
+func StringSink(sp *string) Sink {
+	return &stringSink{sp: sp}
+}
+
+type stringSink struct {
+	sp *string
+	v  ByteView
+	// TODO(bradfitz): track whether any Sets were called.
+}
+
+func (s *stringSink) view() (ByteView, error) {
+	// TODO(bradfitz): return an error if no Set was called
+	return s.v, nil
+}
+
+func (s *stringSink) SetString(v string) error {
+	s.v.b = nil
+	s.v.s = v
+	*s.sp = v
+	return nil
+}
+
+func (s *stringSink) SetBytes(v []byte) error {
+	return s.SetString(string(v))
+}
+
+func (s *stringSink) SetProto(m proto.Message) error {
+	b, err := proto.Marshal(m)
+	if err != nil {
+		return err
+	}
+	s.v.b = b
+	*s.sp = string(b)
+	return nil
+}
+
+// ByteViewSink returns a Sink that populates a ByteView.
+func ByteViewSink(dst *ByteView) Sink {
+	if dst == nil {
+		panic("nil dst")
+	}
+	return &byteViewSink{dst: dst}
+}
+
+type byteViewSink struct {
+	dst *ByteView
+
+	// if this code ever ends up tracking that at least one set*
+	// method was called, don't make it an error to call set
+	// methods multiple times. Lorry's payload.go does that, and
+	// it makes sense. The comment at the top of this file about
+	// "exactly one of the Set methods" is overly strict. We
+	// really care about at least once (in a handler), but if
+	// multiple handlers fail (or multiple functions in a program
+	// using a Sink), it's okay to re-use the same one.
+}
+
+func (s *byteViewSink) setView(v ByteView) error {
+	*s.dst = v
+	return nil
+}
+
+func (s *byteViewSink) view() (ByteView, error) {
+	return *s.dst, nil
+}
+
+func (s *byteViewSink) SetProto(m proto.Message) error {
+	b, err := proto.Marshal(m)
+	if err != nil {
+		return err
+	}
+	*s.dst = ByteView{b: b}
+	return nil
+}
+
+func (s *byteViewSink) SetBytes(b []byte) error {
+	*s.dst = ByteView{b: cloneBytes(b)}
+	return nil
+}
+
+func (s *byteViewSink) SetString(v string) error {
+	*s.dst = ByteView{s: v}
+	return nil
+}
+
+// ProtoSink returns a sink that unmarshals binary proto values into m.
+func ProtoSink(m proto.Message) Sink {
+	return &protoSink{
+		dst: m,
+	}
+}
+
+type protoSink struct {
+	dst proto.Message // authorative value
+	typ string
+
+	v ByteView // encoded
+}
+
+func (s *protoSink) view() (ByteView, error) {
+	return s.v, nil
+}
+
+func (s *protoSink) SetBytes(b []byte) error {
+	err := proto.Unmarshal(b, s.dst)
+	if err != nil {
+		return err
+	}
+	s.v.b = cloneBytes(b)
+	s.v.s = ""
+	return nil
+}
+
+func (s *protoSink) SetString(v string) error {
+	b := []byte(v)
+	err := proto.Unmarshal(b, s.dst)
+	if err != nil {
+		return err
+	}
+	s.v.b = b
+	s.v.s = ""
+	return nil
+}
+
+func (s *protoSink) SetProto(m proto.Message) error {
+	b, err := proto.Marshal(m)
+	if err != nil {
+		return err
+	}
+	// TODO(bradfitz): optimize for same-task case more and write
+	// right through? would need to document ownership rules at
+	// the same time. but then we could just assign *dst = *m
+	// here. This works for now:
+	err = proto.Unmarshal(b, s.dst)
+	if err != nil {
+		return err
+	}
+	s.v.b = b
+	s.v.s = ""
+	return nil
+}
+
+// AllocatingByteSliceSink returns a Sink that allocates
+// a byte slice to hold the received value and assigns
+// it to *dst. The memory is not retained by groupcache.
+func AllocatingByteSliceSink(dst *[]byte) Sink {
+	return &allocBytesSink{dst: dst}
+}
+
+type allocBytesSink struct {
+	dst *[]byte
+	v   ByteView
+}
+
+func (s *allocBytesSink) view() (ByteView, error) {
+	return s.v, nil
+}
+
+func (s *allocBytesSink) setView(v ByteView) error {
+	if v.b != nil {
+		*s.dst = cloneBytes(v.b)
+	} else {
+		*s.dst = []byte(v.s)
+	}
+	s.v = v
+	return nil
+}
+
+func (s *allocBytesSink) SetProto(m proto.Message) error {
+	b, err := proto.Marshal(m)
+	if err != nil {
+		return err
+	}
+	return s.setBytesOwned(b)
+}
+
+func (s *allocBytesSink) SetBytes(b []byte) error {
+	return s.setBytesOwned(cloneBytes(b))
+}
+
+func (s *allocBytesSink) setBytesOwned(b []byte) error {
+	if s.dst == nil {
+		return errors.New("nil AllocatingByteSliceSink *[]byte dst")
+	}
+	*s.dst = cloneBytes(b) // another copy, protecting the read-only s.v.b view
+	s.v.b = b
+	s.v.s = ""
+	return nil
+}
+
+func (s *allocBytesSink) SetString(v string) error {
+	if s.dst == nil {
+		return errors.New("nil AllocatingByteSliceSink *[]byte dst")
+	}
+	*s.dst = []byte(v)
+	s.v.b = nil
+	s.v.s = v
+	return nil
+}
+
+// TruncatingByteSliceSink returns a Sink that writes up to len(*dst)
+// bytes to *dst. If more bytes are available, they're silently
+// truncated. If fewer bytes are available than len(*dst), *dst
+// is shrunk to fit the number of bytes available.
+func TruncatingByteSliceSink(dst *[]byte) Sink {
+	return &truncBytesSink{dst: dst}
+}
+
+type truncBytesSink struct {
+	dst *[]byte
+	v   ByteView
+}
+
+func (s *truncBytesSink) view() (ByteView, error) {
+	return s.v, nil
+}
+
+func (s *truncBytesSink) SetProto(m proto.Message) error {
+	b, err := proto.Marshal(m)
+	if err != nil {
+		return err
+	}
+	return s.setBytesOwned(b)
+}
+
+func (s *truncBytesSink) SetBytes(b []byte) error {
+	return s.setBytesOwned(cloneBytes(b))
+}
+
+func (s *truncBytesSink) setBytesOwned(b []byte) error {
+	if s.dst == nil {
+		return errors.New("nil TruncatingByteSliceSink *[]byte dst")
+	}
+	n := copy(*s.dst, b)
+	if n < len(*s.dst) {
+		*s.dst = (*s.dst)[:n]
+	}
+	s.v.b = b
+	s.v.s = ""
+	return nil
+}
+
+func (s *truncBytesSink) SetString(v string) error {
+	if s.dst == nil {
+		return errors.New("nil TruncatingByteSliceSink *[]byte dst")
+	}
+	n := copy(*s.dst, v)
+	if n < len(*s.dst) {
+		*s.dst = (*s.dst)[:n]
+	}
+	s.v.b = nil
+	s.v.s = v
+	return nil
+}

+ 0 - 201
vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/LICENSE

@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

+ 0 - 201
vendor/github.com/prometheus/client_model/ruby/LICENSE

@@ -1,201 +0,0 @@
-                              Apache License
-                        Version 2.0, January 2004
-                     http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-   "License" shall mean the terms and conditions for use, reproduction,
-   and distribution as defined by Sections 1 through 9 of this document.
-
-   "Licensor" shall mean the copyright owner or entity authorized by
-   the copyright owner that is granting the License.
-
-   "Legal Entity" shall mean the union of the acting entity and all
-   other entities that control, are controlled by, or are under common
-   control with that entity. For the purposes of this definition,
-   "control" means (i) the power, direct or indirect, to cause the
-   direction or management of such entity, whether by contract or
-   otherwise, or (ii) ownership of fifty percent (50%) or more of the
-   outstanding shares, or (iii) beneficial ownership of such entity.
-
-   "You" (or "Your") shall mean an individual or Legal Entity
-   exercising permissions granted by this License.
-
-   "Source" form shall mean the preferred form for making modifications,
-   including but not limited to software source code, documentation
-   source, and configuration files.
-
-   "Object" form shall mean any form resulting from mechanical
-   transformation or translation of a Source form, including but
-   not limited to compiled object code, generated documentation,
-   and conversions to other media types.
-
-   "Work" shall mean the work of authorship, whether in Source or
-   Object form, made available under the License, as indicated by a
-   copyright notice that is included in or attached to the work
-   (an example is provided in the Appendix below).
-
-   "Derivative Works" shall mean any work, whether in Source or Object
-   form, that is based on (or derived from) the Work and for which the
-   editorial revisions, annotations, elaborations, or other modifications
-   represent, as a whole, an original work of authorship. For the purposes
-   of this License, Derivative Works shall not include works that remain
-   separable from, or merely link (or bind by name) to the interfaces of,
-   the Work and Derivative Works thereof.
-
-   "Contribution" shall mean any work of authorship, including
-   the original version of the Work and any modifications or additions
-   to that Work or Derivative Works thereof, that is intentionally
-   submitted to Licensor for inclusion in the Work by the copyright owner
-   or by an individual or Legal Entity authorized to submit on behalf of
-   the copyright owner. For the purposes of this definition, "submitted"
-   means any form of electronic, verbal, or written communication sent
-   to the Licensor or its representatives, including but not limited to
-   communication on electronic mailing lists, source code control systems,
-   and issue tracking systems that are managed by, or on behalf of, the
-   Licensor for the purpose of discussing and improving the Work, but
-   excluding communication that is conspicuously marked or otherwise
-   designated in writing by the copyright owner as "Not a Contribution."
-
-   "Contributor" shall mean Licensor and any individual or Legal Entity
-   on behalf of whom a Contribution has been received by Licensor and
-   subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   copyright license to reproduce, prepare Derivative Works of,
-   publicly display, publicly perform, sublicense, and distribute the
-   Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   (except as stated in this section) patent license to make, have made,
-   use, offer to sell, sell, import, and otherwise transfer the Work,
-   where such license applies only to those patent claims licensable
-   by such Contributor that are necessarily infringed by their
-   Contribution(s) alone or by combination of their Contribution(s)
-   with the Work to which such Contribution(s) was submitted. If You
-   institute patent litigation against any entity (including a
-   cross-claim or counterclaim in a lawsuit) alleging that the Work
-   or a Contribution incorporated within the Work constitutes direct
-   or contributory patent infringement, then any patent licenses
-   granted to You under this License for that Work shall terminate
-   as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
-   Work or Derivative Works thereof in any medium, with or without
-   modifications, and in Source or Object form, provided that You
-   meet the following conditions:
-
-   (a) You must give any other recipients of the Work or
-       Derivative Works a copy of this License; and
-
-   (b) You must cause any modified files to carry prominent notices
-       stating that You changed the files; and
-
-   (c) You must retain, in the Source form of any Derivative Works
-       that You distribute, all copyright, patent, trademark, and
-       attribution notices from the Source form of the Work,
-       excluding those notices that do not pertain to any part of
-       the Derivative Works; and
-
-   (d) If the Work includes a "NOTICE" text file as part of its
-       distribution, then any Derivative Works that You distribute must
-       include a readable copy of the attribution notices contained
-       within such NOTICE file, excluding those notices that do not
-       pertain to any part of the Derivative Works, in at least one
-       of the following places: within a NOTICE text file distributed
-       as part of the Derivative Works; within the Source form or
-       documentation, if provided along with the Derivative Works; or,
-       within a display generated by the Derivative Works, if and
-       wherever such third-party notices normally appear. The contents
-       of the NOTICE file are for informational purposes only and
-       do not modify the License. You may add Your own attribution
-       notices within Derivative Works that You distribute, alongside
-       or as an addendum to the NOTICE text from the Work, provided
-       that such additional attribution notices cannot be construed
-       as modifying the License.
-
-   You may add Your own copyright statement to Your modifications and
-   may provide additional or different license terms and conditions
-   for use, reproduction, or distribution of Your modifications, or
-   for any such Derivative Works as a whole, provided Your use,
-   reproduction, and distribution of the Work otherwise complies with
-   the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
-   any Contribution intentionally submitted for inclusion in the Work
-   by You to the Licensor shall be under the terms and conditions of
-   this License, without any additional terms or conditions.
-   Notwithstanding the above, nothing herein shall supersede or modify
-   the terms of any separate license agreement you may have executed
-   with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
-   names, trademarks, service marks, or product names of the Licensor,
-   except as required for reasonable and customary use in describing the
-   origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
-   agreed to in writing, Licensor provides the Work (and each
-   Contributor provides its Contributions) on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-   implied, including, without limitation, any warranties or conditions
-   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-   PARTICULAR PURPOSE. You are solely responsible for determining the
-   appropriateness of using or redistributing the Work and assume any
-   risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
-   whether in tort (including negligence), contract, or otherwise,
-   unless required by applicable law (such as deliberate and grossly
-   negligent acts) or agreed to in writing, shall any Contributor be
-   liable to You for damages, including any direct, indirect, special,
-   incidental, or consequential damages of any character arising as a
-   result of this License or out of the use or inability to use the
-   Work (including but not limited to damages for loss of goodwill,
-   work stoppage, computer failure or malfunction, or any and all
-   other commercial damages or losses), even if such Contributor
-   has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
-   the Work or Derivative Works thereof, You may choose to offer,
-   and charge a fee for, acceptance of support, warranty, indemnity,
-   or other liability obligations and/or rights consistent with this
-   License. However, in accepting such obligations, You may act only
-   on Your own behalf and on Your sole responsibility, not on behalf
-   of any other Contributor, and only if You agree to indemnify,
-   defend, and hold each Contributor harmless for any liability
-   incurred by, or claims asserted against, such Contributor by reason
-   of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-   To apply the Apache License to your work, attach the following
-   boilerplate notice, with the fields enclosed by brackets "[]"
-   replaced with your own identifying information. (Don't include
-   the brackets!)  The text should be enclosed in the appropriate
-   comment syntax for the file format. We also recommend that a
-   file or class name and description of purpose be included on the
-   same "printed page" as the copyright notice for easier
-   identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.

+ 0 - 1133
vendor/github.com/spf13/cobra/cobra/cmd/licenses.go

@@ -1,1133 +0,0 @@
-// Copyright © 2015 Steve Francia <spf@spf13.com>.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Parts inspired by https://github.com/ryanuber/go-license
-
-package cmd
-
-import "strings"
-
-//Licenses contains all possible licenses a user can chose from
-var Licenses map[string]License
-
-//License represents a software license agreement, containing the Name of
-// the license, its possible matches (on the command line as given to cobra)
-// the header to be used with each file on the file's creating, and the text
-// of the license
-type License struct {
-	Name            string   // The type of license in use
-	PossibleMatches []string // Similar names to guess
-	Text            string   // License text data
-	Header          string   // License header for source files
-}
-
-// given a license name (in), try to match the license indicated
-func matchLicense(in string) string {
-	for key, lic := range Licenses {
-		for _, match := range lic.PossibleMatches {
-			if strings.EqualFold(in, match) {
-				return key
-			}
-		}
-	}
-	return ""
-}
-
-func init() {
-	Licenses = make(map[string]License)
-
-	Licenses["apache"] = License{
-		Name:            "Apache 2.0",
-		PossibleMatches: []string{"apache", "apache20", "apache 2.0", "apache2.0", "apache-2.0"},
-		Header: `
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.`,
-		Text: `
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-`,
-	}
-
-	Licenses["mit"] = License{
-		Name:            "Mit",
-		PossibleMatches: []string{"mit"},
-		Header: `
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.`,
-		Text: `The MIT License (MIT)
-
-{{ .copyright }}
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-`,
-	}
-
-	Licenses["bsd"] = License{
-		Name:            "NewBSD",
-		PossibleMatches: []string{"bsd", "newbsd", "3 clause bsd"},
-		Header: `
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-3. Neither the name of the copyright holder nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.`,
-		Text: `{{ .copyright }}
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-3. Neither the name of the copyright holder nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-`,
-	}
-
-	Licenses["freebsd"] = License{
-		Name:            "Simplified BSD License",
-		PossibleMatches: []string{"freebsd", "simpbsd", "simple bsd", "2 clause bsd"},
-		Header: `
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.`,
-		Text: `{{ .copyright }}
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-`,
-	}
-
-	Licenses["gpl3"] = License{
-		Name:            "GNU General Public License 3.0",
-		PossibleMatches: []string{"gpl3", "gpl", "gnu gpl3", "gnu gpl"},
-		Header: `{{ .copyright }}
-
- This file is part of {{ .appName }}.
-
- {{ .appName }} is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- {{ .appName }} is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with {{ .appName }}. If not, see <http://www.gnu.org/licenses/>.
-	   `,
-		Text: `                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-`,
-	}
-
-	// Licenses["apache20"] = License{
-	// 	Name:            "Apache 2.0",
-	// 	PossibleMatches: []string{"apache", "apache20", ""},
-	//   Header: `
-	//   `,
-	// 	Text: `
-	//   `,
-	// }
-}

+ 97 - 0
vendor/golang.org/x/crypto/ssh/buffer.go

@@ -0,0 +1,97 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"io"
+	"sync"
+)
+
+// buffer provides a linked list buffer for data exchange
+// between producer and consumer. Theoretically the buffer is
+// of unlimited capacity as it does no allocation of its own.
+type buffer struct {
+	// protects concurrent access to head, tail and closed
+	*sync.Cond
+
+	head *element // the buffer that will be read first
+	tail *element // the buffer that will be read last
+
+	closed bool
+}
+
+// An element represents a single link in a linked list.
+type element struct {
+	buf  []byte
+	next *element
+}
+
+// newBuffer returns an empty buffer that is not closed.
+func newBuffer() *buffer {
+	e := new(element)
+	b := &buffer{
+		Cond: newCond(),
+		head: e,
+		tail: e,
+	}
+	return b
+}
+
+// write makes buf available for Read to receive.
+// buf must not be modified after the call to write.
+func (b *buffer) write(buf []byte) {
+	b.Cond.L.Lock()
+	e := &element{buf: buf}
+	b.tail.next = e
+	b.tail = e
+	b.Cond.Signal()
+	b.Cond.L.Unlock()
+}
+
+// eof closes the buffer. Reads from the buffer once all
+// the data has been consumed will receive io.EOF.
+func (b *buffer) eof() {
+	b.Cond.L.Lock()
+	b.closed = true
+	b.Cond.Signal()
+	b.Cond.L.Unlock()
+}
+
+// Read reads data from the internal buffer in buf.  Reads will block
+// if no data is available, or until the buffer is closed.
+func (b *buffer) Read(buf []byte) (n int, err error) {
+	b.Cond.L.Lock()
+	defer b.Cond.L.Unlock()
+
+	for len(buf) > 0 {
+		// if there is data in b.head, copy it
+		if len(b.head.buf) > 0 {
+			r := copy(buf, b.head.buf)
+			buf, b.head.buf = buf[r:], b.head.buf[r:]
+			n += r
+			continue
+		}
+		// if there is a next buffer, make it the head
+		if len(b.head.buf) == 0 && b.head != b.tail {
+			b.head = b.head.next
+			continue
+		}
+
+		// if at least one byte has been copied, return
+		if n > 0 {
+			break
+		}
+
+		// if nothing was read, and there is nothing outstanding
+		// check to see if the buffer is closed.
+		if b.closed {
+			err = io.EOF
+			break
+		}
+		// out of buffers, wait for producer
+		b.Cond.Wait()
+	}
+	return
+}

+ 519 - 0
vendor/golang.org/x/crypto/ssh/certs.go

@@ -0,0 +1,519 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"sort"
+	"time"
+)
+
+// These constants from [PROTOCOL.certkeys] represent the algorithm names
+// for certificate types supported by this package.
+const (
+	CertAlgoRSAv01      = "ssh-rsa-cert-v01@openssh.com"
+	CertAlgoDSAv01      = "ssh-dss-cert-v01@openssh.com"
+	CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
+	CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
+	CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
+	CertAlgoED25519v01  = "ssh-ed25519-cert-v01@openssh.com"
+)
+
+// Certificate types distinguish between host and user
+// certificates. The values can be set in the CertType field of
+// Certificate.
+const (
+	UserCert = 1
+	HostCert = 2
+)
+
+// Signature represents a cryptographic signature.
+type Signature struct {
+	Format string
+	Blob   []byte
+}
+
+// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
+// a certificate does not expire.
+const CertTimeInfinity = 1<<64 - 1
+
+// An Certificate represents an OpenSSH certificate as defined in
+// [PROTOCOL.certkeys]?rev=1.8.
+type Certificate struct {
+	Nonce           []byte
+	Key             PublicKey
+	Serial          uint64
+	CertType        uint32
+	KeyId           string
+	ValidPrincipals []string
+	ValidAfter      uint64
+	ValidBefore     uint64
+	Permissions
+	Reserved     []byte
+	SignatureKey PublicKey
+	Signature    *Signature
+}
+
+// genericCertData holds the key-independent part of the certificate data.
+// Overall, certificates contain an nonce, public key fields and
+// key-independent fields.
+type genericCertData struct {
+	Serial          uint64
+	CertType        uint32
+	KeyId           string
+	ValidPrincipals []byte
+	ValidAfter      uint64
+	ValidBefore     uint64
+	CriticalOptions []byte
+	Extensions      []byte
+	Reserved        []byte
+	SignatureKey    []byte
+	Signature       []byte
+}
+
+func marshalStringList(namelist []string) []byte {
+	var to []byte
+	for _, name := range namelist {
+		s := struct{ N string }{name}
+		to = append(to, Marshal(&s)...)
+	}
+	return to
+}
+
+type optionsTuple struct {
+	Key   string
+	Value []byte
+}
+
+type optionsTupleValue struct {
+	Value string
+}
+
+// serialize a map of critical options or extensions
+// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
+// we need two length prefixes for a non-empty string value
+func marshalTuples(tups map[string]string) []byte {
+	keys := make([]string, 0, len(tups))
+	for key := range tups {
+		keys = append(keys, key)
+	}
+	sort.Strings(keys)
+
+	var ret []byte
+	for _, key := range keys {
+		s := optionsTuple{Key: key}
+		if value := tups[key]; len(value) > 0 {
+			s.Value = Marshal(&optionsTupleValue{value})
+		}
+		ret = append(ret, Marshal(&s)...)
+	}
+	return ret
+}
+
+// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
+// we need two length prefixes for a non-empty option value
+func parseTuples(in []byte) (map[string]string, error) {
+	tups := map[string]string{}
+	var lastKey string
+	var haveLastKey bool
+
+	for len(in) > 0 {
+		var key, val, extra []byte
+		var ok bool
+
+		if key, in, ok = parseString(in); !ok {
+			return nil, errShortRead
+		}
+		keyStr := string(key)
+		// according to [PROTOCOL.certkeys], the names must be in
+		// lexical order.
+		if haveLastKey && keyStr <= lastKey {
+			return nil, fmt.Errorf("ssh: certificate options are not in lexical order")
+		}
+		lastKey, haveLastKey = keyStr, true
+		// the next field is a data field, which if non-empty has a string embedded
+		if val, in, ok = parseString(in); !ok {
+			return nil, errShortRead
+		}
+		if len(val) > 0 {
+			val, extra, ok = parseString(val)
+			if !ok {
+				return nil, errShortRead
+			}
+			if len(extra) > 0 {
+				return nil, fmt.Errorf("ssh: unexpected trailing data after certificate option value")
+			}
+			tups[keyStr] = string(val)
+		} else {
+			tups[keyStr] = ""
+		}
+	}
+	return tups, nil
+}
+
+func parseCert(in []byte, privAlgo string) (*Certificate, error) {
+	nonce, rest, ok := parseString(in)
+	if !ok {
+		return nil, errShortRead
+	}
+
+	key, rest, err := parsePubKey(rest, privAlgo)
+	if err != nil {
+		return nil, err
+	}
+
+	var g genericCertData
+	if err := Unmarshal(rest, &g); err != nil {
+		return nil, err
+	}
+
+	c := &Certificate{
+		Nonce:       nonce,
+		Key:         key,
+		Serial:      g.Serial,
+		CertType:    g.CertType,
+		KeyId:       g.KeyId,
+		ValidAfter:  g.ValidAfter,
+		ValidBefore: g.ValidBefore,
+	}
+
+	for principals := g.ValidPrincipals; len(principals) > 0; {
+		principal, rest, ok := parseString(principals)
+		if !ok {
+			return nil, errShortRead
+		}
+		c.ValidPrincipals = append(c.ValidPrincipals, string(principal))
+		principals = rest
+	}
+
+	c.CriticalOptions, err = parseTuples(g.CriticalOptions)
+	if err != nil {
+		return nil, err
+	}
+	c.Extensions, err = parseTuples(g.Extensions)
+	if err != nil {
+		return nil, err
+	}
+	c.Reserved = g.Reserved
+	k, err := ParsePublicKey(g.SignatureKey)
+	if err != nil {
+		return nil, err
+	}
+
+	c.SignatureKey = k
+	c.Signature, rest, ok = parseSignatureBody(g.Signature)
+	if !ok || len(rest) > 0 {
+		return nil, errors.New("ssh: signature parse error")
+	}
+
+	return c, nil
+}
+
+type openSSHCertSigner struct {
+	pub    *Certificate
+	signer Signer
+}
+
+// NewCertSigner returns a Signer that signs with the given Certificate, whose
+// private key is held by signer. It returns an error if the public key in cert
+// doesn't match the key used by signer.
+func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
+	if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
+		return nil, errors.New("ssh: signer and cert have different public key")
+	}
+
+	return &openSSHCertSigner{cert, signer}, nil
+}
+
+func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
+	return s.signer.Sign(rand, data)
+}
+
+func (s *openSSHCertSigner) PublicKey() PublicKey {
+	return s.pub
+}
+
+const sourceAddressCriticalOption = "source-address"
+
+// CertChecker does the work of verifying a certificate. Its methods
+// can be plugged into ClientConfig.HostKeyCallback and
+// ServerConfig.PublicKeyCallback. For the CertChecker to work,
+// minimally, the IsAuthority callback should be set.
+type CertChecker struct {
+	// SupportedCriticalOptions lists the CriticalOptions that the
+	// server application layer understands. These are only used
+	// for user certificates.
+	SupportedCriticalOptions []string
+
+	// IsUserAuthority should return true if the key is recognized as an
+	// authority for the given user certificate. This allows for
+	// certificates to be signed by other certificates. This must be set
+	// if this CertChecker will be checking user certificates.
+	IsUserAuthority func(auth PublicKey) bool
+
+	// IsHostAuthority should report whether the key is recognized as
+	// an authority for this host. This allows for certificates to be
+	// signed by other keys, and for those other keys to only be valid
+	// signers for particular hostnames. This must be set if this
+	// CertChecker will be checking host certificates.
+	IsHostAuthority func(auth PublicKey, address string) bool
+
+	// Clock is used for verifying time stamps. If nil, time.Now
+	// is used.
+	Clock func() time.Time
+
+	// UserKeyFallback is called when CertChecker.Authenticate encounters a
+	// public key that is not a certificate. It must implement validation
+	// of user keys or else, if nil, all such keys are rejected.
+	UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
+
+	// HostKeyFallback is called when CertChecker.CheckHostKey encounters a
+	// public key that is not a certificate. It must implement host key
+	// validation or else, if nil, all such keys are rejected.
+	HostKeyFallback HostKeyCallback
+
+	// IsRevoked is called for each certificate so that revocation checking
+	// can be implemented. It should return true if the given certificate
+	// is revoked and false otherwise. If nil, no certificates are
+	// considered to have been revoked.
+	IsRevoked func(cert *Certificate) bool
+}
+
+// CheckHostKey checks a host key certificate. This method can be
+// plugged into ClientConfig.HostKeyCallback.
+func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error {
+	cert, ok := key.(*Certificate)
+	if !ok {
+		if c.HostKeyFallback != nil {
+			return c.HostKeyFallback(addr, remote, key)
+		}
+		return errors.New("ssh: non-certificate host key")
+	}
+	if cert.CertType != HostCert {
+		return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType)
+	}
+	if !c.IsHostAuthority(cert.SignatureKey, addr) {
+		return fmt.Errorf("ssh: no authorities for hostname: %v", addr)
+	}
+
+	hostname, _, err := net.SplitHostPort(addr)
+	if err != nil {
+		return err
+	}
+
+	// Pass hostname only as principal for host certificates (consistent with OpenSSH)
+	return c.CheckCert(hostname, cert)
+}
+
+// Authenticate checks a user certificate. Authenticate can be used as
+// a value for ServerConfig.PublicKeyCallback.
+func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) {
+	cert, ok := pubKey.(*Certificate)
+	if !ok {
+		if c.UserKeyFallback != nil {
+			return c.UserKeyFallback(conn, pubKey)
+		}
+		return nil, errors.New("ssh: normal key pairs not accepted")
+	}
+
+	if cert.CertType != UserCert {
+		return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType)
+	}
+	if !c.IsUserAuthority(cert.SignatureKey) {
+		return nil, fmt.Errorf("ssh: certificate signed by unrecognized authority")
+	}
+
+	if err := c.CheckCert(conn.User(), cert); err != nil {
+		return nil, err
+	}
+
+	return &cert.Permissions, nil
+}
+
+// CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and
+// the signature of the certificate.
+func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
+	if c.IsRevoked != nil && c.IsRevoked(cert) {
+		return fmt.Errorf("ssh: certicate serial %d revoked", cert.Serial)
+	}
+
+	for opt, _ := range cert.CriticalOptions {
+		// sourceAddressCriticalOption will be enforced by
+		// serverAuthenticate
+		if opt == sourceAddressCriticalOption {
+			continue
+		}
+
+		found := false
+		for _, supp := range c.SupportedCriticalOptions {
+			if supp == opt {
+				found = true
+				break
+			}
+		}
+		if !found {
+			return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt)
+		}
+	}
+
+	if len(cert.ValidPrincipals) > 0 {
+		// By default, certs are valid for all users/hosts.
+		found := false
+		for _, p := range cert.ValidPrincipals {
+			if p == principal {
+				found = true
+				break
+			}
+		}
+		if !found {
+			return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals)
+		}
+	}
+
+	clock := c.Clock
+	if clock == nil {
+		clock = time.Now
+	}
+
+	unixNow := clock().Unix()
+	if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) {
+		return fmt.Errorf("ssh: cert is not yet valid")
+	}
+	if before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) {
+		return fmt.Errorf("ssh: cert has expired")
+	}
+	if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil {
+		return fmt.Errorf("ssh: certificate signature does not verify")
+	}
+
+	return nil
+}
+
+// SignCert sets c.SignatureKey to the authority's public key and stores a
+// Signature, by authority, in the certificate.
+func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
+	c.Nonce = make([]byte, 32)
+	if _, err := io.ReadFull(rand, c.Nonce); err != nil {
+		return err
+	}
+	c.SignatureKey = authority.PublicKey()
+
+	sig, err := authority.Sign(rand, c.bytesForSigning())
+	if err != nil {
+		return err
+	}
+	c.Signature = sig
+	return nil
+}
+
+var certAlgoNames = map[string]string{
+	KeyAlgoRSA:      CertAlgoRSAv01,
+	KeyAlgoDSA:      CertAlgoDSAv01,
+	KeyAlgoECDSA256: CertAlgoECDSA256v01,
+	KeyAlgoECDSA384: CertAlgoECDSA384v01,
+	KeyAlgoECDSA521: CertAlgoECDSA521v01,
+	KeyAlgoED25519:  CertAlgoED25519v01,
+}
+
+// certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
+// Panics if a non-certificate algorithm is passed.
+func certToPrivAlgo(algo string) string {
+	for privAlgo, pubAlgo := range certAlgoNames {
+		if pubAlgo == algo {
+			return privAlgo
+		}
+	}
+	panic("unknown cert algorithm")
+}
+
+func (cert *Certificate) bytesForSigning() []byte {
+	c2 := *cert
+	c2.Signature = nil
+	out := c2.Marshal()
+	// Drop trailing signature length.
+	return out[:len(out)-4]
+}
+
+// Marshal serializes c into OpenSSH's wire format. It is part of the
+// PublicKey interface.
+func (c *Certificate) Marshal() []byte {
+	generic := genericCertData{
+		Serial:          c.Serial,
+		CertType:        c.CertType,
+		KeyId:           c.KeyId,
+		ValidPrincipals: marshalStringList(c.ValidPrincipals),
+		ValidAfter:      uint64(c.ValidAfter),
+		ValidBefore:     uint64(c.ValidBefore),
+		CriticalOptions: marshalTuples(c.CriticalOptions),
+		Extensions:      marshalTuples(c.Extensions),
+		Reserved:        c.Reserved,
+		SignatureKey:    c.SignatureKey.Marshal(),
+	}
+	if c.Signature != nil {
+		generic.Signature = Marshal(c.Signature)
+	}
+	genericBytes := Marshal(&generic)
+	keyBytes := c.Key.Marshal()
+	_, keyBytes, _ = parseString(keyBytes)
+	prefix := Marshal(&struct {
+		Name  string
+		Nonce []byte
+		Key   []byte `ssh:"rest"`
+	}{c.Type(), c.Nonce, keyBytes})
+
+	result := make([]byte, 0, len(prefix)+len(genericBytes))
+	result = append(result, prefix...)
+	result = append(result, genericBytes...)
+	return result
+}
+
+// Type returns the key name. It is part of the PublicKey interface.
+func (c *Certificate) Type() string {
+	algo, ok := certAlgoNames[c.Key.Type()]
+	if !ok {
+		panic("unknown cert key type " + c.Key.Type())
+	}
+	return algo
+}
+
+// Verify verifies a signature against the certificate's public
+// key. It is part of the PublicKey interface.
+func (c *Certificate) Verify(data []byte, sig *Signature) error {
+	return c.Key.Verify(data, sig)
+}
+
+func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {
+	format, in, ok := parseString(in)
+	if !ok {
+		return
+	}
+
+	out = &Signature{
+		Format: string(format),
+	}
+
+	if out.Blob, in, ok = parseString(in); !ok {
+		return
+	}
+
+	return out, in, ok
+}
+
+func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) {
+	sigBytes, rest, ok := parseString(in)
+	if !ok {
+		return
+	}
+
+	out, trailing, ok := parseSignatureBody(sigBytes)
+	if !ok || len(trailing) > 0 {
+		return nil, nil, false
+	}
+	return
+}

+ 633 - 0
vendor/golang.org/x/crypto/ssh/channel.go

@@ -0,0 +1,633 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"sync"
+)
+
+const (
+	minPacketLength = 9
+	// channelMaxPacket contains the maximum number of bytes that will be
+	// sent in a single packet. As per RFC 4253, section 6.1, 32k is also
+	// the minimum.
+	channelMaxPacket = 1 << 15
+	// We follow OpenSSH here.
+	channelWindowSize = 64 * channelMaxPacket
+)
+
+// NewChannel represents an incoming request to a channel. It must either be
+// accepted for use by calling Accept, or rejected by calling Reject.
+type NewChannel interface {
+	// Accept accepts the channel creation request. It returns the Channel
+	// and a Go channel containing SSH requests. The Go channel must be
+	// serviced otherwise the Channel will hang.
+	Accept() (Channel, <-chan *Request, error)
+
+	// Reject rejects the channel creation request. After calling
+	// this, no other methods on the Channel may be called.
+	Reject(reason RejectionReason, message string) error
+
+	// ChannelType returns the type of the channel, as supplied by the
+	// client.
+	ChannelType() string
+
+	// ExtraData returns the arbitrary payload for this channel, as supplied
+	// by the client. This data is specific to the channel type.
+	ExtraData() []byte
+}
+
+// A Channel is an ordered, reliable, flow-controlled, duplex stream
+// that is multiplexed over an SSH connection.
+type Channel interface {
+	// Read reads up to len(data) bytes from the channel.
+	Read(data []byte) (int, error)
+
+	// Write writes len(data) bytes to the channel.
+	Write(data []byte) (int, error)
+
+	// Close signals end of channel use. No data may be sent after this
+	// call.
+	Close() error
+
+	// CloseWrite signals the end of sending in-band
+	// data. Requests may still be sent, and the other side may
+	// still send data
+	CloseWrite() error
+
+	// SendRequest sends a channel request.  If wantReply is true,
+	// it will wait for a reply and return the result as a
+	// boolean, otherwise the return value will be false. Channel
+	// requests are out-of-band messages so they may be sent even
+	// if the data stream is closed or blocked by flow control.
+	// If the channel is closed before a reply is returned, io.EOF
+	// is returned.
+	SendRequest(name string, wantReply bool, payload []byte) (bool, error)
+
+	// Stderr returns an io.ReadWriter that writes to this channel
+	// with the extended data type set to stderr. Stderr may
+	// safely be read and written from a different goroutine than
+	// Read and Write respectively.
+	Stderr() io.ReadWriter
+}
+
+// Request is a request sent outside of the normal stream of
+// data. Requests can either be specific to an SSH channel, or they
+// can be global.
+type Request struct {
+	Type      string
+	WantReply bool
+	Payload   []byte
+
+	ch  *channel
+	mux *mux
+}
+
+// Reply sends a response to a request. It must be called for all requests
+// where WantReply is true and is a no-op otherwise. The payload argument is
+// ignored for replies to channel-specific requests.
+func (r *Request) Reply(ok bool, payload []byte) error {
+	if !r.WantReply {
+		return nil
+	}
+
+	if r.ch == nil {
+		return r.mux.ackRequest(ok, payload)
+	}
+
+	return r.ch.ackRequest(ok)
+}
+
+// RejectionReason is an enumeration used when rejecting channel creation
+// requests. See RFC 4254, section 5.1.
+type RejectionReason uint32
+
+const (
+	Prohibited RejectionReason = iota + 1
+	ConnectionFailed
+	UnknownChannelType
+	ResourceShortage
+)
+
+// String converts the rejection reason to human readable form.
+func (r RejectionReason) String() string {
+	switch r {
+	case Prohibited:
+		return "administratively prohibited"
+	case ConnectionFailed:
+		return "connect failed"
+	case UnknownChannelType:
+		return "unknown channel type"
+	case ResourceShortage:
+		return "resource shortage"
+	}
+	return fmt.Sprintf("unknown reason %d", int(r))
+}
+
+func min(a uint32, b int) uint32 {
+	if a < uint32(b) {
+		return a
+	}
+	return uint32(b)
+}
+
+type channelDirection uint8
+
+const (
+	channelInbound channelDirection = iota
+	channelOutbound
+)
+
+// channel is an implementation of the Channel interface that works
+// with the mux class.
+type channel struct {
+	// R/O after creation
+	chanType          string
+	extraData         []byte
+	localId, remoteId uint32
+
+	// maxIncomingPayload and maxRemotePayload are the maximum
+	// payload sizes of normal and extended data packets for
+	// receiving and sending, respectively. The wire packet will
+	// be 9 or 13 bytes larger (excluding encryption overhead).
+	maxIncomingPayload uint32
+	maxRemotePayload   uint32
+
+	mux *mux
+
+	// decided is set to true if an accept or reject message has been sent
+	// (for outbound channels) or received (for inbound channels).
+	decided bool
+
+	// direction contains either channelOutbound, for channels created
+	// locally, or channelInbound, for channels created by the peer.
+	direction channelDirection
+
+	// Pending internal channel messages.
+	msg chan interface{}
+
+	// Since requests have no ID, there can be only one request
+	// with WantReply=true outstanding.  This lock is held by a
+	// goroutine that has such an outgoing request pending.
+	sentRequestMu sync.Mutex
+
+	incomingRequests chan *Request
+
+	sentEOF bool
+
+	// thread-safe data
+	remoteWin  window
+	pending    *buffer
+	extPending *buffer
+
+	// windowMu protects myWindow, the flow-control window.
+	windowMu sync.Mutex
+	myWindow uint32
+
+	// writeMu serializes calls to mux.conn.writePacket() and
+	// protects sentClose and packetPool. This mutex must be
+	// different from windowMu, as writePacket can block if there
+	// is a key exchange pending.
+	writeMu   sync.Mutex
+	sentClose bool
+
+	// packetPool has a buffer for each extended channel ID to
+	// save allocations during writes.
+	packetPool map[uint32][]byte
+}
+
+// writePacket sends a packet. If the packet is a channel close, it updates
+// sentClose. This method takes the lock c.writeMu.
+func (c *channel) writePacket(packet []byte) error {
+	c.writeMu.Lock()
+	if c.sentClose {
+		c.writeMu.Unlock()
+		return io.EOF
+	}
+	c.sentClose = (packet[0] == msgChannelClose)
+	err := c.mux.conn.writePacket(packet)
+	c.writeMu.Unlock()
+	return err
+}
+
+func (c *channel) sendMessage(msg interface{}) error {
+	if debugMux {
+		log.Printf("send(%d): %#v", c.mux.chanList.offset, msg)
+	}
+
+	p := Marshal(msg)
+	binary.BigEndian.PutUint32(p[1:], c.remoteId)
+	return c.writePacket(p)
+}
+
+// WriteExtended writes data to a specific extended stream. These streams are
+// used, for example, for stderr.
+func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) {
+	if c.sentEOF {
+		return 0, io.EOF
+	}
+	// 1 byte message type, 4 bytes remoteId, 4 bytes data length
+	opCode := byte(msgChannelData)
+	headerLength := uint32(9)
+	if extendedCode > 0 {
+		headerLength += 4
+		opCode = msgChannelExtendedData
+	}
+
+	c.writeMu.Lock()
+	packet := c.packetPool[extendedCode]
+	// We don't remove the buffer from packetPool, so
+	// WriteExtended calls from different goroutines will be
+	// flagged as errors by the race detector.
+	c.writeMu.Unlock()
+
+	for len(data) > 0 {
+		space := min(c.maxRemotePayload, len(data))
+		if space, err = c.remoteWin.reserve(space); err != nil {
+			return n, err
+		}
+		if want := headerLength + space; uint32(cap(packet)) < want {
+			packet = make([]byte, want)
+		} else {
+			packet = packet[:want]
+		}
+
+		todo := data[:space]
+
+		packet[0] = opCode
+		binary.BigEndian.PutUint32(packet[1:], c.remoteId)
+		if extendedCode > 0 {
+			binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode))
+		}
+		binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo)))
+		copy(packet[headerLength:], todo)
+		if err = c.writePacket(packet); err != nil {
+			return n, err
+		}
+
+		n += len(todo)
+		data = data[len(todo):]
+	}
+
+	c.writeMu.Lock()
+	c.packetPool[extendedCode] = packet
+	c.writeMu.Unlock()
+
+	return n, err
+}
+
+func (c *channel) handleData(packet []byte) error {
+	headerLen := 9
+	isExtendedData := packet[0] == msgChannelExtendedData
+	if isExtendedData {
+		headerLen = 13
+	}
+	if len(packet) < headerLen {
+		// malformed data packet
+		return parseError(packet[0])
+	}
+
+	var extended uint32
+	if isExtendedData {
+		extended = binary.BigEndian.Uint32(packet[5:])
+	}
+
+	length := binary.BigEndian.Uint32(packet[headerLen-4 : headerLen])
+	if length == 0 {
+		return nil
+	}
+	if length > c.maxIncomingPayload {
+		// TODO(hanwen): should send Disconnect?
+		return errors.New("ssh: incoming packet exceeds maximum payload size")
+	}
+
+	data := packet[headerLen:]
+	if length != uint32(len(data)) {
+		return errors.New("ssh: wrong packet length")
+	}
+
+	c.windowMu.Lock()
+	if c.myWindow < length {
+		c.windowMu.Unlock()
+		// TODO(hanwen): should send Disconnect with reason?
+		return errors.New("ssh: remote side wrote too much")
+	}
+	c.myWindow -= length
+	c.windowMu.Unlock()
+
+	if extended == 1 {
+		c.extPending.write(data)
+	} else if extended > 0 {
+		// discard other extended data.
+	} else {
+		c.pending.write(data)
+	}
+	return nil
+}
+
+func (c *channel) adjustWindow(n uint32) error {
+	c.windowMu.Lock()
+	// Since myWindow is managed on our side, and can never exceed
+	// the initial window setting, we don't worry about overflow.
+	c.myWindow += uint32(n)
+	c.windowMu.Unlock()
+	return c.sendMessage(windowAdjustMsg{
+		AdditionalBytes: uint32(n),
+	})
+}
+
+func (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) {
+	switch extended {
+	case 1:
+		n, err = c.extPending.Read(data)
+	case 0:
+		n, err = c.pending.Read(data)
+	default:
+		return 0, fmt.Errorf("ssh: extended code %d unimplemented", extended)
+	}
+
+	if n > 0 {
+		err = c.adjustWindow(uint32(n))
+		// sendWindowAdjust can return io.EOF if the remote
+		// peer has closed the connection, however we want to
+		// defer forwarding io.EOF to the caller of Read until
+		// the buffer has been drained.
+		if n > 0 && err == io.EOF {
+			err = nil
+		}
+	}
+
+	return n, err
+}
+
+func (c *channel) close() {
+	c.pending.eof()
+	c.extPending.eof()
+	close(c.msg)
+	close(c.incomingRequests)
+	c.writeMu.Lock()
+	// This is not necessary for a normal channel teardown, but if
+	// there was another error, it is.
+	c.sentClose = true
+	c.writeMu.Unlock()
+	// Unblock writers.
+	c.remoteWin.close()
+}
+
+// responseMessageReceived is called when a success or failure message is
+// received on a channel to check that such a message is reasonable for the
+// given channel.
+func (c *channel) responseMessageReceived() error {
+	if c.direction == channelInbound {
+		return errors.New("ssh: channel response message received on inbound channel")
+	}
+	if c.decided {
+		return errors.New("ssh: duplicate response received for channel")
+	}
+	c.decided = true
+	return nil
+}
+
+func (c *channel) handlePacket(packet []byte) error {
+	switch packet[0] {
+	case msgChannelData, msgChannelExtendedData:
+		return c.handleData(packet)
+	case msgChannelClose:
+		c.sendMessage(channelCloseMsg{PeersId: c.remoteId})
+		c.mux.chanList.remove(c.localId)
+		c.close()
+		return nil
+	case msgChannelEOF:
+		// RFC 4254 is mute on how EOF affects dataExt messages but
+		// it is logical to signal EOF at the same time.
+		c.extPending.eof()
+		c.pending.eof()
+		return nil
+	}
+
+	decoded, err := decode(packet)
+	if err != nil {
+		return err
+	}
+
+	switch msg := decoded.(type) {
+	case *channelOpenFailureMsg:
+		if err := c.responseMessageReceived(); err != nil {
+			return err
+		}
+		c.mux.chanList.remove(msg.PeersId)
+		c.msg <- msg
+	case *channelOpenConfirmMsg:
+		if err := c.responseMessageReceived(); err != nil {
+			return err
+		}
+		if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
+			return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize)
+		}
+		c.remoteId = msg.MyId
+		c.maxRemotePayload = msg.MaxPacketSize
+		c.remoteWin.add(msg.MyWindow)
+		c.msg <- msg
+	case *windowAdjustMsg:
+		if !c.remoteWin.add(msg.AdditionalBytes) {
+			return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes)
+		}
+	case *channelRequestMsg:
+		req := Request{
+			Type:      msg.Request,
+			WantReply: msg.WantReply,
+			Payload:   msg.RequestSpecificData,
+			ch:        c,
+		}
+
+		c.incomingRequests <- &req
+	default:
+		c.msg <- msg
+	}
+	return nil
+}
+
+func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel {
+	ch := &channel{
+		remoteWin:        window{Cond: newCond()},
+		myWindow:         channelWindowSize,
+		pending:          newBuffer(),
+		extPending:       newBuffer(),
+		direction:        direction,
+		incomingRequests: make(chan *Request, chanSize),
+		msg:              make(chan interface{}, chanSize),
+		chanType:         chanType,
+		extraData:        extraData,
+		mux:              m,
+		packetPool:       make(map[uint32][]byte),
+	}
+	ch.localId = m.chanList.add(ch)
+	return ch
+}
+
+var errUndecided = errors.New("ssh: must Accept or Reject channel")
+var errDecidedAlready = errors.New("ssh: can call Accept or Reject only once")
+
+type extChannel struct {
+	code uint32
+	ch   *channel
+}
+
+func (e *extChannel) Write(data []byte) (n int, err error) {
+	return e.ch.WriteExtended(data, e.code)
+}
+
+func (e *extChannel) Read(data []byte) (n int, err error) {
+	return e.ch.ReadExtended(data, e.code)
+}
+
+func (c *channel) Accept() (Channel, <-chan *Request, error) {
+	if c.decided {
+		return nil, nil, errDecidedAlready
+	}
+	c.maxIncomingPayload = channelMaxPacket
+	confirm := channelOpenConfirmMsg{
+		PeersId:       c.remoteId,
+		MyId:          c.localId,
+		MyWindow:      c.myWindow,
+		MaxPacketSize: c.maxIncomingPayload,
+	}
+	c.decided = true
+	if err := c.sendMessage(confirm); err != nil {
+		return nil, nil, err
+	}
+
+	return c, c.incomingRequests, nil
+}
+
+func (ch *channel) Reject(reason RejectionReason, message string) error {
+	if ch.decided {
+		return errDecidedAlready
+	}
+	reject := channelOpenFailureMsg{
+		PeersId:  ch.remoteId,
+		Reason:   reason,
+		Message:  message,
+		Language: "en",
+	}
+	ch.decided = true
+	return ch.sendMessage(reject)
+}
+
+func (ch *channel) Read(data []byte) (int, error) {
+	if !ch.decided {
+		return 0, errUndecided
+	}
+	return ch.ReadExtended(data, 0)
+}
+
+func (ch *channel) Write(data []byte) (int, error) {
+	if !ch.decided {
+		return 0, errUndecided
+	}
+	return ch.WriteExtended(data, 0)
+}
+
+func (ch *channel) CloseWrite() error {
+	if !ch.decided {
+		return errUndecided
+	}
+	ch.sentEOF = true
+	return ch.sendMessage(channelEOFMsg{
+		PeersId: ch.remoteId})
+}
+
+func (ch *channel) Close() error {
+	if !ch.decided {
+		return errUndecided
+	}
+
+	return ch.sendMessage(channelCloseMsg{
+		PeersId: ch.remoteId})
+}
+
+// Extended returns an io.ReadWriter that sends and receives data on the given,
+// SSH extended stream. Such streams are used, for example, for stderr.
+func (ch *channel) Extended(code uint32) io.ReadWriter {
+	if !ch.decided {
+		return nil
+	}
+	return &extChannel{code, ch}
+}
+
+func (ch *channel) Stderr() io.ReadWriter {
+	return ch.Extended(1)
+}
+
+func (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {
+	if !ch.decided {
+		return false, errUndecided
+	}
+
+	if wantReply {
+		ch.sentRequestMu.Lock()
+		defer ch.sentRequestMu.Unlock()
+	}
+
+	msg := channelRequestMsg{
+		PeersId:             ch.remoteId,
+		Request:             name,
+		WantReply:           wantReply,
+		RequestSpecificData: payload,
+	}
+
+	if err := ch.sendMessage(msg); err != nil {
+		return false, err
+	}
+
+	if wantReply {
+		m, ok := (<-ch.msg)
+		if !ok {
+			return false, io.EOF
+		}
+		switch m.(type) {
+		case *channelRequestFailureMsg:
+			return false, nil
+		case *channelRequestSuccessMsg:
+			return true, nil
+		default:
+			return false, fmt.Errorf("ssh: unexpected response to channel request: %#v", m)
+		}
+	}
+
+	return false, nil
+}
+
+// ackRequest either sends an ack or nack to the channel request.
+func (ch *channel) ackRequest(ok bool) error {
+	if !ch.decided {
+		return errUndecided
+	}
+
+	var msg interface{}
+	if !ok {
+		msg = channelRequestFailureMsg{
+			PeersId: ch.remoteId,
+		}
+	} else {
+		msg = channelRequestSuccessMsg{
+			PeersId: ch.remoteId,
+		}
+	}
+	return ch.sendMessage(msg)
+}
+
+func (ch *channel) ChannelType() string {
+	return ch.chanType
+}
+
+func (ch *channel) ExtraData() []byte {
+	return ch.extraData
+}

+ 629 - 0
vendor/golang.org/x/crypto/ssh/cipher.go

@@ -0,0 +1,629 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/des"
+	"crypto/rc4"
+	"crypto/subtle"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"hash"
+	"io"
+	"io/ioutil"
+)
+
+const (
+	packetSizeMultiple = 16 // TODO(huin) this should be determined by the cipher.
+
+	// RFC 4253 section 6.1 defines a minimum packet size of 32768 that implementations
+	// MUST be able to process (plus a few more kilobytes for padding and mac). The RFC
+	// indicates implementations SHOULD be able to handle larger packet sizes, but then
+	// waffles on about reasonable limits.
+	//
+	// OpenSSH caps their maxPacket at 256kB so we choose to do
+	// the same. maxPacket is also used to ensure that uint32
+	// length fields do not overflow, so it should remain well
+	// below 4G.
+	maxPacket = 256 * 1024
+)
+
+// noneCipher implements cipher.Stream and provides no encryption. It is used
+// by the transport before the first key-exchange.
+type noneCipher struct{}
+
+func (c noneCipher) XORKeyStream(dst, src []byte) {
+	copy(dst, src)
+}
+
+func newAESCTR(key, iv []byte) (cipher.Stream, error) {
+	c, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+	return cipher.NewCTR(c, iv), nil
+}
+
+func newRC4(key, iv []byte) (cipher.Stream, error) {
+	return rc4.NewCipher(key)
+}
+
+type streamCipherMode struct {
+	keySize    int
+	ivSize     int
+	skip       int
+	createFunc func(key, iv []byte) (cipher.Stream, error)
+}
+
+func (c *streamCipherMode) createStream(key, iv []byte) (cipher.Stream, error) {
+	if len(key) < c.keySize {
+		panic("ssh: key length too small for cipher")
+	}
+	if len(iv) < c.ivSize {
+		panic("ssh: iv too small for cipher")
+	}
+
+	stream, err := c.createFunc(key[:c.keySize], iv[:c.ivSize])
+	if err != nil {
+		return nil, err
+	}
+
+	var streamDump []byte
+	if c.skip > 0 {
+		streamDump = make([]byte, 512)
+	}
+
+	for remainingToDump := c.skip; remainingToDump > 0; {
+		dumpThisTime := remainingToDump
+		if dumpThisTime > len(streamDump) {
+			dumpThisTime = len(streamDump)
+		}
+		stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
+		remainingToDump -= dumpThisTime
+	}
+
+	return stream, nil
+}
+
+// cipherModes documents properties of supported ciphers. Ciphers not included
+// are not supported and will not be negotiated, even if explicitly requested in
+// ClientConfig.Crypto.Ciphers.
+var cipherModes = map[string]*streamCipherMode{
+	// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
+	// are defined in the order specified in the RFC.
+	"aes128-ctr": {16, aes.BlockSize, 0, newAESCTR},
+	"aes192-ctr": {24, aes.BlockSize, 0, newAESCTR},
+	"aes256-ctr": {32, aes.BlockSize, 0, newAESCTR},
+
+	// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
+	// They are defined in the order specified in the RFC.
+	"arcfour128": {16, 0, 1536, newRC4},
+	"arcfour256": {32, 0, 1536, newRC4},
+
+	// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
+	// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
+	// RC4) has problems with weak keys, and should be used with caution."
+	// RFC4345 introduces improved versions of Arcfour.
+	"arcfour": {16, 0, 0, newRC4},
+
+	// AES-GCM is not a stream cipher, so it is constructed with a
+	// special case. If we add any more non-stream ciphers, we
+	// should invest a cleaner way to do this.
+	gcmCipherID: {16, 12, 0, nil},
+
+	// CBC mode is insecure and so is not included in the default config.
+	// (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely
+	// needed, it's possible to specify a custom Config to enable it.
+	// You should expect that an active attacker can recover plaintext if
+	// you do.
+	aes128cbcID: {16, aes.BlockSize, 0, nil},
+
+	// 3des-cbc is insecure and is disabled by default.
+	tripledescbcID: {24, des.BlockSize, 0, nil},
+}
+
+// prefixLen is the length of the packet prefix that contains the packet length
+// and number of padding bytes.
+const prefixLen = 5
+
+// streamPacketCipher is a packetCipher using a stream cipher.
+type streamPacketCipher struct {
+	mac    hash.Hash
+	cipher cipher.Stream
+	etm    bool
+
+	// The following members are to avoid per-packet allocations.
+	prefix      [prefixLen]byte
+	seqNumBytes [4]byte
+	padding     [2 * packetSizeMultiple]byte
+	packetData  []byte
+	macResult   []byte
+}
+
+// readPacket reads and decrypt a single packet from the reader argument.
+func (s *streamPacketCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+	if _, err := io.ReadFull(r, s.prefix[:]); err != nil {
+		return nil, err
+	}
+
+	var encryptedPaddingLength [1]byte
+	if s.mac != nil && s.etm {
+		copy(encryptedPaddingLength[:], s.prefix[4:5])
+		s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
+	} else {
+		s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
+	}
+
+	length := binary.BigEndian.Uint32(s.prefix[0:4])
+	paddingLength := uint32(s.prefix[4])
+
+	var macSize uint32
+	if s.mac != nil {
+		s.mac.Reset()
+		binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
+		s.mac.Write(s.seqNumBytes[:])
+		if s.etm {
+			s.mac.Write(s.prefix[:4])
+			s.mac.Write(encryptedPaddingLength[:])
+		} else {
+			s.mac.Write(s.prefix[:])
+		}
+		macSize = uint32(s.mac.Size())
+	}
+
+	if length <= paddingLength+1 {
+		return nil, errors.New("ssh: invalid packet length, packet too small")
+	}
+
+	if length > maxPacket {
+		return nil, errors.New("ssh: invalid packet length, packet too large")
+	}
+
+	// the maxPacket check above ensures that length-1+macSize
+	// does not overflow.
+	if uint32(cap(s.packetData)) < length-1+macSize {
+		s.packetData = make([]byte, length-1+macSize)
+	} else {
+		s.packetData = s.packetData[:length-1+macSize]
+	}
+
+	if _, err := io.ReadFull(r, s.packetData); err != nil {
+		return nil, err
+	}
+	mac := s.packetData[length-1:]
+	data := s.packetData[:length-1]
+
+	if s.mac != nil && s.etm {
+		s.mac.Write(data)
+	}
+
+	s.cipher.XORKeyStream(data, data)
+
+	if s.mac != nil {
+		if !s.etm {
+			s.mac.Write(data)
+		}
+		s.macResult = s.mac.Sum(s.macResult[:0])
+		if subtle.ConstantTimeCompare(s.macResult, mac) != 1 {
+			return nil, errors.New("ssh: MAC failure")
+		}
+	}
+
+	return s.packetData[:length-paddingLength-1], nil
+}
+
+// writePacket encrypts and sends a packet of data to the writer argument
+func (s *streamPacketCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
+	if len(packet) > maxPacket {
+		return errors.New("ssh: packet too large")
+	}
+
+	aadlen := 0
+	if s.mac != nil && s.etm {
+		// packet length is not encrypted for EtM modes
+		aadlen = 4
+	}
+
+	paddingLength := packetSizeMultiple - (prefixLen+len(packet)-aadlen)%packetSizeMultiple
+	if paddingLength < 4 {
+		paddingLength += packetSizeMultiple
+	}
+
+	length := len(packet) + 1 + paddingLength
+	binary.BigEndian.PutUint32(s.prefix[:], uint32(length))
+	s.prefix[4] = byte(paddingLength)
+	padding := s.padding[:paddingLength]
+	if _, err := io.ReadFull(rand, padding); err != nil {
+		return err
+	}
+
+	if s.mac != nil {
+		s.mac.Reset()
+		binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
+		s.mac.Write(s.seqNumBytes[:])
+
+		if s.etm {
+			// For EtM algorithms, the packet length must stay unencrypted,
+			// but the following data (padding length) must be encrypted
+			s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
+		}
+
+		s.mac.Write(s.prefix[:])
+
+		if !s.etm {
+			// For non-EtM algorithms, the algorithm is applied on unencrypted data
+			s.mac.Write(packet)
+			s.mac.Write(padding)
+		}
+	}
+
+	if !(s.mac != nil && s.etm) {
+		// For EtM algorithms, the padding length has already been encrypted
+		// and the packet length must remain unencrypted
+		s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
+	}
+
+	s.cipher.XORKeyStream(packet, packet)
+	s.cipher.XORKeyStream(padding, padding)
+
+	if s.mac != nil && s.etm {
+		// For EtM algorithms, packet and padding must be encrypted
+		s.mac.Write(packet)
+		s.mac.Write(padding)
+	}
+
+	if _, err := w.Write(s.prefix[:]); err != nil {
+		return err
+	}
+	if _, err := w.Write(packet); err != nil {
+		return err
+	}
+	if _, err := w.Write(padding); err != nil {
+		return err
+	}
+
+	if s.mac != nil {
+		s.macResult = s.mac.Sum(s.macResult[:0])
+		if _, err := w.Write(s.macResult); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+type gcmCipher struct {
+	aead   cipher.AEAD
+	prefix [4]byte
+	iv     []byte
+	buf    []byte
+}
+
+func newGCMCipher(iv, key, macKey []byte) (packetCipher, error) {
+	c, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+
+	aead, err := cipher.NewGCM(c)
+	if err != nil {
+		return nil, err
+	}
+
+	return &gcmCipher{
+		aead: aead,
+		iv:   iv,
+	}, nil
+}
+
+const gcmTagSize = 16
+
+func (c *gcmCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
+	// Pad out to multiple of 16 bytes. This is different from the
+	// stream cipher because that encrypts the length too.
+	padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple)
+	if padding < 4 {
+		padding += packetSizeMultiple
+	}
+
+	length := uint32(len(packet) + int(padding) + 1)
+	binary.BigEndian.PutUint32(c.prefix[:], length)
+	if _, err := w.Write(c.prefix[:]); err != nil {
+		return err
+	}
+
+	if cap(c.buf) < int(length) {
+		c.buf = make([]byte, length)
+	} else {
+		c.buf = c.buf[:length]
+	}
+
+	c.buf[0] = padding
+	copy(c.buf[1:], packet)
+	if _, err := io.ReadFull(rand, c.buf[1+len(packet):]); err != nil {
+		return err
+	}
+	c.buf = c.aead.Seal(c.buf[:0], c.iv, c.buf, c.prefix[:])
+	if _, err := w.Write(c.buf); err != nil {
+		return err
+	}
+	c.incIV()
+
+	return nil
+}
+
+func (c *gcmCipher) incIV() {
+	for i := 4 + 7; i >= 4; i-- {
+		c.iv[i]++
+		if c.iv[i] != 0 {
+			break
+		}
+	}
+}
+
+func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+	if _, err := io.ReadFull(r, c.prefix[:]); err != nil {
+		return nil, err
+	}
+	length := binary.BigEndian.Uint32(c.prefix[:])
+	if length > maxPacket {
+		return nil, errors.New("ssh: max packet length exceeded.")
+	}
+
+	if cap(c.buf) < int(length+gcmTagSize) {
+		c.buf = make([]byte, length+gcmTagSize)
+	} else {
+		c.buf = c.buf[:length+gcmTagSize]
+	}
+
+	if _, err := io.ReadFull(r, c.buf); err != nil {
+		return nil, err
+	}
+
+	plain, err := c.aead.Open(c.buf[:0], c.iv, c.buf, c.prefix[:])
+	if err != nil {
+		return nil, err
+	}
+	c.incIV()
+
+	padding := plain[0]
+	if padding < 4 {
+		// padding is a byte, so it automatically satisfies
+		// the maximum size, which is 255.
+		return nil, fmt.Errorf("ssh: illegal padding %d", padding)
+	}
+
+	if int(padding+1) >= len(plain) {
+		return nil, fmt.Errorf("ssh: padding %d too large", padding)
+	}
+	plain = plain[1 : length-uint32(padding)]
+	return plain, nil
+}
+
+// cbcCipher implements aes128-cbc cipher defined in RFC 4253 section 6.1
+type cbcCipher struct {
+	mac       hash.Hash
+	macSize   uint32
+	decrypter cipher.BlockMode
+	encrypter cipher.BlockMode
+
+	// The following members are to avoid per-packet allocations.
+	seqNumBytes [4]byte
+	packetData  []byte
+	macResult   []byte
+
+	// Amount of data we should still read to hide which
+	// verification error triggered.
+	oracleCamouflage uint32
+}
+
+func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+	cbc := &cbcCipher{
+		mac:        macModes[algs.MAC].new(macKey),
+		decrypter:  cipher.NewCBCDecrypter(c, iv),
+		encrypter:  cipher.NewCBCEncrypter(c, iv),
+		packetData: make([]byte, 1024),
+	}
+	if cbc.mac != nil {
+		cbc.macSize = uint32(cbc.mac.Size())
+	}
+
+	return cbc, nil
+}
+
+func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+	c, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+
+	cbc, err := newCBCCipher(c, iv, key, macKey, algs)
+	if err != nil {
+		return nil, err
+	}
+
+	return cbc, nil
+}
+
+func newTripleDESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+	c, err := des.NewTripleDESCipher(key)
+	if err != nil {
+		return nil, err
+	}
+
+	cbc, err := newCBCCipher(c, iv, key, macKey, algs)
+	if err != nil {
+		return nil, err
+	}
+
+	return cbc, nil
+}
+
+func maxUInt32(a, b int) uint32 {
+	if a > b {
+		return uint32(a)
+	}
+	return uint32(b)
+}
+
+const (
+	cbcMinPacketSizeMultiple = 8
+	cbcMinPacketSize         = 16
+	cbcMinPaddingSize        = 4
+)
+
+// cbcError represents a verification error that may leak information.
+type cbcError string
+
+func (e cbcError) Error() string { return string(e) }
+
+func (c *cbcCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+	p, err := c.readPacketLeaky(seqNum, r)
+	if err != nil {
+		if _, ok := err.(cbcError); ok {
+			// Verification error: read a fixed amount of
+			// data, to make distinguishing between
+			// failing MAC and failing length check more
+			// difficult.
+			io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage))
+		}
+	}
+	return p, err
+}
+
+func (c *cbcCipher) readPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) {
+	blockSize := c.decrypter.BlockSize()
+
+	// Read the header, which will include some of the subsequent data in the
+	// case of block ciphers - this is copied back to the payload later.
+	// How many bytes of payload/padding will be read with this first read.
+	firstBlockLength := uint32((prefixLen + blockSize - 1) / blockSize * blockSize)
+	firstBlock := c.packetData[:firstBlockLength]
+	if _, err := io.ReadFull(r, firstBlock); err != nil {
+		return nil, err
+	}
+
+	c.oracleCamouflage = maxPacket + 4 + c.macSize - firstBlockLength
+
+	c.decrypter.CryptBlocks(firstBlock, firstBlock)
+	length := binary.BigEndian.Uint32(firstBlock[:4])
+	if length > maxPacket {
+		return nil, cbcError("ssh: packet too large")
+	}
+	if length+4 < maxUInt32(cbcMinPacketSize, blockSize) {
+		// The minimum size of a packet is 16 (or the cipher block size, whichever
+		// is larger) bytes.
+		return nil, cbcError("ssh: packet too small")
+	}
+	// The length of the packet (including the length field but not the MAC) must
+	// be a multiple of the block size or 8, whichever is larger.
+	if (length+4)%maxUInt32(cbcMinPacketSizeMultiple, blockSize) != 0 {
+		return nil, cbcError("ssh: invalid packet length multiple")
+	}
+
+	paddingLength := uint32(firstBlock[4])
+	if paddingLength < cbcMinPaddingSize || length <= paddingLength+1 {
+		return nil, cbcError("ssh: invalid packet length")
+	}
+
+	// Positions within the c.packetData buffer:
+	macStart := 4 + length
+	paddingStart := macStart - paddingLength
+
+	// Entire packet size, starting before length, ending at end of mac.
+	entirePacketSize := macStart + c.macSize
+
+	// Ensure c.packetData is large enough for the entire packet data.
+	if uint32(cap(c.packetData)) < entirePacketSize {
+		// Still need to upsize and copy, but this should be rare at runtime, only
+		// on upsizing the packetData buffer.
+		c.packetData = make([]byte, entirePacketSize)
+		copy(c.packetData, firstBlock)
+	} else {
+		c.packetData = c.packetData[:entirePacketSize]
+	}
+
+	if n, err := io.ReadFull(r, c.packetData[firstBlockLength:]); err != nil {
+		return nil, err
+	} else {
+		c.oracleCamouflage -= uint32(n)
+	}
+
+	remainingCrypted := c.packetData[firstBlockLength:macStart]
+	c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)
+
+	mac := c.packetData[macStart:]
+	if c.mac != nil {
+		c.mac.Reset()
+		binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
+		c.mac.Write(c.seqNumBytes[:])
+		c.mac.Write(c.packetData[:macStart])
+		c.macResult = c.mac.Sum(c.macResult[:0])
+		if subtle.ConstantTimeCompare(c.macResult, mac) != 1 {
+			return nil, cbcError("ssh: MAC failure")
+		}
+	}
+
+	return c.packetData[prefixLen:paddingStart], nil
+}
+
+func (c *cbcCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
+	effectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize())
+
+	// Length of encrypted portion of the packet (header, payload, padding).
+	// Enforce minimum padding and packet size.
+	encLength := maxUInt32(prefixLen+len(packet)+cbcMinPaddingSize, cbcMinPaddingSize)
+	// Enforce block size.
+	encLength = (encLength + effectiveBlockSize - 1) / effectiveBlockSize * effectiveBlockSize
+
+	length := encLength - 4
+	paddingLength := int(length) - (1 + len(packet))
+
+	// Overall buffer contains: header, payload, padding, mac.
+	// Space for the MAC is reserved in the capacity but not the slice length.
+	bufferSize := encLength + c.macSize
+	if uint32(cap(c.packetData)) < bufferSize {
+		c.packetData = make([]byte, encLength, bufferSize)
+	} else {
+		c.packetData = c.packetData[:encLength]
+	}
+
+	p := c.packetData
+
+	// Packet header.
+	binary.BigEndian.PutUint32(p, length)
+	p = p[4:]
+	p[0] = byte(paddingLength)
+
+	// Payload.
+	p = p[1:]
+	copy(p, packet)
+
+	// Padding.
+	p = p[len(packet):]
+	if _, err := io.ReadFull(rand, p); err != nil {
+		return err
+	}
+
+	if c.mac != nil {
+		c.mac.Reset()
+		binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
+		c.mac.Write(c.seqNumBytes[:])
+		c.mac.Write(c.packetData)
+		// The MAC is now appended into the capacity reserved for it earlier.
+		c.packetData = c.mac.Sum(c.packetData)
+	}
+
+	c.encrypter.CryptBlocks(c.packetData[:encLength], c.packetData[:encLength])
+
+	if _, err := w.Write(c.packetData); err != nil {
+		return err
+	}
+
+	return nil
+}

+ 257 - 0
vendor/golang.org/x/crypto/ssh/client.go

@@ -0,0 +1,257 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"net"
+	"sync"
+	"time"
+)
+
+// Client implements a traditional SSH client that supports shells,
+// subprocesses, TCP port/streamlocal forwarding and tunneled dialing.
+type Client struct {
+	Conn
+
+	forwards        forwardList // forwarded tcpip connections from the remote side
+	mu              sync.Mutex
+	channelHandlers map[string]chan NewChannel
+}
+
+// HandleChannelOpen returns a channel on which NewChannel requests
+// for the given type are sent. If the type already is being handled,
+// nil is returned. The channel is closed when the connection is closed.
+func (c *Client) HandleChannelOpen(channelType string) <-chan NewChannel {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.channelHandlers == nil {
+		// The SSH channel has been closed.
+		c := make(chan NewChannel)
+		close(c)
+		return c
+	}
+
+	ch := c.channelHandlers[channelType]
+	if ch != nil {
+		return nil
+	}
+
+	ch = make(chan NewChannel, chanSize)
+	c.channelHandlers[channelType] = ch
+	return ch
+}
+
+// NewClient creates a Client on top of the given connection.
+func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {
+	conn := &Client{
+		Conn:            c,
+		channelHandlers: make(map[string]chan NewChannel, 1),
+	}
+
+	go conn.handleGlobalRequests(reqs)
+	go conn.handleChannelOpens(chans)
+	go func() {
+		conn.Wait()
+		conn.forwards.closeAll()
+	}()
+	go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-tcpip"))
+	go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
+	return conn
+}
+
+// NewClientConn establishes an authenticated SSH connection using c
+// as the underlying transport.  The Request and NewChannel channels
+// must be serviced or the connection will hang.
+func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) {
+	fullConf := *config
+	fullConf.SetDefaults()
+	if fullConf.HostKeyCallback == nil {
+		c.Close()
+		return nil, nil, nil, errors.New("ssh: must specify HostKeyCallback")
+	}
+
+	conn := &connection{
+		sshConn: sshConn{conn: c},
+	}
+
+	if err := conn.clientHandshake(addr, &fullConf); err != nil {
+		c.Close()
+		return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err)
+	}
+	conn.mux = newMux(conn.transport)
+	return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
+}
+
+// clientHandshake performs the client side key exchange. See RFC 4253 Section
+// 7.
+func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error {
+	if config.ClientVersion != "" {
+		c.clientVersion = []byte(config.ClientVersion)
+	} else {
+		c.clientVersion = []byte(packageVersion)
+	}
+	var err error
+	c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion)
+	if err != nil {
+		return err
+	}
+
+	c.transport = newClientTransport(
+		newTransport(c.sshConn.conn, config.Rand, true /* is client */),
+		c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr())
+	if err := c.transport.waitSession(); err != nil {
+		return err
+	}
+
+	c.sessionID = c.transport.getSessionID()
+	return c.clientAuthenticate(config)
+}
+
+// verifyHostKeySignature verifies the host key obtained in the key
+// exchange.
+func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error {
+	sig, rest, ok := parseSignatureBody(result.Signature)
+	if len(rest) > 0 || !ok {
+		return errors.New("ssh: signature parse error")
+	}
+
+	return hostKey.Verify(result.H, sig)
+}
+
+// NewSession opens a new Session for this client. (A session is a remote
+// execution of a program.)
+func (c *Client) NewSession() (*Session, error) {
+	ch, in, err := c.OpenChannel("session", nil)
+	if err != nil {
+		return nil, err
+	}
+	return newSession(ch, in)
+}
+
+func (c *Client) handleGlobalRequests(incoming <-chan *Request) {
+	for r := range incoming {
+		// This handles keepalive messages and matches
+		// the behaviour of OpenSSH.
+		r.Reply(false, nil)
+	}
+}
+
+// handleChannelOpens channel open messages from the remote side.
+func (c *Client) handleChannelOpens(in <-chan NewChannel) {
+	for ch := range in {
+		c.mu.Lock()
+		handler := c.channelHandlers[ch.ChannelType()]
+		c.mu.Unlock()
+
+		if handler != nil {
+			handler <- ch
+		} else {
+			ch.Reject(UnknownChannelType, fmt.Sprintf("unknown channel type: %v", ch.ChannelType()))
+		}
+	}
+
+	c.mu.Lock()
+	for _, ch := range c.channelHandlers {
+		close(ch)
+	}
+	c.channelHandlers = nil
+	c.mu.Unlock()
+}
+
+// Dial starts a client connection to the given SSH server. It is a
+// convenience function that connects to the given network address,
+// initiates the SSH handshake, and then sets up a Client.  For access
+// to incoming channels and requests, use net.Dial with NewClientConn
+// instead.
+func Dial(network, addr string, config *ClientConfig) (*Client, error) {
+	conn, err := net.DialTimeout(network, addr, config.Timeout)
+	if err != nil {
+		return nil, err
+	}
+	c, chans, reqs, err := NewClientConn(conn, addr, config)
+	if err != nil {
+		return nil, err
+	}
+	return NewClient(c, chans, reqs), nil
+}
+
+// HostKeyCallback is the function type used for verifying server
+// keys.  A HostKeyCallback must return nil if the host key is OK, or
+// an error to reject it. It receives the hostname as passed to Dial
+// or NewClientConn. The remote address is the RemoteAddr of the
+// net.Conn underlying the the SSH connection.
+type HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error
+
+// A ClientConfig structure is used to configure a Client. It must not be
+// modified after having been passed to an SSH function.
+type ClientConfig struct {
+	// Config contains configuration that is shared between clients and
+	// servers.
+	Config
+
+	// User contains the username to authenticate as.
+	User string
+
+	// Auth contains possible authentication methods to use with the
+	// server. Only the first instance of a particular RFC 4252 method will
+	// be used during authentication.
+	Auth []AuthMethod
+
+	// HostKeyCallback is called during the cryptographic
+	// handshake to validate the server's host key. The client
+	// configuration must supply this callback for the connection
+	// to succeed. The functions InsecureIgnoreHostKey or
+	// FixedHostKey can be used for simplistic host key checks.
+	HostKeyCallback HostKeyCallback
+
+	// ClientVersion contains the version identification string that will
+	// be used for the connection. If empty, a reasonable default is used.
+	ClientVersion string
+
+	// HostKeyAlgorithms lists the key types that the client will
+	// accept from the server as host key, in order of
+	// preference. If empty, a reasonable default is used. Any
+	// string returned from PublicKey.Type method may be used, or
+	// any of the CertAlgoXxxx and KeyAlgoXxxx constants.
+	HostKeyAlgorithms []string
+
+	// Timeout is the maximum amount of time for the TCP connection to establish.
+	//
+	// A Timeout of zero means no timeout.
+	Timeout time.Duration
+}
+
+// InsecureIgnoreHostKey returns a function that can be used for
+// ClientConfig.HostKeyCallback to accept any host key. It should
+// not be used for production code.
+func InsecureIgnoreHostKey() HostKeyCallback {
+	return func(hostname string, remote net.Addr, key PublicKey) error {
+		return nil
+	}
+}
+
+type fixedHostKey struct {
+	key PublicKey
+}
+
+func (f *fixedHostKey) check(hostname string, remote net.Addr, key PublicKey) error {
+	if f.key == nil {
+		return fmt.Errorf("ssh: required host key was nil")
+	}
+	if !bytes.Equal(key.Marshal(), f.key.Marshal()) {
+		return fmt.Errorf("ssh: host key mismatch")
+	}
+	return nil
+}
+
+// FixedHostKey returns a function for use in
+// ClientConfig.HostKeyCallback to accept only a specific host key.
+func FixedHostKey(key PublicKey) HostKeyCallback {
+	hk := &fixedHostKey{key}
+	return hk.check
+}

+ 486 - 0
vendor/golang.org/x/crypto/ssh/client_auth.go

@@ -0,0 +1,486 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// clientAuthenticate authenticates with the remote server. See RFC 4252.
+func (c *connection) clientAuthenticate(config *ClientConfig) error {
+	// initiate user auth session
+	if err := c.transport.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})); err != nil {
+		return err
+	}
+	packet, err := c.transport.readPacket()
+	if err != nil {
+		return err
+	}
+	var serviceAccept serviceAcceptMsg
+	if err := Unmarshal(packet, &serviceAccept); err != nil {
+		return err
+	}
+
+	// during the authentication phase the client first attempts the "none" method
+	// then any untried methods suggested by the server.
+	tried := make(map[string]bool)
+	var lastMethods []string
+
+	sessionID := c.transport.getSessionID()
+	for auth := AuthMethod(new(noneAuth)); auth != nil; {
+		ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand)
+		if err != nil {
+			return err
+		}
+		if ok {
+			// success
+			return nil
+		}
+		tried[auth.method()] = true
+		if methods == nil {
+			methods = lastMethods
+		}
+		lastMethods = methods
+
+		auth = nil
+
+	findNext:
+		for _, a := range config.Auth {
+			candidateMethod := a.method()
+			if tried[candidateMethod] {
+				continue
+			}
+			for _, meth := range methods {
+				if meth == candidateMethod {
+					auth = a
+					break findNext
+				}
+			}
+		}
+	}
+	return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", keys(tried))
+}
+
+func keys(m map[string]bool) []string {
+	s := make([]string, 0, len(m))
+
+	for key := range m {
+		s = append(s, key)
+	}
+	return s
+}
+
+// An AuthMethod represents an instance of an RFC 4252 authentication method.
+type AuthMethod interface {
+	// auth authenticates user over transport t.
+	// Returns true if authentication is successful.
+	// If authentication is not successful, a []string of alternative
+	// method names is returned. If the slice is nil, it will be ignored
+	// and the previous set of possible methods will be reused.
+	auth(session []byte, user string, p packetConn, rand io.Reader) (bool, []string, error)
+
+	// method returns the RFC 4252 method name.
+	method() string
+}
+
+// "none" authentication, RFC 4252 section 5.2.
+type noneAuth int
+
+func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+	if err := c.writePacket(Marshal(&userAuthRequestMsg{
+		User:    user,
+		Service: serviceSSH,
+		Method:  "none",
+	})); err != nil {
+		return false, nil, err
+	}
+
+	return handleAuthResponse(c)
+}
+
+func (n *noneAuth) method() string {
+	return "none"
+}
+
+// passwordCallback is an AuthMethod that fetches the password through
+// a function call, e.g. by prompting the user.
+type passwordCallback func() (password string, err error)
+
+func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+	type passwordAuthMsg struct {
+		User     string `sshtype:"50"`
+		Service  string
+		Method   string
+		Reply    bool
+		Password string
+	}
+
+	pw, err := cb()
+	// REVIEW NOTE: is there a need to support skipping a password attempt?
+	// The program may only find out that the user doesn't have a password
+	// when prompting.
+	if err != nil {
+		return false, nil, err
+	}
+
+	if err := c.writePacket(Marshal(&passwordAuthMsg{
+		User:     user,
+		Service:  serviceSSH,
+		Method:   cb.method(),
+		Reply:    false,
+		Password: pw,
+	})); err != nil {
+		return false, nil, err
+	}
+
+	return handleAuthResponse(c)
+}
+
+func (cb passwordCallback) method() string {
+	return "password"
+}
+
+// Password returns an AuthMethod using the given password.
+func Password(secret string) AuthMethod {
+	return passwordCallback(func() (string, error) { return secret, nil })
+}
+
+// PasswordCallback returns an AuthMethod that uses a callback for
+// fetching a password.
+func PasswordCallback(prompt func() (secret string, err error)) AuthMethod {
+	return passwordCallback(prompt)
+}
+
+type publickeyAuthMsg struct {
+	User    string `sshtype:"50"`
+	Service string
+	Method  string
+	// HasSig indicates to the receiver packet that the auth request is signed and
+	// should be used for authentication of the request.
+	HasSig   bool
+	Algoname string
+	PubKey   []byte
+	// Sig is tagged with "rest" so Marshal will exclude it during
+	// validateKey
+	Sig []byte `ssh:"rest"`
+}
+
+// publicKeyCallback is an AuthMethod that uses a set of key
+// pairs for authentication.
+type publicKeyCallback func() ([]Signer, error)
+
+func (cb publicKeyCallback) method() string {
+	return "publickey"
+}
+
+func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+	// Authentication is performed by sending an enquiry to test if a key is
+	// acceptable to the remote. If the key is acceptable, the client will
+	// attempt to authenticate with the valid key.  If not the client will repeat
+	// the process with the remaining keys.
+
+	signers, err := cb()
+	if err != nil {
+		return false, nil, err
+	}
+	var methods []string
+	for _, signer := range signers {
+		ok, err := validateKey(signer.PublicKey(), user, c)
+		if err != nil {
+			return false, nil, err
+		}
+		if !ok {
+			continue
+		}
+
+		pub := signer.PublicKey()
+		pubKey := pub.Marshal()
+		sign, err := signer.Sign(rand, buildDataSignedForAuth(session, userAuthRequestMsg{
+			User:    user,
+			Service: serviceSSH,
+			Method:  cb.method(),
+		}, []byte(pub.Type()), pubKey))
+		if err != nil {
+			return false, nil, err
+		}
+
+		// manually wrap the serialized signature in a string
+		s := Marshal(sign)
+		sig := make([]byte, stringLength(len(s)))
+		marshalString(sig, s)
+		msg := publickeyAuthMsg{
+			User:     user,
+			Service:  serviceSSH,
+			Method:   cb.method(),
+			HasSig:   true,
+			Algoname: pub.Type(),
+			PubKey:   pubKey,
+			Sig:      sig,
+		}
+		p := Marshal(&msg)
+		if err := c.writePacket(p); err != nil {
+			return false, nil, err
+		}
+		var success bool
+		success, methods, err = handleAuthResponse(c)
+		if err != nil {
+			return false, nil, err
+		}
+
+		// If authentication succeeds or the list of available methods does not
+		// contain the "publickey" method, do not attempt to authenticate with any
+		// other keys.  According to RFC 4252 Section 7, the latter can occur when
+		// additional authentication methods are required.
+		if success || !containsMethod(methods, cb.method()) {
+			return success, methods, err
+		}
+	}
+
+	return false, methods, nil
+}
+
+func containsMethod(methods []string, method string) bool {
+	for _, m := range methods {
+		if m == method {
+			return true
+		}
+	}
+
+	return false
+}
+
+// validateKey validates the key provided is acceptable to the server.
+func validateKey(key PublicKey, user string, c packetConn) (bool, error) {
+	pubKey := key.Marshal()
+	msg := publickeyAuthMsg{
+		User:     user,
+		Service:  serviceSSH,
+		Method:   "publickey",
+		HasSig:   false,
+		Algoname: key.Type(),
+		PubKey:   pubKey,
+	}
+	if err := c.writePacket(Marshal(&msg)); err != nil {
+		return false, err
+	}
+
+	return confirmKeyAck(key, c)
+}
+
+func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
+	pubKey := key.Marshal()
+	algoname := key.Type()
+
+	for {
+		packet, err := c.readPacket()
+		if err != nil {
+			return false, err
+		}
+		switch packet[0] {
+		case msgUserAuthBanner:
+			// TODO(gpaul): add callback to present the banner to the user
+		case msgUserAuthPubKeyOk:
+			var msg userAuthPubKeyOkMsg
+			if err := Unmarshal(packet, &msg); err != nil {
+				return false, err
+			}
+			if msg.Algo != algoname || !bytes.Equal(msg.PubKey, pubKey) {
+				return false, nil
+			}
+			return true, nil
+		case msgUserAuthFailure:
+			return false, nil
+		default:
+			return false, unexpectedMessageError(msgUserAuthSuccess, packet[0])
+		}
+	}
+}
+
+// PublicKeys returns an AuthMethod that uses the given key
+// pairs.
+func PublicKeys(signers ...Signer) AuthMethod {
+	return publicKeyCallback(func() ([]Signer, error) { return signers, nil })
+}
+
+// PublicKeysCallback returns an AuthMethod that runs the given
+// function to obtain a list of key pairs.
+func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod {
+	return publicKeyCallback(getSigners)
+}
+
+// handleAuthResponse returns whether the preceding authentication request succeeded
+// along with a list of remaining authentication methods to try next and
+// an error if an unexpected response was received.
+func handleAuthResponse(c packetConn) (bool, []string, error) {
+	for {
+		packet, err := c.readPacket()
+		if err != nil {
+			return false, nil, err
+		}
+
+		switch packet[0] {
+		case msgUserAuthBanner:
+			// TODO: add callback to present the banner to the user
+		case msgUserAuthFailure:
+			var msg userAuthFailureMsg
+			if err := Unmarshal(packet, &msg); err != nil {
+				return false, nil, err
+			}
+			return false, msg.Methods, nil
+		case msgUserAuthSuccess:
+			return true, nil, nil
+		default:
+			return false, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
+		}
+	}
+}
+
+// KeyboardInteractiveChallenge should print questions, optionally
+// disabling echoing (e.g. for passwords), and return all the answers.
+// Challenge may be called multiple times in a single session. After
+// successful authentication, the server may send a challenge with no
+// questions, for which the user and instruction messages should be
+// printed.  RFC 4256 section 3.3 details how the UI should behave for
+// both CLI and GUI environments.
+type KeyboardInteractiveChallenge func(user, instruction string, questions []string, echos []bool) (answers []string, err error)
+
+// KeyboardInteractive returns an AuthMethod using a prompt/response
+// sequence controlled by the server.
+func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod {
+	return challenge
+}
+
+func (cb KeyboardInteractiveChallenge) method() string {
+	return "keyboard-interactive"
+}
+
+func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+	type initiateMsg struct {
+		User       string `sshtype:"50"`
+		Service    string
+		Method     string
+		Language   string
+		Submethods string
+	}
+
+	if err := c.writePacket(Marshal(&initiateMsg{
+		User:    user,
+		Service: serviceSSH,
+		Method:  "keyboard-interactive",
+	})); err != nil {
+		return false, nil, err
+	}
+
+	for {
+		packet, err := c.readPacket()
+		if err != nil {
+			return false, nil, err
+		}
+
+		// like handleAuthResponse, but with less options.
+		switch packet[0] {
+		case msgUserAuthBanner:
+			// TODO: Print banners during userauth.
+			continue
+		case msgUserAuthInfoRequest:
+			// OK
+		case msgUserAuthFailure:
+			var msg userAuthFailureMsg
+			if err := Unmarshal(packet, &msg); err != nil {
+				return false, nil, err
+			}
+			return false, msg.Methods, nil
+		case msgUserAuthSuccess:
+			return true, nil, nil
+		default:
+			return false, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
+		}
+
+		var msg userAuthInfoRequestMsg
+		if err := Unmarshal(packet, &msg); err != nil {
+			return false, nil, err
+		}
+
+		// Manually unpack the prompt/echo pairs.
+		rest := msg.Prompts
+		var prompts []string
+		var echos []bool
+		for i := 0; i < int(msg.NumPrompts); i++ {
+			prompt, r, ok := parseString(rest)
+			if !ok || len(r) == 0 {
+				return false, nil, errors.New("ssh: prompt format error")
+			}
+			prompts = append(prompts, string(prompt))
+			echos = append(echos, r[0] != 0)
+			rest = r[1:]
+		}
+
+		if len(rest) != 0 {
+			return false, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
+		}
+
+		answers, err := cb(msg.User, msg.Instruction, prompts, echos)
+		if err != nil {
+			return false, nil, err
+		}
+
+		if len(answers) != len(prompts) {
+			return false, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
+		}
+		responseLength := 1 + 4
+		for _, a := range answers {
+			responseLength += stringLength(len(a))
+		}
+		serialized := make([]byte, responseLength)
+		p := serialized
+		p[0] = msgUserAuthInfoResponse
+		p = p[1:]
+		p = marshalUint32(p, uint32(len(answers)))
+		for _, a := range answers {
+			p = marshalString(p, []byte(a))
+		}
+
+		if err := c.writePacket(serialized); err != nil {
+			return false, nil, err
+		}
+	}
+}
+
+type retryableAuthMethod struct {
+	authMethod AuthMethod
+	maxTries   int
+}
+
+func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok bool, methods []string, err error) {
+	for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
+		ok, methods, err = r.authMethod.auth(session, user, c, rand)
+		if ok || err != nil { // either success or error terminate
+			return ok, methods, err
+		}
+	}
+	return ok, methods, err
+}
+
+func (r *retryableAuthMethod) method() string {
+	return r.authMethod.method()
+}
+
+// RetryableAuthMethod is a decorator for other auth methods enabling them to
+// be retried up to maxTries before considering that AuthMethod itself failed.
+// If maxTries is <= 0, will retry indefinitely
+//
+// This is useful for interactive clients using challenge/response type
+// authentication (e.g. Keyboard-Interactive, Password, etc) where the user
+// could mistype their response resulting in the server issuing a
+// SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4
+// [keyboard-interactive]); Without this decorator, the non-retryable
+// AuthMethod would be removed from future consideration, and never tried again
+// (and so the user would never be able to retry their entry).
+func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {
+	return &retryableAuthMethod{authMethod: auth, maxTries: maxTries}
+}

+ 373 - 0
vendor/golang.org/x/crypto/ssh/common.go

@@ -0,0 +1,373 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"crypto"
+	"crypto/rand"
+	"fmt"
+	"io"
+	"math"
+	"sync"
+
+	_ "crypto/sha1"
+	_ "crypto/sha256"
+	_ "crypto/sha512"
+)
+
+// These are string constants in the SSH protocol.
+const (
+	compressionNone = "none"
+	serviceUserAuth = "ssh-userauth"
+	serviceSSH      = "ssh-connection"
+)
+
+// supportedCiphers specifies the supported ciphers in preference order.
+var supportedCiphers = []string{
+	"aes128-ctr", "aes192-ctr", "aes256-ctr",
+	"aes128-gcm@openssh.com",
+	"arcfour256", "arcfour128",
+}
+
+// supportedKexAlgos specifies the supported key-exchange algorithms in
+// preference order.
+var supportedKexAlgos = []string{
+	kexAlgoCurve25519SHA256,
+	// P384 and P521 are not constant-time yet, but since we don't
+	// reuse ephemeral keys, using them for ECDH should be OK.
+	kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
+	kexAlgoDH14SHA1, kexAlgoDH1SHA1,
+}
+
+// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
+// of authenticating servers) in preference order.
+var supportedHostKeyAlgos = []string{
+	CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
+	CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
+
+	KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
+	KeyAlgoRSA, KeyAlgoDSA,
+
+	KeyAlgoED25519,
+}
+
+// supportedMACs specifies a default set of MAC algorithms in preference order.
+// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed
+// because they have reached the end of their useful life.
+var supportedMACs = []string{
+	"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96",
+}
+
+var supportedCompressions = []string{compressionNone}
+
+// hashFuncs keeps the mapping of supported algorithms to their respective
+// hashes needed for signature verification.
+var hashFuncs = map[string]crypto.Hash{
+	KeyAlgoRSA:          crypto.SHA1,
+	KeyAlgoDSA:          crypto.SHA1,
+	KeyAlgoECDSA256:     crypto.SHA256,
+	KeyAlgoECDSA384:     crypto.SHA384,
+	KeyAlgoECDSA521:     crypto.SHA512,
+	CertAlgoRSAv01:      crypto.SHA1,
+	CertAlgoDSAv01:      crypto.SHA1,
+	CertAlgoECDSA256v01: crypto.SHA256,
+	CertAlgoECDSA384v01: crypto.SHA384,
+	CertAlgoECDSA521v01: crypto.SHA512,
+}
+
+// unexpectedMessageError results when the SSH message that we received didn't
+// match what we wanted.
+func unexpectedMessageError(expected, got uint8) error {
+	return fmt.Errorf("ssh: unexpected message type %d (expected %d)", got, expected)
+}
+
+// parseError results from a malformed SSH message.
+func parseError(tag uint8) error {
+	return fmt.Errorf("ssh: parse error in message type %d", tag)
+}
+
+func findCommon(what string, client []string, server []string) (common string, err error) {
+	for _, c := range client {
+		for _, s := range server {
+			if c == s {
+				return c, nil
+			}
+		}
+	}
+	return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server)
+}
+
+type directionAlgorithms struct {
+	Cipher      string
+	MAC         string
+	Compression string
+}
+
+// rekeyBytes returns a rekeying intervals in bytes.
+func (a *directionAlgorithms) rekeyBytes() int64 {
+	// According to RFC4344 block ciphers should rekey after
+	// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
+	// 128.
+	switch a.Cipher {
+	case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcmCipherID, aes128cbcID:
+		return 16 * (1 << 32)
+
+	}
+
+	// For others, stick with RFC4253 recommendation to rekey after 1 Gb of data.
+	return 1 << 30
+}
+
+type algorithms struct {
+	kex     string
+	hostKey string
+	w       directionAlgorithms
+	r       directionAlgorithms
+}
+
+func findAgreedAlgorithms(clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) {
+	result := &algorithms{}
+
+	result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos)
+	if err != nil {
+		return
+	}
+
+	result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos)
+	if err != nil {
+		return
+	}
+
+	result.w.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer)
+	if err != nil {
+		return
+	}
+
+	result.r.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient)
+	if err != nil {
+		return
+	}
+
+	result.w.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
+	if err != nil {
+		return
+	}
+
+	result.r.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
+	if err != nil {
+		return
+	}
+
+	result.w.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
+	if err != nil {
+		return
+	}
+
+	result.r.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
+	if err != nil {
+		return
+	}
+
+	return result, nil
+}
+
+// If rekeythreshold is too small, we can't make any progress sending
+// stuff.
+const minRekeyThreshold uint64 = 256
+
+// Config contains configuration data common to both ServerConfig and
+// ClientConfig.
+type Config struct {
+	// Rand provides the source of entropy for cryptographic
+	// primitives. If Rand is nil, the cryptographic random reader
+	// in package crypto/rand will be used.
+	Rand io.Reader
+
+	// The maximum number of bytes sent or received after which a
+	// new key is negotiated. It must be at least 256. If
+	// unspecified, a size suitable for the chosen cipher is used.
+	RekeyThreshold uint64
+
+	// The allowed key exchanges algorithms. If unspecified then a
+	// default set of algorithms is used.
+	KeyExchanges []string
+
+	// The allowed cipher algorithms. If unspecified then a sensible
+	// default is used.
+	Ciphers []string
+
+	// The allowed MAC algorithms. If unspecified then a sensible default
+	// is used.
+	MACs []string
+}
+
+// SetDefaults sets sensible values for unset fields in config. This is
+// exported for testing: Configs passed to SSH functions are copied and have
+// default values set automatically.
+func (c *Config) SetDefaults() {
+	if c.Rand == nil {
+		c.Rand = rand.Reader
+	}
+	if c.Ciphers == nil {
+		c.Ciphers = supportedCiphers
+	}
+	var ciphers []string
+	for _, c := range c.Ciphers {
+		if cipherModes[c] != nil {
+			// reject the cipher if we have no cipherModes definition
+			ciphers = append(ciphers, c)
+		}
+	}
+	c.Ciphers = ciphers
+
+	if c.KeyExchanges == nil {
+		c.KeyExchanges = supportedKexAlgos
+	}
+
+	if c.MACs == nil {
+		c.MACs = supportedMACs
+	}
+
+	if c.RekeyThreshold == 0 {
+		// cipher specific default
+	} else if c.RekeyThreshold < minRekeyThreshold {
+		c.RekeyThreshold = minRekeyThreshold
+	} else if c.RekeyThreshold >= math.MaxInt64 {
+		// Avoid weirdness if somebody uses -1 as a threshold.
+		c.RekeyThreshold = math.MaxInt64
+	}
+}
+
+// buildDataSignedForAuth returns the data that is signed in order to prove
+// possession of a private key. See RFC 4252, section 7.
+func buildDataSignedForAuth(sessionId []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte {
+	data := struct {
+		Session []byte
+		Type    byte
+		User    string
+		Service string
+		Method  string
+		Sign    bool
+		Algo    []byte
+		PubKey  []byte
+	}{
+		sessionId,
+		msgUserAuthRequest,
+		req.User,
+		req.Service,
+		req.Method,
+		true,
+		algo,
+		pubKey,
+	}
+	return Marshal(data)
+}
+
+func appendU16(buf []byte, n uint16) []byte {
+	return append(buf, byte(n>>8), byte(n))
+}
+
+func appendU32(buf []byte, n uint32) []byte {
+	return append(buf, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
+}
+
+func appendU64(buf []byte, n uint64) []byte {
+	return append(buf,
+		byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32),
+		byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
+}
+
+func appendInt(buf []byte, n int) []byte {
+	return appendU32(buf, uint32(n))
+}
+
+func appendString(buf []byte, s string) []byte {
+	buf = appendU32(buf, uint32(len(s)))
+	buf = append(buf, s...)
+	return buf
+}
+
+func appendBool(buf []byte, b bool) []byte {
+	if b {
+		return append(buf, 1)
+	}
+	return append(buf, 0)
+}
+
+// newCond is a helper to hide the fact that there is no usable zero
+// value for sync.Cond.
+func newCond() *sync.Cond { return sync.NewCond(new(sync.Mutex)) }
+
+// window represents the buffer available to clients
+// wishing to write to a channel.
+type window struct {
+	*sync.Cond
+	win          uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1
+	writeWaiters int
+	closed       bool
+}
+
+// add adds win to the amount of window available
+// for consumers.
+func (w *window) add(win uint32) bool {
+	// a zero sized window adjust is a noop.
+	if win == 0 {
+		return true
+	}
+	w.L.Lock()
+	if w.win+win < win {
+		w.L.Unlock()
+		return false
+	}
+	w.win += win
+	// It is unusual that multiple goroutines would be attempting to reserve
+	// window space, but not guaranteed. Use broadcast to notify all waiters
+	// that additional window is available.
+	w.Broadcast()
+	w.L.Unlock()
+	return true
+}
+
+// close sets the window to closed, so all reservations fail
+// immediately.
+func (w *window) close() {
+	w.L.Lock()
+	w.closed = true
+	w.Broadcast()
+	w.L.Unlock()
+}
+
+// reserve reserves win from the available window capacity.
+// If no capacity remains, reserve will block. reserve may
+// return less than requested.
+func (w *window) reserve(win uint32) (uint32, error) {
+	var err error
+	w.L.Lock()
+	w.writeWaiters++
+	w.Broadcast()
+	for w.win == 0 && !w.closed {
+		w.Wait()
+	}
+	w.writeWaiters--
+	if w.win < win {
+		win = w.win
+	}
+	w.win -= win
+	if w.closed {
+		err = io.EOF
+	}
+	w.L.Unlock()
+	return win, err
+}
+
+// waitWriterBlocked waits until some goroutine is blocked for further
+// writes. It is used in tests only.
+func (w *window) waitWriterBlocked() {
+	w.Cond.L.Lock()
+	for w.writeWaiters == 0 {
+		w.Cond.Wait()
+	}
+	w.Cond.L.Unlock()
+}

+ 143 - 0
vendor/golang.org/x/crypto/ssh/connection.go

@@ -0,0 +1,143 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"fmt"
+	"net"
+)
+
+// OpenChannelError is returned if the other side rejects an
+// OpenChannel request.
+type OpenChannelError struct {
+	Reason  RejectionReason
+	Message string
+}
+
+func (e *OpenChannelError) Error() string {
+	return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message)
+}
+
+// ConnMetadata holds metadata for the connection.
+type ConnMetadata interface {
+	// User returns the user ID for this connection.
+	User() string
+
+	// SessionID returns the session hash, also denoted by H.
+	SessionID() []byte
+
+	// ClientVersion returns the client's version string as hashed
+	// into the session ID.
+	ClientVersion() []byte
+
+	// ServerVersion returns the server's version string as hashed
+	// into the session ID.
+	ServerVersion() []byte
+
+	// RemoteAddr returns the remote address for this connection.
+	RemoteAddr() net.Addr
+
+	// LocalAddr returns the local address for this connection.
+	LocalAddr() net.Addr
+}
+
+// Conn represents an SSH connection for both server and client roles.
+// Conn is the basis for implementing an application layer, such
+// as ClientConn, which implements the traditional shell access for
+// clients.
+type Conn interface {
+	ConnMetadata
+
+	// SendRequest sends a global request, and returns the
+	// reply. If wantReply is true, it returns the response status
+	// and payload. See also RFC4254, section 4.
+	SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
+
+	// OpenChannel tries to open an channel. If the request is
+	// rejected, it returns *OpenChannelError. On success it returns
+	// the SSH Channel and a Go channel for incoming, out-of-band
+	// requests. The Go channel must be serviced, or the
+	// connection will hang.
+	OpenChannel(name string, data []byte) (Channel, <-chan *Request, error)
+
+	// Close closes the underlying network connection
+	Close() error
+
+	// Wait blocks until the connection has shut down, and returns the
+	// error causing the shutdown.
+	Wait() error
+
+	// TODO(hanwen): consider exposing:
+	//   RequestKeyChange
+	//   Disconnect
+}
+
+// DiscardRequests consumes and rejects all requests from the
+// passed-in channel.
+func DiscardRequests(in <-chan *Request) {
+	for req := range in {
+		if req.WantReply {
+			req.Reply(false, nil)
+		}
+	}
+}
+
+// A connection represents an incoming connection.
+type connection struct {
+	transport *handshakeTransport
+	sshConn
+
+	// The connection protocol.
+	*mux
+}
+
+func (c *connection) Close() error {
+	return c.sshConn.conn.Close()
+}
+
+// sshconn provides net.Conn metadata, but disallows direct reads and
+// writes.
+type sshConn struct {
+	conn net.Conn
+
+	user          string
+	sessionID     []byte
+	clientVersion []byte
+	serverVersion []byte
+}
+
+func dup(src []byte) []byte {
+	dst := make([]byte, len(src))
+	copy(dst, src)
+	return dst
+}
+
+func (c *sshConn) User() string {
+	return c.user
+}
+
+func (c *sshConn) RemoteAddr() net.Addr {
+	return c.conn.RemoteAddr()
+}
+
+func (c *sshConn) Close() error {
+	return c.conn.Close()
+}
+
+func (c *sshConn) LocalAddr() net.Addr {
+	return c.conn.LocalAddr()
+}
+
+func (c *sshConn) SessionID() []byte {
+	return dup(c.sessionID)
+}
+
+func (c *sshConn) ClientVersion() []byte {
+	return dup(c.clientVersion)
+}
+
+func (c *sshConn) ServerVersion() []byte {
+	return dup(c.serverVersion)
+}

+ 21 - 0
vendor/golang.org/x/crypto/ssh/doc.go

@@ -0,0 +1,21 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package ssh implements an SSH client and server.
+
+SSH is a transport security protocol, an authentication protocol and a
+family of application protocols. The most typical application level
+protocol is a remote shell and this is specifically implemented.  However,
+the multiplexed nature of SSH is exposed to users that wish to support
+others.
+
+References:
+  [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
+  [SSH-PARAMETERS]:    http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
+
+This package does not fall under the stability promise of the Go language itself,
+so its API may be changed when pressing needs arise.
+*/
+package ssh // import "golang.org/x/crypto/ssh"

+ 640 - 0
vendor/golang.org/x/crypto/ssh/handshake.go

@@ -0,0 +1,640 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"crypto/rand"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"sync"
+)
+
+// debugHandshake, if set, prints messages sent and received.  Key
+// exchange messages are printed as if DH were used, so the debug
+// messages are wrong when using ECDH.
+const debugHandshake = false
+
+// chanSize sets the amount of buffering SSH connections. This is
+// primarily for testing: setting chanSize=0 uncovers deadlocks more
+// quickly.
+const chanSize = 16
+
+// keyingTransport is a packet based transport that supports key
+// changes. It need not be thread-safe. It should pass through
+// msgNewKeys in both directions.
+type keyingTransport interface {
+	packetConn
+
+	// prepareKeyChange sets up a key change. The key change for a
+	// direction will be effected if a msgNewKeys message is sent
+	// or received.
+	prepareKeyChange(*algorithms, *kexResult) error
+}
+
+// handshakeTransport implements rekeying on top of a keyingTransport
+// and offers a thread-safe writePacket() interface.
+type handshakeTransport struct {
+	conn   keyingTransport
+	config *Config
+
+	serverVersion []byte
+	clientVersion []byte
+
+	// hostKeys is non-empty if we are the server. In that case,
+	// it contains all host keys that can be used to sign the
+	// connection.
+	hostKeys []Signer
+
+	// hostKeyAlgorithms is non-empty if we are the client. In that case,
+	// we accept these key types from the server as host key.
+	hostKeyAlgorithms []string
+
+	// On read error, incoming is closed, and readError is set.
+	incoming  chan []byte
+	readError error
+
+	mu             sync.Mutex
+	writeError     error
+	sentInitPacket []byte
+	sentInitMsg    *kexInitMsg
+	pendingPackets [][]byte // Used when a key exchange is in progress.
+
+	// If the read loop wants to schedule a kex, it pings this
+	// channel, and the write loop will send out a kex
+	// message.
+	requestKex chan struct{}
+
+	// If the other side requests or confirms a kex, its kexInit
+	// packet is sent here for the write loop to find it.
+	startKex chan *pendingKex
+
+	// data for host key checking
+	hostKeyCallback HostKeyCallback
+	dialAddress     string
+	remoteAddr      net.Addr
+
+	// Algorithms agreed in the last key exchange.
+	algorithms *algorithms
+
+	readPacketsLeft uint32
+	readBytesLeft   int64
+
+	writePacketsLeft uint32
+	writeBytesLeft   int64
+
+	// The session ID or nil if first kex did not complete yet.
+	sessionID []byte
+}
+
+type pendingKex struct {
+	otherInit []byte
+	done      chan error
+}
+
+func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport {
+	t := &handshakeTransport{
+		conn:          conn,
+		serverVersion: serverVersion,
+		clientVersion: clientVersion,
+		incoming:      make(chan []byte, chanSize),
+		requestKex:    make(chan struct{}, 1),
+		startKex:      make(chan *pendingKex, 1),
+
+		config: config,
+	}
+	t.resetReadThresholds()
+	t.resetWriteThresholds()
+
+	// We always start with a mandatory key exchange.
+	t.requestKex <- struct{}{}
+	return t
+}
+
+func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport {
+	t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
+	t.dialAddress = dialAddr
+	t.remoteAddr = addr
+	t.hostKeyCallback = config.HostKeyCallback
+	if config.HostKeyAlgorithms != nil {
+		t.hostKeyAlgorithms = config.HostKeyAlgorithms
+	} else {
+		t.hostKeyAlgorithms = supportedHostKeyAlgos
+	}
+	go t.readLoop()
+	go t.kexLoop()
+	return t
+}
+
+func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport {
+	t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
+	t.hostKeys = config.hostKeys
+	go t.readLoop()
+	go t.kexLoop()
+	return t
+}
+
+func (t *handshakeTransport) getSessionID() []byte {
+	return t.sessionID
+}
+
+// waitSession waits for the session to be established. This should be
+// the first thing to call after instantiating handshakeTransport.
+func (t *handshakeTransport) waitSession() error {
+	p, err := t.readPacket()
+	if err != nil {
+		return err
+	}
+	if p[0] != msgNewKeys {
+		return fmt.Errorf("ssh: first packet should be msgNewKeys")
+	}
+
+	return nil
+}
+
+func (t *handshakeTransport) id() string {
+	if len(t.hostKeys) > 0 {
+		return "server"
+	}
+	return "client"
+}
+
+func (t *handshakeTransport) printPacket(p []byte, write bool) {
+	action := "got"
+	if write {
+		action = "sent"
+	}
+
+	if p[0] == msgChannelData || p[0] == msgChannelExtendedData {
+		log.Printf("%s %s data (packet %d bytes)", t.id(), action, len(p))
+	} else {
+		msg, err := decode(p)
+		log.Printf("%s %s %T %v (%v)", t.id(), action, msg, msg, err)
+	}
+}
+
+func (t *handshakeTransport) readPacket() ([]byte, error) {
+	p, ok := <-t.incoming
+	if !ok {
+		return nil, t.readError
+	}
+	return p, nil
+}
+
+func (t *handshakeTransport) readLoop() {
+	first := true
+	for {
+		p, err := t.readOnePacket(first)
+		first = false
+		if err != nil {
+			t.readError = err
+			close(t.incoming)
+			break
+		}
+		if p[0] == msgIgnore || p[0] == msgDebug {
+			continue
+		}
+		t.incoming <- p
+	}
+
+	// Stop writers too.
+	t.recordWriteError(t.readError)
+
+	// Unblock the writer should it wait for this.
+	close(t.startKex)
+
+	// Don't close t.requestKex; it's also written to from writePacket.
+}
+
+func (t *handshakeTransport) pushPacket(p []byte) error {
+	if debugHandshake {
+		t.printPacket(p, true)
+	}
+	return t.conn.writePacket(p)
+}
+
+func (t *handshakeTransport) getWriteError() error {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	return t.writeError
+}
+
+func (t *handshakeTransport) recordWriteError(err error) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.writeError == nil && err != nil {
+		t.writeError = err
+	}
+}
+
+func (t *handshakeTransport) requestKeyExchange() {
+	select {
+	case t.requestKex <- struct{}{}:
+	default:
+		// something already requested a kex, so do nothing.
+	}
+}
+
+func (t *handshakeTransport) resetWriteThresholds() {
+	t.writePacketsLeft = packetRekeyThreshold
+	if t.config.RekeyThreshold > 0 {
+		t.writeBytesLeft = int64(t.config.RekeyThreshold)
+	} else if t.algorithms != nil {
+		t.writeBytesLeft = t.algorithms.w.rekeyBytes()
+	} else {
+		t.writeBytesLeft = 1 << 30
+	}
+}
+
+func (t *handshakeTransport) kexLoop() {
+
+write:
+	for t.getWriteError() == nil {
+		var request *pendingKex
+		var sent bool
+
+		for request == nil || !sent {
+			var ok bool
+			select {
+			case request, ok = <-t.startKex:
+				if !ok {
+					break write
+				}
+			case <-t.requestKex:
+				break
+			}
+
+			if !sent {
+				if err := t.sendKexInit(); err != nil {
+					t.recordWriteError(err)
+					break
+				}
+				sent = true
+			}
+		}
+
+		if err := t.getWriteError(); err != nil {
+			if request != nil {
+				request.done <- err
+			}
+			break
+		}
+
+		// We're not servicing t.requestKex, but that is OK:
+		// we never block on sending to t.requestKex.
+
+		// We're not servicing t.startKex, but the remote end
+		// has just sent us a kexInitMsg, so it can't send
+		// another key change request, until we close the done
+		// channel on the pendingKex request.
+
+		err := t.enterKeyExchange(request.otherInit)
+
+		t.mu.Lock()
+		t.writeError = err
+		t.sentInitPacket = nil
+		t.sentInitMsg = nil
+
+		t.resetWriteThresholds()
+
+		// we have completed the key exchange. Since the
+		// reader is still blocked, it is safe to clear out
+		// the requestKex channel. This avoids the situation
+		// where: 1) we consumed our own request for the
+		// initial kex, and 2) the kex from the remote side
+		// caused another send on the requestKex channel,
+	clear:
+		for {
+			select {
+			case <-t.requestKex:
+				//
+			default:
+				break clear
+			}
+		}
+
+		request.done <- t.writeError
+
+		// kex finished. Push packets that we received while
+		// the kex was in progress. Don't look at t.startKex
+		// and don't increment writtenSinceKex: if we trigger
+		// another kex while we are still busy with the last
+		// one, things will become very confusing.
+		for _, p := range t.pendingPackets {
+			t.writeError = t.pushPacket(p)
+			if t.writeError != nil {
+				break
+			}
+		}
+		t.pendingPackets = t.pendingPackets[:0]
+		t.mu.Unlock()
+	}
+
+	// drain startKex channel. We don't service t.requestKex
+	// because nobody does blocking sends there.
+	go func() {
+		for init := range t.startKex {
+			init.done <- t.writeError
+		}
+	}()
+
+	// Unblock reader.
+	t.conn.Close()
+}
+
+// The protocol uses uint32 for packet counters, so we can't let them
+// reach 1<<32.  We will actually read and write more packets than
+// this, though: the other side may send more packets, and after we
+// hit this limit on writing we will send a few more packets for the
+// key exchange itself.
+const packetRekeyThreshold = (1 << 31)
+
+func (t *handshakeTransport) resetReadThresholds() {
+	t.readPacketsLeft = packetRekeyThreshold
+	if t.config.RekeyThreshold > 0 {
+		t.readBytesLeft = int64(t.config.RekeyThreshold)
+	} else if t.algorithms != nil {
+		t.readBytesLeft = t.algorithms.r.rekeyBytes()
+	} else {
+		t.readBytesLeft = 1 << 30
+	}
+}
+
+func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
+	p, err := t.conn.readPacket()
+	if err != nil {
+		return nil, err
+	}
+
+	if t.readPacketsLeft > 0 {
+		t.readPacketsLeft--
+	} else {
+		t.requestKeyExchange()
+	}
+
+	if t.readBytesLeft > 0 {
+		t.readBytesLeft -= int64(len(p))
+	} else {
+		t.requestKeyExchange()
+	}
+
+	if debugHandshake {
+		t.printPacket(p, false)
+	}
+
+	if first && p[0] != msgKexInit {
+		return nil, fmt.Errorf("ssh: first packet should be msgKexInit")
+	}
+
+	if p[0] != msgKexInit {
+		return p, nil
+	}
+
+	firstKex := t.sessionID == nil
+
+	kex := pendingKex{
+		done:      make(chan error, 1),
+		otherInit: p,
+	}
+	t.startKex <- &kex
+	err = <-kex.done
+
+	if debugHandshake {
+		log.Printf("%s exited key exchange (first %v), err %v", t.id(), firstKex, err)
+	}
+
+	if err != nil {
+		return nil, err
+	}
+
+	t.resetReadThresholds()
+
+	// By default, a key exchange is hidden from higher layers by
+	// translating it into msgIgnore.
+	successPacket := []byte{msgIgnore}
+	if firstKex {
+		// sendKexInit() for the first kex waits for
+		// msgNewKeys so the authentication process is
+		// guaranteed to happen over an encrypted transport.
+		successPacket = []byte{msgNewKeys}
+	}
+
+	return successPacket, nil
+}
+
+// sendKexInit sends a key change message.
+func (t *handshakeTransport) sendKexInit() error {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.sentInitMsg != nil {
+		// kexInits may be sent either in response to the other side,
+		// or because our side wants to initiate a key change, so we
+		// may have already sent a kexInit. In that case, don't send a
+		// second kexInit.
+		return nil
+	}
+
+	msg := &kexInitMsg{
+		KexAlgos:                t.config.KeyExchanges,
+		CiphersClientServer:     t.config.Ciphers,
+		CiphersServerClient:     t.config.Ciphers,
+		MACsClientServer:        t.config.MACs,
+		MACsServerClient:        t.config.MACs,
+		CompressionClientServer: supportedCompressions,
+		CompressionServerClient: supportedCompressions,
+	}
+	io.ReadFull(rand.Reader, msg.Cookie[:])
+
+	if len(t.hostKeys) > 0 {
+		for _, k := range t.hostKeys {
+			msg.ServerHostKeyAlgos = append(
+				msg.ServerHostKeyAlgos, k.PublicKey().Type())
+		}
+	} else {
+		msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
+	}
+	packet := Marshal(msg)
+
+	// writePacket destroys the contents, so save a copy.
+	packetCopy := make([]byte, len(packet))
+	copy(packetCopy, packet)
+
+	if err := t.pushPacket(packetCopy); err != nil {
+		return err
+	}
+
+	t.sentInitMsg = msg
+	t.sentInitPacket = packet
+
+	return nil
+}
+
+func (t *handshakeTransport) writePacket(p []byte) error {
+	switch p[0] {
+	case msgKexInit:
+		return errors.New("ssh: only handshakeTransport can send kexInit")
+	case msgNewKeys:
+		return errors.New("ssh: only handshakeTransport can send newKeys")
+	}
+
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.writeError != nil {
+		return t.writeError
+	}
+
+	if t.sentInitMsg != nil {
+		// Copy the packet so the writer can reuse the buffer.
+		cp := make([]byte, len(p))
+		copy(cp, p)
+		t.pendingPackets = append(t.pendingPackets, cp)
+		return nil
+	}
+
+	if t.writeBytesLeft > 0 {
+		t.writeBytesLeft -= int64(len(p))
+	} else {
+		t.requestKeyExchange()
+	}
+
+	if t.writePacketsLeft > 0 {
+		t.writePacketsLeft--
+	} else {
+		t.requestKeyExchange()
+	}
+
+	if err := t.pushPacket(p); err != nil {
+		t.writeError = err
+	}
+
+	return nil
+}
+
+func (t *handshakeTransport) Close() error {
+	return t.conn.Close()
+}
+
+func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
+	if debugHandshake {
+		log.Printf("%s entered key exchange", t.id())
+	}
+
+	otherInit := &kexInitMsg{}
+	if err := Unmarshal(otherInitPacket, otherInit); err != nil {
+		return err
+	}
+
+	magics := handshakeMagics{
+		clientVersion: t.clientVersion,
+		serverVersion: t.serverVersion,
+		clientKexInit: otherInitPacket,
+		serverKexInit: t.sentInitPacket,
+	}
+
+	clientInit := otherInit
+	serverInit := t.sentInitMsg
+	if len(t.hostKeys) == 0 {
+		clientInit, serverInit = serverInit, clientInit
+
+		magics.clientKexInit = t.sentInitPacket
+		magics.serverKexInit = otherInitPacket
+	}
+
+	var err error
+	t.algorithms, err = findAgreedAlgorithms(clientInit, serverInit)
+	if err != nil {
+		return err
+	}
+
+	// We don't send FirstKexFollows, but we handle receiving it.
+	//
+	// RFC 4253 section 7 defines the kex and the agreement method for
+	// first_kex_packet_follows. It states that the guessed packet
+	// should be ignored if the "kex algorithm and/or the host
+	// key algorithm is guessed wrong (server and client have
+	// different preferred algorithm), or if any of the other
+	// algorithms cannot be agreed upon". The other algorithms have
+	// already been checked above so the kex algorithm and host key
+	// algorithm are checked here.
+	if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) {
+		// other side sent a kex message for the wrong algorithm,
+		// which we have to ignore.
+		if _, err := t.conn.readPacket(); err != nil {
+			return err
+		}
+	}
+
+	kex, ok := kexAlgoMap[t.algorithms.kex]
+	if !ok {
+		return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex)
+	}
+
+	var result *kexResult
+	if len(t.hostKeys) > 0 {
+		result, err = t.server(kex, t.algorithms, &magics)
+	} else {
+		result, err = t.client(kex, t.algorithms, &magics)
+	}
+
+	if err != nil {
+		return err
+	}
+
+	if t.sessionID == nil {
+		t.sessionID = result.H
+	}
+	result.SessionID = t.sessionID
+
+	if err := t.conn.prepareKeyChange(t.algorithms, result); err != nil {
+		return err
+	}
+	if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {
+		return err
+	}
+	if packet, err := t.conn.readPacket(); err != nil {
+		return err
+	} else if packet[0] != msgNewKeys {
+		return unexpectedMessageError(msgNewKeys, packet[0])
+	}
+
+	return nil
+}
+
+func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
+	var hostKey Signer
+	for _, k := range t.hostKeys {
+		if algs.hostKey == k.PublicKey().Type() {
+			hostKey = k
+		}
+	}
+
+	r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey)
+	return r, err
+}
+
+func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
+	result, err := kex.Client(t.conn, t.config.Rand, magics)
+	if err != nil {
+		return nil, err
+	}
+
+	hostKey, err := ParsePublicKey(result.HostKey)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := verifyHostKeySignature(hostKey, result); err != nil {
+		return nil, err
+	}
+
+	err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey)
+	if err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}

+ 540 - 0
vendor/golang.org/x/crypto/ssh/kex.go

@@ -0,0 +1,540 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/subtle"
+	"errors"
+	"io"
+	"math/big"
+
+	"golang.org/x/crypto/curve25519"
+)
+
+const (
+	kexAlgoDH1SHA1          = "diffie-hellman-group1-sha1"
+	kexAlgoDH14SHA1         = "diffie-hellman-group14-sha1"
+	kexAlgoECDH256          = "ecdh-sha2-nistp256"
+	kexAlgoECDH384          = "ecdh-sha2-nistp384"
+	kexAlgoECDH521          = "ecdh-sha2-nistp521"
+	kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
+)
+
+// kexResult captures the outcome of a key exchange.
+type kexResult struct {
+	// Session hash. See also RFC 4253, section 8.
+	H []byte
+
+	// Shared secret. See also RFC 4253, section 8.
+	K []byte
+
+	// Host key as hashed into H.
+	HostKey []byte
+
+	// Signature of H.
+	Signature []byte
+
+	// A cryptographic hash function that matches the security
+	// level of the key exchange algorithm. It is used for
+	// calculating H, and for deriving keys from H and K.
+	Hash crypto.Hash
+
+	// The session ID, which is the first H computed. This is used
+	// to derive key material inside the transport.
+	SessionID []byte
+}
+
+// handshakeMagics contains data that is always included in the
+// session hash.
+type handshakeMagics struct {
+	clientVersion, serverVersion []byte
+	clientKexInit, serverKexInit []byte
+}
+
+func (m *handshakeMagics) write(w io.Writer) {
+	writeString(w, m.clientVersion)
+	writeString(w, m.serverVersion)
+	writeString(w, m.clientKexInit)
+	writeString(w, m.serverKexInit)
+}
+
+// kexAlgorithm abstracts different key exchange algorithms.
+type kexAlgorithm interface {
+	// Server runs server-side key agreement, signing the result
+	// with a hostkey.
+	Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error)
+
+	// Client runs the client-side key agreement. Caller is
+	// responsible for verifying the host key signature.
+	Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error)
+}
+
+// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
+type dhGroup struct {
+	g, p, pMinus1 *big.Int
+}
+
+func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
+	if theirPublic.Cmp(bigOne) <= 0 || theirPublic.Cmp(group.pMinus1) >= 0 {
+		return nil, errors.New("ssh: DH parameter out of bounds")
+	}
+	return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil
+}
+
+func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
+	hashFunc := crypto.SHA1
+
+	var x *big.Int
+	for {
+		var err error
+		if x, err = rand.Int(randSource, group.pMinus1); err != nil {
+			return nil, err
+		}
+		if x.Sign() > 0 {
+			break
+		}
+	}
+
+	X := new(big.Int).Exp(group.g, x, group.p)
+	kexDHInit := kexDHInitMsg{
+		X: X,
+	}
+	if err := c.writePacket(Marshal(&kexDHInit)); err != nil {
+		return nil, err
+	}
+
+	packet, err := c.readPacket()
+	if err != nil {
+		return nil, err
+	}
+
+	var kexDHReply kexDHReplyMsg
+	if err = Unmarshal(packet, &kexDHReply); err != nil {
+		return nil, err
+	}
+
+	kInt, err := group.diffieHellman(kexDHReply.Y, x)
+	if err != nil {
+		return nil, err
+	}
+
+	h := hashFunc.New()
+	magics.write(h)
+	writeString(h, kexDHReply.HostKey)
+	writeInt(h, X)
+	writeInt(h, kexDHReply.Y)
+	K := make([]byte, intLength(kInt))
+	marshalInt(K, kInt)
+	h.Write(K)
+
+	return &kexResult{
+		H:         h.Sum(nil),
+		K:         K,
+		HostKey:   kexDHReply.HostKey,
+		Signature: kexDHReply.Signature,
+		Hash:      crypto.SHA1,
+	}, nil
+}
+
+func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
+	hashFunc := crypto.SHA1
+	packet, err := c.readPacket()
+	if err != nil {
+		return
+	}
+	var kexDHInit kexDHInitMsg
+	if err = Unmarshal(packet, &kexDHInit); err != nil {
+		return
+	}
+
+	var y *big.Int
+	for {
+		if y, err = rand.Int(randSource, group.pMinus1); err != nil {
+			return
+		}
+		if y.Sign() > 0 {
+			break
+		}
+	}
+
+	Y := new(big.Int).Exp(group.g, y, group.p)
+	kInt, err := group.diffieHellman(kexDHInit.X, y)
+	if err != nil {
+		return nil, err
+	}
+
+	hostKeyBytes := priv.PublicKey().Marshal()
+
+	h := hashFunc.New()
+	magics.write(h)
+	writeString(h, hostKeyBytes)
+	writeInt(h, kexDHInit.X)
+	writeInt(h, Y)
+
+	K := make([]byte, intLength(kInt))
+	marshalInt(K, kInt)
+	h.Write(K)
+
+	H := h.Sum(nil)
+
+	// H is already a hash, but the hostkey signing will apply its
+	// own key-specific hash algorithm.
+	sig, err := signAndMarshal(priv, randSource, H)
+	if err != nil {
+		return nil, err
+	}
+
+	kexDHReply := kexDHReplyMsg{
+		HostKey:   hostKeyBytes,
+		Y:         Y,
+		Signature: sig,
+	}
+	packet = Marshal(&kexDHReply)
+
+	err = c.writePacket(packet)
+	return &kexResult{
+		H:         H,
+		K:         K,
+		HostKey:   hostKeyBytes,
+		Signature: sig,
+		Hash:      crypto.SHA1,
+	}, nil
+}
+
+// ecdh performs Elliptic Curve Diffie-Hellman key exchange as
+// described in RFC 5656, section 4.
+type ecdh struct {
+	curve elliptic.Curve
+}
+
+func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
+	ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
+	if err != nil {
+		return nil, err
+	}
+
+	kexInit := kexECDHInitMsg{
+		ClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y),
+	}
+
+	serialized := Marshal(&kexInit)
+	if err := c.writePacket(serialized); err != nil {
+		return nil, err
+	}
+
+	packet, err := c.readPacket()
+	if err != nil {
+		return nil, err
+	}
+
+	var reply kexECDHReplyMsg
+	if err = Unmarshal(packet, &reply); err != nil {
+		return nil, err
+	}
+
+	x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey)
+	if err != nil {
+		return nil, err
+	}
+
+	// generate shared secret
+	secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes())
+
+	h := ecHash(kex.curve).New()
+	magics.write(h)
+	writeString(h, reply.HostKey)
+	writeString(h, kexInit.ClientPubKey)
+	writeString(h, reply.EphemeralPubKey)
+	K := make([]byte, intLength(secret))
+	marshalInt(K, secret)
+	h.Write(K)
+
+	return &kexResult{
+		H:         h.Sum(nil),
+		K:         K,
+		HostKey:   reply.HostKey,
+		Signature: reply.Signature,
+		Hash:      ecHash(kex.curve),
+	}, nil
+}
+
+// unmarshalECKey parses and checks an EC key.
+func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) {
+	x, y = elliptic.Unmarshal(curve, pubkey)
+	if x == nil {
+		return nil, nil, errors.New("ssh: elliptic.Unmarshal failure")
+	}
+	if !validateECPublicKey(curve, x, y) {
+		return nil, nil, errors.New("ssh: public key not on curve")
+	}
+	return x, y, nil
+}
+
+// validateECPublicKey checks that the point is a valid public key for
+// the given curve. See [SEC1], 3.2.2
+func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
+	if x.Sign() == 0 && y.Sign() == 0 {
+		return false
+	}
+
+	if x.Cmp(curve.Params().P) >= 0 {
+		return false
+	}
+
+	if y.Cmp(curve.Params().P) >= 0 {
+		return false
+	}
+
+	if !curve.IsOnCurve(x, y) {
+		return false
+	}
+
+	// We don't check if N * PubKey == 0, since
+	//
+	// - the NIST curves have cofactor = 1, so this is implicit.
+	// (We don't foresee an implementation that supports non NIST
+	// curves)
+	//
+	// - for ephemeral keys, we don't need to worry about small
+	// subgroup attacks.
+	return true
+}
+
+func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
+	packet, err := c.readPacket()
+	if err != nil {
+		return nil, err
+	}
+
+	var kexECDHInit kexECDHInitMsg
+	if err = Unmarshal(packet, &kexECDHInit); err != nil {
+		return nil, err
+	}
+
+	clientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey)
+	if err != nil {
+		return nil, err
+	}
+
+	// We could cache this key across multiple users/multiple
+	// connection attempts, but the benefit is small. OpenSSH
+	// generates a new key for each incoming connection.
+	ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
+	if err != nil {
+		return nil, err
+	}
+
+	hostKeyBytes := priv.PublicKey().Marshal()
+
+	serializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y)
+
+	// generate shared secret
+	secret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes())
+
+	h := ecHash(kex.curve).New()
+	magics.write(h)
+	writeString(h, hostKeyBytes)
+	writeString(h, kexECDHInit.ClientPubKey)
+	writeString(h, serializedEphKey)
+
+	K := make([]byte, intLength(secret))
+	marshalInt(K, secret)
+	h.Write(K)
+
+	H := h.Sum(nil)
+
+	// H is already a hash, but the hostkey signing will apply its
+	// own key-specific hash algorithm.
+	sig, err := signAndMarshal(priv, rand, H)
+	if err != nil {
+		return nil, err
+	}
+
+	reply := kexECDHReplyMsg{
+		EphemeralPubKey: serializedEphKey,
+		HostKey:         hostKeyBytes,
+		Signature:       sig,
+	}
+
+	serialized := Marshal(&reply)
+	if err := c.writePacket(serialized); err != nil {
+		return nil, err
+	}
+
+	return &kexResult{
+		H:         H,
+		K:         K,
+		HostKey:   reply.HostKey,
+		Signature: sig,
+		Hash:      ecHash(kex.curve),
+	}, nil
+}
+
+var kexAlgoMap = map[string]kexAlgorithm{}
+
+func init() {
+	// This is the group called diffie-hellman-group1-sha1 in RFC
+	// 4253 and Oakley Group 2 in RFC 2409.
+	p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16)
+	kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
+		g:       new(big.Int).SetInt64(2),
+		p:       p,
+		pMinus1: new(big.Int).Sub(p, bigOne),
+	}
+
+	// This is the group called diffie-hellman-group14-sha1 in RFC
+	// 4253 and Oakley Group 14 in RFC 3526.
+	p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
+
+	kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
+		g:       new(big.Int).SetInt64(2),
+		p:       p,
+		pMinus1: new(big.Int).Sub(p, bigOne),
+	}
+
+	kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
+	kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
+	kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
+	kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
+}
+
+// curve25519sha256 implements the curve25519-sha256@libssh.org key
+// agreement protocol, as described in
+// https://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt
+type curve25519sha256 struct{}
+
+type curve25519KeyPair struct {
+	priv [32]byte
+	pub  [32]byte
+}
+
+func (kp *curve25519KeyPair) generate(rand io.Reader) error {
+	if _, err := io.ReadFull(rand, kp.priv[:]); err != nil {
+		return err
+	}
+	curve25519.ScalarBaseMult(&kp.pub, &kp.priv)
+	return nil
+}
+
+// curve25519Zeros is just an array of 32 zero bytes so that we have something
+// convenient to compare against in order to reject curve25519 points with the
+// wrong order.
+var curve25519Zeros [32]byte
+
+func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
+	var kp curve25519KeyPair
+	if err := kp.generate(rand); err != nil {
+		return nil, err
+	}
+	if err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil {
+		return nil, err
+	}
+
+	packet, err := c.readPacket()
+	if err != nil {
+		return nil, err
+	}
+
+	var reply kexECDHReplyMsg
+	if err = Unmarshal(packet, &reply); err != nil {
+		return nil, err
+	}
+	if len(reply.EphemeralPubKey) != 32 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
+	}
+
+	var servPub, secret [32]byte
+	copy(servPub[:], reply.EphemeralPubKey)
+	curve25519.ScalarMult(&secret, &kp.priv, &servPub)
+	if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
+	}
+
+	h := crypto.SHA256.New()
+	magics.write(h)
+	writeString(h, reply.HostKey)
+	writeString(h, kp.pub[:])
+	writeString(h, reply.EphemeralPubKey)
+
+	kInt := new(big.Int).SetBytes(secret[:])
+	K := make([]byte, intLength(kInt))
+	marshalInt(K, kInt)
+	h.Write(K)
+
+	return &kexResult{
+		H:         h.Sum(nil),
+		K:         K,
+		HostKey:   reply.HostKey,
+		Signature: reply.Signature,
+		Hash:      crypto.SHA256,
+	}, nil
+}
+
+func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
+	packet, err := c.readPacket()
+	if err != nil {
+		return
+	}
+	var kexInit kexECDHInitMsg
+	if err = Unmarshal(packet, &kexInit); err != nil {
+		return
+	}
+
+	if len(kexInit.ClientPubKey) != 32 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
+	}
+
+	var kp curve25519KeyPair
+	if err := kp.generate(rand); err != nil {
+		return nil, err
+	}
+
+	var clientPub, secret [32]byte
+	copy(clientPub[:], kexInit.ClientPubKey)
+	curve25519.ScalarMult(&secret, &kp.priv, &clientPub)
+	if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
+	}
+
+	hostKeyBytes := priv.PublicKey().Marshal()
+
+	h := crypto.SHA256.New()
+	magics.write(h)
+	writeString(h, hostKeyBytes)
+	writeString(h, kexInit.ClientPubKey)
+	writeString(h, kp.pub[:])
+
+	kInt := new(big.Int).SetBytes(secret[:])
+	K := make([]byte, intLength(kInt))
+	marshalInt(K, kInt)
+	h.Write(K)
+
+	H := h.Sum(nil)
+
+	sig, err := signAndMarshal(priv, rand, H)
+	if err != nil {
+		return nil, err
+	}
+
+	reply := kexECDHReplyMsg{
+		EphemeralPubKey: kp.pub[:],
+		HostKey:         hostKeyBytes,
+		Signature:       sig,
+	}
+	if err := c.writePacket(Marshal(&reply)); err != nil {
+		return nil, err
+	}
+	return &kexResult{
+		H:         H,
+		K:         K,
+		HostKey:   hostKeyBytes,
+		Signature: sig,
+		Hash:      crypto.SHA256,
+	}, nil
+}

+ 1031 - 0
vendor/golang.org/x/crypto/ssh/keys.go

@@ -0,0 +1,1031 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/md5"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
+	"encoding/asn1"
+	"encoding/base64"
+	"encoding/hex"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+	"strings"
+
+	"golang.org/x/crypto/ed25519"
+)
+
+// These constants represent the algorithm names for key types supported by this
+// package.
+const (
+	KeyAlgoRSA      = "ssh-rsa"
+	KeyAlgoDSA      = "ssh-dss"
+	KeyAlgoECDSA256 = "ecdsa-sha2-nistp256"
+	KeyAlgoECDSA384 = "ecdsa-sha2-nistp384"
+	KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
+	KeyAlgoED25519  = "ssh-ed25519"
+)
+
+// parsePubKey parses a public key of the given algorithm.
+// Use ParsePublicKey for keys with prepended algorithm.
+func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {
+	switch algo {
+	case KeyAlgoRSA:
+		return parseRSA(in)
+	case KeyAlgoDSA:
+		return parseDSA(in)
+	case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
+		return parseECDSA(in)
+	case KeyAlgoED25519:
+		return parseED25519(in)
+	case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01:
+		cert, err := parseCert(in, certToPrivAlgo(algo))
+		if err != nil {
+			return nil, nil, err
+		}
+		return cert, nil, nil
+	}
+	return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo)
+}
+
+// parseAuthorizedKey parses a public key in OpenSSH authorized_keys format
+// (see sshd(8) manual page) once the options and key type fields have been
+// removed.
+func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
+	in = bytes.TrimSpace(in)
+
+	i := bytes.IndexAny(in, " \t")
+	if i == -1 {
+		i = len(in)
+	}
+	base64Key := in[:i]
+
+	key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))
+	n, err := base64.StdEncoding.Decode(key, base64Key)
+	if err != nil {
+		return nil, "", err
+	}
+	key = key[:n]
+	out, err = ParsePublicKey(key)
+	if err != nil {
+		return nil, "", err
+	}
+	comment = string(bytes.TrimSpace(in[i:]))
+	return out, comment, nil
+}
+
+// ParseKnownHosts parses an entry in the format of the known_hosts file.
+//
+// The known_hosts format is documented in the sshd(8) manual page. This
+// function will parse a single entry from in. On successful return, marker
+// will contain the optional marker value (i.e. "cert-authority" or "revoked")
+// or else be empty, hosts will contain the hosts that this entry matches,
+// pubKey will contain the public key and comment will contain any trailing
+// comment at the end of the line. See the sshd(8) manual page for the various
+// forms that a host string can take.
+//
+// The unparsed remainder of the input will be returned in rest. This function
+// can be called repeatedly to parse multiple entries.
+//
+// If no entries were found in the input then err will be io.EOF. Otherwise a
+// non-nil err value indicates a parse error.
+func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) {
+	for len(in) > 0 {
+		end := bytes.IndexByte(in, '\n')
+		if end != -1 {
+			rest = in[end+1:]
+			in = in[:end]
+		} else {
+			rest = nil
+		}
+
+		end = bytes.IndexByte(in, '\r')
+		if end != -1 {
+			in = in[:end]
+		}
+
+		in = bytes.TrimSpace(in)
+		if len(in) == 0 || in[0] == '#' {
+			in = rest
+			continue
+		}
+
+		i := bytes.IndexAny(in, " \t")
+		if i == -1 {
+			in = rest
+			continue
+		}
+
+		// Strip out the beginning of the known_host key.
+		// This is either an optional marker or a (set of) hostname(s).
+		keyFields := bytes.Fields(in)
+		if len(keyFields) < 3 || len(keyFields) > 5 {
+			return "", nil, nil, "", nil, errors.New("ssh: invalid entry in known_hosts data")
+		}
+
+		// keyFields[0] is either "@cert-authority", "@revoked" or a comma separated
+		// list of hosts
+		marker := ""
+		if keyFields[0][0] == '@' {
+			marker = string(keyFields[0][1:])
+			keyFields = keyFields[1:]
+		}
+
+		hosts := string(keyFields[0])
+		// keyFields[1] contains the key type (e.g. “ssh-rsa”).
+		// However, that information is duplicated inside the
+		// base64-encoded key and so is ignored here.
+
+		key := bytes.Join(keyFields[2:], []byte(" "))
+		if pubKey, comment, err = parseAuthorizedKey(key); err != nil {
+			return "", nil, nil, "", nil, err
+		}
+
+		return marker, strings.Split(hosts, ","), pubKey, comment, rest, nil
+	}
+
+	return "", nil, nil, "", nil, io.EOF
+}
+
+// ParseAuthorizedKeys parses a public key from an authorized_keys
+// file used in OpenSSH according to the sshd(8) manual page.
+func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
+	for len(in) > 0 {
+		end := bytes.IndexByte(in, '\n')
+		if end != -1 {
+			rest = in[end+1:]
+			in = in[:end]
+		} else {
+			rest = nil
+		}
+
+		end = bytes.IndexByte(in, '\r')
+		if end != -1 {
+			in = in[:end]
+		}
+
+		in = bytes.TrimSpace(in)
+		if len(in) == 0 || in[0] == '#' {
+			in = rest
+			continue
+		}
+
+		i := bytes.IndexAny(in, " \t")
+		if i == -1 {
+			in = rest
+			continue
+		}
+
+		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
+			return out, comment, options, rest, nil
+		}
+
+		// No key type recognised. Maybe there's an options field at
+		// the beginning.
+		var b byte
+		inQuote := false
+		var candidateOptions []string
+		optionStart := 0
+		for i, b = range in {
+			isEnd := !inQuote && (b == ' ' || b == '\t')
+			if (b == ',' && !inQuote) || isEnd {
+				if i-optionStart > 0 {
+					candidateOptions = append(candidateOptions, string(in[optionStart:i]))
+				}
+				optionStart = i + 1
+			}
+			if isEnd {
+				break
+			}
+			if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) {
+				inQuote = !inQuote
+			}
+		}
+		for i < len(in) && (in[i] == ' ' || in[i] == '\t') {
+			i++
+		}
+		if i == len(in) {
+			// Invalid line: unmatched quote
+			in = rest
+			continue
+		}
+
+		in = in[i:]
+		i = bytes.IndexAny(in, " \t")
+		if i == -1 {
+			in = rest
+			continue
+		}
+
+		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
+			options = candidateOptions
+			return out, comment, options, rest, nil
+		}
+
+		in = rest
+		continue
+	}
+
+	return nil, "", nil, nil, errors.New("ssh: no key found")
+}
+
+// ParsePublicKey parses an SSH public key formatted for use in
+// the SSH wire protocol according to RFC 4253, section 6.6.
+func ParsePublicKey(in []byte) (out PublicKey, err error) {
+	algo, in, ok := parseString(in)
+	if !ok {
+		return nil, errShortRead
+	}
+	var rest []byte
+	out, rest, err = parsePubKey(in, string(algo))
+	if len(rest) > 0 {
+		return nil, errors.New("ssh: trailing junk in public key")
+	}
+
+	return out, err
+}
+
+// MarshalAuthorizedKey serializes key for inclusion in an OpenSSH
+// authorized_keys file. The return value ends with newline.
+func MarshalAuthorizedKey(key PublicKey) []byte {
+	b := &bytes.Buffer{}
+	b.WriteString(key.Type())
+	b.WriteByte(' ')
+	e := base64.NewEncoder(base64.StdEncoding, b)
+	e.Write(key.Marshal())
+	e.Close()
+	b.WriteByte('\n')
+	return b.Bytes()
+}
+
+// PublicKey is an abstraction of different types of public keys.
+type PublicKey interface {
+	// Type returns the key's type, e.g. "ssh-rsa".
+	Type() string
+
+	// Marshal returns the serialized key data in SSH wire format,
+	// with the name prefix.
+	Marshal() []byte
+
+	// Verify that sig is a signature on the given data using this
+	// key. This function will hash the data appropriately first.
+	Verify(data []byte, sig *Signature) error
+}
+
+// CryptoPublicKey, if implemented by a PublicKey,
+// returns the underlying crypto.PublicKey form of the key.
+type CryptoPublicKey interface {
+	CryptoPublicKey() crypto.PublicKey
+}
+
+// A Signer can create signatures that verify against a public key.
+type Signer interface {
+	// PublicKey returns an associated PublicKey instance.
+	PublicKey() PublicKey
+
+	// Sign returns raw signature for the given data. This method
+	// will apply the hash specified for the keytype to the data.
+	Sign(rand io.Reader, data []byte) (*Signature, error)
+}
+
+type rsaPublicKey rsa.PublicKey
+
+func (r *rsaPublicKey) Type() string {
+	return "ssh-rsa"
+}
+
+// parseRSA parses an RSA key according to RFC 4253, section 6.6.
+func parseRSA(in []byte) (out PublicKey, rest []byte, err error) {
+	var w struct {
+		E    *big.Int
+		N    *big.Int
+		Rest []byte `ssh:"rest"`
+	}
+	if err := Unmarshal(in, &w); err != nil {
+		return nil, nil, err
+	}
+
+	if w.E.BitLen() > 24 {
+		return nil, nil, errors.New("ssh: exponent too large")
+	}
+	e := w.E.Int64()
+	if e < 3 || e&1 == 0 {
+		return nil, nil, errors.New("ssh: incorrect exponent")
+	}
+
+	var key rsa.PublicKey
+	key.E = int(e)
+	key.N = w.N
+	return (*rsaPublicKey)(&key), w.Rest, nil
+}
+
+func (r *rsaPublicKey) Marshal() []byte {
+	e := new(big.Int).SetInt64(int64(r.E))
+	// RSA publickey struct layout should match the struct used by
+	// parseRSACert in the x/crypto/ssh/agent package.
+	wirekey := struct {
+		Name string
+		E    *big.Int
+		N    *big.Int
+	}{
+		KeyAlgoRSA,
+		e,
+		r.N,
+	}
+	return Marshal(&wirekey)
+}
+
+func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
+	if sig.Format != r.Type() {
+		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
+	}
+	h := crypto.SHA1.New()
+	h.Write(data)
+	digest := h.Sum(nil)
+	return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob)
+}
+
+func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
+	return (*rsa.PublicKey)(r)
+}
+
+type dsaPublicKey dsa.PublicKey
+
+func (r *dsaPublicKey) Type() string {
+	return "ssh-dss"
+}
+
+func checkDSAParams(param *dsa.Parameters) error {
+	// SSH specifies FIPS 186-2, which only provided a single size
+	// (1024 bits) DSA key. FIPS 186-3 allows for larger key
+	// sizes, which would confuse SSH.
+	if l := param.P.BitLen(); l != 1024 {
+		return fmt.Errorf("ssh: unsupported DSA key size %d", l)
+	}
+
+	return nil
+}
+
+// parseDSA parses an DSA key according to RFC 4253, section 6.6.
+func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
+	var w struct {
+		P, Q, G, Y *big.Int
+		Rest       []byte `ssh:"rest"`
+	}
+	if err := Unmarshal(in, &w); err != nil {
+		return nil, nil, err
+	}
+
+	param := dsa.Parameters{
+		P: w.P,
+		Q: w.Q,
+		G: w.G,
+	}
+	if err := checkDSAParams(&param); err != nil {
+		return nil, nil, err
+	}
+
+	key := &dsaPublicKey{
+		Parameters: param,
+		Y:          w.Y,
+	}
+	return key, w.Rest, nil
+}
+
+func (k *dsaPublicKey) Marshal() []byte {
+	// DSA publickey struct layout should match the struct used by
+	// parseDSACert in the x/crypto/ssh/agent package.
+	w := struct {
+		Name       string
+		P, Q, G, Y *big.Int
+	}{
+		k.Type(),
+		k.P,
+		k.Q,
+		k.G,
+		k.Y,
+	}
+
+	return Marshal(&w)
+}
+
+func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
+	if sig.Format != k.Type() {
+		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
+	}
+	h := crypto.SHA1.New()
+	h.Write(data)
+	digest := h.Sum(nil)
+
+	// Per RFC 4253, section 6.6,
+	// The value for 'dss_signature_blob' is encoded as a string containing
+	// r, followed by s (which are 160-bit integers, without lengths or
+	// padding, unsigned, and in network byte order).
+	// For DSS purposes, sig.Blob should be exactly 40 bytes in length.
+	if len(sig.Blob) != 40 {
+		return errors.New("ssh: DSA signature parse error")
+	}
+	r := new(big.Int).SetBytes(sig.Blob[:20])
+	s := new(big.Int).SetBytes(sig.Blob[20:])
+	if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {
+		return nil
+	}
+	return errors.New("ssh: signature did not verify")
+}
+
+func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {
+	return (*dsa.PublicKey)(k)
+}
+
+type dsaPrivateKey struct {
+	*dsa.PrivateKey
+}
+
+func (k *dsaPrivateKey) PublicKey() PublicKey {
+	return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
+}
+
+func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
+	h := crypto.SHA1.New()
+	h.Write(data)
+	digest := h.Sum(nil)
+	r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
+	if err != nil {
+		return nil, err
+	}
+
+	sig := make([]byte, 40)
+	rb := r.Bytes()
+	sb := s.Bytes()
+
+	copy(sig[20-len(rb):20], rb)
+	copy(sig[40-len(sb):], sb)
+
+	return &Signature{
+		Format: k.PublicKey().Type(),
+		Blob:   sig,
+	}, nil
+}
+
+type ecdsaPublicKey ecdsa.PublicKey
+
+func (key *ecdsaPublicKey) Type() string {
+	return "ecdsa-sha2-" + key.nistID()
+}
+
+func (key *ecdsaPublicKey) nistID() string {
+	switch key.Params().BitSize {
+	case 256:
+		return "nistp256"
+	case 384:
+		return "nistp384"
+	case 521:
+		return "nistp521"
+	}
+	panic("ssh: unsupported ecdsa key size")
+}
+
+type ed25519PublicKey ed25519.PublicKey
+
+func (key ed25519PublicKey) Type() string {
+	return KeyAlgoED25519
+}
+
+func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
+	var w struct {
+		KeyBytes []byte
+		Rest     []byte `ssh:"rest"`
+	}
+
+	if err := Unmarshal(in, &w); err != nil {
+		return nil, nil, err
+	}
+
+	key := ed25519.PublicKey(w.KeyBytes)
+
+	return (ed25519PublicKey)(key), w.Rest, nil
+}
+
+func (key ed25519PublicKey) Marshal() []byte {
+	w := struct {
+		Name     string
+		KeyBytes []byte
+	}{
+		KeyAlgoED25519,
+		[]byte(key),
+	}
+	return Marshal(&w)
+}
+
+func (key ed25519PublicKey) Verify(b []byte, sig *Signature) error {
+	if sig.Format != key.Type() {
+		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type())
+	}
+
+	edKey := (ed25519.PublicKey)(key)
+	if ok := ed25519.Verify(edKey, b, sig.Blob); !ok {
+		return errors.New("ssh: signature did not verify")
+	}
+
+	return nil
+}
+
+func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {
+	return ed25519.PublicKey(k)
+}
+
+func supportedEllipticCurve(curve elliptic.Curve) bool {
+	return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
+}
+
+// ecHash returns the hash to match the given elliptic curve, see RFC
+// 5656, section 6.2.1
+func ecHash(curve elliptic.Curve) crypto.Hash {
+	bitSize := curve.Params().BitSize
+	switch {
+	case bitSize <= 256:
+		return crypto.SHA256
+	case bitSize <= 384:
+		return crypto.SHA384
+	}
+	return crypto.SHA512
+}
+
+// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
+func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
+	var w struct {
+		Curve    string
+		KeyBytes []byte
+		Rest     []byte `ssh:"rest"`
+	}
+
+	if err := Unmarshal(in, &w); err != nil {
+		return nil, nil, err
+	}
+
+	key := new(ecdsa.PublicKey)
+
+	switch w.Curve {
+	case "nistp256":
+		key.Curve = elliptic.P256()
+	case "nistp384":
+		key.Curve = elliptic.P384()
+	case "nistp521":
+		key.Curve = elliptic.P521()
+	default:
+		return nil, nil, errors.New("ssh: unsupported curve")
+	}
+
+	key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
+	if key.X == nil || key.Y == nil {
+		return nil, nil, errors.New("ssh: invalid curve point")
+	}
+	return (*ecdsaPublicKey)(key), w.Rest, nil
+}
+
+func (key *ecdsaPublicKey) Marshal() []byte {
+	// See RFC 5656, section 3.1.
+	keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y)
+	// ECDSA publickey struct layout should match the struct used by
+	// parseECDSACert in the x/crypto/ssh/agent package.
+	w := struct {
+		Name string
+		ID   string
+		Key  []byte
+	}{
+		key.Type(),
+		key.nistID(),
+		keyBytes,
+	}
+
+	return Marshal(&w)
+}
+
+func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
+	if sig.Format != key.Type() {
+		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type())
+	}
+
+	h := ecHash(key.Curve).New()
+	h.Write(data)
+	digest := h.Sum(nil)
+
+	// Per RFC 5656, section 3.1.2,
+	// The ecdsa_signature_blob value has the following specific encoding:
+	//    mpint    r
+	//    mpint    s
+	var ecSig struct {
+		R *big.Int
+		S *big.Int
+	}
+
+	if err := Unmarshal(sig.Blob, &ecSig); err != nil {
+		return err
+	}
+
+	if ecdsa.Verify((*ecdsa.PublicKey)(key), digest, ecSig.R, ecSig.S) {
+		return nil
+	}
+	return errors.New("ssh: signature did not verify")
+}
+
+func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
+	return (*ecdsa.PublicKey)(k)
+}
+
+// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
+// *ecdsa.PrivateKey or any other crypto.Signer and returns a
+// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
+// P-521. DSA keys must use parameter size L1024N160.
+func NewSignerFromKey(key interface{}) (Signer, error) {
+	switch key := key.(type) {
+	case crypto.Signer:
+		return NewSignerFromSigner(key)
+	case *dsa.PrivateKey:
+		return newDSAPrivateKey(key)
+	default:
+		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
+	}
+}
+
+func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
+	if err := checkDSAParams(&key.PublicKey.Parameters); err != nil {
+		return nil, err
+	}
+
+	return &dsaPrivateKey{key}, nil
+}
+
+type wrappedSigner struct {
+	signer crypto.Signer
+	pubKey PublicKey
+}
+
+// NewSignerFromSigner takes any crypto.Signer implementation and
+// returns a corresponding Signer interface. This can be used, for
+// example, with keys kept in hardware modules.
+func NewSignerFromSigner(signer crypto.Signer) (Signer, error) {
+	pubKey, err := NewPublicKey(signer.Public())
+	if err != nil {
+		return nil, err
+	}
+
+	return &wrappedSigner{signer, pubKey}, nil
+}
+
+func (s *wrappedSigner) PublicKey() PublicKey {
+	return s.pubKey
+}
+
+func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
+	var hashFunc crypto.Hash
+
+	switch key := s.pubKey.(type) {
+	case *rsaPublicKey, *dsaPublicKey:
+		hashFunc = crypto.SHA1
+	case *ecdsaPublicKey:
+		hashFunc = ecHash(key.Curve)
+	case ed25519PublicKey:
+	default:
+		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
+	}
+
+	var digest []byte
+	if hashFunc != 0 {
+		h := hashFunc.New()
+		h.Write(data)
+		digest = h.Sum(nil)
+	} else {
+		digest = data
+	}
+
+	signature, err := s.signer.Sign(rand, digest, hashFunc)
+	if err != nil {
+		return nil, err
+	}
+
+	// crypto.Signer.Sign is expected to return an ASN.1-encoded signature
+	// for ECDSA and DSA, but that's not the encoding expected by SSH, so
+	// re-encode.
+	switch s.pubKey.(type) {
+	case *ecdsaPublicKey, *dsaPublicKey:
+		type asn1Signature struct {
+			R, S *big.Int
+		}
+		asn1Sig := new(asn1Signature)
+		_, err := asn1.Unmarshal(signature, asn1Sig)
+		if err != nil {
+			return nil, err
+		}
+
+		switch s.pubKey.(type) {
+		case *ecdsaPublicKey:
+			signature = Marshal(asn1Sig)
+
+		case *dsaPublicKey:
+			signature = make([]byte, 40)
+			r := asn1Sig.R.Bytes()
+			s := asn1Sig.S.Bytes()
+			copy(signature[20-len(r):20], r)
+			copy(signature[40-len(s):40], s)
+		}
+	}
+
+	return &Signature{
+		Format: s.pubKey.Type(),
+		Blob:   signature,
+	}, nil
+}
+
+// NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
+// or ed25519.PublicKey returns a corresponding PublicKey instance.
+// ECDSA keys must use P-256, P-384 or P-521.
+func NewPublicKey(key interface{}) (PublicKey, error) {
+	switch key := key.(type) {
+	case *rsa.PublicKey:
+		return (*rsaPublicKey)(key), nil
+	case *ecdsa.PublicKey:
+		if !supportedEllipticCurve(key.Curve) {
+			return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported.")
+		}
+		return (*ecdsaPublicKey)(key), nil
+	case *dsa.PublicKey:
+		return (*dsaPublicKey)(key), nil
+	case ed25519.PublicKey:
+		return (ed25519PublicKey)(key), nil
+	default:
+		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
+	}
+}
+
+// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
+// the same keys as ParseRawPrivateKey.
+func ParsePrivateKey(pemBytes []byte) (Signer, error) {
+	key, err := ParseRawPrivateKey(pemBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	return NewSignerFromKey(key)
+}
+
+// ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
+// key and passphrase. It supports the same keys as
+// ParseRawPrivateKeyWithPassphrase.
+func ParsePrivateKeyWithPassphrase(pemBytes, passPhrase []byte) (Signer, error) {
+	key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passPhrase)
+	if err != nil {
+		return nil, err
+	}
+
+	return NewSignerFromKey(key)
+}
+
+// encryptedBlock tells whether a private key is
+// encrypted by examining its Proc-Type header
+// for a mention of ENCRYPTED
+// according to RFC 1421 Section 4.6.1.1.
+func encryptedBlock(block *pem.Block) bool {
+	return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
+}
+
+// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
+// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
+func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
+	block, _ := pem.Decode(pemBytes)
+	if block == nil {
+		return nil, errors.New("ssh: no key found")
+	}
+
+	if encryptedBlock(block) {
+		return nil, errors.New("ssh: cannot decode encrypted private keys")
+	}
+
+	switch block.Type {
+	case "RSA PRIVATE KEY":
+		return x509.ParsePKCS1PrivateKey(block.Bytes)
+	case "EC PRIVATE KEY":
+		return x509.ParseECPrivateKey(block.Bytes)
+	case "DSA PRIVATE KEY":
+		return ParseDSAPrivateKey(block.Bytes)
+	case "OPENSSH PRIVATE KEY":
+		return parseOpenSSHPrivateKey(block.Bytes)
+	default:
+		return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
+	}
+}
+
+// ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
+// passphrase from a PEM encoded private key. If wrong passphrase, return
+// x509.IncorrectPasswordError.
+func ParseRawPrivateKeyWithPassphrase(pemBytes, passPhrase []byte) (interface{}, error) {
+	block, _ := pem.Decode(pemBytes)
+	if block == nil {
+		return nil, errors.New("ssh: no key found")
+	}
+	buf := block.Bytes
+
+	if encryptedBlock(block) {
+		if x509.IsEncryptedPEMBlock(block) {
+			var err error
+			buf, err = x509.DecryptPEMBlock(block, passPhrase)
+			if err != nil {
+				if err == x509.IncorrectPasswordError {
+					return nil, err
+				}
+				return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
+			}
+		}
+	}
+
+	switch block.Type {
+	case "RSA PRIVATE KEY":
+		return x509.ParsePKCS1PrivateKey(buf)
+	case "EC PRIVATE KEY":
+		return x509.ParseECPrivateKey(buf)
+	case "DSA PRIVATE KEY":
+		return ParseDSAPrivateKey(buf)
+	case "OPENSSH PRIVATE KEY":
+		return parseOpenSSHPrivateKey(buf)
+	default:
+		return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
+	}
+}
+
+// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
+// specified by the OpenSSL DSA man page.
+func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
+	var k struct {
+		Version int
+		P       *big.Int
+		Q       *big.Int
+		G       *big.Int
+		Pub     *big.Int
+		Priv    *big.Int
+	}
+	rest, err := asn1.Unmarshal(der, &k)
+	if err != nil {
+		return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
+	}
+	if len(rest) > 0 {
+		return nil, errors.New("ssh: garbage after DSA key")
+	}
+
+	return &dsa.PrivateKey{
+		PublicKey: dsa.PublicKey{
+			Parameters: dsa.Parameters{
+				P: k.P,
+				Q: k.Q,
+				G: k.G,
+			},
+			Y: k.Pub,
+		},
+		X: k.Priv,
+	}, nil
+}
+
+// Implemented based on the documentation at
+// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
+func parseOpenSSHPrivateKey(key []byte) (crypto.PrivateKey, error) {
+	magic := append([]byte("openssh-key-v1"), 0)
+	if !bytes.Equal(magic, key[0:len(magic)]) {
+		return nil, errors.New("ssh: invalid openssh private key format")
+	}
+	remaining := key[len(magic):]
+
+	var w struct {
+		CipherName   string
+		KdfName      string
+		KdfOpts      string
+		NumKeys      uint32
+		PubKey       []byte
+		PrivKeyBlock []byte
+	}
+
+	if err := Unmarshal(remaining, &w); err != nil {
+		return nil, err
+	}
+
+	if w.KdfName != "none" || w.CipherName != "none" {
+		return nil, errors.New("ssh: cannot decode encrypted private keys")
+	}
+
+	pk1 := struct {
+		Check1  uint32
+		Check2  uint32
+		Keytype string
+		Rest    []byte `ssh:"rest"`
+	}{}
+
+	if err := Unmarshal(w.PrivKeyBlock, &pk1); err != nil {
+		return nil, err
+	}
+
+	if pk1.Check1 != pk1.Check2 {
+		return nil, errors.New("ssh: checkint mismatch")
+	}
+
+	// we only handle ed25519 and rsa keys currently
+	switch pk1.Keytype {
+	case KeyAlgoRSA:
+		// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
+		key := struct {
+			N       *big.Int
+			E       *big.Int
+			D       *big.Int
+			Iqmp    *big.Int
+			P       *big.Int
+			Q       *big.Int
+			Comment string
+			Pad     []byte `ssh:"rest"`
+		}{}
+
+		if err := Unmarshal(pk1.Rest, &key); err != nil {
+			return nil, err
+		}
+
+		for i, b := range key.Pad {
+			if int(b) != i+1 {
+				return nil, errors.New("ssh: padding not as expected")
+			}
+		}
+
+		pk := &rsa.PrivateKey{
+			PublicKey: rsa.PublicKey{
+				N: key.N,
+				E: int(key.E.Int64()),
+			},
+			D:      key.D,
+			Primes: []*big.Int{key.P, key.Q},
+		}
+
+		if err := pk.Validate(); err != nil {
+			return nil, err
+		}
+
+		pk.Precompute()
+
+		return pk, nil
+	case KeyAlgoED25519:
+		key := struct {
+			Pub     []byte
+			Priv    []byte
+			Comment string
+			Pad     []byte `ssh:"rest"`
+		}{}
+
+		if err := Unmarshal(pk1.Rest, &key); err != nil {
+			return nil, err
+		}
+
+		if len(key.Priv) != ed25519.PrivateKeySize {
+			return nil, errors.New("ssh: private key unexpected length")
+		}
+
+		for i, b := range key.Pad {
+			if int(b) != i+1 {
+				return nil, errors.New("ssh: padding not as expected")
+			}
+		}
+
+		pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
+		copy(pk, key.Priv)
+		return &pk, nil
+	default:
+		return nil, errors.New("ssh: unhandled key type")
+	}
+}
+
+// FingerprintLegacyMD5 returns the user presentation of the key's
+// fingerprint as described by RFC 4716 section 4.
+func FingerprintLegacyMD5(pubKey PublicKey) string {
+	md5sum := md5.Sum(pubKey.Marshal())
+	hexarray := make([]string, len(md5sum))
+	for i, c := range md5sum {
+		hexarray[i] = hex.EncodeToString([]byte{c})
+	}
+	return strings.Join(hexarray, ":")
+}
+
+// FingerprintSHA256 returns the user presentation of the key's
+// fingerprint as unpadded base64 encoded sha256 hash.
+// This format was introduced from OpenSSH 6.8.
+// https://www.openssh.com/txt/release-6.8
+// https://tools.ietf.org/html/rfc4648#section-3.2 (unpadded base64 encoding)
+func FingerprintSHA256(pubKey PublicKey) string {
+	sha256sum := sha256.Sum256(pubKey.Marshal())
+	hash := base64.RawStdEncoding.EncodeToString(sha256sum[:])
+	return "SHA256:" + hash
+}

+ 61 - 0
vendor/golang.org/x/crypto/ssh/mac.go

@@ -0,0 +1,61 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+// Message authentication support
+
+import (
+	"crypto/hmac"
+	"crypto/sha1"
+	"crypto/sha256"
+	"hash"
+)
+
+type macMode struct {
+	keySize int
+	etm     bool
+	new     func(key []byte) hash.Hash
+}
+
+// truncatingMAC wraps around a hash.Hash and truncates the output digest to
+// a given size.
+type truncatingMAC struct {
+	length int
+	hmac   hash.Hash
+}
+
+func (t truncatingMAC) Write(data []byte) (int, error) {
+	return t.hmac.Write(data)
+}
+
+func (t truncatingMAC) Sum(in []byte) []byte {
+	out := t.hmac.Sum(in)
+	return out[:len(in)+t.length]
+}
+
+func (t truncatingMAC) Reset() {
+	t.hmac.Reset()
+}
+
+func (t truncatingMAC) Size() int {
+	return t.length
+}
+
+func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() }
+
+var macModes = map[string]*macMode{
+	"hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash {
+		return hmac.New(sha256.New, key)
+	}},
+	"hmac-sha2-256": {32, false, func(key []byte) hash.Hash {
+		return hmac.New(sha256.New, key)
+	}},
+	"hmac-sha1": {20, false, func(key []byte) hash.Hash {
+		return hmac.New(sha1.New, key)
+	}},
+	"hmac-sha1-96": {20, false, func(key []byte) hash.Hash {
+		return truncatingMAC{12, hmac.New(sha1.New, key)}
+	}},
+}

+ 758 - 0
vendor/golang.org/x/crypto/ssh/messages.go

@@ -0,0 +1,758 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+	"reflect"
+	"strconv"
+	"strings"
+)
+
+// These are SSH message type numbers. They are scattered around several
+// documents but many were taken from [SSH-PARAMETERS].
+const (
+	msgIgnore        = 2
+	msgUnimplemented = 3
+	msgDebug         = 4
+	msgNewKeys       = 21
+
+	// Standard authentication messages
+	msgUserAuthSuccess = 52
+	msgUserAuthBanner  = 53
+)
+
+// SSH messages:
+//
+// These structures mirror the wire format of the corresponding SSH messages.
+// They are marshaled using reflection with the marshal and unmarshal functions
+// in this file. The only wrinkle is that a final member of type []byte with a
+// ssh tag of "rest" receives the remainder of a packet when unmarshaling.
+
+// See RFC 4253, section 11.1.
+const msgDisconnect = 1
+
+// disconnectMsg is the message that signals a disconnect. It is also
+// the error type returned from mux.Wait()
+type disconnectMsg struct {
+	Reason   uint32 `sshtype:"1"`
+	Message  string
+	Language string
+}
+
+func (d *disconnectMsg) Error() string {
+	return fmt.Sprintf("ssh: disconnect, reason %d: %s", d.Reason, d.Message)
+}
+
+// See RFC 4253, section 7.1.
+const msgKexInit = 20
+
+type kexInitMsg struct {
+	Cookie                  [16]byte `sshtype:"20"`
+	KexAlgos                []string
+	ServerHostKeyAlgos      []string
+	CiphersClientServer     []string
+	CiphersServerClient     []string
+	MACsClientServer        []string
+	MACsServerClient        []string
+	CompressionClientServer []string
+	CompressionServerClient []string
+	LanguagesClientServer   []string
+	LanguagesServerClient   []string
+	FirstKexFollows         bool
+	Reserved                uint32
+}
+
+// See RFC 4253, section 8.
+
+// Diffie-Helman
+const msgKexDHInit = 30
+
+type kexDHInitMsg struct {
+	X *big.Int `sshtype:"30"`
+}
+
+const msgKexECDHInit = 30
+
+type kexECDHInitMsg struct {
+	ClientPubKey []byte `sshtype:"30"`
+}
+
+const msgKexECDHReply = 31
+
+type kexECDHReplyMsg struct {
+	HostKey         []byte `sshtype:"31"`
+	EphemeralPubKey []byte
+	Signature       []byte
+}
+
+const msgKexDHReply = 31
+
+type kexDHReplyMsg struct {
+	HostKey   []byte `sshtype:"31"`
+	Y         *big.Int
+	Signature []byte
+}
+
+// See RFC 4253, section 10.
+const msgServiceRequest = 5
+
+type serviceRequestMsg struct {
+	Service string `sshtype:"5"`
+}
+
+// See RFC 4253, section 10.
+const msgServiceAccept = 6
+
+type serviceAcceptMsg struct {
+	Service string `sshtype:"6"`
+}
+
+// See RFC 4252, section 5.
+const msgUserAuthRequest = 50
+
+type userAuthRequestMsg struct {
+	User    string `sshtype:"50"`
+	Service string
+	Method  string
+	Payload []byte `ssh:"rest"`
+}
+
+// Used for debug printouts of packets.
+type userAuthSuccessMsg struct {
+}
+
+// See RFC 4252, section 5.1
+const msgUserAuthFailure = 51
+
+type userAuthFailureMsg struct {
+	Methods        []string `sshtype:"51"`
+	PartialSuccess bool
+}
+
+// See RFC 4256, section 3.2
+const msgUserAuthInfoRequest = 60
+const msgUserAuthInfoResponse = 61
+
+type userAuthInfoRequestMsg struct {
+	User               string `sshtype:"60"`
+	Instruction        string
+	DeprecatedLanguage string
+	NumPrompts         uint32
+	Prompts            []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.1.
+const msgChannelOpen = 90
+
+type channelOpenMsg struct {
+	ChanType         string `sshtype:"90"`
+	PeersId          uint32
+	PeersWindow      uint32
+	MaxPacketSize    uint32
+	TypeSpecificData []byte `ssh:"rest"`
+}
+
+const msgChannelExtendedData = 95
+const msgChannelData = 94
+
+// Used for debug print outs of packets.
+type channelDataMsg struct {
+	PeersId uint32 `sshtype:"94"`
+	Length  uint32
+	Rest    []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.1.
+const msgChannelOpenConfirm = 91
+
+type channelOpenConfirmMsg struct {
+	PeersId          uint32 `sshtype:"91"`
+	MyId             uint32
+	MyWindow         uint32
+	MaxPacketSize    uint32
+	TypeSpecificData []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.1.
+const msgChannelOpenFailure = 92
+
+type channelOpenFailureMsg struct {
+	PeersId  uint32 `sshtype:"92"`
+	Reason   RejectionReason
+	Message  string
+	Language string
+}
+
+const msgChannelRequest = 98
+
+type channelRequestMsg struct {
+	PeersId             uint32 `sshtype:"98"`
+	Request             string
+	WantReply           bool
+	RequestSpecificData []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 5.4.
+const msgChannelSuccess = 99
+
+type channelRequestSuccessMsg struct {
+	PeersId uint32 `sshtype:"99"`
+}
+
+// See RFC 4254, section 5.4.
+const msgChannelFailure = 100
+
+type channelRequestFailureMsg struct {
+	PeersId uint32 `sshtype:"100"`
+}
+
+// See RFC 4254, section 5.3
+const msgChannelClose = 97
+
+type channelCloseMsg struct {
+	PeersId uint32 `sshtype:"97"`
+}
+
+// See RFC 4254, section 5.3
+const msgChannelEOF = 96
+
+type channelEOFMsg struct {
+	PeersId uint32 `sshtype:"96"`
+}
+
+// See RFC 4254, section 4
+const msgGlobalRequest = 80
+
+type globalRequestMsg struct {
+	Type      string `sshtype:"80"`
+	WantReply bool
+	Data      []byte `ssh:"rest"`
+}
+
+// See RFC 4254, section 4
+const msgRequestSuccess = 81
+
+type globalRequestSuccessMsg struct {
+	Data []byte `ssh:"rest" sshtype:"81"`
+}
+
+// See RFC 4254, section 4
+const msgRequestFailure = 82
+
+type globalRequestFailureMsg struct {
+	Data []byte `ssh:"rest" sshtype:"82"`
+}
+
+// See RFC 4254, section 5.2
+const msgChannelWindowAdjust = 93
+
+type windowAdjustMsg struct {
+	PeersId         uint32 `sshtype:"93"`
+	AdditionalBytes uint32
+}
+
+// See RFC 4252, section 7
+const msgUserAuthPubKeyOk = 60
+
+type userAuthPubKeyOkMsg struct {
+	Algo   string `sshtype:"60"`
+	PubKey []byte
+}
+
+// typeTags returns the possible type bytes for the given reflect.Type, which
+// should be a struct. The possible values are separated by a '|' character.
+func typeTags(structType reflect.Type) (tags []byte) {
+	tagStr := structType.Field(0).Tag.Get("sshtype")
+
+	for _, tag := range strings.Split(tagStr, "|") {
+		i, err := strconv.Atoi(tag)
+		if err == nil {
+			tags = append(tags, byte(i))
+		}
+	}
+
+	return tags
+}
+
+func fieldError(t reflect.Type, field int, problem string) error {
+	if problem != "" {
+		problem = ": " + problem
+	}
+	return fmt.Errorf("ssh: unmarshal error for field %s of type %s%s", t.Field(field).Name, t.Name(), problem)
+}
+
+var errShortRead = errors.New("ssh: short read")
+
+// Unmarshal parses data in SSH wire format into a structure. The out
+// argument should be a pointer to struct. If the first member of the
+// struct has the "sshtype" tag set to a '|'-separated set of numbers
+// in decimal, the packet must start with one of those numbers. In
+// case of error, Unmarshal returns a ParseError or
+// UnexpectedMessageError.
+func Unmarshal(data []byte, out interface{}) error {
+	v := reflect.ValueOf(out).Elem()
+	structType := v.Type()
+	expectedTypes := typeTags(structType)
+
+	var expectedType byte
+	if len(expectedTypes) > 0 {
+		expectedType = expectedTypes[0]
+	}
+
+	if len(data) == 0 {
+		return parseError(expectedType)
+	}
+
+	if len(expectedTypes) > 0 {
+		goodType := false
+		for _, e := range expectedTypes {
+			if e > 0 && data[0] == e {
+				goodType = true
+				break
+			}
+		}
+		if !goodType {
+			return fmt.Errorf("ssh: unexpected message type %d (expected one of %v)", data[0], expectedTypes)
+		}
+		data = data[1:]
+	}
+
+	var ok bool
+	for i := 0; i < v.NumField(); i++ {
+		field := v.Field(i)
+		t := field.Type()
+		switch t.Kind() {
+		case reflect.Bool:
+			if len(data) < 1 {
+				return errShortRead
+			}
+			field.SetBool(data[0] != 0)
+			data = data[1:]
+		case reflect.Array:
+			if t.Elem().Kind() != reflect.Uint8 {
+				return fieldError(structType, i, "array of unsupported type")
+			}
+			if len(data) < t.Len() {
+				return errShortRead
+			}
+			for j, n := 0, t.Len(); j < n; j++ {
+				field.Index(j).Set(reflect.ValueOf(data[j]))
+			}
+			data = data[t.Len():]
+		case reflect.Uint64:
+			var u64 uint64
+			if u64, data, ok = parseUint64(data); !ok {
+				return errShortRead
+			}
+			field.SetUint(u64)
+		case reflect.Uint32:
+			var u32 uint32
+			if u32, data, ok = parseUint32(data); !ok {
+				return errShortRead
+			}
+			field.SetUint(uint64(u32))
+		case reflect.Uint8:
+			if len(data) < 1 {
+				return errShortRead
+			}
+			field.SetUint(uint64(data[0]))
+			data = data[1:]
+		case reflect.String:
+			var s []byte
+			if s, data, ok = parseString(data); !ok {
+				return fieldError(structType, i, "")
+			}
+			field.SetString(string(s))
+		case reflect.Slice:
+			switch t.Elem().Kind() {
+			case reflect.Uint8:
+				if structType.Field(i).Tag.Get("ssh") == "rest" {
+					field.Set(reflect.ValueOf(data))
+					data = nil
+				} else {
+					var s []byte
+					if s, data, ok = parseString(data); !ok {
+						return errShortRead
+					}
+					field.Set(reflect.ValueOf(s))
+				}
+			case reflect.String:
+				var nl []string
+				if nl, data, ok = parseNameList(data); !ok {
+					return errShortRead
+				}
+				field.Set(reflect.ValueOf(nl))
+			default:
+				return fieldError(structType, i, "slice of unsupported type")
+			}
+		case reflect.Ptr:
+			if t == bigIntType {
+				var n *big.Int
+				if n, data, ok = parseInt(data); !ok {
+					return errShortRead
+				}
+				field.Set(reflect.ValueOf(n))
+			} else {
+				return fieldError(structType, i, "pointer to unsupported type")
+			}
+		default:
+			return fieldError(structType, i, fmt.Sprintf("unsupported type: %v", t))
+		}
+	}
+
+	if len(data) != 0 {
+		return parseError(expectedType)
+	}
+
+	return nil
+}
+
+// Marshal serializes the message in msg to SSH wire format.  The msg
+// argument should be a struct or pointer to struct. If the first
+// member has the "sshtype" tag set to a number in decimal, that
+// number is prepended to the result. If the last of member has the
+// "ssh" tag set to "rest", its contents are appended to the output.
+func Marshal(msg interface{}) []byte {
+	out := make([]byte, 0, 64)
+	return marshalStruct(out, msg)
+}
+
+func marshalStruct(out []byte, msg interface{}) []byte {
+	v := reflect.Indirect(reflect.ValueOf(msg))
+	msgTypes := typeTags(v.Type())
+	if len(msgTypes) > 0 {
+		out = append(out, msgTypes[0])
+	}
+
+	for i, n := 0, v.NumField(); i < n; i++ {
+		field := v.Field(i)
+		switch t := field.Type(); t.Kind() {
+		case reflect.Bool:
+			var v uint8
+			if field.Bool() {
+				v = 1
+			}
+			out = append(out, v)
+		case reflect.Array:
+			if t.Elem().Kind() != reflect.Uint8 {
+				panic(fmt.Sprintf("array of non-uint8 in field %d: %T", i, field.Interface()))
+			}
+			for j, l := 0, t.Len(); j < l; j++ {
+				out = append(out, uint8(field.Index(j).Uint()))
+			}
+		case reflect.Uint32:
+			out = appendU32(out, uint32(field.Uint()))
+		case reflect.Uint64:
+			out = appendU64(out, uint64(field.Uint()))
+		case reflect.Uint8:
+			out = append(out, uint8(field.Uint()))
+		case reflect.String:
+			s := field.String()
+			out = appendInt(out, len(s))
+			out = append(out, s...)
+		case reflect.Slice:
+			switch t.Elem().Kind() {
+			case reflect.Uint8:
+				if v.Type().Field(i).Tag.Get("ssh") != "rest" {
+					out = appendInt(out, field.Len())
+				}
+				out = append(out, field.Bytes()...)
+			case reflect.String:
+				offset := len(out)
+				out = appendU32(out, 0)
+				if n := field.Len(); n > 0 {
+					for j := 0; j < n; j++ {
+						f := field.Index(j)
+						if j != 0 {
+							out = append(out, ',')
+						}
+						out = append(out, f.String()...)
+					}
+					// overwrite length value
+					binary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))
+				}
+			default:
+				panic(fmt.Sprintf("slice of unknown type in field %d: %T", i, field.Interface()))
+			}
+		case reflect.Ptr:
+			if t == bigIntType {
+				var n *big.Int
+				nValue := reflect.ValueOf(&n)
+				nValue.Elem().Set(field)
+				needed := intLength(n)
+				oldLength := len(out)
+
+				if cap(out)-len(out) < needed {
+					newOut := make([]byte, len(out), 2*(len(out)+needed))
+					copy(newOut, out)
+					out = newOut
+				}
+				out = out[:oldLength+needed]
+				marshalInt(out[oldLength:], n)
+			} else {
+				panic(fmt.Sprintf("pointer to unknown type in field %d: %T", i, field.Interface()))
+			}
+		}
+	}
+
+	return out
+}
+
+var bigOne = big.NewInt(1)
+
+func parseString(in []byte) (out, rest []byte, ok bool) {
+	if len(in) < 4 {
+		return
+	}
+	length := binary.BigEndian.Uint32(in)
+	in = in[4:]
+	if uint32(len(in)) < length {
+		return
+	}
+	out = in[:length]
+	rest = in[length:]
+	ok = true
+	return
+}
+
+var (
+	comma         = []byte{','}
+	emptyNameList = []string{}
+)
+
+func parseNameList(in []byte) (out []string, rest []byte, ok bool) {
+	contents, rest, ok := parseString(in)
+	if !ok {
+		return
+	}
+	if len(contents) == 0 {
+		out = emptyNameList
+		return
+	}
+	parts := bytes.Split(contents, comma)
+	out = make([]string, len(parts))
+	for i, part := range parts {
+		out[i] = string(part)
+	}
+	return
+}
+
+func parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {
+	contents, rest, ok := parseString(in)
+	if !ok {
+		return
+	}
+	out = new(big.Int)
+
+	if len(contents) > 0 && contents[0]&0x80 == 0x80 {
+		// This is a negative number
+		notBytes := make([]byte, len(contents))
+		for i := range notBytes {
+			notBytes[i] = ^contents[i]
+		}
+		out.SetBytes(notBytes)
+		out.Add(out, bigOne)
+		out.Neg(out)
+	} else {
+		// Positive number
+		out.SetBytes(contents)
+	}
+	ok = true
+	return
+}
+
+func parseUint32(in []byte) (uint32, []byte, bool) {
+	if len(in) < 4 {
+		return 0, nil, false
+	}
+	return binary.BigEndian.Uint32(in), in[4:], true
+}
+
+func parseUint64(in []byte) (uint64, []byte, bool) {
+	if len(in) < 8 {
+		return 0, nil, false
+	}
+	return binary.BigEndian.Uint64(in), in[8:], true
+}
+
+func intLength(n *big.Int) int {
+	length := 4 /* length bytes */
+	if n.Sign() < 0 {
+		nMinus1 := new(big.Int).Neg(n)
+		nMinus1.Sub(nMinus1, bigOne)
+		bitLen := nMinus1.BitLen()
+		if bitLen%8 == 0 {
+			// The number will need 0xff padding
+			length++
+		}
+		length += (bitLen + 7) / 8
+	} else if n.Sign() == 0 {
+		// A zero is the zero length string
+	} else {
+		bitLen := n.BitLen()
+		if bitLen%8 == 0 {
+			// The number will need 0x00 padding
+			length++
+		}
+		length += (bitLen + 7) / 8
+	}
+
+	return length
+}
+
+func marshalUint32(to []byte, n uint32) []byte {
+	binary.BigEndian.PutUint32(to, n)
+	return to[4:]
+}
+
+func marshalUint64(to []byte, n uint64) []byte {
+	binary.BigEndian.PutUint64(to, n)
+	return to[8:]
+}
+
+func marshalInt(to []byte, n *big.Int) []byte {
+	lengthBytes := to
+	to = to[4:]
+	length := 0
+
+	if n.Sign() < 0 {
+		// A negative number has to be converted to two's-complement
+		// form. So we'll subtract 1 and invert. If the
+		// most-significant-bit isn't set then we'll need to pad the
+		// beginning with 0xff in order to keep the number negative.
+		nMinus1 := new(big.Int).Neg(n)
+		nMinus1.Sub(nMinus1, bigOne)
+		bytes := nMinus1.Bytes()
+		for i := range bytes {
+			bytes[i] ^= 0xff
+		}
+		if len(bytes) == 0 || bytes[0]&0x80 == 0 {
+			to[0] = 0xff
+			to = to[1:]
+			length++
+		}
+		nBytes := copy(to, bytes)
+		to = to[nBytes:]
+		length += nBytes
+	} else if n.Sign() == 0 {
+		// A zero is the zero length string
+	} else {
+		bytes := n.Bytes()
+		if len(bytes) > 0 && bytes[0]&0x80 != 0 {
+			// We'll have to pad this with a 0x00 in order to
+			// stop it looking like a negative number.
+			to[0] = 0
+			to = to[1:]
+			length++
+		}
+		nBytes := copy(to, bytes)
+		to = to[nBytes:]
+		length += nBytes
+	}
+
+	lengthBytes[0] = byte(length >> 24)
+	lengthBytes[1] = byte(length >> 16)
+	lengthBytes[2] = byte(length >> 8)
+	lengthBytes[3] = byte(length)
+	return to
+}
+
+func writeInt(w io.Writer, n *big.Int) {
+	length := intLength(n)
+	buf := make([]byte, length)
+	marshalInt(buf, n)
+	w.Write(buf)
+}
+
+func writeString(w io.Writer, s []byte) {
+	var lengthBytes [4]byte
+	lengthBytes[0] = byte(len(s) >> 24)
+	lengthBytes[1] = byte(len(s) >> 16)
+	lengthBytes[2] = byte(len(s) >> 8)
+	lengthBytes[3] = byte(len(s))
+	w.Write(lengthBytes[:])
+	w.Write(s)
+}
+
+func stringLength(n int) int {
+	return 4 + n
+}
+
+func marshalString(to []byte, s []byte) []byte {
+	to[0] = byte(len(s) >> 24)
+	to[1] = byte(len(s) >> 16)
+	to[2] = byte(len(s) >> 8)
+	to[3] = byte(len(s))
+	to = to[4:]
+	copy(to, s)
+	return to[len(s):]
+}
+
+var bigIntType = reflect.TypeOf((*big.Int)(nil))
+
+// Decode a packet into its corresponding message.
+func decode(packet []byte) (interface{}, error) {
+	var msg interface{}
+	switch packet[0] {
+	case msgDisconnect:
+		msg = new(disconnectMsg)
+	case msgServiceRequest:
+		msg = new(serviceRequestMsg)
+	case msgServiceAccept:
+		msg = new(serviceAcceptMsg)
+	case msgKexInit:
+		msg = new(kexInitMsg)
+	case msgKexDHInit:
+		msg = new(kexDHInitMsg)
+	case msgKexDHReply:
+		msg = new(kexDHReplyMsg)
+	case msgUserAuthRequest:
+		msg = new(userAuthRequestMsg)
+	case msgUserAuthSuccess:
+		return new(userAuthSuccessMsg), nil
+	case msgUserAuthFailure:
+		msg = new(userAuthFailureMsg)
+	case msgUserAuthPubKeyOk:
+		msg = new(userAuthPubKeyOkMsg)
+	case msgGlobalRequest:
+		msg = new(globalRequestMsg)
+	case msgRequestSuccess:
+		msg = new(globalRequestSuccessMsg)
+	case msgRequestFailure:
+		msg = new(globalRequestFailureMsg)
+	case msgChannelOpen:
+		msg = new(channelOpenMsg)
+	case msgChannelData:
+		msg = new(channelDataMsg)
+	case msgChannelOpenConfirm:
+		msg = new(channelOpenConfirmMsg)
+	case msgChannelOpenFailure:
+		msg = new(channelOpenFailureMsg)
+	case msgChannelWindowAdjust:
+		msg = new(windowAdjustMsg)
+	case msgChannelEOF:
+		msg = new(channelEOFMsg)
+	case msgChannelClose:
+		msg = new(channelCloseMsg)
+	case msgChannelRequest:
+		msg = new(channelRequestMsg)
+	case msgChannelSuccess:
+		msg = new(channelRequestSuccessMsg)
+	case msgChannelFailure:
+		msg = new(channelRequestFailureMsg)
+	default:
+		return nil, unexpectedMessageError(0, packet[0])
+	}
+	if err := Unmarshal(packet, msg); err != nil {
+		return nil, err
+	}
+	return msg, nil
+}

+ 330 - 0
vendor/golang.org/x/crypto/ssh/mux.go

@@ -0,0 +1,330 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"encoding/binary"
+	"fmt"
+	"io"
+	"log"
+	"sync"
+	"sync/atomic"
+)
+
+// debugMux, if set, causes messages in the connection protocol to be
+// logged.
+const debugMux = false
+
+// chanList is a thread safe channel list.
+type chanList struct {
+	// protects concurrent access to chans
+	sync.Mutex
+
+	// chans are indexed by the local id of the channel, which the
+	// other side should send in the PeersId field.
+	chans []*channel
+
+	// This is a debugging aid: it offsets all IDs by this
+	// amount. This helps distinguish otherwise identical
+	// server/client muxes
+	offset uint32
+}
+
+// Assigns a channel ID to the given channel.
+func (c *chanList) add(ch *channel) uint32 {
+	c.Lock()
+	defer c.Unlock()
+	for i := range c.chans {
+		if c.chans[i] == nil {
+			c.chans[i] = ch
+			return uint32(i) + c.offset
+		}
+	}
+	c.chans = append(c.chans, ch)
+	return uint32(len(c.chans)-1) + c.offset
+}
+
+// getChan returns the channel for the given ID.
+func (c *chanList) getChan(id uint32) *channel {
+	id -= c.offset
+
+	c.Lock()
+	defer c.Unlock()
+	if id < uint32(len(c.chans)) {
+		return c.chans[id]
+	}
+	return nil
+}
+
+func (c *chanList) remove(id uint32) {
+	id -= c.offset
+	c.Lock()
+	if id < uint32(len(c.chans)) {
+		c.chans[id] = nil
+	}
+	c.Unlock()
+}
+
+// dropAll forgets all channels it knows, returning them in a slice.
+func (c *chanList) dropAll() []*channel {
+	c.Lock()
+	defer c.Unlock()
+	var r []*channel
+
+	for _, ch := range c.chans {
+		if ch == nil {
+			continue
+		}
+		r = append(r, ch)
+	}
+	c.chans = nil
+	return r
+}
+
+// mux represents the state for the SSH connection protocol, which
+// multiplexes many channels onto a single packet transport.
+type mux struct {
+	conn     packetConn
+	chanList chanList
+
+	incomingChannels chan NewChannel
+
+	globalSentMu     sync.Mutex
+	globalResponses  chan interface{}
+	incomingRequests chan *Request
+
+	errCond *sync.Cond
+	err     error
+}
+
+// When debugging, each new chanList instantiation has a different
+// offset.
+var globalOff uint32
+
+func (m *mux) Wait() error {
+	m.errCond.L.Lock()
+	defer m.errCond.L.Unlock()
+	for m.err == nil {
+		m.errCond.Wait()
+	}
+	return m.err
+}
+
+// newMux returns a mux that runs over the given connection.
+func newMux(p packetConn) *mux {
+	m := &mux{
+		conn:             p,
+		incomingChannels: make(chan NewChannel, chanSize),
+		globalResponses:  make(chan interface{}, 1),
+		incomingRequests: make(chan *Request, chanSize),
+		errCond:          newCond(),
+	}
+	if debugMux {
+		m.chanList.offset = atomic.AddUint32(&globalOff, 1)
+	}
+
+	go m.loop()
+	return m
+}
+
+func (m *mux) sendMessage(msg interface{}) error {
+	p := Marshal(msg)
+	if debugMux {
+		log.Printf("send global(%d): %#v", m.chanList.offset, msg)
+	}
+	return m.conn.writePacket(p)
+}
+
+func (m *mux) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) {
+	if wantReply {
+		m.globalSentMu.Lock()
+		defer m.globalSentMu.Unlock()
+	}
+
+	if err := m.sendMessage(globalRequestMsg{
+		Type:      name,
+		WantReply: wantReply,
+		Data:      payload,
+	}); err != nil {
+		return false, nil, err
+	}
+
+	if !wantReply {
+		return false, nil, nil
+	}
+
+	msg, ok := <-m.globalResponses
+	if !ok {
+		return false, nil, io.EOF
+	}
+	switch msg := msg.(type) {
+	case *globalRequestFailureMsg:
+		return false, msg.Data, nil
+	case *globalRequestSuccessMsg:
+		return true, msg.Data, nil
+	default:
+		return false, nil, fmt.Errorf("ssh: unexpected response to request: %#v", msg)
+	}
+}
+
+// ackRequest must be called after processing a global request that
+// has WantReply set.
+func (m *mux) ackRequest(ok bool, data []byte) error {
+	if ok {
+		return m.sendMessage(globalRequestSuccessMsg{Data: data})
+	}
+	return m.sendMessage(globalRequestFailureMsg{Data: data})
+}
+
+func (m *mux) Close() error {
+	return m.conn.Close()
+}
+
+// loop runs the connection machine. It will process packets until an
+// error is encountered. To synchronize on loop exit, use mux.Wait.
+func (m *mux) loop() {
+	var err error
+	for err == nil {
+		err = m.onePacket()
+	}
+
+	for _, ch := range m.chanList.dropAll() {
+		ch.close()
+	}
+
+	close(m.incomingChannels)
+	close(m.incomingRequests)
+	close(m.globalResponses)
+
+	m.conn.Close()
+
+	m.errCond.L.Lock()
+	m.err = err
+	m.errCond.Broadcast()
+	m.errCond.L.Unlock()
+
+	if debugMux {
+		log.Println("loop exit", err)
+	}
+}
+
+// onePacket reads and processes one packet.
+func (m *mux) onePacket() error {
+	packet, err := m.conn.readPacket()
+	if err != nil {
+		return err
+	}
+
+	if debugMux {
+		if packet[0] == msgChannelData || packet[0] == msgChannelExtendedData {
+			log.Printf("decoding(%d): data packet - %d bytes", m.chanList.offset, len(packet))
+		} else {
+			p, _ := decode(packet)
+			log.Printf("decoding(%d): %d %#v - %d bytes", m.chanList.offset, packet[0], p, len(packet))
+		}
+	}
+
+	switch packet[0] {
+	case msgChannelOpen:
+		return m.handleChannelOpen(packet)
+	case msgGlobalRequest, msgRequestSuccess, msgRequestFailure:
+		return m.handleGlobalPacket(packet)
+	}
+
+	// assume a channel packet.
+	if len(packet) < 5 {
+		return parseError(packet[0])
+	}
+	id := binary.BigEndian.Uint32(packet[1:])
+	ch := m.chanList.getChan(id)
+	if ch == nil {
+		return fmt.Errorf("ssh: invalid channel %d", id)
+	}
+
+	return ch.handlePacket(packet)
+}
+
+func (m *mux) handleGlobalPacket(packet []byte) error {
+	msg, err := decode(packet)
+	if err != nil {
+		return err
+	}
+
+	switch msg := msg.(type) {
+	case *globalRequestMsg:
+		m.incomingRequests <- &Request{
+			Type:      msg.Type,
+			WantReply: msg.WantReply,
+			Payload:   msg.Data,
+			mux:       m,
+		}
+	case *globalRequestSuccessMsg, *globalRequestFailureMsg:
+		m.globalResponses <- msg
+	default:
+		panic(fmt.Sprintf("not a global message %#v", msg))
+	}
+
+	return nil
+}
+
+// handleChannelOpen schedules a channel to be Accept()ed.
+func (m *mux) handleChannelOpen(packet []byte) error {
+	var msg channelOpenMsg
+	if err := Unmarshal(packet, &msg); err != nil {
+		return err
+	}
+
+	if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
+		failMsg := channelOpenFailureMsg{
+			PeersId:  msg.PeersId,
+			Reason:   ConnectionFailed,
+			Message:  "invalid request",
+			Language: "en_US.UTF-8",
+		}
+		return m.sendMessage(failMsg)
+	}
+
+	c := m.newChannel(msg.ChanType, channelInbound, msg.TypeSpecificData)
+	c.remoteId = msg.PeersId
+	c.maxRemotePayload = msg.MaxPacketSize
+	c.remoteWin.add(msg.PeersWindow)
+	m.incomingChannels <- c
+	return nil
+}
+
+func (m *mux) OpenChannel(chanType string, extra []byte) (Channel, <-chan *Request, error) {
+	ch, err := m.openChannel(chanType, extra)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return ch, ch.incomingRequests, nil
+}
+
+func (m *mux) openChannel(chanType string, extra []byte) (*channel, error) {
+	ch := m.newChannel(chanType, channelOutbound, extra)
+
+	ch.maxIncomingPayload = channelMaxPacket
+
+	open := channelOpenMsg{
+		ChanType:         chanType,
+		PeersWindow:      ch.myWindow,
+		MaxPacketSize:    ch.maxIncomingPayload,
+		TypeSpecificData: extra,
+		PeersId:          ch.localId,
+	}
+	if err := m.sendMessage(open); err != nil {
+		return nil, err
+	}
+
+	switch msg := (<-ch.msg).(type) {
+	case *channelOpenConfirmMsg:
+		return ch, nil
+	case *channelOpenFailureMsg:
+		return nil, &OpenChannelError{msg.Reason, msg.Message}
+	default:
+		return nil, fmt.Errorf("ssh: unexpected packet in response to channel open: %T", msg)
+	}
+}

+ 563 - 0
vendor/golang.org/x/crypto/ssh/server.go

@@ -0,0 +1,563 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"strings"
+)
+
+// The Permissions type holds fine-grained permissions that are
+// specific to a user or a specific authentication method for a user.
+// The Permissions value for a successful authentication attempt is
+// available in ServerConn, so it can be used to pass information from
+// the user-authentication phase to the application layer.
+type Permissions struct {
+	// CriticalOptions indicate restrictions to the default
+	// permissions, and are typically used in conjunction with
+	// user certificates. The standard for SSH certificates
+	// defines "force-command" (only allow the given command to
+	// execute) and "source-address" (only allow connections from
+	// the given address). The SSH package currently only enforces
+	// the "source-address" critical option. It is up to server
+	// implementations to enforce other critical options, such as
+	// "force-command", by checking them after the SSH handshake
+	// is successful. In general, SSH servers should reject
+	// connections that specify critical options that are unknown
+	// or not supported.
+	CriticalOptions map[string]string
+
+	// Extensions are extra functionality that the server may
+	// offer on authenticated connections. Lack of support for an
+	// extension does not preclude authenticating a user. Common
+	// extensions are "permit-agent-forwarding",
+	// "permit-X11-forwarding". The Go SSH library currently does
+	// not act on any extension, and it is up to server
+	// implementations to honor them. Extensions can be used to
+	// pass data from the authentication callbacks to the server
+	// application layer.
+	Extensions map[string]string
+}
+
+// ServerConfig holds server specific configuration data.
+type ServerConfig struct {
+	// Config contains configuration shared between client and server.
+	Config
+
+	hostKeys []Signer
+
+	// NoClientAuth is true if clients are allowed to connect without
+	// authenticating.
+	NoClientAuth bool
+
+	// MaxAuthTries specifies the maximum number of authentication attempts
+	// permitted per connection. If set to a negative number, the number of
+	// attempts are unlimited. If set to zero, the number of attempts are limited
+	// to 6.
+	MaxAuthTries int
+
+	// PasswordCallback, if non-nil, is called when a user
+	// attempts to authenticate using a password.
+	PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)
+
+	// PublicKeyCallback, if non-nil, is called when a client
+	// offers a public key for authentication. It must return a nil error
+	// if the given public key can be used to authenticate the
+	// given user. For example, see CertChecker.Authenticate. A
+	// call to this function does not guarantee that the key
+	// offered is in fact used to authenticate. To record any data
+	// depending on the public key, store it inside a
+	// Permissions.Extensions entry.
+	PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
+
+	// KeyboardInteractiveCallback, if non-nil, is called when
+	// keyboard-interactive authentication is selected (RFC
+	// 4256). The client object's Challenge function should be
+	// used to query the user. The callback may offer multiple
+	// Challenge rounds. To avoid information leaks, the client
+	// should be presented a challenge even if the user is
+	// unknown.
+	KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error)
+
+	// AuthLogCallback, if non-nil, is called to log all authentication
+	// attempts.
+	AuthLogCallback func(conn ConnMetadata, method string, err error)
+
+	// ServerVersion is the version identification string to announce in
+	// the public handshake.
+	// If empty, a reasonable default is used.
+	// Note that RFC 4253 section 4.2 requires that this string start with
+	// "SSH-2.0-".
+	ServerVersion string
+}
+
+// AddHostKey adds a private key as a host key. If an existing host
+// key exists with the same algorithm, it is overwritten. Each server
+// config must have at least one host key.
+func (s *ServerConfig) AddHostKey(key Signer) {
+	for i, k := range s.hostKeys {
+		if k.PublicKey().Type() == key.PublicKey().Type() {
+			s.hostKeys[i] = key
+			return
+		}
+	}
+
+	s.hostKeys = append(s.hostKeys, key)
+}
+
+// cachedPubKey contains the results of querying whether a public key is
+// acceptable for a user.
+type cachedPubKey struct {
+	user       string
+	pubKeyData []byte
+	result     error
+	perms      *Permissions
+}
+
+const maxCachedPubKeys = 16
+
+// pubKeyCache caches tests for public keys.  Since SSH clients
+// will query whether a public key is acceptable before attempting to
+// authenticate with it, we end up with duplicate queries for public
+// key validity.  The cache only applies to a single ServerConn.
+type pubKeyCache struct {
+	keys []cachedPubKey
+}
+
+// get returns the result for a given user/algo/key tuple.
+func (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) {
+	for _, k := range c.keys {
+		if k.user == user && bytes.Equal(k.pubKeyData, pubKeyData) {
+			return k, true
+		}
+	}
+	return cachedPubKey{}, false
+}
+
+// add adds the given tuple to the cache.
+func (c *pubKeyCache) add(candidate cachedPubKey) {
+	if len(c.keys) < maxCachedPubKeys {
+		c.keys = append(c.keys, candidate)
+	}
+}
+
+// ServerConn is an authenticated SSH connection, as seen from the
+// server
+type ServerConn struct {
+	Conn
+
+	// If the succeeding authentication callback returned a
+	// non-nil Permissions pointer, it is stored here.
+	Permissions *Permissions
+}
+
+// NewServerConn starts a new SSH server with c as the underlying
+// transport.  It starts with a handshake and, if the handshake is
+// unsuccessful, it closes the connection and returns an error.  The
+// Request and NewChannel channels must be serviced, or the connection
+// will hang.
+func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) {
+	fullConf := *config
+	fullConf.SetDefaults()
+	if fullConf.MaxAuthTries == 0 {
+		fullConf.MaxAuthTries = 6
+	}
+
+	s := &connection{
+		sshConn: sshConn{conn: c},
+	}
+	perms, err := s.serverHandshake(&fullConf)
+	if err != nil {
+		c.Close()
+		return nil, nil, nil, err
+	}
+	return &ServerConn{s, perms}, s.mux.incomingChannels, s.mux.incomingRequests, nil
+}
+
+// signAndMarshal signs the data with the appropriate algorithm,
+// and serializes the result in SSH wire format.
+func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) {
+	sig, err := k.Sign(rand, data)
+	if err != nil {
+		return nil, err
+	}
+
+	return Marshal(sig), nil
+}
+
+// handshake performs key exchange and user authentication.
+func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) {
+	if len(config.hostKeys) == 0 {
+		return nil, errors.New("ssh: server has no host keys")
+	}
+
+	if !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil && config.KeyboardInteractiveCallback == nil {
+		return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
+	}
+
+	if config.ServerVersion != "" {
+		s.serverVersion = []byte(config.ServerVersion)
+	} else {
+		s.serverVersion = []byte(packageVersion)
+	}
+	var err error
+	s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion)
+	if err != nil {
+		return nil, err
+	}
+
+	tr := newTransport(s.sshConn.conn, config.Rand, false /* not client */)
+	s.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config)
+
+	if err := s.transport.waitSession(); err != nil {
+		return nil, err
+	}
+
+	// We just did the key change, so the session ID is established.
+	s.sessionID = s.transport.getSessionID()
+
+	var packet []byte
+	if packet, err = s.transport.readPacket(); err != nil {
+		return nil, err
+	}
+
+	var serviceRequest serviceRequestMsg
+	if err = Unmarshal(packet, &serviceRequest); err != nil {
+		return nil, err
+	}
+	if serviceRequest.Service != serviceUserAuth {
+		return nil, errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating")
+	}
+	serviceAccept := serviceAcceptMsg{
+		Service: serviceUserAuth,
+	}
+	if err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil {
+		return nil, err
+	}
+
+	perms, err := s.serverAuthenticate(config)
+	if err != nil {
+		return nil, err
+	}
+	s.mux = newMux(s.transport)
+	return perms, err
+}
+
+func isAcceptableAlgo(algo string) bool {
+	switch algo {
+	case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoED25519,
+		CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01:
+		return true
+	}
+	return false
+}
+
+func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
+	if addr == nil {
+		return errors.New("ssh: no address known for client, but source-address match required")
+	}
+
+	tcpAddr, ok := addr.(*net.TCPAddr)
+	if !ok {
+		return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr)
+	}
+
+	for _, sourceAddr := range strings.Split(sourceAddrs, ",") {
+		if allowedIP := net.ParseIP(sourceAddr); allowedIP != nil {
+			if allowedIP.Equal(tcpAddr.IP) {
+				return nil
+			}
+		} else {
+			_, ipNet, err := net.ParseCIDR(sourceAddr)
+			if err != nil {
+				return fmt.Errorf("ssh: error parsing source-address restriction %q: %v", sourceAddr, err)
+			}
+
+			if ipNet.Contains(tcpAddr.IP) {
+				return nil
+			}
+		}
+	}
+
+	return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
+}
+
+// ServerAuthError implements the error interface. It appends any authentication
+// errors that may occur, and is returned if all of the authentication methods
+// provided by the user failed to authenticate.
+type ServerAuthError struct {
+	// Errors contains authentication errors returned by the authentication
+	// callback methods.
+	Errors []error
+}
+
+func (l ServerAuthError) Error() string {
+	var errs []string
+	for _, err := range l.Errors {
+		errs = append(errs, err.Error())
+	}
+	return "[" + strings.Join(errs, ", ") + "]"
+}
+
+func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
+	sessionID := s.transport.getSessionID()
+	var cache pubKeyCache
+	var perms *Permissions
+
+	authFailures := 0
+	var authErrs []error
+
+userAuthLoop:
+	for {
+		if authFailures >= config.MaxAuthTries && config.MaxAuthTries > 0 {
+			discMsg := &disconnectMsg{
+				Reason:  2,
+				Message: "too many authentication failures",
+			}
+
+			if err := s.transport.writePacket(Marshal(discMsg)); err != nil {
+				return nil, err
+			}
+
+			return nil, discMsg
+		}
+
+		var userAuthReq userAuthRequestMsg
+		if packet, err := s.transport.readPacket(); err != nil {
+			if err == io.EOF {
+				return nil, &ServerAuthError{Errors: authErrs}
+			}
+			return nil, err
+		} else if err = Unmarshal(packet, &userAuthReq); err != nil {
+			return nil, err
+		}
+
+		if userAuthReq.Service != serviceSSH {
+			return nil, errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service)
+		}
+
+		s.user = userAuthReq.User
+		perms = nil
+		authErr := errors.New("no auth passed yet")
+
+		switch userAuthReq.Method {
+		case "none":
+			if config.NoClientAuth {
+				authErr = nil
+			}
+
+			// allow initial attempt of 'none' without penalty
+			if authFailures == 0 {
+				authFailures--
+			}
+		case "password":
+			if config.PasswordCallback == nil {
+				authErr = errors.New("ssh: password auth not configured")
+				break
+			}
+			payload := userAuthReq.Payload
+			if len(payload) < 1 || payload[0] != 0 {
+				return nil, parseError(msgUserAuthRequest)
+			}
+			payload = payload[1:]
+			password, payload, ok := parseString(payload)
+			if !ok || len(payload) > 0 {
+				return nil, parseError(msgUserAuthRequest)
+			}
+
+			perms, authErr = config.PasswordCallback(s, password)
+		case "keyboard-interactive":
+			if config.KeyboardInteractiveCallback == nil {
+				authErr = errors.New("ssh: keyboard-interactive auth not configubred")
+				break
+			}
+
+			prompter := &sshClientKeyboardInteractive{s}
+			perms, authErr = config.KeyboardInteractiveCallback(s, prompter.Challenge)
+		case "publickey":
+			if config.PublicKeyCallback == nil {
+				authErr = errors.New("ssh: publickey auth not configured")
+				break
+			}
+			payload := userAuthReq.Payload
+			if len(payload) < 1 {
+				return nil, parseError(msgUserAuthRequest)
+			}
+			isQuery := payload[0] == 0
+			payload = payload[1:]
+			algoBytes, payload, ok := parseString(payload)
+			if !ok {
+				return nil, parseError(msgUserAuthRequest)
+			}
+			algo := string(algoBytes)
+			if !isAcceptableAlgo(algo) {
+				authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo)
+				break
+			}
+
+			pubKeyData, payload, ok := parseString(payload)
+			if !ok {
+				return nil, parseError(msgUserAuthRequest)
+			}
+
+			pubKey, err := ParsePublicKey(pubKeyData)
+			if err != nil {
+				return nil, err
+			}
+
+			candidate, ok := cache.get(s.user, pubKeyData)
+			if !ok {
+				candidate.user = s.user
+				candidate.pubKeyData = pubKeyData
+				candidate.perms, candidate.result = config.PublicKeyCallback(s, pubKey)
+				if candidate.result == nil && candidate.perms != nil && candidate.perms.CriticalOptions != nil && candidate.perms.CriticalOptions[sourceAddressCriticalOption] != "" {
+					candidate.result = checkSourceAddress(
+						s.RemoteAddr(),
+						candidate.perms.CriticalOptions[sourceAddressCriticalOption])
+				}
+				cache.add(candidate)
+			}
+
+			if isQuery {
+				// The client can query if the given public key
+				// would be okay.
+
+				if len(payload) > 0 {
+					return nil, parseError(msgUserAuthRequest)
+				}
+
+				if candidate.result == nil {
+					okMsg := userAuthPubKeyOkMsg{
+						Algo:   algo,
+						PubKey: pubKeyData,
+					}
+					if err = s.transport.writePacket(Marshal(&okMsg)); err != nil {
+						return nil, err
+					}
+					continue userAuthLoop
+				}
+				authErr = candidate.result
+			} else {
+				sig, payload, ok := parseSignature(payload)
+				if !ok || len(payload) > 0 {
+					return nil, parseError(msgUserAuthRequest)
+				}
+				// Ensure the public key algo and signature algo
+				// are supported.  Compare the private key
+				// algorithm name that corresponds to algo with
+				// sig.Format.  This is usually the same, but
+				// for certs, the names differ.
+				if !isAcceptableAlgo(sig.Format) {
+					break
+				}
+				signedData := buildDataSignedForAuth(sessionID, userAuthReq, algoBytes, pubKeyData)
+
+				if err := pubKey.Verify(signedData, sig); err != nil {
+					return nil, err
+				}
+
+				authErr = candidate.result
+				perms = candidate.perms
+			}
+		default:
+			authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method)
+		}
+
+		authErrs = append(authErrs, authErr)
+
+		if config.AuthLogCallback != nil {
+			config.AuthLogCallback(s, userAuthReq.Method, authErr)
+		}
+
+		if authErr == nil {
+			break userAuthLoop
+		}
+
+		authFailures++
+
+		var failureMsg userAuthFailureMsg
+		if config.PasswordCallback != nil {
+			failureMsg.Methods = append(failureMsg.Methods, "password")
+		}
+		if config.PublicKeyCallback != nil {
+			failureMsg.Methods = append(failureMsg.Methods, "publickey")
+		}
+		if config.KeyboardInteractiveCallback != nil {
+			failureMsg.Methods = append(failureMsg.Methods, "keyboard-interactive")
+		}
+
+		if len(failureMsg.Methods) == 0 {
+			return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
+		}
+
+		if err := s.transport.writePacket(Marshal(&failureMsg)); err != nil {
+			return nil, err
+		}
+	}
+
+	if err := s.transport.writePacket([]byte{msgUserAuthSuccess}); err != nil {
+		return nil, err
+	}
+	return perms, nil
+}
+
+// sshClientKeyboardInteractive implements a ClientKeyboardInteractive by
+// asking the client on the other side of a ServerConn.
+type sshClientKeyboardInteractive struct {
+	*connection
+}
+
+func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
+	if len(questions) != len(echos) {
+		return nil, errors.New("ssh: echos and questions must have equal length")
+	}
+
+	var prompts []byte
+	for i := range questions {
+		prompts = appendString(prompts, questions[i])
+		prompts = appendBool(prompts, echos[i])
+	}
+
+	if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{
+		Instruction: instruction,
+		NumPrompts:  uint32(len(questions)),
+		Prompts:     prompts,
+	})); err != nil {
+		return nil, err
+	}
+
+	packet, err := c.transport.readPacket()
+	if err != nil {
+		return nil, err
+	}
+	if packet[0] != msgUserAuthInfoResponse {
+		return nil, unexpectedMessageError(msgUserAuthInfoResponse, packet[0])
+	}
+	packet = packet[1:]
+
+	n, packet, ok := parseUint32(packet)
+	if !ok || int(n) != len(questions) {
+		return nil, parseError(msgUserAuthInfoResponse)
+	}
+
+	for i := uint32(0); i < n; i++ {
+		ans, rest, ok := parseString(packet)
+		if !ok {
+			return nil, parseError(msgUserAuthInfoResponse)
+		}
+
+		answers = append(answers, string(ans))
+		packet = rest
+	}
+	if len(packet) != 0 {
+		return nil, errors.New("ssh: junk at end of message")
+	}
+
+	return answers, nil
+}

+ 647 - 0
vendor/golang.org/x/crypto/ssh/session.go

@@ -0,0 +1,647 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+// Session implements an interactive session described in
+// "RFC 4254, section 6".
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"sync"
+)
+
+type Signal string
+
+// POSIX signals as listed in RFC 4254 Section 6.10.
+const (
+	SIGABRT Signal = "ABRT"
+	SIGALRM Signal = "ALRM"
+	SIGFPE  Signal = "FPE"
+	SIGHUP  Signal = "HUP"
+	SIGILL  Signal = "ILL"
+	SIGINT  Signal = "INT"
+	SIGKILL Signal = "KILL"
+	SIGPIPE Signal = "PIPE"
+	SIGQUIT Signal = "QUIT"
+	SIGSEGV Signal = "SEGV"
+	SIGTERM Signal = "TERM"
+	SIGUSR1 Signal = "USR1"
+	SIGUSR2 Signal = "USR2"
+)
+
+var signals = map[Signal]int{
+	SIGABRT: 6,
+	SIGALRM: 14,
+	SIGFPE:  8,
+	SIGHUP:  1,
+	SIGILL:  4,
+	SIGINT:  2,
+	SIGKILL: 9,
+	SIGPIPE: 13,
+	SIGQUIT: 3,
+	SIGSEGV: 11,
+	SIGTERM: 15,
+}
+
+type TerminalModes map[uint8]uint32
+
+// POSIX terminal mode flags as listed in RFC 4254 Section 8.
+const (
+	tty_OP_END    = 0
+	VINTR         = 1
+	VQUIT         = 2
+	VERASE        = 3
+	VKILL         = 4
+	VEOF          = 5
+	VEOL          = 6
+	VEOL2         = 7
+	VSTART        = 8
+	VSTOP         = 9
+	VSUSP         = 10
+	VDSUSP        = 11
+	VREPRINT      = 12
+	VWERASE       = 13
+	VLNEXT        = 14
+	VFLUSH        = 15
+	VSWTCH        = 16
+	VSTATUS       = 17
+	VDISCARD      = 18
+	IGNPAR        = 30
+	PARMRK        = 31
+	INPCK         = 32
+	ISTRIP        = 33
+	INLCR         = 34
+	IGNCR         = 35
+	ICRNL         = 36
+	IUCLC         = 37
+	IXON          = 38
+	IXANY         = 39
+	IXOFF         = 40
+	IMAXBEL       = 41
+	ISIG          = 50
+	ICANON        = 51
+	XCASE         = 52
+	ECHO          = 53
+	ECHOE         = 54
+	ECHOK         = 55
+	ECHONL        = 56
+	NOFLSH        = 57
+	TOSTOP        = 58
+	IEXTEN        = 59
+	ECHOCTL       = 60
+	ECHOKE        = 61
+	PENDIN        = 62
+	OPOST         = 70
+	OLCUC         = 71
+	ONLCR         = 72
+	OCRNL         = 73
+	ONOCR         = 74
+	ONLRET        = 75
+	CS7           = 90
+	CS8           = 91
+	PARENB        = 92
+	PARODD        = 93
+	TTY_OP_ISPEED = 128
+	TTY_OP_OSPEED = 129
+)
+
+// A Session represents a connection to a remote command or shell.
+type Session struct {
+	// Stdin specifies the remote process's standard input.
+	// If Stdin is nil, the remote process reads from an empty
+	// bytes.Buffer.
+	Stdin io.Reader
+
+	// Stdout and Stderr specify the remote process's standard
+	// output and error.
+	//
+	// If either is nil, Run connects the corresponding file
+	// descriptor to an instance of ioutil.Discard. There is a
+	// fixed amount of buffering that is shared for the two streams.
+	// If either blocks it may eventually cause the remote
+	// command to block.
+	Stdout io.Writer
+	Stderr io.Writer
+
+	ch        Channel // the channel backing this session
+	started   bool    // true once Start, Run or Shell is invoked.
+	copyFuncs []func() error
+	errors    chan error // one send per copyFunc
+
+	// true if pipe method is active
+	stdinpipe, stdoutpipe, stderrpipe bool
+
+	// stdinPipeWriter is non-nil if StdinPipe has not been called
+	// and Stdin was specified by the user; it is the write end of
+	// a pipe connecting Session.Stdin to the stdin channel.
+	stdinPipeWriter io.WriteCloser
+
+	exitStatus chan error
+}
+
+// SendRequest sends an out-of-band channel request on the SSH channel
+// underlying the session.
+func (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {
+	return s.ch.SendRequest(name, wantReply, payload)
+}
+
+func (s *Session) Close() error {
+	return s.ch.Close()
+}
+
+// RFC 4254 Section 6.4.
+type setenvRequest struct {
+	Name  string
+	Value string
+}
+
+// Setenv sets an environment variable that will be applied to any
+// command executed by Shell or Run.
+func (s *Session) Setenv(name, value string) error {
+	msg := setenvRequest{
+		Name:  name,
+		Value: value,
+	}
+	ok, err := s.ch.SendRequest("env", true, Marshal(&msg))
+	if err == nil && !ok {
+		err = errors.New("ssh: setenv failed")
+	}
+	return err
+}
+
+// RFC 4254 Section 6.2.
+type ptyRequestMsg struct {
+	Term     string
+	Columns  uint32
+	Rows     uint32
+	Width    uint32
+	Height   uint32
+	Modelist string
+}
+
+// RequestPty requests the association of a pty with the session on the remote host.
+func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error {
+	var tm []byte
+	for k, v := range termmodes {
+		kv := struct {
+			Key byte
+			Val uint32
+		}{k, v}
+
+		tm = append(tm, Marshal(&kv)...)
+	}
+	tm = append(tm, tty_OP_END)
+	req := ptyRequestMsg{
+		Term:     term,
+		Columns:  uint32(w),
+		Rows:     uint32(h),
+		Width:    uint32(w * 8),
+		Height:   uint32(h * 8),
+		Modelist: string(tm),
+	}
+	ok, err := s.ch.SendRequest("pty-req", true, Marshal(&req))
+	if err == nil && !ok {
+		err = errors.New("ssh: pty-req failed")
+	}
+	return err
+}
+
+// RFC 4254 Section 6.5.
+type subsystemRequestMsg struct {
+	Subsystem string
+}
+
+// RequestSubsystem requests the association of a subsystem with the session on the remote host.
+// A subsystem is a predefined command that runs in the background when the ssh session is initiated
+func (s *Session) RequestSubsystem(subsystem string) error {
+	msg := subsystemRequestMsg{
+		Subsystem: subsystem,
+	}
+	ok, err := s.ch.SendRequest("subsystem", true, Marshal(&msg))
+	if err == nil && !ok {
+		err = errors.New("ssh: subsystem request failed")
+	}
+	return err
+}
+
+// RFC 4254 Section 6.7.
+type ptyWindowChangeMsg struct {
+	Columns uint32
+	Rows    uint32
+	Width   uint32
+	Height  uint32
+}
+
+// WindowChange informs the remote host about a terminal window dimension change to h rows and w columns.
+func (s *Session) WindowChange(h, w int) error {
+	req := ptyWindowChangeMsg{
+		Columns: uint32(w),
+		Rows:    uint32(h),
+		Width:   uint32(w * 8),
+		Height:  uint32(h * 8),
+	}
+	_, err := s.ch.SendRequest("window-change", false, Marshal(&req))
+	return err
+}
+
+// RFC 4254 Section 6.9.
+type signalMsg struct {
+	Signal string
+}
+
+// Signal sends the given signal to the remote process.
+// sig is one of the SIG* constants.
+func (s *Session) Signal(sig Signal) error {
+	msg := signalMsg{
+		Signal: string(sig),
+	}
+
+	_, err := s.ch.SendRequest("signal", false, Marshal(&msg))
+	return err
+}
+
+// RFC 4254 Section 6.5.
+type execMsg struct {
+	Command string
+}
+
+// Start runs cmd on the remote host. Typically, the remote
+// server passes cmd to the shell for interpretation.
+// A Session only accepts one call to Run, Start or Shell.
+func (s *Session) Start(cmd string) error {
+	if s.started {
+		return errors.New("ssh: session already started")
+	}
+	req := execMsg{
+		Command: cmd,
+	}
+
+	ok, err := s.ch.SendRequest("exec", true, Marshal(&req))
+	if err == nil && !ok {
+		err = fmt.Errorf("ssh: command %v failed", cmd)
+	}
+	if err != nil {
+		return err
+	}
+	return s.start()
+}
+
+// Run runs cmd on the remote host. Typically, the remote
+// server passes cmd to the shell for interpretation.
+// A Session only accepts one call to Run, Start, Shell, Output,
+// or CombinedOutput.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the remote server does not send an exit status, an error of type
+// *ExitMissingError is returned. If the command completes
+// unsuccessfully or is interrupted by a signal, the error is of type
+// *ExitError. Other error types may be returned for I/O problems.
+func (s *Session) Run(cmd string) error {
+	err := s.Start(cmd)
+	if err != nil {
+		return err
+	}
+	return s.Wait()
+}
+
+// Output runs cmd on the remote host and returns its standard output.
+func (s *Session) Output(cmd string) ([]byte, error) {
+	if s.Stdout != nil {
+		return nil, errors.New("ssh: Stdout already set")
+	}
+	var b bytes.Buffer
+	s.Stdout = &b
+	err := s.Run(cmd)
+	return b.Bytes(), err
+}
+
+type singleWriter struct {
+	b  bytes.Buffer
+	mu sync.Mutex
+}
+
+func (w *singleWriter) Write(p []byte) (int, error) {
+	w.mu.Lock()
+	defer w.mu.Unlock()
+	return w.b.Write(p)
+}
+
+// CombinedOutput runs cmd on the remote host and returns its combined
+// standard output and standard error.
+func (s *Session) CombinedOutput(cmd string) ([]byte, error) {
+	if s.Stdout != nil {
+		return nil, errors.New("ssh: Stdout already set")
+	}
+	if s.Stderr != nil {
+		return nil, errors.New("ssh: Stderr already set")
+	}
+	var b singleWriter
+	s.Stdout = &b
+	s.Stderr = &b
+	err := s.Run(cmd)
+	return b.b.Bytes(), err
+}
+
+// Shell starts a login shell on the remote host. A Session only
+// accepts one call to Run, Start, Shell, Output, or CombinedOutput.
+func (s *Session) Shell() error {
+	if s.started {
+		return errors.New("ssh: session already started")
+	}
+
+	ok, err := s.ch.SendRequest("shell", true, nil)
+	if err == nil && !ok {
+		return errors.New("ssh: could not start shell")
+	}
+	if err != nil {
+		return err
+	}
+	return s.start()
+}
+
+func (s *Session) start() error {
+	s.started = true
+
+	type F func(*Session)
+	for _, setupFd := range []F{(*Session).stdin, (*Session).stdout, (*Session).stderr} {
+		setupFd(s)
+	}
+
+	s.errors = make(chan error, len(s.copyFuncs))
+	for _, fn := range s.copyFuncs {
+		go func(fn func() error) {
+			s.errors <- fn()
+		}(fn)
+	}
+	return nil
+}
+
+// Wait waits for the remote command to exit.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the remote server does not send an exit status, an error of type
+// *ExitMissingError is returned. If the command completes
+// unsuccessfully or is interrupted by a signal, the error is of type
+// *ExitError. Other error types may be returned for I/O problems.
+func (s *Session) Wait() error {
+	if !s.started {
+		return errors.New("ssh: session not started")
+	}
+	waitErr := <-s.exitStatus
+
+	if s.stdinPipeWriter != nil {
+		s.stdinPipeWriter.Close()
+	}
+	var copyError error
+	for _ = range s.copyFuncs {
+		if err := <-s.errors; err != nil && copyError == nil {
+			copyError = err
+		}
+	}
+	if waitErr != nil {
+		return waitErr
+	}
+	return copyError
+}
+
+func (s *Session) wait(reqs <-chan *Request) error {
+	wm := Waitmsg{status: -1}
+	// Wait for msg channel to be closed before returning.
+	for msg := range reqs {
+		switch msg.Type {
+		case "exit-status":
+			wm.status = int(binary.BigEndian.Uint32(msg.Payload))
+		case "exit-signal":
+			var sigval struct {
+				Signal     string
+				CoreDumped bool
+				Error      string
+				Lang       string
+			}
+			if err := Unmarshal(msg.Payload, &sigval); err != nil {
+				return err
+			}
+
+			// Must sanitize strings?
+			wm.signal = sigval.Signal
+			wm.msg = sigval.Error
+			wm.lang = sigval.Lang
+		default:
+			// This handles keepalives and matches
+			// OpenSSH's behaviour.
+			if msg.WantReply {
+				msg.Reply(false, nil)
+			}
+		}
+	}
+	if wm.status == 0 {
+		return nil
+	}
+	if wm.status == -1 {
+		// exit-status was never sent from server
+		if wm.signal == "" {
+			// signal was not sent either.  RFC 4254
+			// section 6.10 recommends against this
+			// behavior, but it is allowed, so we let
+			// clients handle it.
+			return &ExitMissingError{}
+		}
+		wm.status = 128
+		if _, ok := signals[Signal(wm.signal)]; ok {
+			wm.status += signals[Signal(wm.signal)]
+		}
+	}
+
+	return &ExitError{wm}
+}
+
+// ExitMissingError is returned if a session is torn down cleanly, but
+// the server sends no confirmation of the exit status.
+type ExitMissingError struct{}
+
+func (e *ExitMissingError) Error() string {
+	return "wait: remote command exited without exit status or exit signal"
+}
+
+func (s *Session) stdin() {
+	if s.stdinpipe {
+		return
+	}
+	var stdin io.Reader
+	if s.Stdin == nil {
+		stdin = new(bytes.Buffer)
+	} else {
+		r, w := io.Pipe()
+		go func() {
+			_, err := io.Copy(w, s.Stdin)
+			w.CloseWithError(err)
+		}()
+		stdin, s.stdinPipeWriter = r, w
+	}
+	s.copyFuncs = append(s.copyFuncs, func() error {
+		_, err := io.Copy(s.ch, stdin)
+		if err1 := s.ch.CloseWrite(); err == nil && err1 != io.EOF {
+			err = err1
+		}
+		return err
+	})
+}
+
+func (s *Session) stdout() {
+	if s.stdoutpipe {
+		return
+	}
+	if s.Stdout == nil {
+		s.Stdout = ioutil.Discard
+	}
+	s.copyFuncs = append(s.copyFuncs, func() error {
+		_, err := io.Copy(s.Stdout, s.ch)
+		return err
+	})
+}
+
+func (s *Session) stderr() {
+	if s.stderrpipe {
+		return
+	}
+	if s.Stderr == nil {
+		s.Stderr = ioutil.Discard
+	}
+	s.copyFuncs = append(s.copyFuncs, func() error {
+		_, err := io.Copy(s.Stderr, s.ch.Stderr())
+		return err
+	})
+}
+
+// sessionStdin reroutes Close to CloseWrite.
+type sessionStdin struct {
+	io.Writer
+	ch Channel
+}
+
+func (s *sessionStdin) Close() error {
+	return s.ch.CloseWrite()
+}
+
+// StdinPipe returns a pipe that will be connected to the
+// remote command's standard input when the command starts.
+func (s *Session) StdinPipe() (io.WriteCloser, error) {
+	if s.Stdin != nil {
+		return nil, errors.New("ssh: Stdin already set")
+	}
+	if s.started {
+		return nil, errors.New("ssh: StdinPipe after process started")
+	}
+	s.stdinpipe = true
+	return &sessionStdin{s.ch, s.ch}, nil
+}
+
+// StdoutPipe returns a pipe that will be connected to the
+// remote command's standard output when the command starts.
+// There is a fixed amount of buffering that is shared between
+// stdout and stderr streams. If the StdoutPipe reader is
+// not serviced fast enough it may eventually cause the
+// remote command to block.
+func (s *Session) StdoutPipe() (io.Reader, error) {
+	if s.Stdout != nil {
+		return nil, errors.New("ssh: Stdout already set")
+	}
+	if s.started {
+		return nil, errors.New("ssh: StdoutPipe after process started")
+	}
+	s.stdoutpipe = true
+	return s.ch, nil
+}
+
+// StderrPipe returns a pipe that will be connected to the
+// remote command's standard error when the command starts.
+// There is a fixed amount of buffering that is shared between
+// stdout and stderr streams. If the StderrPipe reader is
+// not serviced fast enough it may eventually cause the
+// remote command to block.
+func (s *Session) StderrPipe() (io.Reader, error) {
+	if s.Stderr != nil {
+		return nil, errors.New("ssh: Stderr already set")
+	}
+	if s.started {
+		return nil, errors.New("ssh: StderrPipe after process started")
+	}
+	s.stderrpipe = true
+	return s.ch.Stderr(), nil
+}
+
+// newSession returns a new interactive session on the remote host.
+func newSession(ch Channel, reqs <-chan *Request) (*Session, error) {
+	s := &Session{
+		ch: ch,
+	}
+	s.exitStatus = make(chan error, 1)
+	go func() {
+		s.exitStatus <- s.wait(reqs)
+	}()
+
+	return s, nil
+}
+
+// An ExitError reports unsuccessful completion of a remote command.
+type ExitError struct {
+	Waitmsg
+}
+
+func (e *ExitError) Error() string {
+	return e.Waitmsg.String()
+}
+
+// Waitmsg stores the information about an exited remote command
+// as reported by Wait.
+type Waitmsg struct {
+	status int
+	signal string
+	msg    string
+	lang   string
+}
+
+// ExitStatus returns the exit status of the remote command.
+func (w Waitmsg) ExitStatus() int {
+	return w.status
+}
+
+// Signal returns the exit signal of the remote command if
+// it was terminated violently.
+func (w Waitmsg) Signal() string {
+	return w.signal
+}
+
+// Msg returns the exit message given by the remote command
+func (w Waitmsg) Msg() string {
+	return w.msg
+}
+
+// Lang returns the language tag. See RFC 3066
+func (w Waitmsg) Lang() string {
+	return w.lang
+}
+
+func (w Waitmsg) String() string {
+	str := fmt.Sprintf("Process exited with status %v", w.status)
+	if w.signal != "" {
+		str += fmt.Sprintf(" from signal %v", w.signal)
+	}
+	if w.msg != "" {
+		str += fmt.Sprintf(". Reason was: %v", w.msg)
+	}
+	return str
+}

+ 115 - 0
vendor/golang.org/x/crypto/ssh/streamlocal.go

@@ -0,0 +1,115 @@
+package ssh
+
+import (
+	"errors"
+	"io"
+	"net"
+)
+
+// streamLocalChannelOpenDirectMsg is a struct used for SSH_MSG_CHANNEL_OPEN message
+// with "direct-streamlocal@openssh.com" string.
+//
+// See openssh-portable/PROTOCOL, section 2.4. connection: Unix domain socket forwarding
+// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL#L235
+type streamLocalChannelOpenDirectMsg struct {
+	socketPath string
+	reserved0  string
+	reserved1  uint32
+}
+
+// forwardedStreamLocalPayload is a struct used for SSH_MSG_CHANNEL_OPEN message
+// with "forwarded-streamlocal@openssh.com" string.
+type forwardedStreamLocalPayload struct {
+	SocketPath string
+	Reserved0  string
+}
+
+// streamLocalChannelForwardMsg is a struct used for SSH2_MSG_GLOBAL_REQUEST message
+// with "streamlocal-forward@openssh.com"/"cancel-streamlocal-forward@openssh.com" string.
+type streamLocalChannelForwardMsg struct {
+	socketPath string
+}
+
+// ListenUnix is similar to ListenTCP but uses a Unix domain socket.
+func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
+	m := streamLocalChannelForwardMsg{
+		socketPath,
+	}
+	// send message
+	ok, _, err := c.SendRequest("streamlocal-forward@openssh.com", true, Marshal(&m))
+	if err != nil {
+		return nil, err
+	}
+	if !ok {
+		return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer")
+	}
+	ch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: "unix"})
+
+	return &unixListener{socketPath, c, ch}, nil
+}
+
+func (c *Client) dialStreamLocal(socketPath string) (Channel, error) {
+	msg := streamLocalChannelOpenDirectMsg{
+		socketPath: socketPath,
+	}
+	ch, in, err := c.OpenChannel("direct-streamlocal@openssh.com", Marshal(&msg))
+	if err != nil {
+		return nil, err
+	}
+	go DiscardRequests(in)
+	return ch, err
+}
+
+type unixListener struct {
+	socketPath string
+
+	conn *Client
+	in   <-chan forward
+}
+
+// Accept waits for and returns the next connection to the listener.
+func (l *unixListener) Accept() (net.Conn, error) {
+	s, ok := <-l.in
+	if !ok {
+		return nil, io.EOF
+	}
+	ch, incoming, err := s.newCh.Accept()
+	if err != nil {
+		return nil, err
+	}
+	go DiscardRequests(incoming)
+
+	return &chanConn{
+		Channel: ch,
+		laddr: &net.UnixAddr{
+			Name: l.socketPath,
+			Net:  "unix",
+		},
+		raddr: &net.UnixAddr{
+			Name: "@",
+			Net:  "unix",
+		},
+	}, nil
+}
+
+// Close closes the listener.
+func (l *unixListener) Close() error {
+	// this also closes the listener.
+	l.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: "unix"})
+	m := streamLocalChannelForwardMsg{
+		l.socketPath,
+	}
+	ok, _, err := l.conn.SendRequest("cancel-streamlocal-forward@openssh.com", true, Marshal(&m))
+	if err == nil && !ok {
+		err = errors.New("ssh: cancel-streamlocal-forward@openssh.com failed")
+	}
+	return err
+}
+
+// Addr returns the listener's network address.
+func (l *unixListener) Addr() net.Addr {
+	return &net.UnixAddr{
+		Name: l.socketPath,
+		Net:  "unix",
+	}
+}

+ 465 - 0
vendor/golang.org/x/crypto/ssh/tcpip.go

@@ -0,0 +1,465 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"math/rand"
+	"net"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+// Listen requests the remote peer open a listening socket on
+// addr. Incoming connections will be available by calling Accept on
+// the returned net.Listener. The listener must be serviced, or the
+// SSH connection may hang.
+// N must be "tcp", "tcp4", "tcp6", or "unix".
+func (c *Client) Listen(n, addr string) (net.Listener, error) {
+	switch n {
+	case "tcp", "tcp4", "tcp6":
+		laddr, err := net.ResolveTCPAddr(n, addr)
+		if err != nil {
+			return nil, err
+		}
+		return c.ListenTCP(laddr)
+	case "unix":
+		return c.ListenUnix(addr)
+	default:
+		return nil, fmt.Errorf("ssh: unsupported protocol: %s", n)
+	}
+}
+
+// Automatic port allocation is broken with OpenSSH before 6.0. See
+// also https://bugzilla.mindrot.org/show_bug.cgi?id=2017.  In
+// particular, OpenSSH 5.9 sends a channelOpenMsg with port number 0,
+// rather than the actual port number. This means you can never open
+// two different listeners with auto allocated ports. We work around
+// this by trying explicit ports until we succeed.
+
+const openSSHPrefix = "OpenSSH_"
+
+var portRandomizer = rand.New(rand.NewSource(time.Now().UnixNano()))
+
+// isBrokenOpenSSHVersion returns true if the given version string
+// specifies a version of OpenSSH that is known to have a bug in port
+// forwarding.
+func isBrokenOpenSSHVersion(versionStr string) bool {
+	i := strings.Index(versionStr, openSSHPrefix)
+	if i < 0 {
+		return false
+	}
+	i += len(openSSHPrefix)
+	j := i
+	for ; j < len(versionStr); j++ {
+		if versionStr[j] < '0' || versionStr[j] > '9' {
+			break
+		}
+	}
+	version, _ := strconv.Atoi(versionStr[i:j])
+	return version < 6
+}
+
+// autoPortListenWorkaround simulates automatic port allocation by
+// trying random ports repeatedly.
+func (c *Client) autoPortListenWorkaround(laddr *net.TCPAddr) (net.Listener, error) {
+	var sshListener net.Listener
+	var err error
+	const tries = 10
+	for i := 0; i < tries; i++ {
+		addr := *laddr
+		addr.Port = 1024 + portRandomizer.Intn(60000)
+		sshListener, err = c.ListenTCP(&addr)
+		if err == nil {
+			laddr.Port = addr.Port
+			return sshListener, err
+		}
+	}
+	return nil, fmt.Errorf("ssh: listen on random port failed after %d tries: %v", tries, err)
+}
+
+// RFC 4254 7.1
+type channelForwardMsg struct {
+	addr  string
+	rport uint32
+}
+
+// ListenTCP requests the remote peer open a listening socket
+// on laddr. Incoming connections will be available by calling
+// Accept on the returned net.Listener.
+func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
+	if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
+		return c.autoPortListenWorkaround(laddr)
+	}
+
+	m := channelForwardMsg{
+		laddr.IP.String(),
+		uint32(laddr.Port),
+	}
+	// send message
+	ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m))
+	if err != nil {
+		return nil, err
+	}
+	if !ok {
+		return nil, errors.New("ssh: tcpip-forward request denied by peer")
+	}
+
+	// If the original port was 0, then the remote side will
+	// supply a real port number in the response.
+	if laddr.Port == 0 {
+		var p struct {
+			Port uint32
+		}
+		if err := Unmarshal(resp, &p); err != nil {
+			return nil, err
+		}
+		laddr.Port = int(p.Port)
+	}
+
+	// Register this forward, using the port number we obtained.
+	ch := c.forwards.add(laddr)
+
+	return &tcpListener{laddr, c, ch}, nil
+}
+
+// forwardList stores a mapping between remote
+// forward requests and the tcpListeners.
+type forwardList struct {
+	sync.Mutex
+	entries []forwardEntry
+}
+
+// forwardEntry represents an established mapping of a laddr on a
+// remote ssh server to a channel connected to a tcpListener.
+type forwardEntry struct {
+	laddr net.Addr
+	c     chan forward
+}
+
+// forward represents an incoming forwarded tcpip connection. The
+// arguments to add/remove/lookup should be address as specified in
+// the original forward-request.
+type forward struct {
+	newCh NewChannel // the ssh client channel underlying this forward
+	raddr net.Addr   // the raddr of the incoming connection
+}
+
+func (l *forwardList) add(addr net.Addr) chan forward {
+	l.Lock()
+	defer l.Unlock()
+	f := forwardEntry{
+		laddr: addr,
+		c:     make(chan forward, 1),
+	}
+	l.entries = append(l.entries, f)
+	return f.c
+}
+
+// See RFC 4254, section 7.2
+type forwardedTCPPayload struct {
+	Addr       string
+	Port       uint32
+	OriginAddr string
+	OriginPort uint32
+}
+
+// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr.
+func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) {
+	if port == 0 || port > 65535 {
+		return nil, fmt.Errorf("ssh: port number out of range: %d", port)
+	}
+	ip := net.ParseIP(string(addr))
+	if ip == nil {
+		return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr)
+	}
+	return &net.TCPAddr{IP: ip, Port: int(port)}, nil
+}
+
+func (l *forwardList) handleChannels(in <-chan NewChannel) {
+	for ch := range in {
+		var (
+			laddr net.Addr
+			raddr net.Addr
+			err   error
+		)
+		switch channelType := ch.ChannelType(); channelType {
+		case "forwarded-tcpip":
+			var payload forwardedTCPPayload
+			if err = Unmarshal(ch.ExtraData(), &payload); err != nil {
+				ch.Reject(ConnectionFailed, "could not parse forwarded-tcpip payload: "+err.Error())
+				continue
+			}
+
+			// RFC 4254 section 7.2 specifies that incoming
+			// addresses should list the address, in string
+			// format. It is implied that this should be an IP
+			// address, as it would be impossible to connect to it
+			// otherwise.
+			laddr, err = parseTCPAddr(payload.Addr, payload.Port)
+			if err != nil {
+				ch.Reject(ConnectionFailed, err.Error())
+				continue
+			}
+			raddr, err = parseTCPAddr(payload.OriginAddr, payload.OriginPort)
+			if err != nil {
+				ch.Reject(ConnectionFailed, err.Error())
+				continue
+			}
+
+		case "forwarded-streamlocal@openssh.com":
+			var payload forwardedStreamLocalPayload
+			if err = Unmarshal(ch.ExtraData(), &payload); err != nil {
+				ch.Reject(ConnectionFailed, "could not parse forwarded-streamlocal@openssh.com payload: "+err.Error())
+				continue
+			}
+			laddr = &net.UnixAddr{
+				Name: payload.SocketPath,
+				Net:  "unix",
+			}
+			raddr = &net.UnixAddr{
+				Name: "@",
+				Net:  "unix",
+			}
+		default:
+			panic(fmt.Errorf("ssh: unknown channel type %s", channelType))
+		}
+		if ok := l.forward(laddr, raddr, ch); !ok {
+			// Section 7.2, implementations MUST reject spurious incoming
+			// connections.
+			ch.Reject(Prohibited, "no forward for address")
+			continue
+		}
+
+	}
+}
+
+// remove removes the forward entry, and the channel feeding its
+// listener.
+func (l *forwardList) remove(addr net.Addr) {
+	l.Lock()
+	defer l.Unlock()
+	for i, f := range l.entries {
+		if addr.Network() == f.laddr.Network() && addr.String() == f.laddr.String() {
+			l.entries = append(l.entries[:i], l.entries[i+1:]...)
+			close(f.c)
+			return
+		}
+	}
+}
+
+// closeAll closes and clears all forwards.
+func (l *forwardList) closeAll() {
+	l.Lock()
+	defer l.Unlock()
+	for _, f := range l.entries {
+		close(f.c)
+	}
+	l.entries = nil
+}
+
+func (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool {
+	l.Lock()
+	defer l.Unlock()
+	for _, f := range l.entries {
+		if laddr.Network() == f.laddr.Network() && laddr.String() == f.laddr.String() {
+			f.c <- forward{newCh: ch, raddr: raddr}
+			return true
+		}
+	}
+	return false
+}
+
+type tcpListener struct {
+	laddr *net.TCPAddr
+
+	conn *Client
+	in   <-chan forward
+}
+
+// Accept waits for and returns the next connection to the listener.
+func (l *tcpListener) Accept() (net.Conn, error) {
+	s, ok := <-l.in
+	if !ok {
+		return nil, io.EOF
+	}
+	ch, incoming, err := s.newCh.Accept()
+	if err != nil {
+		return nil, err
+	}
+	go DiscardRequests(incoming)
+
+	return &chanConn{
+		Channel: ch,
+		laddr:   l.laddr,
+		raddr:   s.raddr,
+	}, nil
+}
+
+// Close closes the listener.
+func (l *tcpListener) Close() error {
+	m := channelForwardMsg{
+		l.laddr.IP.String(),
+		uint32(l.laddr.Port),
+	}
+
+	// this also closes the listener.
+	l.conn.forwards.remove(l.laddr)
+	ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m))
+	if err == nil && !ok {
+		err = errors.New("ssh: cancel-tcpip-forward failed")
+	}
+	return err
+}
+
+// Addr returns the listener's network address.
+func (l *tcpListener) Addr() net.Addr {
+	return l.laddr
+}
+
+// Dial initiates a connection to the addr from the remote host.
+// The resulting connection has a zero LocalAddr() and RemoteAddr().
+func (c *Client) Dial(n, addr string) (net.Conn, error) {
+	var ch Channel
+	switch n {
+	case "tcp", "tcp4", "tcp6":
+		// Parse the address into host and numeric port.
+		host, portString, err := net.SplitHostPort(addr)
+		if err != nil {
+			return nil, err
+		}
+		port, err := strconv.ParseUint(portString, 10, 16)
+		if err != nil {
+			return nil, err
+		}
+		ch, err = c.dial(net.IPv4zero.String(), 0, host, int(port))
+		if err != nil {
+			return nil, err
+		}
+		// Use a zero address for local and remote address.
+		zeroAddr := &net.TCPAddr{
+			IP:   net.IPv4zero,
+			Port: 0,
+		}
+		return &chanConn{
+			Channel: ch,
+			laddr:   zeroAddr,
+			raddr:   zeroAddr,
+		}, nil
+	case "unix":
+		var err error
+		ch, err = c.dialStreamLocal(addr)
+		if err != nil {
+			return nil, err
+		}
+		return &chanConn{
+			Channel: ch,
+			laddr: &net.UnixAddr{
+				Name: "@",
+				Net:  "unix",
+			},
+			raddr: &net.UnixAddr{
+				Name: addr,
+				Net:  "unix",
+			},
+		}, nil
+	default:
+		return nil, fmt.Errorf("ssh: unsupported protocol: %s", n)
+	}
+}
+
+// DialTCP connects to the remote address raddr on the network net,
+// which must be "tcp", "tcp4", or "tcp6".  If laddr is not nil, it is used
+// as the local address for the connection.
+func (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error) {
+	if laddr == nil {
+		laddr = &net.TCPAddr{
+			IP:   net.IPv4zero,
+			Port: 0,
+		}
+	}
+	ch, err := c.dial(laddr.IP.String(), laddr.Port, raddr.IP.String(), raddr.Port)
+	if err != nil {
+		return nil, err
+	}
+	return &chanConn{
+		Channel: ch,
+		laddr:   laddr,
+		raddr:   raddr,
+	}, nil
+}
+
+// RFC 4254 7.2
+type channelOpenDirectMsg struct {
+	raddr string
+	rport uint32
+	laddr string
+	lport uint32
+}
+
+func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel, error) {
+	msg := channelOpenDirectMsg{
+		raddr: raddr,
+		rport: uint32(rport),
+		laddr: laddr,
+		lport: uint32(lport),
+	}
+	ch, in, err := c.OpenChannel("direct-tcpip", Marshal(&msg))
+	if err != nil {
+		return nil, err
+	}
+	go DiscardRequests(in)
+	return ch, err
+}
+
+type tcpChan struct {
+	Channel // the backing channel
+}
+
+// chanConn fulfills the net.Conn interface without
+// the tcpChan having to hold laddr or raddr directly.
+type chanConn struct {
+	Channel
+	laddr, raddr net.Addr
+}
+
+// LocalAddr returns the local network address.
+func (t *chanConn) LocalAddr() net.Addr {
+	return t.laddr
+}
+
+// RemoteAddr returns the remote network address.
+func (t *chanConn) RemoteAddr() net.Addr {
+	return t.raddr
+}
+
+// SetDeadline sets the read and write deadlines associated
+// with the connection.
+func (t *chanConn) SetDeadline(deadline time.Time) error {
+	if err := t.SetReadDeadline(deadline); err != nil {
+		return err
+	}
+	return t.SetWriteDeadline(deadline)
+}
+
+// SetReadDeadline sets the read deadline.
+// A zero value for t means Read will not time out.
+// After the deadline, the error from Read will implement net.Error
+// with Timeout() == true.
+func (t *chanConn) SetReadDeadline(deadline time.Time) error {
+	// for compatibility with previous version,
+	// the error message contains "tcpChan"
+	return errors.New("ssh: tcpChan: deadline not supported")
+}
+
+// SetWriteDeadline exists to satisfy the net.Conn interface
+// but is not implemented by this type.  It always returns an error.
+func (t *chanConn) SetWriteDeadline(deadline time.Time) error {
+	return errors.New("ssh: tcpChan: deadline not supported")
+}

+ 375 - 0
vendor/golang.org/x/crypto/ssh/transport.go

@@ -0,0 +1,375 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssh
+
+import (
+	"bufio"
+	"errors"
+	"io"
+	"log"
+)
+
+// debugTransport if set, will print packet types as they go over the
+// wire. No message decoding is done, to minimize the impact on timing.
+const debugTransport = false
+
+const (
+	gcmCipherID    = "aes128-gcm@openssh.com"
+	aes128cbcID    = "aes128-cbc"
+	tripledescbcID = "3des-cbc"
+)
+
+// packetConn represents a transport that implements packet based
+// operations.
+type packetConn interface {
+	// Encrypt and send a packet of data to the remote peer.
+	writePacket(packet []byte) error
+
+	// Read a packet from the connection. The read is blocking,
+	// i.e. if error is nil, then the returned byte slice is
+	// always non-empty.
+	readPacket() ([]byte, error)
+
+	// Close closes the write-side of the connection.
+	Close() error
+}
+
+// transport is the keyingTransport that implements the SSH packet
+// protocol.
+type transport struct {
+	reader connectionState
+	writer connectionState
+
+	bufReader *bufio.Reader
+	bufWriter *bufio.Writer
+	rand      io.Reader
+	isClient  bool
+	io.Closer
+}
+
+// packetCipher represents a combination of SSH encryption/MAC
+// protocol.  A single instance should be used for one direction only.
+type packetCipher interface {
+	// writePacket encrypts the packet and writes it to w. The
+	// contents of the packet are generally scrambled.
+	writePacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error
+
+	// readPacket reads and decrypts a packet of data. The
+	// returned packet may be overwritten by future calls of
+	// readPacket.
+	readPacket(seqnum uint32, r io.Reader) ([]byte, error)
+}
+
+// connectionState represents one side (read or write) of the
+// connection. This is necessary because each direction has its own
+// keys, and can even have its own algorithms
+type connectionState struct {
+	packetCipher
+	seqNum           uint32
+	dir              direction
+	pendingKeyChange chan packetCipher
+}
+
+// prepareKeyChange sets up key material for a keychange. The key changes in
+// both directions are triggered by reading and writing a msgNewKey packet
+// respectively.
+func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {
+	if ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult); err != nil {
+		return err
+	} else {
+		t.reader.pendingKeyChange <- ciph
+	}
+
+	if ciph, err := newPacketCipher(t.writer.dir, algs.w, kexResult); err != nil {
+		return err
+	} else {
+		t.writer.pendingKeyChange <- ciph
+	}
+
+	return nil
+}
+
+func (t *transport) printPacket(p []byte, write bool) {
+	if len(p) == 0 {
+		return
+	}
+	who := "server"
+	if t.isClient {
+		who = "client"
+	}
+	what := "read"
+	if write {
+		what = "write"
+	}
+
+	log.Println(what, who, p[0])
+}
+
+// Read and decrypt next packet.
+func (t *transport) readPacket() (p []byte, err error) {
+	for {
+		p, err = t.reader.readPacket(t.bufReader)
+		if err != nil {
+			break
+		}
+		if len(p) == 0 || (p[0] != msgIgnore && p[0] != msgDebug) {
+			break
+		}
+	}
+	if debugTransport {
+		t.printPacket(p, false)
+	}
+
+	return p, err
+}
+
+func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
+	packet, err := s.packetCipher.readPacket(s.seqNum, r)
+	s.seqNum++
+	if err == nil && len(packet) == 0 {
+		err = errors.New("ssh: zero length packet")
+	}
+
+	if len(packet) > 0 {
+		switch packet[0] {
+		case msgNewKeys:
+			select {
+			case cipher := <-s.pendingKeyChange:
+				s.packetCipher = cipher
+			default:
+				return nil, errors.New("ssh: got bogus newkeys message.")
+			}
+
+		case msgDisconnect:
+			// Transform a disconnect message into an
+			// error. Since this is lowest level at which
+			// we interpret message types, doing it here
+			// ensures that we don't have to handle it
+			// elsewhere.
+			var msg disconnectMsg
+			if err := Unmarshal(packet, &msg); err != nil {
+				return nil, err
+			}
+			return nil, &msg
+		}
+	}
+
+	// The packet may point to an internal buffer, so copy the
+	// packet out here.
+	fresh := make([]byte, len(packet))
+	copy(fresh, packet)
+
+	return fresh, err
+}
+
+func (t *transport) writePacket(packet []byte) error {
+	if debugTransport {
+		t.printPacket(packet, true)
+	}
+	return t.writer.writePacket(t.bufWriter, t.rand, packet)
+}
+
+func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error {
+	changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
+
+	err := s.packetCipher.writePacket(s.seqNum, w, rand, packet)
+	if err != nil {
+		return err
+	}
+	if err = w.Flush(); err != nil {
+		return err
+	}
+	s.seqNum++
+	if changeKeys {
+		select {
+		case cipher := <-s.pendingKeyChange:
+			s.packetCipher = cipher
+		default:
+			panic("ssh: no key material for msgNewKeys")
+		}
+	}
+	return err
+}
+
+func newTransport(rwc io.ReadWriteCloser, rand io.Reader, isClient bool) *transport {
+	t := &transport{
+		bufReader: bufio.NewReader(rwc),
+		bufWriter: bufio.NewWriter(rwc),
+		rand:      rand,
+		reader: connectionState{
+			packetCipher:     &streamPacketCipher{cipher: noneCipher{}},
+			pendingKeyChange: make(chan packetCipher, 1),
+		},
+		writer: connectionState{
+			packetCipher:     &streamPacketCipher{cipher: noneCipher{}},
+			pendingKeyChange: make(chan packetCipher, 1),
+		},
+		Closer: rwc,
+	}
+	t.isClient = isClient
+
+	if isClient {
+		t.reader.dir = serverKeys
+		t.writer.dir = clientKeys
+	} else {
+		t.reader.dir = clientKeys
+		t.writer.dir = serverKeys
+	}
+
+	return t
+}
+
+type direction struct {
+	ivTag     []byte
+	keyTag    []byte
+	macKeyTag []byte
+}
+
+var (
+	serverKeys = direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}}
+	clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}
+)
+
+// generateKeys generates key material for IV, MAC and encryption.
+func generateKeys(d direction, algs directionAlgorithms, kex *kexResult) (iv, key, macKey []byte) {
+	cipherMode := cipherModes[algs.Cipher]
+	macMode := macModes[algs.MAC]
+
+	iv = make([]byte, cipherMode.ivSize)
+	key = make([]byte, cipherMode.keySize)
+	macKey = make([]byte, macMode.keySize)
+
+	generateKeyMaterial(iv, d.ivTag, kex)
+	generateKeyMaterial(key, d.keyTag, kex)
+	generateKeyMaterial(macKey, d.macKeyTag, kex)
+	return
+}
+
+// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
+// described in RFC 4253, section 6.4. direction should either be serverKeys
+// (to setup server->client keys) or clientKeys (for client->server keys).
+func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
+	iv, key, macKey := generateKeys(d, algs, kex)
+
+	if algs.Cipher == gcmCipherID {
+		return newGCMCipher(iv, key, macKey)
+	}
+
+	if algs.Cipher == aes128cbcID {
+		return newAESCBCCipher(iv, key, macKey, algs)
+	}
+
+	if algs.Cipher == tripledescbcID {
+		return newTripleDESCBCCipher(iv, key, macKey, algs)
+	}
+
+	c := &streamPacketCipher{
+		mac: macModes[algs.MAC].new(macKey),
+		etm: macModes[algs.MAC].etm,
+	}
+	c.macResult = make([]byte, c.mac.Size())
+
+	var err error
+	c.cipher, err = cipherModes[algs.Cipher].createStream(key, iv)
+	if err != nil {
+		return nil, err
+	}
+
+	return c, nil
+}
+
+// generateKeyMaterial fills out with key material generated from tag, K, H
+// and sessionId, as specified in RFC 4253, section 7.2.
+func generateKeyMaterial(out, tag []byte, r *kexResult) {
+	var digestsSoFar []byte
+
+	h := r.Hash.New()
+	for len(out) > 0 {
+		h.Reset()
+		h.Write(r.K)
+		h.Write(r.H)
+
+		if len(digestsSoFar) == 0 {
+			h.Write(tag)
+			h.Write(r.SessionID)
+		} else {
+			h.Write(digestsSoFar)
+		}
+
+		digest := h.Sum(nil)
+		n := copy(out, digest)
+		out = out[n:]
+		if len(out) > 0 {
+			digestsSoFar = append(digestsSoFar, digest...)
+		}
+	}
+}
+
+const packageVersion = "SSH-2.0-Go"
+
+// Sends and receives a version line.  The versionLine string should
+// be US ASCII, start with "SSH-2.0-", and should not include a
+// newline. exchangeVersions returns the other side's version line.
+func exchangeVersions(rw io.ReadWriter, versionLine []byte) (them []byte, err error) {
+	// Contrary to the RFC, we do not ignore lines that don't
+	// start with "SSH-2.0-" to make the library usable with
+	// nonconforming servers.
+	for _, c := range versionLine {
+		// The spec disallows non US-ASCII chars, and
+		// specifically forbids null chars.
+		if c < 32 {
+			return nil, errors.New("ssh: junk character in version line")
+		}
+	}
+	if _, err = rw.Write(append(versionLine, '\r', '\n')); err != nil {
+		return
+	}
+
+	them, err = readVersion(rw)
+	return them, err
+}
+
+// maxVersionStringBytes is the maximum number of bytes that we'll
+// accept as a version string. RFC 4253 section 4.2 limits this at 255
+// chars
+const maxVersionStringBytes = 255
+
+// Read version string as specified by RFC 4253, section 4.2.
+func readVersion(r io.Reader) ([]byte, error) {
+	versionString := make([]byte, 0, 64)
+	var ok bool
+	var buf [1]byte
+
+	for len(versionString) < maxVersionStringBytes {
+		_, err := io.ReadFull(r, buf[:])
+		if err != nil {
+			return nil, err
+		}
+		// The RFC says that the version should be terminated with \r\n
+		// but several SSH servers actually only send a \n.
+		if buf[0] == '\n' {
+			ok = true
+			break
+		}
+
+		// non ASCII chars are disallowed, but we are lenient,
+		// since Go doesn't use null-terminated strings.
+
+		// The RFC allows a comment after a space, however,
+		// all of it (version and comments) goes into the
+		// session hash.
+		versionString = append(versionString, buf[0])
+	}
+
+	if !ok {
+		return nil, errors.New("ssh: overflow reading version string")
+	}
+
+	// There might be a '\r' on the end which we should remove.
+	if len(versionString) > 0 && versionString[len(versionString)-1] == '\r' {
+		versionString = versionString[:len(versionString)-1]
+	}
+	return versionString, nil
+}

+ 13 - 0
vendor/golang.org/x/text/doc.go

@@ -0,0 +1,13 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go
+
+// text is a repository of text-related packages related to internationalization
+// (i18n) and localization (l10n), such as character encodings, text
+// transformations, and locale-specific text handling.
+package text
+
+// TODO: more documentation on general concepts, such as Transformers, use
+// of normalization, etc.

+ 292 - 0
vendor/golang.org/x/text/gen.go

@@ -0,0 +1,292 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// gen runs go generate on Unicode- and CLDR-related package in the text
+// repositories, taking into account dependencies and versions.
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/build"
+	"go/format"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strings"
+	"sync"
+	"unicode"
+
+	"golang.org/x/text/internal/gen"
+)
+
+var (
+	verbose     = flag.Bool("v", false, "verbose output")
+	force       = flag.Bool("force", false, "ignore failing dependencies")
+	doCore      = flag.Bool("core", false, "force an update to core")
+	excludeList = flag.String("exclude", "",
+		"comma-separated list of packages to exclude")
+
+	// The user can specify a selection of packages to build on the command line.
+	args []string
+)
+
+func exclude(pkg string) bool {
+	if len(args) > 0 {
+		return !contains(args, pkg)
+	}
+	return contains(strings.Split(*excludeList, ","), pkg)
+}
+
+// TODO:
+// - Better version handling.
+// - Generate tables for the core unicode package?
+// - Add generation for encodings. This requires some retooling here and there.
+// - Running repo-wide "long" tests.
+
+var vprintf = fmt.Printf
+
+func main() {
+	gen.Init()
+	args = flag.Args()
+	if !*verbose {
+		// Set vprintf to a no-op.
+		vprintf = func(string, ...interface{}) (int, error) { return 0, nil }
+	}
+
+	// TODO: create temporary cache directory to load files and create and set
+	// a "cache" option if the user did not specify the UNICODE_DIR environment
+	// variable. This will prevent duplicate downloads and also will enable long
+	// tests, which really need to be run after each generated package.
+
+	updateCore := *doCore
+	if gen.UnicodeVersion() != unicode.Version {
+		fmt.Printf("Requested Unicode version %s; core unicode version is %s.\n",
+			gen.UnicodeVersion(),
+			unicode.Version)
+		// TODO: use collate to compare. Simple comparison will work, though,
+		// until Unicode reaches version 10. To avoid circular dependencies, we
+		// could use the NumericWeighter without using package collate using a
+		// trivial Weighter implementation.
+		if gen.UnicodeVersion() < unicode.Version && !*force {
+			os.Exit(2)
+		}
+		updateCore = true
+	}
+
+	var unicode = &dependency{}
+	if updateCore {
+		fmt.Printf("Updating core to version %s...\n", gen.UnicodeVersion())
+		unicode = generate("unicode")
+
+		// Test some users of the unicode packages, especially the ones that
+		// keep a mirrored table. These may need to be corrected by hand.
+		generate("regexp", unicode)
+		generate("strconv", unicode) // mimics Unicode table
+		generate("strings", unicode)
+		generate("testing", unicode) // mimics Unicode table
+	}
+
+	var (
+		cldr       = generate("./unicode/cldr", unicode)
+		language   = generate("./language", cldr)
+		internal   = generate("./internal", unicode, language)
+		norm       = generate("./unicode/norm", unicode)
+		rangetable = generate("./unicode/rangetable", unicode)
+		cases      = generate("./cases", unicode, norm, language, rangetable)
+		width      = generate("./width", unicode)
+		bidi       = generate("./unicode/bidi", unicode, norm, rangetable)
+		mib        = generate("./encoding/internal/identifier", unicode)
+		_          = generate("./encoding/htmlindex", unicode, language, mib)
+		_          = generate("./encoding/ianaindex", unicode, language, mib)
+		_          = generate("./secure/precis", unicode, norm, rangetable, cases, width, bidi)
+		_          = generate("./currency", unicode, cldr, language, internal)
+		_          = generate("./internal/number", unicode, cldr, language, internal)
+		_          = generate("./feature/plural", unicode, cldr, language, internal)
+		_          = generate("./internal/export/idna", unicode, bidi, norm)
+		_          = generate("./language/display", unicode, cldr, language, internal)
+		_          = generate("./collate", unicode, norm, cldr, language, rangetable)
+		_          = generate("./search", unicode, norm, cldr, language, rangetable)
+	)
+	all.Wait()
+
+	// Copy exported packages to the destination golang.org repo.
+	copyExported("golang.org/x/net/idna")
+
+	if updateCore {
+		copyVendored()
+	}
+
+	if hasErrors {
+		fmt.Println("FAIL")
+		os.Exit(1)
+	}
+	vprintf("SUCCESS\n")
+}
+
+var (
+	all       sync.WaitGroup
+	hasErrors bool
+)
+
+type dependency struct {
+	sync.WaitGroup
+	hasErrors bool
+}
+
+func generate(pkg string, deps ...*dependency) *dependency {
+	var wg dependency
+	if exclude(pkg) {
+		return &wg
+	}
+	wg.Add(1)
+	all.Add(1)
+	go func() {
+		defer wg.Done()
+		defer all.Done()
+		// Wait for dependencies to finish.
+		for _, d := range deps {
+			d.Wait()
+			if d.hasErrors && !*force {
+				fmt.Printf("--- ABORT: %s\n", pkg)
+				wg.hasErrors = true
+				return
+			}
+		}
+		vprintf("=== GENERATE %s\n", pkg)
+		args := []string{"generate"}
+		if *verbose {
+			args = append(args, "-v")
+		}
+		args = append(args, pkg)
+		cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
+		w := &bytes.Buffer{}
+		cmd.Stderr = w
+		cmd.Stdout = w
+		if err := cmd.Run(); err != nil {
+			fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(w), err)
+			hasErrors = true
+			wg.hasErrors = true
+			return
+		}
+
+		vprintf("=== TEST %s\n", pkg)
+		args[0] = "test"
+		cmd = exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
+		wt := &bytes.Buffer{}
+		cmd.Stderr = wt
+		cmd.Stdout = wt
+		if err := cmd.Run(); err != nil {
+			fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(wt), err)
+			hasErrors = true
+			wg.hasErrors = true
+			return
+		}
+		vprintf("--- SUCCESS: %s\n\t%v\n", pkg, indent(w))
+		fmt.Print(wt.String())
+	}()
+	return &wg
+}
+
+// copyExported copies a package in x/text/internal/export to the
+// destination repository.
+func copyExported(p string) {
+	copyPackage(
+		filepath.Join("internal", "export", path.Base(p)),
+		filepath.Join("..", filepath.FromSlash(p[len("golang.org/x"):])),
+		"golang.org/x/text/internal/export/"+path.Base(p),
+		p)
+}
+
+// copyVendored copies packages used by Go core into the vendored directory.
+func copyVendored() {
+	root := filepath.Join(build.Default.GOROOT, filepath.FromSlash("src/vendor/golang_org/x"))
+
+	err := filepath.Walk(root, func(dir string, info os.FileInfo, err error) error {
+		if err != nil || !info.IsDir() || root == dir {
+			return err
+		}
+		src := dir[len(root)+1:]
+		const slash = string(filepath.Separator)
+		if c := strings.Split(src, slash); c[0] == "text" {
+			// Copy a text repo package from its normal location.
+			src = strings.Join(c[1:], slash)
+		} else {
+			// Copy the vendored package if it exists in the export directory.
+			src = filepath.Join("internal", "export", filepath.Base(src))
+		}
+		copyPackage(src, dir, "golang.org", "golang_org")
+		return nil
+	})
+	if err != nil {
+		fmt.Printf("Seeding directory %s has failed %v:", root, err)
+		os.Exit(1)
+	}
+}
+
+// goGenRE is used to remove go:generate lines.
+var goGenRE = regexp.MustCompile("//go:generate[^\n]*\n")
+
+// copyPackage copies relevant files from a directory in x/text to the
+// destination package directory. The destination package is assumed to have
+// the same name. For each copied file go:generate lines are removed and
+// and package comments are rewritten to the new path.
+func copyPackage(dirSrc, dirDst, search, replace string) {
+	err := filepath.Walk(dirSrc, func(file string, info os.FileInfo, err error) error {
+		base := filepath.Base(file)
+		if err != nil || info.IsDir() ||
+			!strings.HasSuffix(base, ".go") ||
+			strings.HasSuffix(base, "_test.go") && !strings.HasPrefix(base, "example") ||
+			// Don't process subdirectories.
+			filepath.Dir(file) != dirSrc {
+			return nil
+		}
+		b, err := ioutil.ReadFile(file)
+		if err != nil || bytes.Contains(b, []byte("\n// +build ignore")) {
+			return err
+		}
+		// Fix paths.
+		b = bytes.Replace(b, []byte(search), []byte(replace), -1)
+		// Remove go:generate lines.
+		b = goGenRE.ReplaceAllLiteral(b, nil)
+		comment := "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n"
+		if *doCore {
+			comment = "// Code generated by running \"go run gen.go -core\" in golang.org/x/text. DO NOT EDIT.\n\n"
+		}
+		if !bytes.HasPrefix(b, []byte(comment)) {
+			b = append([]byte(comment), b...)
+		}
+		if b, err = format.Source(b); err != nil {
+			fmt.Println("Failed to format file:", err)
+			os.Exit(1)
+		}
+		file = filepath.Join(dirDst, base)
+		vprintf("=== COPY %s\n", file)
+		return ioutil.WriteFile(file, b, 0666)
+	})
+	if err != nil {
+		fmt.Println("Copying exported files failed:", err)
+		os.Exit(1)
+	}
+}
+
+func contains(a []string, s string) bool {
+	for _, e := range a {
+		if s == e {
+			return true
+		}
+	}
+	return false
+}
+
+func indent(b *bytes.Buffer) string {
+	return strings.Replace(strings.TrimSpace(b.String()), "\n", "\n\t", -1)
+}

+ 52 - 0
vendor/golang.org/x/text/internal/gen.go

@@ -0,0 +1,52 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package main
+
+import (
+	"log"
+
+	"golang.org/x/text/internal/gen"
+	"golang.org/x/text/language"
+	"golang.org/x/text/unicode/cldr"
+)
+
+func main() {
+	r := gen.OpenCLDRCoreZip()
+	defer r.Close()
+
+	d := &cldr.Decoder{}
+	data, err := d.DecodeZip(r)
+	if err != nil {
+		log.Fatalf("DecodeZip: %v", err)
+	}
+
+	w := gen.NewCodeWriter()
+	defer w.WriteGoFile("tables.go", "internal")
+
+	// Create parents table.
+	parents := make([]uint16, language.NumCompactTags)
+	for _, loc := range data.Locales() {
+		tag := language.MustParse(loc)
+		index, ok := language.CompactIndex(tag)
+		if !ok {
+			continue
+		}
+		parentIndex := 0 // und
+		for p := tag.Parent(); p != language.Und; p = p.Parent() {
+			if x, ok := language.CompactIndex(p); ok {
+				parentIndex = x
+				break
+			}
+		}
+		parents[index] = uint16(parentIndex)
+	}
+
+	w.WriteComment(`
+	Parent maps a compact index of a tag to the compact index of the parent of
+	this tag.`)
+	w.WriteVar("Parent", parents)
+}

+ 51 - 0
vendor/golang.org/x/text/internal/internal.go

@@ -0,0 +1,51 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go
+
+// Package internal contains non-exported functionality that are used by
+// packages in the text repository.
+package internal // import "golang.org/x/text/internal"
+
+import (
+	"sort"
+
+	"golang.org/x/text/language"
+)
+
+// SortTags sorts tags in place.
+func SortTags(tags []language.Tag) {
+	sort.Sort(sorter(tags))
+}
+
+type sorter []language.Tag
+
+func (s sorter) Len() int {
+	return len(s)
+}
+
+func (s sorter) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+
+func (s sorter) Less(i, j int) bool {
+	return s[i].String() < s[j].String()
+}
+
+// UniqueTags sorts and filters duplicate tags in place and returns a slice with
+// only unique tags.
+func UniqueTags(tags []language.Tag) []language.Tag {
+	if len(tags) <= 1 {
+		return tags
+	}
+	SortTags(tags)
+	k := 0
+	for i := 1; i < len(tags); i++ {
+		if tags[k].String() < tags[i].String() {
+			k++
+			tags[k] = tags[i]
+		}
+	}
+	return tags[:k+1]
+}

+ 67 - 0
vendor/golang.org/x/text/internal/match.go

@@ -0,0 +1,67 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal
+
+// This file contains matchers that implement CLDR inheritance.
+//
+//     See http://unicode.org/reports/tr35/#Locale_Inheritance.
+//
+// Some of the inheritance described in this document is already handled by
+// the cldr package.
+
+import (
+	"golang.org/x/text/language"
+)
+
+// TODO: consider if (some of the) matching algorithm needs to be public after
+// getting some feel about what is generic and what is specific.
+
+// NewInheritanceMatcher returns a matcher that matches based on the inheritance
+// chain.
+//
+// The matcher uses canonicalization and the parent relationship to find a
+// match. The resulting match will always be either Und or a language with the
+// same language and script as the requested language. It will not match
+// languages for which there is understood to be mutual or one-directional
+// intelligibility.
+//
+// A Match will indicate an Exact match if the language matches after
+// canonicalization and High if the matched tag is a parent.
+func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher {
+	tags := &InheritanceMatcher{make(map[language.Tag]int)}
+	for i, tag := range t {
+		ct, err := language.All.Canonicalize(tag)
+		if err != nil {
+			ct = tag
+		}
+		tags.index[ct] = i
+	}
+	return tags
+}
+
+type InheritanceMatcher struct {
+	index map[language.Tag]int
+}
+
+func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) {
+	for _, t := range want {
+		ct, err := language.All.Canonicalize(t)
+		if err != nil {
+			ct = t
+		}
+		conf := language.Exact
+		for {
+			if index, ok := m.index[ct]; ok {
+				return ct, index, conf
+			}
+			if ct == language.Und {
+				break
+			}
+			ct = ct.Parent()
+			conf = language.High
+		}
+	}
+	return language.Und, 0, language.No
+}

+ 117 - 0
vendor/golang.org/x/text/internal/tables.go

@@ -0,0 +1,117 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package internal
+
+// Parent maps a compact index of a tag to the compact index of the parent of
+// this tag.
+var Parent = []uint16{ // 754 elements
+	// Entry 0 - 3F
+	0x0000, 0x0053, 0x00e5, 0x0000, 0x0003, 0x0003, 0x0000, 0x0006,
+	0x0000, 0x0008, 0x0000, 0x000a, 0x0000, 0x000c, 0x000c, 0x000c,
+	0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
+	0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
+	0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
+	0x000c, 0x0000, 0x0000, 0x002a, 0x0000, 0x002c, 0x0000, 0x002e,
+	0x0000, 0x0000, 0x0031, 0x0030, 0x0030, 0x0000, 0x0035, 0x0000,
+	0x0037, 0x0000, 0x0039, 0x0000, 0x003b, 0x0000, 0x003d, 0x0000,
+	// Entry 40 - 7F
+	0x0000, 0x0040, 0x0000, 0x0042, 0x0042, 0x0000, 0x0045, 0x0045,
+	0x0000, 0x0048, 0x0000, 0x004a, 0x0000, 0x0000, 0x004d, 0x004c,
+	0x004c, 0x0000, 0x0051, 0x0051, 0x0051, 0x0051, 0x0000, 0x0056,
+	0x0000, 0x0058, 0x0000, 0x005a, 0x0000, 0x005c, 0x005c, 0x0000,
+	0x005f, 0x0000, 0x0061, 0x0000, 0x0063, 0x0000, 0x0065, 0x0065,
+	0x0000, 0x0068, 0x0000, 0x006a, 0x006a, 0x006a, 0x006a, 0x006a,
+	0x006a, 0x006a, 0x0000, 0x0072, 0x0000, 0x0074, 0x0000, 0x0076,
+	0x0000, 0x0000, 0x0079, 0x0000, 0x007b, 0x0000, 0x007d, 0x0000,
+	// Entry 80 - BF
+	0x007f, 0x007f, 0x0000, 0x0082, 0x0082, 0x0000, 0x0085, 0x0086,
+	0x0086, 0x0086, 0x0085, 0x0087, 0x0086, 0x0086, 0x0086, 0x0085,
+	0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087, 0x0086,
+	0x0086, 0x0086, 0x0086, 0x0087, 0x0086, 0x0087, 0x0086, 0x0086,
+	0x0087, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
+	0x0086, 0x0086, 0x0085, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
+	0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
+	0x0086, 0x0086, 0x0086, 0x0086, 0x0085, 0x0086, 0x0085, 0x0086,
+	// Entry C0 - FF
+	0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087,
+	0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0085,
+	0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087, 0x0086, 0x0086,
+	0x0087, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
+	0x0086, 0x0086, 0x0086, 0x0086, 0x0085, 0x0085, 0x0086, 0x0086,
+	0x0085, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0000, 0x00ee,
+	0x0000, 0x00f0, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1,
+	0x00f1, 0x00f1, 0x00f1, 0x00f0, 0x00f1, 0x00f0, 0x00f0, 0x00f1,
+	// Entry 100 - 13F
+	0x00f1, 0x00f0, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f0, 0x00f1,
+	0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x0000, 0x010d, 0x0000,
+	0x010f, 0x0000, 0x0111, 0x0000, 0x0113, 0x0113, 0x0000, 0x0116,
+	0x0116, 0x0116, 0x0116, 0x0000, 0x011b, 0x0000, 0x011d, 0x0000,
+	0x011f, 0x011f, 0x0000, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
+	0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
+	0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
+	0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
+	// Entry 140 - 17F
+	0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
+	0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
+	0x0122, 0x0000, 0x0151, 0x0000, 0x0153, 0x0000, 0x0155, 0x0000,
+	0x0157, 0x0000, 0x0159, 0x0000, 0x015b, 0x015b, 0x015b, 0x0000,
+	0x015f, 0x0000, 0x0000, 0x0162, 0x0000, 0x0164, 0x0000, 0x0166,
+	0x0166, 0x0166, 0x0000, 0x016a, 0x0000, 0x016c, 0x0000, 0x016e,
+	0x0000, 0x0170, 0x0170, 0x0000, 0x0173, 0x0000, 0x0175, 0x0000,
+	0x0177, 0x0000, 0x0179, 0x0000, 0x017b, 0x0000, 0x017d, 0x0000,
+	// Entry 180 - 1BF
+	0x017f, 0x0000, 0x0181, 0x0181, 0x0181, 0x0181, 0x0000, 0x0000,
+	0x0187, 0x0000, 0x0000, 0x018a, 0x0000, 0x018c, 0x0000, 0x0000,
+	0x018f, 0x0000, 0x0191, 0x0000, 0x0000, 0x0194, 0x0000, 0x0000,
+	0x0197, 0x0000, 0x0199, 0x0000, 0x019b, 0x0000, 0x019d, 0x0000,
+	0x019f, 0x0000, 0x01a1, 0x0000, 0x01a3, 0x0000, 0x01a5, 0x0000,
+	0x01a7, 0x0000, 0x01a9, 0x0000, 0x01ab, 0x01ab, 0x0000, 0x01ae,
+	0x0000, 0x01b0, 0x0000, 0x01b2, 0x0000, 0x01b4, 0x0000, 0x01b6,
+	0x0000, 0x0000, 0x01b9, 0x0000, 0x01bb, 0x0000, 0x01bd, 0x0000,
+	// Entry 1C0 - 1FF
+	0x01bf, 0x0000, 0x01c1, 0x0000, 0x01c3, 0x0000, 0x01c5, 0x01c5,
+	0x01c5, 0x01c5, 0x0000, 0x01ca, 0x0000, 0x01cc, 0x01cc, 0x0000,
+	0x01cf, 0x0000, 0x01d1, 0x0000, 0x01d3, 0x0000, 0x01d5, 0x0000,
+	0x01d7, 0x0000, 0x01d9, 0x01d9, 0x0000, 0x01dc, 0x0000, 0x01de,
+	0x0000, 0x01e0, 0x0000, 0x01e2, 0x0000, 0x01e4, 0x0000, 0x01e6,
+	0x0000, 0x01e8, 0x0000, 0x01ea, 0x0000, 0x01ec, 0x0000, 0x01ee,
+	0x01ee, 0x01ee, 0x0000, 0x01f2, 0x0000, 0x01f4, 0x0000, 0x01f6,
+	0x0000, 0x01f8, 0x0000, 0x0000, 0x01fb, 0x0000, 0x01fd, 0x01fd,
+	// Entry 200 - 23F
+	0x0000, 0x0200, 0x0000, 0x0202, 0x0202, 0x0000, 0x0205, 0x0205,
+	0x0000, 0x0208, 0x0208, 0x0208, 0x0208, 0x0208, 0x0208, 0x0208,
+	0x0000, 0x0210, 0x0000, 0x0212, 0x0000, 0x0214, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x021a, 0x0000, 0x0000, 0x021d, 0x0000,
+	0x021f, 0x021f, 0x0000, 0x0222, 0x0000, 0x0224, 0x0224, 0x0000,
+	0x0000, 0x0228, 0x0227, 0x0227, 0x0000, 0x0000, 0x022d, 0x0000,
+	0x022f, 0x0000, 0x0231, 0x0000, 0x023d, 0x0233, 0x023d, 0x023d,
+	0x023d, 0x023d, 0x023d, 0x023d, 0x023d, 0x0233, 0x023d, 0x023d,
+	// Entry 240 - 27F
+	0x0000, 0x0240, 0x0240, 0x0240, 0x0000, 0x0244, 0x0000, 0x0246,
+	0x0000, 0x0248, 0x0248, 0x0000, 0x024b, 0x0000, 0x024d, 0x024d,
+	0x024d, 0x024d, 0x024d, 0x024d, 0x0000, 0x0254, 0x0000, 0x0256,
+	0x0000, 0x0258, 0x0000, 0x025a, 0x0000, 0x025c, 0x0000, 0x0000,
+	0x025f, 0x025f, 0x025f, 0x0000, 0x0263, 0x0000, 0x0265, 0x0000,
+	0x0267, 0x0000, 0x0000, 0x026a, 0x0269, 0x0269, 0x0000, 0x026e,
+	0x0000, 0x0270, 0x0000, 0x0272, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0277, 0x0000, 0x0000, 0x027a, 0x0000, 0x027c, 0x027c, 0x027c,
+	// Entry 280 - 2BF
+	0x027c, 0x0000, 0x0281, 0x0281, 0x0281, 0x0000, 0x0285, 0x0285,
+	0x0285, 0x0285, 0x0285, 0x0000, 0x028b, 0x028b, 0x028b, 0x028b,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0293, 0x0293, 0x0293, 0x0000,
+	0x0297, 0x0297, 0x0297, 0x0297, 0x0000, 0x0000, 0x029d, 0x029d,
+	0x029d, 0x029d, 0x0000, 0x02a2, 0x0000, 0x02a4, 0x02a4, 0x0000,
+	0x02a7, 0x0000, 0x02a9, 0x02a9, 0x0000, 0x0000, 0x02ad, 0x0000,
+	0x0000, 0x02b0, 0x0000, 0x02b2, 0x02b2, 0x0000, 0x0000, 0x02b6,
+	0x0000, 0x02b8, 0x0000, 0x02ba, 0x0000, 0x02bc, 0x0000, 0x02be,
+	// Entry 2C0 - 2FF
+	0x02be, 0x0000, 0x0000, 0x02c2, 0x0000, 0x02c4, 0x02c1, 0x02c1,
+	0x0000, 0x0000, 0x02c9, 0x02c8, 0x02c8, 0x0000, 0x0000, 0x02ce,
+	0x0000, 0x02d0, 0x0000, 0x02d2, 0x0000, 0x0000, 0x02d5, 0x0000,
+	0x0000, 0x0000, 0x02d9, 0x0000, 0x02db, 0x0000, 0x02dd, 0x0000,
+	0x02df, 0x02df, 0x0000, 0x02e2, 0x0000, 0x02e4, 0x0000, 0x02e6,
+	0x02e6, 0x02e6, 0x02e6, 0x02e6, 0x0000, 0x02ec, 0x02ed, 0x02ec,
+	0x0000, 0x02f0,
+} // Size: 1532 bytes
+
+// Total table size 1532 bytes (1KiB); checksum: 90718A2

+ 6 - 0
vendor/golang.org/x/text/secure/doc.go

@@ -0,0 +1,6 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// secure is a repository of text security related packages.
+package secure // import "golang.org/x/text/secure"

+ 8 - 0
vendor/golang.org/x/text/unicode/doc.go

@@ -0,0 +1,8 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// unicode holds packages with implementations of Unicode standards that are
+// mostly used as building blocks for other packages in golang.org/x/text,
+// layout engines, or are otherwise more low-level in nature.
+package unicode

+ 123 - 0
vendor/google.golang.org/genproto/regen.go

@@ -0,0 +1,123 @@
+// Copyright 2016 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build ignore
+
+// Regen.go regenerates the genproto repository.
+//
+// Regen.go recursively walks through each directory named by given arguments,
+// looking for all .proto files. (Symlinks are not followed.)
+// If the pkg_prefix flag is not an empty string,
+// any proto file without `go_package` option
+// or whose option does not begin with the prefix is ignored.
+// Protoc is executed on remaining files,
+// one invocation per set of files declaring the same Go package.
+package main
+
+import (
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+var goPkgOptRe = regexp.MustCompile(`(?m)^option go_package = (.*);`)
+
+func usage() {
+	fmt.Fprintln(os.Stderr, `usage: go run regen.go -go_out=path/to/output [-pkg_prefix=pkg/prefix] roots...
+
+Most users will not need to run this file directly.
+To regenerate this repository, run regen.sh instead.`)
+	flag.PrintDefaults()
+}
+
+func main() {
+	goOutDir := flag.String("go_out", "", "go_out argument to pass to protoc-gen-go")
+	pkgPrefix := flag.String("pkg_prefix", "", "only include proto files with go_package starting with this prefix")
+	flag.Usage = usage
+	flag.Parse()
+
+	if *goOutDir == "" {
+		log.Fatal("need go_out flag")
+	}
+
+	pkgFiles := make(map[string][]string)
+	walkFn := func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
+		if !info.Mode().IsRegular() || !strings.HasSuffix(path, ".proto") {
+			return nil
+		}
+		pkg, err := goPkg(path)
+		if err != nil {
+			return err
+		}
+		pkgFiles[pkg] = append(pkgFiles[pkg], path)
+		return nil
+	}
+	for _, root := range flag.Args() {
+		if err := filepath.Walk(root, walkFn); err != nil {
+			log.Fatal(err)
+		}
+	}
+	for pkg, fnames := range pkgFiles {
+		if !strings.HasPrefix(pkg, *pkgPrefix) {
+			continue
+		}
+		if out, err := protoc(*goOutDir, flag.Args(), fnames); err != nil {
+			log.Fatalf("error executing protoc: %s\n%s", err, out)
+		}
+	}
+}
+
+// goPkg reports the import path declared in the given file's
+// `go_package` option. If the option is missing, goPkg returns empty string.
+func goPkg(fname string) (string, error) {
+	content, err := ioutil.ReadFile(fname)
+	if err != nil {
+		return "", err
+	}
+
+	var pkgName string
+	if match := goPkgOptRe.FindSubmatch(content); len(match) > 0 {
+		pn, err := strconv.Unquote(string(match[1]))
+		if err != nil {
+			return "", err
+		}
+		pkgName = pn
+	}
+	if p := strings.IndexRune(pkgName, ';'); p > 0 {
+		pkgName = pkgName[:p]
+	}
+	return pkgName, nil
+}
+
+// protoc executes the "protoc" command on files named in fnames,
+// passing go_out and include flags specified in goOut and includes respectively.
+// protoc returns combined output from stdout and stderr.
+func protoc(goOut string, includes, fnames []string) ([]byte, error) {
+	args := []string{"--go_out=plugins=grpc:" + goOut}
+	for _, inc := range includes {
+		args = append(args, "-I", inc)
+	}
+	args = append(args, fnames...)
+	return exec.Command("protoc", args...).CombinedOutput()
+}

+ 21 - 0
vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/doc.go

@@ -0,0 +1,21 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package grpc_lb_v1 is the parent package of all gRPC loadbalancer
+// message and service protobuf definitions.
+package grpc_lb_v1