Commit 792a55f5 authored by Dave Cheney's avatar Dave Cheney Committed by Adam Langley

exp/ssh: add experimental ssh client

Requires CL 5285044

client.go:
* add Dial, ClientConn, ClientChan, ClientConfig and Cmd.

doc.go:
* add Client documentation.

server.go:
* adjust for readVersion change.

transport.go:
* return an os.Error not a bool from readVersion.

R=rsc, agl, n13m3y3r
CC=golang-dev
https://golang.org/cl/5162047
parent e8a426ae
......@@ -7,6 +7,7 @@ include ../../../Make.inc
TARG=exp/ssh
GOFILES=\
channel.go\
client.go\
common.go\
messages.go\
transport.go\
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
/*
Package ssh implements an SSH server.
Package ssh implements an SSH client and server.
SSH is a transport security protocol, an authentication protocol and a
family of application protocols. The most typical application level
......@@ -75,5 +75,27 @@ present a simple terminal interface.
}
return
}()
An SSH client is represented with a ClientConn. Currently only the "password"
authentication method is supported.
config := &ClientConfig{
User: "username",
Password: "123456",
}
client, err := Dial("yourserver.com:22", config)
Each ClientConn can support multiple channels, represented by ClientChan. Each
channel should be of a type specified in rfc4250, 4.9.1.
ch, err := client.OpenChan("session")
Once the ClientChan is opened, you can execute a single command on the remote side
using the Exec method.
cmd, err := ch.Exec("/usr/bin/whoami")
reader := bufio.NewReader(cmd.Stdin)
line, _, _ := reader.ReadLine()
fmt.Println(line)
*/
package ssh
......@@ -267,9 +267,9 @@ func (s *ServerConnection) Handshake(conn net.Conn) os.Error {
}
magics.serverVersion = serverVersion[:len(serverVersion)-2]
version, ok := readVersion(s.transport)
if !ok {
return os.NewError("failed to read version string from client")
version, err := readVersion(s.transport)
if err != nil {
return err
}
magics.clientVersion = version
......
......@@ -332,16 +332,15 @@ func (t truncatingMAC) Size() int {
const maxVersionStringBytes = 1024
// Read version string as specified by RFC 4253, section 4.2.
func readVersion(r io.Reader) (versionString []byte, ok bool) {
versionString = make([]byte, 0, 64)
seenCR := false
func readVersion(r io.Reader) ([]byte, os.Error) {
versionString := make([]byte, 0, 64)
var ok, seenCR bool
var buf [1]byte
forEachByte:
for len(versionString) < maxVersionStringBytes {
_, err := io.ReadFull(r, buf[:])
if err != nil {
return
return nil, err
}
b := buf[0]
......@@ -360,10 +359,10 @@ forEachByte:
versionString = append(versionString, b)
}
if ok {
// We need to remove the CR from versionString
versionString = versionString[:len(versionString)-1]
if !ok {
return nil, os.NewError("failed to read version string")
}
return
// We need to remove the CR from versionString
return versionString[:len(versionString)-1], nil
}
......@@ -12,9 +12,9 @@ import (
func TestReadVersion(t *testing.T) {
buf := []byte(serverVersion)
result, ok := readVersion(bufio.NewReader(bytes.NewBuffer(buf)))
if !ok {
t.Error("readVersion didn't read version correctly")
result, err := readVersion(bufio.NewReader(bytes.NewBuffer(buf)))
if err != nil {
t.Errorf("readVersion didn't read version correctly: %s", err)
}
if !bytes.Equal(buf[:len(buf)-2], result) {
t.Error("version read did not match expected")
......@@ -23,7 +23,7 @@ func TestReadVersion(t *testing.T) {
func TestReadVersionTooLong(t *testing.T) {
buf := make([]byte, maxVersionStringBytes+1)
if _, ok := readVersion(bufio.NewReader(bytes.NewBuffer(buf))); ok {
if _, err := readVersion(bufio.NewReader(bytes.NewBuffer(buf))); err == nil {
t.Errorf("readVersion consumed %d bytes without error", len(buf))
}
}
......@@ -31,7 +31,7 @@ func TestReadVersionTooLong(t *testing.T) {
func TestReadVersionWithoutCRLF(t *testing.T) {
buf := []byte(serverVersion)
buf = buf[:len(buf)-1]
if _, ok := readVersion(bufio.NewReader(bytes.NewBuffer(buf))); ok {
if _, err := readVersion(bufio.NewReader(bytes.NewBuffer(buf))); err == nil {
t.Error("readVersion did not notice \\n was missing")
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment