Skip to content

Commit 10c24db

Browse files
committed
Detect account ID automatically via access key
1 parent 47c1792 commit 10c24db

13 files changed

Lines changed: 367 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ You can optionally also include the following arguments to the `iamlive` command
6464

6565
**--ca-key:** _[experimental]_ the CA certificate key to use for proxy mode (_default: ~/.iamlive/ca.key_)
6666

67-
**--account-id:** _[experimental]_ the AWS account ID to use in policy outputs within proxy mode (_default: 123456789012_)
67+
**--account-id:** _[experimental]_ the AWS account ID to use in policy outputs within proxy mode (_default: 123456789012 unless detected_)
6868

6969
_Basic Example (CSM Mode)_
7070

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129
77
github.com/clbanning/mxj/v2 v2.3.2
88
github.com/iann0036/goproxy v0.0.0-20210327130343-c3ec674b9022
9+
github.com/kenshaw/baseconv v0.1.0
910
github.com/mitchellh/go-homedir v1.1.0
1011
github.com/smartystreets/goconvey v1.6.4 // indirect
1112
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ github.com/iann0036/goproxy v0.0.0-20210327130343-c3ec674b9022/go.mod h1:amSgpNk
88
github.com/iann0036/goproxy/ext v0.0.0-20210327125723-db8542d80343 h1:oaTtJCbhCLSueJFpPwaxWZDKBBBkTv6+y5lprHPGFWs=
99
github.com/iann0036/goproxy/ext v0.0.0-20210327125723-db8542d80343/go.mod h1:3SmG3m42N72tivanmYJdY5joEWn5/bEzgawDLBA7T6g=
1010
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
11+
github.com/kenshaw/baseconv v0.1.0 h1:eZd+ZgNkU8jxjp/dTwAhPwI923cz1PE7ARRKUPXjZ5A=
12+
github.com/kenshaw/baseconv v0.1.0/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI=
1113
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
1214
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
1315
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=

logger.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
605643
func 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"

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func parseConfig() {
4242
bindAddr := "127.0.0.1:10080"
4343
caBundle := "~/.iamlive/ca.pem"
4444
caKey := "~/.iamlive/ca.key"
45-
accountID := "123456789012"
45+
accountID := ""
4646
background := false
4747
forceWildcardResource := false
4848

proxy.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,17 @@ func handleAWSRequest(req *http.Request, body []byte, respCode int) {
578578
}
579579
}
580580

581+
// attempt to determine access key from auth header
582+
accessKey := ""
583+
authHeader := req.Header.Get("Authorization")
584+
credOffset := strings.Index(authHeader, "Credential=")
585+
if credOffset > 0 {
586+
endOfKey := strings.Index(authHeader[credOffset:], "/")
587+
if endOfKey > 0 {
588+
accessKey = authHeader[credOffset+len("Credential=") : credOffset+endOfKey]
589+
}
590+
}
591+
581592
callLog = append(callLog, Entry{
582593
Region: region,
583594
Type: "ProxyCall",
@@ -586,6 +597,7 @@ func handleAWSRequest(req *http.Request, body []byte, respCode int) {
586597
Parameters: params,
587598
URIParameters: uriparams,
588599
FinalHTTPStatusCode: respCode,
600+
AccessKey: accessKey,
589601
})
590602

591603
handleLoggedCall()

vendor/github.com/kenshaw/baseconv/.gitignore

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/kenshaw/baseconv/.travis.yml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/kenshaw/baseconv/LICENSE

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/kenshaw/baseconv/README.md

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)