Skip to content

Commit

Permalink
Merge pull request #128 from hashicorp/resolve-profile-name
Browse files Browse the repository at this point in the history
Pre-validates Profile names before using it for authentication
  • Loading branch information
gdavison authored Feb 23, 2022
2 parents b5b7fa3 + 4a955da commit 8a086fb
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 21 deletions.
24 changes: 17 additions & 7 deletions aws_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/aws/smithy-go/middleware"
"github.com/hashicorp/aws-sdk-go-base/v2/internal/constants"
"github.com/hashicorp/aws-sdk-go-base/v2/internal/endpoints"
"github.com/hashicorp/aws-sdk-go-base/v2/internal/expand"
)

func GetAwsConfig(ctx context.Context, c *Config) (aws.Config, error) {
Expand Down Expand Up @@ -176,14 +175,25 @@ func commonLoadOptions(c *Config) ([]func(*config.LoadOptions) error, error) {
config.WithLogger(debugLogger{}),
}

if len(c.SharedConfigFiles) > 0 {
configFiles, err := expand.FilePaths(c.SharedConfigFiles)
if err != nil {
return nil, fmt.Errorf("expanding shared config files: %w", err)
}
sharedCredentialsFiles, err := c.ResolveSharedCredentialsFiles()
if err != nil {
return nil, err
}
if len(sharedCredentialsFiles) > 0 {
loadOptions = append(
loadOptions,
config.WithSharedCredentialsFiles(sharedCredentialsFiles),
)
}

sharedConfigFiles, err := c.ResolveSharedConfigFiles()
if err != nil {
return nil, err
}
if len(sharedConfigFiles) > 0 {
loadOptions = append(
loadOptions,
config.WithSharedConfigFiles(configFiles),
config.WithSharedConfigFiles(sharedConfigFiles),
)
}

Expand Down
34 changes: 34 additions & 0 deletions aws_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,40 @@ source_profile = SourceSharedCredentials
},
ExpectedRegion: "us-east-1",
},
{
Config: &Config{
Region: "us-east-1",
},
Description: "invalid profile name from envvar",
EnvironmentVariables: map[string]string{
"AWS_PROFILE": "no-such-profile",
},
ExpectedError: func(err error) bool {
var e config.SharedConfigProfileNotExistError
return errors.As(err, &e)
},
SharedCredentialsFile: `
[some-profile]
aws_access_key_id = DefaultSharedCredentialsAccessKey
aws_secret_access_key = DefaultSharedCredentialsSecretKey
`,
},
{
Config: &Config{
Profile: "no-such-profile",
Region: "us-east-1",
},
Description: "invalid profile name from config",
ExpectedError: func(err error) bool {
var e config.SharedConfigProfileNotExistError
return errors.As(err, &e)
},
SharedCredentialsFile: `
[some-profile]
aws_access_key_id = DefaultSharedCredentialsAccessKey
aws_secret_access_key = DefaultSharedCredentialsSecretKey
`,
},
}

for _, testCase := range testCases {
Expand Down
56 changes: 44 additions & 12 deletions credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts/types"
"github.com/hashicorp/aws-sdk-go-base/v2/internal/expand"
)

