diff --git a/go.mod b/go.mod index 3c98c107..f1a5e416 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/internal/keyscan/keyscan.go b/internal/keyscan/keyscan.go new file mode 100644 index 00000000..fce7f7eb --- /dev/null +++ b/internal/keyscan/keyscan.go @@ -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 + } +}