Skip to content

Commit

Permalink
Improve errors for aws login with an unbound ARN (#10036) (#10213)
Browse files Browse the repository at this point in the history
* Improve errors for aws login with an unbound ARN

* Factor hasWildcardBind into its own function

Co-authored-by: Calvin Leung Huang <[email protected]>

Co-authored-by: Mike Grass <[email protected]>
  • Loading branch information
calvn and mikegrass authored Oct 22, 2020
1 parent b0701f4 commit 802a690
Showing 1 changed file with 26 additions and 8 deletions.
34 changes: 26 additions & 8 deletions builtin/credential/aws/path_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -1047,18 +1047,23 @@ func (b *backend) pathLoginRenewIam(ctx context.Context, req *logical.Request, d
case !roleEntry.ResolveAWSUniqueIDs && strutil.StrListContains(roleEntry.BoundIamPrincipalARNs, canonicalArn): // check 2 passed
default:
// check 3 is a bit more complex, so we do it last
// only try to look up full ARNs if there's a wildcard ARN in BoundIamPrincipalIDs.
if !hasWildcardBind(roleEntry.BoundIamPrincipalARNs) {
return nil, fmt.Errorf("role %q no longer bound to ARN %q", roleName, canonicalArn)
}

fullArn := b.getCachedUserId(clientUserId)
if fullArn == "" {
entity, err := parseIamArn(canonicalArn)
if err != nil {
return nil, errwrap.Wrapf(fmt.Sprintf("error parsing ARN %q: {{err}}", canonicalArn), err)
return nil, errwrap.Wrapf(fmt.Sprintf("error parsing ARN %q when updating login for role %q: {{err}}", canonicalArn, roleName), err)
}
fullArn, err = b.fullArn(ctx, entity, req.Storage)
if err != nil {
return nil, errwrap.Wrapf(fmt.Sprintf("error looking up full ARN of entity %v: {{err}}", entity), err)
return nil, errwrap.Wrapf(fmt.Sprintf("error looking up full ARN of entity %v when updating login for role %q: {{err}}", entity, roleName), err)
}
if fullArn == "" {
return nil, fmt.Errorf("got empty string back when looking up full ARN of entity %v", entity)
return nil, fmt.Errorf("got empty string back when looking up full ARN of entity %v when updating login for role %q", entity, roleName)
}
if clientUserId != "" {
b.setCachedUserId(clientUserId, fullArn)
Expand All @@ -1072,7 +1077,7 @@ func (b *backend) pathLoginRenewIam(ctx context.Context, req *logical.Request, d
}
}
if !matchedWildcardBind {
return nil, fmt.Errorf("role no longer bound to ARN %q", canonicalArn)
return nil, fmt.Errorf("role %q no longer bound to ARN %q", roleName, canonicalArn)
}
}
}
Expand Down Expand Up @@ -1317,15 +1322,19 @@ func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request,
case strutil.StrListContains(roleEntry.BoundIamPrincipalIDs, callerUniqueId): // check 1 passed
case !roleEntry.ResolveAWSUniqueIDs && strutil.StrListContains(roleEntry.BoundIamPrincipalARNs, entity.canonicalArn()): // check 2 passed
default:
// evaluate check 3
// evaluate check 3 -- only try to look up full ARNs if there's a wildcard ARN in BoundIamPrincipalIDs.
if !hasWildcardBind(roleEntry.BoundIamPrincipalARNs) {
return logical.ErrorResponse("IAM Principal %q does not belong to the role %q", callerID.Arn, roleName), nil
}

fullArn := b.getCachedUserId(callerUniqueId)
if fullArn == "" {
fullArn, err = b.fullArn(ctx, entity, req.Storage)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("error looking up full ARN of entity %v: %v", entity, err)), nil
return logical.ErrorResponse("error looking up full ARN of entity %v when attempting login for role %q: %v", entity, roleName, err), nil
}
if fullArn == "" {
return logical.ErrorResponse(fmt.Sprintf("got empty string back when looking up full ARN of entity %v", entity)), nil
return logical.ErrorResponse("got empty string back when looking up full ARN of entity %v when attempting login for role %q", entity, roleName), nil
}
b.setCachedUserId(callerUniqueId, fullArn)
}
Expand All @@ -1337,7 +1346,7 @@ func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request,
}
}
if !matchedWildcardBind {
return logical.ErrorResponse(fmt.Sprintf("IAM Principal %q does not belong to the role %q", callerID.Arn, roleName)), nil
return logical.ErrorResponse("IAM Principal %q does not belong to the role %q", callerID.Arn, roleName), nil
}
}
}
Expand Down Expand Up @@ -1409,6 +1418,15 @@ func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request,
}, nil
}

func hasWildcardBind(boundIamPrincipalARNs []string) bool {
for _, principalARN := range boundIamPrincipalARNs {
if strings.HasSuffix(principalARN, "*") {
return true
}
}
return false
}

// Validate that the iam_request_body passed is valid for the STS request
func validateLoginIamRequestBody(body string) error {
qs, err := url.ParseQuery(body)
Expand Down

0 comments on commit 802a690

Please sign in to comment.