func TestAgentForward(t *testing.T) { server := newServer(t) defer server.Shutdown() conn := server.Dial(clientConfig()) defer conn.Close() keyring := agent.NewKeyring() keyring.Add(testPrivateKeys["dsa"], nil, "") pub := testPublicKeys["dsa"] sess, err := conn.NewSession() if err != nil { t.Fatalf("NewSession: %v", err) } if err := agent.RequestAgentForwarding(sess); err != nil { t.Fatalf("RequestAgentForwarding: %v", err) } if err := agent.ForwardToAgent(conn, keyring); err != nil { t.Fatalf("SetupForwardKeyring: %v", err) } out, err := sess.CombinedOutput("ssh-add -L") if err != nil { t.Fatalf("running ssh-add: %v, out %s", err, out) } key, _, _, _, err := ssh.ParseAuthorizedKey(out) if err != nil { t.Fatalf("ParseAuthorizedKey(%q): %v", out, err) } if !bytes.Equal(key.Marshal(), pub.Marshal()) { t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub)) } }
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) addr, key, _ := parseKnownHostsLine([]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 }