func getCredentialsProvider(ctx context.Context, c *Config) (aws.CredentialsProvider, string, error) {
Expand All @@ -20,7 +19,6 @@ func getCredentialsProvider(ctx context.Context, c *Config) (aws.CredentialsProv
}
loadOptions = append(
loadOptions,
config.WithSharedConfigProfile(c.Profile),
// Bypass retries when validating authentication
config.WithRetryer(func() aws.Retryer {
return aws.NopRetryer{}
Expand All @@ -29,6 +27,50 @@ func getCredentialsProvider(ctx context.Context, c *Config) (aws.CredentialsProv
// is not included in the aws.Config returned to the caller
config.WithEndpointResolverWithOptions(credentialsEndpointResolver(c)),
)

envConfig, err := config.NewEnvConfig()
if err != nil {
return nil, "", err
}

profile := c.Profile
if profile == "" {
profile = envConfig.SharedConfigProfile
}

sharedCredentialsFiles, err := c.ResolveSharedCredentialsFiles()
if err != nil {
return nil, "", err
}
if len(sharedCredentialsFiles) == 0 {
sharedCredentialsFiles = []string{envConfig.SharedCredentialsFile}
}

sharedConfigFiles, err := c.ResolveSharedConfigFiles()
if err != nil {
return nil, "", err
}
if len(sharedConfigFiles) == 0 {
sharedConfigFiles = []string{envConfig.SharedConfigFile}
}

// The default AWS SDK authentication flow silently ignores invalid Profiles. Pre-validate that the Profile exists
// https://github.com/aws/aws-sdk-go-v2/issues/1591
if profile != "" {
_, err := config.LoadSharedConfigProfile(ctx, profile, func(opts *config.LoadSharedConfigOptions) {
opts.CredentialsFiles = sharedCredentialsFiles
opts.ConfigFiles = sharedConfigFiles
})
if err != nil {
return nil, "", err
}
loadOptions = append(
loadOptions,
config.WithSharedConfigProfile(c.Profile),
)

}

if c.AccessKey != "" || c.SecretKey != "" || c.Token != "" {
loadOptions = append(
loadOptions,
Expand All @@ -41,16 +83,6 @@ func getCredentialsProvider(ctx context.Context, c *Config) (aws.CredentialsProv
),
)
}
if len(c.SharedCredentialsFiles) > 0 {
credsFiles, err := expand.FilePaths(c.SharedCredentialsFiles)
if err != nil {
return nil, "", fmt.Errorf("expanding shared credentials files: %w", err)
}
loadOptions = append(
loadOptions,
config.WithSharedCredentialsFiles(credsFiles),
)
}

cfg, err := config.LoadDefaultConfig(ctx, loadOptions...)
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,19 @@ func (c Config) CustomCABundleReader() (*bytes.Reader, error) {
}
return bytes.NewReader(bundle), nil
}

func (c Config) ResolveSharedConfigFiles() ([]string, error) {
v, err := expand.FilePaths(c.SharedConfigFiles)
if err != nil {
return []string{}, fmt.Errorf("expanding shared config files: %w", err)
}
return v, nil
}

func (c Config) ResolveSharedCredentialsFiles() ([]string, error) {
v, err := expand.FilePaths(c.SharedCredentialsFiles)
if err != nil {
return []string{}, fmt.Errorf("expanding shared credentials files: %w", err)
}
return v, nil
}
1 change: 1 addition & 0 deletions v2/awsv1shim/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2
require (
github.com/aws/aws-sdk-go v1.42.52
github.com/aws/aws-sdk-go-v2 v1.13.0
github.com/aws/aws-sdk-go-v2/config v1.13.1
github.com/aws/aws-sdk-go-v2/credentials v1.8.0
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0
github.com/google/go-cmp v0.5.7
Expand Down
39 changes: 37 additions & 2 deletions v2/awsv1shim/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (
"testing"
"time"

"github.com/aws/aws-sdk-go-v2/aws/retry"
retryv2 "github.com/aws/aws-sdk-go-v2/aws/retry"
configv2 "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client"
Expand Down Expand Up @@ -857,6 +858,40 @@ region = us-east-1
},
ExpectedRegion: "us-east-1",
},
{
Config: &awsbase.Config{
Region: "us-east-1",
},
Description: "invalid profile name from envvar",
EnvironmentVariables: map[string]string{
"AWS_PROFILE": "no-such-profile",
},
ExpectedError: func(err error) bool {
var e configv2.SharedConfigProfileNotExistError
return errors.As(err, &e)
},
SharedCredentialsFile: `
[some-profile]
aws_access_key_id = DefaultSharedCredentialsAccessKey
aws_secret_access_key = DefaultSharedCredentialsSecretKey
`,
},
{
Config: &awsbase.Config{
Profile: "no-such-profile",
Region: "us-east-1",
},
Description: "invalid profile name from config",
ExpectedError: func(err error) bool {
var e configv2.SharedConfigProfileNotExistError
return errors.As(err, &e)
},
SharedCredentialsFile: `
[some-profile]
aws_access_key_id = DefaultSharedCredentialsAccessKey
aws_secret_access_key = DefaultSharedCredentialsSecretKey
`,
},
}

for _, testCase := range testCases {
Expand Down Expand Up @@ -1213,7 +1248,7 @@ func TestMaxAttempts(t *testing.T) {
AccessKey: servicemocks.MockStaticAccessKey,
SecretKey: servicemocks.MockStaticSecretKey,
},
ExpectedMaxAttempts: retry.DefaultMaxAttempts,
ExpectedMaxAttempts: retryv2.DefaultMaxAttempts,
},

"config": {
Expand Down

0 comments on commit 8a086fb

Please sign in to comment.