-
Notifications
You must be signed in to change notification settings - Fork 27
/
discovery_job.go
156 lines (130 loc) · 3.4 KB
/
discovery_job.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
148
149
150
151
152
153
154
155
156
package models
import (
"encoding/csv"
"github.com/cSploit/daemon/models/internal"
"github.com/jinzhu/gorm"
"io"
"io/ioutil"
"path"
"strconv"
"strings"
"time"
)
var aircrackTimeLayout = "2006-01-02 15:04:05"
type DiscoveryJob struct {
internal.Base
Dir string `json:"-"`
Job Job
JobId uint
}
func (d *DiscoveryJob) parseOne(file string) error {
// Dirty hack to have a clean dump
//TODO: from stdout ?
dump, err := ioutil.ReadFile(file)
if err != nil {
return err
}
dump_str := string(dump)
// Replace endline with just an \n
dump_str = strings.Replace(dump_str, ", \r\n", ", \n", -1)
dump_str = strings.Replace(dump_str, ",\r\n", ",\n", -1)
dump_split := strings.SplitN(dump_str, "\r\n", 4)
// Extract the two parts of the csv
dump_aps := dump_split[2]
dump_clients := dump_split[3]
dump_clients = strings.SplitN(dump_clients, "\r\n", 2)[1]
// End of dirty hack, fill the structs
reader_aps := csv.NewReader(strings.NewReader(dump_aps))
reader_clients := csv.NewReader(strings.NewReader(dump_clients))
// Start with the aps
for {
record, csv_err := reader_aps.Read()
if csv_err == io.EOF {
break
}
if csv_err != nil {
return err
}
// Okay, fill an AP struct then append to the dump
ap, e := FindApByBssid(record[0])
if e == gorm.ErrRecordNotFound {
ap = &AP{}
} else if e != nil {
log.Error(e)
continue
}
// TODO: clean that
// FIXME: I am too lazy to check the errors
ap.Bssid = record[0]
ap.First, _ = time.Parse(aircrackTimeLayout, record[1])
ap.Last, _ = time.Parse(aircrackTimeLayout, record[2])
ap.Channel, _ = strconv.Atoi(record[3])
ap.Speed, _ = strconv.Atoi(record[4])
ap.Privacy = record[5]
ap.Cipher = record[6]
ap.Auth = record[7]
ap.Power, _ = strconv.Atoi(record[8])
ap.Beacons, _ = strconv.Atoi(record[9])
ap.IVs, _ = strconv.Atoi(record[10])
ap.Lan = strings.Replace(record[11], " ", "", -1)
ap.IdLen, _ = strconv.Atoi(record[12])
ap.Essid = record[13]
ap.Key = record[14]
if err := internal.Db.Save(ap); err != nil {
log.Error(err)
} else if err := internal.Db.Model(&(d.Job)).Association("job_aps").Append(ap).Error; err != nil {
log.Error(err)
}
}
// Continue with the clients
for {
record, csv_err := reader_clients.Read()
if csv_err == io.EOF {
break
}
if csv_err != nil {
return err
}
// Okay, fill a Client struct then append to the dump
client, e := FindClientByMac(record[0])
if e == gorm.ErrRecordNotFound {
client = &Client{}
} else if e != nil {
log.Error(e)
continue
}
// TODO: clean that
// FIXME: too lazy to fix the errors
client.Station = record[0]
client.First, _ = time.Parse(aircrackTimeLayout, record[1])
client.Last, _ = time.Parse(aircrackTimeLayout, record[2])
client.Power, _ = strconv.Atoi(record[3])
client.Packets, _ = strconv.Atoi(record[4])
client.Bssid = record[5]
client.Probed = record[6]
if err := internal.Db.Save(client); err != nil {
log.Error(err)
} else if err := internal.Db.Model(&(d.Job)).Association("job_clients").Append(client).Error; err != nil {
log.Error(err)
}
}
return nil
}
func (d *DiscoveryJob) Parse() error {
files, e := ioutil.ReadDir(d.Dir)
if e != nil {
return e
}
for _, fi := range files {
if fi.IsDir() {
continue
}
if !strings.HasSuffix(fi.Name(), ".csv") {
continue
}
if err := d.parseOne(path.Join(d.Dir, fi.Name())); err != nil {
return err
}
}
return nil
}