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.
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
@@ -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