Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F133742
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Subscribers
None
View Options
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d1e4909
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.idea
+*~
+*.exe
diff --git a/app.go b/app.go
new file mode 100644
index 0000000..2225ed1
--- /dev/null
+++ b/app.go
@@ -0,0 +1,65 @@
+package sshhop
+
+import (
+ "flag"
+ "log"
+ "golang.org/x/crypto/ssh"
+ "io/ioutil"
+)
+
+
+func(c *Client) Start(){
+
+ //The intermediary server for port binding
+ serverHostname := flag.String("server", "alpine.cse.unr.edu", "Intermediate Server")
+ username := flag.String("username", "user", "Username")
+ privKey := flag.String("privkey", "/nfs/home/user/.ssh/id_rsa", "Private Key")
+
+ var endpoints EndpointsFlag
+ flag.Var(&endpoints,"endpoints", "Local and remote endpoints")
+ flag.Parse()
+
+ if len(endpoints) < 1 {
+ log.Printf("No endpoints defined: %d\n", len(endpoints))
+
+ endpoints = make(EndpointsFlag, 0)
+ endpoints = append(endpoints, "www.cse.unr.edu:22")
+ endpoints = append(endpoints, "www.cse.unr.edu:22")
+ endpoints = append(endpoints, "www.cse.unr.edu:22")
+ }
+
+
+ // 27013
+ serverEndpoint := &Endpoint{
+ Host: *serverHostname,
+ Port: 22,
+ }
+
+ key, err := ioutil.ReadFile(*privKey)
+ if err != nil {
+ log.Fatalf("Unable to read private key: %v", err)
+ }
+
+
+ // Create the Signer for this private key.
+ signer, err := ssh.ParsePrivateKey(key)
+ if err != nil {
+ log.Fatalf("unable to parse private key: %v", err)
+ }
+
+ sshConfig := &ssh.ClientConfig{
+ User: *username,
+ HostKeyCallback: KeyPrint,
+ Auth: []ssh.AuthMethod{
+ ssh.PublicKeys(signer),
+ },
+ }
+
+ tunnel := &SSHtunnel{
+ Config: sshConfig,
+ Server: serverEndpoint,
+ Remote: endpoints,
+ }
+
+ tunnel.Start()
+}
diff --git a/app_test.go b/app_test.go
new file mode 100644
index 0000000..4a09d40
--- /dev/null
+++ b/app_test.go
@@ -0,0 +1,110 @@
+package sshhop
+
+import (
+ "testing"
+ "fmt"
+)
+
+//function
+func TestEndPointString(t *testing.T) {
+ var testend Endpoint
+
+ testend.Host = "localhost"
+ testend.Port = 5555
+
+ // make a string and test what the string should be
+ stringWant := "localhost:5555"
+
+ returnedString := testend.String()
+
+ fmt.Printf("\nstringWant: %s\n\n", stringWant)
+ fmt.Printf("returnedString : %s\n\n", returnedString)
+ // return string == stringwant // success
+}
+
+//function
+func TestEndPointParseString(t *testing.T) {
+ var testRemote, testRemote1 Endpoint
+ var testLocal, testLocal1 Endpoint
+
+
+ // make a string and test what the string should be
+ testLocal, testRemote = ParseEndpointString("5555:motherbrain.unr.edu:5555")
+ testLocal1, testRemote1 = ParseEndpointString("27013:motherbrain.unr.edu:27013")
+
+ fmt.Printf("Local: %s %d\n\n", testLocal.Host, testLocal.Port)
+ fmt.Printf("Remote: %s %d \n\n", testRemote.Host, testRemote.Port)
+
+ fmt.Printf("Local: %s %d\n\n", testLocal1.Host, testLocal1.Port)
+ fmt.Printf("Remote: %s %d \n\n", testRemote1.Host, testRemote1.Port)
+
+ if testLocal.Host != "localhost"{
+ t.Error("Invalid Local EP Hostname")
+ }
+
+ if testLocal.Port != 5555 {
+ t.Error("Invalid Local EP Port")
+ }
+
+ if testRemote.Host != "motherbrain.unr.edu"{
+ t.Error("Invalid remote EP Hostname")
+ }
+
+ if testRemote.Port != 5555 {
+ t.Error("Invalid remote EP Port")
+ }
+
+ ////////////////////////////////////////
+
+ if testLocal1.Host != "localhost"{
+ t.Error("Invalid Local EP Hostname")
+ }
+
+ if testLocal1.Port != 27013 {
+ t.Error("Invalid Local EP Port")
+ }
+
+ if testRemote1.Host != "motherbrain.unr.edu"{
+ t.Error("Invalid remote EP Hostname")
+ }
+
+ if testRemote1.Port != 27013 {
+ t.Error("Invalid remote EP Port")
+ }
+ // return string == stringwant // success
+}
+
+func TestEndPointsArray(t *testing.T) {
+
+ //Input
+ testInput := []string{
+ "5555:motherbrain.unr.edu:5555",
+ "27013:motherbrain.unr.edu:27013",
+ }
+ fmt.Printf("Input %v \n\n", testInput)
+
+ //Anticipated output
+ testLocalEndpoints := [2]Endpoint{
+ {Host: "localhost", Port: 5555},
+ {Host: "localhost", Port: 27013},
+ };
+ testRemoteEndpoints := [2]Endpoint{
+ {Host: "motherbrain.unr.edu", Port: 5555},
+ {Host: "motherbrain.unr.edu", Port: 27013},
+ };
+
+ for r,_ := range(testLocalEndpoints){
+ fmt.Printf("Test Local: %v\n\n", testLocalEndpoints[r])
+ fmt.Printf("Test Remote: %v\n\n", testRemoteEndpoints[r])
+ }
+
+ // try to match the testInput with the anticipated output by passing the test,
+ // append the input to array
+ myLocalEndpoints, myRemoteEndpoints := ParseEndpointsFromArray(testInput);
+
+ //Real output
+ for r,_ := range(myLocalEndpoints){
+ fmt.Printf("Local: %v\n\n", myLocalEndpoints[r])
+ fmt.Printf("Remote: %v\n\n", myRemoteEndpoints[r])
+ }
+}
diff --git a/bin/main.exe.manifest b/bin/main.exe.manifest
new file mode 100644
index 0000000..c4d6dd4
--- /dev/null
+++ b/bin/main.exe.manifest
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
+ </dependentAssembly>
+ </dependency>
+ </assembly>
\ No newline at end of file
diff --git a/bin/main.go b/bin/main.go
new file mode 100644
index 0000000..3ef7105
--- /dev/null
+++ b/bin/main.go
@@ -0,0 +1,15 @@
+package main
+
+import (
+ "sshhop"
+ "fmt"
+)
+
+
+func main() {
+ var ep = &sshhop.Endpoint{};
+ var sshClient = &sshhop.Client{};
+
+ sshClient.Start()
+ fmt.Printf("%v", ep)
+}
diff --git a/credentials.go b/credentials.go
new file mode 100644
index 0000000..4d88741
--- /dev/null
+++ b/credentials.go
@@ -0,0 +1,7 @@
+package sshhop
+
+
+type Credentials struct {
+ Username string
+ Password string
+}
diff --git a/endpoint.go b/endpoint.go
new file mode 100644
index 0000000..ce8bb98
--- /dev/null
+++ b/endpoint.go
@@ -0,0 +1,53 @@
+package sshhop
+
+import (
+ "encoding/base64"
+ "fmt"
+ "golang.org/x/crypto/ssh"
+ "net"
+ "strconv"
+ "strings"
+)
+
+type Client struct {
+}
+
+type Endpoint struct {
+ Host string
+ Port int
+}
+
+func KeyPrint(dialAddr string, addr net.Addr, key ssh.PublicKey) error {
+ fmt.Printf("%s %s %s\n", strings.Split(dialAddr, ":")[0], key.Type(), base64.StdEncoding.EncodeToString(key.Marshal()))
+ return nil
+}
+
+func (endpoint *Endpoint) String() string {
+ return fmt.Sprintf("%s:%d", endpoint.Host, endpoint.Port)
+}
+
+func ParseEndpointString(endpointString string) (localEp Endpoint, remoteEp Endpoint) {
+
+ localEp.Host = "localhost"
+
+ buffer := strings.Split(endpointString, ":")
+ localEp.Port, _ = strconv.Atoi(buffer[0])
+
+ remoteEp.Host = buffer[1]
+ remoteEp.Port, _ = strconv.Atoi(buffer[2])
+
+ return localEp, remoteEp
+}
+
+func ParseEndpointsFromArray(endpointStruct []string) ([]Endpoint, []Endpoint) {
+ localEndpoints := make([]Endpoint, 0)
+ remoteEndpoints := make([]Endpoint, 0)
+
+ for _, e := range endpointStruct {
+ localE, remoteE := ParseEndpointString(e)
+ localEndpoints = append(localEndpoints, localE)
+ remoteEndpoints = append(remoteEndpoints, remoteE)
+ }
+
+ return localEndpoints, remoteEndpoints
+}
diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go
new file mode 100644
index 0000000..78cc77b
--- /dev/null
+++ b/endpoint/endpoint.go
@@ -0,0 +1,85 @@
+package endpoint
+
+import (
+
+ "fmt"
+ "io"
+
+ "golang.org/x/crypto/ssh"
+
+
+ "net"
+)
+
+type Endpoint struct {
+ Host string
+ Port int
+}
+
+func (endpoint *Endpoint) String() string {
+ return fmt.Sprintf("%s:%d", endpoint.Host, endpoint.Port)
+}
+
+type SSHtunnel struct {
+ Local *Endpoint
+ Server *Endpoint
+ Remote *Endpoint
+
+ Config *ssh.ClientConfig
+ ServerConnection *ssh.ServerConfig
+}
+
+// type localEndpoint []Endpoint
+//
+// type remoteEndpoint []Endpoint
+
+
+//func (index *arrayFlags) Set
+
+// var testend Endpoint
+//
+// testend.Host = "localhost"
+// testend.Port = "5"
+
+func (tunnel *SSHtunnel) Start() error {
+ for {
+ listener, err := net.Listen("tcp", tunnel.Local.String())
+ if err != nil {
+ return err
+ }
+ defer listener.Close()
+
+ for {
+ conn, err := listener.Accept()
+ if err != nil {
+ return err
+ }
+ go tunnel.forward(conn)
+ }
+}
+ }
+
+
+func (tunnel *SSHtunnel) forward(localConn net.Conn) {
+ serverConn, err := ssh.Dial("tcp", tunnel.Server.String(), tunnel.Config)
+ if err != nil {
+ fmt.Printf("Server dial error: %s\n", err)
+ return
+ }
+
+ remoteConn, err := serverConn.Dial("tcp", tunnel.Remote.String())
+ if err != nil {
+ fmt.Printf("Remote dial error: %s\n", err)
+ return
+ }
+
+ copyConn:=func(writer, reader net.Conn) {
+ _, err:= io.Copy(writer, reader)
+ if err != nil {
+ fmt.Printf("io.Copy error: %s", err)
+ }
+ }
+
+ go copyConn(localConn, remoteConn)
+ go copyConn(remoteConn, localConn)
+}
diff --git a/endpoint/endpoint_test.go b/endpoint/endpoint_test.go
new file mode 100644
index 0000000..d398c85
--- /dev/null
+++ b/endpoint/endpoint_test.go
@@ -0,0 +1,37 @@
+package endpoint
+
+import (
+ "testing"
+ "fmt"
+ "sshtunnel"
+)
+
+//function
+func TestEndPointString(t *testing.T) {
+ var testend sshtunnel.Endpoint
+
+ testend.Host = "localhost"
+ testend.Port = 5555
+
+ // make a string and test what the string should be
+ stringWant := "localhost:5555"
+
+ returnedString := testend.String()
+
+ fmt.Printf("stringWant: %s\n", stringWant)
+ fmt.Printf("returnedString : %s\n", returnedString)
+ // return string == stringwant // success
+}
+
+//function
+func TestEndPointParseString(t *testing.T) {
+ var testRemote sshtunnel.Endpoint
+ var testLocal sshtunnel.Endpoint
+
+ // make a string and test what the string should be
+ testLocal, testRemote = sshtunnel.ParseEndpointString("5555:motherbrain.unr.edu:5555")
+
+ fmt.Printf("Local: %s %s\n", testLocal.Host, testLocal.Port)
+ fmt.Printf("Remote: %s %s \n", testRemote.Host, testRemote.Port)
+ // return string == stringwant // success
+}
diff --git a/endpoints_flag.go b/endpoints_flag.go
new file mode 100644
index 0000000..c8c5ad1
--- /dev/null
+++ b/endpoints_flag.go
@@ -0,0 +1,12 @@
+package sshhop
+
+type EndpointsFlag []string
+
+func (i *EndpointsFlag) String() string {
+ return "my string representation"
+}
+
+func (i *EndpointsFlag) Set(value string) error {
+ *i = append(*i, value)
+ return nil
+}
diff --git a/terminal/channel.go b/terminal/channel.go
new file mode 100644
index 0000000..2480aed
--- /dev/null
+++ b/terminal/channel.go
@@ -0,0 +1,12 @@
+package main
+
+import (
+ "fmt"
+)
+
+func sum(s []int, c chan int) {
+ sumOfNum := 0
+ for _, v := range s {
+
+ }
+}
diff --git a/tunnel.go b/tunnel.go
new file mode 100644
index 0000000..8c5467e
--- /dev/null
+++ b/tunnel.go
@@ -0,0 +1,83 @@
+package sshhop
+
+import (
+ "fmt"
+ "golang.org/x/crypto/ssh"
+ "golang.org/x/crypto/ssh/agent"
+ "log"
+ "net"
+ "os"
+ "sync"
+ "bytes"
+)
+
+type SSHtunnel struct {
+ Server *Endpoint
+ Remote []string
+ ErrorChans []chan error
+ ServerClient *ssh.Client
+ Config *ssh.ClientConfig
+ ServerConnection *ssh.ServerConfig
+ TargetClients []*ssh.Client
+ sync.Mutex
+}
+
+func (tunnel *SSHtunnel) Start() error {
+ var err error
+
+ tunnel.ErrorChans = make([]chan error, len(tunnel.Remote))
+ tunnel.TargetClients = make([]*ssh.Client, 0)
+
+ tunnel.ServerClient, err = ssh.Dial("tcp", tunnel.Server.String(), tunnel.Config)
+ if err != nil {
+ fmt.Printf("Server dial error: %s\n", err)
+ os.Exit(1)
+ return err
+ }
+
+ //
+ for i, _ := range tunnel.Remote {
+
+ conn, err := tunnel.ServerClient.Dial("tcp", tunnel.Remote[i])
+ if err != nil {
+ return err
+ }
+
+ ncc, chans, reqs, err := ssh.NewClientConn(conn, tunnel.Remote[i], tunnel.Config)
+ if err != nil {
+ log.Fatalf("New client connection error: %s\n", err)
+ return err
+ }
+ client := ssh.NewClient(ncc, chans, reqs)
+ //Keep clients in array
+ tunnel.TargetClients = append(tunnel.TargetClients, client)
+
+ //Execute a command
+ //Ideally this would be done in a go routine for concurrency
+ session, _ := client.NewSession()
+ defer session.Close()
+
+ var stdoutBuf bytes.Buffer
+ session.Stdout = &stdoutBuf
+ session.Run("hostname")
+
+ log.Printf("Target Hostname: %s", stdoutBuf.String())
+
+ }
+
+ return err
+
+}
+
+func SSHAgent() ssh.AuthMethod {
+ if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
+ return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)
+ }
+ return nil
+}
+
+func check(e error) {
+ if e != nil {
+ panic(e)
+ }
+}
diff --git a/windows_ui.go b/windows_ui.go
new file mode 100644
index 0000000..a3d7b4a
--- /dev/null
+++ b/windows_ui.go
@@ -0,0 +1,71 @@
+// +build windows,!linux
+
+package sshhop
+
+import (
+ . "github.com/lxn/walk/declarative"
+ "github.com/lxn/walk"
+)
+
+type PasswordForm struct {
+ Credentials *Credentials
+
+}
+
+func NewPasswordForm() *PasswordForm {
+
+ return &PasswordForm{}
+}
+
+func (p *PasswordForm) Show(){
+ var mainWindow *walk.MainWindow
+ var usernameLE, passwordLE *walk.LineEdit
+ p.Credentials = &Credentials{Username:"Test"}
+
+ MainWindow{
+ AssignTo: &mainWindow,
+ Title: "Login",
+ MinSize: Size{250, 150},
+ Layout: VBox{},
+ Children: []Widget{
+ HSplitter{
+ Children: []Widget{
+ Label{ Text: "Username"},
+ LineEdit{ AssignTo: &usernameLE },
+
+ },
+ },
+ HSplitter{
+ Children: []Widget{
+ Label{ Text: "Password"},
+ LineEdit{PasswordMode: true,
+ AssignTo: &passwordLE,
+ OnKeyDown: func(key walk.Key) {
+ if key == walk.KeyReturn {
+ p.Credentials.Username = usernameLE.Text()
+ p.Credentials.Password = passwordLE.Text()
+ mainWindow.Close()
+ }
+ },
+ },
+
+ },
+ },
+ PushButton{
+ Text: "Login",
+ OnClicked: func() {
+ p.Credentials.Username = usernameLE.Text()
+ p.Credentials.Password = passwordLE.Text()
+ mainWindow.Close()
+ },
+ },
+ PushButton{
+ Text: "Cancel",
+ OnClicked: func() {
+ mainWindow.Close()
+ },
+ },
+
+ },
+ }.Run()
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 1:01 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14650
Default Alt Text
(14 KB)
Attached To
rSH sshhop
Event Timeline
Log In to Comment