From 02fb2d2e57a828d883c2f75c7d9e81679d14ddbc Mon Sep 17 00:00:00 2001 From: Jon Hadfield Date: Wed, 8 May 2024 23:17:56 +0100 Subject: [PATCH] inform user if available provider isn't defined in configuration. --- cmd/root.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++ process/process.go | 17 +++++++++++++ session/session.go | 20 +++++++++++----- 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index f8daeb9..234a291 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -151,67 +151,119 @@ func initConfig(cmd *cobra.Command) error { if v.IsSet("providers.abuseipdb.enabled") { sess.Providers.AbuseIPDB.Enabled = ToPtr(v.GetBool("providers.abuseipdb.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "AbuseIPDB provider not defined in config") + sess.Messages.Mu.Unlock() } + sess.Providers.AbuseIPDB.MaxAge = v.GetInt("providers.abuseipdb.max_age") sess.Providers.AbuseIPDB.ResultCacheTTL = v.GetInt64("providers.abuseipdb.result_cache_ttl") if v.IsSet("providers.annotated.enabled") { sess.Providers.Annotated.Enabled = ToPtr(v.GetBool("providers.annotated.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "Annotated provider not defined in config") + sess.Messages.Mu.Unlock() } + sess.Providers.Annotated.Paths = v.GetStringSlice("providers.annotated.paths") sess.Providers.Annotated.DocumentCacheTTL = v.GetInt64("providers.annotated.document_cache_ttl") if v.IsSet("providers.aws.enabled") { sess.Providers.AWS.Enabled = ToPtr(v.GetBool("providers.aws.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "AWS provider not defined in config") + sess.Messages.Mu.Unlock() } + sess.Providers.AWS.URL = v.GetString("providers.aws.url") sess.Providers.AWS.DocumentCacheTTL = v.GetInt64("providers.aws.document_cache_ttl") if v.IsSet("providers.azure.enabled") { sess.Providers.Azure.Enabled = ToPtr(v.GetBool("providers.azure.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "Azure provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.Azure.URL = v.GetString("providers.azure.url") + sess.Providers.Azure.DocumentCacheTTL = v.GetInt64("providers.azure.document_cache_ttl") if v.IsSet("providers.criminalip.enabled") { sess.Providers.CriminalIP.Enabled = ToPtr(v.GetBool("providers.criminalip.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "Criminal IP provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.CriminalIP.ResultCacheTTL = v.GetInt64("providers.criminalip.result_cache_ttl") if v.IsSet("providers.digitalocean.enabled") { sess.Providers.DigitalOcean.Enabled = ToPtr(v.GetBool("providers.digitalocean.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "DigitalOcean provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.DigitalOcean.URL = v.GetString("providers.digitalocean.url") sess.Providers.DigitalOcean.DocumentCacheTTL = v.GetInt64("providers.digitalocean.document_cache_ttl") if v.IsSet("providers.gcp.enabled") { sess.Providers.GCP.Enabled = ToPtr(v.GetBool("providers.gcp.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "GCP provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.GCP.URL = v.GetString("providers.gcp.url") sess.Providers.GCP.DocumentCacheTTL = v.GetInt64("providers.gcp.document_cache_ttl") if v.IsSet("providers.googlebot.enabled") { sess.Providers.Googlebot.Enabled = ToPtr(v.GetBool("providers.googlebot.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "Googlebot provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.Googlebot.URL = v.GetString("providers.googlebot.url") if v.IsSet("providers.icloudpr.enabled") { sess.Providers.ICloudPR.Enabled = ToPtr(v.GetBool("providers.icloudpr.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "iCloud Private Relay provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.ICloudPR.URL = v.GetString("providers.icloudpr.url") sess.Providers.ICloudPR.DocumentCacheTTL = v.GetInt64("providers.icloudpr.document_cache_ttl") if v.IsSet("providers.ipurl.enabled") { sess.Providers.IPURL.Enabled = ToPtr(v.GetBool("providers.ipurl.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "IP URL provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.IPURL.URLs = v.GetStringSlice("providers.ipurl.urls") sess.Providers.IPURL.DocumentCacheTTL = v.GetInt64("providers.ipurl.document_cache_ttl") if v.IsSet("providers.linode.enabled") { sess.Providers.Linode.Enabled = ToPtr(v.GetBool("providers.linode.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "Linode provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.Linode.DocumentCacheTTL = v.GetInt64("providers.linode.document_cache_ttl") sess.Providers.Linode.URL = v.GetString("providers.linode.url") sess.Providers.Shodan.ResultCacheTTL = v.GetInt64("providers.shodan.result_cache_ttl") if v.IsSet("providers.shodan.enabled") { sess.Providers.Shodan.Enabled = ToPtr(v.GetBool("providers.shodan.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "Shodan provider not defined in config") + sess.Messages.Mu.Unlock() } if v.IsSet("providers.shodan.api_key") { sess.Providers.Shodan.APIKey = v.GetString("providers.shodan.api_key") @@ -219,12 +271,20 @@ func initConfig(cmd *cobra.Command) error { if v.IsSet("providers.ptr.enabled") { sess.Providers.PTR.Enabled = ToPtr(v.GetBool("providers.ptr.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "PTR provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.PTR.ResultCacheTTL = v.GetInt64("providers.ptr.result_cache_ttl") sess.Providers.PTR.Nameservers = v.GetStringSlice("providers.ptr.nameservers") if v.IsSet("providers.ipapi.enabled") { sess.Providers.IPAPI.Enabled = ToPtr(v.GetBool("providers.ipapi.enabled")) + } else { + sess.Messages.Mu.Lock() + sess.Messages.Info = append(sess.Messages.Info, "IPAPI provider not defined in config") + sess.Messages.Mu.Unlock() } sess.Providers.IPAPI.APIKey = v.GetString("providers.ipapi.api_key") sess.Providers.IPAPI.ResultCacheTTL = v.GetInt64("providers.ipapi.result_cache_ttl") diff --git a/process/process.go b/process/process.go index 3fbe3ec..9724e76 100644 --- a/process/process.go +++ b/process/process.go @@ -3,6 +3,7 @@ package process import ( "encoding/json" "fmt" + "github.com/jedib0t/go-pretty/v6/text" "log/slog" "os" "path/filepath" @@ -302,6 +303,8 @@ func output(sess *session.Session, runners map[string]providers.ProviderClient, } present.Tables(sess, tables) + + outputMessages(sess) case "json": jo, err := generateJSON(results) if err != nil { @@ -311,6 +314,8 @@ func output(sess *session.Session, runners map[string]providers.ProviderClient, if err = present.JSON(&jo); err != nil { return fmt.Errorf("error outputting JSON: %w", err) } + + outputMessages(sess) default: return fmt.Errorf("unsupported output format: %s", sess.Config.Global.Output) } @@ -318,6 +323,18 @@ func output(sess *session.Session, runners map[string]providers.ProviderClient, return nil } +func outputMessages(sess *session.Session) { + for x := range sess.Messages.Error { + _, _ = fmt.Fprintf(os.Stderr, "%s %s\n", text.FgRed.Sprint("[ERROR]"), sess.Messages.Info[x]) + } + for x := range sess.Messages.Warning { + _, _ = fmt.Fprintf(os.Stderr, "%s %s\n", text.FgYellow.Sprint("[WARN]"), sess.Messages.Warning[x]) + } + for x := range sess.Messages.Info { + _, _ = fmt.Fprintf(os.Stderr, "%s %s\n", text.FgGreen.Sprint("[INFO]"), sess.Messages.Info[x]) + } +} + func generateTables(conf *session.Session, runners map[string]providers.ProviderClient, results *findHostsResults) []*table.Writer { var tables generateTablesResults diff --git a/session/session.go b/session/session.go index c7bbb75..50421b7 100644 --- a/session/session.go +++ b/session/session.go @@ -47,6 +47,13 @@ func CreateStats() *Stats { } } +type Messages struct { + Mu sync.Mutex + Info []string + Warning []string + Error []string +} + func New() *Session { return &Session{ Stats: CreateStats(), @@ -86,12 +93,13 @@ type Session struct { Version string SemVer string } - Logger *slog.Logger - Stats *Stats - Target *os.File - Output string - Cache *badger.DB - Config Config + Logger *slog.Logger + Stats *Stats + Target *os.File + Output string + Messages Messages + Cache *badger.DB + Config Config HTTPClient *retryablehttp.Client Host netip.Addr