metasploit_data_models 0.18.1-java → 0.19.0-java

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 +4 -4
  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,155 @@
1
+ require 'spec_helper'
2
+
3
+ describe MetasploitDataModels::Match::Parent do
4
+ let(:including_class) {
5
+ described_class = self.described_class
6
+
7
+ Class.new {
8
+ include described_class
9
+ }
10
+ }
11
+
12
+ let(:including_class_instance) {
13
+ including_class.new
14
+ }
15
+
16
+ context 'match_child_names' do
17
+ subject(:match_child_names) {
18
+ including_class.match_child_names
19
+ }
20
+
21
+ context 'default' do
22
+ it { should == [] }
23
+ end
24
+ end
25
+
26
+ context '#match_child' do
27
+ subject(:match_child) {
28
+ including_class_instance.match_child(formatted_value)
29
+ }
30
+
31
+ #
32
+ # lets
33
+ #
34
+
35
+ let(:number_child_class) {
36
+ Class.new(Metasploit::Model::Base) do
37
+ extend MetasploitDataModels::Match::Child
38
+
39
+ attr_accessor :value
40
+ end
41
+ }
42
+
43
+ let(:range_child_class) {
44
+ Class.new(Metasploit::Model::Base) do
45
+ extend MetasploitDataModels::Match::Child
46
+
47
+ attr_accessor :value
48
+ end
49
+ }
50
+
51
+ #
52
+ # Callbacks
53
+ #
54
+
55
+ before(:each) do
56
+ stub_const('NumberChild', number_child_class)
57
+ stub_const('NumberChild::REGEXP', /\d+/)
58
+
59
+ stub_const('RangeChild', range_child_class)
60
+ stub_const('RangeChild::REGEXP', /\d+-\d+/)
61
+
62
+ including_class.class_eval do
63
+ match_children_named %w{NumberChild RangeChild}
64
+ end
65
+ end
66
+
67
+ context 'with matching child class' do
68
+ let(:formatted_value) {
69
+ '1-10'
70
+ }
71
+
72
+ it 'returns instance of matching child class' do
73
+ expect(match_child).to be_a RangeChild
74
+ end
75
+ end
76
+
77
+ context 'without matching child class' do
78
+ let(:formatted_value) {
79
+ 'a-b'
80
+ }
81
+
82
+ it 'calls match on all child classes' do
83
+ expect(NumberChild).to receive(:match).with(formatted_value)
84
+ expect(RangeChild).to receive(:match).with(formatted_value)
85
+
86
+ match_child
87
+ end
88
+
89
+ it { should be_nil }
90
+ end
91
+ end
92
+
93
+ context 'match_children' do
94
+ subject(:match_children) {
95
+ including_class.match_children
96
+ }
97
+
98
+ context 'default' do
99
+ it { should == [] }
100
+ end
101
+
102
+ context 'with class names' do
103
+ #
104
+ # lets
105
+ #
106
+
107
+ let(:child_class_names) {
108
+ [
109
+ 'ChildOne',
110
+ 'ChildTwo'
111
+ ]
112
+ }
113
+
114
+ let(:child_classes) {
115
+ child_class_names.map { |child_class_name|
116
+ child_class = Class.new
117
+
118
+ stub_const(child_class_name, child_class)
119
+
120
+ child_class
121
+ }
122
+ }
123
+
124
+ #
125
+ # Callbacks
126
+ #
127
+
128
+ before(:each) do
129
+ including_class.match_children_named child_classes.map(&:name)
130
+ end
131
+
132
+ it 'includes child Classes' do
133
+ expect(match_children).to match_array(child_classes)
134
+ end
135
+ end
136
+ end
137
+
138
+ context 'match_children_named' do
139
+ subject(:match_children_named) {
140
+ including_class.match_children_named child_class_names
141
+ }
142
+
143
+ let(:child_class_names) {
144
+ Array.new(2) { |i|
145
+ "ChildClass#{i}"
146
+ }
147
+ }
148
+
149
+ it 'sets match_child_names' do
150
+ match_children_named
151
+
152
+ expect(including_class.match_child_names).to eq(child_class_names)
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,28 @@
1
+ # Checks that the string matches the
2
+ RSpec::Matchers.define :match_string_exactly do |string|
3
+ failure_message_for_should do |regexp|
4
+ match = regexp.match(string)
5
+
6
+ failure_message = "expected #{regexp} to match #{string}"
7
+
8
+ if match
9
+ failure_message << ', but'
10
+
11
+ unless match.pre_match.empty?
12
+ failure_message << " pre-match is #{match.pre_match}"
13
+ end
14
+
15
+ unless match.post_match.empty?
16
+ failure_message << " post-match is #{match.post_match}"
17
+ end
18
+ end
19
+
20
+ failure_message
21
+ end
22
+
23
+ match do |regexp|
24
+ match = regexp.match(string)
25
+
26
+ match && match.pre_match.empty? && match.post_match.empty?
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ shared_context 'Rex::Text' do
2
+ before(:each) do
3
+ rex_text = Module.new do
4
+ def self.ascii_safe_hex(str, whitespace=false)
5
+ if whitespace
6
+ str.gsub(/([\x00-\x20\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] }
7
+ else
8
+ str.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0]}
9
+ end
10
+ end
11
+ end
12
+
13
+ stub_const('Rex::Text', rex_text)
14
+ end
15
+ end
@@ -0,0 +1,109 @@
1
+ shared_examples_for 'MetasploitDataModels::Search::Operation::IPAddress::*.match' do |options={}|
2
+ options.assert_valid_keys(4, 6)
3
+
4
+ subject(:match) {
5
+ described_class.match(formatted_value)
6
+ }
7
+
8
+ #
9
+ # Shared Examples
10
+ #
11
+
12
+ shared_examples_for 'match' do |boolean|
13
+ if boolean
14
+ it { should be_a described_class }
15
+
16
+ it 'does not set #operator' do
17
+ expect(match.operator).to be_nil
18
+ end
19
+
20
+ it 'sets #value' do
21
+ expect(match.value).not_to be_nil
22
+ end
23
+ else
24
+ it { should be_nil }
25
+ end
26
+ end
27
+
28
+ context 'with IPv4' do
29
+ ipv4 = options.fetch(4, [])
30
+ ipv4 = Set.new Array.wrap(ipv4)
31
+
32
+ key_set = Set.new([:cidr, :nmap, :range, :single])
33
+
34
+ unless key_set.superset?(ipv4)
35
+ unknown_keys = ipv4 - key_set
36
+
37
+ raise ArgumentError, "keys (#{unknown_keys.sort.to_sentence}) not in known keys (#{key_set.sort.to_sentence})"
38
+ end
39
+
40
+ context 'with CIDR' do
41
+ let(:formatted_value) {
42
+ '1.2.3.4/24'
43
+ }
44
+
45
+ it_should_behave_like 'match', ipv4.include?(:cidr)
46
+ end
47
+
48
+ context 'with NMAP' do
49
+ let(:formatted_value) {
50
+ '1-2,4.5,6-7.8-9,10-11.12,13'
51
+ }
52
+
53
+ it_should_behave_like 'match', ipv4.include?(:nmap)
54
+ end
55
+
56
+ context 'with range' do
57
+ let(:formatted_value) {
58
+ '1.2.3.4-5.6.7.8'
59
+ }
60
+
61
+ it_should_behave_like 'match', ipv4.include?(:range)
62
+ end
63
+
64
+ context 'with single' do
65
+ let(:formatted_value) {
66
+ '1.2.3.4'
67
+ }
68
+
69
+ it_should_behave_like 'match', ipv4.include?(:single)
70
+ end
71
+ end
72
+
73
+ context 'with IPv6' do
74
+ ipv6 = options.fetch(6, [])
75
+ ipv6 = Set.new Array.wrap(ipv6)
76
+
77
+ key_set = Set.new([:cidr, :range, :single])
78
+
79
+ unless key_set.superset?(ipv6)
80
+ unknown_keys = ipv6 - key_set
81
+
82
+ raise ArgumentError, "keys (#{unknown_keys.sort.to_sentence}) not in known keys (#{key_set.sort.to_sentence})"
83
+ end
84
+
85
+ context 'with CIDR' do
86
+ let(:formatted_value) {
87
+ '1:2:3:4:5:6:7:8/48'
88
+ }
89
+
90
+ it_should_behave_like 'match', ipv6.include?(:cidr)
91
+ end
92
+
93
+ context 'with range' do
94
+ let(:formatted_value) {
95
+ '1:2:3:4:5:6:7:8-9:10:11:12:13:14:15:16'
96
+ }
97
+
98
+ it_should_behave_like 'match', ipv6.include?(:range)
99
+ end
100
+
101
+ context 'with single' do
102
+ let(:formatted_value) {
103
+ '1:2:3:4:5:6:7:8'
104
+ }
105
+
106
+ it_should_behave_like 'match', ipv6.include?(:single)
107
+ end
108
+ end
109
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metasploit_data_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.19.0
5
5
  platform: java
