Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Go host key checking for non-standard port(s)
// thes below two functions are talked about in
// http://mfridman.com/2017/09/04/go-ssh-hostkey.html
func validatePort(s string) (string, error) {
// empty string defaults to port 22, ports 1-65535 valid, otherwise error
if s == "" {
// it is the caller's responsibility to pass in a valid, non-empty port
return "22", nil
}
i, _ := strconv.Atoi(s)
if i < 1 || i > 65535 {
return "", fmt.Errorf("Invalid port: %v", s)
}
return s, nil
}
func checkHostKey(host, port string) (ssh.PublicKey, error) {
// $HOME/.ssh/known_hosts
file, err := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts"))
if err != nil {
return nil, err
}
defer file.Close()
var hostport string
if port == "22" {
// standard port assumes 22
// 192.168.10.53 ssh-rsa AAAAB3Nza...vguvx+81N1xaw==
hostport = host
} else {
// non-standard port(s)
// [ssh.example.com]:1999,[93.184.216.34]:1999 ssh-rsa AAAAB3Nza...vguvx+81N1xaw==
hostport = "[" + host + "]:" + port
}
scanner := bufio.NewScanner(file)
var hostKey ssh.PublicKey
for scanner.Scan() {
fields := strings.Split(scanner.Text(), " ")
if len(fields) != 3 {
continue
}
if strings.Contains(fields[0], hostport) {
var err error
hostKey, _, _, _, err = ssh.ParseAuthorizedKey(scanner.Bytes())
if err != nil {
return nil, fmt.Errorf("Error parsing %q: %v", fields[2], err)
}
break // scanning line by line, first occurrence will be returned
}
}
if hostKey == nil {
return nil, fmt.Errorf("No hostkey for %s", host+":"+port)
}
return hostKey, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment