func parseHostLine(line []byte) (string, gossh.PublicKey, error) { end := bytes.IndexByte(line, ' ') if end <= 0 { return "", nil, ErrUnfoundHostAddr } addr := string(line[:end]) keyByte := line[end+1:] key, _, _, _, err := gossh.ParseAuthorizedKey(keyByte) if err != nil { return "", nil, err } return addr, key, nil }
func parseAuthorizedKeys(in []byte) ([]gossh.PublicKey, error) { pubkeys := make([]gossh.PublicKey, 0) for len(in) > 0 { pubkey, _, _, rest, err := gossh.ParseAuthorizedKey(in) if err != nil { return nil, err } in = rest pubkeys = append(pubkeys, pubkey) } return pubkeys, nil }
// TestHostKeyChecker tests to check existing key func TestHostKeyChecker(t *testing.T) { keyFile := NewHostKeyFile(hostFile) checker := NewHostKeyChecker(keyFile, nil, ioutil.Discard) addr, key, _ := parseHostLine([]byte(hostLine)) tcpAddr, _ := net.ResolveTCPAddr("tcp", addr) if err := checker.Check("localhost", tcpAddr, key); err != nil { t.Fatalf("checker should succeed for %v: %v", tcpAddr.String(), err) } wrongKey, _, _, _, _ := gossh.ParseAuthorizedKey([]byte(wrongAuthorizedKey)) if err := checker.Check("localhost", tcpAddr, wrongKey); err != ErrUnmatchKey { t.Fatalf("checker should fail with %v", ErrUnmatchKey) } }
// parseKnownHostsLine parses a line from a known hosts file. It returns a // string containing the hosts section of the line, a gossh.PublicKey parsed // from the line, and any error encountered during the parsing. func parseKnownHostsLine(line []byte) (string, gossh.PublicKey, error) { // Skip any leading whitespace. line = bytes.TrimLeft(line, "\t ") // Skip comments and empty lines. if bytes.HasPrefix(line, []byte("#")) || len(line) == 0 { return "", nil, nil } // Skip markers. if bytes.HasPrefix(line, []byte("@")) { return "", nil, errors.New("marker functionality not implemented") } // Find the end of the host name(s) portion. end := bytes.IndexAny(line, "\t ") if end <= 0 { return "", nil, errors.New("bad format (insufficient fields)") } hosts := string(line[:end]) keyBytes := line[end+1:] // Check for hashed host names. if strings.HasPrefix(hosts, sshHashDelim) { return "", nil, errors.New("hashed hosts not implemented") } // Finally, actually try to extract the key. key, _, _, _, err := gossh.ParseAuthorizedKey(keyBytes) if err != nil { return "", nil, fmt.Errorf("error parsing key: %v", err) } return hosts, key, nil }