Skip to content

Commit

Permalink
add remote signer api and e2e test of it (#320)
Browse files Browse the repository at this point in the history
  • Loading branch information
tg123 authored Feb 11, 2024
1 parent d8b345e commit 82ac6a5
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 4 deletions.
33 changes: 30 additions & 3 deletions e2e/plugin_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package e2e_test

import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"net"
"net/http"
Expand Down Expand Up @@ -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
},
})
Expand Down Expand Up @@ -152,6 +177,8 @@ func TestPlugin(t *testing.T) {
sshsvr.Addr().String(),
"--rpcserver",
rpcsvr.Addr().String(),
"--testremotekey",
base64.StdEncoding.EncodeToString(privKeyPem),
)

if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions libplugin/pluginbase.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -60,6 +61,8 @@ type SshPiperPluginConfig struct {
PipeStartCallback func(conn ConnMetadata)

PipeErrorCallback func(conn ConnMetadata, err error)

GrpcRemoteSignerFactory grpcsigner.SignerFactory
}

type SshPiperPlugin interface {
Expand Down Expand Up @@ -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
}

Expand Down
32 changes: 31 additions & 1 deletion plugin/testplugin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -23,6 +27,10 @@ func main() {
Name: "testsshserver",
Required: true,
},
&cli.StringFlag{
Name: "testremotekey",
Required: true,
},
},
CreateConfig: func(c *cli.Context) (*libplugin.SshPiperPluginConfig, error) {

Expand All @@ -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)
Expand All @@ -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
},
})
Expand Down

0 comments on commit 82ac6a5

Please sign in to comment.