-
-
Notifications
You must be signed in to change notification settings - Fork 907
/
Copy pathqueue.go
147 lines (124 loc) · 3.55 KB
/
queue.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package core
import (
"fmt"
"github.com/fatih/color"
"github.com/fsnotify/fsnotify"
"github.com/j3ssie/osmedeus/libs"
"github.com/j3ssie/osmedeus/utils"
jsoniter "github.com/json-iterator/go"
"github.com/panjf2000/ants"
"github.com/thoas/go-funk"
"os"
"strings"
"sync"
)
func QueueWatcher(options libs.Options) {
queueFile := options.Queue.QueueFile
var wg sync.WaitGroup
p, _ := ants.NewPoolWithFunc(options.Concurrency, func(i interface{}) {
RunTheScan(i.(string), options)
wg.Done()
}, ants.WithPreAlloc(true))
defer p.Release()
data := utils.ReadingFileUnique(queueFile)
/* Start the watcher */
// Create new watcher.
watcher, err := fsnotify.NewWatcher()
if err != nil {
panic(err)
}
defer watcher.Close()
utils.InforF("Starting to watch the queue file: %v", color.HiMagentaString(queueFile))
// Start listening for events.
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Op.String() == "WRITE" {
utils.DebugF(color.HiMagentaString("modified file: %v -- %v", event.Name, event.Op))
target := GetNewLine(queueFile)
wg.Add(1)
_ = p.Invoke(strings.TrimSpace(target))
}
if event.Op.String() == "REMOVE" {
utils.ErrorF("Queue file removed, exiting ...")
os.Exit(-1)
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
utils.ErrorF("error: %v", err)
}
}
}()
err = watcher.Add(queueFile)
if err != nil {
panic(err)
}
// Just to trigger the file events
utils.WriteToFile(queueFile, strings.Join(append(data, "\n"), "\n"))
// Block main goroutine forever.
<-make(chan struct{})
}
func RunTheScan(target string, options libs.Options) error {
if strings.TrimSpace(target) == "" {
return fmt.Errorf("target is empty")
}
utils.InforF("Picking the target from the queue: %v", color.CyanString(target))
var inputFormat libs.InputFormat
if ok := jsoniter.UnmarshalFromString(target, &inputFormat); ok == nil {
utils.DebugF("Parsing the input in JSON format: %v", color.CyanString(target))
cmd := CommandBuilder(inputFormat)
utils.InforF("Running the command: %v", color.CyanString(cmd))
utils.RunOSCommand(cmd)
return nil
}
runner, err := InitRunner(target, options)
if err != nil {
utils.ErrorF("Error init runner with: %s", target)
return err
}
runner.Start()
return nil
}
func GetNewLine(queueFile string) string {
data := utils.ReadingLines(queueFile)
if len(data) == 0 {
return ""
}
target := data[0]
data = funk.DropString(data, 1)
utils.DebugF("Getting the target from the queue file: %v -- %v", queueFile, color.CyanString(target))
utils.WriteToFile(queueFile, strings.Join(data, "\n"))
return target
}
func CommandBuilder(inputFormat libs.InputFormat) (command string) {
if inputFormat.Command == "" {
inputFormat.Command = fmt.Sprintf("%v scan -t %v", libs.BINARY, inputFormat.Input)
if inputFormat.InputAsFile {
inputFormat.Command = fmt.Sprintf("%v scan -T %v", libs.BINARY, inputFormat.Input)
}
if inputFormat.Flow == "" {
inputFormat.Command += " -f " + inputFormat.Flow
}
// append the modules
if len(inputFormat.Modules) > 0 {
for _, item := range inputFormat.Modules {
inputFormat.Command += " -m " + item
}
}
if len(inputFormat.Params) > 0 {
for _, item := range inputFormat.Params {
inputFormat.Command += " -p " + item
}
}
inputFormat.Command += " " + inputFormat.Extra
}
// formatting the command if there is any input in it
inputFormat.Command = strings.ReplaceAll(inputFormat.Command, "{{.input}}", inputFormat.Input)
return command
}