metasploit_data_models 0.18.1 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/app/models/mdm/host.rb +7 -0
- data/app/models/mdm/service.rb +30 -1
- data/app/models/mdm/tag.rb +10 -0
- data/app/models/metasploit_data_models/ip_address/v4/cidr.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/nmap.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list.rb +126 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/single.rb +123 -0
- data/app/models/metasploit_data_models/ip_address/v4/segmented.rb +200 -0
- data/app/models/metasploit_data_models/ip_address/v4/single.rb +53 -0
- data/app/models/metasploit_data_models/search/operation/ip_address.rb +60 -0
- data/app/models/metasploit_data_models/search/operator/ip_address.rb +33 -0
- data/app/models/metasploit_data_models/search/visitor/attribute.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/includes.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/joins.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/where.rb +51 -0
- data/config/locales/en.yml +35 -4
- data/lib/metasploit_data_models/ip_address.rb +5 -0
- data/lib/metasploit_data_models/ip_address/cidr.rb +174 -0
- data/lib/metasploit_data_models/ip_address/range.rb +181 -0
- data/lib/metasploit_data_models/match/child.rb +48 -0
- data/lib/metasploit_data_models/match/parent.rb +103 -0
- data/lib/metasploit_data_models/version.rb +4 -4
- data/metasploit_data_models.gemspec +2 -1
- data/spec/app/models/mdm/cred_spec.rb +164 -31
- data/spec/app/models/mdm/service_spec.rb +33 -44
- data/spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb +121 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb +151 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb +300 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb +278 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb +304 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb +29 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb +315 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb +183 -0
- data/spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb +182 -0
- data/spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb +19 -0
- data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +229 -36
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/db/structure.sql +3011 -0
- data/spec/factories/mdm/services.rb +3 -1
- data/spec/lib/metasploit_data_models/ip_address/cidr_spec.rb +350 -0
- data/spec/lib/metasploit_data_models/ip_address/range_spec.rb +77 -0
- data/spec/lib/metasploit_data_models/match/child_spec.rb +61 -0
- data/spec/lib/metasploit_data_models/match/parent_spec.rb +155 -0
- data/spec/support/matchers/match_regex_exactly.rb +28 -0
- data/spec/support/shared/contexts/rex/text.rb +15 -0
- data/spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb +109 -0
- metadata +58 -9
- data/spec/dummy/db/schema.rb +0 -609
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Segmented do
|
4
|
+
context 'CONSTANTS' do
|
5
|
+
context 'SEGMENT_COUNT' do
|
6
|
+
subject(:segment_count) {
|
7
|
+
described_class::SEGMENT_COUNT
|
8
|
+
}
|
9
|
+
|
10
|
+
it { should == 4 }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'SEPARATOR' do
|
14
|
+
subject(:separator) {
|
15
|
+
described_class::SEPARATOR
|
16
|
+
}
|
17
|
+
|
18
|
+
it { should == '.' }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'segment_count' do
|
23
|
+
subject(:segment_count) {
|
24
|
+
described_class.segment_count
|
25
|
+
}
|
26
|
+
|
27
|
+
it { should == 4 }
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,315 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Segment::Single do
|
4
|
+
subject(:single) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
let(:formatted_value) {
|
11
|
+
nil
|
12
|
+
}
|
13
|
+
|
14
|
+
context 'validations' do
|
15
|
+
it { should validate_numericality_of(:value).is_greater_than_or_equal_to(0).is_less_than_or_equal_to(255).only_integer }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can be used in a Range' do
|
19
|
+
expect {
|
20
|
+
Range.new(single, single)
|
21
|
+
}.not_to raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
context '#add_with_carry' do
|
25
|
+
subject(:add_with_carry) {
|
26
|
+
single.add_with_carry(*arguments)
|
27
|
+
}
|
28
|
+
|
29
|
+
let(:carry_out) {
|
30
|
+
add_with_carry[1]
|
31
|
+
}
|
32
|
+
|
33
|
+
let(:segment_out) {
|
34
|
+
add_with_carry[0]
|
35
|
+
}
|
36
|
+
|
37
|
+
context 'with carry' do
|
38
|
+
let(:arguments) {
|
39
|
+
[
|
40
|
+
other_single,
|
41
|
+
1
|
42
|
+
]
|
43
|
+
}
|
44
|
+
|
45
|
+
context 'with overflow' do
|
46
|
+
let(:formatted_value) {
|
47
|
+
'255'
|
48
|
+
}
|
49
|
+
|
50
|
+
let(:other_single) {
|
51
|
+
described_class.new(value: 255)
|
52
|
+
}
|
53
|
+
|
54
|
+
it 'outputs a proper segment' do
|
55
|
+
expect(segment_out).to be_a described_class
|
56
|
+
expect(segment_out.value).to be <= 255
|
57
|
+
expect(segment_out.value).to eq(255)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'outputs a carry' do
|
61
|
+
expect(carry_out).to eq(1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'without overflow' do
|
66
|
+
let(:formatted_value) {
|
67
|
+
'254'
|
68
|
+
}
|
69
|
+
|
70
|
+
let(:other_single) {
|
71
|
+
described_class.new(value: 0)
|
72
|
+
}
|
73
|
+
|
74
|
+
it 'outs a proper segment' do
|
75
|
+
expect(segment_out).to be_a described_class
|
76
|
+
expect(segment_out.value).to be <= 255
|
77
|
+
expect(segment_out.value).to eq(255)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'does not output a carry' do
|
81
|
+
expect(carry_out).to eq(0)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'without carry' do
|
87
|
+
let(:arguments) {
|
88
|
+
[
|
89
|
+
other_single
|
90
|
+
]
|
91
|
+
}
|
92
|
+
|
93
|
+
context 'with overflow' do
|
94
|
+
let(:formatted_value) {
|
95
|
+
'255'
|
96
|
+
}
|
97
|
+
|
98
|
+
let(:other_single) {
|
99
|
+
described_class.new(value: 255)
|
100
|
+
}
|
101
|
+
|
102
|
+
it 'outputs a proper segment' do
|
103
|
+
expect(segment_out).to be_a described_class
|
104
|
+
expect(segment_out.value).to be <= 255
|
105
|
+
expect(segment_out.value).to eq(254)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'outputs a carry' do
|
109
|
+
expect(carry_out).to eq(1)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'without overflow' do
|
114
|
+
let(:formatted_value) {
|
115
|
+
'255'
|
116
|
+
}
|
117
|
+
|
118
|
+
let(:other_single) {
|
119
|
+
described_class.new(value: 0)
|
120
|
+
}
|
121
|
+
|
122
|
+
it 'outs a proper segment' do
|
123
|
+
expect(segment_out).to be_a described_class
|
124
|
+
expect(segment_out.value).to be <= 255
|
125
|
+
expect(segment_out.value).to eq(255)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'does not output a carry' do
|
129
|
+
expect(carry_out).to eq(0)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'bits' do
|
136
|
+
subject(:bits) {
|
137
|
+
described_class.bits
|
138
|
+
}
|
139
|
+
|
140
|
+
it { should == 8 }
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'match_regexp' do
|
144
|
+
subject(:match_regexp) {
|
145
|
+
described_class.match_regexp
|
146
|
+
}
|
147
|
+
|
148
|
+
it 'matches segment number' do
|
149
|
+
expect(match_regexp).to match('255')
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'does not match segment range' do
|
153
|
+
expect(match_regexp).not_to match('0-225')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context '#<=>' do
|
158
|
+
subject(:compare) {
|
159
|
+
single <=> other
|
160
|
+
}
|
161
|
+
|
162
|
+
let(:other) {
|
163
|
+
double('Other')
|
164
|
+
}
|
165
|
+
|
166
|
+
it 'compares #values' do
|
167
|
+
other_value = double('other.value')
|
168
|
+
|
169
|
+
expect(other).to receive(:value).and_return(other_value)
|
170
|
+
expect(single.value).to receive(:<=>).with(other_value)
|
171
|
+
|
172
|
+
compare
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context '#succ' do
|
177
|
+
subject(:succ) {
|
178
|
+
single.succ
|
179
|
+
}
|
180
|
+
|
181
|
+
context '#value' do
|
182
|
+
context 'with nil' do
|
183
|
+
let(:formatted_value) {
|
184
|
+
nil
|
185
|
+
}
|
186
|
+
|
187
|
+
specify {
|
188
|
+
expect(succ).not_to raise_error
|
189
|
+
}
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'with number' do
|
193
|
+
let(:formatted_value) {
|
194
|
+
value.to_s
|
195
|
+
}
|
196
|
+
|
197
|
+
let(:value) {
|
198
|
+
1
|
199
|
+
}
|
200
|
+
|
201
|
+
it { should be_a described_class }
|
202
|
+
|
203
|
+
context 'succ.value' do
|
204
|
+
it 'is succ of #value' do
|
205
|
+
expect(succ.value).to eq(value.succ)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'without number' do
|
211
|
+
let(:formatted_value) {
|
212
|
+
'a'
|
213
|
+
}
|
214
|
+
|
215
|
+
it { should be_a described_class }
|
216
|
+
|
217
|
+
context 'succ.value' do
|
218
|
+
it 'is succ of #value' do
|
219
|
+
expect(succ.value).to eq(single.value.succ)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context '#to_s' do
|
227
|
+
subject(:to_s) {
|
228
|
+
single.to_s
|
229
|
+
}
|
230
|
+
|
231
|
+
#
|
232
|
+
# let
|
233
|
+
#
|
234
|
+
|
235
|
+
let(:value) {
|
236
|
+
double('#value')
|
237
|
+
}
|
238
|
+
|
239
|
+
#
|
240
|
+
# Callbacks
|
241
|
+
#
|
242
|
+
|
243
|
+
before(:each) do
|
244
|
+
allow(single).to receive(:value).and_return(value)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'delegates to #value' do
|
248
|
+
expect(value).to receive(:to_s)
|
249
|
+
|
250
|
+
to_s
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context '#value' do
|
255
|
+
subject(:value) do
|
256
|
+
single.value
|
257
|
+
end
|
258
|
+
|
259
|
+
context 'with Integer' do
|
260
|
+
let(:formatted_value) do
|
261
|
+
1
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'should pass through Integer' do
|
265
|
+
value.should == formatted_value
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'with Integer#to_s' do
|
270
|
+
let(:formatted_value) do
|
271
|
+
integer.to_s
|
272
|
+
end
|
273
|
+
|
274
|
+
let(:integer) do
|
275
|
+
1
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should convert String to Integer' do
|
279
|
+
value.should == integer
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context 'with mix text and numerals' do
|
284
|
+
let(:formatted_value) do
|
285
|
+
"#{integer}mix"
|
286
|
+
end
|
287
|
+
|
288
|
+
let(:integer) do
|
289
|
+
123
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'should not extract the number' do
|
293
|
+
value.should_not == integer
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'should pass through the full value' do
|
297
|
+
value.should == formatted_value
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
context 'with Float' do
|
302
|
+
let(:formatted_value) do
|
303
|
+
0.1
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'should not truncate Float to Integer' do
|
307
|
+
value.should_not == formatted_value.to_i
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'should pass through Float' do
|
311
|
+
value.should == formatted_value
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Single do
|
4
|
+
subject(:single) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
context 'validation' do
|
11
|
+
before(:each) do
|
12
|
+
single.valid?
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'errors on #segments' do
|
16
|
+
subject(:segments_errors) {
|
17
|
+
single.errors[:segments]
|
18
|
+
}
|
19
|
+
|
20
|
+
context 'with segments' do
|
21
|
+
let(:formatted_value) {
|
22
|
+
'1.2.3.4'
|
23
|
+
}
|
24
|
+
|
25
|
+
it { should be_empty }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'without segments' do
|
29
|
+
let(:formatted_value) {
|
30
|
+
'::1'
|
31
|
+
}
|
32
|
+
|
33
|
+
let(:length_error) {
|
34
|
+
I18n.translate!(
|
35
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segmented.attributes.segments.wrong_length',
|
36
|
+
count: 4
|
37
|
+
)
|
38
|
+
}
|
39
|
+
|
40
|
+
it { should include length_error }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context '+' do
|
46
|
+
subject(:add) do
|
47
|
+
single + other
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with MetasploitDataModels::IPAddress::V4::Single' do
|
51
|
+
let(:other) {
|
52
|
+
described_class.new(
|
53
|
+
value: other_formatted_value
|
54
|
+
)
|
55
|
+
}
|
56
|
+
|
57
|
+
context 'with overflow' do
|
58
|
+
let(:formatted_value) {
|
59
|
+
'255.255.255.255'
|
60
|
+
}
|
61
|
+
|
62
|
+
let(:other_formatted_value) {
|
63
|
+
'0.0.0.1'
|
64
|
+
}
|
65
|
+
|
66
|
+
specify {
|
67
|
+
expect {
|
68
|
+
add
|
69
|
+
}.to raise_error(ArgumentError, "255.255.255.255 + 0.0.0.1 is not a valid IP address. It is 0.0.0.0 with a carry (1)")
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'without overflow' do
|
74
|
+
let(:formatted_value) {
|
75
|
+
'254.255.255.255'
|
76
|
+
}
|
77
|
+
|
78
|
+
context 'with ripple carry' do
|
79
|
+
let(:other_formatted_value) {
|
80
|
+
'0.0.0.1'
|
81
|
+
}
|
82
|
+
|
83
|
+
it 'propagates carry corretly' do
|
84
|
+
expect(add).to eq(described_class.new(value: '255.0.0.0'))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'without ripple carry' do
|
89
|
+
let(:formatted_value) do
|
90
|
+
'4.3.2.1'
|
91
|
+
end
|
92
|
+
|
93
|
+
let(:other_formatted_value) do
|
94
|
+
'5.4.3.2'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'adds the correct segments together' do
|
98
|
+
expect(add).to eq(described_class.new(value: '9.7.5.3'))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'without MetasploitDataMOdels::IPAddress::V4::Single' do
|
105
|
+
let(:formatted_value) {
|
106
|
+
'255.255.255.255'
|
107
|
+
}
|
108
|
+
|
109
|
+
let(:other) {
|
110
|
+
1
|
111
|
+
}
|
112
|
+
|
113
|
+
specify {
|
114
|
+
expect {
|
115
|
+
add
|
116
|
+
}.to raise_error(TypeError, "Cannot add #{other.class} to #{described_class}")
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'regexp' do
|
122
|
+
subject(:regexp) {
|
123
|
+
described_class.regexp
|
124
|
+
}
|
125
|
+
|
126
|
+
it 'matches a normal IPv4 address' do
|
127
|
+
expect(regexp).to match_string_exactly('1.2.3.4')
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'does matches an IPv4 Nmap address with comma separated list of numbers and ranges for each segment' do
|
131
|
+
expect(regexp).not_to match_string_exactly('1,2-3.4-5,6.7,8.9-10,11-12')
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context '#value' do
|
136
|
+
subject(:value) {
|
137
|
+
single.value
|
138
|
+
}
|
139
|
+
|
140
|
+
context 'with nil' do
|
141
|
+
let(:formatted_value) {
|
142
|
+
nil
|
143
|
+
}
|
144
|
+
|
145
|
+
it { should be_nil }
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'with matching formatted value' do
|
149
|
+
let(:formatted_value) {
|
150
|
+
'1.2.3.4'
|
151
|
+
}
|
152
|
+
|
153
|
+
it 'has 4 segments' do
|
154
|
+
expect(value.length).to eq(4)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'has MetasploitDataModels::IPAddress::V4::Segment::Single for segments' do
|
158
|
+
expect(
|
159
|
+
value.all? { |segment|
|
160
|
+
segment.is_a? MetasploitDataModels::IPAddress::V4::Segment::Single
|
161
|
+
}
|
162
|
+
).to eq(true)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'has segments ordered from high to low' do
|
166
|
+
expect(value[0].value).to eq(1)
|
167
|
+
expect(value[1].value).to eq(2)
|
168
|
+
expect(value[2].value).to eq(3)
|
169
|
+
expect(value[3].value).to eq(4)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'without matching formatted value' do
|
174
|
+
let(:formatted_value) {
|
175
|
+
'1.2-3.5.6'
|
176
|
+
}
|
177
|
+
|
178
|
+
it 'is the formated value' do
|
179
|
+
expect(value).to eq(formatted_value)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|