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.

91 lines
2.5 KiB

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