6
6
  authors:
7
7
  - Samuel Huckins
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-07-17 00:00:00.000000000 Z
14
+ date: 2014-07-18 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rake
@@ -31,14 +31,14 @@ dependencies:
31
31
  name: yard
32
32
  version_requirements: !ruby/object:Gem::Requirement
33
33
  requirements:
34
- - - '>='
34
+ - - <
35
35
  - !ruby/object:Gem::Version
36
- version: '0'
36
+ version: 0.8.7.4
37
37
  requirement: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - '>='
39
+ - - <
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
41
+ version: 0.8.7.4
42
42
  prerelease: false
43
43
  type: :development
44
44
  - !ruby/object:Gem::Dependency
@@ -248,9 +248,19 @@ files:
248
248
  - app/models/mdm/wmap_request.rb
249
249
  - app/models/mdm/wmap_target.rb
250
250
  - app/models/mdm/workspace.rb
251
+ - app/models/metasploit_data_models/ip_address/v4/cidr.rb
252
+ - app/models/metasploit_data_models/ip_address/v4/nmap.rb
253
+ - app/models/metasploit_data_models/ip_address/v4/range.rb
254
+ - app/models/metasploit_data_models/ip_address/v4/segment/nmap/list.rb
255
+ - app/models/metasploit_data_models/ip_address/v4/segment/nmap/range.rb
256
+ - app/models/metasploit_data_models/ip_address/v4/segment/single.rb
257
+ - app/models/metasploit_data_models/ip_address/v4/segmented.rb
258
+ - app/models/metasploit_data_models/ip_address/v4/single.rb
259
+ - app/models/metasploit_data_models/search/operation/ip_address.rb
251
260
  - app/models/metasploit_data_models/search/operation/port/number.rb
252
261
  - app/models/metasploit_data_models/search/operation/port/range.rb
253
262
  - app/models/metasploit_data_models/search/operation/range.rb
263
+ - app/models/metasploit_data_models/search/operator/ip_address.rb
254
264
  - app/models/metasploit_data_models/search/operator/multitext.rb
255
265
  - app/models/metasploit_data_models/search/operator/port/list.rb
256
266
  - app/models/metasploit_data_models/search/visitor/attribute.rb
@@ -380,6 +390,11 @@ files:
380
390
  - lib/metasploit_data_models/base64_serializer.rb
381
391
  - lib/metasploit_data_models/change_required_columns_to_null_false.rb
382
392
  - lib/metasploit_data_models/engine.rb
393
+ - lib/metasploit_data_models/ip_address.rb
394
+ - lib/metasploit_data_models/ip_address/cidr.rb
395
+ - lib/metasploit_data_models/ip_address/range.rb
396
+ - lib/metasploit_data_models/match/child.rb
397
+ - lib/metasploit_data_models/match/parent.rb
383
398
  - lib/metasploit_data_models/search.rb
384
399
  - lib/metasploit_data_models/search/visitor.rb
385
400
  - lib/metasploit_data_models/serialized_prefs.rb
@@ -434,9 +449,19 @@ files:
434
449
  - spec/app/models/mdm/wmap_request_spec.rb
435
450
  - spec/app/models/mdm/wmap_target_spec.rb
436
451
  - spec/app/models/mdm/workspace_spec.rb
452
+ - spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb
453
+ - spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb
454
+ - spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb
455
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb
456
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb
457
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb
458
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb
459
+ - spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb
460
+ - spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb
437
461
  - spec/app/models/metasploit_data_models/search/operation/port/number_spec.rb
438
462
  - spec/app/models/metasploit_data_models/search/operation/port/range_spec.rb
439
463
  - spec/app/models/metasploit_data_models/search/operation/range_spec.rb
464
+ - spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb
440
465
  - spec/app/models/metasploit_data_models/search/operator/multitext_spec.rb
441
466
  - spec/app/models/metasploit_data_models/search/operator/port/list_spec.rb
442
467
  - spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb
@@ -472,7 +497,7 @@ files:
472
497
  - spec/dummy/config/initializers/session_store.rb
473
498
  - spec/dummy/config/initializers/wrap_parameters.rb
474
499
  - spec/dummy/config/routes.rb
475
- - spec/dummy/db/schema.rb
500
+ - spec/dummy/db/structure.sql
476
501
  - spec/dummy/lib/assets/.gitkeep
