diff --git a/ssh/knownhosts/knownhosts.go b/ssh/knownhosts/knownhosts.go index c7eda05..cf520ad 100644 --- a/ssh/knownhosts/knownhosts.go +++ b/ssh/knownhosts/knownhosts.go @@ -188,6 +188,12 @@ func parseLine(line []byte) (marker, host string, key ssh.PublicKey, err error) } host, line = nextWord(line) + // If the extracted 'host' starts with '@', it means we either encountered + // a second marker (e.g., "@cert-authority @revoked") or an unknown marker + // (e.g., "@unknown"). Both are invalid. + if len(host) > 0 && host[0] == '@' { + return "", "", nil, fmt.Errorf("knownhosts: unexpected marker: %q", host) + } if len(line) == 0 { return "", "", nil, errors.New("knownhosts: missing host pattern") } diff --git a/ssh/knownhosts/knownhosts_test.go b/ssh/knownhosts/knownhosts_test.go index f3af2da..5e51447 100644 --- a/ssh/knownhosts/knownhosts_test.go +++ b/ssh/knownhosts/knownhosts_test.go @@ -462,3 +462,41 @@ func TestKeyTypeMismatch(t *testing.T) { t.Fatalf("got error %q, want to contain %q", err.Error(), expectedErr) } } + +func TestMultipleMarkers(t *testing.T) { + lineDouble := fmt.Sprintf("@cert-authority @revoked server.org %s %s", edKey.Type(), base64.StdEncoding.EncodeToString(edKey.Marshal())) + db := newHostKeyDB() + err := db.Read(bytes.NewBufferString(lineDouble), "testdb") + if err == nil { + t.Fatal("Read succeeded on line with multiple markers, expected error") + } + expectedError := "unexpected marker" + if !strings.Contains(err.Error(), expectedError) { + t.Errorf("got error %q, want it to contain %q", err.Error(), expectedError) + } + + lineUnknown := fmt.Sprintf("@unknown-marker server.org %s %s", edKey.Type(), base64.StdEncoding.EncodeToString(edKey.Marshal())) + err = db.Read(bytes.NewBufferString(lineUnknown), "testdb") + if err == nil { + t.Fatal("Read succeeded on line with unknown marker, expected error") + } + if !strings.Contains(err.Error(), expectedError) { + t.Errorf("got error %q, want it to contain %q", err.Error(), expectedError) + } +} + +func TestUnknownMarker(t *testing.T) { + line := fmt.Sprintf("@unknown-marker server.org %s %s", edKey.Type(), base64.StdEncoding.EncodeToString(edKey.Marshal())) + + db := newHostKeyDB() + err := db.Read(bytes.NewBufferString(line), "testdb") + + if err == nil { + t.Fatal("Read succeeded on line with unknown marker, expected error") + } + + expectedError := "unexpected marker" + if !strings.Contains(err.Error(), expectedError) { + t.Errorf("got error %q, want it to contain %q", err.Error(), expectedError) + } +}