Skip to content

Commit 03b8ff0

Browse files
committed
add context from session token support
1 parent e9bd3a1 commit 03b8ff0

File tree

153 files changed

+36083
-71
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+36083
-71
lines changed

go.mod

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
module github.com/iann0036/iamlive
22

3-
go 1.16
3+
go 1.21
4+
5+
toolchain go1.23.0
46

57
require (
68
github.com/buger/goterm v1.0.0
79
github.com/clbanning/mxj/v2 v2.5.5
810
github.com/iann0036/goproxy v0.0.0-20210510114007-b2700d29a571
911
github.com/kenshaw/baseconv v0.1.1
1012
github.com/mitchellh/go-homedir v1.1.0
11-
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect
12-
github.com/smartystreets/goconvey v1.6.4 // indirect
13-
github.com/tidwall/gjson v1.16.0 // indirect
14-
github.com/tidwall/pretty v1.2.1 // indirect
15-
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect
13+
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852
14+
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb
15+
google.golang.org/protobuf v1.36.2
1616
gopkg.in/ini.v1 v1.62.0
1717
)
18+
19+
require (
20+
github.com/smartystreets/goconvey v1.6.4 // indirect
21+
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 // indirect
22+
)

go.sum

+10-7
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ github.com/buger/goterm v1.0.0 h1:ZB6uUlY8+sjJyFGzz2WpRqX2XYPeXVgtZAOJMwOsTWM=
22
github.com/buger/goterm v1.0.0/go.mod h1:16STi3LquiscTIHA8SXUNKEa/Cnu4ZHBH8NsCaWgso0=
33
github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
44
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
5+
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
6+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
7+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
58
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
69
github.com/iann0036/goproxy v0.0.0-20210510114007-b2700d29a571 h1:K4C1opSq+EjlLkYUNUKpg/1w0MduaGFDl/iozfZfT4s=
710
github.com/iann0036/goproxy v0.0.0-20210510114007-b2700d29a571/go.mod h1:amSgpNkX5MQL0glEHvPGg0UKbKOhBVem3kNHGhlINS4=
811
github.com/iann0036/goproxy/ext v0.0.0-20210327125723-db8542d80343 h1:oaTtJCbhCLSueJFpPwaxWZDKBBBkTv6+y5lprHPGFWs=
912
github.com/iann0036/goproxy/ext v0.0.0-20210327125723-db8542d80343/go.mod h1:3SmG3m42N72tivanmYJdY5joEWn5/bEzgawDLBA7T6g=
13+
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
1014
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
1115
github.com/kenshaw/baseconv v0.1.1 h1:oAu/C7ipUT2PqT9DT0mZDGDg4URIglizZMjPv9oCu0E=
1216
github.com/kenshaw/baseconv v0.1.1/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI=
@@ -15,15 +19,10 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
1519
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI=
1620
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4=
1721
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
22+
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
1823
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
24+
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
1925
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
20-
github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
21-
github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
22-
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
23-
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
24-
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
25-
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
26-
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
2726
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ=
2827
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM=
2928
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -33,5 +32,9 @@ golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLh
3332
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3433
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
3534
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
35+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
36+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
37+
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
38+
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
3639
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
3740
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

iamlivecore/logger.go

+65-23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package iamlivecore
22

