From 6e18c9215adcedf12d0ff735e10e83eea09e6dae Mon Sep 17 00:00:00 2001 From: Boshi Lian Date: Sun, 17 May 2020 08:32:48 -0700 Subject: [PATCH 1/3] knownhost to support reader --- ssh/knownhosts/reader.go | 21 +++++++++++++++++++++ ssh/knownhosts/reader_test.go | 17 +++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 ssh/knownhosts/reader.go create mode 100644 ssh/knownhosts/reader_test.go diff --git a/ssh/knownhosts/reader.go b/ssh/knownhosts/reader.go new file mode 100644 index 0000000000..62ab7b3178 --- /dev/null +++ b/ssh/knownhosts/reader.go @@ -0,0 +1,21 @@ +package knownhosts + +import ( + "io" + + "golang.org/x/crypto/ssh" +) + +func NewFromReader(r io.Reader) (ssh.HostKeyCallback, error) { + db := newHostKeyDB() + if err := db.Read(r, ""); err != nil { + return nil, err + } + + var certChecker ssh.CertChecker + certChecker.IsHostAuthority = db.IsHostAuthority + certChecker.IsRevoked = db.IsRevoked + certChecker.HostKeyFallback = db.check + + return certChecker.CheckHostKey, nil +} diff --git a/ssh/knownhosts/reader_test.go b/ssh/knownhosts/reader_test.go new file mode 100644 index 0000000000..72b0890091 --- /dev/null +++ b/ssh/knownhosts/reader_test.go @@ -0,0 +1,17 @@ +package knownhosts + +import ( + "fmt" + "strings" + "testing" +) + +func TestNewFromReader(t *testing.T) { + str := fmt.Sprintf("server*.domain %s", edKeyStr) + + _, err := NewFromReader(strings.NewReader(str)) + if err != nil { + t.Fatalf("cannot read from string: %v", err) + } + +} From 4b4a3535e6e7731b9c7ea3010acb50fa4236892a Mon Sep 17 00:00:00 2001 From: Boshi Lian Date: Sun, 17 May 2020 08:31:50 -0700 Subject: [PATCH 2/3] add comment --- ssh/knownhosts/reader.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ssh/knownhosts/reader.go b/ssh/knownhosts/reader.go index 62ab7b3178..68a39bda66 100644 --- a/ssh/knownhosts/reader.go +++ b/ssh/knownhosts/reader.go @@ -6,6 +6,12 @@ import ( "golang.org/x/crypto/ssh" ) +// NewFromReader creates a host key callback from the given OpenSSH host io.Reader +// which is in SSH_KNOWN_HOSTS_FILE_FORMAT. The returned callback is for use in +// ssh.ClientConfig.HostKeyCallback. By preference, the key check +// operates on the hostname if available, i.e. if a server changes its +// IP address, the host key check will still succeed, even though a +// record of the new IP address is not available. func NewFromReader(r io.Reader) (ssh.HostKeyCallback, error) { db := newHostKeyDB() if err := db.Read(r, ""); err != nil { From db271c4bb9303ed915454cd4c428256e7ac73698 Mon Sep 17 00:00:00 2001 From: Boshi LIAN Date: Fri, 23 May 2025 18:53:34 +0000 Subject: [PATCH 3/3] refactor: update NewFromReader to accept multiple io.Reader parameters --- ssh/knownhosts/reader.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssh/knownhosts/reader.go b/ssh/knownhosts/reader.go index 68a39bda66..92c86be57d 100644 --- a/ssh/knownhosts/reader.go +++ b/ssh/knownhosts/reader.go @@ -12,9 +12,9 @@ import ( // operates on the hostname if available, i.e. if a server changes its // IP address, the host key check will still succeed, even though a // record of the new IP address is not available. -func NewFromReader(r io.Reader) (ssh.HostKeyCallback, error) { +func NewFromReader(readers ...io.Reader) (ssh.HostKeyCallback, error) { db := newHostKeyDB() - if err := db.Read(r, ""); err != nil { + if err := db.Read(io.MultiReader(readers...), ""); err != nil { return nil, err }