Skip to content

Commit

Permalink
add context from session token support
Browse files Browse the repository at this point in the history
  • Loading branch information
iann0036 committed Jan 11, 2025
1 parent e9bd3a1 commit 03b8ff0
Show file tree
Hide file tree
Showing 153 changed files with 36,083 additions and 71 deletions.
17 changes: 11 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
module github.com/iann0036/iamlive

go 1.16
go 1.21

toolchain go1.23.0

require (
github.com/buger/goterm v1.0.0
github.com/clbanning/mxj/v2 v2.5.5
github.com/iann0036/goproxy v0.0.0-20210510114007-b2700d29a571
github.com/kenshaw/baseconv v0.1.1
github.com/mitchellh/go-homedir v1.1.0
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/tidwall/gjson v1.16.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb
google.golang.org/protobuf v1.36.2
gopkg.in/ini.v1 v1.62.0
)

require (
github.com/smartystreets/goconvey v1.6.4 // indirect
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 // indirect
)
17 changes: 10 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ github.com/buger/goterm v1.0.0 h1:ZB6uUlY8+sjJyFGzz2WpRqX2XYPeXVgtZAOJMwOsTWM=
github.com/buger/goterm v1.0.0/go.mod h1:16STi3LquiscTIHA8SXUNKEa/Cnu4ZHBH8NsCaWgso0=
github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/iann0036/goproxy v0.0.0-20210510114007-b2700d29a571 h1:K4C1opSq+EjlLkYUNUKpg/1w0MduaGFDl/iozfZfT4s=
github.com/iann0036/goproxy v0.0.0-20210510114007-b2700d29a571/go.mod h1:amSgpNkX5MQL0glEHvPGg0UKbKOhBVem3kNHGhlINS4=
github.com/iann0036/goproxy/ext v0.0.0-20210327125723-db8542d80343 h1:oaTtJCbhCLSueJFpPwaxWZDKBBBkTv6+y5lprHPGFWs=
github.com/iann0036/goproxy/ext v0.0.0-20210327125723-db8542d80343/go.mod h1:3SmG3m42N72tivanmYJdY5joEWn5/bEzgawDLBA7T6g=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kenshaw/baseconv v0.1.1 h1:oAu/C7ipUT2PqT9DT0mZDGDg4URIglizZMjPv9oCu0E=
github.com/kenshaw/baseconv v0.1.1/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI=
Expand All @@ -15,15 +19,10 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI=
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb h1:Ywfo8sUltxogBpFuMOFRrrSifO788kAFxmvVw31PtQQ=
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb/go.mod h1:ikPs9bRWicNw3S7XpJ8sK/smGwU9WcSVU3dy9qahYBM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand All @@ -33,5 +32,9 @@ golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLh
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
88 changes: 65 additions & 23 deletions iamlivecore/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package iamlivecore

