Page MenuHomePhabricator

No OneTemporary

diff --git a/app.go b/app.go
index c8a3ec1..606a942 100644
--- a/app.go
+++ b/app.go
@@ -1,82 +1,91 @@
package sshtunnel
import (
"flag"
"log"
"golang.org/x/crypto/ssh"
"sync"
"os/exec"
+ "os"
+ "io"
)
-
-func(c *Client) Start(){
+func (c *Client) Start() {
var wg sync.WaitGroup
//The intermediary server for port binding
serverHostname := flag.String("server", "ubuntu.cse.unr.edu", "a string")
execPath := flag.String("exec", "", "a binary to execute after connecting.")
- //TODO Add logfile
- //TODO Add exec - Executes an application.
+ logFile := flag.String("log", "log.txt", "logfile location")
+
+ lf, err := os.OpenFile(*logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+ if err != nil {
+ log.Fatalf("error opening file: %v", err)
+ }
+ defer lf.Close()
+
+ mw := io.MultiWriter(os.Stdout, lf)
+ log.SetOutput(mw)
- var endpoints EndpointsFlag
- flag.Var(&endpoints,"endpoints", "Local and remote endpoints")
+ var endpoints EndpointsFlag
+ flag.Var(&endpoints, "endpoints", "Local and remote endpoints")
flag.Parse()
- if len(endpoints) < 1 {
+ if len(endpoints) < 1 {
log.Printf("No endpoints defined: %d\n", len(endpoints))
endpoints = make(EndpointsFlag, 0)
- endpoints = append(endpoints, "5555:172.28.128.230:5555") // MATLAB
- endpoints = append(endpoints, "25734:172.28.128.230:25734") // SolidWorks
- endpoints = append(endpoints, "25735:172.28.128.230:25735") // SolidWorks
- endpoints = append(endpoints, "7788:134.197.20.21:7788") // MATHCAD
+ endpoints = append(endpoints, "5555:172.28.128.230:5555") // MATLAB
+ endpoints = append(endpoints, "25734:172.28.128.230:25734") // SolidWorks
+ endpoints = append(endpoints, "25735:172.28.128.230:25735") // SolidWorks
+ endpoints = append(endpoints, "7788:134.197.20.21:7788") // MATHCAD
}
- localE, remoteE:= ParseEndpointsFromArray(endpoints)
+ localE, remoteE := ParseEndpointsFromArray(endpoints)
log.Printf("localE: %v remoteE: %v", localE, remoteE)
// 27013
serverEndpoint := &Endpoint{
Host: *serverHostname,
Port: 22,
}
- log.Printf("Endpoints: %v \nserverEndpoint: %v\n", endpoints, serverEndpoint)
+ log.Printf("Endpoints: %v serverEndpoint: %v\n", endpoints, serverEndpoint)
//log.Printf("%v %v", serverEndpoint)
//credChan := make(chan Credentials)
- var passwordForm= NewPasswordForm()
+ var passwordForm = NewPasswordForm()
//passwordForm.SetChan(credChan)
passwordForm.Show();
-
credentials := passwordForm.Credentials
log.Printf("Connecting to %s, User: %s ", *serverHostname, credentials.Username)
sshConfig := &ssh.ClientConfig{
- User: credentials.Username,
- HostKeyCallback: KeyPrint,
- Auth: []ssh.AuthMethod{
- ssh.Password(credentials.Password),
- },
- }
+ User: credentials.Username,
+ HostKeyCallback: KeyPrint,
+ Auth: []ssh.AuthMethod{
+ ssh.Password(credentials.Password),
+ },
+ }
tunnel := &SSHtunnel{
- Config: sshConfig,
- Local: localE,
- Server: serverEndpoint,
- Remote: remoteE,
- }
+ Config: sshConfig,
+ Local: localE,
+ Server: serverEndpoint,
+ Remote: remoteE,
+ }
wg.Add(1)
- go func(){
+ go func() {
defer wg.Done()
tunnel.Start()
}();
-
- cmd := exec.Command(*execPath)
- err := cmd.Start()
- if err != nil {
- log.Fatal(err)
+ if len(*execPath) > 0 {
+ cmd := exec.Command(*execPath)
+ err := cmd.Start()
+ if err != nil {
+ log.Fatal(err)
+ }
}
wg.Wait()
}
diff --git a/bin/main.go b/bin/main.go
index 4de2ca6..cb0ea05 100644
--- a/bin/main.go
+++ b/bin/main.go
@@ -1,15 +1,13 @@
package main
import (
"sshtunnel"
"fmt"
)
-
func main() {
var ep = &sshtunnel.Endpoint{};
var sshClient = &sshtunnel.Client{};
-
sshClient.Start()
fmt.Printf("%v", ep)
}
diff --git a/endpoint.go b/endpoint.go
index 1e2acd8..16b5388 100644
--- a/endpoint.go
+++ b/endpoint.go
@@ -1,55 +1,53 @@
package sshtunnel
import (
- "strings"
- "net"
- "golang.org/x/crypto/ssh"
- "fmt"
- "strconv"
- "encoding/base64"
+ "strings"
+ "net"
+ "golang.org/x/crypto/ssh"
+ "fmt"
+ "strconv"
+ "encoding/base64"
)
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){
+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) {
+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)
- }
+ for _, e := range endpointStruct {
+ localE, remoteE := ParseEndpointString(e)
+ localEndpoints = append(localEndpoints, localE)
+ remoteEndpoints = append(remoteEndpoints, remoteE)
+ }
- return localEndpoints, remoteEndpoints
+ return localEndpoints, remoteEndpoints
}
diff --git a/tunnel.go b/tunnel.go
index e512f46..5e384eb 100644
--- a/tunnel.go
+++ b/tunnel.go
@@ -1,138 +1,158 @@
package sshtunnel
import (
"net"
- "golang.org/x/crypto/ssh"
- "golang.org/x/crypto/ssh/agent"
- "fmt"
- "io"
- "os"
- "log"
+ "golang.org/x/crypto/ssh"
+ "golang.org/x/crypto/ssh/agent"
+ "fmt"
+ "io"
+ "os"
+ "log"
"sync"
"time"
)
type SSHtunnel struct {
- Local []Endpoint
- Server *Endpoint
- Remote []Endpoint
- ErrorChans []chan error
- ServerClient *ssh.Client
- Config *ssh.ClientConfig
+ Local []Endpoint
+ Server *Endpoint
+ Remote []Endpoint
+ ErrorChans []chan error
+ ServerClient *ssh.Client
+ Config *ssh.ClientConfig
ServerConnection *ssh.ServerConfig
- ExecPath string
+ ExecPath string
sync.Mutex
}
+func (tunnel *SSHtunnel) Listen(localE Endpoint, remoteE Endpoint, errorChan chan error) {
+ log.Printf("LocalEndpoint: %v, RemoteEndpoint: %v", localE, remoteE)
+ listener, err := net.Listen("tcp", localE.String())
+ if err != nil {
+ return
+ }
-func(tunnel *SSHtunnel) Listen( localE Endpoint, remoteE Endpoint, errorChan chan error) {
-
-
- log.Printf("LocalEndpoint: %v, RemoteEndpoint: %v", localE, remoteE)
- listener, err := net.Listen("tcp", localE.String())
- if err != nil {
- return
- }
-
- for {
- conn, err := listener.Accept()
+ for {
+ conn, err := listener.Accept()
- if err != nil {
- log.Println("Cannot listen.")
- errorChan <- err
- }
+ if err != nil {
+ log.Println("Cannot listen.")
+ errorChan <- err
+ }
- defer listener.Close()
+ defer listener.Close()
- log.Printf("Localhost listen %s, Remote Connection: %s \n", localE.String(), remoteE.String())
- go tunnel.forward(conn, remoteE)
- }
+ log.Printf("Localhost listen %s, Remote Connection: %s \n", localE.String(), remoteE.String())
+ go tunnel.forward(conn, remoteE)
+ }
}
func (tunnel *SSHtunnel) Start() error {
var err error
- tunnel.ErrorChans = make([]chan error, len(tunnel.Local))
+ tunnel.ErrorChans = make([]chan error, len(tunnel.Local))
//
tunnel.ServerClient, err = ssh.Dial("tcp", tunnel.Server.String(), tunnel.Config)
if err != nil {
fmt.Printf("Server dial error: %s\n", err)
//log.Println("Sever dial error occurred. No Internet connection. Program exited.")
- // if err == "ssh: handshake failed: ssh: unable to authenticate, attempted methods [password none], no supported methods remain" {
- // fmt.Println(" Incorrect Password entered.")
+ // if err == "ssh: handshake failed: ssh: unable to authenticate, attempted methods [password none], no supported methods remain" {
+ // fmt.Println(" Incorrect Password entered.")
os.Exit(1)
return err
}
-
-
+ //Keep alive
+ done := make(chan bool)
+ go tunnel.keepalive(done)
//
- for i, _ := range tunnel.Local {
+ for i, _ := range tunnel.Local {
- //defer listener.Close()
- log.Printf("Main - LocalEndpoint: %v, RemoteEndpoint: %v", tunnel.Local[i], tunnel.Remote[i])
- go tunnel.Listen(tunnel.Local[i], tunnel.Remote[i], tunnel.ErrorChans[i])
- }
+ //defer listener.Close()
+ log.Printf("Main - LocalEndpoint: %v, RemoteEndpoint: %v", tunnel.Local[i], tunnel.Remote[i])
+ go tunnel.Listen(tunnel.Local[i], tunnel.Remote[i], tunnel.ErrorChans[i])
+ }
- for {
- for _, c := range tunnel.ErrorChans {
- select {
+ for {
+ for _, c := range tunnel.ErrorChans {
+ select {
case msg := <-c:
log.Printf("\n in tunnel.errorschans : %v", msg)
- // case msg2:= <- done:
- // log.Printf("%v", msg2)
- // os.Exit(1)
- default:
- //fmt.Println("No message received")
+ // case msg2:= <- done:
+ // log.Printf("%v", msg2)
+ // os.Exit(1)
+ default:
+ //fmt.Println("No message received")
}
}
- time.Sleep(time.Second * 1)
+ time.Sleep(time.Second * 1)
//TODO run ExecPath
}
- return err
+ return err
+
+}
+
+func (tunnel *SSHtunnel) keepalive(done chan bool) {
+ for {
+ // Create a session. It is one session per command.
+ session, err := tunnel.ServerClient.NewSession()
+ if err != nil {
+ log.Print("Unable to open keep alive session.")
+ } else {
+ log.Print("Keep alive session opened.")
+ }
+
+ session.Close()
+
+ select {
+ case message := <-done:
+ if message == true {
+ break
+ }
+ default:
+ }
+ time.Sleep(20000 * time.Millisecond)
+ }
}
//TODO refactor to accept remoteEndpoint
func (tunnel *SSHtunnel) forward(localConn net.Conn, remoteEndpoint Endpoint) {
var err error
+ log.Printf("Connect with client. %s \n", remoteEndpoint.String())
+ remoteConn, err := tunnel.ServerClient.Dial("tcp", remoteEndpoint.String())
+ if err != nil {
+ fmt.Printf("Remote dial error: %s\n", err)
+ log.Println("Remote dial error occurred. Trying to establish a new server connection.")
+ tunnel.ServerClient, err = ssh.Dial("tcp", tunnel.Server.String(), tunnel.Config)
+ return
+ }
+ log.Printf("Remote connection: %v", remoteConn)
-
- log.Printf("Connect with client. %s \n", remoteEndpoint.String())
- remoteConn, err := tunnel.ServerClient.Dial("tcp", remoteEndpoint.String())
+ copyConn := func(writer, reader net.Conn) {
+ _, err := io.Copy(writer, reader)
if err != nil {
- fmt.Printf("Remote dial error: %s\n", err)
- log.Println("Remote dial error occurred. Trying to establish a new server connection.")
- tunnel.ServerClient, err = ssh.Dial("tcp", tunnel.Server.String(), tunnel.Config)
- return
- }
- log.Printf("Remote connection: %v", remoteConn)
-
- copyConn:=func(writer, reader net.Conn) {
- _, err:= io.Copy(writer, reader)
- if err != nil {
- log.Printf("%s io.Copy error: %s \n", remoteEndpoint.String(), err)
- }
+ log.Printf("%s io.Copy error: %s \n", remoteEndpoint.String(), err)
}
+ }
- go copyConn(localConn, remoteConn)
- go copyConn(remoteConn, localConn)
+ go copyConn(localConn, remoteConn)
+ go copyConn(remoteConn, localConn)
}
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
index 0037dcb..742969d 100644
--- a/windows_ui.go
+++ b/windows_ui.go
@@ -1,71 +1,67 @@
// +build windows,!linux
package sshtunnel
import (
. "github.com/lxn/walk/declarative"
"github.com/lxn/walk"
)
type PasswordForm struct {
Credentials *Credentials
-
}
func NewPasswordForm() *PasswordForm {
return &PasswordForm{}
}
-func (p *PasswordForm) Show(){
+func (p *PasswordForm) Show() {
var mainWindow *walk.MainWindow
var usernameLE, passwordLE *walk.LineEdit
- p.Credentials = &Credentials{Username:"Test"}
+ p.Credentials = &Credentials{Username: "Test"}
MainWindow{
AssignTo: &mainWindow,
- Title: "Login",
- MinSize: Size{250, 150},
- Layout: VBox{},
+ Title: "Login",
+ MinSize: Size{250, 150},
+ Layout: VBox{},
Children: []Widget{
HSplitter{
Children: []Widget{
- Label{ Text: "Username"},
- LineEdit{ AssignTo: &usernameLE },
-
+ Label{Text: "Username"},
+ LineEdit{AssignTo: &usernameLE},
},
},
HSplitter{
Children: []Widget{
- Label{ Text: "Password"},
+ 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

Mime Type
text/x-diff
Expires
Sun, Apr 6, 12:30 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15399
Default Alt Text
(13 KB)

Event Timeline