Toby Chui 1 год назад
Родитель
Сommit
60543f445a
5 измененных файлов с 206 добавлено и 21 удалено
  1. 2 0
      api.go
  2. 2 0
      main.go
  3. 121 3
      mod/forwardproxy/forwardproxy.go
  4. 12 10
      start.go
  5. 69 8
      web/components/networktools.html

+ 2 - 0
api.go

@@ -163,6 +163,8 @@ func initAPIs() {
 	authRouter.HandleFunc("/api/tools/smtp/set", HandleSMTPSet)
 	authRouter.HandleFunc("/api/tools/smtp/admin", HandleAdminEmailGet)
 	authRouter.HandleFunc("/api/tools/smtp/test", HandleTestEmailSend)
+	authRouter.HandleFunc("/api/tools/fwdproxy/enable", forwardProxy.HandleToogle)
+	authRouter.HandleFunc("/api/tools/fwdproxy/port", forwardProxy.HandlePort)
 
 	//Account Reset
 	http.HandleFunc("/api/account/reset", HandleAdminAccountResetEmail)

+ 2 - 0
main.go

@@ -17,6 +17,7 @@ import (
 	"imuslab.com/zoraxy/mod/database"
 	"imuslab.com/zoraxy/mod/dynamicproxy/redirection"
 	"imuslab.com/zoraxy/mod/email"
+	"imuslab.com/zoraxy/mod/forwardproxy"
 	"imuslab.com/zoraxy/mod/ganserv"
 	"imuslab.com/zoraxy/mod/geodb"
 	"imuslab.com/zoraxy/mod/info/logger"
@@ -79,6 +80,7 @@ var (
 	acmeHandler        *acme.ACMEHandler       //Handler for ACME Certificate renew
 	acmeAutoRenewer    *acme.AutoRenewer       //Handler for ACME auto renew ticking
 	staticWebServer    *webserv.WebServer      //Static web server for hosting simple stuffs
+	forwardProxy       *forwardproxy.Handler   //HTTP Forward proxy, basically VPN for web browser
 
 	//Helper modules
 	EmailSender      *email.Sender        //Email sender that handle email sending

+ 121 - 3
mod/forwardproxy/forwardproxy.go

@@ -1,19 +1,137 @@
 package forwardproxy
 
 import (
+	"context"
+	"encoding/json"
+	"errors"
+	"log"
 	"net/http"
+	"strconv"
+	"time"
 
-	"imuslab.com/zoraxy/mod/auth"
+	"imuslab.com/zoraxy/mod/database"
+	"imuslab.com/zoraxy/mod/forwardproxy/cproxy"
+	"imuslab.com/zoraxy/mod/info/logger"
+	"imuslab.com/zoraxy/mod/utils"
 )
 
 type ZrFilter struct {
-	auth *auth.AuthAgent
+	//To be implemented
 }
 
 type Handler struct {
-	Port int
+	server  *http.Server
+	handler *http.Handler
+	running bool
+	db      *database.Database
+	logger  *logger.Logger
+	Port    int
+}
+
+func NewForwardProxy(sysdb *database.Database, port int, logger *logger.Logger) *Handler {
+	thisFilter := ZrFilter{}
+	handler := cproxy.New(cproxy.Options.Filter(thisFilter))
+
+	return &Handler{
+		db:      sysdb,
+		server:  nil,
+		handler: &handler,
+		running: false,
+		logger:  logger,
+		Port:    port,
+	}
+}
+
+// Start the forward proxy
+func (h *Handler) Start() error {
+	if h.running {
+		return errors.New("forward proxy already running")
+	}
+	server := &http.Server{Addr: ":" + strconv.Itoa(h.Port), Handler: *h.handler}
+	h.server = server
+
+	go func() {
+		if err := server.ListenAndServe(); err != nil {
+			if err != nil {
+				log.Println(err.Error())
+			}
+		}
+	}()
+
+	h.running = true
+	return nil
+}
+
+// Stop the forward proxy
+func (h *Handler) Stop() error {
+	if h.running && h.server != nil {
+		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+		defer cancel()
+		if err := h.server.Shutdown(ctx); err != nil {
+			return err
+		}
+		h.running = false
+		h.server = nil
+	}
+	return nil
+}
+
+// Update the port number of the forward proxy
+func (h *Handler) UpdatePort(newPort int) error {
+	h.Stop()
+	h.Port = newPort
+	return h.Start()
 }
 
 func (it ZrFilter) IsAuthorized(w http.ResponseWriter, r *http.Request) bool {
 	return true
 }
+
+// Handle port change of the forward proxy
+func (h *Handler) HandlePort(w http.ResponseWriter, r *http.Request) {
+	port, err := utils.PostInt(r, "port")
+	if err != nil {
+		js, _ := json.Marshal(h.Port)
+		utils.SendJSONResponse(w, string(js))
+	} else {
+		//Update the port
+		err = h.UpdatePort(port)
+		if err != nil {
+			utils.SendErrorResponse(w, err.Error())
+			return
+		}
+		h.logger.PrintAndLog("Forward Proxy", "HTTP Forward Proxy port updated to :"+strconv.Itoa(h.Port), nil)
+		h.db.Write("fwdproxy", "port", port)
+		utils.SendOK(w)
+	}
+}
+
+// Handle power toggle of the forward proxys
+func (h *Handler) HandleToogle(w http.ResponseWriter, r *http.Request) {
+	enabled, err := utils.PostBool(r, "enable")
+	if err != nil {
+		//Get the current state of the forward proxy
+		js, _ := json.Marshal(h.running)
+		utils.SendJSONResponse(w, string(js))
+	} else {
+		if enabled {
+			err = h.Start()
+			if err != nil {
+				h.logger.PrintAndLog("Forward Proxy", "Unable to start forward proxy server", err)
+				utils.SendErrorResponse(w, err.Error())
+				return
+			}
+			h.logger.PrintAndLog("Forward Proxy", "HTTP Forward Proxy Started, listening on :"+strconv.Itoa(h.Port), nil)
+		} else {
+			err = h.Stop()
+			if err != nil {
+				h.logger.PrintAndLog("Forward Proxy", "Unable to stop forward proxy server", err)
+				utils.SendErrorResponse(w, err.Error())
+				return
+			}
+			h.logger.PrintAndLog("Forward Proxy", "HTTP Forward Proxy Stopped", nil)
+		}
+		h.db.Write("fwdproxy", "enabled", enabled)
+		utils.SendOK(w)
+	}
+}

+ 12 - 10
start.go

@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"log"
 	"net/http"
 	"os"
@@ -14,7 +13,6 @@ import (
 	"imuslab.com/zoraxy/mod/database"
 	"imuslab.com/zoraxy/mod/dynamicproxy/redirection"
 	"imuslab.com/zoraxy/mod/forwardproxy"
-	"imuslab.com/zoraxy/mod/forwardproxy/cproxy"
 	"imuslab.com/zoraxy/mod/ganserv"
 	"imuslab.com/zoraxy/mod/geodb"
 	"imuslab.com/zoraxy/mod/info/logger"
@@ -222,6 +220,18 @@ func startupSequence() {
 	//Create an analytic loader
 	AnalyticLoader = analytic.NewDataLoader(sysdb, statisticCollector)
 
+	//Create basic forward proxy
+	sysdb.NewTable("fwdproxy")
+	fwdProxyEnabled := false
+	fwdProxyPort := 5587
+	sysdb.Read("fwdproxy", "port", &fwdProxyPort)
+	sysdb.Read("fwdproxy", "enabled", &fwdProxyEnabled)
+	forwardProxy = forwardproxy.NewForwardProxy(sysdb, fwdProxyPort, SystemWideLogger)
+	if fwdProxyEnabled {
+		SystemWideLogger.PrintAndLog("Forward Proxy", "HTTP Forward Proxy Listening on :"+strconv.Itoa(forwardProxy.Port), nil)
+		forwardProxy.Start()
+	}
+
 	/*
 		ACME API
 
@@ -245,12 +255,4 @@ func finalSequence() {
 	//Inject routing rules
 	registerBuildInRoutingRules()
 
-	go func() {
-		fmt.Println("Running debug forward web proxy")
-		thisFilter := forwardproxy.ZrFilter{}
-		handler := cproxy.New(cproxy.Options.Filter(thisFilter))
-		http.ListenAndServe(":8088", handler)
-
-	}()
-
 }

+ 69 - 8
web/components/networktools.html

@@ -91,16 +91,15 @@
         <form class="ui form">
             <div class="field">
                 <label>Listening Port</label>
-                <input type="number" placeholder="5587" value="5587">
-            </div>
-            <div class="field">
-                <div class="ui toggle checkbox">
-                    <input type="checkbox" tabindex="0" class="hidden">
-                    <label>Enable Forward Proxy<br>
-                    <small>Start HTTP Forward Proxy Listener</small></label>
+                <div class="ui action input">
+                    <input id="forwardProxyPort" type="number" placeholder="5587" step="1", min="1024" max="65535" value="5587">
+                    <button onclick="updateForwardProxyPort(); event.preventDefault();" class="ui basic button"><i class="ui green check icon"></i> Apply</button>
                 </div>
             </div>
-            <button class="ui basic circular button"><i class="ui green check icon"></i> Apply Change</button>
+            <div id="forwardProxyButtons" class="field">
+                <button onclick="toggleForwadProxy(true); event.preventDefault();" class="ui basic small green button startBtn"><i class="ui green arrow alternate circle up icon"></i>  Start</button>
+                <button onclick="toggleForwadProxy(false); event.preventDefault();" class="ui basic small red button stopBtn"><i class="ui red minus circle icon"></i>  Stop</button>
+            </div>
         </form>
         <div class="ui divider"></div>
         <h2>Wake On LAN</h2>
@@ -575,6 +574,68 @@ function renderWhoisDomainTable(jsonData) {
 }
 
 
+//Forward Proxy
+function initForwardProxyInfo(){
+    $.get("/api/tools/fwdproxy/enable", function(data){
+        if (data == true){
+            //Disable the start btn
+            $("#forwardProxyButtons").find(".startBtn").addClass('disabled');
+            $("#forwardProxyButtons").find(".stopBtn").removeClass('disabled');
+        }else{
+            $("#forwardProxyButtons").find(".startBtn").removeClass('disabled');
+            $("#forwardProxyButtons").find(".stopBtn").addClass('disabled');
+        }
+    });
+
+    $.get("/api/tools/fwdproxy/port", function(data){
+        $("#forwardProxyPort").val(data);
+    })
+}
+initForwardProxyInfo();
+
+function toggleForwadProxy(enabled){
+    $.ajax({
+        url: "/api/tools/fwdproxy/enable",
+        method: "POST",
+        data: {
+            "enable": enabled
+        },
+        success: function(data){
+            if (data.error != undefined){
+                msgbox(data.error, false);
+            }else{
+                msgbox(`Forward proxy ${enabled?"enabled":"disabled"}`)
+            }
+
+            initForwardProxyInfo();
+        }
+    })
+}
+
+function updateForwardProxyPort(){
+    let newPortNumber = $("#forwardProxyPort").val();
+    if (newPortNumber < 1024 || newPortNumber > 65535){
+        $("#newPortNumber").parent().addClass('error');
+    }else{
+        $("#newPortNumber").parent().removeClass('error');
+    }
+
+    $.ajax({
+        url: "/api/tools/fwdproxy/port",
+        method: "POST",
+        data: {
+            "port": newPortNumber
+        },
+        success: function(data){
+            if (data.error != undefined){
+                msgbox(data.error, false);
+            }
+            msgbox("Forward proxy port updated");
+            initForwardProxyInfo();
+        }
+    });
+}
+
 </script>