go.crypto: initial code
Manual edits to README. Moved from main Go repository, deleted Makefiles, ran gofix -r go1rename. Tested with: go test code.google.com/p/go.crypto/... R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/5564059
This commit is contained in:
+132
@@ -0,0 +1,132 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Dial initiates a connection to the addr from the remote host.
|
||||
// addr is resolved using net.ResolveTCPAddr before connection.
|
||||
// This could allow an observer to observe the DNS name of the
|
||||
// remote host. Consider using ssh.DialTCP to avoid this.
|
||||
func (c *ClientConn) Dial(n, addr string) (net.Conn, error) {
|
||||
raddr, err := net.ResolveTCPAddr(n, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.DialTCP(n, nil, raddr)
|
||||
}
|
||||
|
||||
// DialTCP connects to the remote address raddr on the network net,
|
||||
// which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used
|
||||
// as the local address for the connection.
|
||||
func (c *ClientConn) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error) {
|
||||
if laddr == nil {
|
||||
laddr = &net.TCPAddr{
|
||||
IP: net.IPv4zero,
|
||||
Port: 0,
|
||||
}
|
||||
}
|
||||
ch, err := c.dial(laddr.IP.String(), laddr.Port, raddr.IP.String(), raddr.Port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &tcpchanconn{
|
||||
tcpchan: ch,
|
||||
laddr: laddr,
|
||||
raddr: raddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RFC 4254 7.2
|
||||
type channelOpenDirectMsg struct {
|
||||
ChanType string
|
||||
PeersId uint32
|
||||
PeersWindow uint32
|
||||
MaxPacketSize uint32
|
||||
raddr string
|
||||
rport uint32
|
||||
laddr string
|
||||
lport uint32
|
||||
}
|
||||
|
||||
// dial opens a direct-tcpip connection to the remote server. laddr and raddr are passed as
|
||||
// strings and are expected to be resolveable at the remote end.
|
||||
func (c *ClientConn) dial(laddr string, lport int, raddr string, rport int) (*tcpchan, error) {
|
||||
ch := c.newChan(c.transport)
|
||||
if err := c.writePacket(marshal(msgChannelOpen, channelOpenDirectMsg{
|
||||
ChanType: "direct-tcpip",
|
||||
PeersId: ch.id,
|
||||
PeersWindow: 1 << 14,
|
||||
MaxPacketSize: 1 << 15, // RFC 4253 6.1
|
||||
raddr: raddr,
|
||||
rport: uint32(rport),
|
||||
laddr: laddr,
|
||||
lport: uint32(lport),
|
||||
})); err != nil {
|
||||
c.chanlist.remove(ch.id)
|
||||
return nil, err
|
||||
}
|
||||
if err := ch.waitForChannelOpenResponse(); err != nil {
|
||||
c.chanlist.remove(ch.id)
|
||||
return nil, fmt.Errorf("ssh: unable to open direct tcpip connection: %v", err)
|
||||
}
|
||||
return &tcpchan{
|
||||
clientChan: ch,
|
||||
Reader: ch.stdout,
|
||||
Writer: ch.stdin,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type tcpchan struct {
|
||||
*clientChan // the backing channel
|
||||
io.Reader
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// tcpchanconn fulfills the net.Conn interface without
|
||||
// the tcpchan having to hold laddr or raddr directly.
|
||||
type tcpchanconn struct {
|
||||
*tcpchan
|
||||
laddr, raddr net.Addr
|
||||
}
|
||||
|
||||
// LocalAddr returns the local network address.
|
||||
func (t *tcpchanconn) LocalAddr() net.Addr {
|
||||
return t.laddr
|
||||
}
|
||||
|
||||
// RemoteAddr returns the remote network address.
|
||||
func (t *tcpchanconn) RemoteAddr() net.Addr {
|
||||
return t.raddr
|
||||
}
|
||||
|
||||
// SetDeadline sets the read and write deadlines associated
|
||||
// with the connection.
|
||||
func (t *tcpchanconn) SetDeadline(deadline time.Time) error {
|
||||
if err := t.SetReadDeadline(deadline); err != nil {
|
||||
return err
|
||||
}
|
||||
return t.SetWriteDeadline(deadline)
|
||||
}
|
||||
|
||||
// SetReadDeadline sets the read deadline.
|
||||
// A zero value for t means Read will not time out.
|
||||
// After the deadline, the error from Read will implement net.Error
|
||||
// with Timeout() == true.
|
||||
func (t *tcpchanconn) SetReadDeadline(deadline time.Time) error {
|
||||
return errors.New("ssh: tcpchan: deadline not supported")
|
||||
}
|
||||
|
||||
// SetWriteDeadline exists to satisfy the net.Conn interface
|
||||
// but is not implemented by this type. It always returns an error.
|
||||
func (t *tcpchanconn) SetWriteDeadline(deadline time.Time) error {
|
||||
return errors.New("ssh: tcpchan: deadline not supported")
|
||||
}
|
||||
Reference in New Issue
Block a user