Get rid of the last external dependency

This commit is contained in:
Joona Hoikkala 2018-11-15 00:18:43 +02:00
parent e82f762825
commit c9217e39f5
No known key found for this signature in database
GPG Key ID: D5AA86BBF9B29A5C
3 changed files with 51 additions and 21 deletions

View File

@ -112,6 +112,8 @@ eg. `ffuf -u https://example.org/FUZZ -w /path/to/wordlist`
or or
- If you have go compiler installed: `go get github.com/ffuf/ffuf` - If you have go compiler installed: `go get github.com/ffuf/ffuf`
The only dependency of ffuf is Go 1.11. No dependencies outside of Go standard library are needed.
## TODO ## TODO
- Tests! - Tests!
- Option to follow redirects - Option to follow redirects

40
main.go
View File

@ -12,8 +12,6 @@ import (
"github.com/ffuf/ffuf/pkg/input" "github.com/ffuf/ffuf/pkg/input"
"github.com/ffuf/ffuf/pkg/output" "github.com/ffuf/ffuf/pkg/output"
"github.com/ffuf/ffuf/pkg/runner" "github.com/ffuf/ffuf/pkg/runner"
"github.com/hashicorp/go-multierror"
) )
type cliOptions struct { type cliOptions struct {
@ -84,14 +82,14 @@ func main() {
} }
func prepareJob(conf *ffuf.Config) (*ffuf.Job, error) { func prepareJob(conf *ffuf.Config) (*ffuf.Job, error) {
var errlist *multierror.Error errs := ffuf.NewMultierror()
// TODO: implement error handling for runnerprovider and outputprovider // TODO: implement error handling for runnerprovider and outputprovider
// We only have http runner right now // We only have http runner right now
runprovider := runner.NewRunnerByName("http", conf) runprovider := runner.NewRunnerByName("http", conf)
// We only have wordlist inputprovider right now // We only have wordlist inputprovider right now
inputprovider, err := input.NewInputProviderByName("wordlist", conf) inputprovider, err := input.NewInputProviderByName("wordlist", conf)
if err != nil { if err != nil {
errlist = multierror.Append(errlist, fmt.Errorf("%s", err)) errs.Add(fmt.Errorf("%s", err))
} }
// We only have stdout outputprovider right now // We only have stdout outputprovider right now
outprovider := output.NewOutputProviderByName("stdout", conf) outprovider := output.NewOutputProviderByName("stdout", conf)
@ -100,18 +98,18 @@ func prepareJob(conf *ffuf.Config) (*ffuf.Job, error) {
Runner: runprovider, Runner: runprovider,
Output: outprovider, Output: outprovider,
Input: inputprovider, Input: inputprovider,
}, errlist.ErrorOrNil() }, errs.ErrorOrNil()
} }
func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error { func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
//TODO: refactor in a proper flag library that can handle things like required flags //TODO: refactor in a proper flag library that can handle things like required flags
var errlist *multierror.Error errs := ffuf.NewMultierror()
foundkeyword := false foundkeyword := false
if len(conf.Url) == 0 { if len(conf.Url) == 0 {
errlist = multierror.Append(errlist, fmt.Errorf("-u flag is required")) errs.Add(fmt.Errorf("-u flag is required"))
} }
if len(conf.Wordlist) == 0 { if len(conf.Wordlist) == 0 {
errlist = multierror.Append(errlist, fmt.Errorf("-w flag is required")) errs.Add(fmt.Errorf("-w flag is required"))
} }
//Prepare headers //Prepare headers
for _, v := range parseOpts.headers { for _, v := range parseOpts.headers {
@ -131,7 +129,7 @@ func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
conf.StaticHeaders[strings.TrimSpace(hs[0])] = strings.TrimSpace(hs[1]) conf.StaticHeaders[strings.TrimSpace(hs[0])] = strings.TrimSpace(hs[1])
} }
} else { } else {
errlist = multierror.Append(errlist, fmt.Errorf("Header defined by -H needs to have a value. \":\" should be used as a separator")) errs.Add(fmt.Errorf("Header defined by -H needs to have a value. \":\" should be used as a separator"))
} }
} }
//Search for keyword from URL and POST data too //Search for keyword from URL and POST data too
@ -143,54 +141,54 @@ func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
} }
if !foundkeyword { if !foundkeyword {
errlist = multierror.Append(errlist, fmt.Errorf("No FUZZ keyword(s) found in headers, URL or POST data, nothing to do")) errs.Add(fmt.Errorf("No FUZZ keyword(s) found in headers, URL or POST data, nothing to do"))
} }
return errlist.ErrorOrNil() return errs.ErrorOrNil()
} }
func prepareFilters(parseOpts *cliOptions, conf *ffuf.Config) error { func prepareFilters(parseOpts *cliOptions, conf *ffuf.Config) error {
var errlist *multierror.Error errs := ffuf.NewMultierror()
if parseOpts.filterStatus != "" { if parseOpts.filterStatus != "" {
if err := addFilter(conf, "status", parseOpts.filterStatus); err != nil { if err := addFilter(conf, "status", parseOpts.filterStatus); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
if parseOpts.filterSize != "" { if parseOpts.filterSize != "" {
if err := addFilter(conf, "size", parseOpts.filterSize); err != nil { if err := addFilter(conf, "size", parseOpts.filterSize); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
if parseOpts.filterRegexp != "" { if parseOpts.filterRegexp != "" {
if err := addFilter(conf, "regexp", parseOpts.filterRegexp); err != nil { if err := addFilter(conf, "regexp", parseOpts.filterRegexp); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
if parseOpts.filterWords != "" { if parseOpts.filterWords != "" {
if err := addFilter(conf, "word", parseOpts.filterWords); err != nil { if err := addFilter(conf, "word", parseOpts.filterWords); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
if parseOpts.matcherStatus != "" { if parseOpts.matcherStatus != "" {
if err := addMatcher(conf, "status", parseOpts.matcherStatus); err != nil { if err := addMatcher(conf, "status", parseOpts.matcherStatus); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
if parseOpts.matcherSize != "" { if parseOpts.matcherSize != "" {
if err := addMatcher(conf, "size", parseOpts.matcherSize); err != nil { if err := addMatcher(conf, "size", parseOpts.matcherSize); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
if parseOpts.matcherRegexp != "" { if parseOpts.matcherRegexp != "" {
if err := addMatcher(conf, "regexp", parseOpts.matcherRegexp); err != nil { if err := addMatcher(conf, "regexp", parseOpts.matcherRegexp); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
if parseOpts.matcherWords != "" { if parseOpts.matcherWords != "" {
if err := addMatcher(conf, "word", parseOpts.matcherWords); err != nil { if err := addMatcher(conf, "word", parseOpts.matcherWords); err != nil {
errlist = multierror.Append(errlist, err) errs.Add(err)
} }
} }
return errlist.ErrorOrNil() return errs.ErrorOrNil()
} }
func addFilter(conf *ffuf.Config, name string, option string) error { func addFilter(conf *ffuf.Config, name string, option string) error {

30
pkg/ffuf/multierror.go Normal file
View File

@ -0,0 +1,30 @@
package ffuf
import (
"fmt"
)
type Multierror struct {
errors []error
}
//NewMultierror returns a new Multierror
func NewMultierror() Multierror {
return Multierror{}
}
func (m *Multierror) Add(err error) {
m.errors = append(m.errors, err)
}
func (m *Multierror) ErrorOrNil() error {
var errString string
if len(m.errors) > 0 {
errString += fmt.Sprintf("%d errors occured.\n", len(m.errors))
for _, e := range m.errors {
errString += fmt.Sprintf("\t* %s\n", e)
}
return fmt.Errorf("%s", errString)
}
return nil
}