diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index 8e9dcd4ee..4ff8cc935 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -83,6 +83,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http } case authTypeSigned, authTypePresigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -149,6 +150,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http } case authTypeSigned, authTypePresigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 14de46e68..920775c80 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -82,6 +82,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r * } case authTypeSigned, authTypePresigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -137,6 +138,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -183,6 +185,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R // List buckets does not support bucket policies, no need to enforce it. if s3Error := checkAuth(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -228,6 +231,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -343,6 +347,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req // PutBucket does not support policies, use checkAuth to validate signature. if s3Error := checkAuth(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -477,6 +482,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -500,6 +506,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http. // DeleteBucket does not support bucket policies, use checkAuth to validate signature. if s3Error := checkAuth(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index a9f12b983..775102fb1 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -112,6 +112,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -223,6 +224,7 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -279,6 +281,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -460,6 +463,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Initialize stream signature verifier. reader, s3Error := newSignV4ChunkedReader(r) if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -519,6 +523,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -620,6 +625,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http // Initialize stream signature verifier. reader, s3Error := newSignV4ChunkedReader(r) if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -666,6 +672,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -705,6 +712,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -762,6 +770,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite } case authTypePresigned, authTypeSigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -890,6 +899,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. } case authTypeSigned, authTypePresigned: if s3Error := isReqAuthenticated(r); s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) writeErrorResponse(w, r, s3Error, r.URL.Path) return } diff --git a/cmd/signature-v4-utils.go b/cmd/signature-v4-utils.go index d0956422d..b0e5bc6ea 100644 --- a/cmd/signature-v4-utils.go +++ b/cmd/signature-v4-utils.go @@ -19,11 +19,12 @@ package cmd import ( "crypto/hmac" "encoding/hex" - "github.com/minio/sha256-simd" "net/http" "regexp" "strings" "unicode/utf8" + + "github.com/minio/sha256-simd" ) // http Header "x-amz-content-sha256" == "UNSIGNED-PAYLOAD" indicates that the diff --git a/cmd/utils.go b/cmd/utils.go index f861625aa..ab5f0c4b2 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -32,6 +32,8 @@ import ( "sync" "syscall" + "encoding/json" + "github.com/pkg/profile" ) @@ -327,3 +329,20 @@ func startMonitorShutdownSignal(onExitFn onExitFunc) error { // Successfully started routine. return nil } + +// dump the request into a string in JSON format. +func dumpRequest(r *http.Request) string { + header := cloneHeader(r.Header) + header.Set("Host", r.Host) + req := struct { + Method string `json:"method"` + Path string `json:"path"` + Query string `json:"query"` + Header http.Header `json:"header"` + }{r.Method, r.URL.Path, r.URL.RawQuery, header} + jsonBytes, err := json.Marshal(req) + if err != nil { + return "" + } + return string(jsonBytes) +}