updated to code to enforce access rules to the control channel
This commit is contained in:
		| @ -3,6 +3,8 @@ package hodu | |||||||
| import "encoding/json" | import "encoding/json" | ||||||
| import "fmt" | import "fmt" | ||||||
| import "net/http" | import "net/http" | ||||||
|  | import "net/netip" | ||||||
|  | import "path/filepath" | ||||||
| import "strings" | import "strings" | ||||||
| import "time" | import "time" | ||||||
|  |  | ||||||
| @ -82,11 +84,35 @@ func (ctl *server_ctl) Id() string { | |||||||
| func (ctl *server_ctl) Authenticate(req *http.Request) (int, string) { | func (ctl *server_ctl) Authenticate(req *http.Request) (int, string) { | ||||||
| 	var s *Server | 	var s *Server | ||||||
| 	var rule HttpAccessRule | 	var rule HttpAccessRule | ||||||
|  | 	var raddrport netip.AddrPort | ||||||
|  | 	var raddr netip.Addr | ||||||
|  | 	var err error | ||||||
|  |  | ||||||
| 	s = ctl.s | 	s = ctl.s | ||||||
|  |  | ||||||
|  | 	raddrport, err = netip.ParseAddrPort(req.RemoteAddr) | ||||||
|  | 	if err == nil { raddr = raddrport.Addr() } | ||||||
|  |  | ||||||
| 	for _, rule = range s.cfg.CtlAuth.AccessRules { | 	for _, rule = range s.cfg.CtlAuth.AccessRules { | ||||||
| 		if req.URL.Path == rule.Prefix || strings.HasPrefix(req.URL.Path, rule.Prefix + "/") { | 		// i don't take into account X-Forwarded-For and similar headers | ||||||
|  | 		if req.URL.Path == rule.Prefix || strings.HasPrefix(req.URL.Path, filepath.Clean(rule.Prefix + "/")) { | ||||||
|  | 			var org_net_ok bool | ||||||
|  |  | ||||||
|  | 			if len(rule.OrgNets) > 0 && raddr.IsValid() { | ||||||
|  | 				var netpfx netip.Prefix | ||||||
|  |  | ||||||
|  | 				org_net_ok = false | ||||||
|  | 				for  _, netpfx = range rule.OrgNets { | ||||||
|  | 					if err == nil && netpfx.Contains(raddr) { | ||||||
|  | 						org_net_ok = true | ||||||
|  | 						break | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				org_net_ok = true | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if org_net_ok { | ||||||
| 				if rule.Action == HTTP_ACCESS_ACCEPT { | 				if rule.Action == HTTP_ACCESS_ACCEPT { | ||||||
| 					return http.StatusOK, "" | 					return http.StatusOK, "" | ||||||
| 				} else if rule.Action == HTTP_ACCESS_REJECT { | 				} else if rule.Action == HTTP_ACCESS_REJECT { | ||||||
| @ -94,6 +120,7 @@ func (ctl *server_ctl) Authenticate(req *http.Request) (int, string) { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if s.cfg.CtlAuth != nil && s.cfg.CtlAuth.Enabled { | 	if s.cfg.CtlAuth != nil && s.cfg.CtlAuth.Enabled { | ||||||
| 		var auth_hdr string | 		var auth_hdr string | ||||||
|  | |||||||
| @ -980,8 +980,11 @@ func (s *Server) wrap_http_handler(handler ServerHttpHandler) http.Handler { | |||||||
| 		status_code, realm = handler.Authenticate(req) | 		status_code, realm = handler.Authenticate(req) | ||||||
| 		if status_code == http.StatusUnauthorized && realm != "" { | 		if status_code == http.StatusUnauthorized && realm != "" { | ||||||
| 			w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic Realm=\"%s\"", realm)) | 			w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic Realm=\"%s\"", realm)) | ||||||
|  | 			WriteEmptyRespHeader(w, status_code) | ||||||
| 		} else if status_code == http.StatusOK { | 		} else if status_code == http.StatusOK { | ||||||
| 			status_code, err = handler.ServeHTTP(w, req) | 			status_code, err = handler.ServeHTTP(w, req) | ||||||
|  | 		} else { | ||||||
|  | 			WriteEmptyRespHeader(w, status_code) | ||||||
| 		} | 		} | ||||||
| 		time_taken = time.Now().Sub(start_time) | 		time_taken = time.Now().Sub(start_time) | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user