diff --git a/ssh/agent/client.go b/ssh/agent/client.go index 7f2ae502..1a916961 100644 --- a/ssh/agent/client.go +++ b/ssh/agent/client.go @@ -8,7 +8,7 @@ References: [PROTOCOL.agent]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent */ -package agent +package agent // import "golang.org/x/crypto/ssh/agent" import ( "bytes" diff --git a/ssh/client.go b/ssh/client.go index 90a18cb8..03c4e77d 100644 --- a/ssh/client.go +++ b/ssh/client.go @@ -76,21 +76,12 @@ func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err) } conn.mux = newMux(conn.transport) - go conn.mux.loop() - return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil } -func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error { - if err := c.clientHandshakeNoAuth(dialAddress, config); err != nil { - return err - } - return c.clientAuthenticate(config) -} - // clientHandshake performs the client side key exchange. See RFC 4253 Section // 7. -func (c *connection) clientHandshakeNoAuth(dialAddress string, config *ClientConfig) error { +func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error { c.clientVersion = []byte(packageVersion) if config.ClientVersion != "" { c.clientVersion = []byte(config.ClientVersion) @@ -114,8 +105,7 @@ func (c *connection) clientHandshakeNoAuth(dialAddress string, config *ClientCon } else if packet[0] != msgNewKeys { return unexpectedMessageError(msgNewKeys, packet[0]) } - //return c.clientAuthenticate(config) - return nil + return c.clientAuthenticate(config) } // verifyHostKeySignature verifies the host key obtained in the key diff --git a/ssh/doc.go b/ssh/doc.go index d4d16f08..fb6402bb 100644 --- a/ssh/doc.go +++ b/ssh/doc.go @@ -15,4 +15,4 @@ References: [PROTOCOL.certkeys]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 */ -package ssh +package ssh // import "golang.org/x/crypto/ssh" diff --git a/ssh/mux.go b/ssh/mux.go index e1698278..321880ad 100644 --- a/ssh/mux.go +++ b/ssh/mux.go @@ -125,7 +125,7 @@ func newMux(p packetConn) *mux { m.chanList.offset = atomic.AddUint32(&globalOff, 1) } - //go m.loop() + go m.loop() return m } diff --git a/ssh/mux_test.go b/ssh/mux_test.go index d144a084..52303896 100644 --- a/ssh/mux_test.go +++ b/ssh/mux_test.go @@ -15,9 +15,7 @@ func muxPair() (*mux, *mux) { a, b := memPipe() s := newMux(a) - go s.loop() c := newMux(b) - go c.loop() return s, c } diff --git a/ssh/server.go b/ssh/server.go index b7a96abc..8c4f1429 100644 --- a/ssh/server.go +++ b/ssh/server.go @@ -157,23 +157,8 @@ func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) { return Marshal(sig), nil } -func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) { - if _, err := s.serverHandshakeNoAuth(config); err != nil { - return nil, err - } - - perms, err := s.serverAuthenticate(config) - if err != nil { - return nil, err - } - s.mux = newMux(s.transport) - go s.mux.loop() - - return perms, nil -} - // handshake performs key exchange and user authentication. -func (s *connection) serverHandshakeNoAuth(config *ServerConfig) (*Permissions, error) { +func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) { if len(config.hostKeys) == 0 { return nil, errors.New("ssh: server has no host keys") } @@ -217,13 +202,12 @@ func (s *connection) serverHandshakeNoAuth(config *ServerConfig) (*Permissions, return nil, err } - //perms, err := s.serverAuthenticate(config) - //if err != nil { - // return nil, err - //} + perms, err := s.serverAuthenticate(config) + if err != nil { + return nil, err + } s.mux = newMux(s.transport) - //return perms, err - return nil, nil + return perms, err } func isAcceptableAlgo(algo string) bool { diff --git a/ssh/sshpiper.go b/ssh/sshpiper.go index 971ad6af..b1bb05a2 100644 --- a/ssh/sshpiper.go +++ b/ssh/sshpiper.go @@ -285,11 +285,11 @@ func (pipe *pipedConn) loop() error { c := make(chan error) go func() { - c <- piping(pipe.upstream.mux.conn, pipe.downstream.mux.conn) + c <- piping(pipe.upstream.transport, pipe.downstream.transport) }() go func() { - c <- piping(pipe.downstream.mux.conn, pipe.upstream.mux.conn) + c <- piping(pipe.downstream.transport, pipe.upstream.transport) }() defer pipe.Close() @@ -299,8 +299,8 @@ func (pipe *pipedConn) loop() error { } func (pipe *pipedConn) Close() { - pipe.upstream.mux.conn.Close() - pipe.downstream.mux.conn.Close() + pipe.upstream.transport.Close() + pipe.downstream.transport.Close() } func (pipe *pipedConn) pipeAuth(initUserAuthMsg *userAuthRequestMsg) error { @@ -396,7 +396,6 @@ func newUpstream(c net.Conn, addr string, config *ClientConfig) (*upstream, erro c.Close() return nil, err } - conn.mux = newMux(conn.transport) return &upstream{conn}, nil } @@ -424,3 +423,77 @@ func noneAuthMsg(user string) *userAuthRequestMsg { Method: "none", } } + +func (c *connection) clientHandshakeNoAuth(dialAddress string, config *ClientConfig) error { + c.clientVersion = []byte(packageVersion) + if config.ClientVersion != "" { + c.clientVersion = []byte(config.ClientVersion) + } + + var err error + c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion) + if err != nil { + return err + } + + c.transport = newClientTransport( + newTransport(c.sshConn.conn, config.Rand, true /* is client */), + c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr()) + if err := c.transport.requestKeyChange(); err != nil { + return err + } + + if packet, err := c.transport.readPacket(); err != nil { + return err + } else if packet[0] != msgNewKeys { + return unexpectedMessageError(msgNewKeys, packet[0]) + } + return nil +} + +func (s *connection) serverHandshakeNoAuth(config *ServerConfig) (*Permissions, error) { + if len(config.hostKeys) == 0 { + return nil, errors.New("ssh: server has no host keys") + } + + var err error + s.serverVersion = []byte("SSH-2.0-SSHPiper") + s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion) + if err != nil { + return nil, err + } + + tr := newTransport(s.sshConn.conn, config.Rand, false /* not client */) + s.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config) + + if err := s.transport.requestKeyChange(); err != nil { + return nil, err + } + + if packet, err := s.transport.readPacket(); err != nil { + return nil, err + } else if packet[0] != msgNewKeys { + return nil, unexpectedMessageError(msgNewKeys, packet[0]) + } + + var packet []byte + if packet, err = s.transport.readPacket(); err != nil { + return nil, err + } + + var serviceRequest serviceRequestMsg + if err = Unmarshal(packet, &serviceRequest); err != nil { + return nil, err + } + if serviceRequest.Service != serviceUserAuth { + return nil, errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating") + } + serviceAccept := serviceAcceptMsg{ + Service: serviceUserAuth, + } + if err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil { + return nil, err + } + + return nil, nil +} diff --git a/ssh/terminal/util.go b/ssh/terminal/util.go index 0763c9a9..598e3df7 100644 --- a/ssh/terminal/util.go +++ b/ssh/terminal/util.go @@ -14,7 +14,7 @@ // panic(err) // } // defer terminal.Restore(0, oldState) -package terminal +package terminal // import "golang.org/x/crypto/ssh/terminal" import ( "io" diff --git a/ssh/test/doc.go b/ssh/test/doc.go index 787b8fa2..d21d6b71 100644 --- a/ssh/test/doc.go +++ b/ssh/test/doc.go @@ -4,4 +4,4 @@ // This package contains integration tests for the // code.google.com/p/go.crypto/ssh package. -package test +package test // import "golang.org/x/crypto/ssh/test" diff --git a/ssh/testdata/doc.go b/ssh/testdata/doc.go index 43024869..3f4d74d9 100644 --- a/ssh/testdata/doc.go +++ b/ssh/testdata/doc.go @@ -5,4 +5,4 @@ // This package contains test data shared between the various subpackages of // the code.google.com/p/go.crypto/ssh package. Under no circumstance should // this data be used for production code. -package testdata +package testdata // import "golang.org/x/crypto/ssh/testdata" diff --git a/ssh/transport.go b/ssh/transport.go index 34e99b28..4f68b047 100644 --- a/ssh/transport.go +++ b/ssh/transport.go @@ -259,7 +259,7 @@ func generateKeyMaterial(out, tag []byte, r *kexResult) { } } -const packageVersion = "SSH-2.0-SSHPiper" +const packageVersion = "SSH-2.0-Go" // Sends and receives a version line. The versionLine string should // be US ASCII, start with "SSH-2.0-", and should not include a