in dubboctl/pkg/hub/ssh/dialer.go [378:442]
func createHostKeyCallback(hostKeyCallback HostKeyCallback) func(hostPort string, remote net.Addr, key ssh.PublicKey) error {
return func(hostPort string, remote net.Addr, pubKey ssh.PublicKey) error {
host, port := hostPort, "22"
if _h, _p, err := net.SplitHostPort(host); err == nil {
host, port = _h, _p
}
knownHosts := filepath.Join(homedir.Get(), ".ssh", "known_hosts")
_, err := os.Stat(knownHosts)
if err != nil && errors.Is(err, os.ErrNotExist) {
if hostKeyCallback != nil && hostKeyCallback(hostPort, pubKey) == nil {
return nil
}
return errUnknownServerKey
}
f, err := os.Open(knownHosts)
if err != nil {
return fmt.Errorf("failed to open known_hosts: %w", err)
}
defer f.Close()
hashhost := knownhosts.HashHostname(host)
var errs []error
scanner := bufio.NewScanner(f)
for scanner.Scan() {
_, hostPorts, _key, _, _, err := ssh.ParseKnownHosts(scanner.Bytes())
if err != nil {
errs = append(errs, err)
continue
}
for _, hp := range hostPorts {
h, p := hp, "22"
if _h, _p, err := net.SplitHostPort(hp); err == nil {
h, p = _h, _p
}
if (h == host || h == hashhost) && port == p {
if pubKey.Type() != _key.Type() {
errs = append(errs, fmt.Errorf("missmatch in type of a key"))
continue
}
if bytes.Equal(_key.Marshal(), pubKey.Marshal()) {
return nil
}
return errBadServerKey
}
}
}
if hostKeyCallback != nil && hostKeyCallback(hostPort, pubKey) == nil {
return nil
}
if len(errs) > 0 {
return fmt.Errorf("server is not trusted (%v)", errs)
}
return errUnknownServerKey
}
}