From 3305186468e57f6c7535c9e97cb0bde4b2b65908 Mon Sep 17 00:00:00 2001 From: Mark Severson Date: Sat, 2 Apr 2016 19:02:50 -0600 Subject: [PATCH] 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 Run-TryBot: Han-Wen Nienhuys --- ssh/agent/client.go | 5 ++++- ssh/agent/server.go | 7 +++++++ ssh/agent/server_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/ssh/agent/client.go b/ssh/agent/client.go index 2cb9248..f0935e5 100644 --- a/ssh/agent/client.go +++ b/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]) } diff --git a/ssh/agent/server.go b/ssh/agent/server.go index b21a201..0a80d36 100644 --- a/ssh/agent/server.go +++ b/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 { diff --git a/ssh/agent/server_test.go b/ssh/agent/server_test.go index ef0ab29..fd7848e 100644 --- a/ssh/agent/server_test.go +++ b/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) + } +}