Skip to content

Commit 421e903

Browse files
committed
improve HostKeyCallback
1 parent f080b42 commit 421e903

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

utils/file.go

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,10 @@ func processScpUri(src string) (io.ReadCloser, error) {
178178
return nil, fmt.Errorf("no username provided for scp connection")
179179
}
180180

181+
knownHostsPath := ResolvePath("~/.ssh/known_hosts", "")
182+
181183
// try loading ssh agent keys
182-
clientConfig, _ := auth.SshAgent(u.User.Username(), KnownHostsLogWarningCallBack) // skipcq: GSC-G106
184+
clientConfig, _ := auth.SshAgent(u.User.Username(), getCustomHostKeyCallback(knownHostsPath, "/tmp/foobar")) // skipcq: GSC-G106
183185

184186
// if CLAB_SSH_KEY is set we use the key referenced here
185187
keyPath := os.Getenv("CLAB_SSH_KEY")
@@ -527,23 +529,41 @@ func ProcessDownloadableAndEmbeddedFile(nodename string, fileRef string, filenam
527529
return fileRef, nil
528530
}
529531

530-
// KnownHostsLogWarningCallBack is a KnownHostsCallback implementation that relies on the
531-
// implementation of the crypto package of golang. However, it will not error out if the
532-
// Hostkey is unknown, but issue a warning in the logs, if the host is unknown.
533-
func KnownHostsLogWarningCallBack(hostname string, remote net.Addr, key ssh.PublicKey) error {
534-
// rely on the knownhosts implementation of the crypto package
535-
// cretae an instance of it
536-
khFile := ResolvePath("~/.ssh/known_hosts", "")
537-
origKHCB, err := knownhosts.New(khFile)
538-
if err != nil {
539-
return err
532+
// getCustomHostKeyCallback returns a custom ssh.HostKeyCallback.
533+
// it will never block the connection, but issue a log.Warn if the
534+
// host_key cannot be found (due to absense of the entry or
535+
// the file being missing)
536+
func getCustomHostKeyCallback(knownHostsFiles ...string) ssh.HostKeyCallback {
537+
var usefiles []string
538+
// check
539+
for _, file := range knownHostsFiles {
540+
if !FileExists(file) {
541+
log.Debugf("known_hosts file %s does not exist.", file)
542+
continue
543+
}
544+
usefiles = append(usefiles, file)
540545
}
541546

542-
// delegate the call
543-
err = origKHCB(hostname, remote, key)
547+
// load the known_hosts file retrieving an ssh.HostKeyCallback
548+
knownHostsFileCallback, err := knownhosts.New(usefiles...)
544549
if err != nil {
545-
// But if an error crops up, make it a warning and continue
546-
log.Warnf("error while performing host key validation based on %q for hostname %q (%v). continuing anyways", khFile, hostname, err)
550+
log.Debugf("error loading known_hosts files %q", strings.Join(knownHostsFiles, ", "))
551+
// this is an always failing knownHosts checker.
552+
// it will make sure that the log message of the custom function further down
553+
// is consistently logged. Meaning if file can't be loaded or entry does not exist.
554+
knownHostsFileCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
555+
return fmt.Errorf("error loading known_hosts files %v", err)
556+
}
557+
}
558+
559+
// defien the custom ssh.HostKeyCallback function.
560+
return func(hostname string, remote net.Addr, key ssh.PublicKey) error {
561+
// delegate the call
562+
err = knownHostsFileCallback(hostname, remote, key)
563+
if err != nil {
564+
// But if an error crops up, make it a warning and continue
565+
log.Warnf("error performing host key validation based on %q for hostname %q (%v). continuing anyways", strings.Join(knownHostsFiles, ", "), hostname, err)
566+
}
567+
return nil
547568
}
548-
return nil
549569
}

0 commit comments

Comments
 (0)