Sfoglia il codice sorgente

Added WIP ip ban list

tobychui 3 anni fa
parent
commit
a45f043c94

+ 20 - 8
auth.go

@@ -45,13 +45,11 @@ func AuthInit() {
 	}
 
 	//Register the API endpoints for the authentication UI
-	authAgent.RegisterPublicAPIs(auth.AuthEndpoints{
-		Login:         "/system/auth/login",
-		Logout:        "/system/auth/logout",
-		Register:      "/system/auth/register",
-		CheckLoggedIn: "/system/auth/checkLogin",
-		Autologin:     "/api/auth/login",
-	})
+	http.HandleFunc("/system/auth/login", authAgent.HandleLogin)
+	http.HandleFunc("/system/auth/logout", authAgent.HandleLogout)
+	http.HandleFunc("/system/auth/register", authAgent.HandleRegister)
+	http.HandleFunc("/system/auth/checkLogin", authAgent.CheckLogin)
+	http.HandleFunc("/api/auth/login", authAgent.HandleAutologinTokenLogin)
 
 	authAgent.LoadAutologinTokenFromDB()
 
@@ -73,7 +71,6 @@ func AuthSettingsInit() {
 	adminRouter.HandleFunc("/system/auth/groupdel", authAgent.HandleUserDeleteByGroup)
 
 	//System for logging and displaying login user information
-	//Register FTP Server Setting page
 	registerSetting(settingModule{
 		Name:         "Connection Log",
 		Desc:         "Logs for login attempts",
@@ -85,4 +82,19 @@ func AuthSettingsInit() {
 
 	adminRouter.HandleFunc("/system/auth/logger/index", authAgent.Logger.HandleIndexListing)
 	adminRouter.HandleFunc("/system/auth/logger/list", authAgent.Logger.HandleTableListing)
+
+	//Blacklist Management
+	registerSetting(settingModule{
+		Name:         "Access Control",
+		Desc:         "Prevent / Allow certain IP ranges from logging in",
+		IconPath:     "SystemAO/security/img/small_icon.png",
+		Group:        "Security",
+		StartDir:     "SystemAO/security/accesscontrol.html",
+		RequireAdmin: true,
+	})
+
+	adminRouter.HandleFunc("/system/auth/blacklist/list", authAgent.BlacklistManager.HandleListBannedIPs)
+	adminRouter.HandleFunc("/system/auth/blacklist/ban", authAgent.BlacklistManager.HandleAddBannedIP)
+	adminRouter.HandleFunc("/system/auth/blacklist/unban", authAgent.BlacklistManager.HandleRemoveBannedIP)
+
 }

+ 32 - 12
mod/auth/auth.go

@@ -33,6 +33,7 @@ import (
 	"github.com/gorilla/sessions"
 
 	"imuslab.com/arozos/mod/auth/authlogger"
+	"imuslab.com/arozos/mod/auth/blacklist"
 	db "imuslab.com/arozos/mod/database"
 )
 
@@ -53,6 +54,9 @@ type AuthAgent struct {
 	AllowAutoLogin  bool
 	autoLoginTokens []*AutoLoginToken
 
+	//IP Blacklist manager
+	BlacklistManager *blacklist.BlackList
+
 	//Logger
 	Logger *authlogger.Logger
 }
@@ -78,6 +82,9 @@ func NewAuthenticationAgent(sessionName string, key []byte, sysdb *db.Database,
 	ticker := time.NewTicker(300 * time.Second)
 	done := make(chan bool)
 
+	//Create a new blacklist manager
+	thisBlacklistManager := blacklist.NewBlacklistManager(sysdb)
+
 	//Create a new logger for logging all login request
 	newLogger, err := authlogger.NewLogger()
 	if err != nil {
@@ -94,9 +101,14 @@ func NewAuthenticationAgent(sessionName string, key []byte, sysdb *db.Database,
 		ExpireTime:              120,
 		terminateTokenListener:  done,
 		mutex:                   &sync.Mutex{},
-		AllowAutoLogin:          false,
-		autoLoginTokens:         []*AutoLoginToken{},
-		Logger:                  newLogger,
+
+		//Auto login management
+		AllowAutoLogin:  false,
+		autoLoginTokens: []*AutoLoginToken{},
+
+		//Blacklist management
+		BlacklistManager: thisBlacklistManager,
+		Logger:           newLogger,
 	}
 
 	//Create a timer to listen to its token storage
@@ -135,15 +147,6 @@ func (a *AuthAgent) HandleCheckAuth(w http.ResponseWriter, r *http.Request, hand
 	}
 }
 
-//Register APIs that requires public access
-func (a *AuthAgent) RegisterPublicAPIs(ep AuthEndpoints) {
-	http.HandleFunc(ep.Login, a.HandleLogin)
-	http.HandleFunc(ep.Logout, a.HandleLogout)
-	http.HandleFunc(ep.Register, a.HandleRegister)
-	http.HandleFunc(ep.CheckLoggedIn, a.CheckLogin)
-	http.HandleFunc(ep.Autologin, a.HandleAutologinTokenLogin)
-}
-
 //Handle login request, require POST username and password
 func (a *AuthAgent) HandleLogin(w http.ResponseWriter, r *http.Request) {
 
@@ -179,6 +182,12 @@ func (a *AuthAgent) HandleLogin(w http.ResponseWriter, r *http.Request) {
 	//The database contain this user information. Check its password if it is correct
 	if passwordCorrect {
 		//Password correct
+		//Check if this request origin is allowed to access
+		ok, reasons := a.ValidateLoginRequest(w, r)
+		if !ok {
+			sendErrorResponse(w, reasons.Error())
+			return
+		}
 		// Set user as authenticated
 		a.LoginUserByRequest(w, r, username, rememberme)
 		//Print the login message to console
@@ -217,6 +226,17 @@ func (a *AuthAgent) ValidateUsernameAndPasswordWithReason(username string, passw
 	}
 }
 
+//Validate the user request for login
+func (a *AuthAgent) ValidateLoginRequest(w http.ResponseWriter, r *http.Request) (bool, error) {
+	//Check if the account is banned
+	if a.BlacklistManager.CheckIsBannedByRequest(r) {
+		//This user is banned
+		return false, errors.New("This IP is banned")
+	}
+	return true, nil
+}
+
+//Login the user by creating a valid session for this user
 func (a *AuthAgent) LoginUserByRequest(w http.ResponseWriter, r *http.Request, username string, rememberme bool) {
 	session, _ := a.SessionStore.Get(r, a.SessionName)
 

+ 2 - 2
mod/auth/blacklist/blacklist.go

@@ -54,9 +54,9 @@ func (bl *BlackList) IsBanned(ip string) bool {
 }
 
 func (bl *BlackList) ListBannedIpRanges() []string {
-	entries, err := bl.database.ListTable("test")
+	entries, err := bl.database.ListTable("ipblacklist")
 	if err != nil {
-		panic(err)
+		return []string{}
 	}
 	results := []string{}
 	for _, keypairs := range entries {

+ 53 - 2
mod/auth/blacklist/handler.go

@@ -1,8 +1,11 @@
 package blacklist
 
 import (
+	"encoding/json"
 	"net/http"
+	"strings"
 
+	"imuslab.com/arozos/mod/common"
 	"imuslab.com/arozos/mod/network"
 )
 
@@ -12,18 +15,66 @@ import (
 */
 
 func (bl *BlackList) HandleAddBannedIP(w http.ResponseWriter, r *http.Request) {
+	ipRange, err := common.Mv(r, "iprange", true)
+	if err != nil {
+		common.SendErrorResponse(w, "Invalid ip range given")
+		return
+	}
 
+	err = bl.Ban(ipRange)
+	if err != nil {
+		common.SendErrorResponse(w, err.Error())
+		return
+	}
+
+	common.SendOK(w)
 }
 
-func (bl *BlackList) HandleRemoveBannedIP() {
+func (bl *BlackList) HandleRemoveBannedIP(w http.ResponseWriter, r *http.Request) {
+	ipRange, err := common.Mv(r, "iprange", true)
+	if err != nil {
+		common.SendErrorResponse(w, "Invalid ip range given")
+		return
+	}
+
+	err = bl.UnBan(ipRange)
+	if err != nil {
+		common.SendErrorResponse(w, err.Error())
+		return
+	}
 
+	common.SendOK(w)
 }
 
-func (bl *BlackList) HandleListBannedIPs() {
+func (bl *BlackList) HandleSetBlacklistEnable(w http.ResponseWriter, r *http.Request) {
+	enableMode, _ := common.Mv(r, "enable", false)
+	if enableMode == "" {
+		//Get the current blacklist status
+		js, _ := json.Marshal(bl.Enabled)
+		common.SendJSONResponse(w, string(js))
+		return
+	} else {
+		if strings.ToLower(enableMode) == "true" {
+			bl.Enabled = true
+		} else if strings.ToLower(enableMode) == "false" {
+			bl.Enabled = false
+		} else {
+			common.SendErrorResponse(w, "Invalid mode given")
+		}
+	}
+}
 
+func (bl *BlackList) HandleListBannedIPs(w http.ResponseWriter, r *http.Request) {
+	bannedIpRanges := bl.ListBannedIpRanges()
+	js, _ := json.Marshal(bannedIpRanges)
+	common.SendJSONResponse(w, string(js))
 }
 
 func (bl *BlackList) CheckIsBannedByRequest(r *http.Request) bool {
+	if bl.Enabled == false {
+		//Blacklist not enabled. Always return not banned
+		return false
+	}
 	//Get the IP address from the request header
 	requestIP, err := network.GetIpFromRequest(r)
 	if err != nil {

+ 103 - 0
web/SystemAO/security/accesscontrol.html

@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Access Control</title>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
+    <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
+    <script type="text/javascript" src="../../script/jquery.min.js"></script>
+    <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
+    <style>
+        a.pageFocus {
+            background: #222222;
+            color: white !important;
+            border-radius: 50%;
+            -moz-border-radius: 50%;
+            -webkit-border-radius: 50%;
+            display: inline-block;
+            font-weight: bold;
+            line-height: 30px;
+            margin-right: 2px;
+            text-align: center;
+            width: 30px;
+        }
+
+        .noselect {
+            -webkit-touch-callout: none; /* iOS Safari */
+            -webkit-user-select: none; /* Safari */
+            -khtml-user-select: none; /* Konqueror HTML */
+            -moz-user-select: none; /* Old versions of Firefox */
+            -ms-user-select: none; /* Internet Explorer/Edge */
+            user-select: none; /* Non-prefixed version, currently
+                                        supported by Chrome, Edge, Opera and Firefox */
+        }
+    </style>
+</head>
+<body>
+    <br>
+    <div class="ui container" style="height: 100% !important;">
+        <div>
+            <h3 class="ui header">
+                Access Control
+                <div class="sub header">Manage IPs from accessing this host</div>
+            </h3>
+            <div class="ui divider"></div>
+            <h3><i class="ui green checkmark icon"></i> Whitelist</h3>
+
+            <div class="ui divider"></div>
+            <h3><i class="ui red remove icon"></i> Blacklist</h3>
+            <div class="ui black segment">
+                <h4>Usage</h4>
+                <p>Block certain IP or IP range from logging into the system. Syntax Examples:</p>
+                <div class="ui bulleted list">
+                    <div class="item">192.168.1.100</div>
+                    <div class="item">123.36.53.100</div>
+                    <div class="item">192.168.0.100 - 192.168.0.250</div>
+                </div>
+            </div>
+            <div class="ui toggle checkbox">
+                <input type="checkbox" name="enableBlacklist">
+                <label>Enable Blacklist Filtering</label>
+            </div>
+
+            <table class="ui celled table">
+                <thead>
+                  <tr><th>IP Range</th>
+                  <th>Edit</th>
+                  <th>Remove</th>
+                </tr></thead>
+                <tbody id="blacklisttable">
+                  <tr>
+                    <td data-label="Name">James</td>
+                    <td data-label="Age">24</td>
+                    <td data-label="Job">Engineer</td>
+                  </tr>
+                </tbody>
+              </table>
+
+            <div class="ui divider"></div>
+            <h3>Regional Block</h3>
+
+        </div>
+    
+    <script>
+        //Init
+        initBlacklist();
+
+        //Blacklist load
+        function initBlacklist(){
+            $.get("../../system/auth/blacklist/list", function(data){
+                data.forEach(entry => {
+
+                })
+
+                if (data.length == 0){
+                    $("#blacklisttable").html(`<tr>
+                        <td colspan="3"><i class="remove icon"></i> No Banned IPs</td>
+                    </tr>`);
+                }
+            })
+        }
+    </script>
+</body>
+</html>