Browse Source

x/crypto/ssh/agent: Support v1 remove all message

Some ssh-agent clients expect the server to support remove all messages
for protocols 1 & 2 and error if protocol 1 support is missing.

This adds a null-op implementation of the remove all message in similar
fashion to the existing list all message support.

Fixes golang/go#15159

Change-Id: I9389885d89c9147f3e10850893bba6ed7d0a4e82
Reviewed-on: https://go-review.googlesource.com/21468
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
Mark Severson 9 years ago
parent
commit
3305186468
3 changed files with 43 additions and 1 deletions
  1. 4 1
      ssh/agent/client.go
  2. 7 0
      ssh/agent/server.go
  3. 32 0
      ssh/agent/server_test.go

+ 4 - 1
ssh/agent/client.go

@@ -76,7 +76,8 @@ type AddedKey struct {
 
 // See [PROTOCOL.agent], section 3.
 const (
-	agentRequestV1Identities = 1
+	agentRequestV1Identities   = 1
+	agentRemoveAllV1Identities = 9
 
 	// 3.2 Requests from client to agent for protocol 2 key operations
 	agentAddIdentity         = 17
@@ -376,6 +377,8 @@ func unmarshal(packet []byte) (interface{}, error) {
 		msg = new(identitiesAnswerAgentMsg)
 	case agentSignResponse:
 		msg = new(signResponseAgentMsg)
+	case agentV1IdentitiesAnswer:
+		msg = new(agentV1IdentityMsg)
 	default:
 		return nil, fmt.Errorf("agent: unknown type tag %d", packet[0])
 	}

+ 7 - 0
ssh/agent/server.go

@@ -49,6 +49,9 @@ func marshalKey(k *Key) []byte {
 	return ssh.Marshal(&record)
 }
 
+// See [PROTOCOL.agent], section 2.5.1.
+const agentV1IdentitiesAnswer = 2
+
 type agentV1IdentityMsg struct {
 	Numkeys uint32 `sshtype:"2"`
 }
@@ -69,6 +72,10 @@ func (s *server) processRequest(data []byte) (interface{}, error) {
 	switch data[0] {
 	case agentRequestV1Identities:
 		return &agentV1IdentityMsg{0}, nil
+
+	case agentRemoveAllV1Identities:
+		return nil, nil
+
 	case agentRemoveIdentity:
 		var req agentRemoveIdentityMsg
 		if err := ssh.Unmarshal(data, &req); err != nil {

+ 32 - 0
ssh/agent/server_test.go

@@ -75,3 +75,35 @@ func TestSetupForwardAgent(t *testing.T) {
 	testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil, 0)
 	conn.Close()
 }
+
+func TestV1ProtocolMessages(t *testing.T) {
+	c1, c2, err := netPipe()
+	if err != nil {
+		t.Fatalf("netPipe: %v", err)
+	}
+	defer c1.Close()
+	defer c2.Close()
+	c := NewClient(c1)
+
+	go ServeAgent(NewKeyring(), c2)
+
+	testV1ProtocolMessages(t, c.(*client))
+}
+
+func testV1ProtocolMessages(t *testing.T, c *client) {
+	reply, err := c.call([]byte{agentRequestV1Identities})
+	if err != nil {
+		t.Fatalf("v1 request all failed: %v", err)
+	}
+	if msg, ok := reply.(*agentV1IdentityMsg); !ok || msg.Numkeys != 0 {
+		t.Fatalf("invalid request all response: %#v", reply)
+	}
+
+	reply, err = c.call([]byte{agentRemoveAllV1Identities})
+	if err != nil {
+		t.Fatalf("v1 remove all failed: %v", err)
+	}
+	if _, ok := reply.(*successAgentMsg); !ok {
+		t.Fatalf("invalid remove all response: %#v", reply)
+	}
+}