2021-04-19 03:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright (c) 2015-2021 MinIO, Inc.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of MinIO Object Storage stack
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
						 
					
						
							
								
									
										
										
										
											2015-10-05 07:31:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-19 07:23:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"reflect" 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 03:35:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/encrypt" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/set" 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 03:35:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									xhttp  "github.com/minio/minio/internal/http" 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-24 03:35:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/s3select/jstream" 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// startWithConds - map which indicates if a given condition supports starts-with policy operator
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  startsWithConds  =  map [ string ] bool {  
						 
					
						
							
								
									
										
										
										
											2018-12-29 06:04:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"$acl" :                      true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$bucket" :                   false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$cache-control" :            true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$content-type" :             true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$content-disposition" :      true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$content-encoding" :         true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$expires" :                  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$key" :                      true , 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"$success_action_redirect" :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$redirect" :                 true , 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 04:33:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"$success_action_status" :    true , 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"$x-amz-algorithm" :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$x-amz-credential" :         false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"$x-amz-date" :               false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 03:35:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  postPolicyIgnoreKeys  =  map [ string ] bool {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"Policy" :               true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xhttp . AmzSignature :     true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xhttp . ContentEncoding :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									http . CanonicalHeaderKey ( xhttp . AmzChecksumAlgo ) :    true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									http . CanonicalHeaderKey ( xhttp . AmzChecksumCRC32 ) :   true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									http . CanonicalHeaderKey ( xhttp . AmzChecksumCRC32C ) :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									http . CanonicalHeaderKey ( xhttp . AmzChecksumSHA1 ) :    true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									http . CanonicalHeaderKey ( xhttp . AmzChecksumSHA256 ) :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									http . CanonicalHeaderKey ( xhttp . AmzChecksumMode ) :    true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Add policy conditionals.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policyCondEqual          =  "eq" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policyCondStartsWith     =  "starts-with" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policyCondContentLength  =  "content-length-range" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// toString - Safely convert interface to string without causing panic.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  toString ( val  interface { } )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  v  :=  val . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  string : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  v 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-07 01:26:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// toLowerString - safely convert interface to lower string
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  toLowerString ( val  interface { } )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  strings . ToLower ( toString ( val ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// toInteger _ Safely convert interface to integer without causing panic.
  
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  toInteger ( val  interface { } )  ( int64 ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  v  :=  val . ( type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  float64 : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  int64 ( v ) ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  int64 : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  v ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  int : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  int64 ( v ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  string : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i ,  err  :=  strconv . Atoi ( v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  int64 ( i ) ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-07 01:26:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  errors . New ( "Invalid number format" ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// isString - Safely check if val is of type string without causing panic.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isString ( val  interface { } )  bool  {  
						 
					
						
							
								
									
										
										
										
											2018-08-07 01:26:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  ok  :=  val . ( string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ok 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ContentLengthRange - policy content-length-range field.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  contentLengthRange  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Min    int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Max    int64 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									Valid  bool  // If content-length-range was part of policy
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// PostPolicyForm provides strict static type conversion and validation for Amazon S3's POST policy JSON string.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  PostPolicyForm  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Expiration  time . Time  // Expiration date and time of the POST policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Conditions  struct  {   // Conditional policy structure.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Policies  [ ] struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											Operator  string 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Key       string 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											Value     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ContentLengthRange  contentLengthRange 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// implemented to ensure that duplicate keys in JSON
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// are merged together into a single JSON key, also
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to remove any extraneous JSON bodies.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Go stdlib doesn't support parsing JSON with duplicate
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// keys, so we need to use this technique to merge the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// keys.
  
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  sanitizePolicy ( r  io . Reader )  ( io . Reader ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  buf  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									e  :=  json . NewEncoder ( & buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-24 03:35:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d  :=  jstream . NewDecoder ( r ,  0 ) . ObjectAsKVS ( ) . MaxDepth ( 10 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sset  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  mv  :=  range  d . Stream ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  kvs  jstream . KVS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  mv . ValueType  ==  jstream . Object  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This is a JSON object type (that preserves key order)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											kvs  =  mv . Value . ( jstream . KVS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  kv  :=  range  kvs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  sset . Contains ( kv . Key )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Reject duplicate conditions or expiration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  nil ,  fmt . Errorf ( "input policy has multiple %s, please fix your client code" ,  kv . Key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sset . Add ( kv . Key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											e . Encode ( kvs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & buf ,  d . Err ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-10 13:18:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// parsePostPolicyForm - Parse JSON policy string into typed PostPolicyForm structure.
  
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  parsePostPolicyForm ( r  io . Reader )  ( PostPolicyForm ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reader ,  err  :=  sanitizePolicy ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  PostPolicyForm { } ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d  :=  json . NewDecoder ( reader ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Convert po into interfaces and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// perform strict type conversion using reflection.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  rawPolicy  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Expiration  string         ` json:"expiration" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Conditions  [ ] interface { }  ` json:"conditions" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d . DisallowUnknownFields ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  d . Decode ( & rawPolicy ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  PostPolicyForm { } ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parsedPolicy  :=  PostPolicyForm { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Parse expiry time.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 05:24:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									parsedPolicy . Expiration ,  err  =  time . Parse ( time . RFC3339Nano ,  rawPolicy . Expiration ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 13:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  PostPolicyForm { } ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Parse conditions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  val  :=  range  rawPolicy . Conditions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  condt  :=  val . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  map [ string ] interface { } :  // Handle key:value map types.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  k ,  v  :=  range  condt  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! isString ( v )  {  // Pre-check value type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// All values must be of type string.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  parsedPolicy ,  fmt . Errorf ( "Unknown type %s of conditional field value %s found in POST policy form" ,  reflect . TypeOf ( condt ) . String ( ) ,  condt ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// {"acl": "public-read" } is an alternate way to indicate - [ "eq", "$acl", "public-read" ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// In this case we will just collapse this into "eq" for all use cases.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												parsedPolicy . Conditions . Policies  =  append ( parsedPolicy . Conditions . Policies ,  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													Operator  string 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Key       string 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													Value     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													policyCondEqual ,  "$"  +  strings . ToLower ( k ) ,  toString ( v ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  [ ] interface { } :  // Handle array types.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( condt )  !=  3  {  // Return error if we have insufficient elements.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  parsedPolicy ,  fmt . Errorf ( "Malformed conditional fields %s of type %s found in POST policy form" ,  condt ,  reflect . TypeOf ( condt ) . String ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  toLowerString ( condt [ 0 ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  policyCondEqual ,  policyCondStartsWith : 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												for  _ ,  v  :=  range  condt  {  // Pre-check all values for type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ! isString ( v )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														// All values must be of type string.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														return  parsedPolicy ,  fmt . Errorf ( "Unknown type %s of conditional field value %s found in POST policy form" ,  reflect . TypeOf ( condt ) . String ( ) ,  condt ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												operator ,  matchType ,  value  :=  toLowerString ( condt [ 0 ] ) ,  toLowerString ( condt [ 1 ] ) ,  toString ( condt [ 2 ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! strings . HasPrefix ( matchType ,  "$" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  parsedPolicy ,  fmt . Errorf ( "Invalid according to Policy: Policy Condition failed: [%s, %s, %s]" ,  operator ,  matchType ,  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parsedPolicy . Conditions . Policies  =  append ( parsedPolicy . Conditions . Policies ,  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													Operator  string 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Key       string 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													Value     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													operator ,  matchType ,  value , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  policyCondContentLength : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												min ,  err  :=  toInteger ( condt [ 1 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  parsedPolicy ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												max ,  err  :=  toInteger ( condt [ 2 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  parsedPolicy ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												parsedPolicy . Conditions . ContentLengthRange  =  contentLengthRange { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 10:30:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Min :    min , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Max :    max , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Valid :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Condition should be valid.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  parsedPolicy ,  fmt . Errorf ( "Unknown type %s of conditional field value %s found in POST policy form" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													reflect . TypeOf ( condt ) . String ( ) ,  condt ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  parsedPolicy ,  fmt . Errorf ( "Unknown field %s of type %s found in POST policy form" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												condt ,  reflect . TypeOf ( condt ) . String ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  parsedPolicy ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-18 15:03:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// checkPolicyCond returns a boolean to indicate if a condition is satisfied according
  
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// to the passed operator
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  checkPolicyCond ( op  string ,  input1 ,  input2  string )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  op  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  policyCondEqual : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  input1  ==  input2 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  policyCondStartsWith : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  strings . HasPrefix ( input1 ,  input2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-13 08:08:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// checkPostPolicy - apply policy conditions and validate input values.
  
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// (http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html)
  
						 
					
						
							
								
									
										
										
										
											2019-03-06 04:10:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  checkPostPolicy ( formValues  http . Header ,  postPolicyForm  PostPolicyForm )  error  {  
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if policy document expiry date is still not reached
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! postPolicyForm . Expiration . After ( UTCNow ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 04:10:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Invalid according to Policy: Policy expired" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 03:35:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check all formValues appear in postPolicyForm or return error. #https://github.com/minio/minio/issues/17391
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									checkHeader  :=  map [ string ] [ ] string { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ignoreKeys  :=  map [ string ] bool { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  key ,  value  :=  range  formValues  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ignoreKeys [ key ] ,  postPolicyIgnoreKeys [ key ] ,  strings . HasPrefix ( key ,  encrypt . SseGenericHeader ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  strings . HasPrefix ( key ,  "X-Amz-Ignore-" ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ignoreKey  :=  strings . Replace ( key ,  "X-Amz-Ignore-" ,  "" ,  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ignoreKeys [ ignoreKey ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// if it have already
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delete ( checkHeader ,  ignoreKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											checkHeader [ key ]  =  value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-02 14:45:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// map to store the metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									metaMap  :=  make ( map [ string ] string ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  policy  :=  range  postPolicyForm . Conditions . Policies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . HasPrefix ( policy . Key ,  "$x-amz-meta-" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											formCanonicalName  :=  http . CanonicalHeaderKey ( strings . TrimPrefix ( policy . Key ,  "$" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											metaMap [ formCanonicalName ]  =  policy . Value 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-02 14:45:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if any extra metadata field is passed as input
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  key  :=  range  formValues  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . HasPrefix ( key ,  "X-Amz-Meta-" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  ok  :=  metaMap [ key ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  fmt . Errorf ( "Invalid according to Policy: Extra input fields: %s" ,  key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Flag to indicate if all policies conditions are satisfied
 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 09:35:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  condPassed  bool 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterate over policy conditions and check them against received form fields
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  policy  :=  range  postPolicyForm . Conditions . Policies  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Form fields names are in canonical format, convert conditions names
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// to canonical for simplification purpose, so `$key` will become `Key`
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										formCanonicalName  :=  http . CanonicalHeaderKey ( strings . TrimPrefix ( policy . Key ,  "$" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Operator for the current policy condition
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										op  :=  policy . Operator 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 03:35:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Multiple values should not occur
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( checkHeader [ formCanonicalName ] )  >=  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  fmt . Errorf ( "Invalid according to Policy: Policy Condition failed: [%s, %s, %s]. FormValues have multiple values: [%s]" ,  op ,  policy . Key ,  policy . Value ,  strings . Join ( checkHeader [ formCanonicalName ] ,  ", " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// If the current policy condition is known
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  startsWithSupported ,  condFound  :=  startsWithConds [ policy . Key ] ;  condFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Check if the current condition supports starts-with operator
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  op  ==  policyCondStartsWith  &&  ! startsWithSupported  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 04:10:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  fmt . Errorf ( "Invalid according to Policy: Policy Condition failed" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Check if current policy condition is satisfied
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-23 05:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											condPassed  =  checkPolicyCond ( op ,  formValues . Get ( formCanonicalName ) ,  policy . Value ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 04:10:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! condPassed  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  fmt . Errorf ( "Invalid according to Policy: Policy Condition failed" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  strings . HasPrefix ( policy . Key ,  "$x-amz-meta-" )  ||  strings . HasPrefix ( policy . Key ,  "$x-amz-" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// This covers all conditions X-Amz-Meta-* and X-Amz-*
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Check if policy condition is satisfied
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											condPassed  =  checkPolicyCond ( op ,  formValues . Get ( formCanonicalName ) ,  policy . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! condPassed  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  fmt . Errorf ( "Invalid according to Policy: Policy Condition failed: [%s, %s, %s]" ,  op ,  policy . Key ,  policy . Value ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 03:35:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delete ( checkHeader ,  formCanonicalName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-06 18:52:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For SignV2 - Signature/AWSAccessKeyId field will be ignored.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 00:45:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  ok  :=  formValues [ xhttp . AmzSignatureV2 ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delete ( checkHeader ,  xhttp . AmzSignatureV2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-06 18:52:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  k  :=  range  checkHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// case-insensitivity for AWSAccessKeyId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  strings . EqualFold ( k ,  xhttp . AmzAccessKeyID )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												delete ( checkHeader ,  k ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 00:45:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-26 03:35:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( checkHeader )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logKeys  :=  make ( [ ] string ,  0 ,  len ( checkHeader ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  key  :=  range  checkHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logKeys  =  append ( logKeys ,  key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-10 22:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Each form field that you specify in a form must appear in the list of policy conditions. %q not specified in the policy." ,  strings . Join ( logKeys ,  ", " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-03 09:00:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 04:10:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}