1
1
Fork 0
mirror of https://github.com/OJ/gobuster.git synced 2024-05-04 22:46:07 +02:00
gobuster/cli/gobuster.go
Christian Mehlmauer 6a2b40ff86
Cherry-picked the gomodules code from #117
This was cherry-picked from the gomod branch instead of being merged as
a PR for two reasons:

1) The vhost plugin addition isn't yet ready for merging, as there's
   a lot of code duplication.
2) This code can technically be merged as is without the mods to the
   vhost plugin.

When/If we're ready to merge the vhost plugin we'll fix that side up.
2019-01-09 11:17:46 +10:00

143 lines
2.7 KiB
Go

package cli
import (
"context"
"fmt"
"log"
"os"
"strings"
"sync"
"time"
"github.com/OJ/gobuster/v3/libgobuster"
)
func ruler() {
fmt.Println("=====================================================")
}
func banner() {
fmt.Printf("Gobuster v%s OJ Reeves (@TheColonial)\n", libgobuster.VERSION)
}
func resultWorker(g *libgobuster.Gobuster, filename string, wg *sync.WaitGroup) {
defer wg.Done()
var f *os.File
var err error
if filename != "" {
f, err = os.Create(filename)
if err != nil {
log.Fatalf("error on creating output file: %v", err)
}
}
for r := range g.Results() {
s, err := r.ToString(g)
if err != nil {
log.Fatal(err)
}
if s != "" {
g.ClearProgress()
s = strings.TrimSpace(s)
fmt.Println(s)
if f != nil {
err = writeToFile(f, s)
if err != nil {
log.Fatalf("error on writing output file: %v", err)
}
}
}
}
}
func errorWorker(g *libgobuster.Gobuster, wg *sync.WaitGroup) {
defer wg.Done()
for e := range g.Errors() {
if !g.Opts.Quiet {
g.ClearProgress()
log.Printf("[!] %v", e)
}
}
}
func progressWorker(c context.Context, g *libgobuster.Gobuster) {
tick := time.NewTicker(1 * time.Second)
for {
select {
case <-tick.C:
g.PrintProgress()
case <-c.Done():
return
}
}
}
func writeToFile(f *os.File, output string) error {
_, err := f.WriteString(fmt.Sprintf("%s\n", output))
if err != nil {
return fmt.Errorf("[!] Unable to write to file %v", err)
}
return nil
}
// Gobuster is the main entry point for the CLI
func Gobuster(prevCtx context.Context, opts *libgobuster.Options, plugin libgobuster.GobusterPlugin) error {
// Sanity checks
if opts == nil {
return fmt.Errorf("please provide valid options")
}
if plugin == nil {
return fmt.Errorf("please provide a valid plugin")
}
ctx, cancel := context.WithCancel(prevCtx)
defer cancel()
gobuster, err := libgobuster.NewGobuster(ctx, opts, plugin)
if err != nil {
log.Fatalf("[!] %v", err)
}
if !opts.Quiet {
fmt.Println("")
ruler()
banner()
ruler()
c, err := gobuster.GetConfigString()
if err != nil {
log.Fatalf("error on creating config string: %v", err)
}
fmt.Println(c)
ruler()
log.Println("Starting gobuster")
ruler()
}
var wg sync.WaitGroup
wg.Add(2)
go errorWorker(gobuster, &wg)
go resultWorker(gobuster, opts.OutputFilename, &wg)
if !opts.Quiet && !opts.NoProgress {
go progressWorker(ctx, gobuster)
}
if err := gobuster.Start(); err != nil {
log.Printf("[!] %v", err)
} else {
// call cancel func to free ressources and stop progressFunc
cancel()
// wait for all output funcs to finish
wg.Wait()
}
if !opts.Quiet {
gobuster.ClearProgress()
ruler()
log.Println("Finished")
ruler()
}
return nil
}