feat(09-05): add recon full/list commands and remove stub
- cmd/recon.go owns reconCmd with full and list subcommands - Wires pkg/recon.Engine.SweepAll + Dedup with ExampleSource registered - Adds --stealth, --respect-robots (default true), --query flags - Removes reconCmd stub from cmd/stubs.go
This commit is contained in:
74
cmd/recon.go
Normal file
74
cmd/recon.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/salvacybersec/keyhunter/pkg/recon"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
reconStealth bool
|
||||||
|
reconRespectRobots bool
|
||||||
|
reconQuery string
|
||||||
|
)
|
||||||
|
|
||||||
|
var reconCmd = &cobra.Command{
|
||||||
|
Use: "recon",
|
||||||
|
Short: "Run OSINT recon across internet sources",
|
||||||
|
Long: "Run OSINT recon sweeps across registered sources. Phase 9 ships with an ExampleSource stub; real sources land in Phases 10-16.",
|
||||||
|
}
|
||||||
|
|
||||||
|
var reconFullCmd = &cobra.Command{
|
||||||
|
Use: "full",
|
||||||
|
Short: "Sweep all enabled sources in parallel and deduplicate findings",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
eng := buildReconEngine()
|
||||||
|
cfg := recon.Config{
|
||||||
|
Stealth: reconStealth,
|
||||||
|
RespectRobots: reconRespectRobots,
|
||||||
|
Query: reconQuery,
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
all, err := eng.SweepAll(ctx, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("recon sweep: %w", err)
|
||||||
|
}
|
||||||
|
deduped := recon.Dedup(all)
|
||||||
|
fmt.Printf("recon: swept %d sources, %d findings (%d after dedup)\n", len(eng.List()), len(all), len(deduped))
|
||||||
|
for _, f := range deduped {
|
||||||
|
fmt.Printf(" [%s] %s %s %s\n", f.SourceType, f.ProviderName, f.KeyMasked, f.Source)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var reconListCmd = &cobra.Command{
|
||||||
|
Use: "list",
|
||||||
|
Short: "List registered recon sources",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
eng := buildReconEngine()
|
||||||
|
for _, name := range eng.List() {
|
||||||
|
fmt.Println(name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildReconEngine constructs the recon Engine with all sources registered.
|
||||||
|
// Phase 9 ships ExampleSource only; Phases 10-16 will add real sources here
|
||||||
|
// (or via a registration side-effect in their packages).
|
||||||
|
func buildReconEngine() *recon.Engine {
|
||||||
|
e := recon.NewEngine()
|
||||||
|
e.Register(recon.ExampleSource{})
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
reconFullCmd.Flags().BoolVar(&reconStealth, "stealth", false, "enable UA rotation and jitter delays")
|
||||||
|
reconFullCmd.Flags().BoolVar(&reconRespectRobots, "respect-robots", true, "respect robots.txt for web-scraping sources")
|
||||||
|
reconFullCmd.Flags().StringVar(&reconQuery, "query", "", "override query sent to each source")
|
||||||
|
reconCmd.AddCommand(reconFullCmd)
|
||||||
|
reconCmd.AddCommand(reconListCmd)
|
||||||
|
}
|
||||||
@@ -21,11 +21,7 @@ var verifyCmd = &cobra.Command{
|
|||||||
RunE: notImplemented("verify", "Phase 5"),
|
RunE: notImplemented("verify", "Phase 5"),
|
||||||
}
|
}
|
||||||
|
|
||||||
var reconCmd = &cobra.Command{
|
// reconCmd is implemented in cmd/recon.go (Phase 9).
|
||||||
Use: "recon",
|
|
||||||
Short: "Run OSINT recon across internet sources (Phase 9+)",
|
|
||||||
RunE: notImplemented("recon", "Phase 9"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// keysCmd is implemented in cmd/keys.go (Phase 6).
|
// keysCmd is implemented in cmd/keys.go (Phase 6).
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user