diff options
Diffstat (limited to 'weed/security/guard.go')
| -rw-r--r-- | weed/security/guard.go | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/weed/security/guard.go b/weed/security/guard.go index dea3b12f2..6292c67c9 100644 --- a/weed/security/guard.go +++ b/weed/security/guard.go @@ -41,17 +41,31 @@ https://github.com/pkieltyka/jwtauth/blob/master/jwtauth.go */ type Guard struct { - whiteList []string + ipWhiteList []string + rootWhiteList []string SecretKey Secret isActive bool } -func NewGuard(whiteList []string, secretKey string) *Guard { - g := &Guard{whiteList: whiteList, SecretKey: Secret(secretKey)} - g.isActive = len(g.whiteList) != 0 || len(g.SecretKey) != 0 +func NewGuard(ipWhiteList []string, rootWhiteList []string, secretKey string) *Guard { + g := &Guard{ipWhiteList: ipWhiteList, rootWhiteList: rootWhiteList, SecretKey: Secret(secretKey)} + g.isActive = len(g.ipWhiteList) != 0 || len(g.SecretKey) != 0 return g } +func (g *Guard) WhiteList2(f func(w http.ResponseWriter, r *http.Request, b bool)) func(w http.ResponseWriter, r *http.Request, b bool) { + if !g.isActive { + //if no security needed, just skip all checkings + return f + } + return func(w http.ResponseWriter, r *http.Request, b bool) { + if err := g.checkWhiteList(w, r); err != nil { + w.WriteHeader(http.StatusUnauthorized) + return + } + f(w, r, b) + } +} func (g *Guard) WhiteList(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) { if !g.isActive { @@ -96,13 +110,14 @@ func GetActualRemoteHost(r *http.Request) (host string, err error) { } func (g *Guard) checkWhiteList(w http.ResponseWriter, r *http.Request) error { - if len(g.whiteList) == 0 { + if len(g.ipWhiteList) == 0 { + glog.V(0).Info("No whitelist specified for operation") return nil } host, err := GetActualRemoteHost(r) if err == nil { - for _, ip := range g.whiteList { + for _, ip := range g.ipWhiteList { // If the whitelist entry contains a "/" it // is a CIDR range, and we should check the @@ -114,6 +129,7 @@ func (g *Guard) checkWhiteList(w http.ResponseWriter, r *http.Request) error { } remote := net.ParseIP(host) if cidrnet.Contains(remote) { + glog.V(0).Infof("Found %s in CIDR whitelist.", r.RemoteAddr) return nil } } @@ -122,10 +138,30 @@ func (g *Guard) checkWhiteList(w http.ResponseWriter, r *http.Request) error { // Otherwise we're looking for a literal match. // if ip == host { + glog.V(0).Infof("Found %s in whitelist.", r.RemoteAddr) + return nil + } + // ::1 is the same as 127.0.0.1 and localhost + if host == "::1" && (ip == "127.0.0.1" || ip == "localhost") { + glog.V(0).Infof("Found %s (localhost) in whitelist.", r.RemoteAddr) return nil } } } + // The root whitelist allows exceptions to the IP whitelist, but only by certain root paths in the request. + if len(g.rootWhiteList) > 0 { + pathParts := strings.Split(r.RequestURI, "/") + if len(pathParts) > 0 { + requestedRoot := pathParts[1] + for _, root := range g.rootWhiteList { + if root == requestedRoot { + glog.V(0).Infof("Found %s in root whitelist.", requestedRoot) + return nil + } + } + glog.V(0).Infof("Not in root whitelist: %s", requestedRoot) + } + } glog.V(0).Infof("Not in whitelist: %s", r.RemoteAddr) return fmt.Errorf("Not in whitelis: %s", r.RemoteAddr) |
