internal: add simple keyscanner

This is an initial implementation and not a replacement candidate
for ssh-keyscan since it does only scan the key of the algorithm
the client and server agreed upon. This agreement may change
depending on the key being used, making it useless for distributed
usages.
This commit is contained in:
Hidde Beydals 2020-05-04 00:54:58 +02:00
parent 4c7f133315
commit c5491b9da8
2 changed files with 41 additions and 0 deletions

1
go.mod
View file

@ -8,6 +8,7 @@ require (
github.com/fluxcd/source-controller v0.0.1-alpha.2
github.com/manifoldco/promptui v0.7.0
github.com/spf13/cobra v1.0.0
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
k8s.io/api v0.18.2
k8s.io/apimachinery v0.18.2
k8s.io/client-go v0.18.2

View file

@ -0,0 +1,40 @@
package keyscan
import (
"encoding/base64"
"fmt"
"net"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/knownhosts"
)
func ScanKeys(host string) ([]byte, error) {
col := &collector{}
config := &ssh.ClientConfig{
User: "git",
HostKeyCallback: col.StoreKey(),
}
client, err := ssh.Dial("tcp", host, config)
if err == nil {
defer client.Close()
}
if len(col.knownKeys) > 0 {
return col.knownKeys, nil
}
return col.knownKeys, err
}
type collector struct {
knownKeys []byte
}
func (c *collector) StoreKey() ssh.HostKeyCallback {
return func(hostname string, remote net.Addr, key ssh.PublicKey) error {
c.knownKeys = append(
c.knownKeys,
fmt.Sprintf("%s %s %s\n", knownhosts.Normalize(hostname), key.Type(), base64.StdEncoding.EncodeToString(key.Marshal()))...,
)
return nil
}
}