security.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package controller
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strings"
  6. "github.com/gorilla/mux"
  7. "github.com/gravitl/netmaker/database"
  8. "github.com/gravitl/netmaker/functions"
  9. "github.com/gravitl/netmaker/logic"
  10. "github.com/gravitl/netmaker/logic/pro"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/models/promodels"
  13. "github.com/gravitl/netmaker/servercfg"
  14. )
  15. const (
  16. master_uname = "masteradministrator"
  17. unauthorized_msg = "unauthorized"
  18. unauthorized_err = models.Error(unauthorized_msg)
  19. )
  20. func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
  21. return func(w http.ResponseWriter, r *http.Request) {
  22. var errorResponse = models.ErrorResponse{
  23. Code: http.StatusUnauthorized, Message: unauthorized_msg,
  24. }
  25. var params = mux.Vars(r)
  26. bearerToken := r.Header.Get("Authorization")
  27. // to have a custom DNS service adding entries
  28. // we should refactor this, but is for the special case of an external service to query the DNS api
  29. if strings.Contains(r.RequestURI, "/dns") && strings.ToUpper(r.Method) == "GET" && authenticateDNSToken(bearerToken) {
  30. // do dns stuff
  31. r.Header.Set("user", "nameserver")
  32. networks, _ := json.Marshal([]string{ALL_NETWORK_ACCESS})
  33. r.Header.Set("networks", string(networks))
  34. next.ServeHTTP(w, r)
  35. return
  36. }
  37. var networkName = params["networkname"]
  38. if len(networkName) == 0 {
  39. networkName = params["network"]
  40. }
  41. networks, username, err := SecurityCheck(reqAdmin, networkName, bearerToken)
  42. if err != nil {
  43. returnErrorResponse(w, r, errorResponse)
  44. return
  45. }
  46. networksJson, err := json.Marshal(&networks)
  47. if err != nil {
  48. returnErrorResponse(w, r, errorResponse)
  49. return
  50. }
  51. r.Header.Set("user", username)
  52. r.Header.Set("networks", string(networksJson))
  53. next.ServeHTTP(w, r)
  54. }
  55. }
  56. func netUserSecurityCheck(isNodes, isClients bool, next http.Handler) http.HandlerFunc {
  57. return func(w http.ResponseWriter, r *http.Request) {
  58. var errorResponse = models.ErrorResponse{
  59. Code: http.StatusUnauthorized, Message: "unauthorized",
  60. }
  61. r.Header.Set("ismaster", "no")
  62. var params = mux.Vars(r)
  63. var netUserName = params["networkuser"]
  64. var network = params["network"]
  65. bearerToken := r.Header.Get("Authorization")
  66. var tokenSplit = strings.Split(bearerToken, " ")
  67. var authToken = ""
  68. if len(tokenSplit) < 2 {
  69. returnErrorResponse(w, r, errorResponse)
  70. return
  71. } else {
  72. authToken = tokenSplit[1]
  73. }
  74. isMasterAuthenticated := authenticateMaster(authToken)
  75. if isMasterAuthenticated {
  76. r.Header.Set("user", "master token user")
  77. r.Header.Set("ismaster", "yes")
  78. next.ServeHTTP(w, r)
  79. return
  80. }
  81. userName, _, isadmin, err := logic.VerifyUserToken(authToken)
  82. if err != nil {
  83. returnErrorResponse(w, r, errorResponse)
  84. return
  85. }
  86. r.Header.Set("user", userName)
  87. if isadmin {
  88. next.ServeHTTP(w, r)
  89. return
  90. }
  91. if isNodes || isClients {
  92. necessaryAccess := pro.NET_ADMIN
  93. if isClients {
  94. necessaryAccess = pro.CLIENT_ACCESS
  95. }
  96. if isNodes {
  97. necessaryAccess = pro.NODE_ACCESS
  98. }
  99. u, err := pro.GetNetworkUser(network, promodels.NetworkUserID(userName))
  100. if err != nil {
  101. returnErrorResponse(w, r, errorResponse)
  102. return
  103. }
  104. if u.AccessLevel > necessaryAccess {
  105. returnErrorResponse(w, r, errorResponse)
  106. return
  107. }
  108. } else if netUserName != userName {
  109. returnErrorResponse(w, r, errorResponse)
  110. return
  111. }
  112. next.ServeHTTP(w, r)
  113. }
  114. }
  115. // SecurityCheck - checks token stuff
  116. func SecurityCheck(reqAdmin bool, netname string, token string) ([]string, string, error) {
  117. var tokenSplit = strings.Split(token, " ")
  118. var authToken = ""
  119. userNetworks := []string{}
  120. if len(tokenSplit) < 2 {
  121. return userNetworks, "", unauthorized_err
  122. } else {
  123. authToken = tokenSplit[1]
  124. }
  125. //all endpoints here require master so not as complicated
  126. if authenticateMaster(authToken) {
  127. return []string{ALL_NETWORK_ACCESS}, master_uname, nil
  128. }
  129. username, networks, isadmin, err := logic.VerifyUserToken(authToken)
  130. if err != nil {
  131. return nil, username, unauthorized_err
  132. }
  133. if !isadmin && reqAdmin {
  134. return nil, username, unauthorized_err
  135. }
  136. userNetworks = networks
  137. if isadmin {
  138. return []string{ALL_NETWORK_ACCESS}, username, nil
  139. }
  140. // check network admin access
  141. if len(netname) > 0 && (!authenticateNetworkUser(netname, userNetworks) || len(userNetworks) == 0) {
  142. return nil, username, unauthorized_err
  143. }
  144. if !pro.IsUserNetAdmin(netname, username) {
  145. return nil, "", unauthorized_err
  146. }
  147. return userNetworks, username, nil
  148. }
  149. // Consider a more secure way of setting master key
  150. func authenticateMaster(tokenString string) bool {
  151. return tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != ""
  152. }
  153. func authenticateNetworkUser(network string, userNetworks []string) bool {
  154. networkexists, err := functions.NetworkExists(network)
  155. if (err != nil && !database.IsEmptyRecord(err)) || !networkexists {
  156. return false
  157. }
  158. return logic.StringSliceContains(userNetworks, network)
  159. }
  160. //Consider a more secure way of setting master key
  161. func authenticateDNSToken(tokenString string) bool {
  162. tokens := strings.Split(tokenString, " ")
  163. if len(tokens) < 2 {
  164. return false
  165. }
  166. return tokens[1] == servercfg.GetDNSKey()
  167. }
  168. func continueIfUserMatch(next http.Handler) http.HandlerFunc {
  169. return func(w http.ResponseWriter, r *http.Request) {
  170. var errorResponse = models.ErrorResponse{
  171. Code: http.StatusUnauthorized, Message: unauthorized_msg,
  172. }
  173. var params = mux.Vars(r)
  174. var requestedUser = params["username"]
  175. if requestedUser != r.Header.Get("user") {
  176. returnErrorResponse(w, r, errorResponse)
  177. return
  178. }
  179. next.ServeHTTP(w, r)
  180. }
  181. }