|
|
@ -3,7 +3,6 @@ package main
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"code.google.com/p/go.crypto/ssh/terminal"
|
|
|
|
"code.google.com/p/go.crypto/ssh/terminal"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/rsa"
|
|
|
|
"encoding/json"
|
|
|
|
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io"
|
|
|
|
"net"
|
|
|
|
"net"
|
|
|
@ -24,36 +23,50 @@ type ReadWriter struct {
|
|
|
|
io.Writer
|
|
|
|
io.Writer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func connect() {
|
|
|
|
type Client struct {
|
|
|
|
if !terminal.IsTerminal(0) {
|
|
|
|
key *rsa.PrivateKey
|
|
|
|
exit(1, "yeah you have to run this from a tty")
|
|
|
|
host string
|
|
|
|
}
|
|
|
|
port int
|
|
|
|
f, err := os.Open(options.key)
|
|
|
|
nick string
|
|
|
|
|
|
|
|
conn net.Conn
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (c *Client) dial() error {
|
|
|
|
|
|
|
|
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", c.host, c.port))
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
exit(1, "unable to open private key file at %s: %v", options.key, err)
|
|
|
|
return fmt.Errorf("client unable to connect: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
c.conn = conn
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
d1 := json.NewDecoder(f)
|
|
|
|
func (c *Client) handshake() error {
|
|
|
|
var key rsa.PrivateKey
|
|
|
|
r := &Auth{Nick: c.nick, Key: c.key.PublicKey}
|
|
|
|
if err := d1.Decode(&key); err != nil {
|
|
|
|
return c.sendRequest(r)
|
|
|
|
exit(1, "unable to decode key: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", options.host, options.port))
|
|
|
|
func (c *Client) sendRequest(r request) error {
|
|
|
|
if err != nil {
|
|
|
|
return writeRequest(c.conn, r)
|
|
|
|
exit(1, "unable to connect to server at %s:%d: %v", options.host, options.port, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (c *Client) run() {
|
|
|
|
|
|
|
|
if err := c.dial(); err != nil {
|
|
|
|
|
|
|
|
exit(1, "%v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
auth := Auth{
|
|
|
|
defer c.conn.Close()
|
|
|
|
Nick: options.nick,
|
|
|
|
if err := c.handshake(); err != nil {
|
|
|
|
Key: key.PublicKey,
|
|
|
|
exit(1, "%v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
encodeRequest(conn, &auth)
|
|
|
|
c.term()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (c *Client) term() {
|
|
|
|
old, err := terminal.MakeRaw(0)
|
|
|
|
old, err := terminal.MakeRaw(0)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
defer terminal.Restore(0, old)
|
|
|
|
defer terminal.Restore(0, old)
|
|
|
|
|
|
|
|
|
|
|
|
r := &ReadWriter{Reader: os.Stdin, Writer: os.Stdout}
|
|
|
|
r := &ReadWriter{Reader: os.Stdin, Writer: os.Stdout}
|
|
|
|
term := terminal.NewTerminal(r, "> ")
|
|
|
|
term := terminal.NewTerminal(r, "> ")
|
|
|
|
|
|
|
|
|
|
|
@ -67,3 +80,22 @@ func connect() {
|
|
|
|
exit(1, "error on line read: %v", err)
|
|
|
|
exit(1, "error on line read: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func connect() {
|
|
|
|
|
|
|
|
if !terminal.IsTerminal(0) {
|
|
|
|
|
|
|
|
exit(1, "yeah, this only works from a TTY for now, sry.")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
key, err := privateKey()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
exit(1, "unable to open private key file: %v", err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client := &Client{
|
|
|
|
|
|
|
|
key: key,
|
|
|
|
|
|
|
|
host: options.host,
|
|
|
|
|
|
|
|
port: options.port,
|
|
|
|
|
|
|
|
nick: options.nick,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
client.run()
|
|
|
|
|
|
|
|
}
|
|
|
|