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  }