github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/image/registry/ecr/ecr.go (about) 1 package ecr 2 3 import ( 4 "context" 5 "encoding/base64" 6 "strings" 7 8 "github.com/aws/aws-sdk-go-v2/aws" 9 "github.com/aws/aws-sdk-go-v2/config" 10 "github.com/aws/aws-sdk-go-v2/credentials" 11 "github.com/aws/aws-sdk-go-v2/service/ecr" 12 "golang.org/x/xerrors" 13 14 "github.com/devseccon/trivy/pkg/fanal/types" 15 ) 16 17 const ecrURL = "amazonaws.com" 18 19 type ecrAPI interface { 20 GetAuthorizationToken(ctx context.Context, params *ecr.GetAuthorizationTokenInput, optFns ...func(*ecr.Options)) (*ecr.GetAuthorizationTokenOutput, error) 21 } 22 23 type ECR struct { 24 Client ecrAPI 25 } 26 27 func getSession(option types.RegistryOptions) (aws.Config, error) { 28 // create custom credential information if option is valid 29 if option.AWSSecretKey != "" && option.AWSAccessKey != "" && option.AWSRegion != "" { 30 return config.LoadDefaultConfig( 31 context.TODO(), 32 config.WithRegion(option.AWSRegion), 33 config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(option.AWSAccessKey, option.AWSSecretKey, option.AWSSessionToken)), 34 ) 35 } 36 return config.LoadDefaultConfig(context.TODO()) 37 } 38 39 func (e *ECR) CheckOptions(domain string, option types.RegistryOptions) error { 40 if !strings.HasSuffix(domain, ecrURL) { 41 return xerrors.Errorf("ECR : %w", types.InvalidURLPattern) 42 } 43 44 cfg, err := getSession(option) 45 if err != nil { 46 return err 47 } 48 49 svc := ecr.NewFromConfig(cfg) 50 e.Client = svc 51 return nil 52 } 53 54 func (e *ECR) GetCredential(ctx context.Context) (username, password string, err error) { 55 input := &ecr.GetAuthorizationTokenInput{} 56 result, err := e.Client.GetAuthorizationToken(ctx, input) 57 if err != nil { 58 return "", "", xerrors.Errorf("failed to get authorization token: %w", err) 59 } 60 for _, data := range result.AuthorizationData { 61 b, err := base64.StdEncoding.DecodeString(*data.AuthorizationToken) 62 if err != nil { 63 return "", "", xerrors.Errorf("base64 decode failed: %w", err) 64 } 65 // e.g. AWS:eyJwYXlsb2... 66 split := strings.SplitN(string(b), ":", 2) 67 if len(split) == 2 { 68 return split[0], split[1], nil 69 } 70 } 71 return "", "", nil 72 }