diff --git a/controllers/networkHttpController.go b/controllers/networkHttpController.go index 08e69cf1..75e7cdba 100644 --- a/controllers/networkHttpController.go +++ b/controllers/networkHttpController.go @@ -44,6 +44,9 @@ func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc { var errorResponse = models.ErrorResponse{ Code: http.StatusUnauthorized, Message: "W1R3: It's not you it's me.", } + if strings.Contains(r.RequestURI, "/dns") && r.Method == "GET" { + + } var params = mux.Vars(r) bearerToken := r.Header.Get("Authorization") @@ -68,6 +71,7 @@ func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc { } } +// SecurityCheck - checks token stuff func SecurityCheck(reqAdmin bool, netname string, token string) (error, []string, string) { var hasBearer = true diff --git a/controllers/security.go b/controllers/security.go new file mode 100644 index 00000000..3841aae3 --- /dev/null +++ b/controllers/security.go @@ -0,0 +1,143 @@ +package controller + +import ( + "encoding/json" + "errors" + "net/http" + "strings" + + "github.com/gorilla/mux" + "github.com/gravitl/netmaker/database" + "github.com/gravitl/netmaker/functions" + "github.com/gravitl/netmaker/logic" + "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/servercfg" +) + +//Security check DNS is middleware for every DNS function and just checks to make sure that its the master or dns token calling +//Only admin should have access to all these network-level actions +//DNS token should have access to only read functions +func securityCheck(reqAdmin bool, allowDNSToken bool, next http.Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var errorResponse = models.ErrorResponse{ + Code: http.StatusUnauthorized, Message: "W1R3: It's not you it's me.", + } + + var params = mux.Vars(r) + bearerToken := r.Header.Get("Authorization") + if allowDNSToken && authenticateDNSToken(bearerToken) { + r.Header.Set("user", "nameserver") + networks, _ := json.Marshal([]string{ALL_NETWORK_ACCESS}) + r.Header.Set("networks", string(networks)) + next.ServeHTTP(w, r) + } else { + err, networks, username := SecurityCheck(reqAdmin, params["networkname"], bearerToken) + if err != nil { + if strings.Contains(err.Error(), "does not exist") { + errorResponse.Code = http.StatusNotFound + } + errorResponse.Message = err.Error() + returnErrorResponse(w, r, errorResponse) + return + } + networksJson, err := json.Marshal(&networks) + if err != nil { + errorResponse.Message = err.Error() + returnErrorResponse(w, r, errorResponse) + return + } + r.Header.Set("user", username) + r.Header.Set("networks", string(networksJson)) + next.ServeHTTP(w, r) + } + } +} + +func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var errorResponse = models.ErrorResponse{ + Code: http.StatusUnauthorized, Message: "W1R3: It's not you it's me.", + } + + var params = mux.Vars(r) + bearerToken := r.Header.Get("Authorization") + err, networks, username := SecurityCheck(reqAdmin, params["networkname"], bearerToken) + if err != nil { + if strings.Contains(err.Error(), "does not exist") { + errorResponse.Code = http.StatusNotFound + } + errorResponse.Message = err.Error() + returnErrorResponse(w, r, errorResponse) + return + } + networksJson, err := json.Marshal(&networks) + if err != nil { + errorResponse.Message = err.Error() + returnErrorResponse(w, r, errorResponse) + return + } + r.Header.Set("user", username) + r.Header.Set("networks", string(networksJson)) + next.ServeHTTP(w, r) + } +} + +// SecurityCheck - checks token stuff +func SecurityCheck(reqAdmin bool, netname string, token string) (error, []string, string) { + + var hasBearer = true + var tokenSplit = strings.Split(token, " ") + var authToken = "" + + if len(tokenSplit) < 2 { + hasBearer = false + } else { + authToken = tokenSplit[1] + } + userNetworks := []string{} + //all endpoints here require master so not as complicated + isMasterAuthenticated := authenticateMaster(authToken) + username := "" + if !hasBearer || !isMasterAuthenticated { + userName, networks, isadmin, err := logic.VerifyUserToken(authToken) + username = userName + if err != nil { + return errors.New("error verifying user token"), nil, username + } + if !isadmin && reqAdmin { + return errors.New("you are unauthorized to access this endpoint"), nil, username + } + userNetworks = networks + if isadmin { + userNetworks = []string{ALL_NETWORK_ACCESS} + } else { + networkexists, err := functions.NetworkExists(netname) + if err != nil && !database.IsEmptyRecord(err) { + return err, nil, "" + } + if netname != "" && !networkexists { + return errors.New("this network does not exist"), nil, "" + } + } + } else if isMasterAuthenticated { + userNetworks = []string{ALL_NETWORK_ACCESS} + } + if len(userNetworks) == 0 { + userNetworks = append(userNetworks, NO_NETWORKS_PRESENT) + } + return nil, userNetworks, username +} + +//Consider a more secure way of setting master key +func authenticateMaster(tokenString string) bool { + return tokenString == servercfg.GetMasterKey() +} + +//Consider a more secure way of setting master key +func authenticateDNSToken(tokenString string) bool { + tokens := strings.Split(tokenString, " ") + if len(tokens) < 2 { + return false + } + return tokens[1] == servercfg.GetDNSKey() +} diff --git a/logger/logger.go b/logger/logger.go index 71500af8..67c7e0ff 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -94,7 +94,6 @@ func Retrieve(filePath string) string { if err != nil { panic(err) } - fmt.Println(string(contents)) return string(contents) }