From dbef31dd3d9dff040c41ba1f96b28097a4491bc2 Mon Sep 17 00:00:00 2001 From: Boshi Lian Date: Sat, 2 Jul 2022 11:37:38 +0000 Subject: [PATCH] libplugin --- cmd/sshpiperd/daemon.go | 135 ++ cmd/sshpiperd/internal/plugin/chain.go | 144 ++ cmd/sshpiperd/internal/plugin/grpc.go | 519 +++++ cmd/sshpiperd/main.go | 163 ++ crypto | 2 +- go.mod | 10 +- go.sum | 17 + libplugin/doc.go | 3 + libplugin/ioconn/cmd.go | 48 + libplugin/ioconn/conn.go | 113 + libplugin/ioconn/listener.go | 37 + libplugin/plugin.pb.go | 2746 ++++++++++++++++++++++++ libplugin/plugin.proto | 189 ++ libplugin/plugin_grpc.pb.go | 521 +++++ libplugin/pluginbase.go | 374 ++++ libplugin/util.go | 138 ++ plugin/fixed/main.go | 44 + plugin/simplemath/main.go | 51 + 18 files changed, 5250 insertions(+), 4 deletions(-) create mode 100644 cmd/sshpiperd/daemon.go create mode 100644 cmd/sshpiperd/internal/plugin/chain.go create mode 100644 cmd/sshpiperd/internal/plugin/grpc.go create mode 100644 cmd/sshpiperd/main.go create mode 100644 libplugin/doc.go create mode 100644 libplugin/ioconn/cmd.go create mode 100644 libplugin/ioconn/conn.go create mode 100644 libplugin/ioconn/listener.go create mode 100644 libplugin/plugin.pb.go create mode 100644 libplugin/plugin.proto create mode 100644 libplugin/plugin_grpc.pb.go create mode 100644 libplugin/pluginbase.go create mode 100644 libplugin/util.go create mode 100644 plugin/fixed/main.go create mode 100644 plugin/simplemath/main.go diff --git a/cmd/sshpiperd/daemon.go b/cmd/sshpiperd/daemon.go new file mode 100644 index 00000000..48d5cee6 --- /dev/null +++ b/cmd/sshpiperd/daemon.go @@ -0,0 +1,135 @@ +package main + +import ( + "fmt" + "io/ioutil" + "net" + "path/filepath" + "time" + + log "github.com/sirupsen/logrus" + "github.com/tg123/sshpiper/cmd/sshpiperd/internal/plugin" + "github.com/urfave/cli/v2" + "golang.org/x/crypto/ssh" +) + +type daemon struct { + config *ssh.PiperConfig + lis net.Listener + loginGraceTime time.Duration +} + +func newDaemon(ctx *cli.Context) (*daemon, error) { + config := &ssh.PiperConfig{} + config.SetDefaults() + + privateKeys, err := filepath.Glob(ctx.String("server-key")) + if err != nil { + return nil, err + } + + if len(privateKeys) == 0 { + return nil, fmt.Errorf("no server key found") + } + + log.Infof("found host keys %v", privateKeys) + for _, privateKey := range privateKeys { + log.Infof("loading host key %v", privateKey) + privateBytes, err := ioutil.ReadFile(privateKey) + if err != nil { + return nil, err + } + + private, err := ssh.ParsePrivateKey(privateBytes) + if err != nil { + return nil, err + } + + config.AddHostKey(private) + } + + lis, err := net.Listen("tcp", net.JoinHostPort(ctx.String("address"), ctx.String("port"))) + if err != nil { + return nil, fmt.Errorf("failed to listen for connection: %v", err) + } + + return &daemon{ + config: config, + lis: lis, + loginGraceTime: ctx.Duration("login-grace-time"), + }, nil +} + +func (d *daemon) install(plugins ...*plugin.GrpcPlugin) error { + if len(plugins) == 0 { + return fmt.Errorf("no plugins found") + } + + // if len(plugins) == 1 { + // return plugins[0].InstallPiperConfig(d.config) + // } + + m := plugin.ChainPlugins{} + + for _, p := range plugins { + if err := m.Append(p); err != nil { + return err + } + } + + return m.InstallPiperConfig(d.config) +} + +func (d *daemon) run() error { + defer d.lis.Close() + log.Infof("sshpiperd is listening on: %v", d.lis.Addr().String()) + + for { + conn, err := d.lis.Accept() + if err != nil { + log.Debugf("failed to accept connection: %v", err) + continue + } + + log.Debugf("connection accepted: %v", conn.RemoteAddr()) + + go func(c net.Conn) { + defer c.Close() + + pipec := make(chan *ssh.PiperConn) + errorc := make(chan error) + + go func() { + p, err := ssh.NewSSHPiperConn(c, d.config) + + if err != nil { + errorc <- err + return + } + + pipec <- p + }() + + var p *ssh.PiperConn + + select { + case p = <-pipec: + case err := <-errorc: + log.Debugf("connection from %v establishing failed reason: %v", c.RemoteAddr(), err) + return + case <-time.After(d.loginGraceTime): + log.Debugf("pipe establishing timeout, disconnected connection from %v", c.RemoteAddr()) + return + } + + defer p.Close() + + log.Infof("ssh connection pipe created %v -> %v", p.DownstreamConnMeta().RemoteAddr(), p.UpstreamConnMeta().RemoteAddr().String()) + + // TODO add screen recording + err = p.Wait() + + log.Infof("connection from %v closed reason: %v", c.RemoteAddr(), err) + }(conn) + } +} diff --git a/cmd/sshpiperd/internal/plugin/chain.go b/cmd/sshpiperd/internal/plugin/chain.go new file mode 100644 index 00000000..f5261877 --- /dev/null +++ b/cmd/sshpiperd/internal/plugin/chain.go @@ -0,0 +1,144 @@ +package plugin + +import ( + "fmt" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/tg123/sshpiper/libplugin" + "golang.org/x/crypto/ssh" +) + +type ChainPlugins struct { + pluginsCallback []*ssh.PiperConfig + plugins []*GrpcPlugin +} + +func (cp *ChainPlugins) Append(p *GrpcPlugin) error { + config, err := p.CreatePiperConfig() + if err != nil { + return err + } + + p.OnNextPlugin = cp.onNextPlugin + cp.pluginsCallback = append(cp.pluginsCallback, config) + cp.plugins = append(cp.plugins, p) + + return nil +} + +func (cp *ChainPlugins) onNextPlugin(challengeCtx ssh.ChallengeContext, upstream *libplugin.UpstreamNextPluginAuth) error { + chain := challengeCtx.(*chainConnMeta) + + if chain.current+1 >= len(cp.pluginsCallback) { + return fmt.Errorf("no more plugins") + } + + chain.current++ + return nil +} + +type chainConnMeta struct { + connMeta + current int +} + +func (cp *ChainPlugins) CreateChallengeContext(conn ssh.ConnMetadata) (ssh.ChallengeContext, error) { + uiq, err := uuid.NewRandom() + if err != nil { + return nil, err + } + + meta := chainConnMeta{ + connMeta: connMeta{ + UserName: conn.User(), + FromAddr: conn.RemoteAddr().String(), + UniqId: uiq.String(), + }, + } + + for _, p := range cp.plugins { + if err := p.NewConnection(&meta.connMeta); err != nil { + return nil, err + } + } + + return &meta, nil +} + +func (cp *ChainPlugins) NextAuthMethods(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) ([]string, error) { + chain := challengeCtx.(*chainConnMeta) + config := cp.pluginsCallback[chain.current] + + if config.NextAuthMethods != nil { + return config.NextAuthMethods(conn, challengeCtx) + } + + var methods []string + + if config.NoneAuthCallback != nil { + methods = append(methods, "none") + } + + if config.PasswordCallback != nil { + methods = append(methods, "password") + } + + if config.PublicKeyCallback != nil { + methods = append(methods, "publickey") + } + + if config.KeyboardInteractiveCallback != nil { + methods = append(methods, "keyboard-interactive") + } + + log.Debugf("next auth methods %v", methods) + return methods, nil +} + +func (cp *ChainPlugins) InstallPiperConfig(config *ssh.PiperConfig) error { + + config.CreateChallengeContext = func(conn ssh.ConnMetadata) (ssh.ChallengeContext, error) { + ctx, err := cp.CreateChallengeContext(conn) + if err != nil { + log.Errorf("cannot create challenge context %v", err) + } + return ctx, err + } + + config.NextAuthMethods = cp.NextAuthMethods + + config.NoneAuthCallback = func(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + return cp.pluginsCallback[challengeCtx.(*chainConnMeta).current].NoneAuthCallback(conn, challengeCtx) + } + + config.PasswordCallback = func(conn ssh.ConnMetadata, password []byte, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + return cp.pluginsCallback[challengeCtx.(*chainConnMeta).current].PasswordCallback(conn, password, challengeCtx) + } + + config.PublicKeyCallback = func(conn ssh.ConnMetadata, key ssh.PublicKey, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + return cp.pluginsCallback[challengeCtx.(*chainConnMeta).current].PublicKeyCallback(conn, key, challengeCtx) + } + + config.KeyboardInteractiveCallback = func(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + return cp.pluginsCallback[challengeCtx.(*chainConnMeta).current].KeyboardInteractiveCallback(conn, client, challengeCtx) + } + + config.UpstreamAuthFailureCallback = func(conn ssh.ConnMetadata, method string, err error, challengeCtx ssh.ChallengeContext) { + cur := cp.pluginsCallback[challengeCtx.(*chainConnMeta).current] + if cur.UpstreamAuthFailureCallback != nil { + cur.UpstreamAuthFailureCallback(conn, method, err, challengeCtx) + } + } + + config.BannerCallback = func(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) string { + cur := cp.pluginsCallback[challengeCtx.(*chainConnMeta).current] + if cur.BannerCallback != nil { + return cur.BannerCallback(conn, challengeCtx) + } + + return "" + } + + return nil +} diff --git a/cmd/sshpiperd/internal/plugin/grpc.go b/cmd/sshpiperd/internal/plugin/grpc.go new file mode 100644 index 00000000..aea305cf --- /dev/null +++ b/cmd/sshpiperd/internal/plugin/grpc.go @@ -0,0 +1,519 @@ +package plugin + +import ( + "context" + "fmt" + "io" + "net" + "os/exec" + "strconv" + "time" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/tg123/remotesigner" + "github.com/tg123/remotesigner/grpcsigner" + "github.com/tg123/sshpiper/libplugin" + "github.com/tg123/sshpiper/libplugin/ioconn" + "golang.org/x/crypto/ssh" + "google.golang.org/grpc" +) + +type GrpcPlugin struct { + OnNextPlugin func(conn ssh.ChallengeContext, upstream *libplugin.UpstreamNextPluginAuth) error + + grpcconn *grpc.ClientConn + client libplugin.SshPiperPluginClient + remotesignerClient grpcsigner.SignerClient + + hasNewConnectionCallback bool + allowedMethod map[string]bool +} + +func DialGrpc(conn *grpc.ClientConn) (*GrpcPlugin, error) { + p := &GrpcPlugin{ + grpcconn: conn, + client: libplugin.NewSshPiperPluginClient(conn), + remotesignerClient: grpcsigner.NewSignerClient(conn), + } + + return p, nil +} + +func (g *GrpcPlugin) InstallPiperConfig(config *ssh.PiperConfig) error { + + cb, err := g.client.ListCallbacks(context.Background(), &libplugin.ListCallbackRequest{}) + if err != nil { + return err + } + + // config.NextAuthMethods = g.NextAuthMethodsLocal + // config.UpstreamAuthFailureCallback = g.UpstreamAuthFailureCallbackLocal + + config.CreateChallengeContext = func(conn ssh.ConnMetadata) (ssh.ChallengeContext, error) { + ctx, err := g.CreateChallengeContext(conn) + if err != nil { + log.Errorf("cannot create challenge context %v", err) + } + return ctx, err + } + + for _, c := range cb.Callbacks { + switch c { + case "NewConnection": + g.hasNewConnectionCallback = true + case "NextAuthMethods": + config.NextAuthMethods = func(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) ([]string, error) { + methods, err := g.NextAuthMethodsRemote(conn, challengeCtx) + if err != nil { + log.Errorf("cannot get next auth methods %v", err) + } + + log.Debugf("next auth methods %v", methods) + return methods, err + } + + case "NoneAuth": + config.NoneAuthCallback = func(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + log.Debugf("downstream %v is sending none auth", conn.RemoteAddr().String()) + u, err := g.NoneAuthCallback(conn, challengeCtx) + if err != nil { + log.Debugf("cannot create upstream for %v with none auth: %v", conn.RemoteAddr().String(), err) + } + return u, err + } + case "PasswordAuth": + config.PasswordCallback = func(conn ssh.ConnMetadata, password []byte, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + log.Debugf("downstream %v is sending password auth", conn.RemoteAddr().String()) + u, err := g.PasswordCallback(conn, password, challengeCtx) + if err != nil { + log.Debugf("cannot create upstream for %v with password auth: %v", conn.RemoteAddr().String(), err) + } + return u, err + } + case "PublicKeyAuth": + config.PublicKeyCallback = func(conn ssh.ConnMetadata, key ssh.PublicKey, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + log.Debugf("downstream %v is sending public key auth", conn.RemoteAddr().String()) + u, err := g.PublicKeyCallback(conn, key, challengeCtx) + if err != nil { + log.Debugf("cannot create upstream for %v with public key auth: %v", conn.RemoteAddr().String(), err) + } + return u, err + } + case "KeyboardInteractiveAuth": + config.KeyboardInteractiveCallback = func(conn ssh.ConnMetadata, challenge ssh.KeyboardInteractiveChallenge, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + log.Debugf("downstream %v is sending keyboard interactive auth", conn.RemoteAddr().String()) + u, err := g.KeyboardInteractiveCallback(conn, challenge, challengeCtx) + if err != nil { + log.Debugf("cannot create upstream for %v with keyboard interactive auth: %v", conn.RemoteAddr().String(), err) + } + return u, err + } + case "UpstreamAuthFailure": + config.UpstreamAuthFailureCallback = func(conn ssh.ConnMetadata, method string, err error, challengeCtx ssh.ChallengeContext) { + log.Debugf("upstream rejected [%v] auth: %v", method, err) + g.UpstreamAuthFailureCallbackRemote(conn, method, err, challengeCtx) + } + case "Banner": + config.BannerCallback = g.BannerCallback + default: + return fmt.Errorf("unknown callback %s", c) + } + } + + return nil +} + +func (g *GrpcPlugin) CreatePiperConfig() (*ssh.PiperConfig, error) { + config := &ssh.PiperConfig{} + return config, g.InstallPiperConfig(config) +} + +type connMeta libplugin.ConnMeta + +// ChallengedUsername implements ssh.ChallengeContext +func (m *connMeta) ChallengedUsername() string { + return m.UserName +} + +// Meta implements ssh.ChallengeContext +func (m *connMeta) Meta() interface{} { + return m +} + +func (g *GrpcPlugin) CreateChallengeContext(conn ssh.ConnMetadata) (ssh.ChallengeContext, error) { + uiq, err := uuid.NewRandom() + if err != nil { + return nil, err + } + + meta := connMeta{ + UserName: conn.User(), + FromAddr: conn.RemoteAddr().String(), + UniqId: uiq.String(), + } + + return &meta, g.NewConnection(&meta) +} + +func (g *GrpcPlugin) NewConnection(meta *connMeta) error { + if g.hasNewConnectionCallback { + _, err := g.client.NewConnection(context.Background(), &libplugin.NewConnectionRequest{ + Meta: &libplugin.ConnMeta{ + UserName: meta.UserName, + FromAddr: meta.FromAddr, + UniqId: meta.UniqId, + }, + }) + + return err + } + + return nil +} + +func (g *GrpcPlugin) NextAuthMethodsLocal(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) ([]string, error) { + var allow []string + + for k, v := range g.allowedMethod { + if v { + allow = append(allow, k) + } + } + + return allow, nil +} + +func toMeta(challengeCtx ssh.ChallengeContext) *libplugin.ConnMeta { + switch meta := challengeCtx.(type) { + case *connMeta: + return (*libplugin.ConnMeta)(meta) + case *chainConnMeta: + return (*libplugin.ConnMeta)(&meta.connMeta) + } + + panic("unknown challenge context") +} + +func (g *GrpcPlugin) NextAuthMethodsRemote(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) ([]string, error) { + meta := toMeta(challengeCtx) + reply, err := g.client.NextAuthMethods(context.Background(), &libplugin.NextAuthMethodsRequest{ + Meta: meta, + }) + + if err != nil { + return nil, err + } + + var methods []string + + for _, method := range reply.Methods { + m := libplugin.AuthMethodTypeToName(method) + if m == "" { + continue + } + methods = append(methods, m) + } + + return methods, nil +} + +func (g *GrpcPlugin) UpstreamAuthFailureCallbackLocal(onn ssh.ConnMetadata, method string, err error, challengeCtx ssh.ChallengeContext) { + noMoreMethodErr, ok := err.(ssh.NoMoreMethodsErr) + if ok { + for _, allowed := range noMoreMethodErr.Allowed { + g.allowedMethod[allowed] = true + } + + return + } + + g.allowedMethod[method] = false +} + +func (g *GrpcPlugin) UpstreamAuthFailureCallbackRemote(onn ssh.ConnMetadata, method string, err error, challengeCtx ssh.ChallengeContext) { + noMoreMethodErr, ok := err.(ssh.NoMoreMethodsErr) + allowed := make([]libplugin.AuthMethod, len(noMoreMethodErr.Allowed)) + if ok { + for _, method := range noMoreMethodErr.Allowed { + m := libplugin.AuthMethodFromName(method) + if m == -1 { + continue + } + + allowed = append(allowed, m) + } + } + + g.client.UpstreamAuthFailureNotice(context.Background(), &libplugin.UpstreamAuthFailureNoticeRequest{ + Meta: toMeta(challengeCtx), + Method: method, + Error: err.Error(), + AllowedMethods: allowed, + }) +} + +func (g *GrpcPlugin) createUpstream(challengeCtx ssh.ChallengeContext, upstream *libplugin.Upstream) (*ssh.Upstream, error) { + if upstream.GetNextPlugin() != nil { + if g.OnNextPlugin == nil { + return nil, fmt.Errorf("next plugin is not supported") + } + return nil, g.OnNextPlugin(challengeCtx, upstream.GetNextPlugin()) + } + + meta := toMeta(challengeCtx) + + port := upstream.Port + if port <= 0 { + port = 22 + } + addr := net.JoinHostPort(upstream.Host, strconv.Itoa(int(port))) + + c, err := net.Dial("tcp", addr) + if err != nil { + return nil, err + } + + config := ssh.ClientConfig{ + HostKeyCallback: func(_ string, _ net.Addr, key ssh.PublicKey) error { + if upstream.IgnoreHostKey { + return nil + } + + verify, err := g.client.VerifyHostKey(context.Background(), &libplugin.VerifyHostKeyRequest{ + Meta: meta, + Key: key.Marshal(), + }) + + if err != nil { + return err + } + + if !verify.Verified { + return fmt.Errorf("host key verification failed") + } + + return nil + }, + } + + auth := make([]string, 0) + if upstream.GetNone() != nil { + config.Auth = append(config.Auth, ssh.NoneAuth()) + auth = append(auth, "none") + } + + if a := upstream.GetPassword(); a != nil { + config.Auth = append(config.Auth, ssh.Password(a.GetPassword())) + auth = append(auth, "password") + } + + if a := upstream.GetPrivateKey(); a != nil { + private, err := ssh.ParsePrivateKey(a.GetPrivateKey()) + if err != nil { + return nil, err + } + config.Auth = append(config.Auth, ssh.PublicKeys(private)) + auth = append(auth, "privatekey") + } + + if a := upstream.GetRemoteSigner(); a != nil { + rs := remotesigner.New(grpcsigner.New(g.remotesignerClient, a.Meta)) + signer, err := ssh.NewSignerFromSigner(rs) + if err != nil { + return nil, err + } + + config.Auth = append(config.Auth, ssh.PublicKeys(signer)) + auth = append(auth, "remotesigner") + } + + if len(config.Auth) == 0 { + log.Warnf("no auth method found for upstream %s, add none auth", addr) + auth = append(auth, "none") + config.Auth = append(config.Auth, ssh.NoneAuth()) + } + + log.Debugf("connecting to upstream %v with auth %v", c.RemoteAddr().String(), auth) + + return &ssh.Upstream{ + Conn: c, + Address: addr, + ClientConfig: config, + }, nil + +} + +func (g *GrpcPlugin) NoneAuthCallback(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + meta := toMeta(challengeCtx) + reply, err := g.client.NoneAuth(context.Background(), &libplugin.NoneAuthRequest{ + Meta: meta, + }) + + if err != nil { + return nil, err + } + + return g.createUpstream(challengeCtx, reply.Upstream) +} + +func (g *GrpcPlugin) PasswordCallback(conn ssh.ConnMetadata, password []byte, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + meta := toMeta(challengeCtx) + reply, err := g.client.PasswordAuth(context.Background(), &libplugin.PasswordAuthRequest{ + Meta: meta, + Password: password, + }) + + if err != nil { + return nil, err + } + + return g.createUpstream(challengeCtx, reply.Upstream) +} + +func (g *GrpcPlugin) PublicKeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + meta := toMeta(challengeCtx) + reply, err := g.client.PublicKeyAuth(context.Background(), &libplugin.PublicKeyAuthRequest{ + Meta: meta, + PublicKey: key.Marshal(), + }) + + if err != nil { + return nil, err + } + + return g.createUpstream(challengeCtx, reply.Upstream) +} + +func (g *GrpcPlugin) KeyboardInteractiveCallback(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) { + + stream, err := g.client.KeyboardInteractiveAuth(context.Background()) + if err != nil { + return nil, err + } + + defer stream.CloseSend() + + for { + msg, err := stream.Recv() + if err == io.EOF { + return nil, nil + } + + if err != nil { + return nil, err + } + + if r := msg.GetPromptRequest(); r != nil { + var questions []string + var echo []bool + + for _, q := range r.GetQuestions() { + questions = append(questions, q.GetText()) + echo = append(echo, q.GetEcho()) + } + + ans, err := client(conn.User(), r.GetInstruction(), questions, echo) + if err != nil { + return nil, err + } + + if len(questions) > 0 { + if err := stream.Send(&libplugin.KeyboardInteractiveAuthMessage{ + Message: &libplugin.KeyboardInteractiveAuthMessage_UserResponse{ + UserResponse: &libplugin.KeyboardInteractiveUserResponse{ + Answers: ans, + }, + }, + }); err != nil { + return nil, err + } + } + } else if r := msg.GetMetaRequest(); r != nil { + meta := toMeta(challengeCtx) + if err := stream.Send(&libplugin.KeyboardInteractiveAuthMessage{ + Message: &libplugin.KeyboardInteractiveAuthMessage_MetaResponse{ + MetaResponse: &libplugin.KeyboardInteractiveMetaResponse{ + Meta: meta, + }, + }, + }); err != nil { + return nil, err + } + + } else if r := msg.GetFinishRequest(); r != nil { + if r.GetUpstream() != nil { + return g.createUpstream(challengeCtx, r.GetUpstream()) + } + + return nil, fmt.Errorf("auth failed: %s", r.GetErrorMessage()) + } + } +} + +func (g *GrpcPlugin) BannerCallback(conn ssh.ConnMetadata, challengeCtx ssh.ChallengeContext) string { + meta := toMeta(challengeCtx) + reply, err := g.client.Banner(context.Background(), &libplugin.BannerRequest{ + Meta: meta, + }) + + if err != nil { + log.Debugf("failed to get banner: %v", err) + return "" + } + + return reply.GetMessage() +} + +func (g *GrpcPlugin) RecvLogs(writer io.Writer) error { + stream, err := g.client.Logs(context.Background(), &libplugin.StartLogRequest{}) + if err != nil { + return err + } + + for { + line, err := stream.Recv() + if err != nil { + log.Errorf("recv log error: %v", err) + return err + } + + fmt.Fprintln(writer, line.GetMessage()) + } +} + +type CmdPlugin struct { + GrpcPlugin +} + +func DialCmd(cmd *exec.Cmd) (*CmdPlugin, error) { + cmdconn, stderr, err := ioconn.DialCmd(cmd) + if err != nil { + return nil, err + } + + go io.Copy(log.StandardLogger().Out, stderr) + + go func() { + err := cmd.Wait() + if err != nil { + log.Errorf("cmd %v error: %v", cmd.Path, err) + } + }() + + conn, err := grpc.Dial("", grpc.WithInsecure(), grpc.WithDialer(func(_ string, _ time.Duration) (net.Conn, error) { + return cmdconn, nil + })) + + if err != nil { + return nil, err + } + + g, err := DialGrpc(conn) + + if err != nil { + return nil, err + } + + return &CmdPlugin{*g}, nil +} diff --git a/cmd/sshpiperd/main.go b/cmd/sshpiperd/main.go new file mode 100644 index 00000000..15edc1f8 --- /dev/null +++ b/cmd/sshpiperd/main.go @@ -0,0 +1,163 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + "runtime/debug" + "time" + + log "github.com/sirupsen/logrus" + "github.com/tg123/sshpiper/cmd/sshpiperd/internal/plugin" + + "github.com/urfave/cli/v2" +) + +var mainver string = "(devel)" + +func version() string { + + var v = mainver + + bi, ok := debug.ReadBuildInfo() + if !ok { + return v + } + + for _, s := range bi.Settings { + switch s.Key { + case "vcs.revision": + v = fmt.Sprintf("%v, %v", v, s.Value[:9]) + case "vcs.time": + v = fmt.Sprintf("%v, %v", v, s.Value) + } + } + + v = fmt.Sprintf("%v, %v", v, bi.GoVersion) + + return v +} + +func splitByDash(args []string) ([]string, []string) { + for i, arg := range args { + if arg == "--" { + return args[:i], args[i+1:] + } + } + + return args, nil +} + +func main() { + + app := &cli.App{ + Name: "sshpiperd", + Usage: "the missing reverse proxy for ssh scp", + UsageText: "sshpiperd [options] [plugin options] [-- [plugin2] [plugin options] [-- ...]]", + Description: "sshpiperd works as a proxy-like ware, and route connections by username, src ip , etc.\nhttps://github.com/tg123/sshpiper", + Version: version(), + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "address", + Aliases: []string{"l"}, + Value: "0.0.0.0", + Usage: "listening address", + EnvVars: []string{"SSHPIPERD_ADDRESS"}, + }, + &cli.IntFlag{ + Name: "port", + Aliases: []string{"p"}, + Value: 2222, + Usage: "listening port", + EnvVars: []string{"SSHPIPERD_PORT"}, + }, + &cli.StringFlag{ + Name: "server-key", + Aliases: []string{"i"}, + Usage: "server key files, support wildcard", + Value: "/etc/ssh/ssh_host_rsa_key", + EnvVars: []string{"SSHPIPERD_SERVER_KEY"}, + }, + &cli.DurationFlag{ + Name: "login-grace-time", + Value: 30 * time.Second, + Usage: "sshpiperd forcely close the connection after this time if the pipe has not successfully established", + EnvVars: []string{"SSHPIPERD_LOGIN_GRACE_TIME"}, + }, + &cli.StringFlag{ + Name: "log-level", + Value: "info", + Usage: "log level, one of: trace, debug, info, warn, error, fatal, panic", + EnvVars: []string{"SSHPIPERD_LOG_LEVEL"}, + }, + }, + // Commands: []*cli.Command{ + // &cli.Command{ + // Name: "plug", + + // }, + // // &cli.Command{ + // // Name: "grpc", + // // Action: func(ctx *cli.Context) error { + // // return fmt.Errorf("not implemented") + // // }, + // // }, + // }, + Action: func(ctx *cli.Context) error { + level, err := log.ParseLevel(ctx.String("log-level")) + if err != nil { + return err + } + + log.SetLevel(level) + + log.Info("starting sshpiperd version: ", version()) + d, err := newDaemon(ctx) + + if err != nil { + return err + } + + var plugins []*plugin.GrpcPlugin + + args := ctx.Args().Slice() + remain := args + + for { + if len(remain) <= 0 { + break + } + + args, remain = splitByDash(remain) + + if len(args) <= 0 { + continue + } + + exe := args[0] + cmd := exec.Command(exe) + cmd.Args = args + + log.Info("starting plugin: ", cmd.Args) + + p, err := plugin.DialCmd(cmd) + if err != nil { + return err + } + go p.RecvLogs(log.StandardLogger().Out) + + plugins = append(plugins, &p.GrpcPlugin) + } + + if err := d.install(plugins...); err != nil { + return err + } + + return d.run() + }, + } + + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } +} diff --git a/crypto b/crypto index e6852b71..0fa3c5e5 160000 --- a/crypto +++ b/crypto @@ -1 +1 @@ -Subproject commit e6852b712aa5b99917e70720a8c27bf19fcea1b5 +Subproject commit 0fa3c5e5fe2210a9beb517968e40f930398774e8 diff --git a/go.mod b/go.mod index 35d7c95e..647be9be 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ replace ( ) require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0 github.com/dcu/go-authy v1.0.1 github.com/go-sql-driver/mysql v1.6.0 @@ -20,19 +21,20 @@ require ( github.com/sirupsen/logrus v1.8.1 github.com/tg123/remotesigner v0.0.0-20210928104451-7c20285909d1 github.com/tg123/sshkey v0.0.0-20201202190454-3bb356f89f1f + github.com/urfave/cli/v2 v2.10.3 golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 - google.golang.org/grpc v1.45.0 + google.golang.org/grpc v1.47.0 google.golang.org/protobuf v1.28.0 - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b + gopkg.in/yaml.v3 v3.0.1 k8s.io/apimachinery v0.22.2 k8s.io/client-go v1.5.2 ) require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 // indirect github.com/cjlapao/common-go v0.0.19 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denisenkom/go-mssqldb v0.11.0 // indirect github.com/go-logr/logr v1.1.0 // indirect @@ -59,6 +61,8 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect diff --git a/go.sum b/go.sum index 8be77643..d091fd50 100644 --- a/go.sum +++ b/go.sum @@ -71,7 +71,10 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -91,6 +94,7 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= @@ -202,6 +206,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -283,6 +289,8 @@ github.com/pockost/sshpipe-k8s-lib v0.0.3/go.mod h1:gDUHQhvnDsuvrIVuVD6HCaFYEZ1i github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -307,6 +315,10 @@ github.com/tg123/remotesigner v0.0.0-20210928104451-7c20285909d1 h1:17rr5yKlOnsx github.com/tg123/remotesigner v0.0.0-20210928104451-7c20285909d1/go.mod h1:leliuGRH9ayYYwRo6JO8yg+KyWcltK69XJdLv1x7slM= github.com/tg123/sshkey v0.0.0-20201202190454-3bb356f89f1f h1:MOxh2uC27wne9vo2OJqtL2W0Uq3qbBnaOGKgiJA+/fI= github.com/tg123/sshkey v0.0.0-20201202190454-3bb356f89f1f/go.mod h1:0NrddipH8l+ho+Cpbs4qrpEaqbNeHUAfhxURhKC1waE= +github.com/urfave/cli/v2 v2.10.3 h1:oi571Fxz5aHugfBAJd5nkwSk3fzATXtMlpxdLylSCMo= +github.com/urfave/cli/v2 v2.10.3/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -436,8 +448,10 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -587,6 +601,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -624,6 +640,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/libplugin/doc.go b/libplugin/doc.go new file mode 100644 index 00000000..b71720e2 --- /dev/null +++ b/libplugin/doc.go @@ -0,0 +1,3 @@ +//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative plugin.proto + +package libplugin diff --git a/libplugin/ioconn/cmd.go b/libplugin/ioconn/cmd.go new file mode 100644 index 00000000..cb68dbfc --- /dev/null +++ b/libplugin/ioconn/cmd.go @@ -0,0 +1,48 @@ +package ioconn + +import ( + "io" + "net" + "os/exec" +) + +type cmdconn struct { + conn + cmd *exec.Cmd +} + +func (c *cmdconn) Close() error { + err := c.conn.Close() + + if c.cmd.Process != nil { + return c.cmd.Process.Kill() + } + + return err +} + +func DialCmd(cmd *exec.Cmd) (net.Conn, io.ReadCloser, error) { + in, err := cmd.StdoutPipe() + if err != nil { + return nil, nil, err + } + + out, err := cmd.StdinPipe() + if err != nil { + return nil, nil, err + } + + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, nil, err + } + + if err := cmd.Start(); err != nil { + return nil, nil, err + } + + return &cmdconn{ + conn: *dial(in, out), + cmd: cmd, + }, stderr, nil +} diff --git a/libplugin/ioconn/conn.go b/libplugin/ioconn/conn.go new file mode 100644 index 00000000..5306ff7e --- /dev/null +++ b/libplugin/ioconn/conn.go @@ -0,0 +1,113 @@ +package ioconn + +import ( + "fmt" + "io" + "net" + "time" +) + +type addr string + +func (a addr) Network() string { + return "ioconn" +} + +func (a addr) String() string { + return string(a) +} + +type conn struct { + in io.ReadCloser + out io.WriteCloser +} + +func Dial(in io.ReadCloser, out io.WriteCloser) (net.Conn, error) { + return dial(in, out), nil +} + +func dial(in io.ReadCloser, out io.WriteCloser) *conn { + return &conn{in, out} +} + +// Read reads data from the connection. +// Read can be made to time out and return an error after a fixed +// time limit; see SetDeadline and SetReadDeadline. +func (c *conn) Read(b []byte) (n int, err error) { + return c.in.Read(b) +} + +// Write writes data to the connection. +// Write can be made to time out and return an error after a fixed +// time limit; see SetDeadline and SetWriteDeadline. +func (c *conn) Write(b []byte) (n int, err error) { + return c.out.Write(b) +} + +// Close closes the connection. +// Any blocked Read or Write operations will be unblocked and return errors. +func (c *conn) Close() error { + inerr := c.in.Close() + outerr := c.out.Close() + + if inerr == nil { + return outerr + } + + if outerr == nil { + return outerr + } + + return fmt.Errorf("io close error in: %v, out: %v", inerr, outerr) +} + +// LocalAddr returns the local network address, if known. +func (c *conn) LocalAddr() net.Addr { + return addr("ioconn:local") +} + +// RemoteAddr returns the remote network address, if known. +func (c *conn) RemoteAddr() net.Addr { + return addr("ioconn:remote") +} + +// SetDeadline sets the read and write deadlines associated +// with the connection. It is equivalent to calling both +// SetReadDeadline and SetWriteDeadline. +// +// A deadline is an absolute time after which I/O operations +// fail instead of blocking. The deadline applies to all future +// and pending I/O, not just the immediately following call to +// Read or Write. After a deadline has been exceeded, the +// connection can be refreshed by setting a deadline in the future. +// +// If the deadline is exceeded a call to Read or Write or to other +// I/O methods will return an error that wraps os.ErrDeadlineExceeded. +// This can be tested using errors.Is(err, os.ErrDeadlineExceeded). +// The error's Timeout method will return true, but note that there +// are other possible errors for which the Timeout method will +// return true even if the deadline has not been exceeded. +// +// An idle timeout can be implemented by repeatedly extending +// the deadline after successful Read or Write calls. +// +// A zero value for t means I/O operations will not time out. +func (c *conn) SetDeadline(t time.Time) error { + return nil +} + +// SetReadDeadline sets the deadline for future Read calls +// and any currently-blocked Read call. +// A zero value for t means Read will not time out. +func (c *conn) SetReadDeadline(t time.Time) error { + return nil +} + +// SetWriteDeadline sets the deadline for future Write calls +// and any currently-blocked Write call. +// Even if write times out, it may return n > 0, indicating that +// some of the data was successfully written. +// A zero value for t means Write will not time out. +func (c *conn) SetWriteDeadline(t time.Time) error { + return nil +} diff --git a/libplugin/ioconn/listener.go b/libplugin/ioconn/listener.go new file mode 100644 index 00000000..1d33d7c4 --- /dev/null +++ b/libplugin/ioconn/listener.go @@ -0,0 +1,37 @@ +package ioconn + +import ( + "io" + "net" +) + +type singleConnListener struct { + conn + used chan int +} + +// Accept implements net.Listener +func (l *singleConnListener) Accept() (net.Conn, error) { + <-l.used + return &l.conn, nil +} + +// Addr implements net.Listener +func (l *singleConnListener) Addr() net.Addr { + return l.conn.LocalAddr() +} + +// Close implements net.Listener +func (l *singleConnListener) Close() error { + return l.conn.Close() +} + +func ListenFromSingleIO(in io.ReadCloser, out io.WriteCloser) (net.Listener, error) { + l := &singleConnListener{ + conn{in, out}, + make(chan int, 1), + } + + l.used <- 1 // ready for accept + return l, nil +} diff --git a/libplugin/plugin.pb.go b/libplugin/plugin.pb.go new file mode 100644 index 00000000..a9e5256f --- /dev/null +++ b/libplugin/plugin.pb.go @@ -0,0 +1,2746 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.14.0 +// source: plugin.proto + +package libplugin + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type AuthMethod int32 + +const ( + AuthMethod_NONE AuthMethod = 0 + AuthMethod_PASSWORD AuthMethod = 1 + AuthMethod_PUBLICKEY AuthMethod = 2 + AuthMethod_KEYBOARD_INTERACTIVE AuthMethod = 3 +) + +// Enum value maps for AuthMethod. +var ( + AuthMethod_name = map[int32]string{ + 0: "NONE", + 1: "PASSWORD", + 2: "PUBLICKEY", + 3: "KEYBOARD_INTERACTIVE", + } + AuthMethod_value = map[string]int32{ + "NONE": 0, + "PASSWORD": 1, + "PUBLICKEY": 2, + "KEYBOARD_INTERACTIVE": 3, + } +) + +func (x AuthMethod) Enum() *AuthMethod { + p := new(AuthMethod) + *p = x + return p +} + +func (x AuthMethod) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AuthMethod) Descriptor() protoreflect.EnumDescriptor { + return file_plugin_proto_enumTypes[0].Descriptor() +} + +func (AuthMethod) Type() protoreflect.EnumType { + return &file_plugin_proto_enumTypes[0] +} + +func (x AuthMethod) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AuthMethod.Descriptor instead. +func (AuthMethod) EnumDescriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{0} +} + +type ConnMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserName string `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + FromAddr string `protobuf:"bytes,2,opt,name=from_addr,json=fromAddr,proto3" json:"from_addr,omitempty"` + UniqId string `protobuf:"bytes,3,opt,name=uniq_id,json=uniqId,proto3" json:"uniq_id,omitempty"` +} + +func (x *ConnMeta) Reset() { + *x = ConnMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnMeta) ProtoMessage() {} + +func (x *ConnMeta) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnMeta.ProtoReflect.Descriptor instead. +func (*ConnMeta) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{0} +} + +func (x *ConnMeta) GetUserName() string { + if x != nil { + return x.UserName + } + return "" +} + +func (x *ConnMeta) GetFromAddr() string { + if x != nil { + return x.FromAddr + } + return "" +} + +func (x *ConnMeta) GetUniqId() string { + if x != nil { + return x.UniqId + } + return "" +} + +type Upstream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` + UserName string `protobuf:"bytes,3,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + IgnoreHostKey bool `protobuf:"varint,4,opt,name=ignore_host_key,json=ignoreHostKey,proto3" json:"ignore_host_key,omitempty"` + // Types that are assignable to Auth: + // *Upstream_None + // *Upstream_Password + // *Upstream_PrivateKey + // *Upstream_RemoteSigner + // *Upstream_NextPlugin + Auth isUpstream_Auth `protobuf_oneof:"auth"` +} + +func (x *Upstream) Reset() { + *x = Upstream{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Upstream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upstream) ProtoMessage() {} + +func (x *Upstream) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upstream.ProtoReflect.Descriptor instead. +func (*Upstream) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{1} +} + +func (x *Upstream) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *Upstream) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *Upstream) GetUserName() string { + if x != nil { + return x.UserName + } + return "" +} + +func (x *Upstream) GetIgnoreHostKey() bool { + if x != nil { + return x.IgnoreHostKey + } + return false +} + +func (m *Upstream) GetAuth() isUpstream_Auth { + if m != nil { + return m.Auth + } + return nil +} + +func (x *Upstream) GetNone() *UpstreamNoneAuth { + if x, ok := x.GetAuth().(*Upstream_None); ok { + return x.None + } + return nil +} + +func (x *Upstream) GetPassword() *UpstreamPasswordAuth { + if x, ok := x.GetAuth().(*Upstream_Password); ok { + return x.Password + } + return nil +} + +func (x *Upstream) GetPrivateKey() *UpstreamPrivateKeyAuth { + if x, ok := x.GetAuth().(*Upstream_PrivateKey); ok { + return x.PrivateKey + } + return nil +} + +func (x *Upstream) GetRemoteSigner() *UpstreamRemoteSignerAuth { + if x, ok := x.GetAuth().(*Upstream_RemoteSigner); ok { + return x.RemoteSigner + } + return nil +} + +func (x *Upstream) GetNextPlugin() *UpstreamNextPluginAuth { + if x, ok := x.GetAuth().(*Upstream_NextPlugin); ok { + return x.NextPlugin + } + return nil +} + +type isUpstream_Auth interface { + isUpstream_Auth() +} + +type Upstream_None struct { + None *UpstreamNoneAuth `protobuf:"bytes,100,opt,name=none,proto3,oneof"` +} + +type Upstream_Password struct { + Password *UpstreamPasswordAuth `protobuf:"bytes,101,opt,name=password,proto3,oneof"` +} + +type Upstream_PrivateKey struct { + PrivateKey *UpstreamPrivateKeyAuth `protobuf:"bytes,102,opt,name=private_key,json=privateKey,proto3,oneof"` +} + +type Upstream_RemoteSigner struct { + RemoteSigner *UpstreamRemoteSignerAuth `protobuf:"bytes,103,opt,name=remote_signer,json=remoteSigner,proto3,oneof"` +} + +type Upstream_NextPlugin struct { + NextPlugin *UpstreamNextPluginAuth `protobuf:"bytes,200,opt,name=next_plugin,json=nextPlugin,proto3,oneof"` +} + +func (*Upstream_None) isUpstream_Auth() {} + +func (*Upstream_Password) isUpstream_Auth() {} + +func (*Upstream_PrivateKey) isUpstream_Auth() {} + +func (*Upstream_RemoteSigner) isUpstream_Auth() {} + +func (*Upstream_NextPlugin) isUpstream_Auth() {} + +type UpstreamNoneAuth struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpstreamNoneAuth) Reset() { + *x = UpstreamNoneAuth{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamNoneAuth) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamNoneAuth) ProtoMessage() {} + +func (x *UpstreamNoneAuth) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamNoneAuth.ProtoReflect.Descriptor instead. +func (*UpstreamNoneAuth) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{2} +} + +type UpstreamPasswordAuth struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *UpstreamPasswordAuth) Reset() { + *x = UpstreamPasswordAuth{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamPasswordAuth) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamPasswordAuth) ProtoMessage() {} + +func (x *UpstreamPasswordAuth) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamPasswordAuth.ProtoReflect.Descriptor instead. +func (*UpstreamPasswordAuth) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{3} +} + +func (x *UpstreamPasswordAuth) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type UpstreamPrivateKeyAuth struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PrivateKey []byte `protobuf:"bytes,1,opt,name=private_key,json=privateKey,proto3" json:"private_key,omitempty"` +} + +func (x *UpstreamPrivateKeyAuth) Reset() { + *x = UpstreamPrivateKeyAuth{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamPrivateKeyAuth) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamPrivateKeyAuth) ProtoMessage() {} + +func (x *UpstreamPrivateKeyAuth) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamPrivateKeyAuth.ProtoReflect.Descriptor instead. +func (*UpstreamPrivateKeyAuth) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{4} +} + +func (x *UpstreamPrivateKeyAuth) GetPrivateKey() []byte { + if x != nil { + return x.PrivateKey + } + return nil +} + +type UpstreamRemoteSignerAuth struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta string `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *UpstreamRemoteSignerAuth) Reset() { + *x = UpstreamRemoteSignerAuth{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamRemoteSignerAuth) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamRemoteSignerAuth) ProtoMessage() {} + +func (x *UpstreamRemoteSignerAuth) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamRemoteSignerAuth.ProtoReflect.Descriptor instead. +func (*UpstreamRemoteSignerAuth) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{5} +} + +func (x *UpstreamRemoteSignerAuth) GetMeta() string { + if x != nil { + return x.Meta + } + return "" +} + +type UpstreamNextPluginAuth struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta map[string]string `protobuf:"bytes,1,rep,name=meta,proto3" json:"meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *UpstreamNextPluginAuth) Reset() { + *x = UpstreamNextPluginAuth{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamNextPluginAuth) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamNextPluginAuth) ProtoMessage() {} + +func (x *UpstreamNextPluginAuth) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamNextPluginAuth.ProtoReflect.Descriptor instead. +func (*UpstreamNextPluginAuth) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{6} +} + +func (x *UpstreamNextPluginAuth) GetMeta() map[string]string { + if x != nil { + return x.Meta + } + return nil +} + +type StartLogRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UniqId string `protobuf:"bytes,1,opt,name=uniq_id,json=uniqId,proto3" json:"uniq_id,omitempty"` + Level string `protobuf:"bytes,2,opt,name=level,proto3" json:"level,omitempty"` +} + +func (x *StartLogRequest) Reset() { + *x = StartLogRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StartLogRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartLogRequest) ProtoMessage() {} + +func (x *StartLogRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartLogRequest.ProtoReflect.Descriptor instead. +func (*StartLogRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{7} +} + +func (x *StartLogRequest) GetUniqId() string { + if x != nil { + return x.UniqId + } + return "" +} + +func (x *StartLogRequest) GetLevel() string { + if x != nil { + return x.Level + } + return "" +} + +type Log struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *Log) Reset() { + *x = Log{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Log) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Log) ProtoMessage() {} + +func (x *Log) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Log.ProtoReflect.Descriptor instead. +func (*Log) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{8} +} + +func (x *Log) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type ListCallbackRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListCallbackRequest) Reset() { + *x = ListCallbackRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListCallbackRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListCallbackRequest) ProtoMessage() {} + +func (x *ListCallbackRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListCallbackRequest.ProtoReflect.Descriptor instead. +func (*ListCallbackRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{9} +} + +type ListCallbackResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Callbacks []string `protobuf:"bytes,1,rep,name=callbacks,proto3" json:"callbacks,omitempty"` +} + +func (x *ListCallbackResponse) Reset() { + *x = ListCallbackResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListCallbackResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListCallbackResponse) ProtoMessage() {} + +func (x *ListCallbackResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListCallbackResponse.ProtoReflect.Descriptor instead. +func (*ListCallbackResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{10} +} + +func (x *ListCallbackResponse) GetCallbacks() []string { + if x != nil { + return x.Callbacks + } + return nil +} + +type NewConnectionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *NewConnectionRequest) Reset() { + *x = NewConnectionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NewConnectionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NewConnectionRequest) ProtoMessage() {} + +func (x *NewConnectionRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NewConnectionRequest.ProtoReflect.Descriptor instead. +func (*NewConnectionRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{11} +} + +func (x *NewConnectionRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +type NewConnectionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *NewConnectionResponse) Reset() { + *x = NewConnectionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NewConnectionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NewConnectionResponse) ProtoMessage() {} + +func (x *NewConnectionResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NewConnectionResponse.ProtoReflect.Descriptor instead. +func (*NewConnectionResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{12} +} + +type NextAuthMethodsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *NextAuthMethodsRequest) Reset() { + *x = NextAuthMethodsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NextAuthMethodsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NextAuthMethodsRequest) ProtoMessage() {} + +func (x *NextAuthMethodsRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NextAuthMethodsRequest.ProtoReflect.Descriptor instead. +func (*NextAuthMethodsRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{13} +} + +func (x *NextAuthMethodsRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +type NextAuthMethodsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Methods []AuthMethod `protobuf:"varint,1,rep,packed,name=methods,proto3,enum=libplugin.AuthMethod" json:"methods,omitempty"` +} + +func (x *NextAuthMethodsResponse) Reset() { + *x = NextAuthMethodsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NextAuthMethodsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NextAuthMethodsResponse) ProtoMessage() {} + +func (x *NextAuthMethodsResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NextAuthMethodsResponse.ProtoReflect.Descriptor instead. +func (*NextAuthMethodsResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{14} +} + +func (x *NextAuthMethodsResponse) GetMethods() []AuthMethod { + if x != nil { + return x.Methods + } + return nil +} + +type NoneAuthRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *NoneAuthRequest) Reset() { + *x = NoneAuthRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NoneAuthRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NoneAuthRequest) ProtoMessage() {} + +func (x *NoneAuthRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NoneAuthRequest.ProtoReflect.Descriptor instead. +func (*NoneAuthRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{15} +} + +func (x *NoneAuthRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +type NoneAuthResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Upstream *Upstream `protobuf:"bytes,1,opt,name=upstream,proto3" json:"upstream,omitempty"` +} + +func (x *NoneAuthResponse) Reset() { + *x = NoneAuthResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NoneAuthResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NoneAuthResponse) ProtoMessage() {} + +func (x *NoneAuthResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NoneAuthResponse.ProtoReflect.Descriptor instead. +func (*NoneAuthResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{16} +} + +func (x *NoneAuthResponse) GetUpstream() *Upstream { + if x != nil { + return x.Upstream + } + return nil +} + +type PasswordAuthRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + Password []byte `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *PasswordAuthRequest) Reset() { + *x = PasswordAuthRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PasswordAuthRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PasswordAuthRequest) ProtoMessage() {} + +func (x *PasswordAuthRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PasswordAuthRequest.ProtoReflect.Descriptor instead. +func (*PasswordAuthRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{17} +} + +func (x *PasswordAuthRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *PasswordAuthRequest) GetPassword() []byte { + if x != nil { + return x.Password + } + return nil +} + +type PasswordAuthResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Upstream *Upstream `protobuf:"bytes,1,opt,name=upstream,proto3" json:"upstream,omitempty"` +} + +func (x *PasswordAuthResponse) Reset() { + *x = PasswordAuthResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PasswordAuthResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PasswordAuthResponse) ProtoMessage() {} + +func (x *PasswordAuthResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PasswordAuthResponse.ProtoReflect.Descriptor instead. +func (*PasswordAuthResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{18} +} + +func (x *PasswordAuthResponse) GetUpstream() *Upstream { + if x != nil { + return x.Upstream + } + return nil +} + +type PublicKeyAuthRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` +} + +func (x *PublicKeyAuthRequest) Reset() { + *x = PublicKeyAuthRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublicKeyAuthRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublicKeyAuthRequest) ProtoMessage() {} + +func (x *PublicKeyAuthRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublicKeyAuthRequest.ProtoReflect.Descriptor instead. +func (*PublicKeyAuthRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{19} +} + +func (x *PublicKeyAuthRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *PublicKeyAuthRequest) GetPublicKey() []byte { + if x != nil { + return x.PublicKey + } + return nil +} + +type PublicKeyAuthResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Upstream *Upstream `protobuf:"bytes,1,opt,name=upstream,proto3" json:"upstream,omitempty"` +} + +func (x *PublicKeyAuthResponse) Reset() { + *x = PublicKeyAuthResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublicKeyAuthResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublicKeyAuthResponse) ProtoMessage() {} + +func (x *PublicKeyAuthResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublicKeyAuthResponse.ProtoReflect.Descriptor instead. +func (*PublicKeyAuthResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{20} +} + +func (x *PublicKeyAuthResponse) GetUpstream() *Upstream { + if x != nil { + return x.Upstream + } + return nil +} + +type KeyboardInteractiveUserResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Answers []string `protobuf:"bytes,1,rep,name=answers,proto3" json:"answers,omitempty"` +} + +func (x *KeyboardInteractiveUserResponse) Reset() { + *x = KeyboardInteractiveUserResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyboardInteractiveUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyboardInteractiveUserResponse) ProtoMessage() {} + +func (x *KeyboardInteractiveUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyboardInteractiveUserResponse.ProtoReflect.Descriptor instead. +func (*KeyboardInteractiveUserResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{21} +} + +func (x *KeyboardInteractiveUserResponse) GetAnswers() []string { + if x != nil { + return x.Answers + } + return nil +} + +type KeyboardInteractivePromptRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Instruction string `protobuf:"bytes,2,opt,name=instruction,proto3" json:"instruction,omitempty"` + Questions []*KeyboardInteractivePromptRequest_Question `protobuf:"bytes,3,rep,name=questions,proto3" json:"questions,omitempty"` +} + +func (x *KeyboardInteractivePromptRequest) Reset() { + *x = KeyboardInteractivePromptRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyboardInteractivePromptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyboardInteractivePromptRequest) ProtoMessage() {} + +func (x *KeyboardInteractivePromptRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyboardInteractivePromptRequest.ProtoReflect.Descriptor instead. +func (*KeyboardInteractivePromptRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{22} +} + +func (x *KeyboardInteractivePromptRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *KeyboardInteractivePromptRequest) GetInstruction() string { + if x != nil { + return x.Instruction + } + return "" +} + +func (x *KeyboardInteractivePromptRequest) GetQuestions() []*KeyboardInteractivePromptRequest_Question { + if x != nil { + return x.Questions + } + return nil +} + +type KeyboardInteractiveMetaRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *KeyboardInteractiveMetaRequest) Reset() { + *x = KeyboardInteractiveMetaRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyboardInteractiveMetaRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyboardInteractiveMetaRequest) ProtoMessage() {} + +func (x *KeyboardInteractiveMetaRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyboardInteractiveMetaRequest.ProtoReflect.Descriptor instead. +func (*KeyboardInteractiveMetaRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{23} +} + +type KeyboardInteractiveMetaResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *KeyboardInteractiveMetaResponse) Reset() { + *x = KeyboardInteractiveMetaResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyboardInteractiveMetaResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyboardInteractiveMetaResponse) ProtoMessage() {} + +func (x *KeyboardInteractiveMetaResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyboardInteractiveMetaResponse.ProtoReflect.Descriptor instead. +func (*KeyboardInteractiveMetaResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{24} +} + +func (x *KeyboardInteractiveMetaResponse) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +type KeyboardInteractiveFinishRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Upstream *Upstream `protobuf:"bytes,1,opt,name=upstream,proto3" json:"upstream,omitempty"` + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` +} + +func (x *KeyboardInteractiveFinishRequest) Reset() { + *x = KeyboardInteractiveFinishRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyboardInteractiveFinishRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyboardInteractiveFinishRequest) ProtoMessage() {} + +func (x *KeyboardInteractiveFinishRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyboardInteractiveFinishRequest.ProtoReflect.Descriptor instead. +func (*KeyboardInteractiveFinishRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{25} +} + +func (x *KeyboardInteractiveFinishRequest) GetUpstream() *Upstream { + if x != nil { + return x.Upstream + } + return nil +} + +func (x *KeyboardInteractiveFinishRequest) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +type KeyboardInteractiveAuthMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Message: + // *KeyboardInteractiveAuthMessage_PromptRequest + // *KeyboardInteractiveAuthMessage_UserResponse + // *KeyboardInteractiveAuthMessage_MetaRequest + // *KeyboardInteractiveAuthMessage_MetaResponse + // *KeyboardInteractiveAuthMessage_FinishRequest + Message isKeyboardInteractiveAuthMessage_Message `protobuf_oneof:"message"` +} + +func (x *KeyboardInteractiveAuthMessage) Reset() { + *x = KeyboardInteractiveAuthMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyboardInteractiveAuthMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyboardInteractiveAuthMessage) ProtoMessage() {} + +func (x *KeyboardInteractiveAuthMessage) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyboardInteractiveAuthMessage.ProtoReflect.Descriptor instead. +func (*KeyboardInteractiveAuthMessage) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{26} +} + +func (m *KeyboardInteractiveAuthMessage) GetMessage() isKeyboardInteractiveAuthMessage_Message { + if m != nil { + return m.Message + } + return nil +} + +func (x *KeyboardInteractiveAuthMessage) GetPromptRequest() *KeyboardInteractivePromptRequest { + if x, ok := x.GetMessage().(*KeyboardInteractiveAuthMessage_PromptRequest); ok { + return x.PromptRequest + } + return nil +} + +func (x *KeyboardInteractiveAuthMessage) GetUserResponse() *KeyboardInteractiveUserResponse { + if x, ok := x.GetMessage().(*KeyboardInteractiveAuthMessage_UserResponse); ok { + return x.UserResponse + } + return nil +} + +func (x *KeyboardInteractiveAuthMessage) GetMetaRequest() *KeyboardInteractiveMetaRequest { + if x, ok := x.GetMessage().(*KeyboardInteractiveAuthMessage_MetaRequest); ok { + return x.MetaRequest + } + return nil +} + +func (x *KeyboardInteractiveAuthMessage) GetMetaResponse() *KeyboardInteractiveMetaResponse { + if x, ok := x.GetMessage().(*KeyboardInteractiveAuthMessage_MetaResponse); ok { + return x.MetaResponse + } + return nil +} + +func (x *KeyboardInteractiveAuthMessage) GetFinishRequest() *KeyboardInteractiveFinishRequest { + if x, ok := x.GetMessage().(*KeyboardInteractiveAuthMessage_FinishRequest); ok { + return x.FinishRequest + } + return nil +} + +type isKeyboardInteractiveAuthMessage_Message interface { + isKeyboardInteractiveAuthMessage_Message() +} + +type KeyboardInteractiveAuthMessage_PromptRequest struct { + PromptRequest *KeyboardInteractivePromptRequest `protobuf:"bytes,1,opt,name=prompt_request,json=promptRequest,proto3,oneof"` +} + +type KeyboardInteractiveAuthMessage_UserResponse struct { + UserResponse *KeyboardInteractiveUserResponse `protobuf:"bytes,2,opt,name=user_response,json=userResponse,proto3,oneof"` +} + +type KeyboardInteractiveAuthMessage_MetaRequest struct { + MetaRequest *KeyboardInteractiveMetaRequest `protobuf:"bytes,3,opt,name=meta_request,json=metaRequest,proto3,oneof"` +} + +type KeyboardInteractiveAuthMessage_MetaResponse struct { + MetaResponse *KeyboardInteractiveMetaResponse `protobuf:"bytes,4,opt,name=meta_response,json=metaResponse,proto3,oneof"` +} + +type KeyboardInteractiveAuthMessage_FinishRequest struct { + FinishRequest *KeyboardInteractiveFinishRequest `protobuf:"bytes,5,opt,name=finish_request,json=finishRequest,proto3,oneof"` +} + +func (*KeyboardInteractiveAuthMessage_PromptRequest) isKeyboardInteractiveAuthMessage_Message() {} + +func (*KeyboardInteractiveAuthMessage_UserResponse) isKeyboardInteractiveAuthMessage_Message() {} + +func (*KeyboardInteractiveAuthMessage_MetaRequest) isKeyboardInteractiveAuthMessage_Message() {} + +func (*KeyboardInteractiveAuthMessage_MetaResponse) isKeyboardInteractiveAuthMessage_Message() {} + +func (*KeyboardInteractiveAuthMessage_FinishRequest) isKeyboardInteractiveAuthMessage_Message() {} + +type UpstreamAuthFailureNoticeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` + Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` + AllowedMethods []AuthMethod `protobuf:"varint,4,rep,packed,name=allowed_methods,json=allowedMethods,proto3,enum=libplugin.AuthMethod" json:"allowed_methods,omitempty"` +} + +func (x *UpstreamAuthFailureNoticeRequest) Reset() { + *x = UpstreamAuthFailureNoticeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamAuthFailureNoticeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamAuthFailureNoticeRequest) ProtoMessage() {} + +func (x *UpstreamAuthFailureNoticeRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamAuthFailureNoticeRequest.ProtoReflect.Descriptor instead. +func (*UpstreamAuthFailureNoticeRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{27} +} + +func (x *UpstreamAuthFailureNoticeRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *UpstreamAuthFailureNoticeRequest) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *UpstreamAuthFailureNoticeRequest) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *UpstreamAuthFailureNoticeRequest) GetAllowedMethods() []AuthMethod { + if x != nil { + return x.AllowedMethods + } + return nil +} + +type UpstreamAuthFailureNoticeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpstreamAuthFailureNoticeResponse) Reset() { + *x = UpstreamAuthFailureNoticeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamAuthFailureNoticeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamAuthFailureNoticeResponse) ProtoMessage() {} + +func (x *UpstreamAuthFailureNoticeResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamAuthFailureNoticeResponse.ProtoReflect.Descriptor instead. +func (*UpstreamAuthFailureNoticeResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{28} +} + +type BannerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *BannerRequest) Reset() { + *x = BannerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BannerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BannerRequest) ProtoMessage() {} + +func (x *BannerRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BannerRequest.ProtoReflect.Descriptor instead. +func (*BannerRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{29} +} + +func (x *BannerRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +type BannerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *BannerResponse) Reset() { + *x = BannerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BannerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BannerResponse) ProtoMessage() {} + +func (x *BannerResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BannerResponse.ProtoReflect.Descriptor instead. +func (*BannerResponse) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{30} +} + +func (x *BannerResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type VerifyHostKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *ConnMeta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` + Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *VerifyHostKeyRequest) Reset() { + *x = VerifyHostKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VerifyHostKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyHostKeyRequest) ProtoMessage() {} + +func (x *VerifyHostKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyHostKeyRequest.ProtoReflect.Descriptor instead. +func (*VerifyHostKeyRequest) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{31} +} + +func (x *VerifyHostKeyRequest) GetMeta() *ConnMeta { + if x != nil { + return x.Meta + } + return nil +} + +func (x *VerifyHostKeyRequest) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +type VerifyHostKeyReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Verified bool `protobuf:"varint,1,opt,name=verified,proto3" json:"verified,omitempty"` +} + +func (x *VerifyHostKeyReply) Reset() { + *x = VerifyHostKeyReply{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VerifyHostKeyReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyHostKeyReply) ProtoMessage() {} + +func (x *VerifyHostKeyReply) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyHostKeyReply.ProtoReflect.Descriptor instead. +func (*VerifyHostKeyReply) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{32} +} + +func (x *VerifyHostKeyReply) GetVerified() bool { + if x != nil { + return x.Verified + } + return false +} + +type KeyboardInteractivePromptRequest_Question struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` + Echo bool `protobuf:"varint,2,opt,name=echo,proto3" json:"echo,omitempty"` +} + +func (x *KeyboardInteractivePromptRequest_Question) Reset() { + *x = KeyboardInteractivePromptRequest_Question{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyboardInteractivePromptRequest_Question) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyboardInteractivePromptRequest_Question) ProtoMessage() {} + +func (x *KeyboardInteractivePromptRequest_Question) ProtoReflect() protoreflect.Message { + mi := &file_plugin_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyboardInteractivePromptRequest_Question.ProtoReflect.Descriptor instead. +func (*KeyboardInteractivePromptRequest_Question) Descriptor() ([]byte, []int) { + return file_plugin_proto_rawDescGZIP(), []int{22, 0} +} + +func (x *KeyboardInteractivePromptRequest_Question) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *KeyboardInteractivePromptRequest_Question) GetEcho() bool { + if x != nil { + return x.Echo + } + return false +} + +var File_plugin_proto protoreflect.FileDescriptor + +var file_plugin_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, + 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x22, 0x5d, 0x0a, 0x08, 0x43, 0x6f, 0x6e, + 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x12, + 0x17, 0x0a, 0x07, 0x75, 0x6e, 0x69, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x75, 0x6e, 0x69, 0x71, 0x49, 0x64, 0x22, 0xca, 0x03, 0x0a, 0x08, 0x55, 0x70, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x67, + 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x4b, + 0x65, 0x79, 0x12, 0x31, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4e, 0x6f, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52, + 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x12, 0x44, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6c, 0x69, 0x62, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52, 0x0a, + 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x4a, 0x0a, 0x0d, 0x72, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x67, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52, 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x0b, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0xc8, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6c, + 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x48, + 0x00, 0x52, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x42, 0x06, 0x0a, + 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x12, 0x0a, 0x10, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x4e, 0x6f, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x22, 0x32, 0x0a, 0x14, 0x55, 0x70, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x75, 0x74, + 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x39, 0x0a, + 0x16, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x2e, 0x0a, 0x18, 0x55, 0x70, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, + 0x41, 0x75, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x92, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x41, + 0x75, 0x74, 0x68, 0x12, 0x3f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x41, 0x75, 0x74, 0x68, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 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, 0x40, 0x0a, + 0x0f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x17, 0x0a, 0x07, 0x75, 0x6e, 0x69, 0x71, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x75, 0x6e, 0x69, 0x71, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, + 0x1f, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 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, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x43, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x22, 0x3f, 0x0a, + 0x14, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x43, 0x6f, 0x6e, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x17, + 0x0a, 0x15, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x0a, 0x16, 0x4e, 0x65, 0x78, 0x74, 0x41, + 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, + 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x4a, 0x0a, 0x17, 0x4e, 0x65, + 0x78, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x07, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x22, 0x3a, 0x0a, 0x0f, 0x4e, 0x6f, 0x6e, 0x65, 0x41, 0x75, + 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x65, 0x74, + 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x22, 0x43, 0x0a, 0x10, 0x4e, 0x6f, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x08, 0x75, + 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x5a, 0x0a, 0x13, 0x50, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, + 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, + 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x4d, 0x65, 0x74, + 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x22, 0x47, 0x0a, 0x14, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, + 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x75, + 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x08, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x5e, 0x0a, 0x14, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, + 0x6f, 0x6e, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x0a, + 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x48, 0x0a, 0x15, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x08, 0x75, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x3b, 0x0a, 0x1f, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x6e, 0x73, + 0x77, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x6e, 0x73, 0x77, + 0x65, 0x72, 0x73, 0x22, 0xe0, 0x01, 0x0a, 0x20, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x6d, 0x70, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, + 0x0a, 0x09, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x34, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4b, 0x65, + 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x51, + 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x1a, 0x32, 0x0a, 0x08, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, + 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x63, 0x68, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x04, 0x65, 0x63, 0x68, 0x6f, 0x22, 0x20, 0x0a, 0x1e, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4a, 0x0a, 0x1f, 0x4b, 0x65, 0x79, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x6d, + 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, + 0x6d, 0x65, 0x74, 0x61, 0x22, 0x78, 0x0a, 0x20, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x08, 0x75, 0x70, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x08, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xcd, + 0x03, 0x0a, 0x1e, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x54, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6c, 0x69, 0x62, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x51, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, + 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x75, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0c, 0x6d, 0x65, + 0x74, 0x61, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4b, 0x65, 0x79, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6d, + 0x65, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x51, 0x0a, 0x0d, 0x6d, 0x65, + 0x74, 0x61, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2a, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4b, 0x65, + 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, + 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, + 0x0e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb9, + 0x01, 0x0a, 0x20, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x46, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3e, 0x0a, 0x0f, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x22, 0x23, 0x0a, 0x21, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, + 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x38, 0x0a, 0x0d, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x4d, + 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x2a, 0x0a, 0x0e, 0x42, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 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, 0x51, 0x0a, 0x14, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, + 0x6f, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, + 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x69, + 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x30, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2a, 0x4d, 0x0a, 0x0a, 0x41, 0x75, + 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, + 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x10, 0x01, + 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x4b, 0x45, 0x59, 0x10, 0x02, 0x12, + 0x18, 0x0a, 0x14, 0x4b, 0x45, 0x59, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x49, 0x4e, 0x54, 0x45, + 0x52, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x32, 0xc1, 0x07, 0x0a, 0x0e, 0x53, 0x73, + 0x68, 0x50, 0x69, 0x70, 0x65, 0x72, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x36, 0x0a, 0x04, + 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x0e, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4c, 0x6f, 0x67, + 0x22, 0x00, 0x30, 0x01, 0x12, 0x52, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x73, 0x12, 0x1e, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x69, 0x62, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, + 0x0a, 0x0f, 0x4e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x73, 0x12, 0x21, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, + 0x78, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x2e, 0x4e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x08, 0x4e, 0x6f, + 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x2e, 0x4e, 0x6f, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, + 0x6f, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x75, 0x74, + 0x68, 0x12, 0x1e, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x17, 0x4b, 0x65, + 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x41, 0x75, 0x74, 0x68, 0x12, 0x29, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x1a, 0x29, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4b, 0x65, 0x79, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, + 0x78, 0x0a, 0x19, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x46, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x6c, + 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x41, 0x75, 0x74, 0x68, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4e, 0x6f, 0x74, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6c, 0x69, 0x62, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x41, 0x75, + 0x74, 0x68, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x06, 0x42, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x6c, 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0d, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x48, 0x6f, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x2e, 0x6c, 0x69, + 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x6f, + 0x73, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, + 0x69, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, + 0x6f, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x25, 0x5a, + 0x23, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x67, 0x31, 0x32, + 0x33, 0x2f, 0x73, 0x73, 0x68, 0x70, 0x69, 0x70, 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_plugin_proto_rawDescOnce sync.Once + file_plugin_proto_rawDescData = file_plugin_proto_rawDesc +) + +func file_plugin_proto_rawDescGZIP() []byte { + file_plugin_proto_rawDescOnce.Do(func() { + file_plugin_proto_rawDescData = protoimpl.X.CompressGZIP(file_plugin_proto_rawDescData) + }) + return file_plugin_proto_rawDescData +} + +var file_plugin_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 35) +var file_plugin_proto_goTypes = []interface{}{ + (AuthMethod)(0), // 0: libplugin.AuthMethod + (*ConnMeta)(nil), // 1: libplugin.ConnMeta + (*Upstream)(nil), // 2: libplugin.Upstream + (*UpstreamNoneAuth)(nil), // 3: libplugin.UpstreamNoneAuth + (*UpstreamPasswordAuth)(nil), // 4: libplugin.UpstreamPasswordAuth + (*UpstreamPrivateKeyAuth)(nil), // 5: libplugin.UpstreamPrivateKeyAuth + (*UpstreamRemoteSignerAuth)(nil), // 6: libplugin.UpstreamRemoteSignerAuth + (*UpstreamNextPluginAuth)(nil), // 7: libplugin.UpstreamNextPluginAuth + (*StartLogRequest)(nil), // 8: libplugin.StartLogRequest + (*Log)(nil), // 9: libplugin.Log + (*ListCallbackRequest)(nil), // 10: libplugin.ListCallbackRequest + (*ListCallbackResponse)(nil), // 11: libplugin.ListCallbackResponse + (*NewConnectionRequest)(nil), // 12: libplugin.NewConnectionRequest + (*NewConnectionResponse)(nil), // 13: libplugin.NewConnectionResponse + (*NextAuthMethodsRequest)(nil), // 14: libplugin.NextAuthMethodsRequest + (*NextAuthMethodsResponse)(nil), // 15: libplugin.NextAuthMethodsResponse + (*NoneAuthRequest)(nil), // 16: libplugin.NoneAuthRequest + (*NoneAuthResponse)(nil), // 17: libplugin.NoneAuthResponse + (*PasswordAuthRequest)(nil), // 18: libplugin.PasswordAuthRequest + (*PasswordAuthResponse)(nil), // 19: libplugin.PasswordAuthResponse + (*PublicKeyAuthRequest)(nil), // 20: libplugin.PublicKeyAuthRequest + (*PublicKeyAuthResponse)(nil), // 21: libplugin.PublicKeyAuthResponse + (*KeyboardInteractiveUserResponse)(nil), // 22: libplugin.KeyboardInteractiveUserResponse + (*KeyboardInteractivePromptRequest)(nil), // 23: libplugin.KeyboardInteractivePromptRequest + (*KeyboardInteractiveMetaRequest)(nil), // 24: libplugin.KeyboardInteractiveMetaRequest + (*KeyboardInteractiveMetaResponse)(nil), // 25: libplugin.KeyboardInteractiveMetaResponse + (*KeyboardInteractiveFinishRequest)(nil), // 26: libplugin.KeyboardInteractiveFinishRequest + (*KeyboardInteractiveAuthMessage)(nil), // 27: libplugin.KeyboardInteractiveAuthMessage + (*UpstreamAuthFailureNoticeRequest)(nil), // 28: libplugin.UpstreamAuthFailureNoticeRequest + (*UpstreamAuthFailureNoticeResponse)(nil), // 29: libplugin.UpstreamAuthFailureNoticeResponse + (*BannerRequest)(nil), // 30: libplugin.BannerRequest + (*BannerResponse)(nil), // 31: libplugin.BannerResponse + (*VerifyHostKeyRequest)(nil), // 32: libplugin.VerifyHostKeyRequest + (*VerifyHostKeyReply)(nil), // 33: libplugin.VerifyHostKeyReply + nil, // 34: libplugin.UpstreamNextPluginAuth.MetaEntry + (*KeyboardInteractivePromptRequest_Question)(nil), // 35: libplugin.KeyboardInteractivePromptRequest.Question +} +var file_plugin_proto_depIdxs = []int32{ + 3, // 0: libplugin.Upstream.none:type_name -> libplugin.UpstreamNoneAuth + 4, // 1: libplugin.Upstream.password:type_name -> libplugin.UpstreamPasswordAuth + 5, // 2: libplugin.Upstream.private_key:type_name -> libplugin.UpstreamPrivateKeyAuth + 6, // 3: libplugin.Upstream.remote_signer:type_name -> libplugin.UpstreamRemoteSignerAuth + 7, // 4: libplugin.Upstream.next_plugin:type_name -> libplugin.UpstreamNextPluginAuth + 34, // 5: libplugin.UpstreamNextPluginAuth.meta:type_name -> libplugin.UpstreamNextPluginAuth.MetaEntry + 1, // 6: libplugin.NewConnectionRequest.meta:type_name -> libplugin.ConnMeta + 1, // 7: libplugin.NextAuthMethodsRequest.meta:type_name -> libplugin.ConnMeta + 0, // 8: libplugin.NextAuthMethodsResponse.methods:type_name -> libplugin.AuthMethod + 1, // 9: libplugin.NoneAuthRequest.meta:type_name -> libplugin.ConnMeta + 2, // 10: libplugin.NoneAuthResponse.upstream:type_name -> libplugin.Upstream + 1, // 11: libplugin.PasswordAuthRequest.meta:type_name -> libplugin.ConnMeta + 2, // 12: libplugin.PasswordAuthResponse.upstream:type_name -> libplugin.Upstream + 1, // 13: libplugin.PublicKeyAuthRequest.meta:type_name -> libplugin.ConnMeta + 2, // 14: libplugin.PublicKeyAuthResponse.upstream:type_name -> libplugin.Upstream + 35, // 15: libplugin.KeyboardInteractivePromptRequest.questions:type_name -> libplugin.KeyboardInteractivePromptRequest.Question + 1, // 16: libplugin.KeyboardInteractiveMetaResponse.meta:type_name -> libplugin.ConnMeta + 2, // 17: libplugin.KeyboardInteractiveFinishRequest.upstream:type_name -> libplugin.Upstream + 23, // 18: libplugin.KeyboardInteractiveAuthMessage.prompt_request:type_name -> libplugin.KeyboardInteractivePromptRequest + 22, // 19: libplugin.KeyboardInteractiveAuthMessage.user_response:type_name -> libplugin.KeyboardInteractiveUserResponse + 24, // 20: libplugin.KeyboardInteractiveAuthMessage.meta_request:type_name -> libplugin.KeyboardInteractiveMetaRequest + 25, // 21: libplugin.KeyboardInteractiveAuthMessage.meta_response:type_name -> libplugin.KeyboardInteractiveMetaResponse + 26, // 22: libplugin.KeyboardInteractiveAuthMessage.finish_request:type_name -> libplugin.KeyboardInteractiveFinishRequest + 1, // 23: libplugin.UpstreamAuthFailureNoticeRequest.meta:type_name -> libplugin.ConnMeta + 0, // 24: libplugin.UpstreamAuthFailureNoticeRequest.allowed_methods:type_name -> libplugin.AuthMethod + 1, // 25: libplugin.BannerRequest.meta:type_name -> libplugin.ConnMeta + 1, // 26: libplugin.VerifyHostKeyRequest.meta:type_name -> libplugin.ConnMeta + 8, // 27: libplugin.SshPiperPlugin.Logs:input_type -> libplugin.StartLogRequest + 10, // 28: libplugin.SshPiperPlugin.ListCallbacks:input_type -> libplugin.ListCallbackRequest + 12, // 29: libplugin.SshPiperPlugin.NewConnection:input_type -> libplugin.NewConnectionRequest + 14, // 30: libplugin.SshPiperPlugin.NextAuthMethods:input_type -> libplugin.NextAuthMethodsRequest + 16, // 31: libplugin.SshPiperPlugin.NoneAuth:input_type -> libplugin.NoneAuthRequest + 18, // 32: libplugin.SshPiperPlugin.PasswordAuth:input_type -> libplugin.PasswordAuthRequest + 20, // 33: libplugin.SshPiperPlugin.PublicKeyAuth:input_type -> libplugin.PublicKeyAuthRequest + 27, // 34: libplugin.SshPiperPlugin.KeyboardInteractiveAuth:input_type -> libplugin.KeyboardInteractiveAuthMessage + 28, // 35: libplugin.SshPiperPlugin.UpstreamAuthFailureNotice:input_type -> libplugin.UpstreamAuthFailureNoticeRequest + 30, // 36: libplugin.SshPiperPlugin.Banner:input_type -> libplugin.BannerRequest + 32, // 37: libplugin.SshPiperPlugin.VerifyHostKey:input_type -> libplugin.VerifyHostKeyRequest + 9, // 38: libplugin.SshPiperPlugin.Logs:output_type -> libplugin.Log + 11, // 39: libplugin.SshPiperPlugin.ListCallbacks:output_type -> libplugin.ListCallbackResponse + 13, // 40: libplugin.SshPiperPlugin.NewConnection:output_type -> libplugin.NewConnectionResponse + 15, // 41: libplugin.SshPiperPlugin.NextAuthMethods:output_type -> libplugin.NextAuthMethodsResponse + 17, // 42: libplugin.SshPiperPlugin.NoneAuth:output_type -> libplugin.NoneAuthResponse + 19, // 43: libplugin.SshPiperPlugin.PasswordAuth:output_type -> libplugin.PasswordAuthResponse + 21, // 44: libplugin.SshPiperPlugin.PublicKeyAuth:output_type -> libplugin.PublicKeyAuthResponse + 27, // 45: libplugin.SshPiperPlugin.KeyboardInteractiveAuth:output_type -> libplugin.KeyboardInteractiveAuthMessage + 29, // 46: libplugin.SshPiperPlugin.UpstreamAuthFailureNotice:output_type -> libplugin.UpstreamAuthFailureNoticeResponse + 31, // 47: libplugin.SshPiperPlugin.Banner:output_type -> libplugin.BannerResponse + 33, // 48: libplugin.SshPiperPlugin.VerifyHostKey:output_type -> libplugin.VerifyHostKeyReply + 38, // [38:49] is the sub-list for method output_type + 27, // [27:38] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name +} + +func init() { file_plugin_proto_init() } +func file_plugin_proto_init() { + if File_plugin_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_plugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Upstream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamNoneAuth); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamPasswordAuth); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamPrivateKeyAuth); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamRemoteSignerAuth); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamNextPluginAuth); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StartLogRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Log); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListCallbackRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListCallbackResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NewConnectionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NewConnectionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NextAuthMethodsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NextAuthMethodsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NoneAuthRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NoneAuthResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PasswordAuthRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PasswordAuthResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublicKeyAuthRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublicKeyAuthResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyboardInteractiveUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyboardInteractivePromptRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyboardInteractiveMetaRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyboardInteractiveMetaResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyboardInteractiveFinishRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyboardInteractiveAuthMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamAuthFailureNoticeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamAuthFailureNoticeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BannerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BannerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VerifyHostKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VerifyHostKeyReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyboardInteractivePromptRequest_Question); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_plugin_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*Upstream_None)(nil), + (*Upstream_Password)(nil), + (*Upstream_PrivateKey)(nil), + (*Upstream_RemoteSigner)(nil), + (*Upstream_NextPlugin)(nil), + } + file_plugin_proto_msgTypes[26].OneofWrappers = []interface{}{ + (*KeyboardInteractiveAuthMessage_PromptRequest)(nil), + (*KeyboardInteractiveAuthMessage_UserResponse)(nil), + (*KeyboardInteractiveAuthMessage_MetaRequest)(nil), + (*KeyboardInteractiveAuthMessage_MetaResponse)(nil), + (*KeyboardInteractiveAuthMessage_FinishRequest)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_plugin_proto_rawDesc, + NumEnums: 1, + NumMessages: 35, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_plugin_proto_goTypes, + DependencyIndexes: file_plugin_proto_depIdxs, + EnumInfos: file_plugin_proto_enumTypes, + MessageInfos: file_plugin_proto_msgTypes, + }.Build() + File_plugin_proto = out.File + file_plugin_proto_rawDesc = nil + file_plugin_proto_goTypes = nil + file_plugin_proto_depIdxs = nil +} diff --git a/libplugin/plugin.proto b/libplugin/plugin.proto new file mode 100644 index 00000000..a1611055 --- /dev/null +++ b/libplugin/plugin.proto @@ -0,0 +1,189 @@ +syntax = "proto3"; + +package libplugin; + +option go_package = "github.com/tg123/sshpiper/libplugin"; + +message ConnMeta { + string user_name = 1; + string from_addr = 2; + string uniq_id = 3; +} + +message Upstream { + string host = 1; + int32 port = 2; + string user_name = 3; + bool ignore_host_key = 4; + + oneof auth { + UpstreamNoneAuth none = 100; + UpstreamPasswordAuth password = 101; + UpstreamPrivateKeyAuth private_key = 102; + UpstreamRemoteSignerAuth remote_signer = 103; + UpstreamNextPluginAuth next_plugin = 200; + } +} + +message UpstreamNoneAuth { + +} + +message UpstreamPasswordAuth { + string password = 1; +} + +message UpstreamPrivateKeyAuth { + bytes private_key = 1; +} + +message UpstreamRemoteSignerAuth{ + string meta = 1; +} + +message UpstreamNextPluginAuth { + map meta = 1; +} + +service SshPiperPlugin { + rpc Logs(StartLogRequest) returns (stream Log) {} + rpc ListCallbacks(ListCallbackRequest) returns (ListCallbackResponse) {} + + rpc NewConnection(NewConnectionRequest) returns (NewConnectionResponse) {}; + rpc NextAuthMethods(NextAuthMethodsRequest) returns (NextAuthMethodsResponse) {}; + rpc NoneAuth(NoneAuthRequest) returns (NoneAuthResponse) {}; + rpc PasswordAuth(PasswordAuthRequest) returns (PasswordAuthResponse) {}; + rpc PublicKeyAuth(PublicKeyAuthRequest) returns (PublicKeyAuthResponse) {}; + rpc KeyboardInteractiveAuth(stream KeyboardInteractiveAuthMessage) returns (stream KeyboardInteractiveAuthMessage); + rpc UpstreamAuthFailureNotice(UpstreamAuthFailureNoticeRequest) returns (UpstreamAuthFailureNoticeResponse) {}; + rpc Banner(BannerRequest) returns (BannerResponse) {}; + rpc VerifyHostKey (VerifyHostKeyRequest) returns (VerifyHostKeyReply) {} +} + +message StartLogRequest { + string uniq_id = 1; + string level = 2; + +} + +message Log { + string message = 1; +} + +message ListCallbackRequest { +} + +message ListCallbackResponse { + repeated string callbacks = 1; +} + +message NewConnectionRequest { + ConnMeta meta = 1; +} + +message NewConnectionResponse { +} + +message NextAuthMethodsRequest { + ConnMeta meta = 1; +} + +enum AuthMethod { + NONE = 0; + PASSWORD = 1; + PUBLICKEY = 2; + KEYBOARD_INTERACTIVE = 3; +} + +message NextAuthMethodsResponse { + repeated AuthMethod methods = 1; +} + +message NoneAuthRequest { + ConnMeta meta = 1; +} + +message NoneAuthResponse { + Upstream upstream = 1; +} + +message PasswordAuthRequest { + ConnMeta meta = 1; + bytes password = 2; +} + +message PasswordAuthResponse { + Upstream upstream = 1; +} + +message PublicKeyAuthRequest { + ConnMeta meta = 1; + bytes public_key = 2; +} + +message PublicKeyAuthResponse { + Upstream upstream = 1; +} + +message KeyboardInteractiveUserResponse { + repeated string answers = 1; +} + +message KeyboardInteractivePromptRequest { + message Question{ + string text = 1; + bool echo = 2; + } + + string name = 1; + string instruction = 2; + repeated Question questions = 3; +} + +message KeyboardInteractiveMetaRequest { +} + +message KeyboardInteractiveMetaResponse { + ConnMeta meta = 1; +} + +message KeyboardInteractiveFinishRequest { + Upstream upstream = 1; +} + +message KeyboardInteractiveAuthMessage { + oneof message { + KeyboardInteractivePromptRequest prompt_request = 1; + KeyboardInteractiveUserResponse user_response = 2; + KeyboardInteractiveMetaRequest meta_request = 3; + KeyboardInteractiveMetaResponse meta_response = 4; + KeyboardInteractiveFinishRequest finish_request = 5; + } +} + +message UpstreamAuthFailureNoticeRequest { + ConnMeta meta = 1; + string method = 2; + string error = 3; + repeated AuthMethod allowed_methods = 4; +} + +message UpstreamAuthFailureNoticeResponse { +} + +message BannerRequest { + ConnMeta meta = 1; +} + +message BannerResponse { + string message = 1; +} + +message VerifyHostKeyRequest { + ConnMeta meta = 1; + bytes key = 2; +} + +message VerifyHostKeyReply { + bool verified = 1; +} \ No newline at end of file diff --git a/libplugin/plugin_grpc.pb.go b/libplugin/plugin_grpc.pb.go new file mode 100644 index 00000000..be3d860b --- /dev/null +++ b/libplugin/plugin_grpc.pb.go @@ -0,0 +1,521 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package libplugin + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// SshPiperPluginClient is the client API for SshPiperPlugin service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type SshPiperPluginClient interface { + Logs(ctx context.Context, in *StartLogRequest, opts ...grpc.CallOption) (SshPiperPlugin_LogsClient, error) + ListCallbacks(ctx context.Context, in *ListCallbackRequest, opts ...grpc.CallOption) (*ListCallbackResponse, error) + NewConnection(ctx context.Context, in *NewConnectionRequest, opts ...grpc.CallOption) (*NewConnectionResponse, error) + NextAuthMethods(ctx context.Context, in *NextAuthMethodsRequest, opts ...grpc.CallOption) (*NextAuthMethodsResponse, error) + NoneAuth(ctx context.Context, in *NoneAuthRequest, opts ...grpc.CallOption) (*NoneAuthResponse, error) + PasswordAuth(ctx context.Context, in *PasswordAuthRequest, opts ...grpc.CallOption) (*PasswordAuthResponse, error) + PublicKeyAuth(ctx context.Context, in *PublicKeyAuthRequest, opts ...grpc.CallOption) (*PublicKeyAuthResponse, error) + KeyboardInteractiveAuth(ctx context.Context, opts ...grpc.CallOption) (SshPiperPlugin_KeyboardInteractiveAuthClient, error) + UpstreamAuthFailureNotice(ctx context.Context, in *UpstreamAuthFailureNoticeRequest, opts ...grpc.CallOption) (*UpstreamAuthFailureNoticeResponse, error) + Banner(ctx context.Context, in *BannerRequest, opts ...grpc.CallOption) (*BannerResponse, error) + VerifyHostKey(ctx context.Context, in *VerifyHostKeyRequest, opts ...grpc.CallOption) (*VerifyHostKeyReply, error) +} + +type sshPiperPluginClient struct { + cc grpc.ClientConnInterface +} + +func NewSshPiperPluginClient(cc grpc.ClientConnInterface) SshPiperPluginClient { + return &sshPiperPluginClient{cc} +} + +func (c *sshPiperPluginClient) Logs(ctx context.Context, in *StartLogRequest, opts ...grpc.CallOption) (SshPiperPlugin_LogsClient, error) { + stream, err := c.cc.NewStream(ctx, &SshPiperPlugin_ServiceDesc.Streams[0], "/libplugin.SshPiperPlugin/Logs", opts...) + if err != nil { + return nil, err + } + x := &sshPiperPluginLogsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type SshPiperPlugin_LogsClient interface { + Recv() (*Log, error) + grpc.ClientStream +} + +type sshPiperPluginLogsClient struct { + grpc.ClientStream +} + +func (x *sshPiperPluginLogsClient) Recv() (*Log, error) { + m := new(Log) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *sshPiperPluginClient) ListCallbacks(ctx context.Context, in *ListCallbackRequest, opts ...grpc.CallOption) (*ListCallbackResponse, error) { + out := new(ListCallbackResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/ListCallbacks", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) NewConnection(ctx context.Context, in *NewConnectionRequest, opts ...grpc.CallOption) (*NewConnectionResponse, error) { + out := new(NewConnectionResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/NewConnection", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) NextAuthMethods(ctx context.Context, in *NextAuthMethodsRequest, opts ...grpc.CallOption) (*NextAuthMethodsResponse, error) { + out := new(NextAuthMethodsResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/NextAuthMethods", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) NoneAuth(ctx context.Context, in *NoneAuthRequest, opts ...grpc.CallOption) (*NoneAuthResponse, error) { + out := new(NoneAuthResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/NoneAuth", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) PasswordAuth(ctx context.Context, in *PasswordAuthRequest, opts ...grpc.CallOption) (*PasswordAuthResponse, error) { + out := new(PasswordAuthResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/PasswordAuth", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) PublicKeyAuth(ctx context.Context, in *PublicKeyAuthRequest, opts ...grpc.CallOption) (*PublicKeyAuthResponse, error) { + out := new(PublicKeyAuthResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/PublicKeyAuth", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) KeyboardInteractiveAuth(ctx context.Context, opts ...grpc.CallOption) (SshPiperPlugin_KeyboardInteractiveAuthClient, error) { + stream, err := c.cc.NewStream(ctx, &SshPiperPlugin_ServiceDesc.Streams[1], "/libplugin.SshPiperPlugin/KeyboardInteractiveAuth", opts...) + if err != nil { + return nil, err + } + x := &sshPiperPluginKeyboardInteractiveAuthClient{stream} + return x, nil +} + +type SshPiperPlugin_KeyboardInteractiveAuthClient interface { + Send(*KeyboardInteractiveAuthMessage) error + Recv() (*KeyboardInteractiveAuthMessage, error) + grpc.ClientStream +} + +type sshPiperPluginKeyboardInteractiveAuthClient struct { + grpc.ClientStream +} + +func (x *sshPiperPluginKeyboardInteractiveAuthClient) Send(m *KeyboardInteractiveAuthMessage) error { + return x.ClientStream.SendMsg(m) +} + +func (x *sshPiperPluginKeyboardInteractiveAuthClient) Recv() (*KeyboardInteractiveAuthMessage, error) { + m := new(KeyboardInteractiveAuthMessage) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *sshPiperPluginClient) UpstreamAuthFailureNotice(ctx context.Context, in *UpstreamAuthFailureNoticeRequest, opts ...grpc.CallOption) (*UpstreamAuthFailureNoticeResponse, error) { + out := new(UpstreamAuthFailureNoticeResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/UpstreamAuthFailureNotice", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) Banner(ctx context.Context, in *BannerRequest, opts ...grpc.CallOption) (*BannerResponse, error) { + out := new(BannerResponse) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/Banner", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sshPiperPluginClient) VerifyHostKey(ctx context.Context, in *VerifyHostKeyRequest, opts ...grpc.CallOption) (*VerifyHostKeyReply, error) { + out := new(VerifyHostKeyReply) + err := c.cc.Invoke(ctx, "/libplugin.SshPiperPlugin/VerifyHostKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SshPiperPluginServer is the server API for SshPiperPlugin service. +// All implementations must embed UnimplementedSshPiperPluginServer +// for forward compatibility +type SshPiperPluginServer interface { + Logs(*StartLogRequest, SshPiperPlugin_LogsServer) error + ListCallbacks(context.Context, *ListCallbackRequest) (*ListCallbackResponse, error) + NewConnection(context.Context, *NewConnectionRequest) (*NewConnectionResponse, error) + NextAuthMethods(context.Context, *NextAuthMethodsRequest) (*NextAuthMethodsResponse, error) + NoneAuth(context.Context, *NoneAuthRequest) (*NoneAuthResponse, error) + PasswordAuth(context.Context, *PasswordAuthRequest) (*PasswordAuthResponse, error) + PublicKeyAuth(context.Context, *PublicKeyAuthRequest) (*PublicKeyAuthResponse, error) + KeyboardInteractiveAuth(SshPiperPlugin_KeyboardInteractiveAuthServer) error + UpstreamAuthFailureNotice(context.Context, *UpstreamAuthFailureNoticeRequest) (*UpstreamAuthFailureNoticeResponse, error) + Banner(context.Context, *BannerRequest) (*BannerResponse, error) + VerifyHostKey(context.Context, *VerifyHostKeyRequest) (*VerifyHostKeyReply, error) + mustEmbedUnimplementedSshPiperPluginServer() +} + +// UnimplementedSshPiperPluginServer must be embedded to have forward compatible implementations. +type UnimplementedSshPiperPluginServer struct { +} + +func (UnimplementedSshPiperPluginServer) Logs(*StartLogRequest, SshPiperPlugin_LogsServer) error { + return status.Errorf(codes.Unimplemented, "method Logs not implemented") +} +func (UnimplementedSshPiperPluginServer) ListCallbacks(context.Context, *ListCallbackRequest) (*ListCallbackResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListCallbacks not implemented") +} +func (UnimplementedSshPiperPluginServer) NewConnection(context.Context, *NewConnectionRequest) (*NewConnectionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method NewConnection not implemented") +} +func (UnimplementedSshPiperPluginServer) NextAuthMethods(context.Context, *NextAuthMethodsRequest) (*NextAuthMethodsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method NextAuthMethods not implemented") +} +func (UnimplementedSshPiperPluginServer) NoneAuth(context.Context, *NoneAuthRequest) (*NoneAuthResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method NoneAuth not implemented") +} +func (UnimplementedSshPiperPluginServer) PasswordAuth(context.Context, *PasswordAuthRequest) (*PasswordAuthResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PasswordAuth not implemented") +} +func (UnimplementedSshPiperPluginServer) PublicKeyAuth(context.Context, *PublicKeyAuthRequest) (*PublicKeyAuthResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PublicKeyAuth not implemented") +} +func (UnimplementedSshPiperPluginServer) KeyboardInteractiveAuth(SshPiperPlugin_KeyboardInteractiveAuthServer) error { + return status.Errorf(codes.Unimplemented, "method KeyboardInteractiveAuth not implemented") +} +func (UnimplementedSshPiperPluginServer) UpstreamAuthFailureNotice(context.Context, *UpstreamAuthFailureNoticeRequest) (*UpstreamAuthFailureNoticeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpstreamAuthFailureNotice not implemented") +} +func (UnimplementedSshPiperPluginServer) Banner(context.Context, *BannerRequest) (*BannerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Banner not implemented") +} +func (UnimplementedSshPiperPluginServer) VerifyHostKey(context.Context, *VerifyHostKeyRequest) (*VerifyHostKeyReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method VerifyHostKey not implemented") +} +func (UnimplementedSshPiperPluginServer) mustEmbedUnimplementedSshPiperPluginServer() {} + +// UnsafeSshPiperPluginServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SshPiperPluginServer will +// result in compilation errors. +type UnsafeSshPiperPluginServer interface { + mustEmbedUnimplementedSshPiperPluginServer() +} + +func RegisterSshPiperPluginServer(s grpc.ServiceRegistrar, srv SshPiperPluginServer) { + s.RegisterService(&SshPiperPlugin_ServiceDesc, srv) +} + +func _SshPiperPlugin_Logs_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StartLogRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(SshPiperPluginServer).Logs(m, &sshPiperPluginLogsServer{stream}) +} + +type SshPiperPlugin_LogsServer interface { + Send(*Log) error + grpc.ServerStream +} + +type sshPiperPluginLogsServer struct { + grpc.ServerStream +} + +func (x *sshPiperPluginLogsServer) Send(m *Log) error { + return x.ServerStream.SendMsg(m) +} + +func _SshPiperPlugin_ListCallbacks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListCallbackRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).ListCallbacks(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/ListCallbacks", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).ListCallbacks(ctx, req.(*ListCallbackRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_NewConnection_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(NewConnectionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).NewConnection(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/NewConnection", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).NewConnection(ctx, req.(*NewConnectionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_NextAuthMethods_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(NextAuthMethodsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).NextAuthMethods(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/NextAuthMethods", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).NextAuthMethods(ctx, req.(*NextAuthMethodsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_NoneAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(NoneAuthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).NoneAuth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/NoneAuth", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).NoneAuth(ctx, req.(*NoneAuthRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_PasswordAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PasswordAuthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).PasswordAuth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/PasswordAuth", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).PasswordAuth(ctx, req.(*PasswordAuthRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_PublicKeyAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PublicKeyAuthRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).PublicKeyAuth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/PublicKeyAuth", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).PublicKeyAuth(ctx, req.(*PublicKeyAuthRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_KeyboardInteractiveAuth_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(SshPiperPluginServer).KeyboardInteractiveAuth(&sshPiperPluginKeyboardInteractiveAuthServer{stream}) +} + +type SshPiperPlugin_KeyboardInteractiveAuthServer interface { + Send(*KeyboardInteractiveAuthMessage) error + Recv() (*KeyboardInteractiveAuthMessage, error) + grpc.ServerStream +} + +type sshPiperPluginKeyboardInteractiveAuthServer struct { + grpc.ServerStream +} + +func (x *sshPiperPluginKeyboardInteractiveAuthServer) Send(m *KeyboardInteractiveAuthMessage) error { + return x.ServerStream.SendMsg(m) +} + +func (x *sshPiperPluginKeyboardInteractiveAuthServer) Recv() (*KeyboardInteractiveAuthMessage, error) { + m := new(KeyboardInteractiveAuthMessage) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _SshPiperPlugin_UpstreamAuthFailureNotice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpstreamAuthFailureNoticeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).UpstreamAuthFailureNotice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/UpstreamAuthFailureNotice", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).UpstreamAuthFailureNotice(ctx, req.(*UpstreamAuthFailureNoticeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_Banner_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BannerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).Banner(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/Banner", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).Banner(ctx, req.(*BannerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SshPiperPlugin_VerifyHostKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyHostKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SshPiperPluginServer).VerifyHostKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/libplugin.SshPiperPlugin/VerifyHostKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SshPiperPluginServer).VerifyHostKey(ctx, req.(*VerifyHostKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// SshPiperPlugin_ServiceDesc is the grpc.ServiceDesc for SshPiperPlugin service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SshPiperPlugin_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "libplugin.SshPiperPlugin", + HandlerType: (*SshPiperPluginServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListCallbacks", + Handler: _SshPiperPlugin_ListCallbacks_Handler, + }, + { + MethodName: "NewConnection", + Handler: _SshPiperPlugin_NewConnection_Handler, + }, + { + MethodName: "NextAuthMethods", + Handler: _SshPiperPlugin_NextAuthMethods_Handler, + }, + { + MethodName: "NoneAuth", + Handler: _SshPiperPlugin_NoneAuth_Handler, + }, + { + MethodName: "PasswordAuth", + Handler: _SshPiperPlugin_PasswordAuth_Handler, + }, + { + MethodName: "PublicKeyAuth", + Handler: _SshPiperPlugin_PublicKeyAuth_Handler, + }, + { + MethodName: "UpstreamAuthFailureNotice", + Handler: _SshPiperPlugin_UpstreamAuthFailureNotice_Handler, + }, + { + MethodName: "Banner", + Handler: _SshPiperPlugin_Banner_Handler, + }, + { + MethodName: "VerifyHostKey", + Handler: _SshPiperPlugin_VerifyHostKey_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Logs", + Handler: _SshPiperPlugin_Logs_Handler, + ServerStreams: true, + }, + { + StreamName: "KeyboardInteractiveAuth", + Handler: _SshPiperPlugin_KeyboardInteractiveAuth_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "plugin.proto", +} diff --git a/libplugin/pluginbase.go b/libplugin/pluginbase.go new file mode 100644 index 00000000..06ac14b9 --- /dev/null +++ b/libplugin/pluginbase.go @@ -0,0 +1,374 @@ +package libplugin + +import ( + "bufio" + context "context" + "fmt" + "io" + "net" + "os" + + "github.com/tg123/sshpiper/libplugin/ioconn" + "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +type ConnMetadata interface { + User() string + + RemoteAddr() string + + UniqueID() string +} + +func (c *ConnMeta) User() string { + return c.UserName +} + +func (c *ConnMeta) RemoteAddr() string { + return c.FromAddr +} + +func (c *ConnMeta) UniqueID() string { + return c.UniqId +} + +type KeyboardInteractiveChallenge func(instruction string, question string, echo bool) (answer string, err error) + +type SshPiperPluginConfig struct { + NewConnectionCallback func(conn ConnMetadata) error + + NextAuthMethodsCallback func(conn ConnMetadata) ([]string, error) + + NoneAuthCallback func(conn ConnMetadata) (*Upstream, error) + + PasswordCallback func(conn ConnMetadata, password []byte) (*Upstream, error) + + PublicKeyCallback func(conn ConnMetadata, key []byte) (*Upstream, error) + + KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Upstream, error) + + UpstreamAuthFailureCallback func(conn ConnMetadata, method string, err error) + + BannerCallback func(conn ConnMetadata) string + + VerifyHostKeyCallback func(conn ConnMetadata, key []byte) (bool, error) +} + +type SshPiperPlugin interface { + GetLoggerOutput() io.Writer + GetGrpcServer() *grpc.Server + Serve() error +} + +func NewFromStdio(config SshPiperPluginConfig) (SshPiperPlugin, error) { + s := grpc.NewServer() + l, err := ioconn.ListenFromSingleIO(os.Stdin, os.Stdout) + if err != nil { + return nil, err + } + + return NewFromGrpc(config, s, l) +} + +func NewFromGrpc(config SshPiperPluginConfig, grpc *grpc.Server, listener net.Listener) (SshPiperPlugin, error) { + r, w := io.Pipe() + + s := &server{ + config: config, + grpc: grpc, + listener: listener, + logwriter: w, + logs: make(chan string, 1000), + } + + go func() { + scanner := bufio.NewScanner(r) + + for scanner.Scan() { + s.logs <- scanner.Text() + } + }() + + RegisterSshPiperPluginServer(s.grpc, s) + + return s, nil +} + +type server struct { + UnimplementedSshPiperPluginServer + + config SshPiperPluginConfig + grpc *grpc.Server + listener net.Listener + + logs chan string + logwriter io.Writer +} + +func (s *server) GetGrpcServer() *grpc.Server { + return s.grpc +} + +func (s *server) GetLoggerOutput() io.Writer { + return s.logwriter +} + +func (s *server) Serve() error { + return s.grpc.Serve(s.listener) +} + +func (s *server) Logs(req *StartLogRequest, stream SshPiperPlugin_LogsServer) error { + for log := range s.logs { + if err := stream.Send(&Log{ + Message: log, + }); err != nil { + return err + } + } + + return nil +} + +func (s *server) ListCallbacks(ctx context.Context, req *ListCallbackRequest) (*ListCallbackResponse, error) { + + var cb []string + + if s.config.NewConnectionCallback != nil { + cb = append(cb, "NewConnection") + } + + if s.config.NextAuthMethodsCallback != nil { + cb = append(cb, "NextAuthMethods") + } + + if s.config.NoneAuthCallback != nil { + cb = append(cb, "NoneAuth") + } + + if s.config.PasswordCallback != nil { + cb = append(cb, "PasswordAuth") + } + + if s.config.PublicKeyCallback != nil { + cb = append(cb, "PublicKeyAuth") + } + + if s.config.KeyboardInteractiveCallback != nil { + cb = append(cb, "KeyboardInteractiveAuth") + } + + if s.config.UpstreamAuthFailureCallback != nil { + cb = append(cb, "UpstreamAuthFailure") + } + + if s.config.BannerCallback != nil { + cb = append(cb, "Banner") + } + + if s.config.VerifyHostKeyCallback != nil { + cb = append(cb, "VerifyHostKey") + } + + return &ListCallbackResponse{ + Callbacks: cb, + }, nil +} + +func (s *server) NewConnection(ctx context.Context, req *NewConnectionRequest) (*NewConnectionResponse, error) { + if s.config.NewConnectionCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method NewConnection not implemented") + } + + if err := s.config.NewConnectionCallback(req.Meta); err != nil { + return nil, err + } + + return &NewConnectionResponse{}, nil +} + +func (s *server) NextAuthMethods(ctx context.Context, req *NextAuthMethodsRequest) (*NextAuthMethodsResponse, error) { + if s.config.NextAuthMethodsCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method NextAuthMethods not implemented") + } + + methods, err := s.config.NextAuthMethodsCallback(req.Meta) + if err != nil { + return nil, err + } + + resp := &NextAuthMethodsResponse{} + + for _, method := range methods { + m := AuthMethodFromName(method) + if m == -1 { + return nil, status.Errorf(codes.InvalidArgument, "unknown method %s", method) + } + resp.Methods = append(resp.Methods, m) + } + + return resp, nil +} + +func (s *server) NoneAuth(ctx context.Context, req *NoneAuthRequest) (*NoneAuthResponse, error) { + if s.config.NoneAuthCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method NoneAuth not implemented") + } + + upstream, err := s.config.NoneAuthCallback(req.Meta) + if err != nil { + return nil, err + } + + return &NoneAuthResponse{ + Upstream: upstream, + }, nil +} + +func (s *server) PasswordAuth(ctx context.Context, req *PasswordAuthRequest) (*PasswordAuthResponse, error) { + if s.config.PasswordCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method PasswordAuth not implemented") + } + + upstream, err := s.config.PasswordCallback(req.Meta, req.Password) + if err != nil { + return nil, err + } + + return &PasswordAuthResponse{ + Upstream: upstream, + }, nil +} + +func (s *server) PublicKeyAuth(ctx context.Context, req *PublicKeyAuthRequest) (*PublicKeyAuthResponse, error) { + if s.config.PublicKeyCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method PublicKeyAuth not implemented") + } + + upstream, err := s.config.PublicKeyCallback(req.Meta, req.PublicKey) + if err != nil { + return nil, err + } + + return &PublicKeyAuthResponse{ + Upstream: upstream, + }, nil +} + +func (s *server) KeyboardInteractiveAuth(stream SshPiperPlugin_KeyboardInteractiveAuthServer) error { + if s.config.KeyboardInteractiveCallback == nil { + return status.Errorf(codes.Unimplemented, "method KeyboardInteractiveAuth not implemented") + } + + if err := stream.Send(&KeyboardInteractiveAuthMessage{ + Message: &KeyboardInteractiveAuthMessage_MetaRequest{}, + }); err != nil { + return err + } + + metareply, err := stream.Recv() + if err != nil { + return err + } + + meta := metareply.GetMetaResponse() + if meta == nil { + return status.Errorf(codes.InvalidArgument, "missing meta") + } + + upstream, err := s.config.KeyboardInteractiveCallback(meta.Meta, func(instruction string, question string, echo bool) (answer string, err error) { + var questions []*KeyboardInteractivePromptRequest_Question + if question != "" { + questions = append(questions, &KeyboardInteractivePromptRequest_Question{ + Text: question, + Echo: echo, + }) + } + + if err := stream.Send(&KeyboardInteractiveAuthMessage{ + Message: &KeyboardInteractiveAuthMessage_PromptRequest{ + PromptRequest: &KeyboardInteractivePromptRequest{ + Name: "", // temporary unused + Instruction: instruction, + Questions: questions, + }, + }, + }); err != nil { + return "", err + } + + if question == "" { + return "", nil + } + + userInputReply, err := stream.Recv() + if err != nil { + return "", err + } + + userInput := userInputReply.GetUserResponse() + if userInput == nil { + return "", status.Errorf(codes.InvalidArgument, "missing user input") + } + + if len(userInput.Answers) != 1 { + return "", status.Errorf(codes.InvalidArgument, "expected 1 answer, got %d", len(userInput.Answers)) + } + + return userInput.Answers[0], nil + }) + + if err != nil { + return err + } + + if err := stream.Send(&KeyboardInteractiveAuthMessage{ + Message: &KeyboardInteractiveAuthMessage_FinishRequest{ + FinishRequest: &KeyboardInteractiveFinishRequest{ + Upstream: upstream, + }, + }, + }); err != nil { + return err + } + + return nil +} + +func (s *server) UpstreamAuthFailureNotice(ctx context.Context, req *UpstreamAuthFailureNoticeRequest) (*UpstreamAuthFailureNoticeResponse, error) { + if s.config.UpstreamAuthFailureCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method UpstreamAuthFailureNotice not implemented") + } + + s.config.UpstreamAuthFailureCallback(req.Meta, req.Method, fmt.Errorf(req.Error)) + + return &UpstreamAuthFailureNoticeResponse{}, nil +} + +func (s *server) Banner(ctx context.Context, req *BannerRequest) (*BannerResponse, error) { + if s.config.BannerCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method Banner not implemented") + } + + msg := s.config.BannerCallback(req.Meta) + + return &BannerResponse{ + Message: msg, + }, nil +} + +func (s *server) VerifyHostKey(ctx context.Context, req *VerifyHostKeyRequest) (*VerifyHostKeyReply, error) { + if s.config.VerifyHostKeyCallback == nil { + return nil, status.Errorf(codes.Unimplemented, "method VerifyHostKey not implemented") + } + + verifed, err := s.config.VerifyHostKeyCallback(req.Meta, req.Key) + if err != nil { + return nil, err + } + + return &VerifyHostKeyReply{ + Verified: verifed, + }, nil +} diff --git a/libplugin/util.go b/libplugin/util.go new file mode 100644 index 00000000..275f737b --- /dev/null +++ b/libplugin/util.go @@ -0,0 +1,138 @@ +package libplugin + +import ( + "fmt" + "io" + "net" + "os" + "strconv" + + "github.com/sirupsen/logrus" +) + +func WriterToFile(writer io.Writer) (*os.File, error) { + r, w, err := os.Pipe() + if err != nil { + return nil, err + } + + go io.Copy(writer, r) + + return w, nil +} + +func AuthMethodTypeToName(a AuthMethod) string { + switch a { + case AuthMethod_NONE: + return "none" + case AuthMethod_PASSWORD: + return "password" + case AuthMethod_PUBLICKEY: + return "publickey" + case AuthMethod_KEYBOARD_INTERACTIVE: + return "keyboard-interactive" + } + return "" +} + +func AuthMethodFromName(n string) AuthMethod { + switch n { + case "none": + return AuthMethod_NONE + case "password": + return AuthMethod_PASSWORD + case "publickey": + return AuthMethod_PUBLICKEY + case "keyboard-interactive": + return AuthMethod_KEYBOARD_INTERACTIVE + } + return -1 +} + +func ConfigStdioLogrus(p SshPiperPlugin, logger *logrus.Logger) { + if logger == nil { + logger = logrus.StandardLogger() + } + logger.SetOutput(p.GetLoggerOutput()) + logger.SetFormatter(&logrus.TextFormatter{ForceColors: true}) +} + +// SplitHostPortForSSH is the modified version of net.SplitHostPort but return port 22 is no port is specified +func SplitHostPortForSSH(addr string) (host string, port int, err error) { + host = addr + h, p, err := net.SplitHostPort(host) + if err == nil { + host = h + port, err = strconv.Atoi(p) + + if err != nil { + return + } + } else if host != "" { + // test valid after concat :22 + if _, _, err = net.SplitHostPort(host + ":22"); err == nil { + port = 22 + } + } + + if host == "" { + err = fmt.Errorf("empty addr") + } + + return +} + +// DialForSSH is the modified version of net.Dial, would add ":22" automaticlly +func DialForSSH(addr string) (net.Conn, error) { + + if _, _, err := net.SplitHostPort(addr); err != nil && addr != "" { + // test valid after concat :22 + if _, _, err := net.SplitHostPort(addr + ":22"); err == nil { + addr += ":22" + } + } + + return net.Dial("tcp", addr) +} + +func CreateNoneAuth(password []byte) *Upstream_None { + return &Upstream_None{ + None: &UpstreamNoneAuth{}, + } +} + +func CreatePasswordAuth(password []byte) *Upstream_Password { + return CreatePasswordAuthFromString(string(password)) +} + +func CreatePasswordAuthFromString(password string) *Upstream_Password { + return &Upstream_Password{ + Password: &UpstreamPasswordAuth{ + Password: password, + }, + } +} + +func CreatePrivateKeyAuth(key []byte) *Upstream_PrivateKey { + return &Upstream_PrivateKey{ + PrivateKey: &UpstreamPrivateKeyAuth{ + PrivateKey: key, + }, + } +} + +func CreateRemoteSignerAuth(meta string) *Upstream_RemoteSigner { + return &Upstream_RemoteSigner{ + RemoteSigner: &UpstreamRemoteSignerAuth{ + Meta: meta, + }, + } +} + +func CreateNextPluginAuth(meta map[string]string) *Upstream_NextPlugin { + return &Upstream_NextPlugin{ + NextPlugin: &UpstreamNextPluginAuth{ + Meta: meta, + }, + } +} diff --git a/plugin/fixed/main.go b/plugin/fixed/main.go new file mode 100644 index 00000000..9e56622e --- /dev/null +++ b/plugin/fixed/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "os" + + log "github.com/sirupsen/logrus" + "github.com/tg123/sshpiper/libplugin" +) + +func main() { + if len(os.Args) < 2 { + log.Fatal("no target address provided") + } + + target := os.Args[1] + + host, port, err := libplugin.SplitHostPortForSSH(target) + if err != nil { + panic(err) + } + + config := libplugin.SshPiperPluginConfig{ + PasswordCallback: func(conn libplugin.ConnMetadata, password []byte) (*libplugin.Upstream, error) { + log.Info("routing to ", target) + return &libplugin.Upstream{ + Host: host, + Port: int32(port), + IgnoreHostKey: true, + Auth: libplugin.CreatePasswordAuth(password), + }, nil + + }, + } + + p, err := libplugin.NewFromStdio(config) + if err != nil { + panic(err) + } + + libplugin.ConfigStdioLogrus(p, nil) + + log.Printf("starting fix routing to ssh %v (password only)", target) + panic(p.Serve()) +} diff --git a/plugin/simplemath/main.go b/plugin/simplemath/main.go new file mode 100644 index 00000000..3e3f777c --- /dev/null +++ b/plugin/simplemath/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "math/rand" + "strconv" + + log "github.com/sirupsen/logrus" + "github.com/tg123/sshpiper/libplugin" +) + +func main() { + config := libplugin.SshPiperPluginConfig{ + KeyboardInteractiveCallback: func(conn libplugin.ConnMetadata, client libplugin.KeyboardInteractiveChallenge) (*libplugin.Upstream, error) { + client("lets do math", "", false) + + for { + + a := rand.Intn(10) + b := rand.Intn(10) + + ans, err := client("", fmt.Sprintf("what is %v + %v = ", a, b), true) + if err != nil { + return nil, err + } + + log.Printf("got ans = %v", ans) + + if ans == fmt.Sprintf("%v", a+b) { + return &libplugin.Upstream{ + Auth: libplugin.CreateNextPluginAuth(map[string]string{ + "a": strconv.Itoa(a), + "b": strconv.Itoa(b), + "ans": ans, + }), + }, nil + } + } + }, + } + + p, err := libplugin.NewFromStdio(config) + if err != nil { + panic(err) + } + + libplugin.ConfigStdioLogrus(p, nil) + + log.Printf("starting simple math additional auth") + panic(p.Serve()) +}