477
502
  - spec/dummy/log/.gitkeep
478
503
  - spec/dummy/public/404.html
@@ -528,10 +553,17 @@ files:
528
553
  - spec/factories/mdm/web_vulns.rb
529
554
  - spec/factories/mdm/workspaces.rb
530
555
  - spec/lib/base64_serializer_spec.rb
556
+ - spec/lib/metasploit_data_models/ip_address/cidr_spec.rb
557
+ - spec/lib/metasploit_data_models/ip_address/range_spec.rb
558
+ - spec/lib/metasploit_data_models/match/child_spec.rb
559
+ - spec/lib/metasploit_data_models/match/parent_spec.rb
531
560
  - spec/lib/metasploit_data_models/version_spec.rb
532
561
  - spec/spec_helper.rb
562
+ - spec/support/matchers/match_regex_exactly.rb
563
+ - spec/support/shared/contexts/rex/text.rb
533
564
  - spec/support/shared/examples/mdm/module/detail/does_not_support_stance_with_mtype.rb
534
565
  - spec/support/shared/examples/mdm/module/detail/supports_stance_with_mtype.rb
566
+ - spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb
535
567
  - spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_children.rb
536
568
  - spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_metasploit_model_search_operation_base.rb
537
569
  - spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record.rb
@@ -558,7 +590,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
558
590
  version: '0'
559
591
  requirements: []
560
592
  rubyforge_project:
561
- rubygems_version: 2.1.9
593
+ rubygems_version: 2.2.2
562
594
  signing_key:
563
595
  specification_version: 4
564
596
  summary: Database code for MSF and Metasploit Pro
@@ -610,9 +642,19 @@ test_files:
610
642
  - spec/app/models/mdm/wmap_request_spec.rb
611
643
  - spec/app/models/mdm/wmap_target_spec.rb
612
644
  - spec/app/models/mdm/workspace_spec.rb
645
+ - spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb
646
+ - spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb
647
+ - spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb
648
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb
649
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb
650
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb
651
+ - spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb
652
+ - spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb
653
+ - spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb
613
654
  - spec/app/models/metasploit_data_models/search/operation/port/number_spec.rb
614
655
  - spec/app/models/metasploit_data_models/search/operation/port/range_spec.rb
615
656
  - spec/app/models/metasploit_data_models/search/operation/range_spec.rb
657
+ - spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb
616
658
  - spec/app/models/metasploit_data_models/search/operator/multitext_spec.rb
617
659
  - spec/app/models/metasploit_data_models/search/operator/port/list_spec.rb
618
660
  - spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb
@@ -648,7 +690,7 @@ test_files:
648
690
  - spec/dummy/config/initializers/session_store.rb
649
691
  - spec/dummy/config/initializers/wrap_parameters.rb
650
692
  - spec/dummy/config/routes.rb
651
- - spec/dummy/db/schema.rb
693
+ - spec/dummy/db/structure.sql
652
694
  - spec/dummy/lib/assets/.gitkeep
653
695
  - spec/dummy/log/.gitkeep
654
696
  - spec/dummy/public/404.html
@@ -704,10 +746,17 @@ test_files:
704
746
  - spec/factories/mdm/web_vulns.rb
705
747
  - spec/factories/mdm/workspaces.rb
706
748
  - spec/lib/base64_serializer_spec.rb
749
+ - spec/lib/metasploit_data_models/ip_address/cidr_spec.rb
750
+ - spec/lib/metasploit_data_models/ip_address/range_spec.rb
751
+ - spec/lib/metasploit_data_models/match/child_spec.rb
752
+ - spec/lib/metasploit_data_models/match/parent_spec.rb
707
753
  - spec/lib/metasploit_data_models/version_spec.rb
708
754
  - spec/spec_helper.rb
755
+ - spec/support/matchers/match_regex_exactly.rb
756
+ - spec/support/shared/contexts/rex/text.rb
709
757
  - spec/support/shared/examples/mdm/module/detail/does_not_support_stance_with_mtype.rb
710
758
  - spec/support/shared/examples/mdm/module/detail/supports_stance_with_mtype.rb
759
+ - spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb
711
760
  - spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_children.rb
712
761
  - spec/support/shared/examples/metasploit_data_models/search/visitor/includes/visit/with_metasploit_model_search_operation_base.rb
713
762
  - spec/support/shared/examples/metasploit_data_models/search/visitor/relation/visit/matching_record.rb