forked from maxhawkins/easyssh
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bf216fa
commit 7308727
Showing
10 changed files
with
1,341 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package easyssh | ||
|
||
import ( | ||
"log" | ||
"net" | ||
|
||
"golang.org/x/crypto/ssh" | ||
) | ||
|
||
// Client wraps an SSH Client | ||
type Client struct { | ||
*ssh.Client | ||
} | ||
|
||
// Dial starts an ssh connection to the provided server | ||
func Dial(network, addr string, config *ssh.ClientConfig) (*Client, error) { | ||
c, err := ssh.Dial(network, addr, config) | ||
return &Client{c}, err | ||
} | ||
|
||
// NewClient returns a new SSH Client. | ||
func NewClient(c ssh.Conn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request) *Client { | ||
|
||
client := ssh.NewClient(c, chans, reqs) | ||
return &Client{client} | ||
|
||
} | ||
|
||
// LocalForward performs a port forwarding over the ssh connection - ssh -L. Client will bind to the local address, and will tunnel those requests to host addr | ||
func (c *Client) LocalForward(laddr, raddr *net.TCPAddr) error { | ||
|
||
ln, err := net.ListenTCP("tcp", laddr) //tie to the client connection | ||
if err != nil { | ||
println(err.Error()) | ||
return err | ||
} | ||
log.Println("Listening on address: ", ln.Addr().String()) | ||
|
||
quit := make(chan bool) | ||
|
||
go func() { // Handle incoming connections on this new listener | ||
for { | ||
select { | ||
case <-quit: | ||
|
||
return | ||
default: | ||
conn, err := ln.Accept() | ||
if err != nil { // Unable to accept new connection - listener likely closed | ||
continue | ||
} | ||
go func(conn net.Conn) { | ||
conn2, err := c.DialTCP("tcp", laddr, raddr) | ||
|
||
if err != nil { | ||
return | ||
} | ||
go func(conn, conn2 net.Conn) { | ||
|
||
close := func() { | ||
conn.Close() | ||
conn2.Close() | ||
|
||
} | ||
|
||
go CopyReadWriters(conn, conn2, close) | ||
|
||
}(conn, conn2) | ||
|
||
}(conn) | ||
} | ||
|
||
} | ||
}() | ||
|
||
c.Wait() | ||
|
||
ln.Close() | ||
quit <- true | ||
|
||
return nil | ||
} | ||
|
||
// RemoteForward forwards a remote port - ssh -R | ||
func (c *Client) RemoteForward(remote, local string) error { | ||
ln, err := c.Listen("tcp", remote) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
quit := make(chan bool) | ||
|
||
go func() { // Handle incoming connections on this new listener | ||
for { | ||
select { | ||
case <-quit: | ||
|
||
return | ||
default: | ||
conn, err := ln.Accept() | ||
if err != nil { // Unable to accept new connection - listener likely closed | ||
continue | ||
} | ||
|
||
conn2, err := net.Dial("tcp", local) | ||
if err != nil { | ||
continue | ||
} | ||
|
||
close := func() { | ||
conn.Close() | ||
conn2.Close() | ||
|
||
} | ||
|
||
go CopyReadWriters(conn, conn2, close) | ||
|
||
} | ||
|
||
} | ||
}() | ||
|
||
c.Wait() | ||
ln.Close() | ||
quit <- true | ||
|
||
return nil | ||
} | ||
|
||
// HandleOpenChannel requests that the remote end accept a channel request and if accepted, | ||
// passes the newly opened channel and requests to the provided handler | ||
func (c *Client) HandleOpenChannel(channelName string, handler ChannelMultipleRequestsHandler, data ...byte) error { | ||
ch, reqs, err := c.OpenChannel(channelName, data) | ||
if err != nil { | ||
return err | ||
} | ||
handler.HandleMultipleRequests(reqs, c.Conn, channelName, ch) | ||
return nil | ||
} | ||
|
||
// HandleOpenChannelFunc requests that the remote end accept a channel request and if accepted, | ||
// passes the newly opened channel and requests to the provided handler function | ||
func (c *Client) HandleOpenChannelFunc(channelName string, handler ChannelMultipleRequestsHandlerFunc, data ...byte) error { | ||
|
||
return c.HandleOpenChannel(channelName, ChannelMultipleRequestsHandlerFunc(handler), data...) | ||
} |
Oops, something went wrong.