diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 8ff847336..c899ce2d0 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -459,7 +459,7 @@ var errorCodes = errorCodeMap{ }, ErrInvalidAccessKeyID: { Code: "InvalidAccessKeyId", - Description: "The access key ID you provided does not exist in our records.", + Description: "The Access Key Id you provided does not exist in our records.", HTTPStatusCode: http.StatusForbidden, }, ErrInvalidBucketName: { diff --git a/cmd/bucket-handlers_test.go b/cmd/bucket-handlers_test.go index 19ac4aba8..3f4f80706 100644 --- a/cmd/bucket-handlers_test.go +++ b/cmd/bucket-handlers_test.go @@ -115,7 +115,7 @@ func testGetBucketLocationHandler(obj ObjectLayer, instanceType, bucketName stri errorResponse: APIErrorResponse{ Resource: SlashSeparator + bucketName + SlashSeparator, Code: "InvalidAccessKeyId", - Message: "The access key ID you provided does not exist in our records.", + Message: "The Access Key Id you provided does not exist in our records.", }, shouldPass: false, }, diff --git a/cmd/bucket-lifecycle-handlers_test.go b/cmd/bucket-lifecycle-handlers_test.go index b8d5772a2..3af5daf05 100644 --- a/cmd/bucket-lifecycle-handlers_test.go +++ b/cmd/bucket-lifecycle-handlers_test.go @@ -72,7 +72,7 @@ func testBucketLifecycleHandlersWrongCredentials(obj ObjectLayer, instanceType, errorResponse: APIErrorResponse{ Resource: SlashSeparator + bucketName + SlashSeparator, Code: "InvalidAccessKeyId", - Message: "The access key ID you provided does not exist in our records.", + Message: "The Access Key Id you provided does not exist in our records.", }, shouldPass: false, }, @@ -102,7 +102,7 @@ func testBucketLifecycleHandlersWrongCredentials(obj ObjectLayer, instanceType, errorResponse: APIErrorResponse{ Resource: SlashSeparator + bucketName + SlashSeparator, Code: "InvalidAccessKeyId", - Message: "The access key ID you provided does not exist in our records.", + Message: "The Access Key Id you provided does not exist in our records.", }, shouldPass: false, }, @@ -132,7 +132,7 @@ func testBucketLifecycleHandlersWrongCredentials(obj ObjectLayer, instanceType, errorResponse: APIErrorResponse{ Resource: SlashSeparator + bucketName + SlashSeparator, Code: "InvalidAccessKeyId", - Message: "The access key ID you provided does not exist in our records.", + Message: "The Access Key Id you provided does not exist in our records.", }, shouldPass: false, }, diff --git a/cmd/sts-errors.go b/cmd/sts-errors.go index ac93bf64a..7f10af191 100644 --- a/cmd/sts-errors.go +++ b/cmd/sts-errors.go @@ -27,9 +27,12 @@ import ( ) // writeSTSErrorRespone writes error headers -func writeSTSErrorResponse(ctx context.Context, w http.ResponseWriter, errCode STSErrorCode, errCtxt error) { - err := stsErrCodes.ToSTSErr(errCode) - if err.Code == "InternalError" { +func writeSTSErrorResponse(ctx context.Context, w http.ResponseWriter, isErrCodeSTS bool, errCode STSErrorCode, errCtxt error) { + var err STSError + if isErrCodeSTS { + err = stsErrCodes.ToSTSErr(errCode) + } + if err.Code == "InternalError" || !isErrCodeSTS { aerr := getAPIError(APIErrorCode(errCode)) if aerr.Code != "InternalError" { err.Code = aerr.Code @@ -81,7 +84,6 @@ type STSErrorCode int // Error codes, non exhaustive list - http://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithSAML.html const ( ErrSTSNone STSErrorCode = iota - ErrSTSInvalidService ErrSTSAccessDenied ErrSTSMissingParameter ErrSTSInvalidParameterValue diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 5cc0f3b07..16b193193 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -110,37 +110,37 @@ func registerSTSRouter(router *mux.Router) { Queries(stsLDAPPassword, "{LDAPPassword:.*}") } -func checkAssumeRoleAuth(ctx context.Context, r *http.Request) (user auth.Credentials, stsErr STSErrorCode) { +func checkAssumeRoleAuth(ctx context.Context, r *http.Request) (user auth.Credentials, isErrCodeSTS bool, stsErr STSErrorCode) { switch getRequestAuthType(r) { default: - return user, ErrSTSAccessDenied + return user, true, ErrSTSAccessDenied case authTypeSigned: s3Err := isReqAuthenticated(ctx, r, globalServerRegion, serviceSTS) - if STSErrorCode(s3Err) != ErrSTSNone { - return user, STSErrorCode(s3Err) + if APIErrorCode(s3Err) != ErrNone { + return user, false, STSErrorCode(s3Err) } var owner bool user, owner, s3Err = getReqAccessKeyV4(r, globalServerRegion, serviceSTS) - if STSErrorCode(s3Err) != ErrSTSNone { - return user, STSErrorCode(s3Err) + if APIErrorCode(s3Err) != ErrNone { + return user, false, STSErrorCode(s3Err) } // Root credentials are not allowed to use STS API if owner { - return user, ErrSTSAccessDenied + return user, true, ErrSTSAccessDenied } } // Session tokens are not allowed in STS AssumeRole requests. if getSessionToken(r) != "" { - return user, ErrSTSAccessDenied + return user, true, ErrSTSAccessDenied } // Temporary credentials or Service accounts cannot generate further temporary credentials. if user.IsTemp() || user.IsServiceAccount() { - return user, ErrSTSAccessDenied + return user, true, ErrSTSAccessDenied } - return user, ErrSTSNone + return user, true, ErrSTSNone } // AssumeRole - implementation of AWS STS API AssumeRole to get temporary @@ -149,18 +149,18 @@ func checkAssumeRoleAuth(ctx context.Context, r *http.Request) (user auth.Creden func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "AssumeRole") - user, stsErr := checkAssumeRoleAuth(ctx, r) + user, isErrCodeSTS, stsErr := checkAssumeRoleAuth(ctx, r) if stsErr != ErrSTSNone { - writeSTSErrorResponse(ctx, w, stsErr, nil) + writeSTSErrorResponse(ctx, w, isErrCodeSTS, stsErr, nil) return } if err := r.ParseForm(); err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } if r.Form.Get(stsVersion) != stsAPIVersion { - writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get(stsVersion), stsAPIVersion)) + writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get(stsVersion), stsAPIVersion)) return } @@ -168,7 +168,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) { switch action { case assumeRole: default: - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action)) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action)) return } @@ -180,20 +180,20 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) { // The plain text that you use for both inline and managed session // policies shouldn't exceed 2048 characters. if len(sessionPolicyStr) > 2048 { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy shouldn't exceed 2048 characters")) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy shouldn't exceed 2048 characters")) return } if len(sessionPolicyStr) > 0 { sessionPolicy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicyStr))) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } // Version in policy must not be empty if sessionPolicy.Version == "" { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Version cannot be empty expecting '2012-10-17'")) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Version cannot be empty expecting '2012-10-17'")) return } } @@ -202,13 +202,13 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) { m := make(map[string]interface{}) m[expClaim], err = openid.GetDefaultExpiration(r.Form.Get(stsDurationSeconds)) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } policies, err := globalIAMSys.PolicyDBGet(user.AccessKey, false) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } @@ -226,7 +226,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) { secret := globalActiveCred.SecretKey cred, err := auth.GetNewCredentialsWithMetadata(m, secret) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err) return } @@ -236,7 +236,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) { // Set the newly generated credentials. if err = globalIAMSys.SetTempUser(cred.AccessKey, cred, policyName); err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err) return } @@ -263,12 +263,12 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ // Parse the incoming form data. if err := r.ParseForm(); err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } if r.Form.Get(stsVersion) != stsAPIVersion { - writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get("Version"), stsAPIVersion)) + writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get("Version"), stsAPIVersion)) return } @@ -276,7 +276,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ switch action { case clientGrants, webIdentity: default: - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action)) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action)) return } @@ -284,13 +284,13 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ defer logger.AuditLog(w, r, action, nil) if globalOpenIDValidators == nil { - writeSTSErrorResponse(ctx, w, ErrSTSNotInitialized, errServerNotInitialized) + writeSTSErrorResponse(ctx, w, true, ErrSTSNotInitialized, errServerNotInitialized) return } v, err := globalOpenIDValidators.Get("jwt") if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } @@ -305,16 +305,16 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ case openid.ErrTokenExpired: switch action { case clientGrants: - writeSTSErrorResponse(ctx, w, ErrSTSClientGrantsExpiredToken, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSClientGrantsExpiredToken, err) case webIdentity: - writeSTSErrorResponse(ctx, w, ErrSTSWebIdentityExpiredToken, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSWebIdentityExpiredToken, err) } return case auth.ErrInvalidDuration: - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } @@ -323,20 +323,20 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ // The plain text that you use for both inline and managed session // policies shouldn't exceed 2048 characters. if len(sessionPolicyStr) > 2048 { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters")) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters")) return } if len(sessionPolicyStr) > 0 { sessionPolicy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicyStr))) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } // Version in policy must not be empty if sessionPolicy.Version == "" { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid session policy version")) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid session policy version")) return } } @@ -348,7 +348,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ secret := globalActiveCred.SecretKey cred, err := auth.GetNewCredentialsWithMetadata(m, secret) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err) return } @@ -368,7 +368,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ // Set the newly generated credentials. if err = globalIAMSys.SetTempUser(cred.AccessKey, cred, policyName); err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err) return } @@ -430,12 +430,12 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * // Parse the incoming form data. if err := r.ParseForm(); err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } if r.Form.Get(stsVersion) != stsAPIVersion { - writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get("Version"), stsAPIVersion)) + writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, fmt.Errorf("Invalid STS API version %s, expecting %s", r.Form.Get("Version"), stsAPIVersion)) return } @@ -443,7 +443,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * switch action { case ldapIdentity: default: - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action)) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Unsupported action %s", action)) return } @@ -454,7 +454,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * ldapPassword := r.Form.Get(stsLDAPPassword) if ldapUsername == "" || ldapPassword == "" { - writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, fmt.Errorf("LDAPUsername and LDAPPassword cannot be empty")) + writeSTSErrorResponse(ctx, w, true, ErrSTSMissingParameter, fmt.Errorf("LDAPUsername and LDAPPassword cannot be empty")) return } @@ -463,20 +463,20 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * // The plain text that you use for both inline and managed session // policies shouldn't exceed 2048 characters. if len(sessionPolicyStr) > 2048 { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters")) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Session policy should not exceed 2048 characters")) return } if len(sessionPolicyStr) > 0 { sessionPolicy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicyStr))) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } // Version in policy must not be empty if sessionPolicy.Version == "" { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, fmt.Errorf("Version needs to be specified in session policy")) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Version needs to be specified in session policy")) return } } @@ -484,7 +484,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * groups, err := globalLDAPConfig.Bind(ldapUsername, ldapPassword) if err != nil { err = fmt.Errorf("LDAP server connection failure: %w", err) - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err) return } @@ -501,7 +501,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * secret := globalActiveCred.SecretKey cred, err := auth.GetNewCredentialsWithMetadata(m, secret) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err) return } @@ -517,7 +517,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r * // LDAP policies are applied automatically using their ldapUser, ldapGroups // mapping. if err = globalIAMSys.SetTempUser(cred.AccessKey, cred, ""); err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err) + writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err) return }