Переглянути джерело

go.crypto/ssh: add ClientAuthAgent

ClientAuthAgent adapts a *AgentClient to a ClientAuth.

R=golang-dev, agl
CC=golang-dev
https://golang.org/cl/6352056
Gary Burd 13 роки тому
батько
коміт
f997e8a33c
1 змінених файлів з 49 додано та 0 видалено
  1. 49 0
      ssh/client_auth.go

+ 49 - 0
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
+}