diff --git a/command/ssh/proxycommand.go b/command/ssh/proxycommand.go index f73d054c..98a5a14c 100644 --- a/command/ssh/proxycommand.go +++ b/command/ssh/proxycommand.go @@ -122,7 +122,7 @@ func doLoginIfNeeded(ctx *cli.Context, subject string) error { } // Do login flow if key is not in agent - if _, err := agent.GetSigner(subject, opts...); err != nil { + if exists, err := agent.HasKeys(opts...); err != nil || !exists || len(opts) == 0 { flow, err := cautils.NewCertificateFlow(ctx) if err != nil { return err diff --git a/crypto/sshutil/agent.go b/crypto/sshutil/agent.go index a49c9f57..b4b479d6 100644 --- a/crypto/sshutil/agent.go +++ b/crypto/sshutil/agent.go @@ -82,6 +82,21 @@ func (a *Agent) AuthMethod() ssh.AuthMethod { return ssh.PublicKeysCallback(a.Signers) } +// HasKeys returns if a key filtered with the given options exists. +func (a *Agent) HasKeys(opts ...AgentOption) (bool, error) { + o := newOptions(opts) + keys, err := a.List() + if err != nil { + return false, errors.Wrap(err, "error listing keys") + } + for _, key := range keys { + if o.filterBySignatureKey == nil || o.filterBySignatureKey(key) { + return true, nil + } + } + return false, nil +} + // ListKeys returns the list of keys in the agent. func (a *Agent) ListKeys(opts ...AgentOption) ([]*agent.Key, error) { o := newOptions(opts)