import (
_ "embed"
b64 "encoding/base64"
"encoding/json"
"fmt"
"log"
Expand All @@ -15,8 +16,9 @@ import (

"github.com/buger/goterm"
"github.com/kenshaw/baseconv"
"github.com/ucarion/urlpath"
"github.com/oliveagle/jsonpath"
"github.com/ucarion/urlpath"
"google.golang.org/protobuf/proto"
)

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

type AzureEntry struct {
HTTPMethod string
Path string
Parameters map[string][]string
Body []byte
HTTPMethod string
Path string
Parameters map[string][]string
Body []byte
}

// JSON maps
Expand All @@ -58,6 +60,7 @@ type Entry struct {
URIParameters map[string]string
FinalHTTPStatusCode int `json:"FinalHttpStatusCode"`
AccessKey string `json:"AccessKey"`
SessionToken string `json:"SessionToken"`
}

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

type AzureIAMPolicy struct {
Name string `json:"Name"`
IsCustom bool `json:"IsCustom"`
Description string `json:"Description"`
Actions []string `json:"Actions"`
DataActions []string `json:"DataActions"`
NotDataActions []string `json:"NotDataActions"`
Name string `json:"Name"`
IsCustom bool `json:"IsCustom"`
Description string `json:"Description"`
Actions []string `json:"Actions"`
DataActions []string `json:"DataActions"`
NotDataActions []string `json:"NotDataActions"`
AssignableScopes []string `json:"AssignableScopes"`
}

Expand Down Expand Up @@ -234,11 +237,11 @@ func GetPolicyDocument() []byte {
sort.Strings(dataActionsList)

returnPolicy := AzureIAMPolicy{
Actions: actionsList,
DataActions: dataActionsList,
NotDataActions: make([]string, 0),
Actions: actionsList,
DataActions: dataActionsList,
NotDataActions: make([]string, 0),
AssignableScopes: make([]string, 0),
IsCustom: true,
IsCustom: true,
}

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

type AzurePermissionDetail struct {
Automated bool `json:"automated"`
IsDataAction bool `json:"isDataAction"`
Condition AzureCondition `json:"condition"`
Automated bool `json:"automated"`
IsDataAction bool `json:"isDataAction"`
Condition AzureCondition `json:"condition"`
}

type AzureCondition struct {
PathEquals map[string]string `json:"pathEquals"`
BodyPathExists string `json:"bodyPathExists"`
PathEquals map[string]string `json:"pathEquals"`
BodyPathExists string `json:"bodyPathExists"`
}

type gcpIamMapBase struct {
Expand Down Expand Up @@ -790,6 +793,31 @@ func getStatementsForProxyCall(call Entry) (statements []Statement) {
return statements
}

func getAccountAndRegionFromSessionToken(sessionToken string) (string, string, error) {
in, err := b64.StdEncoding.DecodeString(sessionToken)
if err != nil {
return "", "", err
}

msgType := in[0]
in = in[1:]

if msgType == 33 || msgType == 2 {
var t33Msg SessionType33Message
if err := proto.Unmarshal(in, &t33Msg); err != nil {
return "", "", err
}

return t33Msg.GetUser().GetAccountId(), t33Msg.GetRegion(), nil
} else if msgType == 23 {
return "", "", nil
} else if msgType == 21 {
return "", "", nil
}

return "", "", fmt.Errorf("unknown session token type")
}

func getAccountFromAccessKey(accessKeyId string) (string, error) {
base10 := "0123456789"
base32AwsFlavour := "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
Expand Down Expand Up @@ -887,19 +915,33 @@ func subARNParameters(arn string, call Entry, specialsOnly bool) (bool, []string
}
}

region := call.Region

if call.SessionToken != "" {
newAccount, newRegion, err := getAccountAndRegionFromSessionToken(call.SessionToken)
if err == nil {
if newAccount != "" {
account = newAccount
}
if newRegion != "" {
region = newRegion
}
}
}

partition := "aws"
if strings.HasPrefix(call.Region, "cn") {
if strings.HasPrefix(region, "cn") {
partition = "aws-cn"
}
if strings.HasPrefix(call.Region, "us-gov") {
if strings.HasPrefix(region, "us-gov") {
partition = "aws-us-gov"
}

anyUnresolved := false
result := []string{}
for _, arn := range arns {
arn = regexp.MustCompile(`\$\{Partition\}`).ReplaceAllString(arn, partition)
arn = regexp.MustCompile(`\$\{Region\}`).ReplaceAllString(arn, call.Region)
arn = regexp.MustCompile(`\$\{Region\}`).ReplaceAllString(arn, region)
arn = regexp.MustCompile(`\$\{Account\}`).ReplaceAllString(arn, account)
unresolvedArn := arn
arn = regexp.MustCompile(`\$\{.+?\}`).ReplaceAllString(arn, "*") // TODO: preserve ${aws:*} variables
Expand Down
12 changes: 11 additions & 1 deletion iamlivecore/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -746,8 +746,9 @@ func handleAWSRequest(req *http.Request, body []byte, respCode int) {
}
}

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

sessionTokenHeader := req.Header.Get("X-Amz-Security-Token")
sessionTokenQuery := req.URL.Query().Get("X-Amz-Security-Token")
if sessionTokenHeader != "" {
sessionToken = sessionTokenHeader
} else if sessionTokenQuery != "" {
sessionToken = sessionTokenQuery
}

if selectedCandidate.Action != "" {
action = selectedCandidate.Action
params = selectedCandidate.Params
Expand All @@ -773,6 +782,7 @@ func handleAWSRequest(req *http.Request, body []byte, respCode int) {
URIParameters: uriparams,
FinalHTTPStatusCode: respCode,
AccessKey: accessKey,
SessionToken: sessionToken,
})

handleLoggedCall()
Expand Down
Loading

0 comments on commit 03b8ff0

Please sign in to comment.