From f997e8a33c99cb293e168ddab8f99111dbe864e7 Mon Sep 17 00:00:00 2001 From: Gary Burd Date: Fri, 29 Jun 2012 13:05:23 -0400 Subject: [PATCH] go.crypto/ssh: add ClientAuthAgent ClientAuthAgent adapts a *AgentClient to a ClientAuth. R=golang-dev, agl CC=golang-dev https://golang.org/cl/6352056 --- ssh/client_auth.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/ssh/client_auth.go b/ssh/client_auth.go index 8c030ac..21984a1 100644 --- a/ssh/client_auth.go +++ b/ssh/client_auth.go @@ -5,6 +5,7 @@ package ssh import ( + "errors" "fmt" "io" ) @@ -320,3 +321,51 @@ func handleAuthResponse(t *transport) (bool, []string, error) { } panic("unreachable") } + +// ClientAuthKeyring returns a ClientAuth using public key authentication via +// an agent. +func ClientAuthAgent(agent *AgentClient) ClientAuth { + return ClientAuthKeyring(&agentKeyring{agent: agent}) +} + +// agentKeyring implements ClientKeyring. +type agentKeyring struct { + agent *AgentClient + keys []*AgentKey +} + +func (kr *agentKeyring) Key(i int) (key interface{}, err error) { + if kr.keys == nil { + if kr.keys, err = kr.agent.RequestIdentities(); err != nil { + return + } + } + if i >= len(kr.keys) { + return + } + return kr.keys[i].Key() +} + +func (kr *agentKeyring) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) { + var key interface{} + if key, err = kr.Key(i); err != nil { + return + } + if key == nil { + return nil, errors.New("ssh: key index out of range") + } + if sig, err = kr.agent.SignRequest(key, data); err != nil { + return + } + + // Unmarshal the signature. + + var ok bool + if _, sig, ok = parseString(sig); !ok { + return nil, errors.New("ssh: malformed signature response from agent") + } + if sig, _, ok = parseString(sig); !ok { + return nil, errors.New("ssh: malformed signature response from agent") + } + return sig, nil +}