@@ -9,10 +9,12 @@ import (
99 "reflect"
1010 "regexp"
1111 "sort"
12+ "strconv"
1213 "strings"
1314 "time"
1415
1516 "github.com/buger/goterm"
17+ "github.com/kenshaw/baseconv"
1618)
1719
1820//go:embed map.json
@@ -35,7 +37,8 @@ type Entry struct {
3537 Method string `json:"Api"`
3638 Parameters map [string ][]string
3739 URIParameters map [string ]string
38- FinalHTTPStatusCode int `json:"FinalHttpStatusCode"`
40+ FinalHTTPStatusCode int `json:"FinalHttpStatusCode"`
41+ AccessKey string `json:"AccessKey"`
3942}
4043
4144// Statement is a single statement within an IAM policy
@@ -602,6 +605,41 @@ func getStatementsForProxyCall(call Entry) (statements []Statement) {
602605 return statements
603606}
604607
608+ func getAccountFromAccessKey (accessKeyId string ) (string , error ) {
609+ base10 := "0123456789"
610+ base32AwsFlavour := "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
611+
612+ offsetStr , err := baseconv .Convert ("QAAAAAAA" , base32AwsFlavour , base10 )
613+ if err != nil {
614+ return "" , err
615+ }
616+ offset , err := strconv .Atoi (offsetStr )
617+ if err != nil {
618+ return "" , err
619+ }
620+
621+ offsetAccountIdStr , err := baseconv .Convert (accessKeyId [4 :12 ], base32AwsFlavour , base10 )
622+ if err != nil {
623+ return "" , err
624+ }
625+ offsetAccountId , err := strconv .Atoi (offsetAccountIdStr )
626+ if err != nil {
627+ return "" , err
628+ }
629+
630+ accountId := 2 * (offsetAccountId - offset )
631+
632+ if strings .Index (base32AwsFlavour , accessKeyId [12 :13 ]) >= strings .Index (base32AwsFlavour , "Q" ) {
633+ accountId ++
634+ }
635+
636+ if accountId < 0 {
637+ return "" , fmt .Errorf ("negative account ID" )
638+ }
639+
640+ return fmt .Sprintf ("%012d" , accountId ), nil
641+ }
642+
605643func subARNParameters (arn string , call Entry , specialsOnly bool ) (bool , []string ) {
606644 arns := []string {arn }
607645
@@ -638,6 +676,15 @@ func subARNParameters(arn string, call Entry, specialsOnly bool) (bool, []string
638676 }
639677
640678 account := * accountIDFlag
679+ var err error
680+
681+ if account == "" && call .AccessKey != "" {
682+ account , err = getAccountFromAccessKey (call .AccessKey )
683+ if err != nil || account == "" {
684+ account = "123456789012"
685+ }
686+ }
687+
641688 partition := "aws"
642689 if call .Region [0 :3 ] == "cn-" {
643690 partition = "aws-cn"
0 commit comments