Refactor plugin.proto and pluginbase.go to add support for metadata in connection context (#475)

* Refactor plugin.proto and pluginbase.go to add support for metadata in connection context

* go fmt

* move test plugin out

* Refactor Dockerfile to build test plugin in e2e/testplugin directory

* mv testplugin -> testgrpcplugin

* add test for connection metadata

* enable logging to stdout

* Refactor Dockerfile to build test plugin in e2e/testplugin directory
This commit is contained in:
Boshi Lian 2024-10-27 23:57:21 -07:00 • committed by GitHub
parent c8ca0c4f97
commit 0e6168a6b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 549 additions and 375 deletions

View file

@ -1,61 +0,0 @@
//go:build full || e2e
package main
import (
"fmt"
"os"
"github.com/tg123/sshpiper/libplugin"
"github.com/urfave/cli/v2"
)
func main() {
libplugin.CreateAndRunPluginTemplate(&libplugin.PluginTemplate{
Name: "testcaplugin",
Usage: "Plugin to test ca public cert auth",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "target",
Usage: "target ssh endpoint address",
EnvVars: []string{"SSHPIPERD_FIXED_TARGET"},
Required: true,
},
},
CreateConfig: func(c *cli.Context) (*libplugin.SshPiperPluginConfig, error) {
target := c.String("target")
host, port, err := libplugin.SplitHostPortForSSH(target)
if err != nil {
return nil, err
}
return &libplugin.SshPiperPluginConfig{
PasswordCallback: func(conn libplugin.ConnMetadata, password []byte) (*libplugin.Upstream, error) {
if string(password) != "pass" {
return nil, fmt.Errorf("Password is incorrect")
}
// Load the private key
signer, err := os.ReadFile("/etc/ssh/ssh_user")
if err != nil {
return nil, fmt.Errorf("unable to read private key: %v", err)
}
// Load the public ca certificate
capublickey, err := os.ReadFile("/etc/ssh/ssh_user-cert.pub")
if err != nil {
return nil, fmt.Errorf("unable to read ca cert: %v", err)
}
return &libplugin.Upstream{
Host: host,
Port: int32(port),
IgnoreHostKey: true,
Auth: libplugin.CreatePrivateKeyAuth(signer, capublickey),
}, nil
},
}, nil
},
})
}

View file

@ -1,96 +0,0 @@
//go:build e2e
package main
import (
"crypto"
"encoding/base64"
"fmt"
"net/rpc"
"github.com/tg123/sshpiper/libplugin"
"github.com/urfave/cli/v2"
"golang.org/x/crypto/ssh"
)
func main() {
libplugin.CreateAndRunPluginTemplate(&libplugin.PluginTemplate{
Name: "testplugin",
Usage: "e2e test plugin only",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "rpcserver",
Required: true,
},
&cli.StringFlag{
Name: "testsshserver",
Required: true,
},
&cli.StringFlag{
Name: "testremotekey",
Required: true,
},
},
CreateConfig: func(c *cli.Context) (*libplugin.SshPiperPluginConfig, error) {
rpcclient, err := rpc.DialHTTP("tcp", c.String("rpcserver"))
if err != nil {
return nil, err
}
host, port, err := libplugin.SplitHostPortForSSH(c.String("testsshserver"))
if err != nil {
return nil, err
}
keydata, err := base64.StdEncoding.DecodeString(c.String("testremotekey"))
if err != nil {
return nil, err
}
key, err := ssh.ParseRawPrivateKey(keydata)
if err != nil {
return nil, err
}
_, ok := key.(crypto.Signer)
if !ok {
return nil, fmt.Errorf("key format not supported")
}
return &libplugin.SshPiperPluginConfig{
NewConnectionCallback: func(conn libplugin.ConnMetadata) error {
return rpcclient.Call("TestPlugin.NewConnection", "", nil)
},
PipeStartCallback: func(conn libplugin.ConnMetadata) {
rpcclient.Call("TestPlugin.PipeStart", "", nil)
},
PipeErrorCallback: func(conn libplugin.ConnMetadata, err error) {
rpcclient.Call("TestPlugin.PipeError", err.Error(), nil)
},
PasswordCallback: func(conn libplugin.ConnMetadata, password []byte) (*libplugin.Upstream, error) {
var newpass string
err := rpcclient.Call("TestPlugin.Password", string(password), &newpass)
if err != nil {
return nil, err
}
return &libplugin.Upstream{
Host: host,
Port: int32(port),
Auth: libplugin.CreateRemoteSignerAuth("testplugin"),
IgnoreHostKey: true,
}, nil
},
GrpcRemoteSignerFactory: func(metadata string) (crypto.Signer, error) {
if metadata != "testplugin" {
return nil, fmt.Errorf("metadata mismatch")
}
return key.(crypto.Signer), nil
},
}, nil
},
})
}