-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
315 additions
and
262 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
.idea | ||
gcloud-key.json | ||
vendor | ||
data | ||
*.gen.go | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,86 @@ | ||
package main | ||
|
||
import "github.com/projectdiscovery/chaos-client/internal/runner" | ||
import ( | ||
"fmt" | ||
"github.com/alecthomas/kong" | ||
"github.com/projectdiscovery/chaos-client/internal" | ||
"github.com/projectdiscovery/chaos-client/internal/subdomains" | ||
"github.com/projectdiscovery/gologger" | ||
"github.com/projectdiscovery/gologger/levels" | ||
updateutils "github.com/projectdiscovery/utils/update" | ||
"os" | ||
) | ||
|
||
var cli struct { | ||
Key string `help:"Chaos key for API" short:"k"` | ||
Domain string `help:"Domain to search for subdomains" short:"d"` | ||
Silent bool `help:"Make the output silent"` | ||
Output string `help:"File to write output to (optional)" short:"o"` | ||
Version bool `help:"Show version of chaos"` | ||
Verbose bool `help:"Verbose" short:"v"` | ||
Update bool `help:"update Chaos to latest version" aliases:"up"` | ||
DisableUpdateCheck bool `help:"disable automatic Chaos update check" aliases:"duc"` | ||
Subdomains struct { | ||
Domain string `arg:"" help:"Domain."` | ||
Count bool `help:"Show statistics for the specified domain"` | ||
DL string `help:"File containing domains to search for subdomains (optional)" aliases:"dL"` | ||
JSON bool `help:"Print output as json"` | ||
} `cmd:"" help:"List subdomains"` | ||
|
||
DNS struct { | ||
Paths []string `arg:"" optional:"" help:"Paths to list." type:"path"` | ||
} `cmd:"" help:"Get DNS record"` | ||
} | ||
|
||
func main() { | ||
opts := runner.ParseOptions() | ||
runner.RunEnumeration(opts) | ||
ctx := kong.Parse(&cli, | ||
kong.Name("Chaos"), | ||
kong.Description("Chaos client"), | ||
kong.UsageOnError(), | ||
kong.ConfigureHelp(kong.HelpOptions{ | ||
Compact: true, | ||
Summary: true, | ||
})) | ||
|
||
if cli.Silent { | ||
gologger.DefaultLogger.SetMaxLevel(levels.LevelSilent) | ||
} | ||
internal.ShowBanner() | ||
|
||
if cli.Version { | ||
gologger.Info().Msgf("Current Version: %s\n", internal.Version) | ||
os.Exit(0) | ||
} | ||
|
||
if !cli.DisableUpdateCheck { | ||
latestVersion, err := updateutils.GetVersionCheckCallback("chaos-client")() | ||
if err != nil { | ||
if cli.Verbose { | ||
gologger.Error().Msgf("chaos version check failed: %v", err.Error()) | ||
} | ||
} else { | ||
gologger.Info().Msgf("Current chaos version %v %v", internal.Version, updateutils.GetVersionDescription(internal.Version, latestVersion)) | ||
} | ||
} | ||
|
||
switch ctx.Command() { | ||
case "subdomains <domain>": | ||
opts := subdomains.Options{ | ||
APIKey: cli.Key, | ||
Domain: cli.Subdomains.Domain, | ||
Count: cli.Subdomains.Count, | ||
Silent: cli.Silent, | ||
Output: cli.Output, | ||
DomainsFile: cli.Subdomains.DL, | ||
JSONOutput: cli.Subdomains.JSON, | ||
Version: cli.Version, | ||
Verbose: cli.Verbose, | ||
DisableUpdateCheck: cli.DisableUpdateCheck, | ||
} | ||
opts.ValidateOptions() | ||
subdomains.RunEnumeration(&opts) | ||
default: | ||
fmt.Printf("unexpected command") | ||
os.Exit(1) | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,58 @@ | ||
package internal | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/projectdiscovery/ratelimit" | ||
"github.com/projectdiscovery/retryablehttp-go" | ||
"net/http" | ||
"strconv" | ||
"strings" | ||
time "time" | ||
) | ||
|
||
// HTTPClient is a client for making requests to chaos API | ||
type HTTPClient struct { | ||
apiKey string | ||
httpClient *retryablehttp.Client | ||
ratelimit *ratelimit.Limiter | ||
} | ||
|
||
// NewHTTPClient creates a new client for chaos API communication | ||
func NewHTTPClient(apiKey string) *HTTPClient { | ||
httpclient := retryablehttp.NewClient(retryablehttp.DefaultOptionsSingle) | ||
return &HTTPClient{httpClient: httpclient, apiKey: apiKey} | ||
} | ||
|
||
// do adds apiKey and implements rate limit | ||
func (c *HTTPClient) Do(request *retryablehttp.Request) (*http.Response, error) { | ||
request.Header.Set("Authorization", c.apiKey) | ||
if c.ratelimit != nil { | ||
c.ratelimit.Take() | ||
} | ||
resp, err := c.httpClient.Do(request) | ||
if resp != nil && c.ratelimit == nil { | ||
rl := resp.Header.Get("X-Ratelimit-Limit") | ||
rlMax, err := strconv.Atoi(rl) | ||
if err == nil && rlMax > 0 { | ||
// if er then ratelimit header is not present. Hence, no rate limit | ||
c.ratelimit = ratelimit.New(context.Background(), uint(rlMax), time.Minute) | ||
} | ||
} | ||
return resp, err | ||
} | ||
|
||
type InvalidStatusCodeError struct { | ||
StatusCode int | ||
Message []byte | ||
} | ||
|
||
func (e InvalidStatusCodeError) Error() string { | ||
return fmt.Sprintf("invalid status code received: %d - %s", e.StatusCode, e.Message) | ||
} | ||
|
||
func CheckToken(d *json.Decoder, value string) bool { | ||
token, err := d.Token() | ||
return strings.EqualFold(fmt.Sprint(token), value) && err == nil | ||
} |
Oops, something went wrong.