go.crypto/ssh: prevent concurrent reads and concurrent writes over the same agent connection

minor fix for v01 cert parsing when algo is not supported

R=golang-dev, agl, dave
CC=golang-dev
https://golang.org/cl/6116052
This commit is contained in:
Jonathan Pittman
2012-04-26 17:13:49 -04:00
committed by Adam Langley
parent 0d3cfff99f
commit 8ab8312ac8
2 changed files with 21 additions and 6 deletions
+20 -6
View File
@@ -11,6 +11,7 @@ import (
"encoding/base64"
"errors"
"io"
"sync"
)
// See PROTOCOL.agent, section 3.
@@ -126,24 +127,37 @@ func parseAgentKey(in []byte) (out *AgentKey, rest []byte, ok bool) {
}
// AgentClient provides a means to communicate with an ssh agent process based
// on the protocol described in PROTOCOL.agent?rev=1.6. It contains an
// embedded io.ReadWriter that is typically represented by using a *net.UnixConn.
// on the protocol described in PROTOCOL.agent?rev=1.6.
type AgentClient struct {
io.ReadWriter
// conn is typically represented by using a *net.UnixConn
conn io.ReadWriter
// mu is used to prevent concurrent access to the agent
mu sync.Mutex
}
// NewAgentClient creates and returns a new *AgentClient using the
// passed in io.ReadWriter as a connection to a ssh agent.
func NewAgentClient(rw io.ReadWriter) *AgentClient {
return &AgentClient{conn: rw}
}
// sendAndReceive sends req to the agent and waits for a reply. On success,
// the reply is unmarshaled into reply and replyType is set to the first byte of
// the reply, which contains the type of the message.
func (ac *AgentClient) sendAndReceive(req []byte) (reply interface{}, replyType uint8, err error) {
// ac.mu prevents multiple, concurrent requests. Since the agent is typically
// on the same machine, we don't attempt to pipeline the requests.
ac.mu.Lock()
defer ac.mu.Unlock()
msg := make([]byte, stringLength(len(req)))
marshalString(msg, req)
if _, err = ac.Write(msg); err != nil {
if _, err = ac.conn.Write(msg); err != nil {
return
}
var respSizeBuf [4]byte
if _, err = io.ReadFull(ac, respSizeBuf[:]); err != nil {
if _, err = io.ReadFull(ac.conn, respSizeBuf[:]); err != nil {
return
}
respSize, _, _ := parseUint32(respSizeBuf[:])
@@ -154,7 +168,7 @@ func (ac *AgentClient) sendAndReceive(req []byte) (reply interface{}, replyType
}
buf := make([]byte, respSize)
if _, err = io.ReadFull(ac, buf); err != nil {
if _, err = io.ReadFull(ac.conn, buf); err != nil {
return
}
return unmarshalAgentMsg(buf)
+1
View File
@@ -78,6 +78,7 @@ func parseOpenSSHCertV01(in []byte, algo string) (out *OpenSSHCertV01, rest []by
}
cert.Key = dsaPubKey
default:
ok = false
return
}