mirror of
https://github.com/minio/minio.git
synced 2024-12-25 06:35:56 -05:00
Signature-V4: Dump the request with error message on signature mismatch. (#2734)
fixes #2691
This commit is contained in:
parent
725df557b5
commit
a955676986
@ -83,6 +83,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
|
|||||||
}
|
}
|
||||||
case authTypeSigned, authTypePresigned:
|
case authTypeSigned, authTypePresigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -149,6 +150,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
|
|||||||
}
|
}
|
||||||
case authTypeSigned, authTypePresigned:
|
case authTypeSigned, authTypePresigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
|
|||||||
}
|
}
|
||||||
case authTypeSigned, authTypePresigned:
|
case authTypeSigned, authTypePresigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -137,6 +138,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
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.
|
// List buckets does not support bucket policies, no need to enforce it.
|
||||||
if s3Error := checkAuth(r); s3Error != ErrNone {
|
if s3Error := checkAuth(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -228,6 +231,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
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.
|
// PutBucket does not support policies, use checkAuth to validate signature.
|
||||||
if s3Error := checkAuth(r); s3Error != ErrNone {
|
if s3Error := checkAuth(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -477,6 +482,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
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.
|
// DeleteBucket does not support bucket policies, use checkAuth to validate signature.
|
||||||
if s3Error := checkAuth(r); s3Error != ErrNone {
|
if s3Error := checkAuth(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -223,6 +224,7 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -279,6 +281,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -460,6 +463,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
|
|||||||
// Initialize stream signature verifier.
|
// Initialize stream signature verifier.
|
||||||
reader, s3Error := newSignV4ChunkedReader(r)
|
reader, s3Error := newSignV4ChunkedReader(r)
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -519,6 +523,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -620,6 +625,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
|
|||||||
// Initialize stream signature verifier.
|
// Initialize stream signature verifier.
|
||||||
reader, s3Error := newSignV4ChunkedReader(r)
|
reader, s3Error := newSignV4ChunkedReader(r)
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -666,6 +672,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter,
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -705,6 +712,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -762,6 +770,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
|||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -890,6 +899,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
|
|||||||
}
|
}
|
||||||
case authTypeSigned, authTypePresigned:
|
case authTypeSigned, authTypePresigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
||||||
|
errorIf(errSignatureMismatch, dumpRequest(r))
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,12 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"github.com/minio/sha256-simd"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/minio/sha256-simd"
|
||||||
)
|
)
|
||||||
|
|
||||||
// http Header "x-amz-content-sha256" == "UNSIGNED-PAYLOAD" indicates that the
|
// http Header "x-amz-content-sha256" == "UNSIGNED-PAYLOAD" indicates that the
|
||||||
|
19
cmd/utils.go
19
cmd/utils.go
@ -32,6 +32,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/pkg/profile"
|
"github.com/pkg/profile"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -327,3 +329,20 @@ func startMonitorShutdownSignal(onExitFn onExitFunc) error {
|
|||||||
// Successfully started routine.
|
// Successfully started routine.
|
||||||
return nil
|
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 "<error dumping request>"
|
||||||
|
}
|
||||||
|
return string(jsonBytes)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user