@@ -2,6 +2,7 @@ package iamlivecore
2
2
3
3
import (
4
4
_ "embed"
5
+ b64 "encoding/base64"
5
6
"encoding/json"
6
7
"fmt"
7
8
"log"
@@ -15,8 +16,9 @@ import (
15
16
16
17
"github.com/buger/goterm"
17
18
"github.com/kenshaw/baseconv"
18
- "github.com/ucarion/urlpath"
19
19
"github.com/oliveagle/jsonpath"
20
+ "github.com/ucarion/urlpath"
21
+ "google.golang.org/protobuf/proto"
20
22
)
21
23
22
24
//go:embed map.json
@@ -36,10 +38,10 @@ var gcpCallLog []string
36
38
var azureCallLog []AzureEntry
37
39
38
40
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
43
45
}
44
46
45
47
// JSON maps
@@ -58,6 +60,7 @@ type Entry struct {
58
60
URIParameters map [string ]string
59
61
FinalHTTPStatusCode int `json:"FinalHttpStatusCode"`
60
62
AccessKey string `json:"AccessKey"`
63
+ SessionToken string `json:"SessionToken"`
61
64
}
62
65
63
66
// Statement is a single statement within an IAM policy
@@ -74,12 +77,12 @@ type IAMPolicy struct {
74
77
}
75
78
76
79
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"`
83
86
AssignableScopes []string `json:"AssignableScopes"`
84
87
}
85
88
@@ -234,11 +237,11 @@ func GetPolicyDocument() []byte {
234
237
sort .Strings (dataActionsList )
235
238
236
239
returnPolicy := AzureIAMPolicy {
237
- Actions : actionsList ,
238
- DataActions : dataActionsList ,
239
- NotDataActions : make ([]string , 0 ),
240
+ Actions : actionsList ,
241
+ DataActions : dataActionsList ,
242
+ NotDataActions : make ([]string , 0 ),
240
243
AssignableScopes : make ([]string , 0 ),
241
- IsCustom : true ,
244
+ IsCustom : true ,
242
245
}
243
246
244
247
doc , err := json .MarshalIndent (returnPolicy , "" , " " )
@@ -375,14 +378,14 @@ type AzurePath map[string]AzurePermission
375
378
type AzurePermission map [string ]AzurePermissionDetail
376
379
377
380
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"`
381
384
}
382
385
383
386
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"`
386
389
}
387
390
388
391
type gcpIamMapBase struct {
@@ -790,6 +793,31 @@ func getStatementsForProxyCall(call Entry) (statements []Statement) {
790
793
return statements
791
794
}
792
795
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
+
793
821
func getAccountFromAccessKey (accessKeyId string ) (string , error ) {
794
822
base10 := "0123456789"
795
823
base32AwsFlavour := "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
@@ -887,19 +915,33 @@ func subARNParameters(arn string, call Entry, specialsOnly bool) (bool, []string
887
915
}
888
916
}
889
917
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
+
890
932
partition := "aws"
891
- if strings .HasPrefix (call . Region , "cn" ) {
933
+ if strings .HasPrefix (region , "cn" ) {
892
934
partition = "aws-cn"
893
935
}
894
- if strings .HasPrefix (call . Region , "us-gov" ) {
936
+ if strings .HasPrefix (region , "us-gov" ) {
895
937
partition = "aws-us-gov"
896
938
}
897
939
898
940
anyUnresolved := false
899
941
result := []string {}
900
942
for _ , arn := range arns {
901
943
arn = regexp .MustCompile (`\$\{Partition\}` ).ReplaceAllString (arn , partition )
902
- arn = regexp .MustCompile (`\$\{Region\}` ).ReplaceAllString (arn , call . Region )
944
+ arn = regexp .MustCompile (`\$\{Region\}` ).ReplaceAllString (arn , region )
903
945
arn = regexp .MustCompile (`\$\{Account\}` ).ReplaceAllString (arn , account )
904
946
unresolvedArn := arn
905
947
arn = regexp .MustCompile (`\$\{.+?\}` ).ReplaceAllString (arn , "*" ) // TODO: preserve ${aws:*} variables
0 commit comments