auth.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. package gold
  2. import (
  3. "crypto/sha256"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. // DigestAuthentication structure
  13. type DigestAuthentication struct {
  14. Type, Source, Username, Realm, Nonce, URI, QOP, NC, CNonce, Response, Opaque, Algorithm string
  15. }
  16. // DigestAuthorization structure
  17. type DigestAuthorization struct {
  18. Type, Source, Username, Nonce, Signature string
  19. }
  20. func (req *httpRequest) authn(w http.ResponseWriter) string {
  21. user, err := req.userCookie()
  22. if err != nil {
  23. req.Server.debug.Println("userCookie error:", err)
  24. }
  25. if len(user) > 0 {
  26. req.Server.debug.Println("Cookie auth OK for User: " + user)
  27. return user
  28. }
  29. // try WebID-RSA
  30. if len(req.Header.Get("Authorization")) > 0 {
  31. user, err = WebIDDigestAuth(req)
  32. if err != nil {
  33. req.Server.debug.Println("WebID-RSA auth error:", err)
  34. }
  35. if len(user) > 0 {
  36. req.Server.debug.Println("WebID-RSA auth OK for User: " + user)
  37. }
  38. }
  39. // fall back to WebID-TLS
  40. if len(user) == 0 {
  41. user, err = WebIDTLSAuth(req)
  42. if err != nil {
  43. req.Server.debug.Println("WebID-TLS error:", err)
  44. }
  45. if len(user) > 0 {
  46. req.Server.debug.Println("WebID-TLS auth OK for User: " + user)
  47. }
  48. }
  49. if len(user) > 0 {
  50. if len(req.Header.Get("On-Behalf-Of")) > 0 {
  51. delegator := debrack(req.Header.Get("On-Behalf-Of"))
  52. if verifyDelegator(delegator, user) {
  53. req.Server.debug.Println("Setting delegation user to:", delegator)
  54. user = delegator
  55. }
  56. }
  57. req.Server.userCookieSet(w, user)
  58. return user
  59. }
  60. user = ""
  61. req.Server.debug.Println("Unauthenticated User")
  62. return user
  63. }
  64. func (req *httpRequest) userCookie() (string, error) {
  65. value := make(map[string]string)
  66. cookie, err := req.Cookie("Session")
  67. if err != nil {
  68. return "", errors.New(err.Error() + " Got: " + fmt.Sprintf("%s", req.Cookies()))
  69. }
  70. err = req.Server.cookie.Decode("Session", cookie.Value, &value)
  71. if err != nil {
  72. return "", err
  73. }
  74. return value["user"], nil
  75. }
  76. func (srv *Server) userCookieSet(w http.ResponseWriter, user string) error {
  77. value := map[string]string{
  78. "user": user,
  79. }
  80. encoded, err := srv.cookie.Encode("Session", value)
  81. if err != nil {
  82. return err
  83. }
  84. t := time.Duration(srv.Config.CookieAge) * time.Hour
  85. cookieCfg := &http.Cookie{
  86. Expires: time.Now().Add(t),
  87. Name: "Session",
  88. Path: "/",
  89. Value: encoded,
  90. Secure: true,
  91. }
  92. http.SetCookie(w, cookieCfg)
  93. return nil
  94. }
  95. func (srv *Server) userCookieDelete(w http.ResponseWriter) {
  96. http.SetCookie(w, &http.Cookie{
  97. Name: "Session",
  98. Value: "deleted",
  99. Path: "/",
  100. MaxAge: -1,
  101. })
  102. }
  103. // ParseDigestAuthenticateHeader parses an Authenticate header and returns a DigestAuthentication object
  104. func ParseDigestAuthenticateHeader(header string) (*DigestAuthentication, error) {
  105. auth := DigestAuthentication{}
  106. if len(header) == 0 {
  107. return &auth, errors.New("Cannot parse WWW-Authenticate header: no header present")
  108. }
  109. opts := make(map[string]string)
  110. parts := strings.SplitN(header, " ", 2)
  111. opts["type"] = parts[0]
  112. parts = strings.Split(parts[1], ",")
  113. for _, part := range parts {
  114. vals := strings.SplitN(strings.TrimSpace(part), "=", 2)
  115. key := vals[0]
  116. val := strings.Replace(vals[1], "\"", "", -1)
  117. opts[key] = val
  118. }
  119. auth = DigestAuthentication{
  120. opts["type"],
  121. opts["source"],
  122. opts["username"],
  123. opts["realm"],
  124. opts["nonce"],
  125. opts["uri"],
  126. opts["qop"],
  127. opts["nc"],
  128. opts["qnonce"],
  129. opts["response"],
  130. opts["opaque"],
  131. opts["algorithm"],
  132. }
  133. return &auth, nil
  134. }
  135. // ParseDigestAuthorizationHeader parses an Authorization header and returns a DigestAuthorization object
  136. func ParseDigestAuthorizationHeader(header string) (*DigestAuthorization, error) {
  137. auth := DigestAuthorization{}
  138. if len(header) == 0 {
  139. return &auth, errors.New("Cannot parse Authorization header: no header present")
  140. }
  141. opts := make(map[string]string)
  142. parts := strings.SplitN(header, " ", 2)
  143. opts["type"] = parts[0]
  144. if opts["type"] == "Bearer" {
  145. return &auth, errors.New("Not a Digest authorization header. Got " + opts["type"])
  146. }
  147. parts = strings.Split(parts[1], ",")
  148. for _, part := range parts {
  149. vals := strings.SplitN(strings.TrimSpace(part), "=", 2)
  150. key := vals[0]
  151. val := strings.Replace(vals[1], "\"", "", -1)
  152. opts[key] = val
  153. }
  154. auth = DigestAuthorization{
  155. opts["type"],
  156. opts["source"],
  157. opts["username"],
  158. opts["nonce"],
  159. opts["sig"],
  160. }
  161. return &auth, nil
  162. }
  163. func ParseBearerAuthorizationHeader(header string) (string, error) {
  164. if len(header) == 0 {
  165. return "", errors.New("Cannot parse Authorization header: no header present")
  166. }
  167. parts := strings.SplitN(header, " ", 2)
  168. if parts[0] != "Bearer" {
  169. return "", errors.New("Not a Bearer header. Got: " + parts[0])
  170. }
  171. return decodeQuery(parts[1])
  172. }
  173. func NewTokenValues() map[string]string {
  174. return make(map[string]string)
  175. }
  176. // NewSecureToken generates a signed token to be used during account recovery
  177. func NewSecureToken(tokenType string, values map[string]string, duration time.Duration, s *Server) (string, error) {
  178. valid := time.Now().Add(duration).Unix()
  179. values["valid"] = fmt.Sprintf("%d", valid)
  180. token, err := s.cookie.Encode(tokenType, values)
  181. if err != nil {
  182. s.debug.Println("Error encoding new token: " + err.Error())
  183. return "", err
  184. }
  185. return token, nil
  186. }
  187. // ValidateSecureToken returns the values of a secure cookie
  188. func ValidateSecureToken(tokenType string, token string, s *Server) (map[string]string, error) {
  189. values := make(map[string]string)
  190. err := s.cookie.Decode(tokenType, token, &values)
  191. if err != nil {
  192. s.debug.Println("Secure token decoding error: " + err.Error())
  193. return values, err
  194. }
  195. return values, nil
  196. }
  197. func GetValuesFromToken(tokenType string, token string, req *httpRequest, s *Server) (map[string]string, error) {
  198. values := NewTokenValues()
  199. token, err := decodeQuery(token)
  200. if err != nil {
  201. s.debug.Println("Token URL decoding error for type: " + tokenType + " : " + err.Error())
  202. return values, err
  203. }
  204. err = s.cookie.Decode(tokenType, token, &values)
  205. if err != nil {
  206. s.debug.Println("Token decoding error for type: " + tokenType + " \nToken: " + token + "\n" + err.Error())
  207. return values, err
  208. }
  209. return values, nil
  210. }
  211. func IsTokenDateValid(valid string) error {
  212. v, err := strconv.ParseInt(valid, 10, 64)
  213. if err != nil {
  214. return err
  215. }
  216. if time.Now().Local().Unix() > v {
  217. return errors.New("Token has expired!")
  218. }
  219. return nil
  220. }
  221. func GetAuthzFromToken(token string, req *httpRequest) (string, error) {
  222. // values, err := GetValuesFromToken("Authorization", token, req, s)
  223. values, err := req.Server.getPersistedToken("Authorization", req.Host, token)
  224. if err != nil {
  225. return "", err
  226. }
  227. if len(values["webid"]) == 0 && len(values["valid"]) == 0 &&
  228. len(values["origin"]) == 0 {
  229. return "", errors.New("Malformed token is missing required values")
  230. }
  231. err = IsTokenDateValid(values["valid"])
  232. if err != nil {
  233. return "", err
  234. }
  235. origin := req.Header.Get("Origin")
  236. if len(origin) > 0 && origin != values["origin"] {
  237. return "", errors.New("Cannot authorize user: " + req.User + ". Origin: " + origin + " does not match the origin in the token: " + values["origin"])
  238. }
  239. return values["webid"], nil
  240. }
  241. func saltedPassword(salt, pass string) string {
  242. s := sha256.Sum256([]byte(salt + pass))
  243. toString := fmt.Sprintf("%x", s)
  244. return toString
  245. }
  246. func encodeQuery(s string) string {
  247. return url.QueryEscape(s)
  248. }
  249. func decodeQuery(s string) (string, error) {
  250. return url.QueryUnescape(s)
  251. }