mirror of
https://github.com/Vyntral/god-eye.git
synced 2026-05-16 21:43:34 +02:00
3a4c230aa7
Complete architectural overhaul. Replaces the v0.1 monolithic scanner with an event-driven pipeline of auto-registered modules. Foundation (internal/): - eventbus: typed pub/sub, 20 event types, race-safe, drop counter - module: registry with phase-based selection - store: thread-safe host store with per-host locks + deep-copy reads - pipeline: coordinator with phase barriers + panic recovery - config: 5 scan profiles + 3 AI tiers + YAML loader + auto-discovery Modules (26 auto-registered across 6 phases): - Discovery: passive (26 sources), bruteforce, recursive, AXFR, GitHub dorks, CT streaming, permutation, reverse DNS, vhost, ASN, supply chain (npm + PyPI) - Enrichment: HTTP probe + tech fingerprint + TLS appliance ID, ports - Analysis: security checks, takeover (110+ sigs), cloud, JavaScript, GraphQL, JWT, headers (OWASP), HTTP smuggling, AI cascade, Nuclei - Reporting: TXT/JSON/CSV writer + AI scan brief AI layer (internal/ai/ + internal/modules/ai/): - Three profiles: lean (16 GB), balanced (32 GB MoE), heavy (64 GB) - Six event-driven handlers: CVE, JS file, HTTP response, secret filter, multi-agent vuln enrichment, anomaly + executive report - Content-hash cache dedups Ollama calls across hosts - Auto-pull of missing models via /api/pull with streaming progress - End-of-scan AI SCAN BRIEF in terminal with top chains + next actions Nuclei compat layer (internal/nucleitpl/): - Executes ~13k community templates (HTTP subset) - Auto-download of nuclei-templates ZIP to ~/.god-eye/nuclei-templates - Scope filter rejects off-host templates (eliminates OSINT FPs) Operations: - Interactive wizard (internal/wizard/) — zero-flag launch - LivePrinter (internal/tui/) — colorized event stream - Diff engine + scheduler (internal/diff, internal/scheduler) for continuous ASM monitoring with webhook alerts - Proxy support (internal/proxyconf/): http / https / socks5 / socks5h + basic auth Fixes #1 — native SOCKS5 / Tor compatibility via --proxy flag. 185 unit tests across 15 packages, all race-detector clean.
152 lines
3.6 KiB
Go
152 lines
3.6 KiB
Go
package config
|
|
|
|
// View implements module.ConfigView over a *Config. Modules receive a View
|
|
// (not the raw Config pointer) to prevent them from mutating global scan
|
|
// state — reads only.
|
|
//
|
|
// The implementation is intentionally small: it exposes just the shape
|
|
// needed by the module package without pulling in a full generic key/value
|
|
// store. Module-specific settings live in ModuleSettings; typed options
|
|
// should be hoisted to first-class fields on Config when they are used
|
|
// across modules.
|
|
type View struct {
|
|
cfg *Config
|
|
}
|
|
|
|
// NewView wraps cfg as a ConfigView. cfg may be nil, in which case every
|
|
// accessor returns the fallback/zero value.
|
|
func NewView(cfg *Config) *View { return &View{cfg: cfg} }
|
|
|
|
// Profile returns the active profile name ("" when none).
|
|
func (v *View) Profile() string {
|
|
if v == nil || v.cfg == nil {
|
|
return ""
|
|
}
|
|
return v.cfg.Profile
|
|
}
|
|
|
|
// Bool reads a boolean config key by well-known name. Unknown keys return fb.
|
|
// Keys intentionally kept flat to avoid accidental namespacing bugs.
|
|
func (v *View) Bool(key string, fb bool) bool {
|
|
if v == nil || v.cfg == nil {
|
|
return fb
|
|
}
|
|
switch key {
|
|
case "ai.enabled":
|
|
return v.cfg.EnableAI
|
|
case "ai.cascade":
|
|
return v.cfg.AICascade
|
|
case "ai.deep":
|
|
return v.cfg.AIDeepAnalysis
|
|
case "ai.multi_agent":
|
|
return v.cfg.MultiAgent
|
|
case "ai.verbose":
|
|
return v.cfg.AIVerbose
|
|
case "ai.auto_pull":
|
|
return v.cfg.AutoPullModels
|
|
case "silent":
|
|
return v.cfg.Silent
|
|
case "verbose":
|
|
return v.cfg.Verbose
|
|
case "json":
|
|
return v.cfg.JsonOutput
|
|
case "no_brute":
|
|
return v.cfg.NoBrute
|
|
case "no_probe":
|
|
return v.cfg.NoProbe
|
|
case "no_ports":
|
|
return v.cfg.NoPorts
|
|
case "no_takeover":
|
|
return v.cfg.NoTakeover
|
|
case "only_active":
|
|
return v.cfg.OnlyActive
|
|
case "recursive":
|
|
return v.cfg.Recursive
|
|
case "cloud_scan":
|
|
return v.cfg.CloudScan
|
|
case "api_scan":
|
|
return v.cfg.APIScan
|
|
case "secrets_scan":
|
|
return v.cfg.SecretsScan
|
|
case "tech_scan":
|
|
return v.cfg.TechScan
|
|
case "asn_scan":
|
|
return v.cfg.ASNScan
|
|
case "vhost_scan":
|
|
return v.cfg.VHostScan
|
|
case "nuclei_scan":
|
|
return v.cfg.NucleiScan
|
|
case "nuclei_auto_download":
|
|
return v.cfg.NucleiAutoDownload
|
|
}
|
|
return fb
|
|
}
|
|
|
|
// Int reads an int key.
|
|
func (v *View) Int(key string, fb int) int {
|
|
if v == nil || v.cfg == nil {
|
|
return fb
|
|
}
|
|
switch key {
|
|
case "concurrency":
|
|
return v.cfg.Concurrency
|
|
case "timeout":
|
|
return v.cfg.Timeout
|
|
case "recursive.depth":
|
|
return v.cfg.RecursiveDepth
|
|
}
|
|
return fb
|
|
}
|
|
|
|
// String reads a string key.
|
|
func (v *View) String(key string, fb string) string {
|
|
if v == nil || v.cfg == nil {
|
|
return fb
|
|
}
|
|
switch key {
|
|
case "domain":
|
|
return v.cfg.Domain
|
|
case "wordlist":
|
|
return v.cfg.Wordlist
|
|
case "output":
|
|
return v.cfg.Output
|
|
case "format":
|
|
return v.cfg.Format
|
|
case "ports":
|
|
return v.cfg.Ports
|
|
case "resolvers":
|
|
return v.cfg.Resolvers
|
|
case "stealth":
|
|
return v.cfg.StealthMode
|
|
case "ai.url":
|
|
return v.cfg.AIUrl
|
|
case "ai.fast_model":
|
|
return v.cfg.AIFastModel
|
|
case "ai.deep_model":
|
|
return v.cfg.AIDeepModel
|
|
case "nuclei_templates":
|
|
return v.cfg.NucleiTemplates
|
|
}
|
|
return fb
|
|
}
|
|
|
|
// Strings reads a string-slice key. No multi-value keys are defined yet,
|
|
// but reserved for module-specific settings loaded from YAML.
|
|
func (v *View) Strings(key string) []string {
|
|
_ = key
|
|
return nil
|
|
}
|
|
|
|
// ModuleEnabled returns true when the config explicitly enabled the module
|
|
// by name (via ModuleSettings). It returns false otherwise; callers should
|
|
// fall back to the module's DefaultEnabled() when this returns false.
|
|
func (v *View) ModuleEnabled(name string) bool {
|
|
if v == nil || v.cfg == nil {
|
|
return false
|
|
}
|
|
if v.cfg.ModuleSettings == nil {
|
|
return false
|
|
}
|
|
return v.cfg.ModuleSettings[name]
|
|
}
|