metasploit_data_models 0.18.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +8 -8
  2. data/app/models/mdm/host.rb +7 -0
  3. data/app/models/mdm/service.rb +30 -1
  4. data/app/models/mdm/tag.rb +10 -0
  5. data/app/models/metasploit_data_models/ip_address/v4/cidr.rb +14 -0
  6. data/app/models/metasploit_data_models/ip_address/v4/nmap.rb +14 -0
  7. data/app/models/metasploit_data_models/ip_address/v4/range.rb +12 -0
  8. data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list.rb +126 -0
  9. data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range.rb +12 -0
  10. data/app/models/metasploit_data_models/ip_address/v4/segment/single.rb +123 -0
  11. data/app/models/metasploit_data_models/ip_address/v4/segmented.rb +200 -0
  12. data/app/models/metasploit_data_models/ip_address/v4/single.rb +53 -0
  13. data/app/models/metasploit_data_models/search/operation/ip_address.rb +60 -0
  14. data/app/models/metasploit_data_models/search/operator/ip_address.rb +33 -0
  15. data/app/models/metasploit_data_models/search/visitor/attribute.rb +1 -0
  16. data/app/models/metasploit_data_models/search/visitor/includes.rb +1 -0
  17. data/app/models/metasploit_data_models/search/visitor/joins.rb +1 -0
  18. data/app/models/metasploit_data_models/search/visitor/where.rb +51 -0
  19. data/config/locales/en.yml +35 -4
  20. data/lib/metasploit_data_models/ip_address.rb +5 -0
  21. data/lib/metasploit_data_models/ip_address/cidr.rb +174 -0
  22. data/lib/metasploit_data_models/ip_address/range.rb +181 -0
  23. data/lib/metasploit_data_models/match/child.rb +48 -0
  24. data/lib/metasploit_data_models/match/parent.rb +103 -0
  25. data/lib/metasploit_data_models/version.rb +4 -4
  26. data/metasploit_data_models.gemspec +2 -1
  27. data/spec/app/models/mdm/cred_spec.rb +164 -31
  28. data/spec/app/models/mdm/service_spec.rb +33 -44
  29. data/spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb +121 -0
  30. data/spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb +151 -0
  31. data/spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb +300 -0
  32. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb +278 -0
  33. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb +304 -0
  34. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb +29 -0
  35. data/spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb +315 -0
  36. data/spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb +183 -0
  37. data/spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb +182 -0
  38. data/spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb +19 -0
  39. data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +229 -36
  40. data/spec/dummy/config/application.rb +1 -1
  41. data/spec/dummy/db/structure.sql +3011 -0
  42. data/spec/factories/mdm/services.rb +3 -1
  43. data/spec/lib/metasploit_data_models/ip_address/cidr_spec.rb +350 -0
  44. data/spec/lib/metasploit_data_models/ip_address/range_spec.rb +77 -0
  45. data/spec/lib/metasploit_data_models/match/child_spec.rb +61 -0
  46. data/spec/lib/metasploit_data_models/match/parent_spec.rb +155 -0
  47. data/spec/support/matchers/match_regex_exactly.rb +28 -0
  48. data/spec/support/shared/contexts/rex/text.rb +15 -0
  49. data/spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb +109 -0
  50. metadata +58 -9
  51. data/spec/dummy/db/schema.rb +0 -609
@@ -10,7 +10,7 @@ FactoryGirl.define do
10
10
  #
11
11
  name { generate :mdm_service_name }
12
12
  port { generate :port }
13
- proto 'snmp'
13
+ proto { generate :mdm_service_proto }
14
14
  state 'open'
15
15
 
16
16
  factory :web_service do
@@ -23,6 +23,8 @@ FactoryGirl.define do
23
23
  "mdm_service_name#{n}"
24
24
  }
25
25
 
26
+ sequence :mdm_service_proto, Mdm::Service::PROTOS.cycle
27
+
26
28
  port_bits = 16
27
29
  port_limit = 1 << port_bits
28
30
 
