mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-18 21:24:36 +08:00
feat: add syncthing for clone mode (#270)
* feat: add syncthing for clone mode --------- Co-authored-by: wencaiwulue <895703375@qq.com>
This commit is contained in:
5
Makefile
5
Makefile
@@ -21,7 +21,8 @@ IMAGE_TEST = docker.io/naison/kubevpn:test
|
||||
IMAGE_GH = ghcr.io/kubenetworks/kubevpn:$(VERSION)
|
||||
|
||||
# Setup the -ldflags option for go build here, interpolate the variable values
|
||||
LDFLAGS=--ldflags "\
|
||||
# add '-tag noassets' for syncthing gui
|
||||
LDFLAGS=-tags noassets --ldflags "-s -w\
|
||||
-X ${BASE}/pkg/config.Image=${IMAGE} \
|
||||
-X ${BASE}/pkg/config.Version=${VERSION} \
|
||||
-X ${BASE}/pkg/config.GitCommit=${GIT_COMMIT} \
|
||||
@@ -107,7 +108,7 @@ gen:
|
||||
|
||||
.PHONY: ut
|
||||
ut:
|
||||
go test -coverprofile=coverage.txt -coverpkg=./... -v ./... -timeout=60m
|
||||
go test -tags=noassets -coverprofile=coverage.txt -coverpkg=./... -v ./... -timeout=60m
|
||||
|
||||
.PHONY: cover
|
||||
cover: ut
|
||||
|
@@ -14,7 +14,7 @@ import (
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
yaml "sigs.k8s.io/yaml/goyaml.v3"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
@@ -106,7 +106,7 @@ func CmdAlias(f cmdutil.Factory) *cobra.Command {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(&localFile, "file", "f", daemon.GetConfigFilePath(), "Config file location")
|
||||
cmd.Flags().StringVarP(&localFile, "file", "f", config.GetConfigFilePath(), "Config file location")
|
||||
cmd.Flags().StringVarP(&remoteAddr, "remote", "r", "", "Remote config file, eg: https://raw.githubusercontent.com/kubenetworks/kubevpn/master/pkg/config/config.yaml")
|
||||
return cmd
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func ParseAndGet(localFile, remoteAddr string, aliasName string) ([]Config, erro
|
||||
path = remoteAddr
|
||||
content, err = util.DownloadFileStream(path)
|
||||
} else {
|
||||
path = daemon.GetConfigFilePath()
|
||||
path = config.GetConfigFilePath()
|
||||
content, err = os.ReadFile(path)
|
||||
}
|
||||
if err != nil {
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
pkgerr "github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -28,6 +29,7 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
|
||||
var sshConf = &util.SshConfig{}
|
||||
var extraRoute = &handler.ExtraRouteInfo{}
|
||||
var transferImage bool
|
||||
var syncDir string
|
||||
cmd := &cobra.Command{
|
||||
Use: "clone",
|
||||
Short: i18n.T("Clone workloads to target-kubeconfig cluster with same volume、env、and network"),
|
||||
@@ -91,6 +93,17 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
|
||||
// special empty string, eg: --target-registry ""
|
||||
options.IsChangeTargetRegistry = cmd.Flags().Changed("target-registry")
|
||||
|
||||
if syncDir != "" {
|
||||
local, remote, err := util.ParseDirMapping(syncDir)
|
||||
if err != nil {
|
||||
return pkgerr.Wrapf(err, "options 'sync' is invalid, %s", syncDir)
|
||||
}
|
||||
options.LocalDir = local
|
||||
options.RemoteDir = remote
|
||||
} else {
|
||||
options.RemoteDir = config.DefaultRemoteDir
|
||||
}
|
||||
|
||||
bytes, ns, err := util.ConvertToKubeConfigBytes(f)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -117,6 +130,8 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
|
||||
TransferImage: transferImage,
|
||||
Image: config.Image,
|
||||
Level: int32(logLevel),
|
||||
LocalDir: options.LocalDir,
|
||||
RemoteDir: options.RemoteDir,
|
||||
}
|
||||
cli := daemon.GetClient(false)
|
||||
resp, err := cli.Clone(cmd.Context(), req)
|
||||
@@ -149,6 +164,7 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
|
||||
cmd.Flags().StringVar(&options.TargetNamespace, "target-namespace", "", "Clone workloads in this namespace, if not special, use origin namespace")
|
||||
cmd.Flags().StringVar(&options.TargetKubeconfig, "target-kubeconfig", "", "Clone workloads will create in this cluster, if not special, use origin cluster")
|
||||
cmd.Flags().StringVar(&options.TargetRegistry, "target-registry", "", "Clone workloads will create this registry domain to replace origin registry, if not special, use origin registry")
|
||||
cmd.Flags().StringVar(&syncDir, "sync", "", "Sync local dir to remote pod dir. format: LOCAL_DIR:REMOTE_DIR, eg: ~/code:/app/code")
|
||||
|
||||
handler.AddExtraRoute(cmd.Flags(), extraRoute)
|
||||
util.AddSshFlags(cmd.Flags(), sshConf)
|
||||
|
@@ -64,6 +64,7 @@ func NewKubeVPNCommand() *cobra.Command {
|
||||
CmdServe(factory),
|
||||
CmdDaemon(factory),
|
||||
CmdWebhook(factory),
|
||||
CmdSyncthing(factory),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@@ -17,6 +17,7 @@ import (
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
|
||||
@@ -94,7 +95,7 @@ func CmdStatus(f cmdutil.Factory) *cobra.Command {
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&aliasName, "alias", "", "Alias name, query connect status by alias config name")
|
||||
cmd.Flags().StringVarP(&localFile, "file", "f", daemon.GetConfigFilePath(), "Config file location")
|
||||
cmd.Flags().StringVarP(&localFile, "file", "f", config.GetConfigFilePath(), "Config file location")
|
||||
cmd.Flags().StringVarP(&remoteAddr, "remote", "r", "", "Remote config file, eg: https://raw.githubusercontent.com/kubenetworks/kubevpn/master/pkg/config/config.yaml")
|
||||
cmd.Flags().StringVarP(&format, "output", "o", FormatTable, fmt.Sprintf("Output format. One of: (%s, %s, %s)", FormatJson, FormatYaml, FormatTable))
|
||||
return cmd
|
||||
@@ -195,7 +196,7 @@ func genCloneMsg(w *tabwriter.Writer, list []*rpc.Status) {
|
||||
|
||||
_, _ = fmt.Fprintf(w, "\n")
|
||||
w.SetRememberedWidths(nil)
|
||||
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", "ID", "Name", "Headers", "ToName", "ToKubeconfig", "ToNamespace")
|
||||
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "ID", "Name", "Headers", "ToName", "ToKubeconfig", "ToNamespace", "SyncthingGUI")
|
||||
for _, c := range list {
|
||||
for _, clone := range c.CloneList {
|
||||
//_, _ = fmt.Fprintf(w, "%s\n", clone.Workload)
|
||||
@@ -207,13 +208,14 @@ func genCloneMsg(w *tabwriter.Writer, list []*rpc.Status) {
|
||||
if len(headers) == 0 {
|
||||
headers = []string{"*"}
|
||||
}
|
||||
_, _ = fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%s\n",
|
||||
_, _ = fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%s\t%s\n",
|
||||
c.ID,
|
||||
clone.Workload,
|
||||
strings.Join(headers, ","),
|
||||
rule.DstWorkload,
|
||||
rule.DstKubeconfig,
|
||||
rule.DstNamespace,
|
||||
clone.SyncthingGUIAddr,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
30
cmd/kubevpn/cmds/syncthing.go
Normal file
30
cmd/kubevpn/cmds/syncthing.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/syncthing"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
func CmdSyncthing(_ cmdutil.Factory) *cobra.Command {
|
||||
var detach bool
|
||||
var dir string
|
||||
cmd := &cobra.Command{
|
||||
Use: "syncthing",
|
||||
Short: i18n.T("Syncthing"),
|
||||
Long: templates.LongDesc(i18n.T(`Syncthing`)),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
go util.StartupPProf(0)
|
||||
return syncthing.StartServer(cmd.Context(), detach, dir)
|
||||
},
|
||||
Hidden: true,
|
||||
DisableFlagsInUseLine: true,
|
||||
}
|
||||
cmd.Flags().StringVar(&dir, "dir", "", "dir")
|
||||
cmd.Flags().BoolVarP(&detach, "detach", "d", false, "Run syncthing in background")
|
||||
return cmd
|
||||
}
|
@@ -3,14 +3,14 @@ package cmds
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
|
||||
|
64
go.mod
64
go.mod
@@ -19,9 +19,11 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/hpcloud/tail v1.0.0
|
||||
github.com/jcmturner/gofork v1.7.6
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4
|
||||
github.com/kevinburke/ssh_config v1.2.0
|
||||
github.com/libp2p/go-netroute v0.2.1
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
|
||||
github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38
|
||||
github.com/miekg/dns v1.1.58
|
||||
github.com/moby/sys/signal v0.7.0
|
||||
@@ -33,14 +35,16 @@ require (
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/syncthing/syncthing v1.27.7
|
||||
github.com/thejerf/suture/v4 v4.0.5
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0
|
||||
golang.org/x/net v0.25.0
|
||||
golang.org/x/oauth2 v0.18.0
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/sys v0.19.0
|
||||
golang.org/x/text v0.14.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/sys v0.20.0
|
||||
golang.org/x/text v0.15.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c
|
||||
@@ -53,6 +57,7 @@ require (
|
||||
k8s.io/apimachinery v0.31.0-alpha.0
|
||||
k8s.io/cli-runtime v0.29.3
|
||||
k8s.io/client-go v0.31.0-alpha.0
|
||||
k8s.io/klog/v2 v2.120.1
|
||||
k8s.io/kubectl v0.29.3
|
||||
k8s.io/utils v0.0.0-20240310230437-4693a0247e57
|
||||
sigs.k8s.io/controller-runtime v0.17.1-0.20240327193027-21368602d84b
|
||||
@@ -77,6 +82,7 @@ require (
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||
github.com/DataDog/appsec-internal-go v1.5.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.52.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.52.0 // indirect
|
||||
@@ -92,9 +98,13 @@ require (
|
||||
github.com/apparentlymart/go-cidr v1.1.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.51.12 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/calmh/incontainer v1.0.0 // indirect
|
||||
github.com/calmh/xdr v1.1.0 // indirect
|
||||
github.com/ccding/go-stun v0.1.4 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
github.com/chmduquesne/rollinghash v4.0.0+incompatible // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20240329184929-0c46c01016dc // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
@@ -119,50 +129,62 @@ require (
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
|
||||
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
|
||||
github.com/go-errors/errors v1.5.1 // indirect
|
||||
github.com/go-ldap/ldap/v3 v3.4.6 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240327155427-868f304927ed // indirect
|
||||
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/greatroar/blobloom v0.7.2 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc // indirect
|
||||
github.com/jackpal/gateway v1.0.14 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 // indirect
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
@@ -190,20 +212,31 @@ require (
|
||||
github.com/outcaste-io/ristretto v0.2.3 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/prometheus/client_golang v1.19.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.0 // indirect
|
||||
github.com/prometheus/common v0.51.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.52.2 // indirect
|
||||
github.com/prometheus/procfs v0.13.0 // indirect
|
||||
github.com/quic-go/quic-go v0.42.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
|
||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||
github.com/tinylib/msgp v1.1.9 // indirect
|
||||
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.13 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.13 // indirect
|
||||
@@ -218,9 +251,9 @@ require (
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/term v0.20.0 // indirect
|
||||
golang.org/x/tools v0.21.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/api v0.172.0 // indirect
|
||||
@@ -236,7 +269,6 @@ require (
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.31.0-alpha.0 // indirect
|
||||
k8s.io/component-base v0.31.0-alpha.0 // indirect
|
||||
k8s.io/klog/v2 v2.120.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.16.0 // indirect
|
||||
|
158
go.sum
158
go.sum
@@ -38,6 +38,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
@@ -70,6 +72,9 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d h1:hi6J4K6D
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/antonmedv/expr v1.15.5 h1:y0Iz3cEwmpRz5/r3w4qQR0MfIqJGdGM1zbhD/v0G5Vg=
|
||||
github.com/antonmedv/expr v1.15.5/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE=
|
||||
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
|
||||
@@ -92,6 +97,12 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/calmh/incontainer v1.0.0 h1:g2cTUtZuFGmMGX8GoykPkN1Judj2uw8/3/aEtq4Z/rg=
|
||||
github.com/calmh/incontainer v1.0.0/go.mod h1:eOhqnw15c9X+4RNBe0W3HlUZFfX16O0EDsCOInTndHY=
|
||||
github.com/calmh/xdr v1.1.0 h1:U/Dd4CXNLoo8EiQ4ulJUXkgO1/EyQLgDKLgpY1SOoJE=
|
||||
github.com/calmh/xdr v1.1.0/go.mod h1:E8sz2ByAdXC8MbANf1LCRYzedSnnc+/sXXJs/PVqoeg=
|
||||
github.com/ccding/go-stun v0.1.4 h1:lC0co3Q3vjAuu2Jz098WivVPBPbemYFqbwE1syoka4M=
|
||||
github.com/ccding/go-stun v0.1.4/go.mod h1:cCZjJ1J3WFSJV6Wj8Y9Di8JMTsEXh6uv2eNmLzKaUeM=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
@@ -99,10 +110,12 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
|
||||
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
||||
github.com/chmduquesne/rollinghash v4.0.0+incompatible h1:hnREQO+DXjqIw3rUTzWN7/+Dpw+N5Um8zpKV0JOEgbo=
|
||||
github.com/chmduquesne/rollinghash v4.0.0+incompatible/go.mod h1:Uc2I36RRfTAf7Dge82bi3RU0OQUmXT9iweIcPqvr8A0=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
@@ -132,6 +145,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
|
||||
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
@@ -201,13 +216,18 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
|
||||
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
|
||||
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A=
|
||||
github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@@ -217,6 +237,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
@@ -230,6 +253,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@@ -262,6 +287,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI=
|
||||
@@ -275,6 +302,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
@@ -284,14 +312,15 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20240327155427-868f304927ed h1:n8QtJTrwsv3P7dNxPaMeNkMcxvUpqocsHLr8iDLGlQI=
|
||||
github.com/google/pprof v0.0.0-20240327155427-868f304927ed/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f h1:f00RU+zOX+B3rLAmMMkzHUF2h1z4DeYR9tTCvEq2REY=
|
||||
github.com/google/pprof v0.0.0-20240402174815-29b9bb013b0f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||
@@ -308,6 +337,8 @@ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/greatroar/blobloom v0.7.2 h1:F30MGLHOcb4zr0pwCPTcKdlTM70rEgkf+LzdUPc5ss8=
|
||||
github.com/greatroar/blobloom v0.7.2/go.mod h1:mjMJ1hh1wjGVfr93QIHJ6FfDNVrA0IELv8OvMHJxHKs=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
@@ -327,6 +358,8 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
@@ -337,6 +370,10 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc h1:RhT2pjLo3EVRmldbEcBdeRA7CGPWsNEJC+Y/N1aXQbg=
|
||||
github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc/go.mod h1:BaIJzjD2ZnHmx2acPF6XfGLPzNCMiBbMRqJr+8/8uRI=
|
||||
github.com/jackpal/gateway v1.0.14 h1:6ZfIuFvnvWrS59hHbvZGR/R33ojV2LASBODomt7zlJU=
|
||||
github.com/jackpal/gateway v1.0.14/go.mod h1:6c8LjW+FVESFmwxaXySkt7fU98Yv806ADS3OY6Cvh2U=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
@@ -368,13 +405,19 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
@@ -390,6 +433,7 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t
|
||||
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.5.3 h1:C8fxWnhYyME3n0klPOhVM7PtYUB3eV1W3DeFmN3j53Y=
|
||||
github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
@@ -409,6 +453,10 @@ github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPk
|
||||
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 h1:cUVxyR+UfmdEAZGJ8IiKld1O0dbGotEnkMolG5hfMSY=
|
||||
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75/go.mod h1:pBbZyGwC5i16IBkjVKoy/sznA8jPD/K9iedwe1ESE6w=
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
@@ -453,10 +501,14 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
|
||||
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
@@ -464,6 +516,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
|
||||
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@@ -491,6 +544,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
||||
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -498,6 +553,9 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4=
|
||||
@@ -512,13 +570,13 @@ github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
|
||||
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw=
|
||||
github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q=
|
||||
github.com/prometheus/common v0.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck=
|
||||
github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
@@ -527,6 +585,8 @@ github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGK
|
||||
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
|
||||
github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=
|
||||
github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 h1:Qp27Idfgi6ACvFQat5+VJvlYToylpM/hcyLBI3WaKPA=
|
||||
github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052/go.mod h1:uvX/8buq8uVeiZiFht+0lqSLBHF+uGV8BrTv8W/SIwk=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
@@ -542,6 +602,10 @@ github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbm
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
@@ -567,8 +631,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
|
||||
github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@@ -576,15 +640,29 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 h1:F4snRP//nIuTTW9LYEzVH4HVwDG9T3M4t8y/2nqMbiY=
|
||||
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2/go.mod h1:J0q59IWjLtpRIJulohwqEZvjzwOfTEPp8SVhDJl+y0Y=
|
||||
github.com/syncthing/syncthing v1.27.7 h1:N06QpAUPQi2VaB+X0wko5h8JtH3qJP5Dd4MYq952pEw=
|
||||
github.com/syncthing/syncthing v1.27.7/go.mod h1:bMhGhc70k3UFszFhmCVNxM5bOsDfhxYMHvj4lWlIYBk=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=
|
||||
github.com/thejerf/suture/v4 v4.0.5 h1:F1E/4FZwXWqvlWDKEUo6/ndLtxGAUzMmNqkrMknZbAA=
|
||||
github.com/thejerf/suture/v4 v4.0.5/go.mod h1:gu9Y4dXNUWFrByqRt30Rm9/UZ0wzRSt9AJS6xu/ZGxU=
|
||||
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
|
||||
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
|
||||
github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU=
|
||||
github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0 h1:okhMind4q9H1OxF44gNegWkiP4H/gsTFLalHFa4OOUI=
|
||||
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0/go.mod h1:TTbGUfE+cXXceWtbTHq6lqcTvYPBKLNejBEbnUsQJtU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@@ -598,6 +676,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.etcd.io/etcd/api/v3 v3.5.13 h1:8WXU2/NBge6AUF1K1gOexB6e07NgsN1hXK0rSTtgSp4=
|
||||
go.etcd.io/etcd/api/v3 v3.5.13/go.mod h1:gBqlqkcMMZMVTMm4NDZloEVJzxQOQIls8splbqBDa0c=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.13 h1:RVZSAnWWWiI5IrYAXjQorajncORbS0zI48LQlE2kQWg=
|
||||
@@ -648,11 +728,12 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8=
|
||||
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
@@ -662,8 +743,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -683,11 +765,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
@@ -699,16 +784,19 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -717,6 +805,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -725,30 +814,41 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -764,12 +864,14 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
||||
|
@@ -31,8 +31,10 @@ const (
|
||||
ContainerSidecarEnvoyProxy = "envoy-proxy"
|
||||
ContainerSidecarControlPlane = "control-plane"
|
||||
ContainerSidecarVPN = "vpn"
|
||||
ContainerSidecarSyncthing = "syncthing"
|
||||
|
||||
VolumeEnvoyConfig = "envoy-config"
|
||||
VolumeSyncthing = "syncthing"
|
||||
|
||||
innerIPv4Pool = "223.254.0.100/16"
|
||||
// 原因:在docker环境中,设置docker的 gateway 和 subnet,不能 inner 的冲突,也不能和 docker的 172.17 冲突
|
||||
|
@@ -55,3 +55,31 @@ func init() {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func GetSockPath(isSudo bool) string {
|
||||
name := SockPath
|
||||
if isSudo {
|
||||
name = SudoSockPath
|
||||
}
|
||||
return filepath.Join(DaemonPath, name)
|
||||
}
|
||||
|
||||
func GetPidPath(isSudo bool) string {
|
||||
name := PidPath
|
||||
if isSudo {
|
||||
name = SudoPidPath
|
||||
}
|
||||
return filepath.Join(DaemonPath, name)
|
||||
}
|
||||
|
||||
func GetSyncthingPath() string {
|
||||
return filepath.Join(DaemonPath, SyncthingDir)
|
||||
}
|
||||
|
||||
func GetSyncthingGUIPath() string {
|
||||
return filepath.Join(DaemonPath, SyncthingDir, SyncthingGUIDir)
|
||||
}
|
||||
|
||||
func GetConfigFilePath() string {
|
||||
return filepath.Join(HomePath, ConfigFile)
|
||||
}
|
||||
|
92
pkg/config/syncthing.go
Normal file
92
pkg/config/syncthing.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
|
||||
const (
|
||||
SyncthingDir = "syncthing"
|
||||
|
||||
SyncthingGUIDir = "gui"
|
||||
|
||||
DefaultRemoteDir = "/kubevpn-data"
|
||||
)
|
||||
|
||||
var LocalCert tls.Certificate
|
||||
var RemoteCert tls.Certificate
|
||||
var LocalDeviceID protocol.DeviceID
|
||||
var RemoteDeviceID protocol.DeviceID
|
||||
|
||||
const (
|
||||
SyncthingLocalDeviceID = "BSNCBRY-ZI5HLYC-YH6544V-SQ3IDKT-4JQKING-ZGSW463-UKYEYCA-WO7ZHA3"
|
||||
SyncthingLocalCert = `-----BEGIN CERTIFICATE-----
|
||||
MIICHjCCAaSgAwIBAgIIHY0CWDFbXYEwCgYIKoZIzj0EAwIwSjESMBAGA1UEChMJ
|
||||
U3luY3RoaW5nMSAwHgYDVQQLExdBdXRvbWF0aWNhbGx5IEdlbmVyYXRlZDESMBAG
|
||||
A1UEAxMJc3luY3RoaW5nMCAXDTI0MDYxOTAwMDAwMFoYDzE4NTQwOTExMDA1MDUy
|
||||
WjBKMRIwEAYDVQQKEwlTeW5jdGhpbmcxIDAeBgNVBAsTF0F1dG9tYXRpY2FsbHkg
|
||||
R2VuZXJhdGVkMRIwEAYDVQQDEwlzeW5jdGhpbmcwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAAQj1ov1aM0902yssK+3LPiGM1e1pUcVRuQjxl0nDX0fpZp3kdeWeiBm9AlE
|
||||
uwhAll/8QjoWBlNiEXyGFN9lOaIGf7ZIk7owPT6LiJXc1n3E6iqHWeSXcZ9dJL7M
|
||||
+E4eleajVTBTMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
|
||||
KwYBBQUHAwIwDAYDVR0TAQH/BAIwADAUBgNVHREEDTALgglzeW5jdGhpbmcwCgYI
|
||||
KoZIzj0EAwIDaAAwZQIwJI4KA9JgFXWU4dWq6JnIr+lAuIJ5ON2lFPrX8JWi1Z3F
|
||||
UXrvm80w+uR+1rLt6AdkAjEA3dpoBnS7tV21krEVmfX2vabtkzZidhXwuvP+1VJN
|
||||
By4EwZnuTLX3TqQx2TERF9rV
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
SyncthingLocalKey = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDAltfhZ8YO4CrPsvFRpU6P8lOspm5VXFGvJghSaDr4D/ub66+4HpTk9
|
||||
3TdgtbUSMSmgBwYFK4EEACKhZANiAAQj1ov1aM0902yssK+3LPiGM1e1pUcVRuQj
|
||||
xl0nDX0fpZp3kdeWeiBm9AlEuwhAll/8QjoWBlNiEXyGFN9lOaIGf7ZIk7owPT6L
|
||||
iJXc1n3E6iqHWeSXcZ9dJL7M+E4eleY=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
)
|
||||
|
||||
const (
|
||||
SyncthingRemoteDeviceID = "OELB2JL-MIOW652-6JPBYPZ-POV3EBV-XEOW2Z2-I45QUGZ-QF5TT4P-Z2AH7AU"
|
||||
SyncthingRemoteCert = `-----BEGIN CERTIFICATE-----
|
||||
MIICHzCCAaWgAwIBAgIJAOGCLdtwnUShMAoGCCqGSM49BAMCMEoxEjAQBgNVBAoT
|
||||
CVN5bmN0aGluZzEgMB4GA1UECxMXQXV0b21hdGljYWxseSBHZW5lcmF0ZWQxEjAQ
|
||||
BgNVBAMTCXN5bmN0aGluZzAgFw0yNDA2MTkwMDAwMDBaGA8xODU0MDkxMTAwNTA1
|
||||
MlowSjESMBAGA1UEChMJU3luY3RoaW5nMSAwHgYDVQQLExdBdXRvbWF0aWNhbGx5
|
||||
IEdlbmVyYXRlZDESMBAGA1UEAxMJc3luY3RoaW5nMHYwEAYHKoZIzj0CAQYFK4EE
|
||||
ACIDYgAETwaM3V92D499uMXWFgGxdTUAvtp1tN7ePuJxt8W+FO0izG1fa7oU29Hp
|
||||
FU0Ohh3xwnQfEHIWzlKJllZ2ZbbXGOvcfr0Yfiir6ToKuN6185EA8RHkA+5HRtu5
|
||||
nw5wyWL/o1UwUzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
|
||||
CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwFAYDVR0RBA0wC4IJc3luY3RoaW5nMAoG
|
||||
CCqGSM49BAMCA2gAMGUCMGxR9q9vjzm4GynOkoRIC+BQJN0zpiNusYUD6iYJNGe1
|
||||
wNH8jhOJEG+rjGracDZ6bgIxAIpyHv/rOAjEX7/wcafRqGTFhwXdRq0l3493aERd
|
||||
RCwqD8rbzP0QStVOCAE7xYt/sQ==
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
SyncthingRemoteKey = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDAKabOokHf64xAsIQp5PA1zZ5vLjfcgKcuikx/D0CP6c2Cf48a6eADE
|
||||
GWrY1Ng8UzOgBwYFK4EEACKhZANiAARPBozdX3YPj324xdYWAbF1NQC+2nW03t4+
|
||||
4nG3xb4U7SLMbV9ruhTb0ekVTQ6GHfHCdB8QchbOUomWVnZlttcY69x+vRh+KKvp
|
||||
Ogq43rXzkQDxEeQD7kdG27mfDnDJYv8=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
LocalCert, err = tls.X509KeyPair([]byte(SyncthingLocalCert), []byte(SyncthingLocalKey))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
RemoteCert, err = tls.X509KeyPair([]byte(SyncthingRemoteCert), []byte(SyncthingRemoteKey))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
LocalDeviceID, err = protocol.DeviceIDFromString(SyncthingLocalDeviceID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
RemoteDeviceID, err = protocol.DeviceIDFromString(SyncthingRemoteDeviceID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
@@ -74,6 +74,8 @@ func (svr *Server) Clone(req *rpc.CloneRequest, resp rpc.Daemon_CloneServer) (er
|
||||
TargetRegistry: req.TargetRegistry,
|
||||
IsChangeTargetRegistry: req.IsChangeTargetRegistry,
|
||||
TargetWorkloadNames: map[string]string{},
|
||||
LocalDir: req.LocalDir,
|
||||
RemoteDir: req.RemoteDir,
|
||||
}
|
||||
file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
|
||||
if err != nil {
|
||||
@@ -108,6 +110,7 @@ func (svr *Server) Clone(req *rpc.CloneRequest, resp rpc.Daemon_CloneServer) (er
|
||||
}
|
||||
config.Image = req.Image
|
||||
log.Infof("clone workloads...")
|
||||
options.SetContext(sshCtx)
|
||||
err = options.DoClone(resp.Context(), []byte(req.KubeconfigBytes))
|
||||
if err != nil {
|
||||
log.Errorf("clone workloads failed: %v", err)
|
||||
|
@@ -135,6 +135,7 @@ func gen(connect *handler.ConnectOptions, clone *handler.CloneOptions) ([]*rpc.P
|
||||
Kubeconfig: kubeconfig,
|
||||
Namespace: namespace,
|
||||
Workload: workload,
|
||||
SyncthingGUIAddr: clone.GetSyncthingGUIAddr(),
|
||||
RuleList: []*rpc.CloneRule{
|
||||
{
|
||||
DstCluster: util.GetKubeconfigCluster(clone.GetFactory()),
|
||||
|
@@ -7,7 +7,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
@@ -24,7 +23,7 @@ import (
|
||||
var daemonClient, sudoDaemonClient rpc.DaemonClient
|
||||
|
||||
func GetClient(isSudo bool) (cli rpc.DaemonClient) {
|
||||
sockPath := GetSockPath(isSudo)
|
||||
sockPath := config.GetSockPath(isSudo)
|
||||
if _, err := os.Stat(sockPath); errors.Is(err, os.ErrNotExist) {
|
||||
return nil
|
||||
}
|
||||
@@ -85,7 +84,7 @@ func GetClient(isSudo bool) (cli rpc.DaemonClient) {
|
||||
}
|
||||
|
||||
func GetClientWithoutCache(ctx context.Context, isSudo bool) (cli rpc.DaemonClient, conn *grpc.ClientConn, err error) {
|
||||
sockPath := GetSockPath(isSudo)
|
||||
sockPath := config.GetSockPath(isSudo)
|
||||
_, err = os.Stat(sockPath)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return
|
||||
@@ -112,26 +111,6 @@ func GetClientWithoutCache(ctx context.Context, isSudo bool) (cli rpc.DaemonClie
|
||||
return cli, conn, nil
|
||||
}
|
||||
|
||||
func GetSockPath(isSudo bool) string {
|
||||
name := config.SockPath
|
||||
if isSudo {
|
||||
name = config.SudoSockPath
|
||||
}
|
||||
return filepath.Join(config.DaemonPath, name)
|
||||
}
|
||||
|
||||
func GetPidPath(isSudo bool) string {
|
||||
name := config.PidPath
|
||||
if isSudo {
|
||||
name = config.SudoPidPath
|
||||
}
|
||||
return filepath.Join(config.DaemonPath, name)
|
||||
}
|
||||
|
||||
func GetConfigFilePath() string {
|
||||
return filepath.Join(config.HomePath, config.ConfigFile)
|
||||
}
|
||||
|
||||
func StartupDaemon(ctx context.Context, path ...string) error {
|
||||
var exe string
|
||||
var err error
|
||||
@@ -165,7 +144,7 @@ func runDaemon(ctx context.Context, exe string, isSudo bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
pidPath := GetPidPath(isSudo)
|
||||
pidPath := config.GetPidPath(isSudo)
|
||||
err := os.Remove(pidPath)
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
@@ -204,7 +183,7 @@ func GetHttpClient(isSudo bool) *http.Client {
|
||||
var d net.Dialer
|
||||
d.Timeout = 30 * time.Second
|
||||
d.KeepAlive = 30 * time.Second
|
||||
return d.DialContext(ctx, "unix", GetSockPath(isSudo))
|
||||
return d.DialContext(ctx, "unix", config.GetSockPath(isSudo))
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -212,7 +191,7 @@ func GetHttpClient(isSudo bool) *http.Client {
|
||||
}
|
||||
|
||||
func GetTCPClient(isSudo bool) net.Conn {
|
||||
conn, err := net.Dial("unix", GetSockPath(isSudo))
|
||||
conn, err := net.Dial("unix", config.GetSockPath(isSudo))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/action"
|
||||
_ "github.com/wencaiwulue/kubevpn/v2/pkg/daemon/handler"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
@@ -69,7 +70,7 @@ func (o *SvrOption) Start(ctx context.Context) error {
|
||||
}()
|
||||
}
|
||||
|
||||
sockPath := GetSockPath(o.IsSudo)
|
||||
sockPath := config.GetSockPath(o.IsSudo)
|
||||
err := os.Remove(sockPath)
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
@@ -161,7 +162,7 @@ func CreateDowngradingHandler(grpcServer *grpc.Server, httpHandler http.Handler)
|
||||
|
||||
func (o *SvrOption) detectUnixSocksFile(ctx context.Context) {
|
||||
var f = func() {
|
||||
_, err := os.Stat(GetSockPath(o.IsSudo))
|
||||
_, err := os.Stat(config.GetSockPath(o.IsSudo))
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
o.Stop()
|
||||
return
|
||||
@@ -190,7 +191,7 @@ func (o *SvrOption) detectUnixSocksFile(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
defer watcher.Close()
|
||||
err = watcher.Add(GetPidPath(o.IsSudo))
|
||||
err = watcher.Add(config.GetPidPath(o.IsSudo))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -218,7 +219,7 @@ func (o *SvrOption) detectUnixSocksFile(ctx context.Context) {
|
||||
}
|
||||
|
||||
func writePIDToFile(isSudo bool) error {
|
||||
pidPath := GetPidPath(isSudo)
|
||||
pidPath := config.GetPidPath(isSudo)
|
||||
pid := os.Getpid()
|
||||
err := os.WriteFile(pidPath, []byte(strconv.Itoa(pid)), 0644)
|
||||
if err != nil {
|
||||
|
@@ -474,6 +474,8 @@ type CloneRequest struct {
|
||||
// log level
|
||||
Level int32 `protobuf:"varint,17,opt,name=Level,proto3" json:"Level,omitempty"`
|
||||
OriginKubeconfigPath string `protobuf:"bytes,18,opt,name=OriginKubeconfigPath,proto3" json:"OriginKubeconfigPath,omitempty"`
|
||||
LocalDir string `protobuf:"bytes,19,opt,name=LocalDir,proto3" json:"LocalDir,omitempty"`
|
||||
RemoteDir string `protobuf:"bytes,20,opt,name=RemoteDir,proto3" json:"RemoteDir,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CloneRequest) Reset() {
|
||||
@@ -627,6 +629,20 @@ func (x *CloneRequest) GetOriginKubeconfigPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *CloneRequest) GetLocalDir() string {
|
||||
if x != nil {
|
||||
return x.LocalDir
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *CloneRequest) GetRemoteDir() string {
|
||||
if x != nil {
|
||||
return x.RemoteDir
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type CloneResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1242,7 +1258,8 @@ type Clone struct {
|
||||
Kubeconfig string `protobuf:"bytes,3,opt,name=Kubeconfig,proto3" json:"Kubeconfig,omitempty"`
|
||||
Namespace string `protobuf:"bytes,4,opt,name=Namespace,proto3" json:"Namespace,omitempty"`
|
||||
Workload string `protobuf:"bytes,5,opt,name=Workload,proto3" json:"Workload,omitempty"`
|
||||
RuleList []*CloneRule `protobuf:"bytes,6,rep,name=RuleList,proto3" json:"RuleList,omitempty"`
|
||||
SyncthingGUIAddr string `protobuf:"bytes,6,opt,name=SyncthingGUIAddr,proto3" json:"SyncthingGUIAddr,omitempty"`
|
||||
RuleList []*CloneRule `protobuf:"bytes,7,rep,name=RuleList,proto3" json:"RuleList,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Clone) Reset() {
|
||||
@@ -1312,6 +1329,13 @@ func (x *Clone) GetWorkload() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Clone) GetSyncthingGUIAddr() string {
|
||||
if x != nil {
|
||||
return x.SyncthingGUIAddr
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Clone) GetRuleList() []*CloneRule {
|
||||
if x != nil {
|
||||
return x.RuleList
|
||||
@@ -2812,7 +2836,7 @@ var file_daemon_proto_rawDesc = []byte{
|
||||
0x28, 0x09, 0x52, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x22, 0x29, 0x0a,
|
||||
0x0d, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xe3, 0x05, 0x0a, 0x0c, 0x43, 0x6c, 0x6f,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9d, 0x06, 0x0a, 0x0c, 0x43, 0x6c, 0x6f,
|
||||
0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4b, 0x75, 0x62,
|
||||
0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79,
|
||||
@@ -2855,82 +2879,51 @@ var file_daemon_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x50, 0x61, 0x74, 0x68, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x4f, 0x72,
|
||||
0x69, 0x67, 0x69, 0x6e, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x61,
|
||||
0x74, 0x68, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x29,
|
||||
0x0a, 0x0d, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2d, 0x0a, 0x0d, 0x52, 0x65, 0x6d,
|
||||
0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x57, 0x6f,
|
||||
0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x57,
|
||||
0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x22, 0x2a, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x22, 0x28, 0x0a, 0x0c, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2f, 0x0a,
|
||||
0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x73, 0x22, 0x31,
|
||||
0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x1f, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b,
|
||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x22, 0xa4, 0x02, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02,
|
||||
0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6c, 0x75,
|
||||
0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x4b, 0x75, 0x62, 0x65,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x75,
|
||||
0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x4e, 0x65, 0x74, 0x69, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4e,
|
||||
0x65, 0x74, 0x69, 0x66, 0x12, 0x28, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72,
|
||||
0x6f, 0x78, 0x79, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28,
|
||||
0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x0a, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x09, 0x43,
|
||||
0x6c, 0x6f, 0x6e, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0xc5, 0x01, 0x0a, 0x05, 0x50, 0x72, 0x6f,
|
||||
0x78, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x4b, 0x75,
|
||||
0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b,
|
||||
0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x57, 0x6f, 0x72, 0x6b,
|
||||
0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2a, 0x0a, 0x08, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f,
|
||||
0x78, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x08, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x22, 0xdf, 0x02, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x35,
|
||||
0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x2e,
|
||||
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x48, 0x65,
|
||||
0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x75,
|
||||
0x6e, 0x49, 0x50, 0x76, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4c, 0x6f, 0x63,
|
||||
0x61, 0x6c, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x76, 0x34, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x6f, 0x63,
|
||||
0x61, 0x6c, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x76, 0x36, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x76, 0x36, 0x12, 0x24, 0x0a,
|
||||
0x0d, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x76,
|
||||
0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x07, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x70, 0x18, 0x05,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79,
|
||||
0x52, 0x75, 0x6c, 0x65, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x07, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65,
|
||||
0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3a, 0x0a, 0x0c, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61,
|
||||
0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
||||
0x38, 0x01, 0x22, 0xc5, 0x01, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x44, 0x69, 0x72, 0x18, 0x13,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x44, 0x69, 0x72, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x69, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x69, 0x72, 0x1a, 0x3a, 0x0a, 0x0c,
|
||||
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x29, 0x0a, 0x0d, 0x43, 0x6c, 0x6f, 0x6e,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x22, 0x2d, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64,
|
||||
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61,
|
||||
0x64, 0x73, 0x22, 0x2a, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x0d,
|
||||
0x0a, 0x0b, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x28, 0x0a,
|
||||
0x0c, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6c, 0x75, 0x73,
|
||||
0x74, 0x65, 0x72, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x73, 0x22, 0x31, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x22, 0xa4, 0x02, 0x0a, 0x06,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74,
|
||||
0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4d, 0x6f,
|
||||
0x64, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x65, 0x74, 0x69,
|
||||
0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x65, 0x74, 0x69, 0x66, 0x12, 0x28,
|
||||
0x0a, 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x09, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x09, 0x50,
|
||||
0x72, 0x6f, 0x78, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x6e,
|
||||
0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x09, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x22, 0xc5, 0x01, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6c, 0x75,
|
||||
@@ -2941,211 +2934,248 @@ var file_daemon_proto_rawDesc = []byte{
|
||||
0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2a,
|
||||
0x0a, 0x08, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x75, 0x6c, 0x65,
|
||||
0x52, 0x08, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x43,
|
||||
0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64,
|
||||
0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||
0x32, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x75, 0x6c, 0x65,
|
||||
0x52, 0x08, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0xdf, 0x02, 0x0a, 0x09, 0x50,
|
||||
0x72, 0x6f, 0x78, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64,
|
||||
0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12,
|
||||
0x22, 0x0a, 0x0c, 0x44, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18,
|
||||
0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x44, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73,
|
||||
0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x73, 0x74, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x44, 0x73, 0x74, 0x4b,
|
||||
0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x44, 0x73, 0x74,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0c, 0x44, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x44, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x0d, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x44, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x1a,
|
||||
0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x10, 0x0a, 0x0e, 0x56,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2b, 0x0a,
|
||||
0x0f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x82, 0x01, 0x0a, 0x10, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x28, 0x0a, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74,
|
||||
0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75,
|
||||
0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53,
|
||||
0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x52, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22,
|
||||
0x2d, 0x0a, 0x0f, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x22, 0x2e,
|
||||
0x0a, 0x10, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x22, 0x2c,
|
||||
0x0a, 0x0e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x22, 0x2d, 0x0a, 0x0f,
|
||||
0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x50, 0x22, 0x51, 0x0a, 0x11, 0x53,
|
||||
0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x53, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d,
|
||||
0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73,
|
||||
0x68, 0x4a, 0x75, 0x6d, 0x70, 0x52, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22, 0x44,
|
||||
0x0a, 0x12, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74,
|
||||
0x64, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64,
|
||||
0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6c, 0x75,
|
||||
0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x22, 0x33, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x22, 0x16, 0x0a, 0x14,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x06, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0x27, 0x0a, 0x0b, 0x4c, 0x6f,
|
||||
0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x22, 0x28, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x46, 0x0a, 0x0a,
|
||||
0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x22, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22,
|
||||
0x5e, 0x0a, 0x0e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x24, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x6c, 0x69, 0x65, 0x6e,
|
||||
0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x22,
|
||||
0x33, 0x0a, 0x0f, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x65, 0x64, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x65, 0x64, 0x55, 0x70, 0x67,
|
||||
0x72, 0x61, 0x64, 0x65, 0x22, 0x7e, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4b,
|
||||
0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x07,
|
||||
0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
|
||||
0x22, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x75, 0x6e, 0x49, 0x50, 0x76, 0x34, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x75, 0x6e, 0x49,
|
||||
0x50, 0x76, 0x34, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x75, 0x6e, 0x49,
|
||||
0x50, 0x76, 0x36, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
|
||||
0x54, 0x75, 0x6e, 0x49, 0x50, 0x76, 0x36, 0x12, 0x24, 0x0a, 0x0d, 0x43, 0x75, 0x72, 0x72, 0x65,
|
||||
0x6e, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
|
||||
0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a,
|
||||
0x07, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x70, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b,
|
||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x50,
|
||||
0x6f, 0x72, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x50, 0x6f, 0x72,
|
||||
0x74, 0x4d, 0x61, 0x70, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
|
||||
0x1a, 0x3a, 0x0a, 0x0c, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf1, 0x01, 0x0a,
|
||||
0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74,
|
||||
0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
|
||||
0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63,
|
||||
0x74, 0x68, 0x69, 0x6e, 0x67, 0x47, 0x55, 0x49, 0x41, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x47, 0x55, 0x49,
|
||||
0x41, 0x64, 0x64, 0x72, 0x12, 0x2a, 0x0a, 0x08, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f,
|
||||
0x6e, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x08, 0x52, 0x75, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x22, 0xae, 0x02, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x35,
|
||||
0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x2e,
|
||||
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x48, 0x65,
|
||||
0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x44, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73,
|
||||
0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x44, 0x73, 0x74,
|
||||
0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x73, 0x74,
|
||||
0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44,
|
||||
0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x73, 0x74,
|
||||
0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x44, 0x73, 0x74, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x22, 0x0a, 0x0c, 0x44, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18,
|
||||
0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x44, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f,
|
||||
0x61, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x73, 0x74, 0x57, 0x6f, 0x72,
|
||||
0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||
0x01, 0x22, 0x10, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x22, 0x82, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
|
||||
0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a,
|
||||
0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c,
|
||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x52, 0x07, 0x53, 0x73,
|
||||
0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22, 0x2d, 0x0a, 0x0f, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65,
|
||||
0x6e, 0x74, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65,
|
||||
0x6e, 0x74, 0x49, 0x50, 0x22, 0x2e, 0x0a, 0x10, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x49, 0x50, 0x22, 0x2c, 0x0a, 0x0e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
||||
0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
||||
0x49, 0x50, 0x22, 0x2d, 0x0a, 0x0f, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49,
|
||||
0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49,
|
||||
0x50, 0x22, 0x51, 0x0a, 0x11, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x64, 0x69, 0x6e, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x07,
|
||||
0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x52, 0x07, 0x53, 0x73, 0x68,
|
||||
0x4a, 0x75, 0x6d, 0x70, 0x22, 0x29, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
|
||||
0xc7, 0x02, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x41,
|
||||
0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x64, 0x64, 0x72, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55,
|
||||
0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4a, 0x75, 0x6d,
|
||||
0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4a, 0x75, 0x6d, 0x70, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12,
|
||||
0x2a, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74,
|
||||
0x65, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x0a, 0x10, 0x47,
|
||||
0x53, 0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79,
|
||||
0x74, 0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x26, 0x0a, 0x0e, 0x47, 0x53, 0x53, 0x41, 0x50,
|
||||
0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12,
|
||||
0x28, 0x0a, 0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69,
|
||||
0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49,
|
||||
0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x6e, 0x0a, 0x0a, 0x45, 0x78, 0x74,
|
||||
0x72, 0x61, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x72, 0x61,
|
||||
0x43, 0x49, 0x44, 0x52, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x45, 0x78, 0x74, 0x72,
|
||||
0x61, 0x43, 0x49, 0x44, 0x52, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x44, 0x6f,
|
||||
0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x45, 0x78, 0x74, 0x72,
|
||||
0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61,
|
||||
0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x45, 0x78,
|
||||
0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x22, 0x11, 0x0a, 0x0f, 0x49, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x10,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44,
|
||||
0x32, 0xa6, 0x09, 0x0a, 0x06, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x07, 0x43,
|
||||
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e,
|
||||
0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
|
||||
0x46, 0x6f, 0x72, 0x6b, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
|
||||
0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12,
|
||||
0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32,
|
||||
0x0a, 0x05, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65,
|
||||
0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
|
||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
|
||||
0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a,
|
||||
0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64,
|
||||
0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0c, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x18, 0x2e, 0x72, 0x70,
|
||||
0x4a, 0x75, 0x6d, 0x70, 0x22, 0x44, 0x0a, 0x12, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74,
|
||||
0x64, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x64, 0x6f,
|
||||
0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x11, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x22, 0x33, 0x0a,
|
||||
0x13, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49,
|
||||
0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
|
||||
0x49, 0x44, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x0a, 0x0a, 0x4c, 0x6f,
|
||||
0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x6f, 0x6c, 0x6c,
|
||||
0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77,
|
||||
0x22, 0x27, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x28, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x22, 0x46, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x29, 0x0a, 0x0b, 0x47, 0x65,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5e, 0x0a, 0x0e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e,
|
||||
0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
|
||||
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a,
|
||||
0x0e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x64, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d,
|
||||
0x6d, 0x69, 0x74, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x0f, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x65, 0x64,
|
||||
0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e,
|
||||
0x65, 0x65, 0x64, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x22, 0x7e, 0x0a, 0x0c, 0x52, 0x65,
|
||||
0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4b, 0x75,
|
||||
0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42,
|
||||
0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
|
||||
0x63, 0x65, 0x12, 0x26, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d,
|
||||
0x70, 0x52, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22, 0x29, 0x0a, 0x0d, 0x52, 0x65,
|
||||
0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xc7, 0x02, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d,
|
||||
0x70, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x41, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73,
|
||||
0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73,
|
||||
0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4a,
|
||||
0x75, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c, 0x69,
|
||||
0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b,
|
||||
0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x12, 0x2a, 0x0a, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61,
|
||||
0x62, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x47, 0x53, 0x53,
|
||||
0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x26, 0x0a,
|
||||
0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18,
|
||||
0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73,
|
||||
0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43,
|
||||
0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
|
||||
0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x22,
|
||||
0x6e, 0x0a, 0x0a, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x45, 0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x09, 0x45, 0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x12, 0x20, 0x0a, 0x0b, 0x45,
|
||||
0x78, 0x74, 0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x22,
|
||||
0x11, 0x0a, 0x0f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x22, 0x22, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x32, 0xa6, 0x09, 0x0a, 0x06, 0x44, 0x61, 0x65, 0x6d, 0x6f,
|
||||
0x6e, 0x12, 0x38, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x13, 0x2e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x0b, 0x43,
|
||||
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x46, 0x6f, 0x72, 0x6b, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69,
|
||||
0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x36, 0x0a, 0x05,
|
||||
0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x11, 0x2e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e,
|
||||
0x65, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x06,
|
||||
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6d,
|
||||
0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64,
|
||||
0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x45, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76,
|
||||
0x65, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
|
||||
0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14,
|
||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74,
|
||||
0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a,
|
||||
0x07, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53,
|
||||
0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e,
|
||||
0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e,
|
||||
0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x6f,
|
||||
0x67, 0x73, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12,
|
||||
0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12,
|
||||
0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61,
|
||||
0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x06,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x05, 0x52, 0x65, 0x73,
|
||||
0x65, 0x74, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2f, 0x0a,
|
||||
0x04, 0x51, 0x75, 0x69, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x69, 0x74,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75,
|
||||
0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x39,
|
||||
0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, 0x72,
|
||||
0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x73, 0x68, 0x53,
|
||||
0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74,
|
||||
0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x13,
|
||||
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f,
|
||||
0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0a, 0x53,
|
||||
0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01,
|
||||
0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c,
|
||||
0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12,
|
||||
0x2d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2a,
|
||||
0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x55, 0x70,
|
||||
0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67, 0x72,
|
||||
0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x12, 0x33, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x2e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x32, 0x0a, 0x05, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52,
|
||||
0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x30, 0x01, 0x12, 0x2f, 0x0a, 0x04, 0x51, 0x75, 0x69, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79,
|
||||
0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42,
|
||||
0x07, 0x5a, 0x05, 0x2e, 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@@ -116,6 +116,9 @@ message CloneRequest {
|
||||
int32 Level = 17;
|
||||
|
||||
string OriginKubeconfigPath = 18;
|
||||
|
||||
string LocalDir = 19;
|
||||
string RemoteDir = 20;
|
||||
}
|
||||
|
||||
message CloneResponse {
|
||||
@@ -181,7 +184,8 @@ message Clone {
|
||||
string Kubeconfig = 3;
|
||||
string Namespace = 4;
|
||||
string Workload = 5;
|
||||
repeated CloneRule RuleList = 6;
|
||||
string SyncthingGUIAddr = 6;
|
||||
repeated CloneRule RuleList = 7;
|
||||
}
|
||||
|
||||
message CloneRule {
|
||||
|
@@ -109,6 +109,7 @@ kubevpn serve -L "tun:/127.0.0.1:8422?net=${TunIPv4}&route=${CIDR4}" -F "tcp://$
|
||||
},
|
||||
},
|
||||
RunAsUser: pointer.Int64(0),
|
||||
RunAsGroup: pointer.Int64(0),
|
||||
Privileged: pointer.Bool(true),
|
||||
},
|
||||
Resources: corev1.ResourceRequirements{
|
||||
|
@@ -4,19 +4,25 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/google/uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
libconfig "github.com/syncthing/syncthing/lib/config"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/client-go/dynamic"
|
||||
@@ -25,12 +31,14 @@ import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/util/retry"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"k8s.io/kubectl/pkg/util/podutils"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/mesh"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/syncthing"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
@@ -52,6 +60,8 @@ type CloneOptions struct {
|
||||
isSame bool
|
||||
|
||||
OriginKubeconfigPath string
|
||||
LocalDir string
|
||||
RemoteDir string
|
||||
|
||||
targetClientset *kubernetes.Clientset
|
||||
targetRestclient *rest.RESTClient
|
||||
@@ -64,6 +74,8 @@ type CloneOptions struct {
|
||||
factory cmdutil.Factory
|
||||
|
||||
rollbackFuncList []func() error
|
||||
ctx context.Context
|
||||
syncthingGUIAddr string
|
||||
}
|
||||
|
||||
func (d *CloneOptions) InitClient(f cmdutil.Factory) (err error) {
|
||||
@@ -108,6 +120,10 @@ func (d *CloneOptions) InitClient(f cmdutil.Factory) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (d *CloneOptions) SetContext(ctx context.Context) {
|
||||
d.ctx = ctx
|
||||
}
|
||||
|
||||
// DoClone
|
||||
/*
|
||||
* 1) download mount path use empty-dir but skip empty-dir in init-containers
|
||||
@@ -180,8 +196,10 @@ func (d *CloneOptions) DoClone(ctx context.Context, kubeconfigJsonBytes []byte)
|
||||
// (2) modify labels
|
||||
spec.SetLabels(labelsMap)
|
||||
|
||||
// (3) add volumes KUBECONFIG
|
||||
spec.Spec.Volumes = append(spec.Spec.Volumes, v1.Volume{
|
||||
// (3) add volumes KUBECONFIG and syncDir
|
||||
syncDataDirName := config.VolumeSyncthing
|
||||
spec.Spec.Volumes = append(spec.Spec.Volumes,
|
||||
v1.Volume{
|
||||
Name: config.KUBECONFIG,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
DownwardAPI: &v1.DownwardAPIVolumeSource{
|
||||
@@ -193,36 +211,46 @@ func (d *CloneOptions) DoClone(ctx context.Context, kubeconfigJsonBytes []byte)
|
||||
}},
|
||||
},
|
||||
},
|
||||
})
|
||||
},
|
||||
v1.Volume{
|
||||
Name: syncDataDirName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
EmptyDir: &v1.EmptyDirVolumeSource{},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// (4) add kubevpn containers
|
||||
containers := spec.Spec.Containers
|
||||
// remove vpn sidecar
|
||||
for i := 0; i < len(containers); i++ {
|
||||
containers[i].ReadinessProbe = nil
|
||||
containers[i].LivenessProbe = nil
|
||||
containers[i].StartupProbe = nil
|
||||
containerName := containers[i].Name
|
||||
if err == nil && (containerName == config.ContainerSidecarVPN || containerName == config.ContainerSidecarEnvoyProxy) {
|
||||
containers = append(containers[:i], containers[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
{
|
||||
container, err := podcmd.FindOrDefaultContainerByName(&v1.Pod{Spec: v1.PodSpec{Containers: containers}}, d.TargetContainer, false, log.StandardLogger().Out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.TargetImage != "" {
|
||||
var index = -1
|
||||
if d.TargetContainer != "" {
|
||||
for i, container := range containers {
|
||||
nestedString := container.Name
|
||||
if err == nil && nestedString == d.TargetContainer {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
index = 0
|
||||
}
|
||||
if index < 0 {
|
||||
return fmt.Errorf("can not found container %s in pod template", d.TargetContainer)
|
||||
}
|
||||
// update container[index] image
|
||||
containers[index].Image = d.TargetImage
|
||||
container.Image = d.TargetImage
|
||||
}
|
||||
if d.LocalDir != "" {
|
||||
container.Command = []string{"tail", "-f", "/dev/null"}
|
||||
container.Args = []string{}
|
||||
container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{
|
||||
Name: syncDataDirName,
|
||||
ReadOnly: false,
|
||||
MountPath: d.RemoteDir,
|
||||
})
|
||||
}
|
||||
}
|
||||
// https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/
|
||||
if spec.Spec.SecurityContext == nil {
|
||||
@@ -278,11 +306,13 @@ func (d *CloneOptions) DoClone(ctx context.Context, kubeconfigJsonBytes []byte)
|
||||
v1.ResourceMemory: resource.MustParse("2048Mi"),
|
||||
},
|
||||
},
|
||||
VolumeMounts: []v1.VolumeMount{{
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: config.KUBECONFIG,
|
||||
ReadOnly: false,
|
||||
MountPath: "/tmp/.kube",
|
||||
}},
|
||||
},
|
||||
},
|
||||
Lifecycle: &v1.Lifecycle{
|
||||
PostStart: &v1.LifecycleHandler{
|
||||
Exec: &v1.ExecAction{
|
||||
@@ -302,10 +332,39 @@ func (d *CloneOptions) DoClone(ctx context.Context, kubeconfigJsonBytes []byte)
|
||||
},
|
||||
},
|
||||
RunAsUser: pointer.Int64(0),
|
||||
RunAsGroup: pointer.Int64(0),
|
||||
Privileged: pointer.Bool(true),
|
||||
},
|
||||
}
|
||||
spec.Spec.Containers = append(containers, *container)
|
||||
containerSync := &v1.Container{
|
||||
Name: config.ContainerSidecarSyncthing,
|
||||
Image: config.Image,
|
||||
// https://stackoverflow.com/questions/32918849/what-process-signal-does-pod-receive-when-executing-kubectl-rolling-update
|
||||
Command: []string{
|
||||
"kubevpn",
|
||||
"syncthing",
|
||||
"--dir",
|
||||
d.RemoteDir,
|
||||
},
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: map[v1.ResourceName]resource.Quantity{
|
||||
v1.ResourceCPU: resource.MustParse("500m"),
|
||||
v1.ResourceMemory: resource.MustParse("512Mi"),
|
||||
},
|
||||
Limits: map[v1.ResourceName]resource.Quantity{
|
||||
v1.ResourceCPU: resource.MustParse("1000m"),
|
||||
v1.ResourceMemory: resource.MustParse("1024Mi"),
|
||||
},
|
||||
},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: syncDataDirName,
|
||||
ReadOnly: false,
|
||||
MountPath: d.RemoteDir,
|
||||
},
|
||||
},
|
||||
}
|
||||
spec.Spec.Containers = append(containers, *container, *containerSync)
|
||||
//set spec
|
||||
marshal, err := json.Marshal(spec)
|
||||
if err != nil {
|
||||
@@ -340,6 +399,26 @@ func (d *CloneOptions) DoClone(ctx context.Context, kubeconfigJsonBytes []byte)
|
||||
return err
|
||||
}
|
||||
_ = util.RolloutStatus(ctx, d.factory, d.Namespace, workload, time.Minute*60)
|
||||
|
||||
if d.LocalDir == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
list, err := util.GetRunningPodList(ctx, d.targetClientset, d.TargetNamespace, fields.SelectorFromSet(labelsMap).String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
remoteAddr := net.JoinHostPort(list[0].Status.PodIP, strconv.Itoa(libconfig.DefaultTCPPort))
|
||||
localPort, _ := util.GetAvailableTCPPortOrDie()
|
||||
localAddr := net.JoinHostPort("127.0.0.1", strconv.Itoa(localPort))
|
||||
// disable synchting log, because it can not set output writer, only write std.Out or discard
|
||||
_ = os.Setenv("LOGGER_DISCARD", "1")
|
||||
err = syncthing.StartClient(d.ctx, d.LocalDir, localAddr, remoteAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.syncthingGUIAddr = (&url.URL{Scheme: "http", Host: localAddr}).String()
|
||||
log.Infof("access the syncthing GUI via the following URL: %s", d.syncthingGUIAddr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -777,3 +856,7 @@ func (d *CloneOptions) AddRollbackFunc(f func() error) {
|
||||
func (d *CloneOptions) GetFactory() cmdutil.Factory {
|
||||
return d.factory
|
||||
}
|
||||
|
||||
func (d *CloneOptions) GetSyncthingGUIAddr() string {
|
||||
return d.syncthingGUIAddr
|
||||
}
|
||||
|
@@ -347,6 +347,7 @@ kubevpn serve -L "tcp://:10800" -L "tun://:8422?net=${TunIPv4}" -L "gtcp://:1080
|
||||
},
|
||||
},
|
||||
RunAsUser: pointer.Int64(0),
|
||||
RunAsGroup: pointer.Int64(0),
|
||||
Privileged: pointer.Bool(true),
|
||||
},
|
||||
},
|
||||
|
@@ -120,6 +120,7 @@ kubevpn serve -L "tun:/localhost:8422?net=${TunIPv4}&route=${CIDR4}" -F "tcp://$
|
||||
},
|
||||
},
|
||||
RunAsUser: pointer.Int64(0),
|
||||
RunAsGroup: pointer.Int64(0),
|
||||
Privileged: pointer.Bool(true),
|
||||
},
|
||||
})
|
||||
|
72
pkg/syncthing/gui.go
Normal file
72
pkg/syncthing/gui.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package syncthing
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"embed"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
)
|
||||
|
||||
//go:embed gui.zip
|
||||
var assetsZip embed.FS
|
||||
|
||||
func MakeSureGui() error {
|
||||
return ExtractSyncthingGUIZipToDir(assetsZip, "gui.zip", config.GetSyncthingPath())
|
||||
}
|
||||
|
||||
func ExtractSyncthingGUIZipToDir(fs embed.FS, zipPath, targetDir string) error {
|
||||
zipData, err := fs.Open(zipPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer zipData.Close()
|
||||
|
||||
all, err := io.ReadAll(zipData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zipReader, err := zip.NewReader(bytes.NewReader(all), int64(len(all)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, file := range zipReader.File {
|
||||
filePath := filepath.Join(targetDir, file.Name)
|
||||
|
||||
if file.FileInfo().IsDir() {
|
||||
if err = os.MkdirAll(filePath, file.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(filepath.Dir(filePath), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var fileWriter *os.File
|
||||
fileWriter, err = os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var fileReader io.ReadCloser
|
||||
fileReader, err = file.Open()
|
||||
if err != nil {
|
||||
_ = fileWriter.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(fileWriter, fileReader)
|
||||
_ = fileReader.Close()
|
||||
_ = fileWriter.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
BIN
pkg/syncthing/gui.zip
Normal file
BIN
pkg/syncthing/gui.zip
Normal file
Binary file not shown.
235
pkg/syncthing/syncthing.go
Normal file
235
pkg/syncthing/syncthing.go
Normal file
@@ -0,0 +1,235 @@
|
||||
package syncthing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/syncthing/syncthing/cmd/syncthing/cmdutil"
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/db/backend"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/locations"
|
||||
"github.com/syncthing/syncthing/lib/logger"
|
||||
"github.com/syncthing/syncthing/lib/netutil"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/svcutil"
|
||||
"github.com/syncthing/syncthing/lib/syncthing"
|
||||
"github.com/thejerf/suture/v4"
|
||||
|
||||
pkgconfig "github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
)
|
||||
|
||||
const (
|
||||
dir = "dir"
|
||||
local = "local"
|
||||
remote = "remote"
|
||||
label = "kubevpn"
|
||||
guiPort = 8384
|
||||
)
|
||||
|
||||
var (
|
||||
conf = filepath.Join(pkgconfig.GetSyncthingPath(), "config.xml")
|
||||
)
|
||||
|
||||
func StartClient(ctx context.Context, localDir string, localAddr, remoteAddr string) error {
|
||||
if err := MakeSureGui(); err != nil {
|
||||
return err
|
||||
}
|
||||
err := cmdutil.SetConfigDataLocationsFromFlags(pkgconfig.GetSyncthingPath(), "", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = locations.Set(locations.GUIAssets, pkgconfig.GetSyncthingGUIPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var l = logger.New().NewFacility("main", "Main package")
|
||||
spec := svcutil.SpecWithDebugLogger(l)
|
||||
earlyService := suture.New("early", spec)
|
||||
earlyService.ServeBackground(ctx)
|
||||
|
||||
evLogger := events.NewLogger()
|
||||
earlyService.Add(evLogger)
|
||||
|
||||
var localID = pkgconfig.LocalDeviceID
|
||||
var remoteID = pkgconfig.RemoteDeviceID
|
||||
var devices []config.DeviceConfiguration
|
||||
devices = append(devices, config.DeviceConfiguration{
|
||||
DeviceID: localID,
|
||||
Compression: protocol.CompressionAlways,
|
||||
Addresses: []string{localAddr},
|
||||
Name: local,
|
||||
Untrusted: false,
|
||||
AutoAcceptFolders: true,
|
||||
Paused: false,
|
||||
})
|
||||
devices = append(devices, config.DeviceConfiguration{
|
||||
DeviceID: remoteID,
|
||||
Compression: protocol.CompressionAlways,
|
||||
Addresses: []string{remoteAddr},
|
||||
Name: remote,
|
||||
Untrusted: false,
|
||||
AutoAcceptFolders: true,
|
||||
Paused: false,
|
||||
})
|
||||
|
||||
var folder []config.FolderConfiguration
|
||||
folder = append(folder, config.FolderConfiguration{
|
||||
ID: dir,
|
||||
Label: label,
|
||||
FilesystemType: fs.FilesystemTypeBasic,
|
||||
Path: localDir,
|
||||
Type: config.FolderTypeSendReceive,
|
||||
Paused: false,
|
||||
Devices: []config.FolderDeviceConfiguration{
|
||||
{DeviceID: localID},
|
||||
{DeviceID: remoteID},
|
||||
},
|
||||
})
|
||||
cfgWrapper := config.Wrap(conf, config.Configuration{
|
||||
Devices: devices,
|
||||
Folders: folder,
|
||||
GUI: config.GUIConfiguration{
|
||||
Enabled: true,
|
||||
RawAddress: localAddr,
|
||||
},
|
||||
Options: config.OptionsConfiguration{
|
||||
AutoUpgradeIntervalH: 0,
|
||||
UpgradeToPreReleases: false,
|
||||
CREnabled: false,
|
||||
},
|
||||
}, localID, events.NoopLogger)
|
||||
earlyService.Add(cfgWrapper)
|
||||
|
||||
ldb := backend.OpenMemory()
|
||||
appOpts := syncthing.Options{
|
||||
NoUpgrade: true,
|
||||
ProfilerAddr: "",
|
||||
ResetDeltaIdxs: false,
|
||||
Verbose: false,
|
||||
DBRecheckInterval: 0,
|
||||
DBIndirectGCInterval: 0,
|
||||
}
|
||||
|
||||
app, err := syncthing.New(cfgWrapper, ldb, evLogger, pkgconfig.LocalCert, appOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = app.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
app.Stop(svcutil.ExitSuccess)
|
||||
}()
|
||||
go app.Wait()
|
||||
return app.Error()
|
||||
}
|
||||
|
||||
func StartServer(ctx context.Context, detach bool, remoteDir string) error {
|
||||
if err := MakeSureGui(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := cmdutil.SetConfigDataLocationsFromFlags(pkgconfig.GetSyncthingPath(), "", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = locations.Set(locations.GUIAssets, pkgconfig.GetSyncthingGUIPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spec := svcutil.SpecWithDebugLogger(logger.New().NewFacility("", ""))
|
||||
earlyService := suture.New("early", spec)
|
||||
earlyService.ServeBackground(ctx)
|
||||
|
||||
evLogger := events.NewLogger()
|
||||
earlyService.Add(evLogger)
|
||||
|
||||
var localID = pkgconfig.LocalDeviceID
|
||||
var remoteID = pkgconfig.RemoteDeviceID
|
||||
addr := net.JoinHostPort("0.0.0.0", strconv.Itoa(guiPort))
|
||||
var devices []config.DeviceConfiguration
|
||||
devices = append(devices, config.DeviceConfiguration{
|
||||
DeviceID: remoteID,
|
||||
Compression: protocol.CompressionAlways,
|
||||
Addresses: []string{addr},
|
||||
Name: remote,
|
||||
Untrusted: false,
|
||||
AutoAcceptFolders: true,
|
||||
Paused: false,
|
||||
})
|
||||
devices = append(devices, config.DeviceConfiguration{
|
||||
DeviceID: localID,
|
||||
Compression: protocol.CompressionAlways,
|
||||
Addresses: []string{"dynamic"},
|
||||
Name: local,
|
||||
Untrusted: false,
|
||||
AutoAcceptFolders: true,
|
||||
Paused: false,
|
||||
})
|
||||
|
||||
var folder []config.FolderConfiguration
|
||||
folder = append(folder, config.FolderConfiguration{
|
||||
ID: dir,
|
||||
Label: label,
|
||||
FilesystemType: fs.FilesystemTypeBasic,
|
||||
Path: remoteDir,
|
||||
Type: config.FolderTypeSendReceive,
|
||||
Paused: false,
|
||||
Devices: []config.FolderDeviceConfiguration{
|
||||
{DeviceID: remoteID},
|
||||
{DeviceID: localID},
|
||||
},
|
||||
})
|
||||
cfgWrapper := config.Wrap(conf, config.Configuration{
|
||||
Devices: devices,
|
||||
Folders: folder,
|
||||
GUI: config.GUIConfiguration{
|
||||
Enabled: true,
|
||||
RawAddress: addr,
|
||||
},
|
||||
Options: config.OptionsConfiguration{
|
||||
RawListenAddresses: []string{netutil.AddressURL("tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(config.DefaultTCPPort)))},
|
||||
CRURL: "",
|
||||
CREnabled: false,
|
||||
AutoUpgradeIntervalH: 0,
|
||||
UpgradeToPreReleases: false,
|
||||
GlobalAnnEnabled: false,
|
||||
},
|
||||
}, remoteID, events.NoopLogger)
|
||||
earlyService.Add(cfgWrapper)
|
||||
|
||||
ldb := backend.OpenMemory()
|
||||
appOpts := syncthing.Options{
|
||||
NoUpgrade: true,
|
||||
ProfilerAddr: "",
|
||||
ResetDeltaIdxs: false,
|
||||
Verbose: false,
|
||||
DBRecheckInterval: 0,
|
||||
DBIndirectGCInterval: 0,
|
||||
}
|
||||
|
||||
app, err := syncthing.New(cfgWrapper, ldb, evLogger, pkgconfig.RemoteCert, appOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = app.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
app.Stop(svcutil.ExitSuccess)
|
||||
}()
|
||||
if detach {
|
||||
go app.Wait()
|
||||
} else {
|
||||
app.Wait()
|
||||
}
|
||||
return app.Error()
|
||||
}
|
18
pkg/syncthing/syncthing_test.go
Normal file
18
pkg/syncthing/syncthing_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package syncthing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||
)
|
||||
|
||||
func TestGenerateCertificate(t *testing.T) {
|
||||
cert, err := tlsutil.NewCertificate("cert.pem", "key.pem", "syncthing", 365000)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(cert)
|
||||
id := protocol.NewDeviceID(cert.Certificate[0])
|
||||
t.Log(id)
|
||||
}
|
@@ -45,7 +45,7 @@ func Main(ctx context.Context) error {
|
||||
}
|
||||
|
||||
fmt.Fprint(os.Stdout, "Upgrade daemon...\n")
|
||||
err = daemon.StartupDaemon(ctx)
|
||||
err = daemon.StartupDaemon(context.Background())
|
||||
fmt.Fprint(os.Stdout, "Done\n")
|
||||
return err
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -104,3 +105,18 @@ func backoff(min, max time.Duration, attemptNum int) time.Duration {
|
||||
}
|
||||
return sleep
|
||||
}
|
||||
|
||||
func ParseDirMapping(dir string) (local, remote string, err error) {
|
||||
index := strings.LastIndex(dir, ":")
|
||||
if index < 0 {
|
||||
err = fmt.Errorf("directory mapping is invaild: %s", dir)
|
||||
return
|
||||
}
|
||||
local = dir[:index]
|
||||
_, err = os.Stat(local)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
remote = dir[index+1:]
|
||||
return
|
||||
}
|
||||
|
17
vendor/github.com/Azure/go-ntlmssp/.travis.yml
generated
vendored
Normal file
17
vendor/github.com/Azure/go-ntlmssp/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
sudo: false
|
||||
|
||||
language: go
|
||||
|
||||
before_script:
|
||||
- go get -u golang.org/x/lint/golint
|
||||
|
||||
go:
|
||||
- 1.10.x
|
||||
- master
|
||||
|
||||
script:
|
||||
- test -z "$(gofmt -s -l . | tee /dev/stderr)"
|
||||
- test -z "$(golint ./... | tee /dev/stderr)"
|
||||
- go vet ./...
|
||||
- go build -v ./...
|
||||
- go test -v ./...
|
21
vendor/github.com/Azure/go-ntlmssp/LICENSE
generated
vendored
Normal file
21
vendor/github.com/Azure/go-ntlmssp/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Microsoft
|
||||
|
||||
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.
|
29
vendor/github.com/Azure/go-ntlmssp/README.md
generated
vendored
Normal file
29
vendor/github.com/Azure/go-ntlmssp/README.md
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# go-ntlmssp
|
||||
Golang package that provides NTLM/Negotiate authentication over HTTP
|
||||
|
||||
[](https://godoc.org/github.com/Azure/go-ntlmssp) [](https://travis-ci.org/Azure/go-ntlmssp)
|
||||
|
||||
Protocol details from https://msdn.microsoft.com/en-us/library/cc236621.aspx
|
||||
Implementation hints from http://davenport.sourceforge.net/ntlm.html
|
||||
|
||||
This package only implements authentication, no key exchange or encryption. It
|
||||
only supports Unicode (UTF16LE) encoding of protocol strings, no OEM encoding.
|
||||
This package implements NTLMv2.
|
||||
|
||||
# Usage
|
||||
|
||||
```
|
||||
url, user, password := "http://www.example.com/secrets", "robpike", "pw123"
|
||||
client := &http.Client{
|
||||
Transport: ntlmssp.Negotiator{
|
||||
RoundTripper:&http.Transport{},
|
||||
},
|
||||
}
|
||||
|
||||
req, _ := http.NewRequest("GET", url, nil)
|
||||
req.SetBasicAuth(user, password)
|
||||
res, _ := client.Do(req)
|
||||
```
|
||||
|
||||
-----
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
41
vendor/github.com/Azure/go-ntlmssp/SECURITY.md
generated
vendored
Normal file
41
vendor/github.com/Azure/go-ntlmssp/SECURITY.md
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.8 BLOCK -->
|
||||
|
||||
## Security
|
||||
|
||||
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
|
||||
|
||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
|
||||
|
||||
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
|
||||
|
||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
|
||||
|
||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||
|
||||
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
|
||||
|
||||
## Preferred Languages
|
||||
|
||||
We prefer all communications to be in English.
|
||||
|
||||
## Policy
|
||||
|
||||
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
|
||||
|
||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
187
vendor/github.com/Azure/go-ntlmssp/authenticate_message.go
generated
vendored
Normal file
187
vendor/github.com/Azure/go-ntlmssp/authenticate_message.go
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type authenicateMessage struct {
|
||||
LmChallengeResponse []byte
|
||||
NtChallengeResponse []byte
|
||||
|
||||
TargetName string
|
||||
UserName string
|
||||
|
||||
// only set if negotiateFlag_NTLMSSP_NEGOTIATE_KEY_EXCH
|
||||
EncryptedRandomSessionKey []byte
|
||||
|
||||
NegotiateFlags negotiateFlags
|
||||
|
||||
MIC []byte
|
||||
}
|
||||
|
||||
type authenticateMessageFields struct {
|
||||
messageHeader
|
||||
LmChallengeResponse varField
|
||||
NtChallengeResponse varField
|
||||
TargetName varField
|
||||
UserName varField
|
||||
Workstation varField
|
||||
_ [8]byte
|
||||
NegotiateFlags negotiateFlags
|
||||
}
|
||||
|
||||
func (m authenicateMessage) MarshalBinary() ([]byte, error) {
|
||||
if !m.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEUNICODE) {
|
||||
return nil, errors.New("Only unicode is supported")
|
||||
}
|
||||
|
||||
target, user := toUnicode(m.TargetName), toUnicode(m.UserName)
|
||||
workstation := toUnicode("")
|
||||
|
||||
ptr := binary.Size(&authenticateMessageFields{})
|
||||
f := authenticateMessageFields{
|
||||
messageHeader: newMessageHeader(3),
|
||||
NegotiateFlags: m.NegotiateFlags,
|
||||
LmChallengeResponse: newVarField(&ptr, len(m.LmChallengeResponse)),
|
||||
NtChallengeResponse: newVarField(&ptr, len(m.NtChallengeResponse)),
|
||||
TargetName: newVarField(&ptr, len(target)),
|
||||
UserName: newVarField(&ptr, len(user)),
|
||||
Workstation: newVarField(&ptr, len(workstation)),
|
||||
}
|
||||
|
||||
f.NegotiateFlags.Unset(negotiateFlagNTLMSSPNEGOTIATEVERSION)
|
||||
|
||||
b := bytes.Buffer{}
|
||||
if err := binary.Write(&b, binary.LittleEndian, &f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Write(&b, binary.LittleEndian, &m.LmChallengeResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Write(&b, binary.LittleEndian, &m.NtChallengeResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Write(&b, binary.LittleEndian, &target); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Write(&b, binary.LittleEndian, &user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binary.Write(&b, binary.LittleEndian, &workstation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
//ProcessChallenge crafts an AUTHENTICATE message in response to the CHALLENGE message
|
||||
//that was received from the server
|
||||
func ProcessChallenge(challengeMessageData []byte, user, password string, domainNeeded bool) ([]byte, error) {
|
||||
if user == "" && password == "" {
|
||||
return nil, errors.New("Anonymous authentication not supported")
|
||||
}
|
||||
|
||||
var cm challengeMessage
|
||||
if err := cm.UnmarshalBinary(challengeMessageData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATELMKEY) {
|
||||
return nil, errors.New("Only NTLM v2 is supported, but server requested v1 (NTLMSSP_NEGOTIATE_LM_KEY)")
|
||||
}
|
||||
if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEKEYEXCH) {
|
||||
return nil, errors.New("Key exchange requested but not supported (NTLMSSP_NEGOTIATE_KEY_EXCH)")
|
||||
}
|
||||
|
||||
if !domainNeeded {
|
||||
cm.TargetName = ""
|
||||
}
|
||||
|
||||
am := authenicateMessage{
|
||||
UserName: user,
|
||||
TargetName: cm.TargetName,
|
||||
NegotiateFlags: cm.NegotiateFlags,
|
||||
}
|
||||
|
||||
timestamp := cm.TargetInfo[avIDMsvAvTimestamp]
|
||||
if timestamp == nil { // no time sent, take current time
|
||||
ft := uint64(time.Now().UnixNano()) / 100
|
||||
ft += 116444736000000000 // add time between unix & windows offset
|
||||
timestamp = make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(timestamp, ft)
|
||||
}
|
||||
|
||||
clientChallenge := make([]byte, 8)
|
||||
rand.Reader.Read(clientChallenge)
|
||||
|
||||
ntlmV2Hash := getNtlmV2Hash(password, user, cm.TargetName)
|
||||
|
||||
am.NtChallengeResponse = computeNtlmV2Response(ntlmV2Hash,
|
||||
cm.ServerChallenge[:], clientChallenge, timestamp, cm.TargetInfoRaw)
|
||||
|
||||
if cm.TargetInfoRaw == nil {
|
||||
am.LmChallengeResponse = computeLmV2Response(ntlmV2Hash,
|
||||
cm.ServerChallenge[:], clientChallenge)
|
||||
}
|
||||
return am.MarshalBinary()
|
||||
}
|
||||
|
||||
func ProcessChallengeWithHash(challengeMessageData []byte, user, hash string) ([]byte, error) {
|
||||
if user == "" && hash == "" {
|
||||
return nil, errors.New("Anonymous authentication not supported")
|
||||
}
|
||||
|
||||
var cm challengeMessage
|
||||
if err := cm.UnmarshalBinary(challengeMessageData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATELMKEY) {
|
||||
return nil, errors.New("Only NTLM v2 is supported, but server requested v1 (NTLMSSP_NEGOTIATE_LM_KEY)")
|
||||
}
|
||||
if cm.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEKEYEXCH) {
|
||||
return nil, errors.New("Key exchange requested but not supported (NTLMSSP_NEGOTIATE_KEY_EXCH)")
|
||||
}
|
||||
|
||||
am := authenicateMessage{
|
||||
UserName: user,
|
||||
TargetName: cm.TargetName,
|
||||
NegotiateFlags: cm.NegotiateFlags,
|
||||
}
|
||||
|
||||
timestamp := cm.TargetInfo[avIDMsvAvTimestamp]
|
||||
if timestamp == nil { // no time sent, take current time
|
||||
ft := uint64(time.Now().UnixNano()) / 100
|
||||
ft += 116444736000000000 // add time between unix & windows offset
|
||||
timestamp = make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(timestamp, ft)
|
||||
}
|
||||
|
||||
clientChallenge := make([]byte, 8)
|
||||
rand.Reader.Read(clientChallenge)
|
||||
|
||||
hashParts := strings.Split(hash, ":")
|
||||
if len(hashParts) > 1 {
|
||||
hash = hashParts[1]
|
||||
}
|
||||
hashBytes, err := hex.DecodeString(hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ntlmV2Hash := hmacMd5(hashBytes, toUnicode(strings.ToUpper(user)+cm.TargetName))
|
||||
|
||||
am.NtChallengeResponse = computeNtlmV2Response(ntlmV2Hash,
|
||||
cm.ServerChallenge[:], clientChallenge, timestamp, cm.TargetInfoRaw)
|
||||
|
||||
if cm.TargetInfoRaw == nil {
|
||||
am.LmChallengeResponse = computeLmV2Response(ntlmV2Hash,
|
||||
cm.ServerChallenge[:], clientChallenge)
|
||||
}
|
||||
return am.MarshalBinary()
|
||||
}
|
66
vendor/github.com/Azure/go-ntlmssp/authheader.go
generated
vendored
Normal file
66
vendor/github.com/Azure/go-ntlmssp/authheader.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type authheader []string
|
||||
|
||||
func (h authheader) IsBasic() bool {
|
||||
for _, s := range h {
|
||||
if strings.HasPrefix(string(s), "Basic ") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h authheader) Basic() string {
|
||||
for _, s := range h {
|
||||
if strings.HasPrefix(string(s), "Basic ") {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (h authheader) IsNegotiate() bool {
|
||||
for _, s := range h {
|
||||
if strings.HasPrefix(string(s), "Negotiate") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h authheader) IsNTLM() bool {
|
||||
for _, s := range h {
|
||||
if strings.HasPrefix(string(s), "NTLM") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h authheader) GetData() ([]byte, error) {
|
||||
for _, s := range h {
|
||||
if strings.HasPrefix(string(s), "NTLM") || strings.HasPrefix(string(s), "Negotiate") || strings.HasPrefix(string(s), "Basic ") {
|
||||
p := strings.Split(string(s), " ")
|
||||
if len(p) < 2 {
|
||||
return nil, nil
|
||||
}
|
||||
return base64.StdEncoding.DecodeString(string(p[1]))
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (h authheader) GetBasicCreds() (username, password string, err error) {
|
||||
d, err := h.GetData()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
parts := strings.SplitN(string(d), ":", 2)
|
||||
return parts[0], parts[1], nil
|
||||
}
|
17
vendor/github.com/Azure/go-ntlmssp/avids.go
generated
vendored
Normal file
17
vendor/github.com/Azure/go-ntlmssp/avids.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package ntlmssp
|
||||
|
||||
type avID uint16
|
||||
|
||||
const (
|
||||
avIDMsvAvEOL avID = iota
|
||||
avIDMsvAvNbComputerName
|
||||
avIDMsvAvNbDomainName
|
||||
avIDMsvAvDNSComputerName
|
||||
avIDMsvAvDNSDomainName
|
||||
avIDMsvAvDNSTreeName
|
||||
avIDMsvAvFlags
|
||||
avIDMsvAvTimestamp
|
||||
avIDMsvAvSingleHost
|
||||
avIDMsvAvTargetName
|
||||
avIDMsvChannelBindings
|
||||
)
|
82
vendor/github.com/Azure/go-ntlmssp/challenge_message.go
generated
vendored
Normal file
82
vendor/github.com/Azure/go-ntlmssp/challenge_message.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type challengeMessageFields struct {
|
||||
messageHeader
|
||||
TargetName varField
|
||||
NegotiateFlags negotiateFlags
|
||||
ServerChallenge [8]byte
|
||||
_ [8]byte
|
||||
TargetInfo varField
|
||||
}
|
||||
|
||||
func (m challengeMessageFields) IsValid() bool {
|
||||
return m.messageHeader.IsValid() && m.MessageType == 2
|
||||
}
|
||||
|
||||
type challengeMessage struct {
|
||||
challengeMessageFields
|
||||
TargetName string
|
||||
TargetInfo map[avID][]byte
|
||||
TargetInfoRaw []byte
|
||||
}
|
||||
|
||||
func (m *challengeMessage) UnmarshalBinary(data []byte) error {
|
||||
r := bytes.NewReader(data)
|
||||
err := binary.Read(r, binary.LittleEndian, &m.challengeMessageFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !m.challengeMessageFields.IsValid() {
|
||||
return fmt.Errorf("Message is not a valid challenge message: %+v", m.challengeMessageFields.messageHeader)
|
||||
}
|
||||
|
||||
if m.challengeMessageFields.TargetName.Len > 0 {
|
||||
m.TargetName, err = m.challengeMessageFields.TargetName.ReadStringFrom(data, m.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEUNICODE))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if m.challengeMessageFields.TargetInfo.Len > 0 {
|
||||
d, err := m.challengeMessageFields.TargetInfo.ReadFrom(data)
|
||||
m.TargetInfoRaw = d
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.TargetInfo = make(map[avID][]byte)
|
||||
r := bytes.NewReader(d)
|
||||
for {
|
||||
var id avID
|
||||
var l uint16
|
||||
err = binary.Read(r, binary.LittleEndian, &id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if id == avIDMsvAvEOL {
|
||||
break
|
||||
}
|
||||
|
||||
err = binary.Read(r, binary.LittleEndian, &l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value := make([]byte, l)
|
||||
n, err := r.Read(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != int(l) {
|
||||
return fmt.Errorf("Expected to read %d bytes, got only %d", l, n)
|
||||
}
|
||||
m.TargetInfo[id] = value
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
21
vendor/github.com/Azure/go-ntlmssp/messageheader.go
generated
vendored
Normal file
21
vendor/github.com/Azure/go-ntlmssp/messageheader.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
var signature = [8]byte{'N', 'T', 'L', 'M', 'S', 'S', 'P', 0}
|
||||
|
||||
type messageHeader struct {
|
||||
Signature [8]byte
|
||||
MessageType uint32
|
||||
}
|
||||
|
||||
func (h messageHeader) IsValid() bool {
|
||||
return bytes.Equal(h.Signature[:], signature[:]) &&
|
||||
h.MessageType > 0 && h.MessageType < 4
|
||||
}
|
||||
|
||||
func newMessageHeader(messageType uint32) messageHeader {
|
||||
return messageHeader{signature, messageType}
|
||||
}
|
52
vendor/github.com/Azure/go-ntlmssp/negotiate_flags.go
generated
vendored
Normal file
52
vendor/github.com/Azure/go-ntlmssp/negotiate_flags.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
package ntlmssp
|
||||
|
||||
type negotiateFlags uint32
|
||||
|
||||
const (
|
||||
/*A*/ negotiateFlagNTLMSSPNEGOTIATEUNICODE negotiateFlags = 1 << 0
|
||||
/*B*/ negotiateFlagNTLMNEGOTIATEOEM = 1 << 1
|
||||
/*C*/ negotiateFlagNTLMSSPREQUESTTARGET = 1 << 2
|
||||
|
||||
/*D*/
|
||||
negotiateFlagNTLMSSPNEGOTIATESIGN = 1 << 4
|
||||
/*E*/ negotiateFlagNTLMSSPNEGOTIATESEAL = 1 << 5
|
||||
/*F*/ negotiateFlagNTLMSSPNEGOTIATEDATAGRAM = 1 << 6
|
||||
/*G*/ negotiateFlagNTLMSSPNEGOTIATELMKEY = 1 << 7
|
||||
|
||||
/*H*/
|
||||
negotiateFlagNTLMSSPNEGOTIATENTLM = 1 << 9
|
||||
|
||||
/*J*/
|
||||
negotiateFlagANONYMOUS = 1 << 11
|
||||
/*K*/ negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED = 1 << 12
|
||||
/*L*/ negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED = 1 << 13
|
||||
|
||||
/*M*/
|
||||
negotiateFlagNTLMSSPNEGOTIATEALWAYSSIGN = 1 << 15
|
||||
/*N*/ negotiateFlagNTLMSSPTARGETTYPEDOMAIN = 1 << 16
|
||||
/*O*/ negotiateFlagNTLMSSPTARGETTYPESERVER = 1 << 17
|
||||
|
||||
/*P*/
|
||||
negotiateFlagNTLMSSPNEGOTIATEEXTENDEDSESSIONSECURITY = 1 << 19
|
||||
/*Q*/ negotiateFlagNTLMSSPNEGOTIATEIDENTIFY = 1 << 20
|
||||
|
||||
/*R*/
|
||||
negotiateFlagNTLMSSPREQUESTNONNTSESSIONKEY = 1 << 22
|
||||
/*S*/ negotiateFlagNTLMSSPNEGOTIATETARGETINFO = 1 << 23
|
||||
|
||||
/*T*/
|
||||
negotiateFlagNTLMSSPNEGOTIATEVERSION = 1 << 25
|
||||
|
||||
/*U*/
|
||||
negotiateFlagNTLMSSPNEGOTIATE128 = 1 << 29
|
||||
/*V*/ negotiateFlagNTLMSSPNEGOTIATEKEYEXCH = 1 << 30
|
||||
/*W*/ negotiateFlagNTLMSSPNEGOTIATE56 = 1 << 31
|
||||
)
|
||||
|
||||
func (field negotiateFlags) Has(flags negotiateFlags) bool {
|
||||
return field&flags == flags
|
||||
}
|
||||
|
||||
func (field *negotiateFlags) Unset(flags negotiateFlags) {
|
||||
*field = *field ^ (*field & flags)
|
||||
}
|
64
vendor/github.com/Azure/go-ntlmssp/negotiate_message.go
generated
vendored
Normal file
64
vendor/github.com/Azure/go-ntlmssp/negotiate_message.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const expMsgBodyLen = 40
|
||||
|
||||
type negotiateMessageFields struct {
|
||||
messageHeader
|
||||
NegotiateFlags negotiateFlags
|
||||
|
||||
Domain varField
|
||||
Workstation varField
|
||||
|
||||
Version
|
||||
}
|
||||
|
||||
var defaultFlags = negotiateFlagNTLMSSPNEGOTIATETARGETINFO |
|
||||
negotiateFlagNTLMSSPNEGOTIATE56 |
|
||||
negotiateFlagNTLMSSPNEGOTIATE128 |
|
||||
negotiateFlagNTLMSSPNEGOTIATEUNICODE |
|
||||
negotiateFlagNTLMSSPNEGOTIATEEXTENDEDSESSIONSECURITY
|
||||
|
||||
//NewNegotiateMessage creates a new NEGOTIATE message with the
|
||||
//flags that this package supports.
|
||||
func NewNegotiateMessage(domainName, workstationName string) ([]byte, error) {
|
||||
payloadOffset := expMsgBodyLen
|
||||
flags := defaultFlags
|
||||
|
||||
if domainName != "" {
|
||||
flags |= negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED
|
||||
}
|
||||
|
||||
if workstationName != "" {
|
||||
flags |= negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED
|
||||
}
|
||||
|
||||
msg := negotiateMessageFields{
|
||||
messageHeader: newMessageHeader(1),
|
||||
NegotiateFlags: flags,
|
||||
Domain: newVarField(&payloadOffset, len(domainName)),
|
||||
Workstation: newVarField(&payloadOffset, len(workstationName)),
|
||||
Version: DefaultVersion(),
|
||||
}
|
||||
|
||||
b := bytes.Buffer{}
|
||||
if err := binary.Write(&b, binary.LittleEndian, &msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if b.Len() != expMsgBodyLen {
|
||||
return nil, errors.New("incorrect body length")
|
||||
}
|
||||
|
||||
payload := strings.ToUpper(domainName + workstationName)
|
||||
if _, err := b.WriteString(payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
151
vendor/github.com/Azure/go-ntlmssp/negotiator.go
generated
vendored
Normal file
151
vendor/github.com/Azure/go-ntlmssp/negotiator.go
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetDomain : parse domain name from based on slashes in the input
|
||||
// Need to check for upn as well
|
||||
func GetDomain(user string) (string, string, bool) {
|
||||
domain := ""
|
||||
domainNeeded := false
|
||||
|
||||
if strings.Contains(user, "\\") {
|
||||
ucomponents := strings.SplitN(user, "\\", 2)
|
||||
domain = ucomponents[0]
|
||||
user = ucomponents[1]
|
||||
domainNeeded = true
|
||||
} else if strings.Contains(user, "@") {
|
||||
domainNeeded = false
|
||||
} else {
|
||||
domainNeeded = true
|
||||
}
|
||||
return user, domain, domainNeeded
|
||||
}
|
||||
|
||||
//Negotiator is a http.Roundtripper decorator that automatically
|
||||
//converts basic authentication to NTLM/Negotiate authentication when appropriate.
|
||||
type Negotiator struct{ http.RoundTripper }
|
||||
|
||||
//RoundTrip sends the request to the server, handling any authentication
|
||||
//re-sends as needed.
|
||||
func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) {
|
||||
// Use default round tripper if not provided
|
||||
rt := l.RoundTripper
|
||||
if rt == nil {
|
||||
rt = http.DefaultTransport
|
||||
}
|
||||
// If it is not basic auth, just round trip the request as usual
|
||||
reqauth := authheader(req.Header.Values("Authorization"))
|
||||
if !reqauth.IsBasic() {
|
||||
return rt.RoundTrip(req)
|
||||
}
|
||||
reqauthBasic := reqauth.Basic()
|
||||
// Save request body
|
||||
body := bytes.Buffer{}
|
||||
if req.Body != nil {
|
||||
_, err = body.ReadFrom(req.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Body.Close()
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
|
||||
}
|
||||
// first try anonymous, in case the server still finds us
|
||||
// authenticated from previous traffic
|
||||
req.Header.Del("Authorization")
|
||||
res, err = rt.RoundTrip(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.StatusCode != http.StatusUnauthorized {
|
||||
return res, err
|
||||
}
|
||||
resauth := authheader(res.Header.Values("Www-Authenticate"))
|
||||
if !resauth.IsNegotiate() && !resauth.IsNTLM() {
|
||||
// Unauthorized, Negotiate not requested, let's try with basic auth
|
||||
req.Header.Set("Authorization", string(reqauthBasic))
|
||||
io.Copy(ioutil.Discard, res.Body)
|
||||
res.Body.Close()
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
|
||||
|
||||
res, err = rt.RoundTrip(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.StatusCode != http.StatusUnauthorized {
|
||||
return res, err
|
||||
}
|
||||
resauth = authheader(res.Header.Values("Www-Authenticate"))
|
||||
}
|
||||
|
||||
if resauth.IsNegotiate() || resauth.IsNTLM() {
|
||||
// 401 with request:Basic and response:Negotiate
|
||||
io.Copy(ioutil.Discard, res.Body)
|
||||
res.Body.Close()
|
||||
|
||||
// recycle credentials
|
||||
u, p, err := reqauth.GetBasicCreds()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get domain from username
|
||||
domain := ""
|
||||
u, domain, domainNeeded := GetDomain(u)
|
||||
|
||||
// send negotiate
|
||||
negotiateMessage, err := NewNegotiateMessage(domain, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resauth.IsNTLM() {
|
||||
req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(negotiateMessage))
|
||||
} else {
|
||||
req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(negotiateMessage))
|
||||
}
|
||||
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
|
||||
|
||||
res, err = rt.RoundTrip(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// receive challenge?
|
||||
resauth = authheader(res.Header.Values("Www-Authenticate"))
|
||||
challengeMessage, err := resauth.GetData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !(resauth.IsNegotiate() || resauth.IsNTLM()) || len(challengeMessage) == 0 {
|
||||
// Negotiation failed, let client deal with response
|
||||
return res, nil
|
||||
}
|
||||
io.Copy(ioutil.Discard, res.Body)
|
||||
res.Body.Close()
|
||||
|
||||
// send authenticate
|
||||
authenticateMessage, err := ProcessChallenge(challengeMessage, u, p, domainNeeded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resauth.IsNTLM() {
|
||||
req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(authenticateMessage))
|
||||
} else {
|
||||
req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(authenticateMessage))
|
||||
}
|
||||
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
|
||||
|
||||
return rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
51
vendor/github.com/Azure/go-ntlmssp/nlmp.go
generated
vendored
Normal file
51
vendor/github.com/Azure/go-ntlmssp/nlmp.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Package ntlmssp provides NTLM/Negotiate authentication over HTTP
|
||||
//
|
||||
// Protocol details from https://msdn.microsoft.com/en-us/library/cc236621.aspx,
|
||||
// implementation hints from http://davenport.sourceforge.net/ntlm.html .
|
||||
// This package only implements authentication, no key exchange or encryption. It
|
||||
// only supports Unicode (UTF16LE) encoding of protocol strings, no OEM encoding.
|
||||
// This package implements NTLMv2.
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"golang.org/x/crypto/md4"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getNtlmV2Hash(password, username, target string) []byte {
|
||||
return hmacMd5(getNtlmHash(password), toUnicode(strings.ToUpper(username)+target))
|
||||
}
|
||||
|
||||
func getNtlmHash(password string) []byte {
|
||||
hash := md4.New()
|
||||
hash.Write(toUnicode(password))
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func computeNtlmV2Response(ntlmV2Hash, serverChallenge, clientChallenge,
|
||||
timestamp, targetInfo []byte) []byte {
|
||||
|
||||
temp := []byte{1, 1, 0, 0, 0, 0, 0, 0}
|
||||
temp = append(temp, timestamp...)
|
||||
temp = append(temp, clientChallenge...)
|
||||
temp = append(temp, 0, 0, 0, 0)
|
||||
temp = append(temp, targetInfo...)
|
||||
temp = append(temp, 0, 0, 0, 0)
|
||||
|
||||
NTProofStr := hmacMd5(ntlmV2Hash, serverChallenge, temp)
|
||||
return append(NTProofStr, temp...)
|
||||
}
|
||||
|
||||
func computeLmV2Response(ntlmV2Hash, serverChallenge, clientChallenge []byte) []byte {
|
||||
return append(hmacMd5(ntlmV2Hash, serverChallenge, clientChallenge), clientChallenge...)
|
||||
}
|
||||
|
||||
func hmacMd5(key []byte, data ...[]byte) []byte {
|
||||
mac := hmac.New(md5.New, key)
|
||||
for _, d := range data {
|
||||
mac.Write(d)
|
||||
}
|
||||
return mac.Sum(nil)
|
||||
}
|
29
vendor/github.com/Azure/go-ntlmssp/unicode.go
generated
vendored
Normal file
29
vendor/github.com/Azure/go-ntlmssp/unicode.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"unicode/utf16"
|
||||
)
|
||||
|
||||
// helper func's for dealing with Windows Unicode (UTF16LE)
|
||||
|
||||
func fromUnicode(d []byte) (string, error) {
|
||||
if len(d)%2 > 0 {
|
||||
return "", errors.New("Unicode (UTF 16 LE) specified, but uneven data length")
|
||||
}
|
||||
s := make([]uint16, len(d)/2)
|
||||
err := binary.Read(bytes.NewReader(d), binary.LittleEndian, &s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(utf16.Decode(s)), nil
|
||||
}
|
||||
|
||||
func toUnicode(s string) []byte {
|
||||
uints := utf16.Encode([]rune(s))
|
||||
b := bytes.Buffer{}
|
||||
binary.Write(&b, binary.LittleEndian, &uints)
|
||||
return b.Bytes()
|
||||
}
|
40
vendor/github.com/Azure/go-ntlmssp/varfield.go
generated
vendored
Normal file
40
vendor/github.com/Azure/go-ntlmssp/varfield.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package ntlmssp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type varField struct {
|
||||
Len uint16
|
||||
MaxLen uint16
|
||||
BufferOffset uint32
|
||||
}
|
||||
|
||||
func (f varField) ReadFrom(buffer []byte) ([]byte, error) {
|
||||
if len(buffer) < int(f.BufferOffset+uint32(f.Len)) {
|
||||
return nil, errors.New("Error reading data, varField extends beyond buffer")
|
||||
}
|
||||
return buffer[f.BufferOffset : f.BufferOffset+uint32(f.Len)], nil
|
||||
}
|
||||
|
||||
func (f varField) ReadStringFrom(buffer []byte, unicode bool) (string, error) {
|
||||
d, err := f.ReadFrom(buffer)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if unicode { // UTF-16LE encoding scheme
|
||||
return fromUnicode(d)
|
||||
}
|
||||
// OEM encoding, close enough to ASCII, since no code page is specified
|
||||
return string(d), err
|
||||
}
|
||||
|
||||
func newVarField(ptr *int, fieldsize int) varField {
|
||||
f := varField{
|
||||
Len: uint16(fieldsize),
|
||||
MaxLen: uint16(fieldsize),
|
||||
BufferOffset: uint32(*ptr),
|
||||
}
|
||||
*ptr += fieldsize
|
||||
return f
|
||||
}
|
20
vendor/github.com/Azure/go-ntlmssp/version.go
generated
vendored
Normal file
20
vendor/github.com/Azure/go-ntlmssp/version.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package ntlmssp
|
||||
|
||||
// Version is a struct representing https://msdn.microsoft.com/en-us/library/cc236654.aspx
|
||||
type Version struct {
|
||||
ProductMajorVersion uint8
|
||||
ProductMinorVersion uint8
|
||||
ProductBuild uint16
|
||||
_ [3]byte
|
||||
NTLMRevisionCurrent uint8
|
||||
}
|
||||
|
||||
// DefaultVersion returns a Version with "sensible" defaults (Windows 7)
|
||||
func DefaultVersion() Version {
|
||||
return Version{
|
||||
ProductMajorVersion: 6,
|
||||
ProductMinorVersion: 1,
|
||||
ProductBuild: 7601,
|
||||
NTLMRevisionCurrent: 15,
|
||||
}
|
||||
}
|
21
vendor/github.com/calmh/incontainer/LICENSE
generated
vendored
Normal file
21
vendor/github.com/calmh/incontainer/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 calmh
|
||||
|
||||
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.
|
11
vendor/github.com/calmh/incontainer/README.md
generated
vendored
Normal file
11
vendor/github.com/calmh/incontainer/README.md
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
incontainer
|
||||
===========
|
||||
|
||||
Small package to try to determine if we're running inside a container or not.
|
||||
|
||||
Loosely based on https://github.com/pitkley/in-container for Rust.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
3
vendor/github.com/calmh/incontainer/docker-test.sh
generated
vendored
Normal file
3
vendor/github.com/calmh/incontainer/docker-test.sh
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker run -v $(pwd):/src -w /src -e IN_DOCKER_TEST=1 golang:latest go test -v
|
65
vendor/github.com/calmh/incontainer/incontainer_linux.go
generated
vendored
Normal file
65
vendor/github.com/calmh/incontainer/incontainer_linux.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
package incontainer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func Detect() bool {
|
||||
return hasContainerEnv() || isCgroupV2Container() || hasDockerCgroup() || pid1EnvHasContainer() || syscall.Getpid() == 1 || isOpenVZ() || isWSL() || isKubernetes()
|
||||
}
|
||||
|
||||
func hasContainerEnv() bool {
|
||||
return exists("/.dockerenv") || exists("/run/.containerenv")
|
||||
}
|
||||
|
||||
func isOpenVZ() bool {
|
||||
return exists("/proc/vz") && !exists("/proc/bc")
|
||||
}
|
||||
|
||||
func exists(file string) bool {
|
||||
_, err := os.Stat(file)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func hasDockerCgroup() bool {
|
||||
cgroup, err := os.ReadFile("/proc/self/cgroup")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Contains(cgroup, []byte("/docker/"))
|
||||
}
|
||||
|
||||
func isCgroupV2Container() bool {
|
||||
if !exists("/sys/fs/cgroup/cgroup.events") {
|
||||
return false
|
||||
}
|
||||
if exists("/sys/fs/cgroup/cgroup.type") {
|
||||
return true
|
||||
}
|
||||
if !exists("/sys/kernel/cgroup/features") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func pid1EnvHasContainer() bool {
|
||||
bs, err := os.ReadFile("/proc/1/environ")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Contains(bs, []byte("CONTAINER="))
|
||||
}
|
||||
|
||||
func isWSL() bool {
|
||||
bs, err := os.ReadFile("/proc/sys/kernel/osrelease")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Contains(bs, []byte("Microsoft"))
|
||||
}
|
||||
|
||||
func isKubernetes() bool {
|
||||
return os.Getenv("KUBERNETES_SERVICE_HOST") != ""
|
||||
}
|
8
vendor/github.com/calmh/incontainer/incontainer_other.go
generated
vendored
Normal file
8
vendor/github.com/calmh/incontainer/incontainer_other.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package incontainer
|
||||
|
||||
func Detect() bool {
|
||||
return false
|
||||
}
|
1
vendor/github.com/calmh/xdr/.gitignore
generated
vendored
Normal file
1
vendor/github.com/calmh/xdr/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
coverage.out
|
19
vendor/github.com/calmh/xdr/.travis.yml
generated
vendored
Normal file
19
vendor/github.com/calmh/xdr/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
language: go
|
||||
go:
|
||||
- tip
|
||||
|
||||
install:
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- go get golang.org/x/tools/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
script:
|
||||
- ./generate.sh
|
||||
- go test -coverprofile=coverage.out
|
||||
|
||||
after_success:
|
||||
- goveralls -coverprofile=coverage.out -service=travis-ci -package=calmh/xdr -repotoken="$COVERALLS_TOKEN"
|
||||
|
||||
env:
|
||||
global:
|
||||
secure: SmgnrGfp2zLrA44ChRMpjPeujubt9veZ8Fx/OseMWECmacyV5N/TuDhzIbwo6QwV4xB0sBacoPzvxQbJRVjNKsPiSu72UbcQmQ7flN4Tf7nW09tSh1iW8NgrpBCq/3UYLoBu2iPBEBKm93IK0aGNAKs6oEkB0fU27iTVBwiTXOY=
|
19
vendor/github.com/calmh/xdr/LICENSE
generated
vendored
Normal file
19
vendor/github.com/calmh/xdr/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2014 Jakob Borg.
|
||||
|
||||
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.
|
18
vendor/github.com/calmh/xdr/README.md
generated
vendored
Normal file
18
vendor/github.com/calmh/xdr/README.md
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# This project is not actively maintained
|
||||
|
||||
Issues and pull requests on this repository may not be acted on in a timely
|
||||
manner, or at all. You are of course welcome to use it anyway. You are even
|
||||
more welcome to fork it and maintain the results.
|
||||
|
||||

|
||||
|
||||
xdr
|
||||
===
|
||||
|
||||
[](https://circleci.com/gh/calmh/xdr)
|
||||
[](https://coveralls.io/r/calmh/xdr?branch=master)
|
||||
[](http://godoc.org/github.com/calmh/xdr)
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
|
||||
This is an XDR marshalling/unmarshalling library. It uses code generation and
|
||||
not reflection.
|
3
vendor/github.com/calmh/xdr/circle.yml
generated
vendored
Normal file
3
vendor/github.com/calmh/xdr/circle.yml
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
post:
|
||||
- ./generate.sh
|
59
vendor/github.com/calmh/xdr/common.go
generated
vendored
Normal file
59
vendor/github.com/calmh/xdr/common.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||
|
||||
package xdr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var padBytes = []byte{0, 0, 0}
|
||||
|
||||
// Pad returns the number of bytes that should be added to an item of length l
|
||||
// bytes to conform to the XDR padding standard. This function is used by the
|
||||
// generated marshalling code.
|
||||
func Padding(l int) int {
|
||||
d := l % 4
|
||||
if d == 0 {
|
||||
return 0
|
||||
}
|
||||
return 4 - d
|
||||
}
|
||||
|
||||
// ElementSizeExceeded returns an error describing the violated size
|
||||
// constraint. This function is used by the generated marshalling code.
|
||||
func ElementSizeExceeded(field string, size, limit int) error {
|
||||
return fmt.Errorf("%s exceeds size limit; %d > %d", field, size, limit)
|
||||
}
|
||||
|
||||
type XDRSizer interface {
|
||||
XDRSize() int
|
||||
}
|
||||
|
||||
// SizeOfSlice returns the XDR encoded size of the given []T. Supported types
|
||||
// for T are string, []byte and types implementing XDRSizer. SizeOfSlice
|
||||
// panics if the parameter is not a slice or if T is not one of the supported
|
||||
// types. This function is used by the generated marshalling code.
|
||||
func SizeOfSlice(ss interface{}) int {
|
||||
l := 0
|
||||
switch ss := ss.(type) {
|
||||
case []string:
|
||||
for _, s := range ss {
|
||||
l += 4 + len(s) + Padding(len(s))
|
||||
}
|
||||
|
||||
case [][]byte:
|
||||
for _, s := range ss {
|
||||
l += 4 + len(s) + Padding(len(s))
|
||||
}
|
||||
|
||||
default:
|
||||
v := reflect.ValueOf(ss)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
l += v.Index(i).Interface().(XDRSizer).XDRSize()
|
||||
}
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
5
vendor/github.com/calmh/xdr/doc.go
generated
vendored
Normal file
5
vendor/github.com/calmh/xdr/doc.go
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||
|
||||
// Package xdr implements an XDR (RFC 4506) marshaller/unmarshaller.
|
||||
package xdr
|
4
vendor/github.com/calmh/xdr/generate.sh
generated
vendored
Normal file
4
vendor/github.com/calmh/xdr/generate.sh
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
go run cmd/genxdr/main.go -- bench_test.go > bench_xdr_test.go
|
||||
go run cmd/genxdr/main.go -- encdec_test.go > encdec_xdr_test.go
|
123
vendor/github.com/calmh/xdr/marshaller.go
generated
vendored
Normal file
123
vendor/github.com/calmh/xdr/marshaller.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
||||
// is governed by an MIT-style license that can be found in the LICENSE file.
|
||||
|
||||
package xdr
|
||||
|
||||
import "io"
|
||||
|
||||
// The Marshaller is a thin wrapper around a byte buffer. The buffer must be
|
||||
// of sufficient size to hold the complete marshalled object, or an
|
||||
// io.ErrShortBuffer error will result. The Marshal... methods don't
|
||||
// individually return an error - the intention is that multiple fields are
|
||||
// marshalled in rapid succession, followed by a check of the Error field on
|
||||
// the Marshaller.
|
||||
type Marshaller struct {
|
||||
Data []byte
|
||||
Error error
|
||||
|
||||
offset int
|
||||
}
|
||||
|
||||
// MarshalRaw copies the raw bytes to the buffer, without a size prefix or
|
||||
// padding. This is suitable for appending data already in XDR format from
|
||||
// another source.
|
||||
func (m *Marshaller) MarshalRaw(bs []byte) {
|
||||
if m.Error != nil {
|
||||
return
|
||||
}
|
||||
if len(m.Data) < m.offset+len(bs) {
|
||||
m.Error = io.ErrShortBuffer
|
||||
return
|
||||
}
|
||||
|
||||
m.offset += copy(m.Data[m.offset:], bs)
|
||||
}
|
||||
|
||||
// MarshalString appends the string to the buffer, with a size prefix and
|
||||
// correct padding.
|
||||
func (m *Marshaller) MarshalString(s string) {
|
||||
if m.Error != nil {
|
||||
return
|
||||
}
|
||||
if len(m.Data) < m.offset+4+len(s)+Padding(len(s)) {
|
||||
m.Error = io.ErrShortBuffer
|
||||
return
|
||||
}
|
||||
|
||||
m.MarshalUint32(uint32(len(s)))
|
||||
m.offset += copy(m.Data[m.offset:], s)
|
||||
m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(s))])
|
||||
}
|
||||
|
||||
// MarshalString appends the bytes to the buffer, with a size prefix and
|
||||
// correct padding.
|
||||
func (m *Marshaller) MarshalBytes(bs []byte) {
|
||||
if m.Error != nil {
|
||||
return
|
||||
}
|
||||
if len(m.Data) < m.offset+4+len(bs)+Padding(len(bs)) {
|
||||
m.Error = io.ErrShortBuffer
|
||||
return
|
||||
}
|
||||
|
||||
m.MarshalUint32(uint32(len(bs)))
|
||||
m.offset += copy(m.Data[m.offset:], bs)
|
||||
m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(bs))])
|
||||
}
|
||||
|
||||
// MarshalString appends the bool to the buffer, as an uint32.
|
||||
func (m *Marshaller) MarshalBool(v bool) {
|
||||
if v {
|
||||
m.MarshalUint8(1)
|
||||
} else {
|
||||
m.MarshalUint8(0)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalString appends the uint8 to the buffer, as an uint32.
|
||||
func (m *Marshaller) MarshalUint8(v uint8) {
|
||||
m.MarshalUint32(uint32(v))
|
||||
}
|
||||
|
||||
// MarshalString appends the uint16 to the buffer, as an uint32.
|
||||
func (m *Marshaller) MarshalUint16(v uint16) {
|
||||
m.MarshalUint32(uint32(v))
|
||||
}
|
||||
|
||||
// MarshalString appends the uint32 to the buffer.
|
||||
func (m *Marshaller) MarshalUint32(v uint32) {
|
||||
if m.Error != nil {
|
||||
return
|
||||
}
|
||||
if len(m.Data) < m.offset+4 {
|
||||
m.Error = io.ErrShortBuffer
|
||||
return
|
||||
}
|
||||
|
||||
m.Data[m.offset+0] = byte(v >> 24)
|
||||
m.Data[m.offset+1] = byte(v >> 16)
|
||||
m.Data[m.offset+2] = byte(v >> 8)
|
||||
m.Data[m.offset+3] = byte(v)
|
||||
m.offset += 4
|
||||
}
|
||||
|
||||
// MarshalString appends the uint64 to the buffer.
|
||||
func (m *Marshaller) MarshalUint64(v uint64) {
|
||||
if m.Error != nil {
|
||||
return
|
||||
}
|
||||
if len(m.Data) < m.offset+8 {
|
||||
m.Error = io.ErrShortBuffer
|
||||
return
|
||||
}
|
||||
|
||||
m.Data[m.offset+0] = byte(v >> 56)
|
||||
m.Data[m.offset+1] = byte(v >> 48)
|
||||
m.Data[m.offset+2] = byte(v >> 40)
|
||||
m.Data[m.offset+3] = byte(v >> 32)
|
||||
m.Data[m.offset+4] = byte(v >> 24)
|
||||
m.Data[m.offset+5] = byte(v >> 16)
|
||||
m.Data[m.offset+6] = byte(v >> 8)
|
||||
m.Data[m.offset+7] = byte(v)
|
||||
m.offset += 8
|
||||
}
|
139
vendor/github.com/calmh/xdr/unmarshal.go
generated
vendored
Normal file
139
vendor/github.com/calmh/xdr/unmarshal.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xdr
|
||||
|
||||
import "io"
|
||||
|
||||
type Unmarshaller struct {
|
||||
Error error
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalRaw(l int) []byte {
|
||||
if u.Error != nil {
|
||||
return nil
|
||||
}
|
||||
if len(u.Data) < l {
|
||||
u.Error = io.ErrUnexpectedEOF
|
||||
return nil
|
||||
}
|
||||
|
||||
v := u.Data[:l]
|
||||
u.Data = u.Data[l:]
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalString() string {
|
||||
return u.UnmarshalStringMax(0)
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalStringMax(max int) string {
|
||||
buf := u.UnmarshalBytesMax(max)
|
||||
if len(buf) == 0 || u.Error != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalBytes() []byte {
|
||||
return u.UnmarshalBytesMax(0)
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalBytesMax(max int) []byte {
|
||||
if u.Error != nil {
|
||||
return nil
|
||||
}
|
||||
if len(u.Data) < 4 {
|
||||
u.Error = io.ErrUnexpectedEOF
|
||||
return nil
|
||||
}
|
||||
|
||||
l := int(u.Data[3]) | int(u.Data[2])<<8 | int(u.Data[1])<<16 | int(u.Data[0])<<24
|
||||
if l == 0 {
|
||||
u.Data = u.Data[4:]
|
||||
return nil
|
||||
}
|
||||
if l < 0 || max > 0 && l > max {
|
||||
// l may be negative on 32 bit builds
|
||||
u.Error = ElementSizeExceeded("bytes field", l, max)
|
||||
return nil
|
||||
}
|
||||
if len(u.Data) < l+4 {
|
||||
u.Error = io.ErrUnexpectedEOF
|
||||
return nil
|
||||
}
|
||||
|
||||
v := u.Data[4 : 4+l]
|
||||
u.Data = u.Data[4+l+Padding(l):]
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalBool() bool {
|
||||
return u.UnmarshalUint8() != 0
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalUint8() uint8 {
|
||||
if u.Error != nil {
|
||||
return 0
|
||||
}
|
||||
if len(u.Data) < 4 {
|
||||
u.Error = io.ErrUnexpectedEOF
|
||||
return 0
|
||||
}
|
||||
|
||||
v := uint8(u.Data[3])
|
||||
u.Data = u.Data[4:]
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalUint16() uint16 {
|
||||
if u.Error != nil {
|
||||
return 0
|
||||
}
|
||||
if len(u.Data) < 4 {
|
||||
u.Error = io.ErrUnexpectedEOF
|
||||
return 0
|
||||
}
|
||||
|
||||
v := uint16(u.Data[3]) | uint16(u.Data[2])<<8
|
||||
u.Data = u.Data[4:]
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalUint32() uint32 {
|
||||
if u.Error != nil {
|
||||
return 0
|
||||
}
|
||||
if len(u.Data) < 4 {
|
||||
u.Error = io.ErrUnexpectedEOF
|
||||
return 0
|
||||
}
|
||||
|
||||
v := uint32(u.Data[3]) | uint32(u.Data[2])<<8 | uint32(u.Data[1])<<16 | uint32(u.Data[0])<<24
|
||||
u.Data = u.Data[4:]
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (u *Unmarshaller) UnmarshalUint64() uint64 {
|
||||
if u.Error != nil {
|
||||
return 0
|
||||
}
|
||||
if len(u.Data) < 8 {
|
||||
u.Error = io.ErrUnexpectedEOF
|
||||
return 0
|
||||
}
|
||||
|
||||
v := uint64(u.Data[7]) | uint64(u.Data[6])<<8 | uint64(u.Data[5])<<16 | uint64(u.Data[4])<<24 |
|
||||
uint64(u.Data[3])<<32 | uint64(u.Data[2])<<40 | uint64(u.Data[1])<<48 | uint64(u.Data[0])<<56
|
||||
u.Data = u.Data[8:]
|
||||
|
||||
return v
|
||||
}
|
191
vendor/github.com/ccding/go-stun/LICENSE
generated
vendored
Normal file
191
vendor/github.com/ccding/go-stun/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
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:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
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
|
||||
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.
|
104
vendor/github.com/ccding/go-stun/stun/attribute.go
generated
vendored
Normal file
104
vendor/github.com/ccding/go-stun/stun/attribute.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"hash/crc32"
|
||||
"net"
|
||||
)
|
||||
|
||||
type attribute struct {
|
||||
types uint16
|
||||
length uint16
|
||||
value []byte
|
||||
}
|
||||
|
||||
func newAttribute(types uint16, value []byte) *attribute {
|
||||
att := new(attribute)
|
||||
att.types = types
|
||||
att.value = padding(value)
|
||||
att.length = uint16(len(att.value))
|
||||
return att
|
||||
}
|
||||
|
||||
func newFingerprintAttribute(packet *packet) *attribute {
|
||||
crc := crc32.ChecksumIEEE(packet.bytes()) ^ fingerprint
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(buf, crc)
|
||||
return newAttribute(attributeFingerprint, buf)
|
||||
}
|
||||
|
||||
func newSoftwareAttribute(name string) *attribute {
|
||||
return newAttribute(attributeSoftware, []byte(name))
|
||||
}
|
||||
|
||||
func newChangeReqAttribute(changeIP bool, changePort bool) *attribute {
|
||||
value := make([]byte, 4)
|
||||
if changeIP {
|
||||
value[3] |= 0x04
|
||||
}
|
||||
if changePort {
|
||||
value[3] |= 0x02
|
||||
}
|
||||
return newAttribute(attributeChangeRequest, value)
|
||||
}
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |x x x x x x x x| Family | X-Port |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | X-Address (Variable)
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// Figure 6: Format of XOR-MAPPED-ADDRESS Attribute
|
||||
func (v *attribute) xorAddr(transID []byte) *Host {
|
||||
xorIP := make([]byte, 16)
|
||||
for i := 0; i < len(v.value)-4; i++ {
|
||||
xorIP[i] = v.value[i+4] ^ transID[i]
|
||||
}
|
||||
family := uint16(v.value[1])
|
||||
port := binary.BigEndian.Uint16(v.value[2:4])
|
||||
// Truncate if IPv4, otherwise net.IP sometimes renders it as an IPv6 address.
|
||||
if family == attributeFamilyIPv4 {
|
||||
xorIP = xorIP[:4]
|
||||
}
|
||||
x := binary.BigEndian.Uint16(transID[:2])
|
||||
return &Host{family, net.IP(xorIP).String(), port ^ x}
|
||||
}
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// |0 0 0 0 0 0 0 0| Family | Port |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// | Address (32 bits or 128 bits) |
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// Figure 5: Format of MAPPED-ADDRESS Attribute
|
||||
func (v *attribute) rawAddr() *Host {
|
||||
host := new(Host)
|
||||
host.family = uint16(v.value[1])
|
||||
host.port = binary.BigEndian.Uint16(v.value[2:4])
|
||||
// Truncate if IPv4, otherwise net.IP sometimes renders it as an IPv6 address.
|
||||
if host.family == attributeFamilyIPv4 {
|
||||
v.value = v.value[:8]
|
||||
}
|
||||
host.ip = net.IP(v.value[4:]).String()
|
||||
return host
|
||||
}
|
145
vendor/github.com/ccding/go-stun/stun/client.go
generated
vendored
Normal file
145
vendor/github.com/ccding/go-stun/stun/client.go
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Client is a STUN client, which can be set STUN server address and is used
|
||||
// to discover NAT type.
|
||||
type Client struct {
|
||||
serverAddr string
|
||||
softwareName string
|
||||
conn net.PacketConn
|
||||
logger *Logger
|
||||
}
|
||||
|
||||
// NewClient returns a client without network connection. The network
|
||||
// connection will be build when calling Discover function.
|
||||
func NewClient() *Client {
|
||||
c := new(Client)
|
||||
c.SetSoftwareName(DefaultSoftwareName)
|
||||
c.logger = NewLogger()
|
||||
return c
|
||||
}
|
||||
|
||||
// NewClientWithConnection returns a client which uses the given connection.
|
||||
// Please note the connection should be acquired via net.Listen* method.
|
||||
func NewClientWithConnection(conn net.PacketConn) *Client {
|
||||
c := new(Client)
|
||||
c.conn = conn
|
||||
c.SetSoftwareName(DefaultSoftwareName)
|
||||
c.logger = NewLogger()
|
||||
return c
|
||||
}
|
||||
|
||||
// SetVerbose sets the client to be in the verbose mode, which prints
|
||||
// information in the discover process.
|
||||
func (c *Client) SetVerbose(v bool) {
|
||||
c.logger.SetDebug(v)
|
||||
}
|
||||
|
||||
// SetVVerbose sets the client to be in the double verbose mode, which prints
|
||||
// information and packet in the discover process.
|
||||
func (c *Client) SetVVerbose(v bool) {
|
||||
c.logger.SetInfo(v)
|
||||
}
|
||||
|
||||
// SetServerHost allows user to set the STUN hostname and port.
|
||||
func (c *Client) SetServerHost(host string, port int) {
|
||||
c.serverAddr = net.JoinHostPort(host, strconv.Itoa(port))
|
||||
}
|
||||
|
||||
// SetServerAddr allows user to set the transport layer STUN server address.
|
||||
func (c *Client) SetServerAddr(address string) {
|
||||
c.serverAddr = address
|
||||
}
|
||||
|
||||
// SetSoftwareName allows user to set the name of the software, which is used
|
||||
// for logging purpose (NOT used in the current implementation).
|
||||
func (c *Client) SetSoftwareName(name string) {
|
||||
c.softwareName = name
|
||||
}
|
||||
|
||||
// Discover contacts the STUN server and gets the response of NAT type, host
|
||||
// for UDP punching.
|
||||
func (c *Client) Discover() (NATType, *Host, error) {
|
||||
if c.serverAddr == "" {
|
||||
c.SetServerAddr(DefaultServerAddr)
|
||||
}
|
||||
serverUDPAddr, err := net.ResolveUDPAddr("udp", c.serverAddr)
|
||||
if err != nil {
|
||||
return NATError, nil, err
|
||||
}
|
||||
// Use the connection passed to the client if it is not nil, otherwise
|
||||
// create a connection and close it at the end.
|
||||
conn := c.conn
|
||||
if conn == nil {
|
||||
conn, err = net.ListenUDP("udp", nil)
|
||||
if err != nil {
|
||||
return NATError, nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
}
|
||||
return c.discover(conn, serverUDPAddr)
|
||||
}
|
||||
|
||||
func (c *Client) BehaviorTest() (*NATBehavior, error) {
|
||||
if c.serverAddr == "" {
|
||||
c.SetServerAddr(DefaultServerAddr)
|
||||
}
|
||||
serverUDPAddr, err := net.ResolveUDPAddr("udp", c.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Use the connection passed to the client if it is not nil, otherwise
|
||||
// create a connection and close it at the end.
|
||||
conn := c.conn
|
||||
if conn == nil {
|
||||
conn, err = net.ListenUDP("udp", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
}
|
||||
return c.behaviorTest(conn, serverUDPAddr)
|
||||
}
|
||||
|
||||
// Keepalive sends and receives a bind request, which ensures the mapping stays open
|
||||
// Only applicable when client was created with a connection.
|
||||
func (c *Client) Keepalive() (*Host, error) {
|
||||
if c.conn == nil {
|
||||
return nil, errors.New("no connection available")
|
||||
}
|
||||
if c.serverAddr == "" {
|
||||
c.SetServerAddr(DefaultServerAddr)
|
||||
}
|
||||
serverUDPAddr, err := net.ResolveUDPAddr("udp", c.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.test1(c.conn, serverUDPAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp == nil || resp.packet == nil {
|
||||
return nil, errors.New("failed to contact")
|
||||
}
|
||||
return resp.mappedAddr, nil
|
||||
}
|
222
vendor/github.com/ccding/go-stun/stun/const.go
generated
vendored
Normal file
222
vendor/github.com/ccding/go-stun/stun/const.go
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
// Default server address and client name.
|
||||
const (
|
||||
DefaultServerAddr = "stun.ekiga.net:3478"
|
||||
DefaultSoftwareName = "StunClient"
|
||||
)
|
||||
|
||||
const (
|
||||
magicCookie = 0x2112A442
|
||||
fingerprint = 0x5354554e
|
||||
)
|
||||
|
||||
// NATType is the type of NAT described by int.
|
||||
type NATType int
|
||||
|
||||
// NAT behavior type
|
||||
type BehaviorType int
|
||||
|
||||
type NATBehavior struct {
|
||||
MappingType BehaviorType
|
||||
FilteringType BehaviorType
|
||||
}
|
||||
|
||||
// NAT types.
|
||||
const (
|
||||
NATError NATType = iota
|
||||
NATUnknown
|
||||
NATNone
|
||||
NATBlocked
|
||||
NATFull
|
||||
NATSymmetric
|
||||
NATRestricted
|
||||
NATPortRestricted
|
||||
SymmetricUDPFirewall
|
||||
|
||||
// Deprecated spellings of these constants
|
||||
NATSymetric = NATSymmetric
|
||||
NATSymetricUDPFirewall = SymmetricUDPFirewall
|
||||
NATSymmetricUDPFirewall = SymmetricUDPFirewall
|
||||
)
|
||||
|
||||
const (
|
||||
BehaviorTypeUnknown BehaviorType = iota
|
||||
BehaviorTypeEndpoint
|
||||
BehaviorTypeAddr
|
||||
BehaviorTypeAddrAndPort
|
||||
)
|
||||
|
||||
var natStr map[NATType]string
|
||||
var natBehaviorTypeStr map[BehaviorType]string
|
||||
var natNormalTypeStr map[NATBehavior]string
|
||||
|
||||
func init() {
|
||||
natStr = map[NATType]string{
|
||||
NATError: "Test failed",
|
||||
NATUnknown: "Unexpected response from the STUN server",
|
||||
NATBlocked: "UDP is blocked",
|
||||
NATFull: "Full cone NAT",
|
||||
NATSymmetric: "Symmetric NAT",
|
||||
NATRestricted: "Restricted NAT",
|
||||
NATPortRestricted: "Port restricted NAT",
|
||||
NATNone: "Not behind a NAT",
|
||||
SymmetricUDPFirewall: "Symmetric UDP firewall",
|
||||
}
|
||||
|
||||
natBehaviorTypeStr = map[BehaviorType]string{
|
||||
BehaviorTypeEndpoint: "EndpointIndependent",
|
||||
BehaviorTypeAddr: "AddressDependent",
|
||||
BehaviorTypeAddrAndPort: "AddressAndPortDependent",
|
||||
}
|
||||
|
||||
// Defined in RFC 3489
|
||||
natNormalTypeStr = map[NATBehavior]string{
|
||||
NATBehavior{BehaviorTypeEndpoint, BehaviorTypeEndpoint}: "Full cone NAT",
|
||||
NATBehavior{BehaviorTypeEndpoint, BehaviorTypeAddr}: "Restricted cone NAT",
|
||||
NATBehavior{BehaviorTypeEndpoint, BehaviorTypeAddrAndPort}: "Port Restricted cone NAT",
|
||||
NATBehavior{BehaviorTypeAddrAndPort, BehaviorTypeAddrAndPort}: "Symmetric NAT",
|
||||
}
|
||||
}
|
||||
|
||||
func (nat NATType) String() string {
|
||||
if s, ok := natStr[nat]; ok {
|
||||
return s
|
||||
}
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
func (natBhType BehaviorType) String() string {
|
||||
if s, ok := natBehaviorTypeStr[natBhType]; ok {
|
||||
return s
|
||||
}
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
func (natBehavior NATBehavior) NormalType() string {
|
||||
if s, ok := natNormalTypeStr[natBehavior]; ok {
|
||||
return s
|
||||
}
|
||||
return "Undefined"
|
||||
}
|
||||
|
||||
const (
|
||||
errorTryAlternate = 300
|
||||
errorBadRequest = 400
|
||||
errorUnauthorized = 401
|
||||
errorUnassigned402 = 402
|
||||
errorForbidden = 403
|
||||
errorUnknownAttribute = 420
|
||||
errorAllocationMismatch = 437
|
||||
errorStaleNonce = 438
|
||||
errorUnassigned439 = 439
|
||||
errorAddressFamilyNotSupported = 440
|
||||
errorWrongCredentials = 441
|
||||
errorUnsupportedTransportProtocol = 442
|
||||
errorPeerAddressFamilyMismatch = 443
|
||||
errorConnectionAlreadyExists = 446
|
||||
errorConnectionTimeoutOrFailure = 447
|
||||
errorAllocationQuotaReached = 486
|
||||
errorRoleConflict = 487
|
||||
errorServerError = 500
|
||||
errorInsufficientCapacity = 508
|
||||
)
|
||||
const (
|
||||
attributeFamilyIPv4 = 0x01
|
||||
attributeFamilyIPV6 = 0x02
|
||||
)
|
||||
|
||||
const (
|
||||
attributeMappedAddress = 0x0001
|
||||
attributeResponseAddress = 0x0002
|
||||
attributeChangeRequest = 0x0003
|
||||
attributeSourceAddress = 0x0004
|
||||
attributeChangedAddress = 0x0005
|
||||
attributeUsername = 0x0006
|
||||
attributePassword = 0x0007
|
||||
attributeMessageIntegrity = 0x0008
|
||||
attributeErrorCode = 0x0009
|
||||
attributeUnknownAttributes = 0x000a
|
||||
attributeReflectedFrom = 0x000b
|
||||
attributeChannelNumber = 0x000c
|
||||
attributeLifetime = 0x000d
|
||||
attributeBandwidth = 0x0010
|
||||
attributeXorPeerAddress = 0x0012
|
||||
attributeData = 0x0013
|
||||
attributeRealm = 0x0014
|
||||
attributeNonce = 0x0015
|
||||
attributeXorRelayedAddress = 0x0016
|
||||
attributeRequestedAddressFamily = 0x0017
|
||||
attributeEvenPort = 0x0018
|
||||
attributeRequestedTransport = 0x0019
|
||||
attributeDontFragment = 0x001a
|
||||
attributeXorMappedAddress = 0x0020
|
||||
attributeTimerVal = 0x0021
|
||||
attributeReservationToken = 0x0022
|
||||
attributePriority = 0x0024
|
||||
attributeUseCandidate = 0x0025
|
||||
attributePadding = 0x0026
|
||||
attributeResponsePort = 0x0027
|
||||
attributeConnectionID = 0x002a
|
||||
attributeXorMappedAddressExp = 0x8020
|
||||
attributeSoftware = 0x8022
|
||||
attributeAlternateServer = 0x8023
|
||||
attributeCacheTimeout = 0x8027
|
||||
attributeFingerprint = 0x8028
|
||||
attributeIceControlled = 0x8029
|
||||
attributeIceControlling = 0x802a
|
||||
attributeResponseOrigin = 0x802b
|
||||
attributeOtherAddress = 0x802c
|
||||
attributeEcnCheckStun = 0x802d
|
||||
attributeCiscoFlowdata = 0xc000
|
||||
)
|
||||
|
||||
const (
|
||||
typeBindingRequest = 0x0001
|
||||
typeBindingResponse = 0x0101
|
||||
typeBindingErrorResponse = 0x0111
|
||||
typeSharedSecretRequest = 0x0002
|
||||
typeSharedSecretResponse = 0x0102
|
||||
typeSharedErrorResponse = 0x0112
|
||||
typeAllocate = 0x0003
|
||||
typeAllocateResponse = 0x0103
|
||||
typeAllocateErrorResponse = 0x0113
|
||||
typeRefresh = 0x0004
|
||||
typeRefreshResponse = 0x0104
|
||||
typeRefreshErrorResponse = 0x0114
|
||||
typeSend = 0x0006
|
||||
typeSendResponse = 0x0106
|
||||
typeSendErrorResponse = 0x0116
|
||||
typeData = 0x0007
|
||||
typeDataResponse = 0x0107
|
||||
typeDataErrorResponse = 0x0117
|
||||
typeCreatePermisiion = 0x0008
|
||||
typeCreatePermisiionResponse = 0x0108
|
||||
typeCreatePermisiionErrorResponse = 0x0118
|
||||
typeChannelBinding = 0x0009
|
||||
typeChannelBindingResponse = 0x0109
|
||||
typeChannelBindingErrorResponse = 0x0119
|
||||
typeConnect = 0x000a
|
||||
typeConnectResponse = 0x010a
|
||||
typeConnectErrorResponse = 0x011a
|
||||
typeConnectionBind = 0x000b
|
||||
typeConnectionBindResponse = 0x010b
|
||||
typeConnectionBindErrorResponse = 0x011b
|
||||
typeConnectionAttempt = 0x000c
|
||||
typeConnectionAttemptResponse = 0x010c
|
||||
typeConnectionAttemptErrorResponse = 0x011c
|
||||
)
|
253
vendor/github.com/ccding/go-stun/stun/discover.go
generated
vendored
Normal file
253
vendor/github.com/ccding/go-stun/stun/discover.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
// Follow RFC 3489 and RFC 5389.
|
||||
// Figure 2: Flow for type discovery process (from RFC 3489).
|
||||
// +--------+
|
||||
// | Test |
|
||||
// | I |
|
||||
// +--------+
|
||||
// |
|
||||
// |
|
||||
// V
|
||||
// /\ /\
|
||||
// N / \ Y / \ Y +--------+
|
||||
// UDP <-------/Resp\--------->/ IP \------------->| Test |
|
||||
// Blocked \ ? / \Same/ | II |
|
||||
// \ / \? / +--------+
|
||||
// \/ \/ |
|
||||
// | N |
|
||||
// | V
|
||||
// V /\
|
||||
// +--------+ Sym. N / \
|
||||
// | Test | UDP <---/Resp\
|
||||
// | II | Firewall \ ? /
|
||||
// +--------+ \ /
|
||||
// | \/
|
||||
// V |Y
|
||||
// /\ /\ |
|
||||
// Symmetric N / \ +--------+ N / \ V
|
||||
// NAT <--- / IP \<-----| Test |<--- /Resp\ Open
|
||||
// \Same/ | I | \ ? / Internet
|
||||
// \? / +--------+ \ /
|
||||
// \/ \/
|
||||
// |Y |Y
|
||||
// | |
|
||||
// | V
|
||||
// | Full
|
||||
// | Cone
|
||||
// V /\
|
||||
// +--------+ / \ Y
|
||||
// | Test |------>/Resp\---->Restricted
|
||||
// | III | \ ? /
|
||||
// +--------+ \ /
|
||||
// \/
|
||||
// |N
|
||||
// | Port
|
||||
// +------>Restricted
|
||||
func (c *Client) discover(conn net.PacketConn, addr *net.UDPAddr) (NATType, *Host, error) {
|
||||
// Perform test1 to check if it is under NAT.
|
||||
c.logger.Debugln("Do Test1")
|
||||
c.logger.Debugln("Send To:", addr)
|
||||
resp, err := c.test1(conn, addr)
|
||||
if err != nil {
|
||||
return NATError, nil, err
|
||||
}
|
||||
c.logger.Debugln("Received:", resp)
|
||||
if resp == nil {
|
||||
return NATBlocked, nil, nil
|
||||
}
|
||||
// identical used to check if it is open Internet or not.
|
||||
identical := resp.identical
|
||||
// changedAddr is used to perform second time test1 and test3.
|
||||
changedAddr := resp.changedAddr
|
||||
// mappedAddr is used as the return value, its IP is used for tests
|
||||
mappedAddr := resp.mappedAddr
|
||||
// Make sure IP and port are not changed.
|
||||
if resp.serverAddr.IP() != addr.IP.String() ||
|
||||
resp.serverAddr.Port() != uint16(addr.Port) {
|
||||
return NATError, mappedAddr, errors.New("Server error: response IP/port")
|
||||
}
|
||||
// if changedAddr is not available, use otherAddr as changedAddr,
|
||||
// which is updated in RFC 5780
|
||||
if changedAddr == nil {
|
||||
changedAddr = resp.otherAddr
|
||||
}
|
||||
// changedAddr shall not be nil
|
||||
if changedAddr == nil {
|
||||
return NATError, mappedAddr, errors.New("Server error: no changed address.")
|
||||
}
|
||||
// Perform test2 to see if the client can receive packet sent from
|
||||
// another IP and port.
|
||||
c.logger.Debugln("Do Test2")
|
||||
c.logger.Debugln("Send To:", addr)
|
||||
resp, err = c.test2(conn, addr)
|
||||
if err != nil {
|
||||
return NATError, mappedAddr, err
|
||||
}
|
||||
c.logger.Debugln("Received:", resp)
|
||||
// Make sure IP and port are changed.
|
||||
if resp != nil &&
|
||||
(resp.serverAddr.IP() == addr.IP.String() ||
|
||||
resp.serverAddr.Port() == uint16(addr.Port)) {
|
||||
return NATError, mappedAddr, errors.New("Server error: response IP/port")
|
||||
}
|
||||
if identical {
|
||||
if resp == nil {
|
||||
return SymmetricUDPFirewall, mappedAddr, nil
|
||||
}
|
||||
return NATNone, mappedAddr, nil
|
||||
}
|
||||
if resp != nil {
|
||||
return NATFull, mappedAddr, nil
|
||||
}
|
||||
// Perform test1 to another IP and port to see if the NAT use the same
|
||||
// external IP.
|
||||
c.logger.Debugln("Do Test1")
|
||||
c.logger.Debugln("Send To:", changedAddr)
|
||||
caddr, err := net.ResolveUDPAddr("udp", changedAddr.String())
|
||||
if err != nil {
|
||||
c.logger.Debugf("ResolveUDPAddr error: %v", err)
|
||||
}
|
||||
resp, err = c.test1(conn, caddr)
|
||||
if err != nil {
|
||||
return NATError, mappedAddr, err
|
||||
}
|
||||
c.logger.Debugln("Received:", resp)
|
||||
if resp == nil {
|
||||
// It should be NAT_BLOCKED, but will be detected in the first
|
||||
// step. So this will never happen.
|
||||
return NATUnknown, mappedAddr, nil
|
||||
}
|
||||
// Make sure IP/port is not changed.
|
||||
if resp.serverAddr.IP() != caddr.IP.String() ||
|
||||
resp.serverAddr.Port() != uint16(caddr.Port) {
|
||||
return NATError, mappedAddr, errors.New("Server error: response IP/port")
|
||||
}
|
||||
if mappedAddr.IP() == resp.mappedAddr.IP() && mappedAddr.Port() == resp.mappedAddr.Port() {
|
||||
// Perform test3 to see if the client can receive packet sent
|
||||
// from another port.
|
||||
c.logger.Debugln("Do Test3")
|
||||
c.logger.Debugln("Send To:", caddr)
|
||||
resp, err = c.test3(conn, caddr)
|
||||
if err != nil {
|
||||
return NATError, mappedAddr, err
|
||||
}
|
||||
c.logger.Debugln("Received:", resp)
|
||||
if resp == nil {
|
||||
return NATPortRestricted, mappedAddr, nil
|
||||
}
|
||||
// Make sure IP is not changed, and port is changed.
|
||||
if resp.serverAddr.IP() != caddr.IP.String() ||
|
||||
resp.serverAddr.Port() == uint16(caddr.Port) {
|
||||
return NATError, mappedAddr, errors.New("Server error: response IP/port")
|
||||
}
|
||||
return NATRestricted, mappedAddr, nil
|
||||
}
|
||||
return NATSymmetric, mappedAddr, nil
|
||||
}
|
||||
|
||||
func (c *Client) behaviorTest(conn net.PacketConn, addr *net.UDPAddr) (*NATBehavior, error) {
|
||||
natBehavior := &NATBehavior{}
|
||||
|
||||
// Test1 ->(IP1,port1)
|
||||
// Perform test to check if it is under NAT.
|
||||
c.logger.Debugln("Do Test1")
|
||||
resp1, err := c.test(conn, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// identical used to check if it is open Internet or not.
|
||||
if resp1.identical {
|
||||
return nil, errors.New("Not behind a NAT.")
|
||||
}
|
||||
// use otherAddr or changedAddr
|
||||
otherAddr := resp1.otherAddr
|
||||
if otherAddr == nil {
|
||||
if resp1.changedAddr != nil {
|
||||
otherAddr = resp1.changedAddr
|
||||
} else {
|
||||
return nil, errors.New("Server error: no other address and changed address.")
|
||||
}
|
||||
}
|
||||
|
||||
// Test2 ->(IP2,port1)
|
||||
// Perform test to see if mapping to the same IP and port when
|
||||
// send to another IP.
|
||||
c.logger.Debugln("Do Test2")
|
||||
tmpAddr := &net.UDPAddr{IP: net.ParseIP(otherAddr.IP()), Port: addr.Port}
|
||||
resp2, err := c.test(conn, tmpAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp2.mappedAddr.IP() == resp1.mappedAddr.IP() &&
|
||||
resp2.mappedAddr.Port() == resp1.mappedAddr.Port() {
|
||||
natBehavior.MappingType = BehaviorTypeEndpoint
|
||||
}
|
||||
|
||||
// Test3 ->(IP2,port2)
|
||||
// Perform test to see if mapping to the same IP and port when
|
||||
// send to another port.
|
||||
if natBehavior.MappingType == BehaviorTypeUnknown {
|
||||
c.logger.Debugln("Do Test3")
|
||||
tmpAddr.Port = int(otherAddr.Port())
|
||||
resp3, err := c.test(conn, tmpAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp3.mappedAddr.IP() == resp2.mappedAddr.IP() &&
|
||||
resp3.mappedAddr.Port() == resp2.mappedAddr.Port() {
|
||||
natBehavior.MappingType = BehaviorTypeAddr
|
||||
} else {
|
||||
natBehavior.MappingType = BehaviorTypeAddrAndPort
|
||||
}
|
||||
}
|
||||
|
||||
// Test4 ->(IP1,port1) (IP2,port2)->
|
||||
// Perform test to see if the client can receive packet sent from
|
||||
// another IP and port.
|
||||
c.logger.Debugln("Do Test4")
|
||||
resp4, err := c.testChangeBoth(conn, addr)
|
||||
if err != nil {
|
||||
return natBehavior, err
|
||||
}
|
||||
if resp4 != nil {
|
||||
natBehavior.FilteringType = BehaviorTypeEndpoint
|
||||
}
|
||||
|
||||
// Test5 ->(IP1,port1) (IP1,port2)->
|
||||
// Perform test to see if the client can receive packet sent from
|
||||
// another port.
|
||||
if natBehavior.FilteringType == BehaviorTypeUnknown {
|
||||
c.logger.Debugln("Do Test5")
|
||||
resp5, err := c.testChangePort(conn, addr)
|
||||
if err != nil {
|
||||
return natBehavior, err
|
||||
}
|
||||
if resp5 != nil {
|
||||
natBehavior.FilteringType = BehaviorTypeAddr
|
||||
} else {
|
||||
natBehavior.FilteringType = BehaviorTypeAddrAndPort
|
||||
}
|
||||
}
|
||||
|
||||
return natBehavior, nil
|
||||
}
|
23
vendor/github.com/ccding/go-stun/stun/doc.go
generated
vendored
Normal file
23
vendor/github.com/ccding/go-stun/stun/doc.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun is a STUN (RFC 3489 and RFC 5389) client implementation in
|
||||
// golang.
|
||||
//
|
||||
// It is extremely easy to use -- just one line of code.
|
||||
//
|
||||
// nat, host, err := stun.NewClient().Discover()
|
||||
//
|
||||
// More details please go to `main.go`.
|
||||
package stun
|
68
vendor/github.com/ccding/go-stun/stun/host.go
generated
vendored
Normal file
68
vendor/github.com/ccding/go-stun/stun/host.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Host defines the network address including address family, IP address and port.
|
||||
type Host struct {
|
||||
family uint16
|
||||
ip string
|
||||
port uint16
|
||||
}
|
||||
|
||||
func newHostFromStr(s string) *Host {
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", s)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
host := new(Host)
|
||||
if udpAddr.IP.To4() != nil {
|
||||
host.family = attributeFamilyIPv4
|
||||
} else {
|
||||
host.family = attributeFamilyIPV6
|
||||
}
|
||||
host.ip = udpAddr.IP.String()
|
||||
host.port = uint16(udpAddr.Port)
|
||||
return host
|
||||
}
|
||||
|
||||
// Family returns the family type of a host (IPv4 or IPv6).
|
||||
func (h *Host) Family() uint16 {
|
||||
return h.family
|
||||
}
|
||||
|
||||
// IP returns the internet protocol address of the host.
|
||||
func (h *Host) IP() string {
|
||||
return h.ip
|
||||
}
|
||||
|
||||
// Port returns the port number of the host.
|
||||
func (h *Host) Port() uint16 {
|
||||
return h.port
|
||||
}
|
||||
|
||||
// TransportAddr returns the transport layer address of the host.
|
||||
func (h *Host) TransportAddr() string {
|
||||
return net.JoinHostPort(h.ip, strconv.Itoa(int(h.port)))
|
||||
}
|
||||
|
||||
// String returns the string representation of the host address.
|
||||
func (h *Host) String() string {
|
||||
return h.TransportAddr()
|
||||
}
|
85
vendor/github.com/ccding/go-stun/stun/log.go
generated
vendored
Normal file
85
vendor/github.com/ccding/go-stun/stun/log.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Logger is a simple logger specified for this STUN client.
|
||||
type Logger struct {
|
||||
log.Logger
|
||||
debug bool
|
||||
info bool
|
||||
}
|
||||
|
||||
// NewLogger creates a default logger.
|
||||
func NewLogger() *Logger {
|
||||
logger := &Logger{*log.New(os.Stdout, "", log.LstdFlags), false, false}
|
||||
return logger
|
||||
}
|
||||
|
||||
// SetDebug sets the logger running in debug mode or not.
|
||||
func (l *Logger) SetDebug(v bool) {
|
||||
l.debug = v
|
||||
}
|
||||
|
||||
// SetInfo sets the logger running in info mode or not.
|
||||
func (l *Logger) SetInfo(v bool) {
|
||||
l.info = v
|
||||
}
|
||||
|
||||
// Debug outputs the log in the format of log.Print.
|
||||
func (l *Logger) Debug(v ...interface{}) {
|
||||
if l.debug {
|
||||
l.Print(v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Debugf outputs the log in the format of log.Printf.
|
||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||
if l.debug {
|
||||
l.Printf(format, v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Debugln outputs the log in the format of log.Println.
|
||||
func (l *Logger) Debugln(v ...interface{}) {
|
||||
if l.debug {
|
||||
l.Println(v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Info outputs the log in the format of log.Print.
|
||||
func (l *Logger) Info(v ...interface{}) {
|
||||
if l.info {
|
||||
l.Print(v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Infof outputs the log in the format of log.Printf.
|
||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||
if l.info {
|
||||
l.Printf(format, v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Infoln outputs the log in the format of log.Println.
|
||||
func (l *Logger) Infoln(v ...interface{}) {
|
||||
if l.info {
|
||||
l.Println(v...)
|
||||
}
|
||||
}
|
104
vendor/github.com/ccding/go-stun/stun/net.go
generated
vendored
Normal file
104
vendor/github.com/ccding/go-stun/stun/net.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
numRetransmit = 9
|
||||
defaultTimeout = 100
|
||||
maxTimeout = 1600
|
||||
maxPacketSize = 1024
|
||||
)
|
||||
|
||||
func (c *Client) sendBindingReq(conn net.PacketConn, addr net.Addr, changeIP bool, changePort bool) (*response, error) {
|
||||
// Construct packet.
|
||||
pkt, err := newPacket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pkt.types = typeBindingRequest
|
||||
attribute := newSoftwareAttribute(c.softwareName)
|
||||
pkt.addAttribute(*attribute)
|
||||
if changeIP || changePort {
|
||||
attribute = newChangeReqAttribute(changeIP, changePort)
|
||||
pkt.addAttribute(*attribute)
|
||||
}
|
||||
// length of fingerprint attribute must be included into crc,
|
||||
// so we add it before calculating crc, then subtract it after calculating crc.
|
||||
pkt.length += 8
|
||||
attribute = newFingerprintAttribute(pkt)
|
||||
pkt.length -= 8
|
||||
pkt.addAttribute(*attribute)
|
||||
// Send packet.
|
||||
return c.send(pkt, conn, addr)
|
||||
}
|
||||
|
||||
// RFC 3489: Clients SHOULD retransmit the request starting with an interval
|
||||
// of 100ms, doubling every retransmit until the interval reaches 1.6s.
|
||||
// Retransmissions continue with intervals of 1.6s until a response is
|
||||
// received, or a total of 9 requests have been sent.
|
||||
func (c *Client) send(pkt *packet, conn net.PacketConn, addr net.Addr) (*response, error) {
|
||||
c.logger.Info("\n" + hex.Dump(pkt.bytes()))
|
||||
timeout := defaultTimeout
|
||||
packetBytes := make([]byte, maxPacketSize)
|
||||
for i := 0; i < numRetransmit; i++ {
|
||||
// Send packet to the server.
|
||||
length, err := conn.WriteTo(pkt.bytes(), addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if length != len(pkt.bytes()) {
|
||||
return nil, errors.New("Error in sending data.")
|
||||
}
|
||||
err = conn.SetReadDeadline(time.Now().Add(time.Duration(timeout) * time.Millisecond))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if timeout < maxTimeout {
|
||||
timeout *= 2
|
||||
}
|
||||
for {
|
||||
// Read from the port.
|
||||
length, raddr, err := conn.ReadFrom(packetBytes)
|
||||
if err != nil {
|
||||
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
p, err := newPacketFromBytes(packetBytes[0:length])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If transId mismatches, keep reading until get a
|
||||
// matched packet or timeout.
|
||||
if !bytes.Equal(pkt.transID, p.transID) {
|
||||
continue
|
||||
}
|
||||
c.logger.Info("\n" + hex.Dump(packetBytes[0:length]))
|
||||
resp := newResponse(p, conn)
|
||||
resp.serverAddr = newHostFromStr(raddr.String())
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
133
vendor/github.com/ccding/go-stun/stun/packet.go
generated
vendored
Normal file
133
vendor/github.com/ccding/go-stun/stun/packet.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
type packet struct {
|
||||
types uint16
|
||||
length uint16
|
||||
transID []byte // 4 bytes magic cookie + 12 bytes transaction id
|
||||
attributes []attribute
|
||||
}
|
||||
|
||||
func newPacket() (*packet, error) {
|
||||
v := new(packet)
|
||||
v.transID = make([]byte, 16)
|
||||
binary.BigEndian.PutUint32(v.transID[:4], magicCookie)
|
||||
_, err := rand.Read(v.transID[4:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v.attributes = make([]attribute, 0, 10)
|
||||
v.length = 0
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func newPacketFromBytes(packetBytes []byte) (*packet, error) {
|
||||
if len(packetBytes) < 20 {
|
||||
return nil, errors.New("Received data length too short.")
|
||||
}
|
||||
if len(packetBytes) > math.MaxUint16+20 {
|
||||
return nil, errors.New("Received data length too long.")
|
||||
}
|
||||
pkt := new(packet)
|
||||
pkt.types = binary.BigEndian.Uint16(packetBytes[0:2])
|
||||
pkt.length = binary.BigEndian.Uint16(packetBytes[2:4])
|
||||
pkt.transID = packetBytes[4:20]
|
||||
pkt.attributes = make([]attribute, 0, 10)
|
||||
packetBytes = packetBytes[20:]
|
||||
for pos := uint16(0); pos+4 < uint16(len(packetBytes)); {
|
||||
types := binary.BigEndian.Uint16(packetBytes[pos : pos+2])
|
||||
length := binary.BigEndian.Uint16(packetBytes[pos+2 : pos+4])
|
||||
end := pos + 4 + length
|
||||
if end < pos+4 || end > uint16(len(packetBytes)) {
|
||||
return nil, errors.New("Received data format mismatch.")
|
||||
}
|
||||
value := packetBytes[pos+4 : end]
|
||||
attribute := newAttribute(types, value)
|
||||
pkt.addAttribute(*attribute)
|
||||
pos += align(length) + 4
|
||||
}
|
||||
return pkt, nil
|
||||
}
|
||||
|
||||
func (v *packet) addAttribute(a attribute) {
|
||||
v.attributes = append(v.attributes, a)
|
||||
v.length += align(a.length) + 4
|
||||
}
|
||||
|
||||
func (v *packet) bytes() []byte {
|
||||
packetBytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint16(packetBytes[0:2], v.types)
|
||||
binary.BigEndian.PutUint16(packetBytes[2:4], v.length)
|
||||
packetBytes = append(packetBytes, v.transID...)
|
||||
for _, a := range v.attributes {
|
||||
buf := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(buf, a.types)
|
||||
packetBytes = append(packetBytes, buf...)
|
||||
binary.BigEndian.PutUint16(buf, a.length)
|
||||
packetBytes = append(packetBytes, buf...)
|
||||
packetBytes = append(packetBytes, a.value...)
|
||||
}
|
||||
return packetBytes
|
||||
}
|
||||
|
||||
func (v *packet) getSourceAddr() *Host {
|
||||
return v.getRawAddr(attributeSourceAddress)
|
||||
}
|
||||
|
||||
func (v *packet) getMappedAddr() *Host {
|
||||
return v.getRawAddr(attributeMappedAddress)
|
||||
}
|
||||
|
||||
func (v *packet) getChangedAddr() *Host {
|
||||
return v.getRawAddr(attributeChangedAddress)
|
||||
}
|
||||
|
||||
func (v *packet) getOtherAddr() *Host {
|
||||
return v.getRawAddr(attributeOtherAddress)
|
||||
}
|
||||
|
||||
func (v *packet) getRawAddr(attribute uint16) *Host {
|
||||
for _, a := range v.attributes {
|
||||
if a.types == attribute {
|
||||
return a.rawAddr()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *packet) getXorMappedAddr() *Host {
|
||||
addr := v.getXorAddr(attributeXorMappedAddress)
|
||||
if addr == nil {
|
||||
addr = v.getXorAddr(attributeXorMappedAddressExp)
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
func (v *packet) getXorAddr(attribute uint16) *Host {
|
||||
for _, a := range v.attributes {
|
||||
if a.types == attribute {
|
||||
return a.xorAddr(v.transID)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
76
vendor/github.com/ccding/go-stun/stun/response.go
generated
vendored
Normal file
76
vendor/github.com/ccding/go-stun/stun/response.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
type response struct {
|
||||
packet *packet // the original packet from the server
|
||||
serverAddr *Host // the address received packet
|
||||
changedAddr *Host // parsed from packet
|
||||
mappedAddr *Host // parsed from packet, external addr of client NAT
|
||||
otherAddr *Host // parsed from packet, to replace changedAddr in RFC 5780
|
||||
identical bool // if mappedAddr is in local addr list
|
||||
}
|
||||
|
||||
func newResponse(pkt *packet, conn net.PacketConn) *response {
|
||||
resp := &response{pkt, nil, nil, nil, nil, false}
|
||||
if pkt == nil {
|
||||
return resp
|
||||
}
|
||||
// RFC 3489 doesn't require the server return XOR mapped address.
|
||||
mappedAddr := pkt.getXorMappedAddr()
|
||||
if mappedAddr == nil {
|
||||
mappedAddr = pkt.getMappedAddr()
|
||||
}
|
||||
resp.mappedAddr = mappedAddr
|
||||
// compute identical
|
||||
localAddrStr := conn.LocalAddr().String()
|
||||
if mappedAddr != nil {
|
||||
mappedAddrStr := mappedAddr.String()
|
||||
resp.identical = isLocalAddress(localAddrStr, mappedAddrStr)
|
||||
}
|
||||
// compute changedAddr
|
||||
changedAddr := pkt.getChangedAddr()
|
||||
if changedAddr != nil {
|
||||
changedAddrHost := newHostFromStr(changedAddr.String())
|
||||
resp.changedAddr = changedAddrHost
|
||||
}
|
||||
// compute otherAddr
|
||||
otherAddr := pkt.getOtherAddr()
|
||||
if otherAddr != nil {
|
||||
otherAddrHost := newHostFromStr(otherAddr.String())
|
||||
resp.otherAddr = otherAddrHost
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// String is only used for verbose mode output.
|
||||
func (r *response) String() string {
|
||||
if r == nil {
|
||||
return "Nil"
|
||||
}
|
||||
return fmt.Sprintf("{packet nil: %v, local: %v, remote: %v, changed: %v, other: %v, identical: %v}",
|
||||
r.packet == nil,
|
||||
r.mappedAddr,
|
||||
r.serverAddr,
|
||||
r.changedAddr,
|
||||
r.otherAddr,
|
||||
r.identical)
|
||||
}
|
67
vendor/github.com/ccding/go-stun/stun/tests.go
generated
vendored
Normal file
67
vendor/github.com/ccding/go-stun/stun/tests.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
func (c *Client) sendWithLog(conn net.PacketConn, addr *net.UDPAddr, changeIP bool, changePort bool) (*response, error) {
|
||||
c.logger.Debugln("Send To:", addr)
|
||||
resp, err := c.sendBindingReq(conn, addr, changeIP, changePort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.logger.Debugln("Received:", resp)
|
||||
if resp == nil && changeIP == false && changePort == false {
|
||||
return nil, errors.New("NAT blocked.")
|
||||
}
|
||||
if resp != nil && !addrCompare(resp.serverAddr, addr, changeIP, changePort) {
|
||||
return nil, errors.New("Server error: response IP/port")
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Make sure IP and port have or haven't change
|
||||
func addrCompare(host *Host, addr *net.UDPAddr, IPChange, portChange bool) bool {
|
||||
isIPChange := host.IP() != addr.IP.String()
|
||||
isPortChange := host.Port() != uint16(addr.Port)
|
||||
return isIPChange == IPChange && isPortChange == portChange
|
||||
}
|
||||
|
||||
func (c *Client) test(conn net.PacketConn, addr *net.UDPAddr) (*response, error) {
|
||||
return c.sendWithLog(conn, addr, false, false)
|
||||
}
|
||||
|
||||
func (c *Client) testChangePort(conn net.PacketConn, addr *net.UDPAddr) (*response, error) {
|
||||
return c.sendWithLog(conn, addr, false, true)
|
||||
}
|
||||
|
||||
func (c *Client) testChangeBoth(conn net.PacketConn, addr *net.UDPAddr) (*response, error) {
|
||||
return c.sendWithLog(conn, addr, true, true)
|
||||
}
|
||||
|
||||
func (c *Client) test1(conn net.PacketConn, addr net.Addr) (*response, error) {
|
||||
return c.sendBindingReq(conn, addr, false, false)
|
||||
}
|
||||
|
||||
func (c *Client) test2(conn net.PacketConn, addr net.Addr) (*response, error) {
|
||||
return c.sendBindingReq(conn, addr, true, true)
|
||||
}
|
||||
|
||||
func (c *Client) test3(conn net.PacketConn, addr net.Addr) (*response, error) {
|
||||
return c.sendBindingReq(conn, addr, false, true)
|
||||
}
|
61
vendor/github.com/ccding/go-stun/stun/utils.go
generated
vendored
Normal file
61
vendor/github.com/ccding/go-stun/stun/utils.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2016 Cong Ding
|
||||
//
|
||||
// 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 stun
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// Padding the length of the byte slice to multiple of 4.
|
||||
func padding(bytes []byte) []byte {
|
||||
length := uint16(len(bytes))
|
||||
return append(bytes, make([]byte, align(length)-length)...)
|
||||
}
|
||||
|
||||
// Align the uint16 number to the smallest multiple of 4, which is larger than
|
||||
// or equal to the uint16 number.
|
||||
func align(n uint16) uint16 {
|
||||
return (n + 3) & 0xfffc
|
||||
}
|
||||
|
||||
// isLocalAddress check if localRemote is a local address.
|
||||
func isLocalAddress(local, localRemote string) bool {
|
||||
// Resolve the IP returned by the STUN server first.
|
||||
localRemoteAddr, err := net.ResolveUDPAddr("udp", localRemote)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// Try comparing with the local address on the socket first, but only if
|
||||
// it's actually specified.
|
||||
addr, err := net.ResolveUDPAddr("udp", local)
|
||||
if err == nil && addr.IP != nil && !addr.IP.IsUnspecified() {
|
||||
return addr.IP.Equal(localRemoteAddr.IP)
|
||||
}
|
||||
// Fallback to checking IPs of all interfaces
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
ip, _, err := net.ParseCIDR(addr.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ip.Equal(localRemoteAddr.IP) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
2
vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
2
vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
@@ -70,3 +70,5 @@ benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)
|
||||
- [FreeCache](https://github.com/coocood/freecache)
|
||||
- [FastCache](https://github.com/VictoriaMetrics/fastcache)
|
||||
- [Ristretto](https://github.com/dgraph-io/ristretto)
|
||||
- [Badger](https://github.com/dgraph-io/badger)
|
||||
|
29
vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
29
vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
@@ -19,10 +19,13 @@ const (
|
||||
// Store the primes in an array as well.
|
||||
//
|
||||
// The consts are used when possible in Go code to avoid MOVs but we need a
|
||||
// contiguous array of the assembly code.
|
||||
// contiguous array for the assembly code.
|
||||
var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}
|
||||
|
||||
// Digest implements hash.Hash64.
|
||||
//
|
||||
// Note that a zero-valued Digest is not ready to receive writes.
|
||||
// Call Reset or create a Digest using New before calling other methods.
|
||||
type Digest struct {
|
||||
v1 uint64
|
||||
v2 uint64
|
||||
@@ -33,19 +36,31 @@ type Digest struct {
|
||||
n int // how much of mem is used
|
||||
}
|
||||
|
||||
// New creates a new Digest that computes the 64-bit xxHash algorithm.
|
||||
// New creates a new Digest with a zero seed.
|
||||
func New() *Digest {
|
||||
return NewWithSeed(0)
|
||||
}
|
||||
|
||||
// NewWithSeed creates a new Digest with the given seed.
|
||||
func NewWithSeed(seed uint64) *Digest {
|
||||
var d Digest
|
||||
d.Reset()
|
||||
d.ResetWithSeed(seed)
|
||||
return &d
|
||||
}
|
||||
|
||||
// Reset clears the Digest's state so that it can be reused.
|
||||
// It uses a seed value of zero.
|
||||
func (d *Digest) Reset() {
|
||||
d.v1 = primes[0] + prime2
|
||||
d.v2 = prime2
|
||||
d.v3 = 0
|
||||
d.v4 = -primes[0]
|
||||
d.ResetWithSeed(0)
|
||||
}
|
||||
|
||||
// ResetWithSeed clears the Digest's state so that it can be reused.
|
||||
// It uses the given seed to initialize the state.
|
||||
func (d *Digest) ResetWithSeed(seed uint64) {
|
||||
d.v1 = seed + prime1 + prime2
|
||||
d.v2 = seed + prime2
|
||||
d.v3 = seed
|
||||
d.v4 = seed - prime1
|
||||
d.total = 0
|
||||
d.n = 0
|
||||
}
|
||||
|
2
vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
generated
vendored
2
vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
generated
vendored
@@ -6,7 +6,7 @@
|
||||
|
||||
package xxhash
|
||||
|
||||
// Sum64 computes the 64-bit xxHash digest of b.
|
||||
// Sum64 computes the 64-bit xxHash digest of b with a zero seed.
|
||||
//
|
||||
//go:noescape
|
||||
func Sum64(b []byte) uint64
|
||||
|
2
vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
2
vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
@@ -3,7 +3,7 @@
|
||||
|
||||
package xxhash
|
||||
|
||||
// Sum64 computes the 64-bit xxHash digest of b.
|
||||
// Sum64 computes the 64-bit xxHash digest of b with a zero seed.
|
||||
func Sum64(b []byte) uint64 {
|
||||
// A simpler version would be
|
||||
// d := New()
|
||||
|
2
vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
2
vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
@@ -5,7 +5,7 @@
|
||||
|
||||
package xxhash
|
||||
|
||||
// Sum64String computes the 64-bit xxHash digest of s.
|
||||
// Sum64String computes the 64-bit xxHash digest of s with a zero seed.
|
||||
func Sum64String(s string) uint64 {
|
||||
return Sum64([]byte(s))
|
||||
}
|
||||
|
2
vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
2
vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
@@ -33,7 +33,7 @@ import (
|
||||
//
|
||||
// See https://github.com/golang/go/issues/42739 for discussion.
|
||||
|
||||
// Sum64String computes the 64-bit xxHash digest of s.
|
||||
// Sum64String computes the 64-bit xxHash digest of s with a zero seed.
|
||||
// It may be faster than Sum64([]byte(s)) by avoiding a copy.
|
||||
func Sum64String(s string) uint64 {
|
||||
b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))
|
||||
|
12
vendor/github.com/chmduquesne/rollinghash/.travis.yml
generated
vendored
Normal file
12
vendor/github.com/chmduquesne/rollinghash/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
language: go
|
||||
go:
|
||||
- "1.10"
|
||||
- "1.9"
|
||||
- "1.8"
|
||||
- "1.7"
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
script:
|
||||
- go test -v ./...
|
||||
- go test -bench=. ./...
|
||||
- $HOME/gopath/bin/goveralls -package=./... -service=travis-ci
|
19
vendor/github.com/chmduquesne/rollinghash/LICENSE.txt
generated
vendored
Normal file
19
vendor/github.com/chmduquesne/rollinghash/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright 2015 Christophe-Marie Duquesne
|
||||
|
||||
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.
|
120
vendor/github.com/chmduquesne/rollinghash/README.md
generated
vendored
Normal file
120
vendor/github.com/chmduquesne/rollinghash/README.md
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
[](https://travis-ci.org/chmduquesne/rollinghash)
|
||||
[](https://coveralls.io/github/chmduquesne/rollinghash?branch=master)
|
||||
[](https://godoc.org/github.com/chmduquesne/rollinghash)
|
||||

|
||||
|
||||
Rolling Hashes
|
||||
==============
|
||||
|
||||
Philosophy
|
||||
----------
|
||||
|
||||
This package contains several various rolling hashes for you to play with
|
||||
crazy ideas. The API design philosophy is to stick as closely as possible
|
||||
to the interface provided by the builtin hash package (the hashes
|
||||
implemented here are effectively drop-in replacements for their builtin
|
||||
counterparts), while providing simultaneously the highest speed and
|
||||
simplicity.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
A [`rollinghash.Hash`](https://godoc.org/github.com/chmduquesne/rollinghash#Hash)
|
||||
is just a [`hash.Hash`](https://golang.org/pkg/hash/#Hash) which
|
||||
implements the
|
||||
[`Roller`](https://godoc.org/github.com/chmduquesne/rollinghash#Roller)
|
||||
interface. Here is how it is typically used:
|
||||
|
||||
```golang
|
||||
data := []byte("here is some data to roll on")
|
||||
h := buzhash64.New()
|
||||
n := 16
|
||||
|
||||
// Initialize the rolling window
|
||||
h.Write(data[:n])
|
||||
|
||||
for _, c := range(data[n:]) {
|
||||
|
||||
// Slide the window and update the hash
|
||||
h.Roll(c)
|
||||
|
||||
// Get the updated hash value
|
||||
fmt.Println(h.Sum64())
|
||||
}
|
||||
```
|
||||
|
||||
Gotchas
|
||||
-------
|
||||
|
||||
The rolling window MUST be initialized by calling `Write` first (which
|
||||
saves a copy). The byte leaving the rolling window is inferred from the
|
||||
internal copy of the rolling window, which is updated with every call to
|
||||
`Roll`.
|
||||
|
||||
If you want your code to run at the highest speed, do NOT cast the result
|
||||
of a `New()` as a rollinghash.Hash. Instead, use the native type returned
|
||||
by `New()`. This is because the go compiler cannot inline calls from an
|
||||
interface. When later you call Roll(), the native type call will be
|
||||
inlined by the compiler, but not the casted type call.
|
||||
|
||||
```golang
|
||||
var h1 rollinghash.Hash
|
||||
h1 = buzhash32.New()
|
||||
h2 := buzhash32.New()
|
||||
|
||||
[...]
|
||||
|
||||
h1.Roll(b) // Not inlined (slow)
|
||||
h2.Roll(b) // inlined (fast)
|
||||
```
|
||||
|
||||
What's new in v4
|
||||
----------------
|
||||
|
||||
In v4:
|
||||
|
||||
* `Write` has become fully consistent with `hash.Hash`. As opposed to
|
||||
previous versions, where writing data would reinitialize the window, it
|
||||
now appends this data to the existing window. In order to reset the
|
||||
window, one should instead use the `Reset` method.
|
||||
|
||||
* Calling `Roll` on an empty window is considered a bug, and now triggers
|
||||
a panic.
|
||||
|
||||
Brief reminder of the behaviors in previous versions:
|
||||
|
||||
* From v0.x.x to v2.x.x: `Roll` returns an error for an empty window.
|
||||
`Write` reinitializes the rolling window.
|
||||
|
||||
* v3.x.x : `Roll` does not return anything. `Write` still reinitializes
|
||||
the rolling window. The rolling window always has a minimum size of 1,
|
||||
which yields wrong results when using roll before having initialized the
|
||||
window.
|
||||
|
||||
Go versions
|
||||
-----------
|
||||
|
||||
The `RabinKarp64` rollinghash does not yield consistent results before
|
||||
go1.7. This is because it uses `Rand.Read()` from the builtin `math/rand`.
|
||||
This function was [fixed in go
|
||||
1.7](https://golang.org/doc/go1.7#math_rand) to produce a consistent
|
||||
stream of bytes that is independant of the size of the input buffer. If
|
||||
you depend on this hash, it is strongly recommended to stick to versions
|
||||
of go superior to 1.7.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This code is delivered to you under the terms of the MIT public license,
|
||||
except the `rabinkarp64` subpackage, which has been adapted from
|
||||
[restic](https://github.com/restic/chunker) (BSD 2-clause "Simplified").
|
||||
|
||||
Notable users
|
||||
-------------
|
||||
|
||||
* [syncthing](https://syncthing.net/), a decentralized synchronisation
|
||||
solution
|
||||
* [muscato](https://github.com/kshedden/muscato), a genome analysis tool
|
||||
|
||||
If you are using this in production or for research, let me know and I
|
||||
will happily put a link here!
|
117
vendor/github.com/chmduquesne/rollinghash/adler32/adler32.go
generated
vendored
Normal file
117
vendor/github.com/chmduquesne/rollinghash/adler32/adler32.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Package rollinghash/adler32 implements a rolling version of hash/adler32
|
||||
|
||||
package adler32
|
||||
|
||||
import (
|
||||
"hash"
|
||||
vanilla "hash/adler32"
|
||||
|
||||
"github.com/chmduquesne/rollinghash"
|
||||
)
|
||||
|
||||
const (
|
||||
Mod = 65521
|
||||
Size = 4
|
||||
)
|
||||
|
||||
// Adler32 is a digest which satisfies the rollinghash.Hash32 interface.
|
||||
// It implements the adler32 algorithm https://en.wikipedia.org/wiki/Adler-32
|
||||
type Adler32 struct {
|
||||
a, b uint32
|
||||
n uint32
|
||||
|
||||
// window is treated like a circular buffer, where the oldest element
|
||||
// is indicated by d.oldest
|
||||
window []byte
|
||||
oldest int
|
||||
|
||||
vanilla hash.Hash32
|
||||
}
|
||||
|
||||
// Reset resets the digest to its initial state.
|
||||
func (d *Adler32) Reset() {
|
||||
d.window = d.window[:0] // Reset the size but don't reallocate
|
||||
d.oldest = 0
|
||||
d.a = 1
|
||||
d.b = 0
|
||||
d.n = 0
|
||||
d.vanilla.Reset()
|
||||
}
|
||||
|
||||
// New returns a new Adler32 digest
|
||||
func New() *Adler32 {
|
||||
return &Adler32{
|
||||
a: 1,
|
||||
b: 0,
|
||||
n: 0,
|
||||
window: make([]byte, 0, rollinghash.DefaultWindowCap),
|
||||
oldest: 0,
|
||||
vanilla: vanilla.New(),
|
||||
}
|
||||
}
|
||||
|
||||
// Size is 4 bytes
|
||||
func (d *Adler32) Size() int { return Size }
|
||||
|
||||
// BlockSize is 1 byte
|
||||
func (d *Adler32) BlockSize() int { return 1 }
|
||||
|
||||
// Write appends data to the rolling window and updates the digest.
|
||||
func (d *Adler32) Write(data []byte) (int, error) {
|
||||
l := len(data)
|
||||
if l == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
// Re-arrange the window so that the leftmost element is at index 0
|
||||
n := len(d.window)
|
||||
if d.oldest != 0 {
|
||||
tmp := make([]byte, d.oldest)
|
||||
copy(tmp, d.window[:d.oldest])
|
||||
copy(d.window, d.window[d.oldest:])
|
||||
copy(d.window[n-d.oldest:], tmp)
|
||||
d.oldest = 0
|
||||
}
|
||||
d.window = append(d.window, data...)
|
||||
|
||||
// Piggy-back on the core implementation
|
||||
d.vanilla.Reset()
|
||||
d.vanilla.Write(d.window)
|
||||
s := d.vanilla.Sum32()
|
||||
d.a, d.b = s&0xffff, s>>16
|
||||
d.n = uint32(len(d.window)) % Mod
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
// Sum32 returns the hash as a uint32
|
||||
func (d *Adler32) Sum32() uint32 {
|
||||
return d.b<<16 | d.a
|
||||
}
|
||||
|
||||
// Sum returns the hash as a byte slice
|
||||
func (d *Adler32) Sum(b []byte) []byte {
|
||||
v := d.Sum32()
|
||||
return append(b, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
||||
}
|
||||
|
||||
// Roll updates the checksum of the window from the entering byte. You
|
||||
// MUST initialize a window with Write() before calling this method.
|
||||
func (d *Adler32) Roll(b byte) {
|
||||
// This check costs 10-15% performance. If we disable it, we crash
|
||||
// when the window is empty. If we enable it, we are always correct
|
||||
// (an empty window never changes no matter how much you roll it).
|
||||
//if len(d.window) == 0 {
|
||||
// return
|
||||
//}
|
||||
// extract the entering/leaving bytes and update the circular buffer.
|
||||
enter := uint32(b)
|
||||
leave := uint32(d.window[d.oldest])
|
||||
d.window[d.oldest] = b
|
||||
d.oldest += 1
|
||||
if d.oldest >= len(d.window) {
|
||||
d.oldest = 0
|
||||
}
|
||||
|
||||
// See http://stackoverflow.com/questions/40985080/why-does-my-rolling-adler32-checksum-not-work-in-go-modulo-arithmetic
|
||||
d.a = (d.a + Mod + enter - leave) % Mod
|
||||
d.b = (d.b + (d.n*leave/Mod+1)*Mod + d.a - (d.n * leave) - 1) % Mod
|
||||
}
|
48
vendor/github.com/chmduquesne/rollinghash/rollinghash.go
generated
vendored
Normal file
48
vendor/github.com/chmduquesne/rollinghash/rollinghash.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
|
||||
Package rollinghash implements rolling versions of some hashes
|
||||
|
||||
*/
|
||||
package rollinghash
|
||||
|
||||
import "hash"
|
||||
|
||||
// DefaultWindowCap is the default capacity of the internal window of a
|
||||
// new Hash.
|
||||
const DefaultWindowCap = 64
|
||||
|
||||
// A Roller is a type that has the method Roll. Roll updates the hash of a
|
||||
// rolling window from just the entering byte. You MUST call Write()
|
||||
// BEFORE using this method and provide it with an initial window of size
|
||||
// at least 1 byte. You can then call this method for every new byte
|
||||
// entering the window. The byte leaving the window is automatically
|
||||
// computed from a copy of the window internally kept in the checksum.
|
||||
// This window is updated along with the internal state of the checksum
|
||||
// every time Roll() is called.
|
||||
type Roller interface {
|
||||
Roll(b byte)
|
||||
}
|
||||
|
||||
// rollinghash.Hash extends hash.Hash by adding the method Roll. A
|
||||
// rollinghash.Hash can be updated byte by byte, by specifying which byte
|
||||
// enters the window.
|
||||
type Hash interface {
|
||||
hash.Hash
|
||||
Roller
|
||||
}
|
||||
|
||||
// rollinghash.Hash32 extends hash.Hash by adding the method Roll. A
|
||||
// rollinghash.Hash32 can be updated byte by byte, by specifying which
|
||||
// byte enters the window.
|
||||
type Hash32 interface {
|
||||
hash.Hash32
|
||||
Roller
|
||||
}
|
||||
|
||||
// rollinghash.Hash64 extends hash.Hash by adding the method Roll. A
|
||||
// rollinghash.Hash64 can be updated byte by byte, by specifying which
|
||||
// byte enters the window.
|
||||
type Hash64 interface {
|
||||
hash.Hash64
|
||||
Roller
|
||||
}
|
22
vendor/github.com/go-asn1-ber/asn1-ber/LICENSE
generated
vendored
Normal file
22
vendor/github.com/go-asn1-ber/asn1-ber/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)
|
||||
Portions copyright (c) 2015-2016 go-asn1-ber Authors
|
||||
|
||||
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.
|
24
vendor/github.com/go-asn1-ber/asn1-ber/README.md
generated
vendored
Normal file
24
vendor/github.com/go-asn1-ber/asn1-ber/README.md
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
[](https://godoc.org/gopkg.in/asn1-ber.v1) [](https://travis-ci.org/go-asn1-ber/asn1-ber)
|
||||
|
||||
|
||||
ASN1 BER Encoding / Decoding Library for the GO programming language.
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Required libraries:
|
||||
None
|
||||
|
||||
Working:
|
||||
Very basic encoding / decoding needed for LDAP protocol
|
||||
|
||||
Tests Implemented:
|
||||
A few
|
||||
|
||||
TODO:
|
||||
Fix all encoding / decoding to conform to ASN1 BER spec
|
||||
Implement Tests / Benchmarks
|
||||
|
||||
---
|
||||
|
||||
The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
|
||||
The design is licensed under the Creative Commons 3.0 Attributions license.
|
||||
Read this article for more details: http://blog.golang.org/gopher
|
625
vendor/github.com/go-asn1-ber/asn1-ber/ber.go
generated
vendored
Normal file
625
vendor/github.com/go-asn1-ber/asn1-ber/ber.go
generated
vendored
Normal file
@@ -0,0 +1,625 @@
|
||||
package ber
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// MaxPacketLengthBytes specifies the maximum allowed packet size when calling ReadPacket or DecodePacket. Set to 0 for
|
||||
// no limit.
|
||||
var MaxPacketLengthBytes int64 = math.MaxInt32
|
||||
|
||||
type Packet struct {
|
||||
Identifier
|
||||
Value interface{}
|
||||
ByteValue []byte
|
||||
Data *bytes.Buffer
|
||||
Children []*Packet
|
||||
Description string
|
||||
}
|
||||
|
||||
type Identifier struct {
|
||||
ClassType Class
|
||||
TagType Type
|
||||
Tag Tag
|
||||
}
|
||||
|
||||
type Tag uint64
|
||||
|
||||
const (
|
||||
TagEOC Tag = 0x00
|
||||
TagBoolean Tag = 0x01
|
||||
TagInteger Tag = 0x02
|
||||
TagBitString Tag = 0x03
|
||||
TagOctetString Tag = 0x04
|
||||
TagNULL Tag = 0x05
|
||||
TagObjectIdentifier Tag = 0x06
|
||||
TagObjectDescriptor Tag = 0x07
|
||||
TagExternal Tag = 0x08
|
||||
TagRealFloat Tag = 0x09
|
||||
TagEnumerated Tag = 0x0a
|
||||
TagEmbeddedPDV Tag = 0x0b
|
||||
TagUTF8String Tag = 0x0c
|
||||
TagRelativeOID Tag = 0x0d
|
||||
TagSequence Tag = 0x10
|
||||
TagSet Tag = 0x11
|
||||
TagNumericString Tag = 0x12
|
||||
TagPrintableString Tag = 0x13
|
||||
TagT61String Tag = 0x14
|
||||
TagVideotexString Tag = 0x15
|
||||
TagIA5String Tag = 0x16
|
||||
TagUTCTime Tag = 0x17
|
||||
TagGeneralizedTime Tag = 0x18
|
||||
TagGraphicString Tag = 0x19
|
||||
TagVisibleString Tag = 0x1a
|
||||
TagGeneralString Tag = 0x1b
|
||||
TagUniversalString Tag = 0x1c
|
||||
TagCharacterString Tag = 0x1d
|
||||
TagBMPString Tag = 0x1e
|
||||
TagBitmask Tag = 0x1f // xxx11111b
|
||||
|
||||
// HighTag indicates the start of a high-tag byte sequence
|
||||
HighTag Tag = 0x1f // xxx11111b
|
||||
// HighTagContinueBitmask indicates the high-tag byte sequence should continue
|
||||
HighTagContinueBitmask Tag = 0x80 // 10000000b
|
||||
// HighTagValueBitmask obtains the tag value from a high-tag byte sequence byte
|
||||
HighTagValueBitmask Tag = 0x7f // 01111111b
|
||||
)
|
||||
|
||||
const (
|
||||
// LengthLongFormBitmask is the mask to apply to the length byte to see if a long-form byte sequence is used
|
||||
LengthLongFormBitmask = 0x80
|
||||
// LengthValueBitmask is the mask to apply to the length byte to get the number of bytes in the long-form byte sequence
|
||||
LengthValueBitmask = 0x7f
|
||||
|
||||
// LengthIndefinite is returned from readLength to indicate an indefinite length
|
||||
LengthIndefinite = -1
|
||||
)
|
||||
|
||||
var tagMap = map[Tag]string{
|
||||
TagEOC: "EOC (End-of-Content)",
|
||||
TagBoolean: "Boolean",
|
||||
TagInteger: "Integer",
|
||||
TagBitString: "Bit String",
|
||||
TagOctetString: "Octet String",
|
||||
TagNULL: "NULL",
|
||||
TagObjectIdentifier: "Object Identifier",
|
||||
TagObjectDescriptor: "Object Descriptor",
|
||||
TagExternal: "External",
|
||||
TagRealFloat: "Real (float)",
|
||||
TagEnumerated: "Enumerated",
|
||||
TagEmbeddedPDV: "Embedded PDV",
|
||||
TagUTF8String: "UTF8 String",
|
||||
TagRelativeOID: "Relative-OID",
|
||||
TagSequence: "Sequence and Sequence of",
|
||||
TagSet: "Set and Set OF",
|
||||
TagNumericString: "Numeric String",
|
||||
TagPrintableString: "Printable String",
|
||||
TagT61String: "T61 String",
|
||||
TagVideotexString: "Videotex String",
|
||||
TagIA5String: "IA5 String",
|
||||
TagUTCTime: "UTC Time",
|
||||
TagGeneralizedTime: "Generalized Time",
|
||||
TagGraphicString: "Graphic String",
|
||||
TagVisibleString: "Visible String",
|
||||
TagGeneralString: "General String",
|
||||
TagUniversalString: "Universal String",
|
||||
TagCharacterString: "Character String",
|
||||
TagBMPString: "BMP String",
|
||||
}
|
||||
|
||||
type Class uint8
|
||||
|
||||
const (
|
||||
ClassUniversal Class = 0 // 00xxxxxxb
|
||||
ClassApplication Class = 64 // 01xxxxxxb
|
||||
ClassContext Class = 128 // 10xxxxxxb
|
||||
ClassPrivate Class = 192 // 11xxxxxxb
|
||||
ClassBitmask Class = 192 // 11xxxxxxb
|
||||
)
|
||||
|
||||
var ClassMap = map[Class]string{
|
||||
ClassUniversal: "Universal",
|
||||
ClassApplication: "Application",
|
||||
ClassContext: "Context",
|
||||
ClassPrivate: "Private",
|
||||
}
|
||||
|
||||
type Type uint8
|
||||
|
||||
const (
|
||||
TypePrimitive Type = 0 // xx0xxxxxb
|
||||
TypeConstructed Type = 32 // xx1xxxxxb
|
||||
TypeBitmask Type = 32 // xx1xxxxxb
|
||||
)
|
||||
|
||||
var TypeMap = map[Type]string{
|
||||
TypePrimitive: "Primitive",
|
||||
TypeConstructed: "Constructed",
|
||||
}
|
||||
|
||||
var Debug = false
|
||||
|
||||
func PrintBytes(out io.Writer, buf []byte, indent string) {
|
||||
dataLines := make([]string, (len(buf)/30)+1)
|
||||
numLines := make([]string, (len(buf)/30)+1)
|
||||
|
||||
for i, b := range buf {
|
||||
dataLines[i/30] += fmt.Sprintf("%02x ", b)
|
||||
numLines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
|
||||
}
|
||||
|
||||
for i := 0; i < len(dataLines); i++ {
|
||||
_, _ = out.Write([]byte(indent + dataLines[i] + "\n"))
|
||||
_, _ = out.Write([]byte(indent + numLines[i] + "\n\n"))
|
||||
}
|
||||
}
|
||||
|
||||
func WritePacket(out io.Writer, p *Packet) {
|
||||
printPacket(out, p, 0, false)
|
||||
}
|
||||
|
||||
func PrintPacket(p *Packet) {
|
||||
printPacket(os.Stdout, p, 0, false)
|
||||
}
|
||||
|
||||
// Return a string describing packet content. This is not recursive,
|
||||
// If the packet is a sequence, use `printPacket()`, or browse
|
||||
// sequence yourself.
|
||||
func DescribePacket(p *Packet) string {
|
||||
|
||||
classStr := ClassMap[p.ClassType]
|
||||
|
||||
tagTypeStr := TypeMap[p.TagType]
|
||||
|
||||
tagStr := fmt.Sprintf("0x%02X", p.Tag)
|
||||
|
||||
if p.ClassType == ClassUniversal {
|
||||
tagStr = tagMap[p.Tag]
|
||||
}
|
||||
|
||||
value := fmt.Sprint(p.Value)
|
||||
description := ""
|
||||
|
||||
if p.Description != "" {
|
||||
description = p.Description + ": "
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s(%s, %s, %s) Len=%d %q", description, classStr, tagTypeStr, tagStr, p.Data.Len(), value)
|
||||
}
|
||||
|
||||
func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
|
||||
indentStr := ""
|
||||
|
||||
for len(indentStr) != indent {
|
||||
indentStr += " "
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(out, "%s%s\n", indentStr, DescribePacket(p))
|
||||
|
||||
if printBytes {
|
||||
PrintBytes(out, p.Bytes(), indentStr)
|
||||
}
|
||||
|
||||
for _, child := range p.Children {
|
||||
printPacket(out, child, indent+1, printBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadPacket reads a single Packet from the reader.
|
||||
func ReadPacket(reader io.Reader) (*Packet, error) {
|
||||
p, _, err := readPacket(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func DecodeString(data []byte) string {
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func ParseInt64(bytes []byte) (ret int64, err error) {
|
||||
if len(bytes) > 8 {
|
||||
// We'll overflow an int64 in this case.
|
||||
err = fmt.Errorf("integer too large")
|
||||
return
|
||||
}
|
||||
for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
|
||||
ret <<= 8
|
||||
ret |= int64(bytes[bytesRead])
|
||||
}
|
||||
|
||||
// Shift up and down in order to sign extend the result.
|
||||
ret <<= 64 - uint8(len(bytes))*8
|
||||
ret >>= 64 - uint8(len(bytes))*8
|
||||
return
|
||||
}
|
||||
|
||||
func encodeInteger(i int64) []byte {
|
||||
n := int64Length(i)
|
||||
out := make([]byte, n)
|
||||
|
||||
var j int
|
||||
for ; n > 0; n-- {
|
||||
out[j] = byte(i >> uint((n-1)*8))
|
||||
j++
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func int64Length(i int64) (numBytes int) {
|
||||
numBytes = 1
|
||||
|
||||
for i > 127 {
|
||||
numBytes++
|
||||
i >>= 8
|
||||
}
|
||||
|
||||
for i < -128 {
|
||||
numBytes++
|
||||
i >>= 8
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DecodePacket decodes the given bytes into a single Packet
|
||||
// If a decode error is encountered, nil is returned.
|
||||
func DecodePacket(data []byte) *Packet {
|
||||
p, _, _ := readPacket(bytes.NewBuffer(data))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// DecodePacketErr decodes the given bytes into a single Packet
|
||||
// If a decode error is encountered, nil is returned.
|
||||
func DecodePacketErr(data []byte) (*Packet, error) {
|
||||
p, _, err := readPacket(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// readPacket reads a single Packet from the reader, returning the number of bytes read.
|
||||
func readPacket(reader io.Reader) (*Packet, int, error) {
|
||||
identifier, length, read, err := readHeader(reader)
|
||||
if err != nil {
|
||||
return nil, read, err
|
||||
}
|
||||
|
||||
p := &Packet{
|
||||
Identifier: identifier,
|
||||
}
|
||||
|
||||
p.Data = new(bytes.Buffer)
|
||||
p.Children = make([]*Packet, 0, 2)
|
||||
p.Value = nil
|
||||
|
||||
if p.TagType == TypeConstructed {
|
||||
// TODO: if universal, ensure tag type is allowed to be constructed
|
||||
|
||||
// Track how much content we've read
|
||||
contentRead := 0
|
||||
for {
|
||||
if length != LengthIndefinite {
|
||||
// End if we've read what we've been told to
|
||||
if contentRead == length {
|
||||
break
|
||||
}
|
||||
// Detect if a packet boundary didn't fall on the expected length
|
||||
if contentRead > length {
|
||||
return nil, read, fmt.Errorf("expected to read %d bytes, read %d", length, contentRead)
|
||||
}
|
||||
}
|
||||
|
||||
// Read the next packet
|
||||
child, r, err := readPacket(reader)
|
||||
if err != nil {
|
||||
return nil, read, unexpectedEOF(err)
|
||||
}
|
||||
contentRead += r
|
||||
read += r
|
||||
|
||||
// Test is this is the EOC marker for our packet
|
||||
if isEOCPacket(child) {
|
||||
if length == LengthIndefinite {
|
||||
break
|
||||
}
|
||||
return nil, read, errors.New("eoc child not allowed with definite length")
|
||||
}
|
||||
|
||||
// Append and continue
|
||||
p.AppendChild(child)
|
||||
}
|
||||
return p, read, nil
|
||||
}
|
||||
|
||||
if length == LengthIndefinite {
|
||||
return nil, read, errors.New("indefinite length used with primitive type")
|
||||
}
|
||||
|
||||
// Read definite-length content
|
||||
if MaxPacketLengthBytes > 0 && int64(length) > MaxPacketLengthBytes {
|
||||
return nil, read, fmt.Errorf("length %d greater than maximum %d", length, MaxPacketLengthBytes)
|
||||
}
|
||||
content := make([]byte, length)
|
||||
if length > 0 {
|
||||
_, err := io.ReadFull(reader, content)
|
||||
if err != nil {
|
||||
return nil, read, unexpectedEOF(err)
|
||||
}
|
||||
read += length
|
||||
}
|
||||
|
||||
if p.ClassType == ClassUniversal {
|
||||
p.Data.Write(content)
|
||||
p.ByteValue = content
|
||||
|
||||
switch p.Tag {
|
||||
case TagEOC:
|
||||
case TagBoolean:
|
||||
val, _ := ParseInt64(content)
|
||||
|
||||
p.Value = val != 0
|
||||
case TagInteger:
|
||||
p.Value, _ = ParseInt64(content)
|
||||
case TagBitString:
|
||||
case TagOctetString:
|
||||
// the actual string encoding is not known here
|
||||
// (e.g. for LDAP content is already an UTF8-encoded
|
||||
// string). Return the data without further processing
|
||||
p.Value = DecodeString(content)
|
||||
case TagNULL:
|
||||
case TagObjectIdentifier:
|
||||
case TagObjectDescriptor:
|
||||
case TagExternal:
|
||||
case TagRealFloat:
|
||||
p.Value, err = ParseReal(content)
|
||||
case TagEnumerated:
|
||||
p.Value, _ = ParseInt64(content)
|
||||
case TagEmbeddedPDV:
|
||||
case TagUTF8String:
|
||||
val := DecodeString(content)
|
||||
if !utf8.Valid([]byte(val)) {
|
||||
err = errors.New("invalid UTF-8 string")
|
||||
} else {
|
||||
p.Value = val
|
||||
}
|
||||
case TagRelativeOID:
|
||||
case TagSequence:
|
||||
case TagSet:
|
||||
case TagNumericString:
|
||||
case TagPrintableString:
|
||||
val := DecodeString(content)
|
||||
if err = isPrintableString(val); err == nil {
|
||||
p.Value = val
|
||||
}
|
||||
case TagT61String:
|
||||
case TagVideotexString:
|
||||
case TagIA5String:
|
||||
val := DecodeString(content)
|
||||
for i, c := range val {
|
||||
if c >= 0x7F {
|
||||
err = fmt.Errorf("invalid character for IA5String at pos %d: %c", i, c)
|
||||
break
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
p.Value = val
|
||||
}
|
||||
case TagUTCTime:
|
||||
case TagGeneralizedTime:
|
||||
p.Value, err = ParseGeneralizedTime(content)
|
||||
case TagGraphicString:
|
||||
case TagVisibleString:
|
||||
case TagGeneralString:
|
||||
case TagUniversalString:
|
||||
case TagCharacterString:
|
||||
case TagBMPString:
|
||||
}
|
||||
} else {
|
||||
p.Data.Write(content)
|
||||
}
|
||||
|
||||
return p, read, err
|
||||
}
|
||||
|
||||
func isPrintableString(val string) error {
|
||||
for i, c := range val {
|
||||
switch {
|
||||
case c >= 'a' && c <= 'z':
|
||||
case c >= 'A' && c <= 'Z':
|
||||
case c >= '0' && c <= '9':
|
||||
default:
|
||||
switch c {
|
||||
case '\'', '(', ')', '+', ',', '-', '.', '=', '/', ':', '?', ' ':
|
||||
default:
|
||||
return fmt.Errorf("invalid character in position %d", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Packet) Bytes() []byte {
|
||||
var out bytes.Buffer
|
||||
|
||||
out.Write(encodeIdentifier(p.Identifier))
|
||||
out.Write(encodeLength(p.Data.Len()))
|
||||
out.Write(p.Data.Bytes())
|
||||
|
||||
return out.Bytes()
|
||||
}
|
||||
|
||||
func (p *Packet) AppendChild(child *Packet) {
|
||||
p.Data.Write(child.Bytes())
|
||||
p.Children = append(p.Children, child)
|
||||
}
|
||||
|
||||
func Encode(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet {
|
||||
p := new(Packet)
|
||||
|
||||
p.ClassType = classType
|
||||
p.TagType = tagType
|
||||
p.Tag = tag
|
||||
p.Data = new(bytes.Buffer)
|
||||
|
||||
p.Children = make([]*Packet, 0, 2)
|
||||
|
||||
p.Value = value
|
||||
p.Description = description
|
||||
|
||||
if value != nil {
|
||||
v := reflect.ValueOf(value)
|
||||
|
||||
if classType == ClassUniversal {
|
||||
switch tag {
|
||||
case TagOctetString:
|
||||
sv, ok := v.Interface().(string)
|
||||
|
||||
if ok {
|
||||
p.Data.Write([]byte(sv))
|
||||
}
|
||||
case TagEnumerated:
|
||||
bv, ok := v.Interface().([]byte)
|
||||
if ok {
|
||||
p.Data.Write(bv)
|
||||
}
|
||||
case TagEmbeddedPDV:
|
||||
bv, ok := v.Interface().([]byte)
|
||||
if ok {
|
||||
p.Data.Write(bv)
|
||||
}
|
||||
}
|
||||
} else if classType == ClassContext {
|
||||
switch tag {
|
||||
case TagEnumerated:
|
||||
bv, ok := v.Interface().([]byte)
|
||||
if ok {
|
||||
p.Data.Write(bv)
|
||||
}
|
||||
case TagEmbeddedPDV:
|
||||
bv, ok := v.Interface().([]byte)
|
||||
if ok {
|
||||
p.Data.Write(bv)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func NewSequence(description string) *Packet {
|
||||
return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, description)
|
||||
}
|
||||
|
||||
func NewBoolean(classType Class, tagType Type, tag Tag, value bool, description string) *Packet {
|
||||
intValue := int64(0)
|
||||
|
||||
if value {
|
||||
intValue = 1
|
||||
}
|
||||
|
||||
p := Encode(classType, tagType, tag, nil, description)
|
||||
|
||||
p.Value = value
|
||||
p.Data.Write(encodeInteger(intValue))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// NewLDAPBoolean returns a RFC 4511-compliant Boolean packet.
|
||||
func NewLDAPBoolean(classType Class, tagType Type, tag Tag, value bool, description string) *Packet {
|
||||
intValue := int64(0)
|
||||
|
||||
if value {
|
||||
intValue = 255
|
||||
}
|
||||
|
||||
p := Encode(classType, tagType, tag, nil, description)
|
||||
|
||||
p.Value = value
|
||||
p.Data.Write(encodeInteger(intValue))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func NewInteger(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet {
|
||||
p := Encode(classType, tagType, tag, nil, description)
|
||||
|
||||
p.Value = value
|
||||
switch v := value.(type) {
|
||||
case int:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case uint:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case int64:
|
||||
p.Data.Write(encodeInteger(v))
|
||||
case uint64:
|
||||
// TODO : check range or add encodeUInt...
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case int32:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case uint32:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case int16:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case uint16:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case int8:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
case uint8:
|
||||
p.Data.Write(encodeInteger(int64(v)))
|
||||
default:
|
||||
// TODO : add support for big.Int ?
|
||||
panic(fmt.Sprintf("Invalid type %T, expected {u|}int{64|32|16|8}", v))
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func NewString(classType Class, tagType Type, tag Tag, value, description string) *Packet {
|
||||
p := Encode(classType, tagType, tag, nil, description)
|
||||
|
||||
p.Value = value
|
||||
p.Data.Write([]byte(value))
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func NewGeneralizedTime(classType Class, tagType Type, tag Tag, value time.Time, description string) *Packet {
|
||||
p := Encode(classType, tagType, tag, nil, description)
|
||||
var s string
|
||||
if value.Nanosecond() != 0 {
|
||||
s = value.Format(`20060102150405.000000000Z`)
|
||||
} else {
|
||||
s = value.Format(`20060102150405Z`)
|
||||
}
|
||||
p.Value = s
|
||||
p.Data.Write([]byte(s))
|
||||
return p
|
||||
}
|
||||
|
||||
func NewReal(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet {
|
||||
p := Encode(classType, tagType, tag, nil, description)
|
||||
|
||||
switch v := value.(type) {
|
||||
case float64:
|
||||
p.Data.Write(encodeFloat(v))
|
||||
case float32:
|
||||
p.Data.Write(encodeFloat(float64(v)))
|
||||
default:
|
||||
panic(fmt.Sprintf("Invalid type %T, expected float{64|32}", v))
|
||||
}
|
||||
return p
|
||||
}
|
25
vendor/github.com/go-asn1-ber/asn1-ber/content_int.go
generated
vendored
Normal file
25
vendor/github.com/go-asn1-ber/asn1-ber/content_int.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package ber
|
||||
|
||||
func encodeUnsignedInteger(i uint64) []byte {
|
||||
n := uint64Length(i)
|
||||
out := make([]byte, n)
|
||||
|
||||
var j int
|
||||
for ; n > 0; n-- {
|
||||
out[j] = byte(i >> uint((n-1)*8))
|
||||
j++
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func uint64Length(i uint64) (numBytes int) {
|
||||
numBytes = 1
|
||||
|
||||
for i > 255 {
|
||||
numBytes++
|
||||
i >>= 8
|
||||
}
|
||||
|
||||
return
|
||||
}
|
105
vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go
generated
vendored
Normal file
105
vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
package ber
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErrInvalidTimeFormat is returned when the generalizedTime string was not correct.
|
||||
var ErrInvalidTimeFormat = errors.New("invalid time format")
|
||||
|
||||
var zeroTime = time.Time{}
|
||||
|
||||
// ParseGeneralizedTime parses a string value and if it conforms to
|
||||
// GeneralizedTime[^0] format, will return a time.Time for that value.
|
||||
//
|
||||
// [^0]: https://www.itu.int/rec/T-REC-X.690-201508-I/en Section 11.7
|
||||
func ParseGeneralizedTime(v []byte) (time.Time, error) {
|
||||
var format string
|
||||
var fract time.Duration
|
||||
|
||||
str := []byte(DecodeString(v))
|
||||
tzIndex := bytes.IndexAny(str, "Z+-")
|
||||
if tzIndex < 0 {
|
||||
return zeroTime, ErrInvalidTimeFormat
|
||||
}
|
||||
|
||||
dot := bytes.IndexAny(str, ".,")
|
||||
switch dot {
|
||||
case -1:
|
||||
switch tzIndex {
|
||||
case 10:
|
||||
format = `2006010215Z`
|
||||
case 12:
|
||||
format = `200601021504Z`
|
||||
case 14:
|
||||
format = `20060102150405Z`
|
||||
default:
|
||||
return zeroTime, ErrInvalidTimeFormat
|
||||
}
|
||||
|
||||
case 10, 12:
|
||||
if tzIndex < dot {
|
||||
return zeroTime, ErrInvalidTimeFormat
|
||||
}
|
||||
// a "," is also allowed, but would not be parsed by time.Parse():
|
||||
str[dot] = '.'
|
||||
|
||||
// If <minute> is omitted, then <fraction> represents a fraction of an
|
||||
// hour; otherwise, if <second> and <leap-second> are omitted, then
|
||||
// <fraction> represents a fraction of a minute; otherwise, <fraction>
|
||||
// represents a fraction of a second.
|
||||
|
||||
// parse as float from dot to timezone
|
||||
f, err := strconv.ParseFloat(string(str[dot:tzIndex]), 64)
|
||||
if err != nil {
|
||||
return zeroTime, fmt.Errorf("failed to parse float: %s", err)
|
||||
}
|
||||
// ...and strip that part
|
||||
str = append(str[:dot], str[tzIndex:]...)
|
||||
tzIndex = dot
|
||||
|
||||
if dot == 10 {
|
||||
fract = time.Duration(int64(f * float64(time.Hour)))
|
||||
format = `2006010215Z`
|
||||
} else {
|
||||
fract = time.Duration(int64(f * float64(time.Minute)))
|
||||
format = `200601021504Z`
|
||||
}
|
||||
|
||||
case 14:
|
||||
if tzIndex < dot {
|
||||
return zeroTime, ErrInvalidTimeFormat
|
||||
}
|
||||
str[dot] = '.'
|
||||
// no need for fractional seconds, time.Parse() handles that
|
||||
format = `20060102150405Z`
|
||||
|
||||
default:
|
||||
return zeroTime, ErrInvalidTimeFormat
|
||||
}
|
||||
|
||||
l := len(str)
|
||||
switch l - tzIndex {
|
||||
case 1:
|
||||
if str[l-1] != 'Z' {
|
||||
return zeroTime, ErrInvalidTimeFormat
|
||||
}
|
||||
case 3:
|
||||
format += `0700`
|
||||
str = append(str, []byte("00")...)
|
||||
case 5:
|
||||
format += `0700`
|
||||
default:
|
||||
return zeroTime, ErrInvalidTimeFormat
|
||||
}
|
||||
|
||||
t, err := time.Parse(format, string(str))
|
||||
if err != nil {
|
||||
return zeroTime, fmt.Errorf("%s: %s", ErrInvalidTimeFormat, err)
|
||||
}
|
||||
return t.Add(fract), nil
|
||||
}
|
38
vendor/github.com/go-asn1-ber/asn1-ber/header.go
generated
vendored
Normal file
38
vendor/github.com/go-asn1-ber/asn1-ber/header.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package ber
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) {
|
||||
var (
|
||||
c, l int
|
||||
i Identifier
|
||||
)
|
||||
|
||||
if i, c, err = readIdentifier(reader); err != nil {
|
||||
return Identifier{}, 0, read, err
|
||||
}
|
||||
identifier = i
|
||||
read += c
|
||||
|
||||
if l, c, err = readLength(reader); err != nil {
|
||||
return Identifier{}, 0, read, err
|
||||
}
|
||||
length = l
|
||||
read += c
|
||||
|
||||
// Validate length type with identifier (x.600, 8.1.3.2.a)
|
||||
if length == LengthIndefinite && identifier.TagType == TypePrimitive {
|
||||
return Identifier{}, 0, read, errors.New("indefinite length used with primitive type")
|
||||
}
|
||||
|
||||
if length < LengthIndefinite {
|
||||
err = fmt.Errorf("length cannot be less than %d", LengthIndefinite)
|
||||
return
|
||||
}
|
||||
|
||||
return identifier, length, read, nil
|
||||
}
|
112
vendor/github.com/go-asn1-ber/asn1-ber/identifier.go
generated
vendored
Normal file
112
vendor/github.com/go-asn1-ber/asn1-ber/identifier.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
package ber
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func readIdentifier(reader io.Reader) (Identifier, int, error) {
|
||||
identifier := Identifier{}
|
||||
read := 0
|
||||
|
||||
// identifier byte
|
||||
b, err := readByte(reader)
|
||||
if err != nil {
|
||||
if Debug {
|
||||
fmt.Printf("error reading identifier byte: %v\n", err)
|
||||
}
|
||||
return Identifier{}, read, err
|
||||
}
|
||||
read++
|
||||
|
||||
identifier.ClassType = Class(b) & ClassBitmask
|
||||
identifier.TagType = Type(b) & TypeBitmask
|
||||
|
||||
if tag := Tag(b) & TagBitmask; tag != HighTag {
|
||||
// short-form tag
|
||||
identifier.Tag = tag
|
||||
return identifier, read, nil
|
||||
}
|
||||
|
||||
// high-tag-number tag
|
||||
tagBytes := 0
|
||||
for {
|
||||
b, err := readByte(reader)
|
||||
if err != nil {
|
||||
if Debug {
|
||||
fmt.Printf("error reading high-tag-number tag byte %d: %v\n", tagBytes, err)
|
||||
}
|
||||
return Identifier{}, read, unexpectedEOF(err)
|
||||
}
|
||||
tagBytes++
|
||||
read++
|
||||
|
||||
// Lowest 7 bits get appended to the tag value (x.690, 8.1.2.4.2.b)
|
||||
identifier.Tag <<= 7
|
||||
identifier.Tag |= Tag(b) & HighTagValueBitmask
|
||||
|
||||
// First byte may not be all zeros (x.690, 8.1.2.4.2.c)
|
||||
if tagBytes == 1 && identifier.Tag == 0 {
|
||||
return Identifier{}, read, errors.New("invalid first high-tag-number tag byte")
|
||||
}
|
||||
// Overflow of int64
|
||||
// TODO: support big int tags?
|
||||
if tagBytes > 9 {
|
||||
return Identifier{}, read, errors.New("high-tag-number tag overflow")
|
||||
}
|
||||
|
||||
// Top bit of 0 means this is the last byte in the high-tag-number tag (x.690, 8.1.2.4.2.a)
|
||||
if Tag(b)&HighTagContinueBitmask == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return identifier, read, nil
|
||||
}
|
||||
|
||||
func encodeIdentifier(identifier Identifier) []byte {
|
||||
b := []byte{0x0}
|
||||
b[0] |= byte(identifier.ClassType)
|
||||
b[0] |= byte(identifier.TagType)
|
||||
|
||||
if identifier.Tag < HighTag {
|
||||
// Short-form
|
||||
b[0] |= byte(identifier.Tag)
|
||||
} else {
|
||||
// high-tag-number
|
||||
b[0] |= byte(HighTag)
|
||||
|
||||
tag := identifier.Tag
|
||||
|
||||
b = append(b, encodeHighTag(tag)...)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func encodeHighTag(tag Tag) []byte {
|
||||
// set cap=4 to hopefully avoid additional allocations
|
||||
b := make([]byte, 0, 4)
|
||||
for tag != 0 {
|
||||
// t := last 7 bits of tag (HighTagValueBitmask = 0x7F)
|
||||
t := tag & HighTagValueBitmask
|
||||
|
||||
// right shift tag 7 to remove what was just pulled off
|
||||
tag >>= 7
|
||||
|
||||
// if b already has entries this entry needs a continuation bit (0x80)
|
||||
if len(b) != 0 {
|
||||
t |= HighTagContinueBitmask
|
||||
}
|
||||
|
||||
b = append(b, byte(t))
|
||||
}
|
||||
// reverse
|
||||
// since bits were pulled off 'tag' small to high the byte slice is in reverse order.
|
||||
// example: tag = 0xFF results in {0x7F, 0x01 + 0x80 (continuation bit)}
|
||||
// this needs to be reversed into 0x81 0x7F
|
||||
for i, j := 0, len(b)-1; i < len(b)/2; i++ {
|
||||
b[i], b[j-i] = b[j-i], b[i]
|
||||
}
|
||||
return b
|
||||
}
|
81
vendor/github.com/go-asn1-ber/asn1-ber/length.go
generated
vendored
Normal file
81
vendor/github.com/go-asn1-ber/asn1-ber/length.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
package ber
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func readLength(reader io.Reader) (length int, read int, err error) {
|
||||
// length byte
|
||||
b, err := readByte(reader)
|
||||
if err != nil {
|
||||
if Debug {
|
||||
fmt.Printf("error reading length byte: %v\n", err)
|
||||
}
|
||||
return 0, 0, unexpectedEOF(err)
|
||||
}
|
||||
read++
|
||||
|
||||
switch {
|
||||
case b == 0xFF:
|
||||
// Invalid 0xFF (x.600, 8.1.3.5.c)
|
||||
return 0, read, errors.New("invalid length byte 0xff")
|
||||
|
||||
case b == LengthLongFormBitmask:
|
||||
// Indefinite form, we have to decode packets until we encounter an EOC packet (x.600, 8.1.3.6)
|
||||
length = LengthIndefinite
|
||||
|
||||
case b&LengthLongFormBitmask == 0:
|
||||
// Short definite form, extract the length from the bottom 7 bits (x.600, 8.1.3.4)
|
||||
length = int(b) & LengthValueBitmask
|
||||
|
||||
case b&LengthLongFormBitmask != 0:
|
||||
// Long definite form, extract the number of length bytes to follow from the bottom 7 bits (x.600, 8.1.3.5.b)
|
||||
lengthBytes := int(b) & LengthValueBitmask
|
||||
// Protect against overflow
|
||||
// TODO: support big int length?
|
||||
if lengthBytes > 8 {
|
||||
return 0, read, errors.New("long-form length overflow")
|
||||
}
|
||||
|
||||
// Accumulate into a 64-bit variable
|
||||
var length64 int64
|
||||
for i := 0; i < lengthBytes; i++ {
|
||||
b, err = readByte(reader)
|
||||
if err != nil {
|
||||
if Debug {
|
||||
fmt.Printf("error reading long-form length byte %d: %v\n", i, err)
|
||||
}
|
||||
return 0, read, unexpectedEOF(err)
|
||||
}
|
||||
read++
|
||||
|
||||
// x.600, 8.1.3.5
|
||||
length64 <<= 8
|
||||
length64 |= int64(b)
|
||||
}
|
||||
|
||||
// Cast to a platform-specific integer
|
||||
length = int(length64)
|
||||
// Ensure we didn't overflow
|
||||
if int64(length) != length64 {
|
||||
return 0, read, errors.New("long-form length overflow")
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, read, errors.New("invalid length byte")
|
||||
}
|
||||
|
||||
return length, read, nil
|
||||
}
|
||||
|
||||
func encodeLength(length int) []byte {
|
||||
lengthBytes := encodeUnsignedInteger(uint64(length))
|
||||
if length > 127 || len(lengthBytes) > 1 {
|
||||
longFormBytes := []byte{LengthLongFormBitmask | byte(len(lengthBytes))}
|
||||
longFormBytes = append(longFormBytes, lengthBytes...)
|
||||
lengthBytes = longFormBytes
|
||||
}
|
||||
return lengthBytes
|
||||
}
|
163
vendor/github.com/go-asn1-ber/asn1-ber/real.go
generated
vendored
Normal file
163
vendor/github.com/go-asn1-ber/asn1-ber/real.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
package ber
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func encodeFloat(v float64) []byte {
|
||||
switch {
|
||||
case math.IsInf(v, 1):
|
||||
return []byte{0x40}
|
||||
case math.IsInf(v, -1):
|
||||
return []byte{0x41}
|
||||
case math.IsNaN(v):
|
||||
return []byte{0x42}
|
||||
case v == 0.0:
|
||||
if math.Signbit(v) {
|
||||
return []byte{0x43}
|
||||
}
|
||||
return []byte{}
|
||||
default:
|
||||
// we take the easy part ;-)
|
||||
value := []byte(strconv.FormatFloat(v, 'G', -1, 64))
|
||||
var ret []byte
|
||||
if bytes.Contains(value, []byte{'E'}) {
|
||||
ret = []byte{0x03}
|
||||
} else {
|
||||
ret = []byte{0x02}
|
||||
}
|
||||
ret = append(ret, value...)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
func ParseReal(v []byte) (val float64, err error) {
|
||||
if len(v) == 0 {
|
||||
return 0.0, nil
|
||||
}
|
||||
switch {
|
||||
case v[0]&0x80 == 0x80:
|
||||
val, err = parseBinaryFloat(v)
|
||||
case v[0]&0xC0 == 0x40:
|
||||
val, err = parseSpecialFloat(v)
|
||||
case v[0]&0xC0 == 0x0:
|
||||
val, err = parseDecimalFloat(v)
|
||||
default:
|
||||
return 0.0, fmt.Errorf("invalid info block")
|
||||
}
|
||||
if err != nil {
|
||||
return 0.0, err
|
||||
}
|
||||
|
||||
if val == 0.0 && !math.Signbit(val) {
|
||||
return 0.0, errors.New("REAL value +0 must be encoded with zero-length value block")
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func parseBinaryFloat(v []byte) (float64, error) {
|
||||
var info byte
|
||||
var buf []byte
|
||||
|
||||
info, v = v[0], v[1:]
|
||||
|
||||
var base int
|
||||
switch info & 0x30 {
|
||||
case 0x00:
|
||||
base = 2
|
||||
case 0x10:
|
||||
base = 8
|
||||
case 0x20:
|
||||
base = 16
|
||||
case 0x30:
|
||||
return 0.0, errors.New("bits 6 and 5 of information octet for REAL are equal to 11")
|
||||
}
|
||||
|
||||
scale := uint((info & 0x0c) >> 2)
|
||||
|
||||
var expLen int
|
||||
switch info & 0x03 {
|
||||
case 0x00:
|
||||
expLen = 1
|
||||
case 0x01:
|
||||
expLen = 2
|
||||
case 0x02:
|
||||
expLen = 3
|
||||
case 0x03:
|
||||
if len(v) < 2 {
|
||||
return 0.0, errors.New("invalid data")
|
||||
}
|
||||
expLen = int(v[0])
|
||||
if expLen > 8 {
|
||||
return 0.0, errors.New("too big value of exponent")
|
||||
}
|
||||
v = v[1:]
|
||||
}
|
||||
if expLen > len(v) {
|
||||
return 0.0, errors.New("too big value of exponent")
|
||||
}
|
||||
buf, v = v[:expLen], v[expLen:]
|
||||
exponent, err := ParseInt64(buf)
|
||||
if err != nil {
|
||||
return 0.0, err
|
||||
}
|
||||
|
||||
if len(v) > 8 {
|
||||
return 0.0, errors.New("too big value of mantissa")
|
||||
}
|
||||
|
||||
mant, err := ParseInt64(v)
|
||||
if err != nil {
|
||||
return 0.0, err
|
||||
}
|
||||
mantissa := mant << scale
|
||||
|
||||
if info&0x40 == 0x40 {
|
||||
mantissa = -mantissa
|
||||
}
|
||||
|
||||
return float64(mantissa) * math.Pow(float64(base), float64(exponent)), nil
|
||||
}
|
||||
|
||||
func parseDecimalFloat(v []byte) (val float64, err error) {
|
||||
switch v[0] & 0x3F {
|
||||
case 0x01: // NR form 1
|
||||
var iVal int64
|
||||
iVal, err = strconv.ParseInt(strings.TrimLeft(string(v[1:]), " "), 10, 64)
|
||||
val = float64(iVal)
|
||||
case 0x02, 0x03: // NR form 2, 3
|
||||
val, err = strconv.ParseFloat(strings.Replace(strings.TrimLeft(string(v[1:]), " "), ",", ".", -1), 64)
|
||||
default:
|
||||
err = errors.New("incorrect NR form")
|
||||
}
|
||||
if err != nil {
|
||||
return 0.0, err
|
||||
}
|
||||
|
||||
if val == 0.0 && math.Signbit(val) {
|
||||
return 0.0, errors.New("REAL value -0 must be encoded as a special value")
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func parseSpecialFloat(v []byte) (float64, error) {
|
||||
if len(v) != 1 {
|
||||
return 0.0, errors.New(`encoding of "special value" must not contain exponent and mantissa`)
|
||||
}
|
||||
switch v[0] {
|
||||
case 0x40:
|
||||
return math.Inf(1), nil
|
||||
case 0x41:
|
||||
return math.Inf(-1), nil
|
||||
case 0x42:
|
||||
return math.NaN(), nil
|
||||
case 0x43:
|
||||
return math.Copysign(0, -1), nil
|
||||
}
|
||||
return 0.0, errors.New(`encoding of "special value" not from ASN.1 standard`)
|
||||
}
|
28
vendor/github.com/go-asn1-ber/asn1-ber/util.go
generated
vendored
Normal file
28
vendor/github.com/go-asn1-ber/asn1-ber/util.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
package ber
|
||||
|
||||
import "io"
|
||||
|
||||
func readByte(reader io.Reader) (byte, error) {
|
||||
bytes := make([]byte, 1)
|
||||
_, err := io.ReadFull(reader, bytes)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return bytes[0], nil
|
||||
}
|
||||
|
||||
func unexpectedEOF(err error) error {
|
||||
if err == io.EOF {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func isEOCPacket(p *Packet) bool {
|
||||
return p != nil &&
|
||||
p.Tag == TagEOC &&
|
||||
p.ClassType == ClassUniversal &&
|
||||
p.TagType == TypePrimitive &&
|
||||
len(p.ByteValue) == 0 &&
|
||||
len(p.Children) == 0
|
||||
}
|
22
vendor/github.com/go-ldap/ldap/v3/LICENSE
generated
vendored
Normal file
22
vendor/github.com/go-ldap/ldap/v3/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)
|
||||
Portions copyright (c) 2015-2016 go-ldap Authors
|
||||
|
||||
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.
|
89
vendor/github.com/go-ldap/ldap/v3/add.go
generated
vendored
Normal file
89
vendor/github.com/go-ldap/ldap/v3/add.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
ber "github.com/go-asn1-ber/asn1-ber"
|
||||
)
|
||||
|
||||
// Attribute represents an LDAP attribute
|
||||
type Attribute struct {
|
||||
// Type is the name of the LDAP attribute
|
||||
Type string
|
||||
// Vals are the LDAP attribute values
|
||||
Vals []string
|
||||
}
|
||||
|
||||
func (a *Attribute) encode() *ber.Packet {
|
||||
seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attribute")
|
||||
seq.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, a.Type, "Type"))
|
||||
set := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSet, nil, "AttributeValue")
|
||||
for _, value := range a.Vals {
|
||||
set.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "Vals"))
|
||||
}
|
||||
seq.AppendChild(set)
|
||||
return seq
|
||||
}
|
||||
|
||||
// AddRequest represents an LDAP AddRequest operation
|
||||
type AddRequest struct {
|
||||
// DN identifies the entry being added
|
||||
DN string
|
||||
// Attributes list the attributes of the new entry
|
||||
Attributes []Attribute
|
||||
// Controls hold optional controls to send with the request
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
func (req *AddRequest) appendTo(envelope *ber.Packet) error {
|
||||
pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationAddRequest, nil, "Add Request")
|
||||
pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.DN, "DN"))
|
||||
attributes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Attributes")
|
||||
for _, attribute := range req.Attributes {
|
||||
attributes.AppendChild(attribute.encode())
|
||||
}
|
||||
pkt.AppendChild(attributes)
|
||||
|
||||
envelope.AppendChild(pkt)
|
||||
if len(req.Controls) > 0 {
|
||||
envelope.AppendChild(encodeControls(req.Controls))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Attribute adds an attribute with the given type and values
|
||||
func (req *AddRequest) Attribute(attrType string, attrVals []string) {
|
||||
req.Attributes = append(req.Attributes, Attribute{Type: attrType, Vals: attrVals})
|
||||
}
|
||||
|
||||
// NewAddRequest returns an AddRequest for the given DN, with no attributes
|
||||
func NewAddRequest(dn string, controls []Control) *AddRequest {
|
||||
return &AddRequest{
|
||||
DN: dn,
|
||||
Controls: controls,
|
||||
}
|
||||
}
|
||||
|
||||
// Add performs the given AddRequest
|
||||
func (l *Conn) Add(addRequest *AddRequest) error {
|
||||
msgCtx, err := l.doRequest(addRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if packet.Children[1].Tag == ApplicationAddResponse {
|
||||
err := GetLDAPError(packet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("ldap: unexpected response: %d", packet.Children[1].Tag)
|
||||
}
|
||||
return nil
|
||||
}
|
735
vendor/github.com/go-ldap/ldap/v3/bind.go
generated
vendored
Normal file
735
vendor/github.com/go-ldap/ldap/v3/bind.go
generated
vendored
Normal file
@@ -0,0 +1,735 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
enchex "encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-ntlmssp"
|
||||
ber "github.com/go-asn1-ber/asn1-ber"
|
||||
)
|
||||
|
||||
// SimpleBindRequest represents a username/password bind operation
|
||||
type SimpleBindRequest struct {
|
||||
// Username is the name of the Directory object that the client wishes to bind as
|
||||
Username string
|
||||
// Password is the credentials to bind with
|
||||
Password string
|
||||
// Controls are optional controls to send with the bind request
|
||||
Controls []Control
|
||||
// AllowEmptyPassword sets whether the client allows binding with an empty password
|
||||
// (normally used for unauthenticated bind).
|
||||
AllowEmptyPassword bool
|
||||
}
|
||||
|
||||
// SimpleBindResult contains the response from the server
|
||||
type SimpleBindResult struct {
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
// NewSimpleBindRequest returns a bind request
|
||||
func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest {
|
||||
return &SimpleBindRequest{
|
||||
Username: username,
|
||||
Password: password,
|
||||
Controls: controls,
|
||||
AllowEmptyPassword: false,
|
||||
}
|
||||
}
|
||||
|
||||
func (req *SimpleBindRequest) appendTo(envelope *ber.Packet) error {
|
||||
pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
||||
pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
||||
pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.Username, "User Name"))
|
||||
pkt.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, req.Password, "Password"))
|
||||
|
||||
envelope.AppendChild(pkt)
|
||||
if len(req.Controls) > 0 {
|
||||
envelope.AppendChild(encodeControls(req.Controls))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SimpleBind performs the simple bind operation defined in the given request
|
||||
func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) {
|
||||
if simpleBindRequest.Password == "" && !simpleBindRequest.AllowEmptyPassword {
|
||||
return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client"))
|
||||
}
|
||||
|
||||
msgCtx, err := l.doRequest(simpleBindRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &SimpleBindResult{
|
||||
Controls: make([]Control, 0),
|
||||
}
|
||||
|
||||
if len(packet.Children) == 3 {
|
||||
for _, child := range packet.Children[2].Children {
|
||||
decodedChild, decodeErr := DecodeControl(child)
|
||||
if decodeErr != nil {
|
||||
return nil, fmt.Errorf("failed to decode child control: %s", decodeErr)
|
||||
}
|
||||
result.Controls = append(result.Controls, decodedChild)
|
||||
}
|
||||
}
|
||||
|
||||
err = GetLDAPError(packet)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Bind performs a bind with the given username and password.
|
||||
//
|
||||
// It does not allow unauthenticated bind (i.e. empty password). Use the UnauthenticatedBind method
|
||||
// for that.
|
||||
func (l *Conn) Bind(username, password string) error {
|
||||
req := &SimpleBindRequest{
|
||||
Username: username,
|
||||
Password: password,
|
||||
AllowEmptyPassword: false,
|
||||
}
|
||||
_, err := l.SimpleBind(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// UnauthenticatedBind performs an unauthenticated bind.
|
||||
//
|
||||
// A username may be provided for trace (e.g. logging) purpose only, but it is normally not
|
||||
// authenticated or otherwise validated by the LDAP server.
|
||||
//
|
||||
// See https://tools.ietf.org/html/rfc4513#section-5.1.2 .
|
||||
// See https://tools.ietf.org/html/rfc4513#section-6.3.1 .
|
||||
func (l *Conn) UnauthenticatedBind(username string) error {
|
||||
req := &SimpleBindRequest{
|
||||
Username: username,
|
||||
Password: "",
|
||||
AllowEmptyPassword: true,
|
||||
}
|
||||
_, err := l.SimpleBind(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// DigestMD5BindRequest represents a digest-md5 bind operation
|
||||
type DigestMD5BindRequest struct {
|
||||
Host string
|
||||
// Username is the name of the Directory object that the client wishes to bind as
|
||||
Username string
|
||||
// Password is the credentials to bind with
|
||||
Password string
|
||||
// Controls are optional controls to send with the bind request
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
func (req *DigestMD5BindRequest) appendTo(envelope *ber.Packet) error {
|
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name"))
|
||||
|
||||
auth := ber.Encode(ber.ClassContext, ber.TypeConstructed, 3, "", "authentication")
|
||||
auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "DIGEST-MD5", "SASL Mech"))
|
||||
request.AppendChild(auth)
|
||||
envelope.AppendChild(request)
|
||||
if len(req.Controls) > 0 {
|
||||
envelope.AppendChild(encodeControls(req.Controls))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DigestMD5BindResult contains the response from the server
|
||||
type DigestMD5BindResult struct {
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
// MD5Bind performs a digest-md5 bind with the given host, username and password.
|
||||
func (l *Conn) MD5Bind(host, username, password string) error {
|
||||
req := &DigestMD5BindRequest{
|
||||
Host: host,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
_, err := l.DigestMD5Bind(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// DigestMD5Bind performs the digest-md5 bind operation defined in the given request
|
||||
func (l *Conn) DigestMD5Bind(digestMD5BindRequest *DigestMD5BindRequest) (*DigestMD5BindResult, error) {
|
||||
if digestMD5BindRequest.Password == "" {
|
||||
return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client"))
|
||||
}
|
||||
|
||||
msgCtx, err := l.doRequest(digestMD5BindRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||
if l.Debug {
|
||||
if err = addLDAPDescriptions(packet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ber.PrintPacket(packet)
|
||||
}
|
||||
|
||||
result := &DigestMD5BindResult{
|
||||
Controls: make([]Control, 0),
|
||||
}
|
||||
var params map[string]string
|
||||
if len(packet.Children) == 2 {
|
||||
if len(packet.Children[1].Children) == 4 {
|
||||
child := packet.Children[1].Children[0]
|
||||
if child.Tag != ber.TagEnumerated {
|
||||
return result, GetLDAPError(packet)
|
||||
}
|
||||
if child.Value.(int64) != 14 {
|
||||
return result, GetLDAPError(packet)
|
||||
}
|
||||
child = packet.Children[1].Children[3]
|
||||
if child.Tag != ber.TagObjectDescriptor {
|
||||
return result, GetLDAPError(packet)
|
||||
}
|
||||
if child.Data == nil {
|
||||
return result, GetLDAPError(packet)
|
||||
}
|
||||
data, _ := ioutil.ReadAll(child.Data)
|
||||
params, err = parseParams(string(data))
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("parsing digest-challenge: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if params != nil {
|
||||
resp := computeResponse(
|
||||
params,
|
||||
"ldap/"+strings.ToLower(digestMD5BindRequest.Host),
|
||||
digestMD5BindRequest.Username,
|
||||
digestMD5BindRequest.Password,
|
||||
)
|
||||
packet = ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||
|
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name"))
|
||||
|
||||
auth := ber.Encode(ber.ClassContext, ber.TypeConstructed, 3, "", "authentication")
|
||||
auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "DIGEST-MD5", "SASL Mech"))
|
||||
auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, resp, "Credentials"))
|
||||
request.AppendChild(auth)
|
||||
packet.AppendChild(request)
|
||||
msgCtx, err = l.sendMessage(packet)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("send message: %s", err)
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
packetResponse, ok := <-msgCtx.responses
|
||||
if !ok {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
|
||||
}
|
||||
packet, err = packetResponse.ReadPacket()
|
||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read packet: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = GetLDAPError(packet)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func parseParams(str string) (map[string]string, error) {
|
||||
m := make(map[string]string)
|
||||
var key, value string
|
||||
var state int
|
||||
for i := 0; i <= len(str); i++ {
|
||||
switch state {
|
||||
case 0: // reading key
|
||||
if i == len(str) {
|
||||
return nil, fmt.Errorf("syntax error on %d", i)
|
||||
}
|
||||
if str[i] != '=' {
|
||||
key += string(str[i])
|
||||
continue
|
||||
}
|
||||
state = 1
|
||||
case 1: // reading value
|
||||
if i == len(str) {
|
||||
m[key] = value
|
||||
break
|
||||
}
|
||||
switch str[i] {
|
||||
case ',':
|
||||
m[key] = value
|
||||
state = 0
|
||||
key = ""
|
||||
value = ""
|
||||
case '"':
|
||||
if value != "" {
|
||||
return nil, fmt.Errorf("syntax error on %d", i)
|
||||
}
|
||||
state = 2
|
||||
default:
|
||||
value += string(str[i])
|
||||
}
|
||||
case 2: // inside quotes
|
||||
if i == len(str) {
|
||||
return nil, fmt.Errorf("syntax error on %d", i)
|
||||
}
|
||||
if str[i] != '"' {
|
||||
value += string(str[i])
|
||||
} else {
|
||||
state = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func computeResponse(params map[string]string, uri, username, password string) string {
|
||||
nc := "00000001"
|
||||
qop := "auth"
|
||||
cnonce := enchex.EncodeToString(randomBytes(16))
|
||||
x := username + ":" + params["realm"] + ":" + password
|
||||
y := md5Hash([]byte(x))
|
||||
|
||||
a1 := bytes.NewBuffer(y)
|
||||
a1.WriteString(":" + params["nonce"] + ":" + cnonce)
|
||||
if len(params["authzid"]) > 0 {
|
||||
a1.WriteString(":" + params["authzid"])
|
||||
}
|
||||
a2 := bytes.NewBuffer([]byte("AUTHENTICATE"))
|
||||
a2.WriteString(":" + uri)
|
||||
ha1 := enchex.EncodeToString(md5Hash(a1.Bytes()))
|
||||
ha2 := enchex.EncodeToString(md5Hash(a2.Bytes()))
|
||||
|
||||
kd := ha1
|
||||
kd += ":" + params["nonce"]
|
||||
kd += ":" + nc
|
||||
kd += ":" + cnonce
|
||||
kd += ":" + qop
|
||||
kd += ":" + ha2
|
||||
resp := enchex.EncodeToString(md5Hash([]byte(kd)))
|
||||
return fmt.Sprintf(
|
||||
`username="%s",realm="%s",nonce="%s",cnonce="%s",nc=00000001,qop=%s,digest-uri="%s",response=%s`,
|
||||
username,
|
||||
params["realm"],
|
||||
params["nonce"],
|
||||
cnonce,
|
||||
qop,
|
||||
uri,
|
||||
resp,
|
||||
)
|
||||
}
|
||||
|
||||
func md5Hash(b []byte) []byte {
|
||||
hasher := md5.New()
|
||||
hasher.Write(b)
|
||||
return hasher.Sum(nil)
|
||||
}
|
||||
|
||||
func randomBytes(len int) []byte {
|
||||
b := make([]byte, len)
|
||||
for i := 0; i < len; i++ {
|
||||
b[i] = byte(rand.Intn(256))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
var externalBindRequest = requestFunc(func(envelope *ber.Packet) error {
|
||||
pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
||||
pkt.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
||||
pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name"))
|
||||
|
||||
saslAuth := ber.Encode(ber.ClassContext, ber.TypeConstructed, 3, "", "authentication")
|
||||
saslAuth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "EXTERNAL", "SASL Mech"))
|
||||
saslAuth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "SASL Cred"))
|
||||
|
||||
pkt.AppendChild(saslAuth)
|
||||
|
||||
envelope.AppendChild(pkt)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
// ExternalBind performs SASL/EXTERNAL authentication.
|
||||
//
|
||||
// Use ldap.DialURL("ldapi://") to connect to the Unix socket before ExternalBind.
|
||||
//
|
||||
// See https://tools.ietf.org/html/rfc4422#appendix-A
|
||||
func (l *Conn) ExternalBind() error {
|
||||
msgCtx, err := l.doRequest(externalBindRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return GetLDAPError(packet)
|
||||
}
|
||||
|
||||
// NTLMBind performs an NTLMSSP bind leveraging https://github.com/Azure/go-ntlmssp
|
||||
|
||||
// NTLMBindRequest represents an NTLMSSP bind operation
|
||||
type NTLMBindRequest struct {
|
||||
// Domain is the AD Domain to authenticate too. If not specified, it will be grabbed from the NTLMSSP Challenge
|
||||
Domain string
|
||||
// Username is the name of the Directory object that the client wishes to bind as
|
||||
Username string
|
||||
// Password is the credentials to bind with
|
||||
Password string
|
||||
// AllowEmptyPassword sets whether the client allows binding with an empty password
|
||||
// (normally used for unauthenticated bind).
|
||||
AllowEmptyPassword bool
|
||||
// Hash is the hex NTLM hash to bind with. Password or hash must be provided
|
||||
Hash string
|
||||
// Controls are optional controls to send with the bind request
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
func (req *NTLMBindRequest) appendTo(envelope *ber.Packet) error {
|
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name"))
|
||||
|
||||
// generate an NTLMSSP Negotiation message for the specified domain (it can be blank)
|
||||
negMessage, err := ntlmssp.NewNegotiateMessage(req.Domain, "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("err creating negmessage: %s", err)
|
||||
}
|
||||
|
||||
// append the generated NTLMSSP message as a TagEnumerated BER value
|
||||
auth := ber.Encode(ber.ClassContext, ber.TypePrimitive, ber.TagEnumerated, negMessage, "authentication")
|
||||
request.AppendChild(auth)
|
||||
envelope.AppendChild(request)
|
||||
if len(req.Controls) > 0 {
|
||||
envelope.AppendChild(encodeControls(req.Controls))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NTLMBindResult contains the response from the server
|
||||
type NTLMBindResult struct {
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
// NTLMBind performs an NTLMSSP Bind with the given domain, username and password
|
||||
func (l *Conn) NTLMBind(domain, username, password string) error {
|
||||
req := &NTLMBindRequest{
|
||||
Domain: domain,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
_, err := l.NTLMChallengeBind(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// NTLMUnauthenticatedBind performs an bind with an empty password.
|
||||
//
|
||||
// A username is required. The anonymous bind is not (yet) supported by the go-ntlmssp library (https://github.com/Azure/go-ntlmssp/blob/819c794454d067543bc61d29f61fef4b3c3df62c/authenticate_message.go#L87)
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b38c36ed-2804-4868-a9ff-8dd3182128e4 part 3.2.5.1.2
|
||||
func (l *Conn) NTLMUnauthenticatedBind(domain, username string) error {
|
||||
req := &NTLMBindRequest{
|
||||
Domain: domain,
|
||||
Username: username,
|
||||
Password: "",
|
||||
AllowEmptyPassword: true,
|
||||
}
|
||||
_, err := l.NTLMChallengeBind(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// NTLMBindWithHash performs an NTLM Bind with an NTLM hash instead of plaintext password (pass-the-hash)
|
||||
func (l *Conn) NTLMBindWithHash(domain, username, hash string) error {
|
||||
req := &NTLMBindRequest{
|
||||
Domain: domain,
|
||||
Username: username,
|
||||
Hash: hash,
|
||||
}
|
||||
_, err := l.NTLMChallengeBind(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// NTLMChallengeBind performs the NTLMSSP bind operation defined in the given request
|
||||
func (l *Conn) NTLMChallengeBind(ntlmBindRequest *NTLMBindRequest) (*NTLMBindResult, error) {
|
||||
if !ntlmBindRequest.AllowEmptyPassword && ntlmBindRequest.Password == "" && ntlmBindRequest.Hash == "" {
|
||||
return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client"))
|
||||
}
|
||||
|
||||
msgCtx, err := l.doRequest(ntlmBindRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||
if l.Debug {
|
||||
if err = addLDAPDescriptions(packet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ber.PrintPacket(packet)
|
||||
}
|
||||
result := &NTLMBindResult{
|
||||
Controls: make([]Control, 0),
|
||||
}
|
||||
var ntlmsspChallenge []byte
|
||||
|
||||
// now find the NTLM Response Message
|
||||
if len(packet.Children) == 2 {
|
||||
if len(packet.Children[1].Children) == 3 {
|
||||
child := packet.Children[1].Children[1]
|
||||
ntlmsspChallenge = child.ByteValue
|
||||
// Check to make sure we got the right message. It will always start with NTLMSSP
|
||||
if len(ntlmsspChallenge) < 7 || !bytes.Equal(ntlmsspChallenge[:7], []byte("NTLMSSP")) {
|
||||
return result, GetLDAPError(packet)
|
||||
}
|
||||
l.Debug.Printf("%d: found ntlmssp challenge", msgCtx.id)
|
||||
}
|
||||
}
|
||||
if ntlmsspChallenge != nil {
|
||||
var err error
|
||||
var responseMessage []byte
|
||||
// generate a response message to the challenge with the given Username/Password if password is provided
|
||||
if ntlmBindRequest.Hash != "" {
|
||||
responseMessage, err = ntlmssp.ProcessChallengeWithHash(ntlmsspChallenge, ntlmBindRequest.Username, ntlmBindRequest.Hash)
|
||||
} else if ntlmBindRequest.Password != "" || ntlmBindRequest.AllowEmptyPassword {
|
||||
_, _, domainNeeded := ntlmssp.GetDomain(ntlmBindRequest.Username)
|
||||
responseMessage, err = ntlmssp.ProcessChallenge(ntlmsspChallenge, ntlmBindRequest.Username, ntlmBindRequest.Password, domainNeeded)
|
||||
} else {
|
||||
err = fmt.Errorf("need a password or hash to generate reply")
|
||||
}
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("parsing ntlm-challenge: %s", err)
|
||||
}
|
||||
packet = ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||
|
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name"))
|
||||
|
||||
// append the challenge response message as a TagEmbeddedPDV BER value
|
||||
auth := ber.Encode(ber.ClassContext, ber.TypePrimitive, ber.TagEmbeddedPDV, responseMessage, "authentication")
|
||||
|
||||
request.AppendChild(auth)
|
||||
packet.AppendChild(request)
|
||||
msgCtx, err = l.sendMessage(packet)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("send message: %s", err)
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
packetResponse, ok := <-msgCtx.responses
|
||||
if !ok {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
|
||||
}
|
||||
packet, err = packetResponse.ReadPacket()
|
||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read packet: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = GetLDAPError(packet)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GSSAPIClient interface is used as the client-side implementation for the
|
||||
// GSSAPI SASL mechanism.
|
||||
// Interface inspired by GSSAPIClient from golang.org/x/crypto/ssh
|
||||
type GSSAPIClient interface {
|
||||
// InitSecContext initiates the establishment of a security context for
|
||||
// GSS-API between the client and server.
|
||||
// Initially the token parameter should be specified as nil.
|
||||
// The routine may return a outputToken which should be transferred to
|
||||
// the server, where the server will present it to AcceptSecContext.
|
||||
// If no token need be sent, InitSecContext will indicate this by setting
|
||||
// needContinue to false. To complete the context
|
||||
// establishment, one or more reply tokens may be required from the server;
|
||||
// if so, InitSecContext will return a needContinue which is true.
|
||||
// In this case, InitSecContext should be called again when the
|
||||
// reply token is received from the server, passing the reply token
|
||||
// to InitSecContext via the token parameters.
|
||||
// See RFC 4752 section 3.1.
|
||||
InitSecContext(target string, token []byte) (outputToken []byte, needContinue bool, err error)
|
||||
// NegotiateSaslAuth performs the last step of the Sasl handshake.
|
||||
// It takes a token, which, when unwrapped, describes the servers supported
|
||||
// security layers (first octet) and maximum receive buffer (remaining
|
||||
// three octets).
|
||||
// If the received token is unacceptable an error must be returned to abort
|
||||
// the handshake.
|
||||
// Outputs a signed token describing the client's selected security layer
|
||||
// and receive buffer size and optionally an authorization identity.
|
||||
// The returned token will be sent to the server and the handshake considered
|
||||
// completed successfully and the server authenticated.
|
||||
// See RFC 4752 section 3.1.
|
||||
NegotiateSaslAuth(token []byte, authzid string) ([]byte, error)
|
||||
// DeleteSecContext destroys any established secure context.
|
||||
DeleteSecContext() error
|
||||
}
|
||||
|
||||
// GSSAPIBindRequest represents a GSSAPI SASL mechanism bind request.
|
||||
// See rfc4752 and rfc4513 section 5.2.1.2.
|
||||
type GSSAPIBindRequest struct {
|
||||
// Service Principal Name user for the service ticket. Eg. "ldap/<host>"
|
||||
ServicePrincipalName string
|
||||
// (Optional) Authorization entity
|
||||
AuthZID string
|
||||
// (Optional) Controls to send with the bind request
|
||||
Controls []Control
|
||||
}
|
||||
|
||||
// GSSAPIBind performs the GSSAPI SASL bind using the provided GSSAPI client.
|
||||
func (l *Conn) GSSAPIBind(client GSSAPIClient, servicePrincipal, authzid string) error {
|
||||
return l.GSSAPIBindRequest(client, &GSSAPIBindRequest{
|
||||
ServicePrincipalName: servicePrincipal,
|
||||
AuthZID: authzid,
|
||||
})
|
||||
}
|
||||
|
||||
// GSSAPIBindRequest performs the GSSAPI SASL bind using the provided GSSAPI client.
|
||||
func (l *Conn) GSSAPIBindRequest(client GSSAPIClient, req *GSSAPIBindRequest) error {
|
||||
//nolint:errcheck
|
||||
defer client.DeleteSecContext()
|
||||
|
||||
var err error
|
||||
var reqToken []byte
|
||||
var recvToken []byte
|
||||
needInit := true
|
||||
for {
|
||||
if needInit {
|
||||
// Establish secure context between client and server.
|
||||
reqToken, needInit, err = client.InitSecContext(req.ServicePrincipalName, recvToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Secure context is set up, perform the last step of SASL handshake.
|
||||
reqToken, err = client.NegotiateSaslAuth(recvToken, req.AuthZID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Send Bind request containing the current token and extract the
|
||||
// token sent by server.
|
||||
recvToken, err = l.saslBindTokenExchange(req.Controls, reqToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !needInit && len(recvToken) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Conn) saslBindTokenExchange(reqControls []Control, reqToken []byte) ([]byte, error) {
|
||||
// Construct LDAP Bind request with GSSAPI SASL mechanism.
|
||||
envelope := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||
envelope.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||
|
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
||||
request.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "", "User Name"))
|
||||
|
||||
auth := ber.Encode(ber.ClassContext, ber.TypeConstructed, 3, "", "authentication")
|
||||
auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, "GSSAPI", "SASL Mech"))
|
||||
if len(reqToken) > 0 {
|
||||
auth.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, string(reqToken), "Credentials"))
|
||||
}
|
||||
request.AppendChild(auth)
|
||||
envelope.AppendChild(request)
|
||||
if len(reqControls) > 0 {
|
||||
envelope.AppendChild(encodeControls(reqControls))
|
||||
}
|
||||
|
||||
msgCtx, err := l.sendMessage(envelope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||
if l.Debug {
|
||||
if err = addLDAPDescriptions(packet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ber.PrintPacket(packet)
|
||||
}
|
||||
|
||||
// https://www.rfc-editor.org/rfc/rfc4511#section-4.1.1
|
||||
// packet is an envelope
|
||||
// child 0 is message id
|
||||
// child 1 is protocolOp
|
||||
if len(packet.Children) != 2 {
|
||||
return nil, fmt.Errorf("bad bind response")
|
||||
}
|
||||
|
||||
protocolOp := packet.Children[1]
|
||||
RESP:
|
||||
switch protocolOp.Description {
|
||||
case "Bind Response": // Bind Response
|
||||
// Bind Reponse is an LDAP Response (https://www.rfc-editor.org/rfc/rfc4511#section-4.1.9)
|
||||
// with an additional optional serverSaslCreds string (https://www.rfc-editor.org/rfc/rfc4511#section-4.2.2)
|
||||
// child 0 is resultCode
|
||||
resultCode := protocolOp.Children[0]
|
||||
if resultCode.Tag != ber.TagEnumerated {
|
||||
break RESP
|
||||
}
|
||||
switch resultCode.Value.(int64) {
|
||||
case 14: // Sasl bind in progress
|
||||
if len(protocolOp.Children) < 3 {
|
||||
break RESP
|
||||
}
|
||||
referral := protocolOp.Children[3]
|
||||
switch referral.Description {
|
||||
case "Referral":
|
||||
if referral.ClassType != ber.ClassContext || referral.Tag != ber.TagObjectDescriptor {
|
||||
break RESP
|
||||
}
|
||||
return ioutil.ReadAll(referral.Data)
|
||||
}
|
||||
// Optional:
|
||||
//if len(protocolOp.Children) == 4 {
|
||||
// serverSaslCreds := protocolOp.Children[4]
|
||||
//}
|
||||
case 0: // Success - Bind OK.
|
||||
// SASL layer in effect (if any) (See https://www.rfc-editor.org/rfc/rfc4513#section-5.2.1.4)
|
||||
// NOTE: SASL security layers are not supported currently.
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, GetLDAPError(packet)
|
||||
}
|
41
vendor/github.com/go-ldap/ldap/v3/client.go
generated
vendored
Normal file
41
vendor/github.com/go-ldap/ldap/v3/client.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Client knows how to interact with an LDAP server
|
||||
type Client interface {
|
||||
Start()
|
||||
StartTLS(*tls.Config) error
|
||||
Close() error
|
||||
GetLastError() error
|
||||
IsClosing() bool
|
||||
SetTimeout(time.Duration)
|
||||
TLSConnectionState() (tls.ConnectionState, bool)
|
||||
|
||||
Bind(username, password string) error
|
||||
UnauthenticatedBind(username string) error
|
||||
SimpleBind(*SimpleBindRequest) (*SimpleBindResult, error)
|
||||
ExternalBind() error
|
||||
NTLMUnauthenticatedBind(domain, username string) error
|
||||
Unbind() error
|
||||
|
||||
Add(*AddRequest) error
|
||||
Del(*DelRequest) error
|
||||
Modify(*ModifyRequest) error
|
||||
ModifyDN(*ModifyDNRequest) error
|
||||
ModifyWithResult(*ModifyRequest) (*ModifyResult, error)
|
||||
|
||||
Compare(dn, attribute, value string) (bool, error)
|
||||
PasswordModify(*PasswordModifyRequest) (*PasswordModifyResult, error)
|
||||
|
||||
Search(*SearchRequest) (*SearchResult, error)
|
||||
SearchAsync(ctx context.Context, searchRequest *SearchRequest, bufferSize int) Response
|
||||
SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32) (*SearchResult, error)
|
||||
DirSync(searchRequest *SearchRequest, flags, maxAttrCount int64, cookie []byte) (*SearchResult, error)
|
||||
DirSyncAsync(ctx context.Context, searchRequest *SearchRequest, bufferSize int, flags, maxAttrCount int64, cookie []byte) Response
|
||||
Syncrepl(ctx context.Context, searchRequest *SearchRequest, bufferSize int, mode ControlSyncRequestMode, cookie []byte, reloadHint bool) Response
|
||||
}
|
62
vendor/github.com/go-ldap/ldap/v3/compare.go
generated
vendored
Normal file
62
vendor/github.com/go-ldap/ldap/v3/compare.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
ber "github.com/go-asn1-ber/asn1-ber"
|
||||
)
|
||||
|
||||
// CompareRequest represents an LDAP CompareRequest operation.
|
||||
type CompareRequest struct {
|
||||
DN string
|
||||
Attribute string
|
||||
Value string
|
||||
}
|
||||
|
||||
func (req *CompareRequest) appendTo(envelope *ber.Packet) error {
|
||||
pkt := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationCompareRequest, nil, "Compare Request")
|
||||
pkt.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.DN, "DN"))
|
||||
|
||||
ava := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "AttributeValueAssertion")
|
||||
ava.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.Attribute, "AttributeDesc"))
|
||||
ava.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, req.Value, "AssertionValue"))
|
||||
|
||||
pkt.AppendChild(ava)
|
||||
|
||||
envelope.AppendChild(pkt)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compare checks to see if the attribute of the dn matches value. Returns true if it does otherwise
|
||||
// false with any error that occurs if any.
|
||||
func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
|
||||
msgCtx, err := l.doRequest(&CompareRequest{
|
||||
DN: dn,
|
||||
Attribute: attribute,
|
||||
Value: value,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
packet, err := l.readPacket(msgCtx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if packet.Children[1].Tag == ApplicationCompareResponse {
|
||||
err := GetLDAPError(packet)
|
||||
|
||||
switch {
|
||||
case IsErrorWithCode(err, LDAPResultCompareTrue):
|
||||
return true, nil
|
||||
case IsErrorWithCode(err, LDAPResultCompareFalse):
|
||||
return false, nil
|
||||
default:
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("unexpected Response: %d", packet.Children[1].Tag)
|
||||
}
|
629
vendor/github.com/go-ldap/ldap/v3/conn.go
generated
vendored
Normal file
629
vendor/github.com/go-ldap/ldap/v3/conn.go
generated
vendored
Normal file
@@ -0,0 +1,629 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
ber "github.com/go-asn1-ber/asn1-ber"
|
||||
)
|
||||
|
||||
const (
|
||||
// MessageQuit causes the processMessages loop to exit
|
||||
MessageQuit = 0
|
||||
// MessageRequest sends a request to the server
|
||||
MessageRequest = 1
|
||||
// MessageResponse receives a response from the server
|
||||
MessageResponse = 2
|
||||
// MessageFinish indicates the client considers a particular message ID to be finished
|
||||
MessageFinish = 3
|
||||
// MessageTimeout indicates the client-specified timeout for a particular message ID has been reached
|
||||
MessageTimeout = 4
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultLdapPort default ldap port for pure TCP connection
|
||||
DefaultLdapPort = "389"
|
||||
// DefaultLdapsPort default ldap port for SSL connection
|
||||
DefaultLdapsPort = "636"
|
||||
)
|
||||
|
||||
// PacketResponse contains the packet or error encountered reading a response
|
||||
type PacketResponse struct {
|
||||
// Packet is the packet read from the server
|
||||
Packet *ber.Packet
|
||||
// Error is an error encountered while reading
|
||||
Error error
|
||||
}
|
||||
|
||||
// ReadPacket returns the packet or an error
|
||||
func (pr *PacketResponse) ReadPacket() (*ber.Packet, error) {
|
||||
if (pr == nil) || (pr.Packet == nil && pr.Error == nil) {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve response"))
|
||||
}
|
||||
return pr.Packet, pr.Error
|
||||
}
|
||||
|
||||
type messageContext struct {
|
||||
id int64
|
||||
// close(done) should only be called from finishMessage()
|
||||
done chan struct{}
|
||||
// close(responses) should only be called from processMessages(), and only sent to from sendResponse()
|
||||
responses chan *PacketResponse
|
||||
}
|
||||
|
||||
// sendResponse should only be called within the processMessages() loop which
|
||||
// is also responsible for closing the responses channel.
|
||||
func (msgCtx *messageContext) sendResponse(packet *PacketResponse, timeout time.Duration) {
|
||||
timeoutCtx := context.Background()
|
||||
if timeout > 0 {
|
||||
var cancelFunc context.CancelFunc
|
||||
timeoutCtx, cancelFunc = context.WithTimeout(context.Background(), timeout)
|
||||
defer cancelFunc()
|
||||
}
|
||||
select {
|
||||
case msgCtx.responses <- packet:
|
||||
// Successfully sent packet to message handler.
|
||||
case <-msgCtx.done:
|
||||
// The request handler is done and will not receive more
|
||||
// packets.
|
||||
case <-timeoutCtx.Done():
|
||||
// The timeout was reached before the packet was sent.
|
||||
}
|
||||
}
|
||||
|
||||
type messagePacket struct {
|
||||
Op int
|
||||
MessageID int64
|
||||
Packet *ber.Packet
|
||||
Context *messageContext
|
||||
}
|
||||
|
||||
type sendMessageFlags uint
|
||||
|
||||
const (
|
||||
startTLS sendMessageFlags = 1 << iota
|
||||
)
|
||||
|
||||
// Conn represents an LDAP Connection
|
||||
type Conn struct {
|
||||
// requestTimeout is loaded atomically
|
||||
// so we need to ensure 64-bit alignment on 32-bit platforms.
|
||||
// https://github.com/go-ldap/ldap/pull/199
|
||||
requestTimeout int64
|
||||
conn net.Conn
|
||||
isTLS bool
|
||||
closing uint32
|
||||
closeErr atomic.Value
|
||||
isStartingTLS bool
|
||||
Debug debugging
|
||||
chanConfirm chan struct{}
|
||||
messageContexts map[int64]*messageContext
|
||||
chanMessage chan *messagePacket
|
||||
chanMessageID chan int64
|
||||
wgClose sync.WaitGroup
|
||||
outstandingRequests uint
|
||||
messageMutex sync.Mutex
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
var _ Client = &Conn{}
|
||||
|
||||
// DefaultTimeout is a package-level variable that sets the timeout value
|
||||
// used for the Dial and DialTLS methods.
|
||||
//
|
||||
// WARNING: since this is a package-level variable, setting this value from
|
||||
// multiple places will probably result in undesired behaviour.
|
||||
var DefaultTimeout = 60 * time.Second
|
||||
|
||||
// DialOpt configures DialContext.
|
||||
type DialOpt func(*DialContext)
|
||||
|
||||
// DialWithDialer updates net.Dialer in DialContext.
|
||||
func DialWithDialer(d *net.Dialer) DialOpt {
|
||||
return func(dc *DialContext) {
|
||||
dc.dialer = d
|
||||
}
|
||||
}
|
||||
|
||||
// DialWithTLSConfig updates tls.Config in DialContext.
|
||||
func DialWithTLSConfig(tc *tls.Config) DialOpt {
|
||||
return func(dc *DialContext) {
|
||||
dc.tlsConfig = tc
|
||||
}
|
||||
}
|
||||
|
||||
// DialWithTLSDialer is a wrapper for DialWithTLSConfig with the option to
|
||||
// specify a net.Dialer to for example define a timeout or a custom resolver.
|
||||
// @deprecated Use DialWithDialer and DialWithTLSConfig instead
|
||||
func DialWithTLSDialer(tlsConfig *tls.Config, dialer *net.Dialer) DialOpt {
|
||||
return func(dc *DialContext) {
|
||||
dc.tlsConfig = tlsConfig
|
||||
dc.dialer = dialer
|
||||
}
|
||||
}
|
||||
|
||||
// DialContext contains necessary parameters to dial the given ldap URL.
|
||||
type DialContext struct {
|
||||
dialer *net.Dialer
|
||||
tlsConfig *tls.Config
|
||||
}
|
||||
|
||||
func (dc *DialContext) dial(u *url.URL) (net.Conn, error) {
|
||||
if u.Scheme == "ldapi" {
|
||||
if u.Path == "" || u.Path == "/" {
|
||||
u.Path = "/var/run/slapd/ldapi"
|
||||
}
|
||||
return dc.dialer.Dial("unix", u.Path)
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(u.Host)
|
||||
if err != nil {
|
||||
// we assume that error is due to missing port
|
||||
host = u.Host
|
||||
port = ""
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "cldap":
|
||||
if port == "" {
|
||||
port = DefaultLdapPort
|
||||
}
|
||||
return dc.dialer.Dial("udp", net.JoinHostPort(host, port))
|
||||
case "ldap":
|
||||
if port == "" {
|
||||
port = DefaultLdapPort
|
||||
}
|
||||
return dc.dialer.Dial("tcp", net.JoinHostPort(host, port))
|
||||
case "ldaps":
|
||||
if port == "" {
|
||||
port = DefaultLdapsPort
|
||||
}
|
||||
return tls.DialWithDialer(dc.dialer, "tcp", net.JoinHostPort(host, port), dc.tlsConfig)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Unknown scheme '%s'", u.Scheme)
|
||||
}
|
||||
|
||||
// Dial connects to the given address on the given network using net.Dial
|
||||
// and then returns a new Conn for the connection.
|
||||
// @deprecated Use DialURL instead.
|
||||
func Dial(network, addr string) (*Conn, error) {
|
||||
c, err := net.DialTimeout(network, addr, DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, NewError(ErrorNetwork, err)
|
||||
}
|
||||
conn := NewConn(c, false)
|
||||
conn.Start()
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// DialTLS connects to the given address on the given network using tls.Dial
|
||||
// and then returns a new Conn for the connection.
|
||||
// @deprecated Use DialURL instead.
|
||||
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
|
||||
c, err := tls.DialWithDialer(&net.Dialer{Timeout: DefaultTimeout}, network, addr, config)
|
||||
if err != nil {
|
||||
return nil, NewError(ErrorNetwork, err)
|
||||
}
|
||||
conn := NewConn(c, true)
|
||||
conn.Start()
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// DialURL connects to the given ldap URL.
|
||||
// The following schemas are supported: ldap://, ldaps://, ldapi://,
|
||||
// and cldap:// (RFC1798, deprecated but used by Active Directory).
|
||||
// On success a new Conn for the connection is returned.
|
||||
func DialURL(addr string, opts ...DialOpt) (*Conn, error) {
|
||||
u, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return nil, NewError(ErrorNetwork, err)
|
||||
}
|
||||
|
||||
var dc DialContext
|
||||
for _, opt := range opts {
|
||||
opt(&dc)
|
||||
}
|
||||
if dc.dialer == nil {
|
||||
dc.dialer = &net.Dialer{Timeout: DefaultTimeout}
|
||||
}
|
||||
|
||||
c, err := dc.dial(u)
|
||||
if err != nil {
|
||||
return nil, NewError(ErrorNetwork, err)
|
||||
}
|
||||
|
||||
conn := NewConn(c, u.Scheme == "ldaps")
|
||||
conn.Start()
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// NewConn returns a new Conn using conn for network I/O.
|
||||
func NewConn(conn net.Conn, isTLS bool) *Conn {
|
||||
l := &Conn{
|
||||
conn: conn,
|
||||
chanConfirm: make(chan struct{}),
|
||||
chanMessageID: make(chan int64),
|
||||
chanMessage: make(chan *messagePacket, 10),
|
||||
messageContexts: map[int64]*messageContext{},
|
||||
requestTimeout: 0,
|
||||
isTLS: isTLS,
|
||||
}
|
||||
l.wgClose.Add(1)
|
||||
return l
|
||||
}
|
||||
|
||||
// Start initializes goroutines to read responses and process messages
|
||||
func (l *Conn) Start() {
|
||||
go l.reader()
|
||||
go l.processMessages()
|
||||
}
|
||||
|
||||
// IsClosing returns whether or not we're currently closing.
|
||||
func (l *Conn) IsClosing() bool {
|
||||
return atomic.LoadUint32(&l.closing) == 1
|
||||
}
|
||||
|
||||
// setClosing sets the closing value to true
|
||||
func (l *Conn) setClosing() bool {
|
||||
return atomic.CompareAndSwapUint32(&l.closing, 0, 1)
|
||||
}
|
||||
|
||||
// Close closes the connection.
|
||||
func (l *Conn) Close() (err error) {
|
||||
l.messageMutex.Lock()
|
||||
defer l.messageMutex.Unlock()
|
||||
|
||||
if l.setClosing() {
|
||||
l.Debug.Printf("Sending quit message and waiting for confirmation")
|
||||
l.chanMessage <- &messagePacket{Op: MessageQuit}
|
||||
|
||||
timeoutCtx := context.Background()
|
||||
if l.getTimeout() > 0 {
|
||||
var cancelFunc context.CancelFunc
|
||||
timeoutCtx, cancelFunc = context.WithTimeout(timeoutCtx, time.Duration(l.getTimeout()))
|
||||
defer cancelFunc()
|
||||
}
|
||||
select {
|
||||
case <-l.chanConfirm:
|
||||
// Confirmation was received.
|
||||
case <-timeoutCtx.Done():
|
||||
// The timeout was reached before confirmation was received.
|
||||
}
|
||||
|
||||
close(l.chanMessage)
|
||||
|
||||
l.Debug.Printf("Closing network connection")
|
||||
err = l.conn.Close()
|
||||
l.wgClose.Done()
|
||||
}
|
||||
l.wgClose.Wait()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// SetTimeout sets the time after a request is sent that a MessageTimeout triggers
|
||||
func (l *Conn) SetTimeout(timeout time.Duration) {
|
||||
atomic.StoreInt64(&l.requestTimeout, int64(timeout))
|
||||
}
|
||||
|
||||
func (l *Conn) getTimeout() int64 {
|
||||
return atomic.LoadInt64(&l.requestTimeout)
|
||||
}
|
||||
|
||||
// Returns the next available messageID
|
||||
func (l *Conn) nextMessageID() int64 {
|
||||
if messageID, ok := <-l.chanMessageID; ok {
|
||||
return messageID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetLastError returns the last recorded error from goroutines like processMessages and reader.
|
||||
// Only the last recorded error will be returned.
|
||||
func (l *Conn) GetLastError() error {
|
||||
l.messageMutex.Lock()
|
||||
defer l.messageMutex.Unlock()
|
||||
return l.err
|
||||
}
|
||||
|
||||
// StartTLS sends the command to start a TLS session and then creates a new TLS Client
|
||||
func (l *Conn) StartTLS(config *tls.Config) error {
|
||||
if l.isTLS {
|
||||
return NewError(ErrorNetwork, errors.New("ldap: already encrypted"))
|
||||
}
|
||||
|
||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationExtendedRequest, nil, "Start TLS")
|
||||
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, "1.3.6.1.4.1.1466.20037", "TLS Extended Command"))
|
||||
packet.AppendChild(request)
|
||||
l.Debug.PrintPacket(packet)
|
||||
|
||||
msgCtx, err := l.sendMessageWithFlags(packet, startTLS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer l.finishMessage(msgCtx)
|
||||
|
||||
l.Debug.Printf("%d: waiting for response", msgCtx.id)
|
||||
|
||||
packetResponse, ok := <-msgCtx.responses
|
||||
if !ok {
|
||||
return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
|
||||
}
|
||||
packet, err = packetResponse.ReadPacket()
|
||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if l.Debug {
|
||||
if err := addLDAPDescriptions(packet); err != nil {
|
||||
l.Close()
|
||||
return err
|
||||
}
|
||||
l.Debug.PrintPacket(packet)
|
||||
}
|
||||
|
||||
if err := GetLDAPError(packet); err == nil {
|
||||
conn := tls.Client(l.conn, config)
|
||||
|
||||
if connErr := conn.Handshake(); connErr != nil {
|
||||
l.Close()
|
||||
return NewError(ErrorNetwork, fmt.Errorf("TLS handshake failed (%v)", connErr))
|
||||
}
|
||||
|
||||
l.isTLS = true
|
||||
l.conn = conn
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
go l.reader()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TLSConnectionState returns the client's TLS connection state.
|
||||
// The return values are their zero values if StartTLS did
|
||||
// not succeed.
|
||||
func (l *Conn) TLSConnectionState() (state tls.ConnectionState, ok bool) {
|
||||
tc, ok := l.conn.(*tls.Conn)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
return tc.ConnectionState(), true
|
||||
}
|
||||
|
||||
func (l *Conn) sendMessage(packet *ber.Packet) (*messageContext, error) {
|
||||
return l.sendMessageWithFlags(packet, 0)
|
||||
}
|
||||
|
||||
func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags) (*messageContext, error) {
|
||||
if l.IsClosing() {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed"))
|
||||
}
|
||||
l.messageMutex.Lock()
|
||||
l.Debug.Printf("flags&startTLS = %d", flags&startTLS)
|
||||
if l.isStartingTLS {
|
||||
l.messageMutex.Unlock()
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: connection is in startls phase"))
|
||||
}
|
||||
if flags&startTLS != 0 {
|
||||
if l.outstandingRequests != 0 {
|
||||
l.messageMutex.Unlock()
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: cannot StartTLS with outstanding requests"))
|
||||
}
|
||||
l.isStartingTLS = true
|
||||
}
|
||||
l.outstandingRequests++
|
||||
|
||||
l.messageMutex.Unlock()
|
||||
|
||||
responses := make(chan *PacketResponse)
|
||||
messageID := packet.Children[0].Value.(int64)
|
||||
message := &messagePacket{
|
||||
Op: MessageRequest,
|
||||
MessageID: messageID,
|
||||
Packet: packet,
|
||||
Context: &messageContext{
|
||||
id: messageID,
|
||||
done: make(chan struct{}),
|
||||
responses: responses,
|
||||
},
|
||||
}
|
||||
if !l.sendProcessMessage(message) {
|
||||
if l.IsClosing() {
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed"))
|
||||
}
|
||||
return nil, NewError(ErrorNetwork, errors.New("ldap: could not send message for unknown reason"))
|
||||
}
|
||||
return message.Context, nil
|
||||
}
|
||||
|
||||
func (l *Conn) finishMessage(msgCtx *messageContext) {
|
||||
close(msgCtx.done)
|
||||
|
||||
if l.IsClosing() {
|
||||
return
|
||||
}
|
||||
|
||||
l.messageMutex.Lock()
|
||||
l.outstandingRequests--
|
||||
if l.isStartingTLS {
|
||||
l.isStartingTLS = false
|
||||
}
|
||||
l.messageMutex.Unlock()
|
||||
|
||||
message := &messagePacket{
|
||||
Op: MessageFinish,
|
||||
MessageID: msgCtx.id,
|
||||
}
|
||||
l.sendProcessMessage(message)
|
||||
}
|
||||
|
||||
func (l *Conn) sendProcessMessage(message *messagePacket) bool {
|
||||
l.messageMutex.Lock()
|
||||
defer l.messageMutex.Unlock()
|
||||
if l.IsClosing() {
|
||||
return false
|
||||
}
|
||||
l.chanMessage <- message
|
||||
return true
|
||||
}
|
||||
|
||||
func (l *Conn) processMessages() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
l.err = fmt.Errorf("ldap: recovered panic in processMessages: %v", err)
|
||||
}
|
||||
for messageID, msgCtx := range l.messageContexts {
|
||||
// If we are closing due to an error, inform anyone who
|
||||
// is waiting about the error.
|
||||
if l.IsClosing() && l.closeErr.Load() != nil {
|
||||
msgCtx.sendResponse(&PacketResponse{Error: l.closeErr.Load().(error)}, time.Duration(l.getTimeout()))
|
||||
}
|
||||
l.Debug.Printf("Closing channel for MessageID %d", messageID)
|
||||
close(msgCtx.responses)
|
||||
delete(l.messageContexts, messageID)
|
||||
}
|
||||
close(l.chanMessageID)
|
||||
close(l.chanConfirm)
|
||||
}()
|
||||
|
||||
var messageID int64 = 1
|
||||
for {
|
||||
select {
|
||||
case l.chanMessageID <- messageID:
|
||||
messageID++
|
||||
case message := <-l.chanMessage:
|
||||
switch message.Op {
|
||||
case MessageQuit:
|
||||
l.Debug.Printf("Shutting down - quit message received")
|
||||
return
|
||||
case MessageRequest:
|
||||
// Add to message list and write to network
|
||||
l.Debug.Printf("Sending message %d", message.MessageID)
|
||||
|
||||
buf := message.Packet.Bytes()
|
||||
_, err := l.conn.Write(buf)
|
||||
if err != nil {
|
||||
l.Debug.Printf("Error Sending Message: %s", err.Error())
|
||||
message.Context.sendResponse(&PacketResponse{Error: fmt.Errorf("unable to send request: %s", err)}, time.Duration(l.getTimeout()))
|
||||
close(message.Context.responses)
|
||||
break
|
||||
}
|
||||
|
||||
// Only add to messageContexts if we were able to
|
||||
// successfully write the message.
|
||||
l.messageContexts[message.MessageID] = message.Context
|
||||
|
||||
// Add timeout if defined
|
||||
requestTimeout := l.getTimeout()
|
||||
if requestTimeout > 0 {
|
||||
go func() {
|
||||
timer := time.NewTimer(time.Duration(requestTimeout))
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
l.err = fmt.Errorf("ldap: recovered panic in RequestTimeout: %v", err)
|
||||
}
|
||||
|
||||
timer.Stop()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
timeoutMessage := &messagePacket{
|
||||
Op: MessageTimeout,
|
||||
MessageID: message.MessageID,
|
||||
}
|
||||
l.sendProcessMessage(timeoutMessage)
|
||||
case <-message.Context.done:
|
||||
}
|
||||
}()
|
||||
}
|
||||
case MessageResponse:
|
||||
l.Debug.Printf("Receiving message %d", message.MessageID)
|
||||
if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
|
||||
msgCtx.sendResponse(&PacketResponse{message.Packet, nil}, time.Duration(l.getTimeout()))
|
||||
} else {
|
||||
l.err = fmt.Errorf("ldap: received unexpected message %d, %v", message.MessageID, l.IsClosing())
|
||||
l.Debug.PrintPacket(message.Packet)
|
||||
}
|
||||
case MessageTimeout:
|
||||
// Handle the timeout by closing the channel
|
||||
// All reads will return immediately
|
||||
if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
|
||||
l.Debug.Printf("Receiving message timeout for %d", message.MessageID)
|
||||
msgCtx.sendResponse(&PacketResponse{message.Packet, NewError(ErrorNetwork, errors.New("ldap: connection timed out"))}, time.Duration(l.getTimeout()))
|
||||
delete(l.messageContexts, message.MessageID)
|
||||
close(msgCtx.responses)
|
||||
}
|
||||
case MessageFinish:
|
||||
l.Debug.Printf("Finished message %d", message.MessageID)
|
||||
if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
|
||||
delete(l.messageContexts, message.MessageID)
|
||||
close(msgCtx.responses)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Conn) reader() {
|
||||
cleanstop := false
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
l.err = fmt.Errorf("ldap: recovered panic in reader: %v", err)
|
||||
}
|
||||
if !cleanstop {
|
||||
l.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
bufConn := bufio.NewReader(l.conn)
|
||||
for {
|
||||
if cleanstop {
|
||||
l.Debug.Printf("reader clean stopping (without closing the connection)")
|
||||
return
|
||||
}
|
||||
packet, err := ber.ReadPacket(bufConn)
|
||||
if err != nil {
|
||||
// A read error is expected here if we are closing the connection...
|
||||
if !l.IsClosing() {
|
||||
l.closeErr.Store(fmt.Errorf("unable to read LDAP response packet: %s", err))
|
||||
l.Debug.Printf("reader error: %s", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err := addLDAPDescriptions(packet); err != nil {
|
||||
l.Debug.Printf("descriptions error: %s", err)
|
||||
}
|
||||
if len(packet.Children) == 0 {
|
||||
l.Debug.Printf("Received bad ldap packet")
|
||||
continue
|
||||
}
|
||||
l.messageMutex.Lock()
|
||||
if l.isStartingTLS {
|
||||
cleanstop = true
|
||||
}
|
||||
l.messageMutex.Unlock()
|
||||
message := &messagePacket{
|
||||
Op: MessageResponse,
|
||||
MessageID: packet.Children[0].Value.(int64),
|
||||
Packet: packet,
|
||||
}
|
||||
if !l.sendProcessMessage(message) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
1294
vendor/github.com/go-ldap/ldap/v3/control.go
generated
vendored
Normal file
1294
vendor/github.com/go-ldap/ldap/v3/control.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user