subfinder/pkg/runner/runner.go

92 lines
2.4 KiB
Go
Raw Normal View History

package runner
2019-12-03 18:12:45 +00:00
import (
2019-12-04 15:00:59 +00:00
"bufio"
"io"
"os"
2019-12-04 15:00:59 +00:00
"path"
2019-12-05 10:41:06 +00:00
"github.com/projectdiscovery/subfinder/pkg/passive"
"github.com/projectdiscovery/subfinder/pkg/resolve"
2019-12-03 18:12:45 +00:00
)
// Runner is an instance of the subdomain enumeration
// client used to orchestrate the whole process.
type Runner struct {
2019-12-03 18:12:45 +00:00
options *Options
passiveAgent *passive.Agent
resolverClient *resolve.Resolver
}
// NewRunner creates a new runner struct instance by parsing
// the configuration options, configuring sources, reading lists
// and setting up loggers, etc.
func NewRunner(options *Options) (*Runner, error) {
runner := &Runner{options: options}
2019-12-03 18:12:45 +00:00
// Initialize the passive subdomain enumeration engine
runner.initializePassiveEngine()
// Initialize the active subdomain enumeration engine
err := runner.initializeActiveEngine()
if err != nil {
return nil, err
}
2019-12-03 18:12:45 +00:00
return runner, nil
}
// RunEnumeration runs the subdomain enumeration flow on the targets specified
func (r *Runner) RunEnumeration() error {
// Check if only a single domain is sent as input. Process the domain now.
if r.options.Domain != "" {
2020-01-10 10:15:54 +00:00
return r.EnumerateSingleDomain(r.options.Domain, r.options.Output, false)
}
// If we have multiple domains as input,
if r.options.DomainsFile != "" {
2019-12-04 15:00:59 +00:00
f, err := os.Open(r.options.DomainsFile)
if err != nil {
return err
}
err = r.EnumerateMultipleDomains(f)
f.Close()
return err
}
// If we have STDIN input, treat it as multiple domains
if r.options.Stdin {
return r.EnumerateMultipleDomains(os.Stdin)
}
return nil
}
// EnumerateMultipleDomains enumerates subdomains for multiple domains
// We keep enumerating subdomains for a given domain until we reach an error
func (r *Runner) EnumerateMultipleDomains(reader io.Reader) error {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
domain := scanner.Text()
if domain == "" {
continue
}
2020-01-10 10:15:54 +00:00
var err error
2020-07-22 13:35:01 +00:00
// If the user has specified an output file, use that output file instead
2020-01-10 10:15:54 +00:00
// of creating a new output file for each domain. Else create a new file
// for each domain in the directory.
if r.options.Output != "" {
err = r.EnumerateSingleDomain(domain, r.options.Output, true)
} else if r.options.OutputDirectory != "" {
2020-01-10 10:15:54 +00:00
outputFile := path.Join(r.options.OutputDirectory, domain)
err = r.EnumerateSingleDomain(domain, outputFile, false)
} else {
err = r.EnumerateSingleDomain(domain, "", true)
2020-01-10 10:15:54 +00:00
}
2019-12-04 15:00:59 +00:00
if err != nil {
return err
}
}
return nil
}