mirror of
https://github.com/minio/minio.git
synced 2025-01-12 15:33:22 -05:00
Verify md5 content hash, closes #4285
This commit is contained in:
parent
bd67117756
commit
5c78415b31
@ -706,6 +706,8 @@ func toAPIErrorCode(err error) (apiErr APIErrorCode) {
|
||||
apiErr = ErrNoSuchUpload
|
||||
case PartTooSmall:
|
||||
apiErr = ErrEntityTooSmall
|
||||
case SignatureDoesNotMatch:
|
||||
apiErr = ErrSignatureDoesNotMatch
|
||||
case SHA256Mismatch:
|
||||
apiErr = ErrContentSHA256Mismatch
|
||||
case ObjectTooLarge:
|
||||
|
@ -35,6 +35,8 @@ import (
|
||||
|
||||
"encoding/base64"
|
||||
|
||||
"bytes"
|
||||
|
||||
minio "github.com/minio/minio-go"
|
||||
"github.com/minio/minio-go/pkg/policy"
|
||||
)
|
||||
@ -469,17 +471,18 @@ func (l *gcsGateway) PutObject(bucket string, key string, size int64, data io.Re
|
||||
return ObjectInfo{}, gcsToObjectError(traceError(err), bucket)
|
||||
}
|
||||
|
||||
var sha256Writer hash.Hash
|
||||
|
||||
teeReader := data
|
||||
|
||||
var sha256Writer hash.Hash
|
||||
if sha256sum == "" {
|
||||
} else if _, err := hex.DecodeString(sha256sum); err != nil {
|
||||
return ObjectInfo{}, gcsToObjectError(traceError(err), bucket, key)
|
||||
} else {
|
||||
sha256Writer = sha256.New()
|
||||
teeReader = io.TeeReader(data, sha256Writer)
|
||||
teeReader = io.TeeReader(teeReader, sha256Writer)
|
||||
}
|
||||
|
||||
md5sum := metadata["md5Sum"]
|
||||
delete(metadata, "md5Sum")
|
||||
|
||||
object := l.client.Bucket(bucket).Object(key)
|
||||
@ -504,12 +507,18 @@ func (l *gcsGateway) PutObject(bucket string, key string, size int64, data io.Re
|
||||
if err != nil {
|
||||
return ObjectInfo{}, gcsToObjectError(traceError(err), bucket, key)
|
||||
}
|
||||
if sha256sum != "" {
|
||||
newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil))
|
||||
if newSHA256sum != sha256sum {
|
||||
//l.Client.RemoveObject(bucket, object)
|
||||
return ObjectInfo{}, traceError(SHA256Mismatch{})
|
||||
}
|
||||
|
||||
if sha256sum == "" {
|
||||
} else if newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil)); newSHA256sum != sha256sum {
|
||||
object.Delete(l.ctx)
|
||||
return ObjectInfo{}, traceError(SHA256Mismatch{})
|
||||
}
|
||||
|
||||
if md5sum == "" {
|
||||
} else if b, err := hex.DecodeString(md5sum); err != nil {
|
||||
} else if bytes.Compare(b, attrs.MD5) != 0 {
|
||||
object.Delete(l.ctx)
|
||||
return ObjectInfo{}, traceError(SignatureDoesNotMatch{})
|
||||
}
|
||||
|
||||
return fromGCSObjectInfo(attrs), nil
|
||||
|
@ -238,8 +238,6 @@ func (api gatewayAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
// Make sure we hex encode md5sum here.
|
||||
metadata["etag"] = hex.EncodeToString(md5Bytes)
|
||||
|
||||
sha256sum := ""
|
||||
|
||||
// Lock the object.
|
||||
objectLock := globalNSMutex.NewNSLock(bucket, object)
|
||||
objectLock.Lock()
|
||||
@ -249,7 +247,7 @@ func (api gatewayAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
switch reqAuthType {
|
||||
case authTypeAnonymous:
|
||||
// Create anonymous object.
|
||||
objInfo, err = objectAPI.AnonPutObject(bucket, object, size, r.Body, metadata, sha256sum)
|
||||
objInfo, err = objectAPI.AnonPutObject(bucket, object, size, r.Body, metadata, "")
|
||||
case authTypeStreamingSigned:
|
||||
// Initialize stream signature verifier.
|
||||
reader, s3Error := newSignV4ChunkedReader(r)
|
||||
@ -258,7 +256,7 @@ func (api gatewayAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
writeErrorResponse(w, s3Error, r.URL)
|
||||
return
|
||||
}
|
||||
objInfo, err = objectAPI.PutObject(bucket, object, size, reader, metadata, sha256sum)
|
||||
objInfo, err = objectAPI.PutObject(bucket, object, size, reader, metadata, "")
|
||||
case authTypeSignedV2, authTypePresignedV2:
|
||||
s3Error := isReqAuthenticatedV2(r)
|
||||
if s3Error != ErrNone {
|
||||
@ -266,16 +264,20 @@ func (api gatewayAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
writeErrorResponse(w, s3Error, r.URL)
|
||||
return
|
||||
}
|
||||
objInfo, err = objectAPI.PutObject(bucket, object, size, r.Body, metadata, sha256sum)
|
||||
objInfo, err = objectAPI.PutObject(bucket, object, size, r.Body, metadata, "")
|
||||
case authTypePresigned, authTypeSigned:
|
||||
if s3Error := reqSignatureV4Verify(r, serverConfig.GetRegion()); s3Error != ErrNone {
|
||||
errorIf(errSignatureMismatch, "%s", dumpRequest(r))
|
||||
writeErrorResponse(w, s3Error, r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
sha256sum := getContentSha256Cksum(r)
|
||||
|
||||
if !skipContentSha256Cksum(r) {
|
||||
sha256sum = r.Header.Get("X-Amz-Content-Sha256")
|
||||
}
|
||||
|
||||
// Create object.
|
||||
objInfo, err = objectAPI.PutObject(bucket, object, size, r.Body, metadata, sha256sum)
|
||||
default:
|
||||
|
@ -110,6 +110,13 @@ func (e SHA256Mismatch) Error() string {
|
||||
return "sha256 computed does not match with what is expected"
|
||||
}
|
||||
|
||||
// SignatureDoesNotMatch - when content md5 does not match with what was sent from client.
|
||||
type SignatureDoesNotMatch struct{}
|
||||
|
||||
func (e SignatureDoesNotMatch) Error() string {
|
||||
return "The request signature we calculated does not match the signature you provided. Check your key and signing method."
|
||||
}
|
||||
|
||||
// StorageFull storage ran out of space.
|
||||
type StorageFull struct{}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user