Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/input/provider/interface.go
2070 views
1
package provider
2
3
import (
4
"errors"
5
"fmt"
6
"strings"
7
8
"github.com/projectdiscovery/gologger"
9
"github.com/projectdiscovery/nuclei/v3/pkg/input/formats"
10
"github.com/projectdiscovery/nuclei/v3/pkg/input/provider/http"
11
"github.com/projectdiscovery/nuclei/v3/pkg/input/provider/list"
12
"github.com/projectdiscovery/nuclei/v3/pkg/input/types"
13
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
14
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
15
configTypes "github.com/projectdiscovery/nuclei/v3/pkg/types"
16
"github.com/projectdiscovery/utils/errkit"
17
stringsutil "github.com/projectdiscovery/utils/strings"
18
)
19
20
var (
21
ErrNotImplemented = errkit.New("provider does not implement method")
22
ErrInactiveInput = fmt.Errorf("input is inactive")
23
)
24
25
const (
26
MultiFormatInputProvider = "MultiFormatInputProvider"
27
ListInputProvider = "ListInputProvider"
28
SimpleListInputProvider = "SimpleInputProvider"
29
)
30
31
// IsErrNotImplemented checks if an error is a not implemented error
32
func IsErrNotImplemented(err error) bool {
33
if err == nil {
34
return false
35
}
36
if stringsutil.ContainsAll(err.Error(), "provider", "does not implement") {
37
return true
38
}
39
return false
40
}
41
42
// Validate all Implementations
43
var (
44
// SimpleInputProvider is more like a No-Op and returns given list of urls as input
45
_ InputProvider = &SimpleInputProvider{}
46
// HttpInputProvider provides support for formats that contain complete request/response
47
// like burp, openapi, postman,proxify, etc.
48
_ InputProvider = &http.HttpInputProvider{}
49
// ListInputProvider provides support for simple list of urls or files etc
50
_ InputProvider = &list.ListInputProvider{}
51
)
52
53
// InputProvider is unified input provider interface that provides
54
// processed inputs to nuclei by parsing and providing different
55
// formats such as list,openapi,postman,proxify,burp etc.
56
type InputProvider interface {
57
// Count returns total targets for input provider
58
Count() int64
59
// Iterate over all inputs in order
60
Iterate(callback func(value *contextargs.MetaInput) bool)
61
// Set adds item to input provider
62
Set(executionId string, value string)
63
// SetWithProbe adds item to input provider with http probing
64
SetWithProbe(executionId string, value string, probe types.InputLivenessProbe) error
65
// SetWithExclusions adds item to input provider if it doesn't match any of the exclusions
66
SetWithExclusions(executionId string, value string) error
67
// InputType returns the type of input provider
68
InputType() string
69
// Close the input provider and cleanup any resources
70
Close()
71
}
72
73
// InputOptions contains options for input provider
74
type InputOptions struct {
75
// Options for global config
76
Options *configTypes.Options
77
// NotFoundCallback is the callback to call when input is not found
78
// only supported in list input provider
79
NotFoundCallback func(template string) bool
80
}
81
82
// NewInputProvider creates a new input provider based on the options
83
// and returns it
84
func NewInputProvider(opts InputOptions) (InputProvider, error) {
85
// optionally load generated vars values if available
86
val, err := formats.ReadOpenAPIVarDumpFile()
87
if err != nil && !errors.Is(err, formats.ErrNoVarsDumpFile) {
88
// log error and continue
89
gologger.Error().Msgf("Could not read vars dump file: %s\n", err)
90
}
91
extraVars := make(map[string]interface{})
92
if val != nil {
93
for _, v := range val.Var {
94
v = strings.TrimSpace(v)
95
// split into key value
96
parts := strings.SplitN(v, "=", 2)
97
if len(parts) == 2 {
98
extraVars[parts[0]] = parts[1]
99
}
100
}
101
}
102
103
// check if input provider is supported
104
if strings.EqualFold(opts.Options.InputFileMode, "list") {
105
// create a new list input provider
106
return list.New(&list.Options{
107
Options: opts.Options,
108
NotFoundCallback: opts.NotFoundCallback,
109
})
110
} else {
111
// use HttpInputProvider
112
return http.NewHttpInputProvider(&http.HttpMultiFormatOptions{
113
InputFile: opts.Options.TargetsFilePath,
114
InputMode: opts.Options.InputFileMode,
115
Options: formats.InputFormatOptions{
116
Variables: generators.MergeMaps(extraVars, opts.Options.Vars.AsMap()),
117
SkipFormatValidation: opts.Options.SkipFormatValidation,
118
RequiredOnly: opts.Options.FormatUseRequiredOnly,
119
},
120
})
121
}
122
}
123
124
// SupportedInputFormats returns all supported input formats of nuclei
125
func SupportedInputFormats() string {
126
return "list, " + http.SupportedFormats()
127
}
128
129