From 2d0cc80646fe4bc63d4a0029654ae327fdaf8f94 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 14 Oct 2015 15:45:34 -0700 Subject: [PATCH] Fix bugs in post policy and presigned signature handling --- server-api-bucket-handlers.go | 40 --------------------------------- server-api-object-handlers.go | 32 -------------------------- server-api-signature-handler.go | 16 +++++++++++++ 3 files changed, 16 insertions(+), 72 deletions(-) diff --git a/server-api-bucket-handlers.go b/server-api-bucket-handlers.go index d2ab6f21e..8eec77bad 100644 --- a/server-api-bucket-handlers.go +++ b/server-api-bucket-handlers.go @@ -25,38 +25,6 @@ import ( signv4 "github.com/minio/minio/pkg/signature" ) -func (api API) isValidOp(w http.ResponseWriter, req *http.Request) bool { - vars := mux.Vars(req) - bucket := vars["bucket"] - - bucketMetadata, err := api.Donut.GetBucketMetadata(bucket) - if err != nil { - errorIf(err.Trace(), "GetBucketMetadata failed.", nil) - switch err.ToGoError().(type) { - case donut.BucketNotFound: - writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) - return false - case donut.BucketNameInvalid: - writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) - return false - default: - writeErrorResponse(w, req, InternalError, req.URL.Path) - return false - } - } - if _, err = stripAccessKeyID(req.Header.Get("Authorization")); err != nil { - if bucketMetadata.ACL.IsPrivate() { - writeErrorResponse(w, req, AccessDenied, req.URL.Path) - return false - } - if bucketMetadata.ACL.IsPublicRead() && req.Method == "PUT" { - writeErrorResponse(w, req, AccessDenied, req.URL.Path) - return false - } - } - return true -} - // ListMultipartUploadsHandler - GET Bucket (List Multipart uploads) // ------------------------- // This operation lists in-progress multipart uploads. An in-progress @@ -74,10 +42,6 @@ func (api API) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Requ <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - resources := getBucketMultipartResources(req.URL.Query()) if resources.MaxUploads < 0 { writeErrorResponse(w, req, InvalidMaxUploads, req.URL.Path) @@ -126,10 +90,6 @@ func (api API) ListObjectsHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - if isRequestUploads(req.URL.Query()) { api.ListMultipartUploadsHandler(w, req) return diff --git a/server-api-object-handlers.go b/server-api-object-handlers.go index 65f3ff923..73f35333b 100644 --- a/server-api-object-handlers.go +++ b/server-api-object-handlers.go @@ -44,10 +44,6 @@ func (api API) GetObjectHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - var object, bucket string vars := mux.Vars(req) bucket = vars["bucket"] @@ -96,10 +92,6 @@ func (api API) HeadObjectHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - var object, bucket string vars := mux.Vars(req) bucket = vars["bucket"] @@ -139,10 +131,6 @@ func (api API) PutObjectHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - var object, bucket string vars := mux.Vars(req) bucket = vars["bucket"] @@ -243,10 +231,6 @@ func (api API) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Reques <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - if !isRequestUploads(req.URL.Query()) { writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) return @@ -288,10 +272,6 @@ func (api API) PutObjectPartHandler(w http.ResponseWriter, req *http.Request) { <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - // get Content-MD5 sent by client and verify if valid md5 := req.Header.Get("Content-MD5") if !isValidMD5(md5) { @@ -391,10 +371,6 @@ func (api API) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Requ <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - vars := mux.Vars(req) bucket := vars["bucket"] object := vars["object"] @@ -427,10 +403,6 @@ func (api API) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request) <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - objectResourcesMetadata := getObjectResources(req.URL.Query()) if objectResourcesMetadata.PartNumberMarker < 0 { writeErrorResponse(w, req, InvalidPartNumberMarker, req.URL.Path) @@ -478,10 +450,6 @@ func (api API) CompleteMultipartUploadHandler(w http.ResponseWriter, req *http.R <-op.ProceedCh } - if !api.isValidOp(w, req) { - return - } - vars := mux.Vars(req) bucket := vars["bucket"] object := vars["object"] diff --git a/server-api-signature-handler.go b/server-api-signature-handler.go index c9272cce4..354fde159 100644 --- a/server-api-signature-handler.go +++ b/server-api-signature-handler.go @@ -19,6 +19,7 @@ package main import ( "encoding/hex" "net/http" + "strings" "github.com/minio/minio/pkg/crypto/sha256" "github.com/minio/minio/pkg/probe" @@ -48,7 +49,21 @@ func isRequestPresignedSignatureV4(req *http.Request) bool { return false } +func isRequestPostPolicySignatureV4(req *http.Request) bool { + if _, ok := req.Header["Content-Type"]; ok { + if strings.Contains(req.Header.Get("Content-Type"), "multipart/form-data") { + return true + } + } + return false +} + func (s signatureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if isRequestPostPolicySignatureV4(r) && r.Method == "POST" { + s.handler.ServeHTTP(w, r) + return + } + var signature *signv4.Signature if isRequestSignatureV4(r) { // For PUT and POST requests with payload, send the call upwards for verification. @@ -113,6 +128,7 @@ func (s signatureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } s.handler.ServeHTTP(w, r) + return } writeErrorResponse(w, r, AccessDenied, r.URL.Path) }