The ssh install and ssh to commands (closes #2)
All checks were successful
check / check (push) Successful in 2m30s
All checks were successful
check / check (push) Successful in 2m30s
keyfunc ssh install appends the public line on a host through the system ssh, only when absent, feeding the line on standard input; keyfunc ssh to serves the derived key from an in-process agent on a private socket and runs the system ssh with it, the private key never on disk. Two review rounds; the second passed with no findings. Model: opus-5 (implementation and review); fable-5-1 (landing)
This commit was merged in pull request #8.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package sshkey_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -8,8 +11,16 @@ import (
|
||||
"git.eeqj.de/sneak/keyfunc/internal/sshkey"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/agent"
|
||||
)
|
||||
|
||||
// agentDirectoryMode is what the directory holding the agent socket
|
||||
// has to be: nobody but its owner may enter it.
|
||||
const agentDirectoryMode = 0o700
|
||||
|
||||
// exampleIndex is the key index every test here derives at.
|
||||
const exampleIndex = 0
|
||||
|
||||
// example returns the mnemonic every BIP-39 document uses to show its
|
||||
// test vectors: eleven abandons and about.
|
||||
func example() string {
|
||||
@@ -26,7 +37,7 @@ func TestTooFewBytesAreRefused(t *testing.T) {
|
||||
func TestTheCommentIsPutAtTheEndOfTheLine(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
key := forIndex(t, 0)
|
||||
key := exampleKey(t)
|
||||
|
||||
line, err := key.Line("hello")
|
||||
require.NoError(t, err)
|
||||
@@ -37,7 +48,7 @@ func TestTheCommentIsPutAtTheEndOfTheLine(t *testing.T) {
|
||||
func TestThePrivateKeyCarriesTheSamePublicKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
key := forIndex(t, 0)
|
||||
key := exampleKey(t)
|
||||
|
||||
line, err := key.Line("")
|
||||
require.NoError(t, err)
|
||||
@@ -54,11 +65,60 @@ func TestThePrivateKeyCarriesTheSamePublicKey(t *testing.T) {
|
||||
require.Equal(t, line, back)
|
||||
}
|
||||
|
||||
// forIndex derives the key for one index.
|
||||
func forIndex(t *testing.T, index uint32) *sshkey.Key {
|
||||
func TestTheAgentServesTheOneKeyAndNothingElse(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
key := exampleKey(t)
|
||||
|
||||
served, err := key.Serve(t.Context(), "a comment")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(served.Stop)
|
||||
|
||||
directory, err := os.Stat(filepath.Dir(served.Socket()))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t,
|
||||
os.FileMode(agentDirectoryMode), directory.Mode().Perm(),
|
||||
)
|
||||
|
||||
var dialer net.Dialer
|
||||
|
||||
connection, err := dialer.DialContext(t.Context(), "unix", served.Socket())
|
||||
require.NoError(t, err)
|
||||
|
||||
defer func() { _ = connection.Close() }()
|
||||
|
||||
held, err := agent.NewClient(connection).List()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, held, 1)
|
||||
|
||||
line, err := key.Line("a comment")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, line, held[0].String())
|
||||
}
|
||||
|
||||
func TestStoppingTheAgentLeavesNothingBehind(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
served, err := exampleKey(t).Serve(t.Context(), "a comment")
|
||||
require.NoError(t, err)
|
||||
|
||||
directory := filepath.Dir(served.Socket())
|
||||
require.DirExists(t, directory)
|
||||
|
||||
served.Stop()
|
||||
require.NoDirExists(t, directory)
|
||||
|
||||
var dialer net.Dialer
|
||||
|
||||
_, err = dialer.DialContext(t.Context(), "unix", served.Socket())
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// exampleKey derives the key the example mnemonic gives.
|
||||
func exampleKey(t *testing.T) *sshkey.Key {
|
||||
t.Helper()
|
||||
|
||||
material, err := derive.Bytes(example(), sshkey.Application, index)
|
||||
material, err := derive.Bytes(example(), sshkey.Application, exampleIndex)
|
||||
require.NoError(t, err)
|
||||
|
||||
key, err := sshkey.New(material)
|
||||
|
||||
Reference in New Issue
Block a user