@@ -0,0 +1,350 @@
1
+ require 'spec_helper'
2
+
3
+ describe MetasploitDataModels::IPAddress::CIDR do
4
+ subject(:including_class_instance) {
5
+ including_class.new(
6
+ value: formatted_value
7
+ )
8
+ }
9
+
10
+ #
11
+ # lets
12
+ #
13
+
14
+ let(:expected_address) {
15
+ double(
16
+ '#address',
17
+ valid?: true
18
+ )
19
+ }
20
+
21
+ let(:expected_address_class) {
22
+ double(
23
+ '#address_class',
24
+ new: expected_address,
25
+ regexp: expected_address_class_regexp,
26
+ segment_class: segment_class,
27
+ segment_count: segment_count
28
+ )
29
+ }
30
+
31
+ let(:expected_address_class_regexp) {
32
+ /\d+\.\d+/
33
+ }
34
+
35
+ let(:formatted_value) {
36
+ nil
37
+ }
38
+
39
+ let(:including_class) {
40
+ expected_address_class = self.expected_address_class
41
+ described_class = self.described_class
42
+
43
+ Class.new(Metasploit::Model::Base) do
44
+ include described_class
45
+
46
+ #
47
+ # CIDR
48
+ #
49
+
50
+ cidr address_class: expected_address_class
51
+ end
52
+ }
53
+
54
+ let(:segment_bits) {
55
+ 4
56
+ }
57
+
58
+ let(:segment_class) {
59
+ double(
60
+ '#address_class segment_class',
61
+ bits: segment_bits
62
+ )
63
+ }
64
+
65
+ let(:segment_count) {
66
+ 2
67
+ }
68
+
69
+ #
70
+ # Callbacks
71
+ #
72
+
73
+ before(:each) do
74
+ stub_const('IncludingClass', including_class)
75
+ end
76
+
77
+ context 'CONSTANTS' do
78
+ context 'SEPARATOR' do
79
+ subject(:separator) {
80
+ described_class::SEPARATOR
81
+ }
82
+
83
+ it { should == '/' }
84
+ end
85
+ end
86
+
87
+ context 'validation errors on' do
88
+ before(:each) do
89
+ including_class_instance.valid?
90
+ end
91
+
92
+ context '#address' do
93
+ subject(:address_errors) {
94
+ including_class_instance.errors[:address]
95
+ }
96
+
97
+ context 'with #address' do
98
+ let(:expected_address) {
99
+ super().tap { |address|
100
+ expect(address).to receive(:valid?).and_return(address_valid)
101
+ }
102
+ }
103
+
104
+ let(:invalid_error) {
105
+ I18n.translate!('errors.messages.invalid')
106
+ }
107
+
108
+ context 'with valid' do
109
+ let(:address_valid) {
110
+ true
111
+ }
112
+
113
+ it { should_not include(invalid_error) }
114
+ end
115
+
116
+ context 'without valid' do
117
+ let(:address_valid) {
118
+ false
119
+ }
120
+
121
+ it { should include(invalid_error) }
122
+ end
123
+ end
124
+
125
+ context 'without #address' do
126
+ let(:expected_address) {
127
+ nil
128
+ }
129
+
130
+ let(:blank_error) {
131
+ I18n.translate!('errors.messages.blank')
132
+ }
133
+
134
+ it { should include(blank_error) }
135
+ end
136
+ end
137
+
138
+ context '#prefix_length' do
139
+ let(:maximum_prefix_length) {
140
+ segment_count * segment_bits
141
+ }
142
+
143
+ it 'validates it is an integer between 0 and maximum_prefix_length' do
144
+ expect(including_class_instance).to validate_numericality_of(:prefix_length).only_integer.is_greater_than_or_equal_to(0).is_less_than_or_equal_to(maximum_prefix_length)
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'address_class' do
150
+ subject(:address_class) do
151
+ including_class.address_class
152
+ end
153
+
154
+ context 'with call to cidr' do
155
+ it 'is value for :address_class key passed to cidr' do
156
+ expect(address_class).to eq(expected_address_class)
157
+ end
158
+ end
159
+
160
+ context 'without call to cidr' do
161
+ let(:including_class) {
162
+ described_class = self.described_class
163
+
164
+ Class.new(Metasploit::Model::Base) do
165
+ include described_class
166
+ end
167
+ }
168
+
169
+ it { should be_nil }
170
+ end
171
+ end
172
+
173
+ context 'match_regexp' do
174
+ subject(:match_regexp) {
175
+ including_class.match_regexp
176
+ }
177
+
178
+ before(:each) do
179
+ expect(including_class).to receive(:regexp).and_return(/regexp/)
180
+ end
181
+
182
+ it "is regexp pinned with '\\A' and '\\z'" do
183
+ expect(match_regexp).to eq(/\A(?-mix:regexp)\z/)
184
+ end
185
+ end
186
+
187
+ context 'maximum_prefix_length' do
188
+ subject(:maximum_prefix_length) {
189
+ including_class.maximum_prefix_length
190
+ }
191
+
192
+ it 'is the total number of bits across all segments' do
193
+ expect(maximum_prefix_length).to eq(segment_count * segment_bits)
194
+ end
195
+ end
196
+
197
+ context 'regexp' do
198
+ subject(:regexp) {
199
+ including_class.regexp
200
+ }
201
+
202
+ it 'includes address_class.regexp' do
203
+ expect(regexp.to_s).to include(expected_address_class_regexp.to_s)
204
+ end
205
+
206
+ context 'Regexp#names' do
207
+ subject(:names) {
208
+ regexp.names
209
+ }
210
+
211
+ it { should include 'address' }
212
+ it { should include 'prefix_length' }
213
+ end
214
+ end
215
+
216
+ context '#address' do
217
+ subject(:address) {
218
+ including_class_instance.address
219
+ }
220
+
221
+ let(:expected_address_class) {
222
+ Class.new(Metasploit::Model::Base) {
223
+ attr_accessor :value
224
+ }.tap { |address_class|
225
+
226
+ allow(address_class).to receive(:segment_class).and_return(segment_class)
227
+ allow(address_class).to receive(:segment_count).and_return(segment_count)
228
+ }
229
+ }
230
+
231
+ context 'writer' do
232
+ #
233
+ # lets
234
+ #
235
+
236
+ let(:formatted_address) {
237
+ '1.2'
238
+ }
239
+
240
+ it 'sets address_class #value' do
241
+ including_class_instance
242
+
243
+ expect(expected_address_class).to receive(:new).with(
244
+ hash_including(
245
+ value: formatted_value
246
+ )
247
+ )
248
+
249
+ including_class_instance.address = formatted_value
250
+ end
251
+ end
252
+ end
253
+
254
+ context '#prefix_length' do
255
+ subject(:prefix_length) {
256
+ including_class_instance.prefix_length
257
+ }
258
+
259
+ let(:formatted_address) {
260
+ ''
261
+ }
262
+
263
+ let(:formatted_value) {
264
+ "#{formatted_address}/#{formatted_prefix_length}"
265
+ }
266
+
267
+ context 'with integer' do
268
+ let(:formatted_prefix_length) {
269
+ expected_prefix_length.to_s
270
+ }
271
+
272
+ let(:expected_prefix_length) {
273
+ 7
274
+ }
275
+
276
+ it 'sets #prefix_length_before_type_cast to formatted prefix length' do
277
+ expect(including_class_instance.prefix_length_before_type_cast).to eq(formatted_prefix_length)
278
+ end
279
+
280
+ it 'is set to Integer' do
281
+ expect(prefix_length).to eq(expected_prefix_length)
282
+ end
283
+ end
284
+
285
+ context 'without integer' do
286
+ let(:formatted_prefix_length) {
287
+ '255.255.255.0'
288
+ }
289
+
290
+ it 'sets #prefix_length_before_type_cast to formatted prefix length' do
291
+ expect(including_class_instance.prefix_length_before_type_cast).to eq(formatted_prefix_length)
292
+ end
293
+
294
+ it 'is set to the formatted prefix length' do
295
+ expect(prefix_length).to eq(formatted_prefix_length)
296
+ end
297
+ end
298
+ end
299
+
300
+ context '#value' do
301
+ subject(:value) {
302
+ including_class_instance.value
303
+ }
304
+
305
+ let(:formatted_address) {
306
+ '1.2'
307
+ }
308
+
309
+ context "with '/'" do
310
+ let(:formatted_value) {
311
+ "#{formatted_address}/#{formatted_prefix_length}"
312
+ }
313
+
314
+ let(:formatted_prefix_length) {
315
+ '7'
316
+ }
317
+
318
+ it "sets #address to formatted address before '/'" do
319
+ expect(including_class_instance).to receive(:address=).with(formatted_address)
320
+
321
+ including_class_instance.value = formatted_value
322
+ end
323
+
324
+ it "sets #prefix_length to formatted prefix length after '/'" do
325
+ expect(including_class_instance).to receive(:prefix_length=).with(formatted_prefix_length)
326
+
327
+ including_class_instance.value = formatted_value
328
+ end
329
+ end
330
+
331
+ context "without '/'" do
332
+ let(:formatted_value) {
333
+ "#{formatted_address}"
334
+ }
335
+
336
+
337
+ it "sets #address to formatted address before '/'" do
338
+ expect(including_class_instance).to receive(:address=).with(formatted_address)
339
+
340
+ including_class_instance.value = formatted_value
341
+ end
342
+
343
+ it "sets #prefix_length to nil" do
344
+ expect(including_class_instance).to receive(:prefix_length=).with(nil)
345
+
346
+ including_class_instance.value = formatted_value
347
+ end
348
+ end
349
+ end
350
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe MetasploitDataModels::IPAddress::Range do
4
+ subject(:range) {
5
+ range_class.new
6
+ }
7
+
8
+ #
9
+ # Shared examples
10
+ #
11
+
12
+ shared_examples_for 'extreme' do |extreme|
13
+ context "##{extreme}" do
14
+ subject("range_#{extreme}") {
15
+ range.send(extreme)
16
+ }
17
+
18
+ before(:each) do
19
+ allow(range).to receive(:value).and_return(value)
20
+ end
21
+
22
+ context 'with #value' do
23
+ context 'with Range' do
24
+ let(:value) {
25
+ Range.new(0, 1)
26
+ }
27
+
28
+ it "is Range##{extreme} of #value" do
29
+ expect(send("range_#{extreme}")).to eq(value.send(extreme))
30
+ end
31
+ end
32
+
33
+ context 'without Range' do
34
+ let(:value) {
35
+ 'invalid_value'
36
+ }
37
+
38
+ it { should be_nil }
39
+ end
40
+ end
41
+
42
+ context 'without #value' do
43
+ let(:value) {
44
+ nil
45
+ }
46
+
47
+ it { should be_nil }
48
+ end
49
+ end
50
+ end
51
+
52
+ #
53
+ # lets
54
+ #
55
+
56
+ let(:range_class) {
57
+ described_class = self.described_class
58
+
59
+ Class.new do
60
+ include described_class
61
+ end
62
+ }
63
+
64
+ context 'CONSTANTS' do
65
+ context 'SEPARATOR' do
66
+ subject(:separator) {
67
+ described_class::SEPARATOR
68
+ }
69
+
70
+ it { should == '-' }
71
+ end
72
+ end
73
+
74
+ it_should_behave_like 'extreme', :begin
75
+ it_should_behave_like 'extreme', :end
76
+
77
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe MetasploitDataModels::Match::Child do
4
+ let(:extending_class) {
5
+ # capture as local for Class.new block scope
6
+ described_class = self.described_class
7
+
8
+ Class.new(Metasploit::Model::Base) {
9
+ extend described_class
10
+
11
+ #
12
+ # Attributes
13
+ #
14
+
15
+ # @!attribute value
16
+ # @return [String]
17
+ attr_accessor :value
18
+ }
19
+ }
20
+
21
+ before(:each) do
22
+ stub_const('ExtendingClass', extending_class)
23
+ stub_const('ExtendingClass::REGEXP', /\d+-\d+/)
24
+ end
25
+
26
+ context '#match' do
27
+ subject(:match) {
28
+ extending_class.match(formatted_value)
29
+ }
30
+
31
+ context 'formatted value' do
32
+ context 'with matching' do
33
+ let(:formatted_value) {
34
+ '1-2'
35
+ }
36
+
37
+ it 'returns instance of extending class' do
38
+ expect(match).to be_an extending_class
39
+ end
40
+
41
+ context '#value' do
42
+ subject(:value) {
43
+ match.value
44
+ }
45
+
46
+ it 'is set to formatted value' do
47
+ expect(value).to eq(formatted_value)
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'without matching' do
53
+ let(:formatted_value) do
54
+ '1,2-3'
55
+ end
56
+
57
+ it { should be_nil }
58
+ end
59
+ end
60
+ end
61
+ end