You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.4 KiB

6 years ago
  1. package s3api
  2. import (
  3. "net/http"
  4. "strings"
  5. )
  6. // AWS Signature Version '4' constants.
  7. const (
  8. signV4Algorithm = "AWS4-HMAC-SHA256"
  9. signV2Algorithm = "AWS"
  10. )
  11. // Verify if request has JWT.
  12. func isRequestJWT(r *http.Request) bool {
  13. return strings.HasPrefix(r.Header.Get("Authorization"), "Bearer")
  14. }
  15. // Verify if request has AWS Signature Version '4'.
  16. func isRequestSignatureV4(r *http.Request) bool {
  17. return strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm)
  18. }
  19. // Verify if request has AWS Signature Version '2'.
  20. func isRequestSignatureV2(r *http.Request) bool {
  21. return (!strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm) &&
  22. strings.HasPrefix(r.Header.Get("Authorization"), signV2Algorithm))
  23. }
  24. // Verify if request has AWS PreSign Version '4'.
  25. func isRequestPresignedSignatureV4(r *http.Request) bool {
  26. _, ok := r.URL.Query()["X-Amz-Credential"]
  27. return ok
  28. }
  29. // Verify request has AWS PreSign Version '2'.
  30. func isRequestPresignedSignatureV2(r *http.Request) bool {
  31. _, ok := r.URL.Query()["AWSAccessKeyId"]
  32. return ok
  33. }
  34. // Verify if request has AWS Post policy Signature Version '4'.
  35. func isRequestPostPolicySignatureV4(r *http.Request) bool {
  36. return strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data") &&
  37. r.Method == http.MethodPost
  38. }
  39. // Verify if the request has AWS Streaming Signature Version '4'. This is only valid for 'PUT' operation.
  40. func isRequestSignStreamingV4(r *http.Request) bool {
  41. return r.Header.Get("x-amz-content-sha256") == streamingContentSHA256 &&
  42. r.Method == http.MethodPut
  43. }
  44. // Authorization type.
  45. type authType int
  46. // List of all supported auth types.
  47. const (
  48. authTypeUnknown authType = iota
  49. authTypeAnonymous
  50. authTypePresigned
  51. authTypePresignedV2
  52. authTypePostPolicy
  53. authTypeStreamingSigned
  54. authTypeSigned
  55. authTypeSignedV2
  56. authTypeJWT
  57. )
  58. // Get request authentication type.
  59. func getRequestAuthType(r *http.Request) authType {
  60. if isRequestSignatureV2(r) {
  61. return authTypeSignedV2
  62. } else if isRequestPresignedSignatureV2(r) {
  63. return authTypePresignedV2
  64. } else if isRequestSignStreamingV4(r) {
  65. return authTypeStreamingSigned
  66. } else if isRequestSignatureV4(r) {
  67. return authTypeSigned
  68. } else if isRequestPresignedSignatureV4(r) {
  69. return authTypePresigned
  70. } else if isRequestJWT(r) {
  71. return authTypeJWT
  72. } else if isRequestPostPolicySignatureV4(r) {
  73. return authTypePostPolicy
  74. } else if _, ok := r.Header["Authorization"]; !ok {
  75. return authTypeAnonymous
  76. }
  77. return authTypeUnknown
  78. }