diff --git a/README.md b/README.md index 24431cd..5bcc6fc 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ You can optionally also include the following arguments to the `iamlive` command **--account-id:** the AWS account ID to use in policy outputs within proxy mode (_default: 123456789012 unless detected_) (_AWS only_) +**--debug:** dumps associated HTTP requests when set in proxy mode (_default: false_) + _Basic Example (CSM Mode)_ ``` diff --git a/iamlivecore/logger.go b/iamlivecore/logger.go index 1f6c0a9..2e48a6d 100644 --- a/iamlivecore/logger.go +++ b/iamlivecore/logger.go @@ -324,15 +324,20 @@ func writePolicyToTerminal() { } policyDoc := string(GetPolicyDocument()) - policyHeight := countRune(policyDoc, '\n') + 1 - goterm.Clear() - goterm.MoveCursor(1, 1) - if goterm.Height() < policyHeight { - fmt.Println("\n\n" + policyDoc) + if *debugFlag { + fmt.Println(policyDoc) } else { - goterm.Println(policyDoc) - goterm.Flush() + policyHeight := countRune(policyDoc, '\n') + 1 + + goterm.Clear() + goterm.MoveCursor(1, 1) + if goterm.Height() < policyHeight { + fmt.Println("\n\n" + policyDoc) + } else { + goterm.Println(policyDoc) + goterm.Flush() + } } } diff --git a/iamlivecore/proxy.go b/iamlivecore/proxy.go index f4f17bd..1004fed 100644 --- a/iamlivecore/proxy.go +++ b/iamlivecore/proxy.go @@ -16,6 +16,7 @@ import ( "log" "math/big" "net/http" + "net/http/httputil" "net/url" "os" "path/filepath" @@ -160,6 +161,11 @@ func loadCAKeys() error { return nil } +func dumpReq(req *http.Request) { + dump, _ := httputil.DumpRequestOut(req, true) + fmt.Printf("%v\n", string(dump)) +} + func createProxy(addr string) { err := loadCAKeys() if err != nil { @@ -170,19 +176,32 @@ func createProxy(addr string) { proxy.Logger = log.New(io.Discard, "", log.LstdFlags) proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm) proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { // TODO: Move to onResponse for HTTP response codes - body, _ := ioutil.ReadAll(req.Body) + var body []byte isAWSHostname, _ := regexp.MatchString(`^.*\.amazonaws\.com(?:\.cn)?$`, req.Host) + isAzureHostname, _ := regexp.MatchString(`^(?:management\.azure\.com)|(?:management\.core\.windows\.net)$`, req.Host) + isGCPHostname, _ := regexp.MatchString(`^.*\.googleapis\.com$`, req.Host) + if isAWSHostname && *providerFlag == "aws" { + if *debugFlag { + dumpReq(req) + } + body, _ = ioutil.ReadAll(req.Body) handleAWSRequest(req, body, 200) - } - isAzureHostname, _ := regexp.MatchString(`^(?:management\.azure\.com)|(?:management\.core\.windows\.net)$`, req.Host) - if isAzureHostname && *providerFlag == "azure" { + } else if isAzureHostname && *providerFlag == "azure" { + if *debugFlag { + dumpReq(req) + } + body, _ = ioutil.ReadAll(req.Body) handleAzureRequest(req, body, 200) - } - isGCPHostname, _ := regexp.MatchString(`^.*\.googleapis\.com$`, req.Host) - if isGCPHostname && *providerFlag == "gcp" { + } else if isGCPHostname && *providerFlag == "gcp" { + if *debugFlag { + dumpReq(req) + } + body, _ = ioutil.ReadAll(req.Body) handleGCPRequest(req, body, 200) + } else { + return req, nil } req.Body = ioutil.NopCloser(bytes.NewBuffer(body)) diff --git a/iamlivecore/service.go b/iamlivecore/service.go index 11e2e41..f9dc7a5 100644 --- a/iamlivecore/service.go +++ b/iamlivecore/service.go @@ -27,6 +27,7 @@ var caBundleFlag *string var caKeyFlag *string var accountIDFlag *string var backgroundFlag *bool +var debugFlag *bool var forceWildcardResourceFlag *bool var cpuProfileFlag = flag.String("cpu-profile", "", "write a CPU profile to this file (for performance testing purposes)") @@ -45,6 +46,7 @@ func parseConfig() { caKey := "~/.iamlive/ca.key" accountID := "" background := false + debug := false forceWildcardResource := false cfgfile, err := homedir.Expand("~/.iamlive/config") @@ -93,6 +95,9 @@ func parseConfig() { if cfg.Section("").HasKey("background") { background, _ = cfg.Section("").Key("background").Bool() } + if cfg.Section("").HasKey("debug") { + debug, _ = cfg.Section("").Key("debug").Bool() + } if cfg.Section("").HasKey("force-wildcard-resource") { forceWildcardResource, _ = cfg.Section("").Key("force-wildcard-resource").Bool() } @@ -113,6 +118,7 @@ func parseConfig() { caKeyFlag = flag.String("ca-key", caKey, "the CA certificate key to use for proxy mode") accountIDFlag = flag.String("account-id", accountID, "the AWS account ID to use in policy outputs within proxy mode") backgroundFlag = flag.Bool("background", background, "when set, the process will return the current PID and run in the background without output") + debugFlag = flag.Bool("debug", debug, "dumps associated HTTP requests when set in proxy mode") forceWildcardResourceFlag = flag.Bool("force-wildcard-resource", forceWildcardResource, "when set, the Resource will always be a wildcard") } @@ -169,7 +175,7 @@ func Run() { } } -func RunWithArgs(provider string, setIni bool, profile string, failsOnly bool, outputFile string, refreshRate int, sortAlphabetical bool, host, mode, bindAddr, caBundle, caKey, accountID string, background, forceWildcardResource bool) { +func RunWithArgs(provider string, setIni bool, profile string, failsOnly bool, outputFile string, refreshRate int, sortAlphabetical bool, host, mode, bindAddr, caBundle, caKey, accountID string, background, debug, forceWildcardResource bool) { providerFlag = &provider setiniFlag = &setIni profileFlag = &profile @@ -184,6 +190,7 @@ func RunWithArgs(provider string, setIni bool, profile string, failsOnly bool, o caKeyFlag = &caKey accountIDFlag = &accountID backgroundFlag = &background + debugFlag = &debug forceWildcardResourceFlag = &forceWildcardResource if *cpuProfileFlag != "" {