|
@@ -8,6 +8,7 @@ import (
|
|
"os/exec"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"path/filepath"
|
|
"runtime"
|
|
"runtime"
|
|
|
|
+ "strconv"
|
|
|
|
|
|
"imuslab.com/zoraxy/mod/reverseproxy"
|
|
"imuslab.com/zoraxy/mod/reverseproxy"
|
|
"imuslab.com/zoraxy/mod/utils"
|
|
"imuslab.com/zoraxy/mod/utils"
|
|
@@ -21,13 +22,50 @@ import (
|
|
online ssh terminal
|
|
online ssh terminal
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+type Manager struct {
|
|
|
|
+ StartingPort int
|
|
|
|
+ ReservedPorts map[string]int
|
|
|
|
+ Instances []*Instance
|
|
|
|
+}
|
|
|
|
+
|
|
type Instance struct {
|
|
type Instance struct {
|
|
ExecPath string
|
|
ExecPath string
|
|
|
|
+ conn *reverseproxy.ReverseProxy //HTTP proxy
|
|
|
|
+ tty *exec.Cmd //SSH connection ported to web interface
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func NewSSHProxyManager() *Manager {
|
|
|
|
+ return &Manager{
|
|
|
|
+ StartingPort: 14810,
|
|
|
|
+ ReservedPorts: map[string]int{},
|
|
|
|
+ Instances: []*Instance{},
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//Get the next free port in the list
|
|
|
|
+func (m *Manager) GetNextPort() int {
|
|
|
|
+ nextPort := m.StartingPort
|
|
|
|
+ for {
|
|
|
|
+ if _, exists := m.ReservedPorts[strconv.Itoa(nextPort)]; !exists {
|
|
|
|
+ if !isPortInUse(nextPort) {
|
|
|
|
+ return nextPort
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if nextPort == 65534 {
|
|
|
|
+ return -1
|
|
|
|
+ }
|
|
|
|
+ nextPort++
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-func NewSSHProxy(binaryRoot string) (*Instance, error) {
|
|
|
|
|
|
+func (m *Manager) NewSSHProxy(binaryRoot string) (*Instance, error) {
|
|
//Check if the binary exists in system/gotty/
|
|
//Check if the binary exists in system/gotty/
|
|
binary := "gotty_" + runtime.GOOS + "_" + runtime.GOARCH
|
|
binary := "gotty_" + runtime.GOOS + "_" + runtime.GOARCH
|
|
|
|
+
|
|
|
|
+ if runtime.GOOS == "windows" {
|
|
|
|
+ binary = binary + ".exe"
|
|
|
|
+ }
|
|
execPath := filepath.Join(binaryRoot, binary)
|
|
execPath := filepath.Join(binaryRoot, binary)
|
|
|
|
|
|
if !utils.FileExists(execPath) {
|
|
if !utils.FileExists(execPath) {
|
|
@@ -47,22 +85,31 @@ func NewSSHProxy(binaryRoot string) (*Instance, error) {
|
|
}
|
|
}
|
|
|
|
|
|
//Create a new Connection to target address
|
|
//Create a new Connection to target address
|
|
-func (i *Instance) CreateNewConnection(ipaddr string) (*reverseproxy.ReverseProxy, error) {
|
|
|
|
|
|
+func (i *Instance) CreateNewConnection(listenPort int, remoteIpAddr string, remotePort int) error {
|
|
|
|
+
|
|
//Create a gotty instance
|
|
//Create a gotty instance
|
|
- cmd := exec.Command(i.ExecPath, "-p", "8080", "-w", "ssh", ipaddr)
|
|
|
|
|
|
+ cmd := exec.Command(i.ExecPath, "-w", "-p", strconv.Itoa(listenPort), "-a", "127.0.0.1", "--once", "--ws-origin", `\w*`, "ssh", remoteIpAddr, "-p", strconv.Itoa(remotePort))
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Stderr = os.Stderr
|
|
- cmd.Run()
|
|
|
|
|
|
+ go func() {
|
|
|
|
+ cmd.Run()
|
|
|
|
+ }()
|
|
|
|
+ i.tty = cmd
|
|
|
|
+
|
|
//Create a new proxy agent for this root
|
|
//Create a new proxy agent for this root
|
|
- path, err := url.Parse(ipaddr)
|
|
|
|
|
|
+ path, err := url.Parse("http://127.0.0.1:" + strconv.Itoa(listenPort))
|
|
if err != nil {
|
|
if err != nil {
|
|
- return nil, err
|
|
|
|
|
|
+ return err
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //Create a new proxy object to the proxy
|
|
proxy := reverseproxy.NewReverseProxy(path)
|
|
proxy := reverseproxy.NewReverseProxy(path)
|
|
- return proxy, nil
|
|
|
|
-}
|
|
|
|
|
|
+ i.conn = proxy
|
|
|
|
|
|
-func HandleWebSSHConnection(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
|
|
|
|
+//Bridge the remote connection to reverse proxy
|
|
|
|
+func (i *Instance) BridgeConnection(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
+ return i.conn.ProxyHTTP(w, r)
|
|
}
|
|
}
|