Move ssh-client's tests and dependencies onto the SDK's forgekey (issue 1480), part 3 of 17
This commit is contained in:
@@ -12,6 +12,8 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/forgekey"
|
||||
)
|
||||
|
||||
// Public keys made for these tests only; their private halves were never kept.
|
||||
@@ -29,7 +31,7 @@ type call struct {
|
||||
}
|
||||
|
||||
type fake struct {
|
||||
answer func(c call) Ran
|
||||
answer func(c call) forgekey.Ran
|
||||
mu sync.Mutex
|
||||
calls []call
|
||||
}
|
||||
@@ -41,13 +43,13 @@ func (f *fake) recorded() []call {
|
||||
return append([]call(nil), f.calls...)
|
||||
}
|
||||
|
||||
func (f *fake) run(_ context.Context, env []string, name string, args ...string) Ran {
|
||||
func (f *fake) run(_ context.Context, env []string, name string, args ...string) forgekey.Ran {
|
||||
c := call{env, name, args}
|
||||
f.mu.Lock()
|
||||
f.calls = append(f.calls, c)
|
||||
f.mu.Unlock()
|
||||
if f.answer == nil {
|
||||
return Ran{Status: 1}
|
||||
return forgekey.Ran{Status: 1}
|
||||
}
|
||||
return f.answer(c)
|
||||
}
|
||||
@@ -130,19 +132,19 @@ func TestKeysAreDescribedByTheirPublicHalfAndAPassphraseIsAskedNotRead(t *testin
|
||||
files := map[string]string{"config": layout["config"], "id_ed25519": "-----BEGIN OPENSSH PRIVATE KEY-----\nnot a key\n",
|
||||
"id_ed25519.pub": edPub + "\n", "id_box": "-----BEGIN OPENSSH PRIVATE KEY-----\nnot a key\n", "id_box.pub": rsaPub + "\n",
|
||||
"stray": "-----BEGIN RSA PRIVATE KEY-----\nnot a key\n", "notes.txt": "hello\n"}
|
||||
f := &fake{answer: func(c call) Ran {
|
||||
f := &fake{answer: func(c call) forgekey.Ran {
|
||||
if c.name == "ssh-keygen" && c.args[0] == "-y" {
|
||||
if strings.HasSuffix(c.args[len(c.args)-1], "id_box") {
|
||||
return Ran{Status: 1, Stderr: "Load key \"id_box\": incorrect passphrase supplied to decrypt private key\n"}
|
||||
return forgekey.Ran{Status: 1, Stderr: "Load key \"id_box\": incorrect passphrase supplied to decrypt private key\n"}
|
||||
}
|
||||
if strings.HasSuffix(c.args[len(c.args)-1], "id_ed25519") {
|
||||
return Ran{Stdout: edPub + "\n"}
|
||||
return forgekey.Ran{Stdout: edPub + "\n"}
|
||||
}
|
||||
}
|
||||
if c.name == "ssh-keygen" && c.args[0] == "-l" {
|
||||
return Ran{Stdout: "256 " + edFP + " no comment (ED25519)\n"}
|
||||
return forgekey.Ran{Stdout: "256 " + edFP + " no comment (ED25519)\n"}
|
||||
}
|
||||
return Ran{Status: 1, Stderr: "unexpected"}
|
||||
return forgekey.Ran{Status: 1, Stderr: "unexpected"}
|
||||
}}
|
||||
keys, err := client(home(t, files), f).Keys(context.Background())
|
||||
if err != nil {
|
||||
@@ -173,7 +175,7 @@ func TestKeysAreDescribedByTheirPublicHalfAndAPassphraseIsAskedNotRead(t *testin
|
||||
|
||||
func TestAPublicHalfThatIsAnotherKeysIsFound(t *testing.T) {
|
||||
files := map[string]string{"config": layout["config"], "id_ed25519": "-----BEGIN OPENSSH PRIVATE KEY-----\n", "id_ed25519.pub": rsaPub + "\n"}
|
||||
f := &fake{answer: func(c call) Ran { return Ran{Stdout: edPub + "\n"} }}
|
||||
f := &fake{answer: func(c call) forgekey.Ran { return forgekey.Ran{Stdout: edPub + "\n"} }}
|
||||
keys, _ := client(home(t, files), f).Keys(context.Background())
|
||||
if len(keys) != 1 || keys[0].PublicMismatch == "" || keys[0].Fingerprint != edFP {
|
||||
t.Fatalf("%+v", keys)
|
||||
@@ -181,15 +183,15 @@ func TestAPublicHalfThatIsAnotherKeysIsFound(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFingerprintsAreSshKeygens(t *testing.T) {
|
||||
k, err := ParseKeyLine("from=\"10.0.0.0/8,192.0.2.1\",no-pty " + edPub)
|
||||
k, err := forgekey.ParseKeyLine("from=\"10.0.0.0/8,192.0.2.1\",no-pty " + edPub)
|
||||
if err != nil || k.Fingerprint != edFP || k.Bits != 256 || k.Comment != "op@laptop" || !strings.HasPrefix(k.Options, "from=") {
|
||||
t.Fatalf("%+v %v", k, err)
|
||||
}
|
||||
k, _ = ParseKeyLine(rsaPub)
|
||||
k, _ = forgekey.ParseKeyLine(rsaPub)
|
||||
if k.Fingerprint != rsaFP || k.Bits != 2048 || !strings.Contains(k.Weak, "below 3072") {
|
||||
t.Fatalf("%+v", k)
|
||||
}
|
||||
if _, err := ParseKeyLine("ssh-ed25519 !!!notbase64"); err == nil {
|
||||
if _, err := forgekey.ParseKeyLine("ssh-ed25519 !!!notbase64"); err == nil {
|
||||
t.Fatal("garbage accepted")
|
||||
}
|
||||
}
|
||||
@@ -245,16 +247,16 @@ func scanOf(host, pub string) string { return host + " " + pub + "\n" }
|
||||
func TestKnownHostComparesWhatIsKnownWithWhatIsOffered(t *testing.T) {
|
||||
h := home(t, map[string]string{"config": layout["config"], "known_hosts": "ace.internal " + edPub + "\n"})
|
||||
offered := edPub
|
||||
f := &fake{answer: func(c call) Ran {
|
||||
f := &fake{answer: func(c call) forgekey.Ran {
|
||||
switch {
|
||||
case c.name == "ssh-keygen" && c.args[0] == "-F":
|
||||
return Ran{Stdout: "# Host ace.internal found: line 1\nace.internal " + edPub + "\n"}
|
||||
return forgekey.Ran{Stdout: "# Host ace.internal found: line 1\nace.internal " + edPub + "\n"}
|
||||
case c.name == "ssh-keyscan":
|
||||
return Ran{Stdout: scanOf("ace.internal", offered)}
|
||||
return forgekey.Ran{Stdout: scanOf("ace.internal", offered)}
|
||||
case c.name == "ssh-keygen" && c.args[0] == "-R":
|
||||
return Ran{}
|
||||
return forgekey.Ran{}
|
||||
}
|
||||
return Ran{Status: 1}
|
||||
return forgekey.Ran{Status: 1}
|
||||
}}
|
||||
c := client(h, f)
|
||||
got, err := c.KnownHost(context.Background(), "ace.internal", 22, false)
|
||||
@@ -293,11 +295,11 @@ func TestKnownHostComparesWhatIsKnownWithWhatIsOffered(t *testing.T) {
|
||||
|
||||
func TestAnUnreachableHostIsNotRefreshed(t *testing.T) {
|
||||
h := home(t, map[string]string{"known_hosts": ""})
|
||||
f := &fake{answer: func(c call) Ran {
|
||||
f := &fake{answer: func(c call) forgekey.Ran {
|
||||
if c.name == "ssh-keyscan" {
|
||||
return Ran{Status: 1}
|
||||
return forgekey.Ran{Status: 1}
|
||||
}
|
||||
return Ran{Status: 1}
|
||||
return forgekey.Ran{Status: 1}
|
||||
}}
|
||||
got, err := client(h, f).KnownHost(context.Background(), "gone.example", 22, false)
|
||||
if err != nil || !strings.HasPrefix(got["state"].(string), "unreachable") {
|
||||
@@ -310,7 +312,7 @@ func TestAnUnreachableHostIsNotRefreshed(t *testing.T) {
|
||||
|
||||
func TestTestSaysHowItAuthenticatedOrWhyNot(t *testing.T) {
|
||||
ok := "debug1: Connecting to ace.internal [10.0.0.2] port 22.\ndebug1: Server accepts key: /h/.ssh/id_ed25519 ED25519 " + edFP + "\nAuthenticated to ace.internal ([10.0.0.2]:22) using \"publickey\".\n"
|
||||
f := &fake{answer: func(c call) Ran { return Ran{Stderr: ok} }}
|
||||
f := &fake{answer: func(c call) forgekey.Ran { return forgekey.Ran{Stderr: ok} }}
|
||||
got, err := client(t.TempDir(), f).Test(context.Background(), "ace")
|
||||
if err != nil || got["ok"] != true || got["method"] != "publickey" || got["connected_to"] != "10.0.0.2:22" {
|
||||
t.Fatalf("%v %v", got, err)
|
||||
@@ -320,7 +322,7 @@ func TestTestSaysHowItAuthenticatedOrWhyNot(t *testing.T) {
|
||||
t.Fatalf("not a batch test: %s", args)
|
||||
}
|
||||
denied := "debug1: Offering public key: /h/.ssh/id_box RSA " + rsaFP + "\nop@ace.internal: Permission denied (publickey).\n"
|
||||
f = &fake{answer: func(c call) Ran { return Ran{Status: 255, Stderr: denied} }}
|
||||
f = &fake{answer: func(c call) forgekey.Ran { return forgekey.Ran{Status: 255, Stderr: denied} }}
|
||||
got, _ = client(t.TempDir(), f).Test(context.Background(), "ace")
|
||||
if got["ok"] != false || got["why"] != "no key it offered was accepted" || !reflect.DeepEqual(got["offered"], []string{"/h/.ssh/id_box"}) {
|
||||
t.Fatalf("%v", got)
|
||||
@@ -337,14 +339,14 @@ func TestCheckFindsWhatIsWrongAndSaysWhatItDidNotCheck(t *testing.T) {
|
||||
h := home(t, files)
|
||||
os.Chmod(filepath.Join(h, ".ssh", "config"), 0o666)
|
||||
os.Chmod(filepath.Join(h, ".ssh", "id_ed25519"), 0o644)
|
||||
f := &fake{answer: func(c call) Ran {
|
||||
f := &fake{answer: func(c call) forgekey.Ran {
|
||||
switch {
|
||||
case c.name == "ssh-keygen" && c.args[0] == "-y":
|
||||
return Ran{Stdout: edPub}
|
||||
return forgekey.Ran{Stdout: edPub}
|
||||
case c.name == "ssh-keyscan":
|
||||
return Ran{Stdout: scanOf("x", edPub)}
|
||||
return forgekey.Ran{Stdout: scanOf("x", edPub)}
|
||||
}
|
||||
return Ran{Status: 1}
|
||||
return forgekey.Ran{Status: 1}
|
||||
}}
|
||||
got, err := client(h, f).Check(context.Background(), true)
|
||||
if err != nil {
|
||||
@@ -381,7 +383,7 @@ func TestCheckFindsWhatIsWrongAndSaysWhatItDidNotCheck(t *testing.T) {
|
||||
// as problems, and says when no sweep has run.
|
||||
func TestCheckShowsAFailedSweep(t *testing.T) {
|
||||
h := home(t, map[string]string{"config": layout["config"], "known_hosts": ""})
|
||||
f := &fake{answer: func(call) Ran { return Ran{Status: 1} }}
|
||||
f := &fake{answer: func(call) forgekey.Ran { return forgekey.Ran{Status: 1} }}
|
||||
c := client(h, f)
|
||||
got, _ := c.Check(context.Background(), false)
|
||||
if !slices.ContainsFunc(got["not_checked"].([]string), func(s string) bool { return strings.Contains(s, "the sweep") }) {
|
||||
|
||||
Reference in New Issue
Block a user