33
import (
44
_ "embed"
5+
b64 "encoding/base64"
56
"encoding/json"
67
"fmt"
78
"log"
@@ -15,8 +16,9 @@ import (
1516

1617
"github.com/buger/goterm"
1718
"github.com/kenshaw/baseconv"
18-
"github.com/ucarion/urlpath"
1919
"github.com/oliveagle/jsonpath"
20+
"github.com/ucarion/urlpath"
21+
"google.golang.org/protobuf/proto"
2022
)
2123

2224
//go:embed map.json
@@ -36,10 +38,10 @@ var gcpCallLog []string
3638
var azureCallLog []AzureEntry
3739

3840
type AzureEntry struct {
39-
HTTPMethod string
40-
Path string
41-
Parameters map[string][]string
42-
Body []byte
41+
HTTPMethod string
42+
Path string
43+
Parameters map[string][]string
44+
Body []byte
4345
}
4446

4547
// JSON maps
@@ -58,6 +60,7 @@ type Entry struct {
5860
URIParameters map[string]string
5961
FinalHTTPStatusCode int `json:"FinalHttpStatusCode"`
6062
AccessKey string `json:"AccessKey"`
63+
SessionToken string `json:"SessionToken"`
6164
}
6265

6366
// Statement is a single statement within an IAM policy
@@ -74,12 +77,12 @@ type IAMPolicy struct {
7477
}
7578

7679
type AzureIAMPolicy struct {
77-
Name string `json:"Name"`
78-
IsCustom bool `json:"IsCustom"`
79-
Description string `json:"Description"`
80-
Actions []string `json:"Actions"`
81-
DataActions []string `json:"DataActions"`
82-
NotDataActions []string `json:"NotDataActions"`
80+
Name string `json:"Name"`
81+
IsCustom bool `json:"IsCustom"`
82+
Description string `json:"Description"`
83+
Actions []string `json:"Actions"`
84+
DataActions []string `json:"DataActions"`
85+
NotDataActions []string `json:"NotDataActions"`
8386
AssignableScopes []string `json:"AssignableScopes"`
8487
}
8588

@@ -234,11 +237,11 @@ func GetPolicyDocument() []byte {
234237
sort.Strings(dataActionsList)
235238

236239
returnPolicy := AzureIAMPolicy{
237-
Actions: actionsList,
238-
DataActions: dataActionsList,
239-
NotDataActions: make([]string, 0),
240+
Actions: actionsList,
241+
DataActions: dataActionsList,
242+
NotDataActions: make([]string, 0),
240243
AssignableScopes: make([]string, 0),
241-
IsCustom: true,
244+
IsCustom: true,
242245
}
243246

244247
doc, err := json.MarshalIndent(returnPolicy, "", " ")
@@ -375,14 +378,14 @@ type AzurePath map[string]AzurePermission
375378
type AzurePermission map[string]AzurePermissionDetail
376379

377380
type AzurePermissionDetail struct {
378-
Automated bool `json:"automated"`
379-
IsDataAction bool `json:"isDataAction"`
380-
Condition AzureCondition `json:"condition"`
381+
Automated bool `json:"automated"`
382+
IsDataAction bool `json:"isDataAction"`
383+
Condition AzureCondition `json:"condition"`
381384
}
382385

383386
type AzureCondition struct {
384-
PathEquals map[string]string `json:"pathEquals"`
385-
BodyPathExists string `json:"bodyPathExists"`
387+
PathEquals map[string]string `json:"pathEquals"`
388+
BodyPathExists string `json:"bodyPathExists"`
386389
}
387390

388391
type gcpIamMapBase struct {
@@ -790,6 +793,31 @@ func getStatementsForProxyCall(call Entry) (statements []Statement) {
790793
return statements
791794
}
792795

796+
func getAccountAndRegionFromSessionToken(sessionToken string) (string, string, error) {
797+
in, err := b64.StdEncoding.DecodeString(sessionToken)
798+
if err != nil {
799+
return "", "", err
800+
}
801+
802+
msgType := in[0]
803+
in = in[1:]
804+
805+
if msgType == 33 || msgType == 2 {
806+
var t33Msg SessionType33Message
807+
if err := proto.Unmarshal(in, &t33Msg); err != nil {
808+
return "", "", err
809+
}
810+
811+
return t33Msg.GetUser().GetAccountId(), t33Msg.GetRegion(), nil
812+
} else if msgType == 23 {
813+
return "", "", nil
814+
} else if msgType == 21 {
815+
return "", "", nil
816+
}
817+
818+
return "", "", fmt.Errorf("unknown session token type")
819+
}
820+
793821
func getAccountFromAccessKey(accessKeyId string) (string, error) {
794822
base10 := "0123456789"
795823
base32AwsFlavour := "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
@@ -887,19 +915,33 @@ func subARNParameters(arn string, call Entry, specialsOnly bool) (bool, []string
887915
}
888916
}
889917

918+
region := call.Region
919+
920+
if call.SessionToken != "" {
921+
newAccount, newRegion, err := getAccountAndRegionFromSessionToken(call.SessionToken)
922+
if err == nil {
923+
if newAccount != "" {
924+
account = newAccount
925+
}
926+
if newRegion != "" {
927+
region = newRegion
928+
}
929+
}
930+
}
931+
890932
partition := "aws"
891-
if strings.HasPrefix(call.Region, "cn") {
933+
if strings.HasPrefix(region, "cn") {
892934
partition = "aws-cn"
893935
}
894-
if strings.HasPrefix(call.Region, "us-gov") {
936+
if strings.HasPrefix(region, "us-gov") {
895937
partition = "aws-us-gov"
896938
}
897939

898940
anyUnresolved := false
899941
result := []string{}
900942
for _, arn := range arns {
901943
arn = regexp.MustCompile(`\$\{Partition\}`).ReplaceAllString(arn, partition)
902-
arn = regexp.MustCompile(`\$\{Region\}`).ReplaceAllString(arn, call.Region)
944+
arn = regexp.MustCompile(`\$\{Region\}`).ReplaceAllString(arn, region)
903945
arn = regexp.MustCompile(`\$\{Account\}`).ReplaceAllString(arn, account)
904946
unresolvedArn := arn
905947
arn = regexp.MustCompile(`\$\{.+?\}`).ReplaceAllString(arn, "*") // TODO: preserve ${aws:*} variables

iamlivecore/proxy.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -746,8 +746,9 @@ func handleAWSRequest(req *http.Request, body []byte, respCode int) {
746746
}
747747
}
748748

749-
// attempt to determine access key from auth header
749+
// attempt to determine access key and/or session token from auth header
750750
accessKey := ""
751+
sessionToken := ""
751752
authHeader := req.Header.Get("Authorization")
752753
credOffset := strings.Index(authHeader, "Credential=")
753754
if credOffset > 0 {
@@ -757,6 +758,14 @@ func handleAWSRequest(req *http.Request, body []byte, respCode int) {
757758
}
758759
}
759760

761+
sessionTokenHeader := req.Header.Get("X-Amz-Security-Token")
762+
sessionTokenQuery := req.URL.Query().Get("X-Amz-Security-Token")
763+
if sessionTokenHeader != "" {
764+
sessionToken = sessionTokenHeader
765+
} else if sessionTokenQuery != "" {
766+
sessionToken = sessionTokenQuery
767+
}
768+
760769
if selectedCandidate.Action != "" {
761770
action = selectedCandidate.Action
762771
params = selectedCandidate.Params
@@ -773,6 +782,7 @@ func handleAWSRequest(req *http.Request, body []byte, respCode int) {
773782
URIParameters: uriparams,
774783
FinalHTTPStatusCode: respCode,
775784
AccessKey: accessKey,
785+
SessionToken: sessionToken,
776786
})
777787

778788
handleLoggedCall()

0 commit comments

Comments
 (0)