add remote signer api and e2e test of it (#320)
This commit is contained in:
parent
d8b345eeb7
commit
82ac6a5fff
3 changed files with 72 additions and 4 deletions
|
|
@ -1,6 +1,12 @@
|
|||
package e2e_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
|
@ -110,11 +116,30 @@ func createRpcServer(r *rpcServer) net.Listener {
|
|||
|
||||
func TestPlugin(t *testing.T) {
|
||||
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to generate private key: %v", err)
|
||||
}
|
||||
|
||||
privKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
privKeyPem := pem.EncodeToMemory(
|
||||
&pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: privKeyBytes,
|
||||
},
|
||||
)
|
||||
|
||||
sshkey, err := ssh.NewSignerFromKey(privateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create ssh signer: %v", err)
|
||||
}
|
||||
|
||||
sshsvr := createFakeSshServer(&ssh.ServerConfig{
|
||||
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
|
||||
if string(pass) != "rpcpassword" {
|
||||
return nil, fmt.Errorf("invalid password")
|
||||
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
|
||||
if !bytes.Equal(key.Marshal(), sshkey.PublicKey().Marshal()) {
|
||||
return nil, fmt.Errorf("public key mismatch")
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
},
|
||||
})
|
||||
|
|
@ -152,6 +177,8 @@ func TestPlugin(t *testing.T) {
|
|||
sshsvr.Addr().String(),
|
||||
"--rpcserver",
|
||||
rpcsvr.Addr().String(),
|
||||
"--testremotekey",
|
||||
base64.StdEncoding.EncodeToString(privKeyPem),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/tg123/remotesigner/grpcsigner"
|
||||
"github.com/tg123/sshpiper/libplugin/ioconn"
|
||||
"google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
|
|
@ -60,6 +61,8 @@ type SshPiperPluginConfig struct {
|
|||
PipeStartCallback func(conn ConnMetadata)
|
||||
|
||||
PipeErrorCallback func(conn ConnMetadata, err error)
|
||||
|
||||
GrpcRemoteSignerFactory grpcsigner.SignerFactory
|
||||
}
|
||||
|
||||
type SshPiperPlugin interface {
|
||||
|
|
@ -99,6 +102,14 @@ func NewFromGrpc(config SshPiperPluginConfig, grpc *grpc.Server, listener net.Li
|
|||
|
||||
RegisterSshPiperPluginServer(s.grpc, s)
|
||||
|
||||
if config.GrpcRemoteSignerFactory != nil {
|
||||
gs, err := grpcsigner.NewSignerServer(config.GrpcRemoteSignerFactory)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grpcsigner.RegisterSignerServer(s.grpc, gs)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,14 @@
|
|||
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() {
|
||||
|
|
@ -23,6 +27,10 @@ func main() {
|
|||
Name: "testsshserver",
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "testremotekey",
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
CreateConfig: func(c *cli.Context) (*libplugin.SshPiperPluginConfig, error) {
|
||||
|
||||
|
|
@ -36,6 +44,21 @@ func main() {
|
|||
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)
|
||||
|
|
@ -56,10 +79,17 @@ func main() {
|
|||
return &libplugin.Upstream{
|
||||
Host: host,
|
||||
Port: int32(port),
|
||||
Auth: libplugin.CreatePasswordAuthFromString(newpass),
|
||||
Auth: libplugin.CreateRemoteSignerAuth("testplugin"),
|
||||
IgnoreHostKey: true,
|
||||
}, nil
|
||||
},
|
||||
GrpcRemoteSignerFactory: func(metadata string) crypto.Signer {
|
||||
if metadata != "testplugin" {
|
||||
panic("metadata mismatch")
|
||||
}
|
||||
|
||||
return key.(crypto.Signer)
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue