go.crypto/ssh: add ClientAuthAgent
ClientAuthAgent adapts a *AgentClient to a ClientAuth. R=golang-dev, agl CC=golang-dev https://golang.org/cl/6352056
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user