metasploit-model 0.27.3 → 0.27.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +8 -8
  2. data/.rspec +1 -1
  3. data/app/models/metasploit/model/association/reflection.rb +0 -3
  4. data/app/models/metasploit/model/module/ancestor/spec/template.rb +0 -3
  5. data/app/models/metasploit/model/module/class/spec/template.rb +0 -4
  6. data/app/models/metasploit/model/module/instance/spec/template.rb +0 -4
  7. data/app/models/metasploit/model/search/group/base.rb +0 -3
  8. data/app/models/metasploit/model/search/group/intersection.rb +0 -3
  9. data/app/models/metasploit/model/search/group/union.rb +0 -3
  10. data/app/models/metasploit/model/search/operation/association.rb +0 -2
  11. data/app/models/metasploit/model/search/operation/base.rb +0 -3
  12. data/app/models/metasploit/model/search/operation/boolean.rb +0 -2
  13. data/app/models/metasploit/model/search/operation/date.rb +0 -2
  14. data/app/models/metasploit/model/search/operation/group/base.rb +0 -2
  15. data/app/models/metasploit/model/search/operation/group/intersection.rb +0 -2
  16. data/app/models/metasploit/model/search/operation/group/union.rb +0 -2
  17. data/app/models/metasploit/model/search/operation/integer.rb +1 -5
  18. data/app/models/metasploit/model/search/operation/null.rb +0 -2
  19. data/app/models/metasploit/model/search/operation/set.rb +5 -2
  20. data/app/models/metasploit/model/search/operation/set/integer.rb +1 -3
  21. data/app/models/metasploit/model/search/operation/set/string.rb +1 -3
  22. data/app/models/metasploit/model/search/operation/string.rb +1 -5
  23. data/app/models/metasploit/model/search/operator/association.rb +0 -2
  24. data/app/models/metasploit/model/search/operator/attribute.rb +0 -2
  25. data/app/models/metasploit/model/search/operator/base.rb +0 -4
  26. data/app/models/metasploit/model/search/operator/delegation.rb +0 -2
  27. data/app/models/metasploit/model/search/operator/deprecated/app.rb +0 -2
  28. data/app/models/metasploit/model/search/operator/deprecated/author.rb +0 -2
  29. data/app/models/metasploit/model/search/operator/deprecated/authority.rb +0 -2
  30. data/app/models/metasploit/model/search/operator/deprecated/platform.rb +0 -2
  31. data/app/models/metasploit/model/search/operator/deprecated/ref.rb +0 -2
  32. data/app/models/metasploit/model/search/operator/deprecated/text.rb +0 -2
  33. data/app/models/metasploit/model/search/operator/group/base.rb +0 -2
  34. data/app/models/metasploit/model/search/operator/group/intersection.rb +0 -2
  35. data/app/models/metasploit/model/search/operator/group/union.rb +0 -2
  36. data/app/models/metasploit/model/search/operator/null.rb +0 -2
  37. data/app/models/metasploit/model/search/operator/single.rb +0 -2
  38. data/app/models/metasploit/model/search/query.rb +0 -3
  39. data/app/models/metasploit/model/spec/template.rb +0 -3
  40. data/app/models/metasploit/model/visitation/visitor.rb +0 -3
  41. data/lib/metasploit/model.rb +14 -8
  42. data/lib/metasploit/model/architecture.rb +320 -326
  43. data/lib/metasploit/model/association.rb +43 -46
  44. data/lib/metasploit/model/association/error.rb +29 -33
  45. data/lib/metasploit/model/association/tree.rb +119 -125
  46. data/lib/metasploit/model/author.rb +45 -51
  47. data/lib/metasploit/model/authority.rb +139 -146
  48. data/lib/metasploit/model/authority/bid.rb +0 -2
  49. data/lib/metasploit/model/authority/cve.rb +0 -2
  50. data/lib/metasploit/model/authority/msb.rb +0 -2
  51. data/lib/metasploit/model/authority/osvdb.rb +0 -2
  52. data/lib/metasploit/model/authority/pmasa.rb +0 -2
  53. data/lib/metasploit/model/authority/secunia.rb +0 -2
  54. data/lib/metasploit/model/authority/us_cert_vu.rb +0 -2
  55. data/lib/metasploit/model/authority/waraxe.rb +0 -2
  56. data/lib/metasploit/model/authority/zdi.rb +0 -2
  57. data/lib/metasploit/model/base.rb +0 -2
  58. data/lib/metasploit/model/derivation.rb +95 -99
  59. data/lib/metasploit/model/derivation/full_name.rb +16 -22
  60. data/lib/metasploit/model/email_address.rb +122 -128
  61. data/lib/metasploit/model/engine.rb +26 -21
  62. data/lib/metasploit/model/error.rb +3 -7
  63. data/lib/metasploit/model/file.rb +0 -2
  64. data/lib/metasploit/model/invalid.rb +11 -17
  65. data/lib/metasploit/model/login.rb +0 -3
  66. data/lib/metasploit/model/login/status.rb +0 -2
  67. data/lib/metasploit/model/module.rb +19 -23
  68. data/lib/metasploit/model/module/action.rb +50 -58
  69. data/lib/metasploit/model/module/ancestor.rb +456 -465
  70. data/lib/metasploit/model/module/ancestor/spec.rb +3 -2
  71. data/lib/metasploit/model/module/architecture.rb +27 -35
  72. data/lib/metasploit/model/module/author.rb +38 -47
  73. data/lib/metasploit/model/module/class.rb +358 -366
  74. data/lib/metasploit/model/module/class/spec.rb +3 -2
  75. data/lib/metasploit/model/module/handler.rb +28 -34
  76. data/lib/metasploit/model/module/instance.rb +586 -596
  77. data/lib/metasploit/model/module/instance/spec.rb +3 -2
  78. data/lib/metasploit/model/module/path.rb +157 -166
  79. data/lib/metasploit/model/module/platform.rb +25 -33
  80. data/lib/metasploit/model/module/rank.rb +71 -79
  81. data/lib/metasploit/model/module/reference.rb +25 -33
  82. data/lib/metasploit/model/module/stance.rb +15 -21
  83. data/lib/metasploit/model/module/target.rb +76 -84
  84. data/lib/metasploit/model/module/target/architecture.rb +27 -37
  85. data/lib/metasploit/model/module/target/platform.rb +27 -37
  86. data/lib/metasploit/model/module/type.rb +35 -41
  87. data/lib/metasploit/model/nilify_blanks.rb +39 -43
  88. data/lib/metasploit/model/platform.rb +231 -237
  89. data/lib/metasploit/model/real_pathname.rb +12 -16
  90. data/lib/metasploit/model/realm.rb +0 -2
  91. data/lib/metasploit/model/realm/key.rb +0 -2
  92. data/lib/metasploit/model/reference.rb +102 -108
  93. data/lib/metasploit/model/search.rb +94 -97
  94. data/lib/metasploit/model/search/association.rb +163 -169
  95. data/lib/metasploit/model/search/attribute.rb +131 -139
  96. data/lib/metasploit/model/search/group.rb +5 -2
  97. data/lib/metasploit/model/search/operation.rb +32 -29
  98. data/lib/metasploit/model/search/operation/group.rb +5 -2
  99. data/lib/metasploit/model/search/operation/value.rb +7 -0
  100. data/lib/metasploit/model/search/operation/{integer/value.rb → value/integer.rb} +1 -1
  101. data/lib/metasploit/model/search/operation/{string/value.rb → value/string.rb} +1 -1
  102. data/lib/metasploit/model/search/operator.rb +65 -65
  103. data/lib/metasploit/model/search/operator/deprecated.rb +8 -2
  104. data/lib/metasploit/model/search/operator/group.rb +5 -2
  105. data/lib/metasploit/model/search/operator/help.rb +71 -79
  106. data/lib/metasploit/model/search/with.rb +72 -78
  107. data/lib/metasploit/model/spec.rb +133 -136
  108. data/lib/metasploit/model/spec/error.rb +3 -9
  109. data/lib/metasploit/model/spec/i18n_exception_handler.rb +0 -2
  110. data/lib/metasploit/model/spec/pathname_collision.rb +19 -27
  111. data/lib/metasploit/model/spec/template/write.rb +0 -2
  112. data/lib/metasploit/model/spec/temporary_pathname.rb +47 -56
  113. data/lib/metasploit/model/translation.rb +0 -2
  114. data/lib/metasploit/model/version.rb +1 -1
  115. data/lib/metasploit/model/visitation.rb +7 -10
  116. data/lib/metasploit/model/visitation/visit.rb +79 -85
  117. data/metasploit-model.gemspec +1 -1
  118. data/spec/app/models/metasploit/model/search/operation/integer_spec.rb +1 -1
  119. data/spec/app/models/metasploit/model/search/operation/set/integer_spec.rb +1 -1
  120. data/spec/app/models/metasploit/model/search/operation/set/string_spec.rb +1 -1
  121. data/spec/app/models/metasploit/model/search/operation/string_spec.rb +1 -1
  122. data/spec/dummy/config/application.rb +1 -0
  123. data/spec/lib/metasploit/model/search/operation/{integer/value_spec.rb → value/integer_spec.rb} +2 -2
  124. data/spec/lib/metasploit/model/search/operation/{string/value_spec.rb → value/string_spec.rb} +2 -2
  125. data/spec/support/shared/examples/metasploit/model/search/operation/{integer/value.rb → value/integer.rb} +2 -2
  126. data/spec/support/shared/examples/metasploit/model/search/operation/{string/value.rb → value/string.rb} +2 -2
  127. metadata +16 -13
@@ -1,5 +1,6 @@
1
- require 'metasploit/model/module/class'
2
-
3
1
  # Namespace for `Module`s that help with writing specs for {Metasploit::Model::Module::Class}.
4
2
  module Metasploit::Model::Module::Class::Spec
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Template
5
6
  end
@@ -1,35 +1,29 @@
1
- module Metasploit
2
- module Model
3
- module Module
4
- # The handler Module for a {Metasploit::Model::Module::Ancestor#handled?} {Metasploit::Model::Module::Ancestor}.
5
- module Handler
6
- #
7
- # CONSTANTS
8
- #
1
+ # The handler Module for a {Metasploit::Model::Module::Ancestor#handled?} {Metasploit::Model::Module::Ancestor}.
2
+ module Metasploit::Model::Module::Handler
3
+ #
4
+ # CONSTANTS
5
+ #
9
6
 
10
- # Maps {TYPES} to {GENERAL_TYPES} used as connection types for `Msf::Payload`.
11
- GENERAL_TYPE_BY_TYPE = {
12
- 'bind_tcp' => 'bind',
13
- 'find_port' => 'find',
14
- 'find_shell' => 'find',
15
- 'find_tag' => 'find',
16
- 'none' => 'none',
17
- 'reverse_http' => 'tunnel',
18
- 'reverse_https' => 'tunnel',
19
- 'reverse_https_proxy' => 'tunnel',
20
- 'reverse_ipv6_http' => 'tunnel',
21
- 'reverse_ipv6_https' => 'tunnel',
22
- 'reverse_tcp' => 'reverse',
23
- 'reverse_tcp_allports' => 'reverse',
24
- 'reverse_tcp_double' => 'reverse',
25
- 'reverse_tcp_double_ssl' => 'reverse',
26
- 'reverse_tcp_ssl' => 'reverse'
27
- }
28
- # General handler types that are used as connection types for Msf::Payloads.
29
- GENERAL_TYPES = GENERAL_TYPE_BY_TYPE.values.uniq.sort
30
- # Types of handlers
31
- TYPES = GENERAL_TYPE_BY_TYPE.keys.sort
32
- end
33
- end
34
- end
35
- end
7
+ # Maps {TYPES} to {GENERAL_TYPES} used as connection types for `Msf::Payload`.
8
+ GENERAL_TYPE_BY_TYPE = {
9
+ 'bind_tcp' => 'bind',
10
+ 'find_port' => 'find',
11
+ 'find_shell' => 'find',
12
+ 'find_tag' => 'find',
13
+ 'none' => 'none',
14
+ 'reverse_http' => 'tunnel',
15
+ 'reverse_https' => 'tunnel',
16
+ 'reverse_https_proxy' => 'tunnel',
17
+ 'reverse_ipv6_http' => 'tunnel',
18
+ 'reverse_ipv6_https' => 'tunnel',
19
+ 'reverse_tcp' => 'reverse',
20
+ 'reverse_tcp_allports' => 'reverse',
21
+ 'reverse_tcp_double' => 'reverse',
22
+ 'reverse_tcp_double_ssl' => 'reverse',
23
+ 'reverse_tcp_ssl' => 'reverse'
24
+ }
25
+ # General handler types that are used as connection types for Msf::Payloads.
26
+ GENERAL_TYPES = GENERAL_TYPE_BY_TYPE.values.uniq.sort
27
+ # Types of handlers
28
+ TYPES = GENERAL_TYPE_BY_TYPE.keys.sort
29
+ end
@@ -1,632 +1,622 @@
1
- require 'metasploit/model/module/type'
2
- require 'metasploit/model/translation'
3
-
4
- module Metasploit
5
- module Model
6
- module Module
7
- # Code shared between `Mdm::Module::Instance` and `Metasploit::Framework::Module::Instance`.
8
- module Instance
9
- extend ActiveModel::Naming
10
- extend ActiveSupport::Autoload
11
- extend ActiveSupport::Concern
12
-
13
- include Metasploit::Model::Translation
14
-
15
- autoload :Spec
16
-
17
- #
18
- # CONSTANTS
19
- #
20
-
21
- # {#dynamic_length_validation_options} by {#module_type} by attribute.
22
- DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE = {
23
- actions: {
24
- Metasploit::Model::Module::Type::AUX => {
25
- minimum: 0
26
- },
27
- Metasploit::Model::Module::Type::ENCODER => {
28
- is: 0
29
- },
30
- Metasploit::Model::Module::Type::EXPLOIT => {
31
- is: 0
32
- },
33
- Metasploit::Model::Module::Type::NOP => {
34
- is: 0
35
- },
36
- Metasploit::Model::Module::Type::PAYLOAD => {
37
- is: 0
38
- },
39
- Metasploit::Model::Module::Type::POST => {
40
- minimum: 0
41
- }
42
- },
43
- module_architectures: {
44
- Metasploit::Model::Module::Type::AUX => {
45
- is: 0
46
- },
47
- Metasploit::Model::Module::Type::ENCODER => {
48
- minimum: 1
49
- },
50
- Metasploit::Model::Module::Type::EXPLOIT => {
51
- minimum: 1
52
- },
53
- Metasploit::Model::Module::Type::NOP => {
54
- minimum: 1
55
- },
56
- Metasploit::Model::Module::Type::PAYLOAD => {
57
- minimum: 1
58
- },
59
- Metasploit::Model::Module::Type::POST => {
60
- minimum: 1
61
- }
62
- },
63
- module_platforms: {
64
- Metasploit::Model::Module::Type::AUX => {
65
- is: 0
66
- },
67
- Metasploit::Model::Module::Type::ENCODER => {
68
- is: 0
69
- },
70
- Metasploit::Model::Module::Type::EXPLOIT => {
71
- minimum: 1
72
- },
73
- Metasploit::Model::Module::Type::NOP => {
74
- is: 0
75
- },
76
- Metasploit::Model::Module::Type::PAYLOAD => {
77
- minimum: 1
78
- },
79
- Metasploit::Model::Module::Type::POST => {
80
- minimum: 1
81
- }
82
- },
83
- module_references: {
84
- Metasploit::Model::Module::Type::AUX => {
85
- minimum: 0
86
- },
87
- Metasploit::Model::Module::Type::ENCODER => {
88
- is: 0
89
- },
90
- Metasploit::Model::Module::Type::EXPLOIT => {
91
- minimum: 1
92
- },
93
- Metasploit::Model::Module::Type::NOP => {
94
- is: 0
95
- },
96
- Metasploit::Model::Module::Type::PAYLOAD => {
97
- is: 0
98
- },
99
- Metasploit::Model::Module::Type::POST => {
100
- minimum: 0
101
- }
102
- },
103
- targets: {
104
- Metasploit::Model::Module::Type::AUX => {
105
- is: 0
106
- },
107
- Metasploit::Model::Module::Type::ENCODER => {
108
- is: 0
109
- },
110
- Metasploit::Model::Module::Type::EXPLOIT => {
111
- minimum: 1
112
- },
113
- Metasploit::Model::Module::Type::NOP => {
114
- is: 0
115
- },
116
- Metasploit::Model::Module::Type::PAYLOAD => {
117
- is: 0
118
- },
119
- Metasploit::Model::Module::Type::POST => {
120
- is: 0
121
- }
122
- }
123
- }
124
-
125
- # Minimum length of {#module_authors}.
126
- MINIMUM_MODULE_AUTHORS_LENGTH = 1
127
-
128
- # {#privileged} is Boolean so, valid values are just `true` and `false`, but since both the validation and
129
- # factory need an array of valid values, this constant exists.
130
- PRIVILEGES = [
131
- false,
132
- true
133
- ]
134
-
135
- # Member of {Metasploit::Model::Module::Type::ALL} that require {#stance} to be non-`nil`.
136
- STANCED_MODULE_TYPES = [
137
- Metasploit::Model::Module::Type::AUX,
138
- Metasploit::Model::Module::Type::EXPLOIT
139
- ]
140
-
141
- included do
142
- include ActiveModel::Validations
143
- include Metasploit::Model::Search
144
-
145
- #
146
- #
147
- # Search
148
- #
149
- #
150
-
151
- #
152
- # Search Associations
153
- #
154
-
155
- search_association :actions
156
- search_association :architectures
157
- search_association :authorities
158
- search_association :authors
159
- search_association :email_addresses
160
- search_association :module_class
161
- search_association :platforms
162
- search_association :rank
163
- search_association :references
164
- search_association :targets
165
-
166
- #
167
- # Search Attributes
168
- #
169
-
170
- search_attribute :description, :type => :string
171
- search_attribute :disclosed_on, :type => :date
172
- search_attribute :license, :type => :string
173
- search_attribute :name, :type => :string
174
- search_attribute :privileged, :type => :boolean
175
- search_attribute :stance, :type => :string
176
-
177
- #
178
- # Search Withs
179
- #
180
-
181
- search_with Metasploit::Model::Search::Operator::Deprecated::App
182
- search_with Metasploit::Model::Search::Operator::Deprecated::Author
183
- search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
184
- :abbreviation => :bid
185
- search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
186
- :abbreviation => :cve
187
- search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
188
- :abbreviation => :edb
189
- search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
190
- :abbreviation => :osvdb
191
- search_with Metasploit::Model::Search::Operator::Deprecated::Platform,
192
- :name => :os
193
- search_with Metasploit::Model::Search::Operator::Deprecated::Platform,
194
- :name => :platform
195
- search_with Metasploit::Model::Search::Operator::Deprecated::Ref
196
- search_with Metasploit::Model::Search::Operator::Deprecated::Text
197
-
198
- #
199
- #
200
- # Validations
201
- #
202
- #
203
-
204
- #
205
- # Method Validations
206
- #
207
-
208
- validate :architectures_from_targets,
209
- if: 'allows?(:targets)'
210
- validate :platforms_from_targets,
211
- if: 'allows?(:targets)'
212
-
213
- #
214
- # Attribute Validations
215
- #
216
-
217
- validates :actions,
218
- dynamic_length: true
219
- validates :description,
220
- :presence => true
221
- validates :license,
222
- :presence => true
223
- validates :module_architectures,
224
- dynamic_length: true
225
- validates :module_authors,
226
- :length => {
227
- :minimum => MINIMUM_MODULE_AUTHORS_LENGTH
228
- }
229
- validates :module_class,
230
- :presence => true
231
- validates :module_platforms,
232
- dynamic_length: true
233
- validates :module_references,
234
- dynamic_length: true
235
- validates :name,
236
- :presence => true
237
- validates :privileged,
238
- :inclusion => {
239
- :in => PRIVILEGES
240
- }
241
- validates :stance,
242
- inclusion: {
243
- if: :stanced?,
244
- in: Metasploit::Model::Module::Stance::ALL
245
- },
246
- nil: {
247
- unless: :stanced?
248
- }
249
- validates :targets,
250
- dynamic_length: true
1
+ # Code shared between `Mdm::Module::Instance` and `Metasploit::Framework::Module::Instance`.
2
+ module Metasploit::Model::Module::Instance
3
+ extend ActiveModel::Naming
4
+ extend ActiveSupport::Autoload
5
+ extend ActiveSupport::Concern
6
+
7
+ include Metasploit::Model::Translation
8
+
9
+ autoload :Spec
10
+
11
+ #
12
+ # CONSTANTS
13
+ #
14
+
15
+ # {#dynamic_length_validation_options} by {#module_type} by attribute.
16
+ DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE = {
17
+ actions: {
18
+ Metasploit::Model::Module::Type::AUX => {
19
+ minimum: 0
20
+ },
21
+ Metasploit::Model::Module::Type::ENCODER => {
22
+ is: 0
23
+ },
24
+ Metasploit::Model::Module::Type::EXPLOIT => {
25
+ is: 0
26
+ },
27
+ Metasploit::Model::Module::Type::NOP => {
28
+ is: 0
29
+ },
30
+ Metasploit::Model::Module::Type::PAYLOAD => {
31
+ is: 0
32
+ },
33
+ Metasploit::Model::Module::Type::POST => {
34
+ minimum: 0
35
+ }
36
+ },
37
+ module_architectures: {
38
+ Metasploit::Model::Module::Type::AUX => {
39
+ is: 0
40
+ },
41
+ Metasploit::Model::Module::Type::ENCODER => {
42
+ minimum: 1
43
+ },
44
+ Metasploit::Model::Module::Type::EXPLOIT => {
45
+ minimum: 1
46
+ },
47
+ Metasploit::Model::Module::Type::NOP => {
48
+ minimum: 1
49
+ },
50
+ Metasploit::Model::Module::Type::PAYLOAD => {
51
+ minimum: 1
52
+ },
53
+ Metasploit::Model::Module::Type::POST => {
54
+ minimum: 1
55
+ }
56
+ },
57
+ module_platforms: {
58
+ Metasploit::Model::Module::Type::AUX => {
59
+ is: 0
60
+ },
61
+ Metasploit::Model::Module::Type::ENCODER => {
62
+ is: 0
63
+ },
64
+ Metasploit::Model::Module::Type::EXPLOIT => {
65
+ minimum: 1
66
+ },
67
+ Metasploit::Model::Module::Type::NOP => {
68
+ is: 0
69
+ },
70
+ Metasploit::Model::Module::Type::PAYLOAD => {
71
+ minimum: 1
72
+ },
73
+ Metasploit::Model::Module::Type::POST => {
74
+ minimum: 1
75
+ }
76
+ },
77
+ module_references: {
78
+ Metasploit::Model::Module::Type::AUX => {
79
+ minimum: 0
80
+ },
81
+ Metasploit::Model::Module::Type::ENCODER => {
82
+ is: 0
83
+ },
84
+ Metasploit::Model::Module::Type::EXPLOIT => {
85
+ minimum: 1
86
+ },
87
+ Metasploit::Model::Module::Type::NOP => {
88
+ is: 0
89
+ },
90
+ Metasploit::Model::Module::Type::PAYLOAD => {
91
+ is: 0
92
+ },
93
+ Metasploit::Model::Module::Type::POST => {
94
+ minimum: 0
95
+ }
96
+ },
97
+ targets: {
98
+ Metasploit::Model::Module::Type::AUX => {
99
+ is: 0
100
+ },
101
+ Metasploit::Model::Module::Type::ENCODER => {
102
+ is: 0
103
+ },
104
+ Metasploit::Model::Module::Type::EXPLOIT => {
105
+ minimum: 1
106
+ },
107
+ Metasploit::Model::Module::Type::NOP => {
108
+ is: 0
109
+ },
110
+ Metasploit::Model::Module::Type::PAYLOAD => {
111
+ is: 0
112
+ },
113
+ Metasploit::Model::Module::Type::POST => {
114
+ is: 0
115
+ }
116
+ }
117
+ }
118
+
119
+ # Minimum length of {#module_authors}.
120
+ MINIMUM_MODULE_AUTHORS_LENGTH = 1
121
+
122
+ # {#privileged} is Boolean so, valid values are just `true` and `false`, but since both the validation and
123
+ # factory need an array of valid values, this constant exists.
124
+ PRIVILEGES = [
125
+ false,
126
+ true
127
+ ]
128
+
129
+ # Member of {Metasploit::Model::Module::Type::ALL} that require {#stance} to be non-`nil`.
130
+ STANCED_MODULE_TYPES = [
131
+ Metasploit::Model::Module::Type::AUX,
132
+ Metasploit::Model::Module::Type::EXPLOIT
133
+ ]
134
+
135
+ included do
136
+ include ActiveModel::Validations
137
+ include Metasploit::Model::Search
138
+
139
+ #
140
+ #
141
+ # Search
142
+ #
143
+ #
144
+
145
+ #
146
+ # Search Associations
147
+ #
148
+
149
+ search_association :actions
150
+ search_association :architectures
151
+ search_association :authorities
152
+ search_association :authors
153
+ search_association :email_addresses
154
+ search_association :module_class
155
+ search_association :platforms
156
+ search_association :rank
157
+ search_association :references
158
+ search_association :targets
159
+
160
+ #
161
+ # Search Attributes
162
+ #
163
+
164
+ search_attribute :description, :type => :string
165
+ search_attribute :disclosed_on, :type => :date
166
+ search_attribute :license, :type => :string
167
+ search_attribute :name, :type => :string
168
+ search_attribute :privileged, :type => :boolean
169
+ search_attribute :stance, :type => :string
170
+
171
+ #
172
+ # Search Withs
173
+ #
174
+
175
+ search_with Metasploit::Model::Search::Operator::Deprecated::App
176
+ search_with Metasploit::Model::Search::Operator::Deprecated::Author
177
+ search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
178
+ :abbreviation => :bid
179
+ search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
180
+ :abbreviation => :cve
181
+ search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
182
+ :abbreviation => :edb
183
+ search_with Metasploit::Model::Search::Operator::Deprecated::Authority,
184
+ :abbreviation => :osvdb
185
+ search_with Metasploit::Model::Search::Operator::Deprecated::Platform,
186
+ :name => :os
187
+ search_with Metasploit::Model::Search::Operator::Deprecated::Platform,
188
+ :name => :platform
189
+ search_with Metasploit::Model::Search::Operator::Deprecated::Ref
190
+ search_with Metasploit::Model::Search::Operator::Deprecated::Text
191
+
192
+ #
193
+ #
194
+ # Validations
195
+ #
196
+ #
197
+
198
+ #
199
+ # Method Validations
200
+ #
201
+
202
+ validate :architectures_from_targets,
203
+ if: 'allows?(:targets)'
204
+ validate :platforms_from_targets,
205
+ if: 'allows?(:targets)'
206
+
207
+ #
208
+ # Attribute Validations
209
+ #
210
+
211
+ validates :actions,
212
+ dynamic_length: true
213
+ validates :description,
214
+ :presence => true
215
+ validates :license,
216
+ :presence => true
217
+ validates :module_architectures,
218
+ dynamic_length: true
219
+ validates :module_authors,
220
+ :length => {
221
+ :minimum => MINIMUM_MODULE_AUTHORS_LENGTH
222
+ }
223
+ validates :module_class,
224
+ :presence => true
225
+ validates :module_platforms,
226
+ dynamic_length: true
227
+ validates :module_references,
228
+ dynamic_length: true
229
+ validates :name,
230
+ :presence => true
231
+ validates :privileged,
232
+ :inclusion => {
233
+ :in => PRIVILEGES
234
+ }
235
+ validates :stance,
236
+ inclusion: {
237
+ if: :stanced?,
238
+ in: Metasploit::Model::Module::Stance::ALL
239
+ },
240
+ nil: {
241
+ unless: :stanced?
242
+ }
243
+ validates :targets,
244
+ dynamic_length: true
245
+ end
246
+
247
+ #
248
+ #
249
+ # Associations
250
+ #
251
+ #
252
+
253
+ # @!attribute [rw] actions
254
+ # Auxiliary actions to perform when this running this module.
255
+ #
256
+ # @return [Array<Metasploit::Model::Module::Action>]
257
+
258
+ # @!attribute [rw] default_action
259
+ # The default action in {#actions}.
260
+ #
261
+ # @return [Metasploit::Model::Module::Action]
262
+
263
+ # @!attribute [rw] default_target
264
+ # The default target in {#targets}.
265
+ #
266
+ # @return [Metasploit::Model::Module::Target]
267
+
268
+ # @!attribute [rw] module_architectures
269
+ # Joins this with {#architectures}.
270
+ #
271
+ # @return [Array<Metasploit::Model::Module::Architecture>]
272
+
273
+ # @!attribute [rw] module_authors
274
+ # Joins this with {#authors} and {#email_addresses} to model the name and email address used for an author
275
+ # entry in the module metadata.
276
+ #
277
+ # @return [Array<Metasploit::Model::Module::Author>]
278
+
279
+ # @!attribute [rw] module_class
280
+ # Class-derived metadata to go along with the instance-derived metadata in this model.
281
+ #
282
+ # @return [Metasploit::Model::Module::Class]
283
+
284
+ # @!attribute [rw] module_platforms
285
+ # Joins this with {#platforms}.
286
+ #
287
+ # @return [Array<Metasploit::Model::Module::Platform>]
288
+
289
+ # @!attribute [rw] targets
290
+ # Names of targets with different configurations that can be exploited by this module.
291
+ #
292
+ # @return [Array<Metasploit::Model::Module::Target>]
293
+
294
+ # @!attribute [r] architectures
295
+ # The {Metasploit::Model::Architecture architectures} supported by this module.
296
+ #
297
+ # @return [Array<Metasploit::Model::Architecture>]
298
+
299
+ # @!attribute [r] authors
300
+ # The names of the authors of this module.
301
+ #
302
+ # @return [Array<Metasploit::Model::Author>]
303
+
304
+ # @!attribute [r] email_addresses
305
+ # The email addresses of the authors of this module.
306
+ #
307
+ # @return [Array<Metasploit::Model::EmailAddress>]
308
+
309
+ # @!attribute [r] platforms
310
+ # Platforms supported by this module.
311
+ #
312
+ # @return [Array<Metasploit::Model::Module::Platform>]
313
+
314
+ # @!attribute [r] references
315
+ # External references to the exploit or proof-of-concept (PoC) code in this module.
316
+ #
317
+ # @return [Array<Metasploit::Model::Reference>]
318
+
319
+ # @!attribute [r] vulns
320
+ # Vulnerabilities with same {Metasploit::Model::Reference reference} as this module.
321
+ #
322
+ # @return [Array<Metasploit::Model::Vuln>]
323
+
324
+ # @!attribute [r] vulnerable_hosts
325
+ # Hosts vulnerable to this module.
326
+ #
327
+ # @return [Array<Metasploit::Model::Host>]
328
+
329
+ # @!attribute [r] vulnerable_services
330
+ # Services vulnerable to this module.
331
+ #
332
+ # @return [Array<Metasploit::Model::Service>]
333
+
334
+ #
335
+ # Attributes
336
+ #
337
+
338
+ # @!attribute [rw] description
339
+ # A long, paragraph description of what the module does.
340
+ #
341
+ # @return [String]
342
+
343
+ # @!attribute [rw] disclosed_on
344
+ # The date the vulnerability exploited by this module was disclosed to the public.
345
+ #
346
+ # @return [Date, nil]
347
+
348
+ # @!attribute [rw] license
349
+ # The name of the software license for the module's code.
350
+ #
351
+ # @return [String]
352
+
353
+ # @!attribute [rw] name
354
+ # The human readable name of the module. It is unrelated to {Metasploit::Model::Module::Class#full_name} or
355
+ # {Metasploit::Model::Module::Class#reference_name} and is better thought of as a short summary of the
356
+ # {#description}.
357
+ #
358
+ # @return [String]
359
+
360
+ # @!attribute [rw] privileged
361
+ # Whether this module requires privileged access to run.
362
+ #
363
+ # @return [Boolean]
364
+
365
+ # @!attribute [rw] stance
366
+ # Whether the module is active or passive. `nil` if the {#module_type} is not {#stanced?}.
367
+ #
368
+ # @return ['active', 'passive', nil]
369
+
370
+ #
371
+ # Module Methods
372
+ #
373
+
374
+ module ClassMethods
375
+ # Whether the given `:attribute` is allowed to be present for the given `:module_type`. An attribute is
376
+ # considered allowed if it allows greatrr than 0 elements for a collection.
377
+ #
378
+ # @raise [KeyError] if `:attribute` is not given in `options`.
379
+ # @raise [KeyError] if `:module_type` is not given in `options`.
380
+ # @return [true] if maximum elements is greater than 0 or value can be non-nil
381
+ def allows?(options={})
382
+ allowed = false
383
+ length_validation_options = dynamic_length_validation_options(options)
384
+
385
+ is = length_validation_options[:is]
386
+
387
+ if is
388
+ if is > 0
389
+ allowed = true
251
390
  end
391
+ else
392
+ maximum = length_validation_options[:maximum]
252
393
 
253
- #
254
- #
255
- # Associations
256
- #
257
- #
258
-
259
- # @!attribute [rw] actions
260
- # Auxiliary actions to perform when this running this module.
261
- #
262
- # @return [Array<Metasploit::Model::Module::Action>]
263
-
264
- # @!attribute [rw] default_action
265
- # The default action in {#actions}.
266
- #
267
- # @return [Metasploit::Model::Module::Action]
268
-
269
- # @!attribute [rw] default_target
270
- # The default target in {#targets}.
271
- #
272
- # @return [Metasploit::Model::Module::Target]
273
-
274
- # @!attribute [rw] module_architectures
275
- # Joins this with {#architectures}.
276
- #
277
- # @return [Array<Metasploit::Model::Module::Architecture>]
278
-
279
- # @!attribute [rw] module_authors
280
- # Joins this with {#authors} and {#email_addresses} to model the name and email address used for an author
281
- # entry in the module metadata.
282
- #
283
- # @return [Array<Metasploit::Model::Module::Author>]
284
-
285
- # @!attribute [rw] module_class
286
- # Class-derived metadata to go along with the instance-derived metadata in this model.
287
- #
288
- # @return [Metasploit::Model::Module::Class]
289
-
290
- # @!attribute [rw] module_platforms
291
- # Joins this with {#platforms}.
292
- #
293
- # @return [Array<Metasploit::Model::Module::Platform>]
294
-
295
- # @!attribute [rw] targets
296
- # Names of targets with different configurations that can be exploited by this module.
297
- #
298
- # @return [Array<Metasploit::Model::Module::Target>]
299
-
300
- # @!attribute [r] architectures
301
- # The {Metasploit::Model::Architecture architectures} supported by this module.
302
- #
303
- # @return [Array<Metasploit::Model::Architecture>]
304
-
305
- # @!attribute [r] authors
306
- # The names of the authors of this module.
307
- #
308
- # @return [Array<Metasploit::Model::Author>]
309
-
310
- # @!attribute [r] email_addresses
311
- # The email addresses of the authors of this module.
312
- #
313
- # @return [Array<Metasploit::Model::EmailAddress>]
314
-
315
- # @!attribute [r] platforms
316
- # Platforms supported by this module.
317
- #
318
- # @return [Array<Metasploit::Model::Module::Platform>]
319
-
320
- # @!attribute [r] references
321
- # External references to the exploit or proof-of-concept (PoC) code in this module.
322
- #
323
- # @return [Array<Metasploit::Model::Reference>]
324
-
325
- # @!attribute [r] vulns
326
- # Vulnerabilities with same {Metasploit::Model::Reference reference} as this module.
327
- #
328
- # @return [Array<Metasploit::Model::Vuln>]
329
-
330
- # @!attribute [r] vulnerable_hosts
331
- # Hosts vulnerable to this module.
332
- #
333
- # @return [Array<Metasploit::Model::Host>]
334
-
335
- # @!attribute [r] vulnerable_services
336
- # Services vulnerable to this module.
337
- #
338
- # @return [Array<Metasploit::Model::Service>]
339
-
340
- #
341
- # Attributes
342
- #
343
-
344
- # @!attribute [rw] description
345
- # A long, paragraph description of what the module does.
346
- #
347
- # @return [String]
348
-
349
- # @!attribute [rw] disclosed_on
350
- # The date the vulnerability exploited by this module was disclosed to the public.
351
- #
352
- # @return [Date, nil]
353
-
354
- # @!attribute [rw] license
355
- # The name of the software license for the module's code.
356
- #
357
- # @return [String]
358
-
359
- # @!attribute [rw] name
360
- # The human readable name of the module. It is unrelated to {Metasploit::Model::Module::Class#full_name} or
361
- # {Metasploit::Model::Module::Class#reference_name} and is better thought of as a short summary of the
362
- # {#description}.
363
- #
364
- # @return [String]
365
-
366
- # @!attribute [rw] privileged
367
- # Whether this module requires privileged access to run.
368
- #
369
- # @return [Boolean]
370
-
371
- # @!attribute [rw] stance
372
- # Whether the module is active or passive. `nil` if the {#module_type} is not {#stanced?}.
373
- #
374
- # @return ['active', 'passive', nil]
375
-
376
- #
377
- # Module Methods
378
- #
379
-
380
- module ClassMethods
381
- # Whether the given `:attribute` is allowed to be present for the given `:module_type`. An attribute is
382
- # considered allowed if it allows greatrr than 0 elements for a collection.
383
- #
384
- # @raise [KeyError] if `:attribute` is not given in `options`.
385
- # @raise [KeyError] if `:module_type` is not given in `options`.
386
- # @return [true] if maximum elements is greater than 0 or value can be non-nil
387
- def allows?(options={})
388
- allowed = false
389
- length_validation_options = dynamic_length_validation_options(options)
390
-
391
- is = length_validation_options[:is]
392
-
393
- if is
394
- if is > 0
395
- allowed = true
396
- end
397
- else
398
- maximum = length_validation_options[:maximum]
399
-
400
- if maximum
401
- if maximum > 0
402
- allowed = true
403
- end
404
- else
405
- # if there is no maximum, then it's treated as infinite
406
- allowed = true
407
- end
408
- end
409
-
410
- allowed
394
+ if maximum
395
+ if maximum > 0
396
+ allowed = true
411
397
  end
398
+ else
399
+ # if there is no maximum, then it's treated as infinite
400
+ allowed = true
401
+ end
402
+ end
412
403
 
413
- # The length validation options for the given `:attribute` and `:module_type`.
414
- # @return [Hash{Symbol => Integer}] Hash containing either `:is` (meaning :maximum and :minimum are the same) or
415
- # `:minimum` (no attribute has an explicit :maximum currently).
416
- # @raise [KeyError] if `:attribute` is not given in `options`.
417
- # @raise [KeyError] if `:module_type` is not given in `options`.
418
- # @raise [KeyError] if `:attribute` value is not a key in
419
- # {DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE}.
420
- # @raise [KeyError] if `:module_type` value is a not a {Metasploit::Model::Module::Type::ALL} member.
421
- def dynamic_length_validation_options(options={})
422
- options.assert_valid_keys(:attribute, :module_type)
423
- attribute = options.fetch(:attribute)
424
- module_type = options.fetch(:module_type)
425
-
426
- dynamic_length_validation_options_by_module_type = DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE.fetch(attribute)
427
- dynamic_length_validation_options_by_module_type.fetch(module_type)
428
- end
404
+ allowed
405
+ end
429
406
 
430
- # Whether the `:module_type` requires stance to be in {Metasploit::Model::Module::Stance::ALL} or if it must
431
- # be `nil`.
432
- #
433
- # @param module_type [String] A member of `Metasploit::Model::Module::Type::ALL`.
434
- # @return [true] if `module_type` is in {STANCED_MODULE_TYPES}.
435
- # @return [false] otherwise.
436
- def stanced?(module_type)
437
- STANCED_MODULE_TYPES.include? module_type
438
- end
439
- end
407
+ # The length validation options for the given `:attribute` and `:module_type`.
408
+ # @return [Hash{Symbol => Integer}] Hash containing either `:is` (meaning :maximum and :minimum are the same) or
409
+ # `:minimum` (no attribute has an explicit :maximum currently).
410
+ # @raise [KeyError] if `:attribute` is not given in `options`.
411
+ # @raise [KeyError] if `:module_type` is not given in `options`.
412
+ # @raise [KeyError] if `:attribute` value is not a key in
413
+ # {DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE}.
414
+ # @raise [KeyError] if `:module_type` value is a not a {Metasploit::Model::Module::Type::ALL} member.
415
+ def dynamic_length_validation_options(options={})
416
+ options.assert_valid_keys(:attribute, :module_type)
417
+ attribute = options.fetch(:attribute)
418
+ module_type = options.fetch(:module_type)
419
+
420
+ dynamic_length_validation_options_by_module_type = DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE.fetch(attribute)
421
+ dynamic_length_validation_options_by_module_type.fetch(module_type)
422
+ end
440
423
 
441
- # make ClassMethods directly callable on Metasploit::Model::Module::Instance for factories
442
- extend ClassMethods
443
-
444
- #
445
- # Module Methods
446
- #
447
-
448
- # Values of {#module_type} (members of {Metasploit::Model::Module::Type::ALL}), which have an exact length
449
- # (`:is`) or maximum length (`:maximum`) greater than 0 for the given `attribute`.
450
- #
451
- # @return [Array<String>] Array with members of {Metasploit::Model::Module::Type::ALL}.
452
- # @see DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE
453
- def self.module_types_that_allow(attribute)
454
- dynamic_length_validation_options_by_module_type = DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE.fetch(attribute)
455
-
456
- dynamic_length_validation_options_by_module_type.each_with_object([]) { |(module_type, dynamic_length_validation_options), module_types|
457
- is = dynamic_length_validation_options[:is]
458
-
459
- if is
460
- if is > 0
461
- module_types << module_type
462
- end
463
- else
464
- maximum = dynamic_length_validation_options[:maximum]
465
-
466
- if maximum
467
- if maximum > 0
468
- module_types << module_type
469
- end
470
- else
471
- module_types << module_type
472
- end
473
- end
424
+ # Whether the `:module_type` requires stance to be in {Metasploit::Model::Module::Stance::ALL} or if it must
425
+ # be `nil`.
426
+ #
427
+ # @param module_type [String] A member of `Metasploit::Model::Module::Type::ALL`.
428
+ # @return [true] if `module_type` is in {STANCED_MODULE_TYPES}.
429
+ # @return [false] otherwise.
430
+ def stanced?(module_type)
431
+ STANCED_MODULE_TYPES.include? module_type
432
+ end
433
+ end
474
434
 
475
- }
476
- end
435
+ # make ClassMethods directly callable on Metasploit::Model::Module::Instance for factories
436
+ extend ClassMethods
477
437
 
478
- #
479
- # Instance Methods
480
- #
481
-
482
- # Whether the given `attribute` is allowed to have elements.
483
- #
484
- # @param attribute [Symbol] name of attribute to check if {#module_type} allows it to have one or more
485
- # elements.
486
- # @return (see Metasploit::Model::Module::Instance::ClassMethods#allows?)
487
- # @return [false] if {#module_type} is not valid
488
- def allows?(attribute)
489
- if Metasploit::Model::Module::Type::ALL.include? module_type
490
- self.class.allows?(
491
- attribute: attribute,
492
- module_type: module_type
493
- )
494
- else
495
- false
496
- end
438
+ #
439
+ # Module Methods
440
+ #
441
+
442
+ # Values of {#module_type} (members of {Metasploit::Model::Module::Type::ALL}), which have an exact length
443
+ # (`:is`) or maximum length (`:maximum`) greater than 0 for the given `attribute`.
444
+ #
445
+ # @return [Array<String>] Array with members of {Metasploit::Model::Module::Type::ALL}.
446
+ # @see DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE
447
+ def self.module_types_that_allow(attribute)
448
+ dynamic_length_validation_options_by_module_type = DYNAMIC_LENGTH_VALIDATION_OPTIONS_BY_MODULE_TYPE_BY_ATTRIBUTE.fetch(attribute)
449
+
450
+ dynamic_length_validation_options_by_module_type.each_with_object([]) { |(module_type, dynamic_length_validation_options), module_types|
451
+ is = dynamic_length_validation_options[:is]
452
+
453
+ if is
454
+ if is > 0
455
+ module_types << module_type
497
456
  end
457
+ else
458
+ maximum = dynamic_length_validation_options[:maximum]
498
459
 
499
- # The dynamic length valdiations, such as `:is` and `:minimum` for the given attribute for the current
500
- # {#module_type}.
501
- #
502
- # @param attribute [Symbol] name of attribute whose dynamic length validation options to be
503
- # @return (see Metasploit::Model::Module::Instance::ClassMethods#dynamic_length_validation_options)
504
- # @return [{}] an empty Hash if {#module_type} is not a member of {Metasploit::Model::Module::Type::ALL}
505
- def dynamic_length_validation_options(attribute)
506
- if Metasploit::Model::Module::Type::ALL.include? module_type
507
- self.class.dynamic_length_validation_options(
508
- module_type: module_type,
509
- attribute: attribute
510
- )
511
- else
512
- {}
460
+ if maximum
461
+ if maximum > 0
462
+ module_types << module_type
513
463
  end
464
+ else
465
+ module_types << module_type
514
466
  end
467
+ end
515
468
 
516
- # @!method module_type
517
- # The {Metasploit::Model::Module::Class#module_type} of the {#module_class}.
518
- #
519
- # @return (see Metasploit;:Model::Module::Class#module_type)
520
- delegate :module_type,
521
- allow_nil: true,
522
- to: :module_class
523
-
524
- # Whether {#module_type} requires {#stance} to be set or to be `nil`.
525
- #
526
- # @return (see Metasploit::Model::Module::Instance::ClassMethods#stanced?)
527
- # @return [false] if {#module_type} is not valid
528
- def stanced?
529
- self.class.stanced?(module_type)
530
- end
469
+ }
470
+ end
531
471
 
532
- private
533
-
534
- # Validates that the {#module_architectures}
535
- # {Metasploit::Model::Module::Architecture#architecture architectures} match the {#targets}
536
- # {Metasploit::Model::Module::Target#target_architectures target_architectures}
537
- # {Metasploit::Model::Module::Target::Architecture#architecture architectures}.
538
- #
539
- # @return [void]
540
- def architectures_from_targets
541
- actual_architecture_set = Set.new module_architectures.map(&:architecture)
542
- expected_architecture_set = Set.new
543
-
544
- targets.each do |module_target|
545
- module_target.target_architectures.each do |target_architecture|
546
- expected_architecture_set.add target_architecture.architecture
547
- end
548
- end
472
+ #
473
+ # Instance Methods
474
+ #
475
+
476
+ # Whether the given `attribute` is allowed to have elements.
477
+ #
478
+ # @param attribute [Symbol] name of attribute to check if {#module_type} allows it to have one or more
479
+ # elements.
480
+ # @return (see Metasploit::Model::Module::Instance::ClassMethods#allows?)
481
+ # @return [false] if {#module_type} is not valid
482
+ def allows?(attribute)
483
+ if Metasploit::Model::Module::Type::ALL.include? module_type
484
+ self.class.allows?(
485
+ attribute: attribute,
486
+ module_type: module_type
487
+ )
488
+ else
489
+ false
490
+ end
491
+ end
549
492
 
550
- extra_architecture_set = actual_architecture_set - expected_architecture_set
493
+ # The dynamic length valdiations, such as `:is` and `:minimum` for the given attribute for the current
494
+ # {#module_type}.
495
+ #
496
+ # @param attribute [Symbol] name of attribute whose dynamic length validation options to be
497
+ # @return (see Metasploit::Model::Module::Instance::ClassMethods#dynamic_length_validation_options)
498
+ # @return [{}] an empty Hash if {#module_type} is not a member of {Metasploit::Model::Module::Type::ALL}
499
+ def dynamic_length_validation_options(attribute)
500
+ if Metasploit::Model::Module::Type::ALL.include? module_type
501
+ self.class.dynamic_length_validation_options(
502
+ module_type: module_type,
503
+ attribute: attribute
504
+ )
505
+ else
506
+ {}
507
+ end
508
+ end
551
509
 
552
- unless extra_architecture_set.empty?
553
- human_extra_architectures = human_architecture_set(extra_architecture_set)
510
+ # @!method module_type
511
+ # The {Metasploit::Model::Module::Class#module_type} of the {#module_class}.
512
+ #
513
+ # @return (see Metasploit;:Model::Module::Class#module_type)
514
+ delegate :module_type,
515
+ allow_nil: true,
516
+ to: :module_class
517
+
518
+ # Whether {#module_type} requires {#stance} to be set or to be `nil`.
519
+ #
520
+ # @return (see Metasploit::Model::Module::Instance::ClassMethods#stanced?)
521
+ # @return [false] if {#module_type} is not valid
522
+ def stanced?
523
+ self.class.stanced?(module_type)
524
+ end
554
525
 
555
- errors.add(:architectures, :extra, extra: human_extra_architectures)
556
- end
526
+ private
527
+
528
+ # Validates that the {#module_architectures}
529
+ # {Metasploit::Model::Module::Architecture#architecture architectures} match the {#targets}
530
+ # {Metasploit::Model::Module::Target#target_architectures target_architectures}
531
+ # {Metasploit::Model::Module::Target::Architecture#architecture architectures}.
532
+ #
533
+ # @return [void]
534
+ def architectures_from_targets
535
+ actual_architecture_set = Set.new module_architectures.map(&:architecture)
536
+ expected_architecture_set = Set.new
537
+
538
+ targets.each do |module_target|
539
+ module_target.target_architectures.each do |target_architecture|
540
+ expected_architecture_set.add target_architecture.architecture
541
+ end
542
+ end
557
543
 
558
- missing_architecture_set = expected_architecture_set - actual_architecture_set
544
+ extra_architecture_set = actual_architecture_set - expected_architecture_set
559
545
 
560
- unless missing_architecture_set.empty?
561
- human_missing_architectures = human_architecture_set(missing_architecture_set)
546
+ unless extra_architecture_set.empty?
547
+ human_extra_architectures = human_architecture_set(extra_architecture_set)
562
548
 
563
- errors.add(:architectures, :missing, missing: human_missing_architectures)
564
- end
565
- end
549
+ errors.add(:architectures, :extra, extra: human_extra_architectures)
550
+ end
566
551
 
567
- # Converts a Set<Metasploit::Model::Architecture> to a human readable representation including the
568
- # {Metasploit::Model::Architecture#abbreviation}.
569
- #
570
- # @return [String]
571
- def human_architecture_set(architecture_set)
572
- abbreviations = architecture_set.map(&:abbreviation)
552
+ missing_architecture_set = expected_architecture_set - actual_architecture_set
573
553
 
574
- human_set(abbreviations)
575
- end
554
+ unless missing_architecture_set.empty?
555
+ human_missing_architectures = human_architecture_set(missing_architecture_set)
576
556
 
577
- # Converts a Set<Metasploit::Model::Platform> to a human-readable representation including the
578
- # {Metasploit::Model::Platform#fully_qualified_name}.
579
- #
580
- # @return [String]
581
- def human_platform_set(platform_set)
582
- fully_qualified_names = platform_set.map(&:fully_qualified_name)
557
+ errors.add(:architectures, :missing, missing: human_missing_architectures)
558
+ end
559
+ end
583
560
 
584
- human_set(fully_qualified_names)
585
- end
561
+ # Converts a Set<Metasploit::Model::Architecture> to a human readable representation including the
562
+ # {Metasploit::Model::Architecture#abbreviation}.
563
+ #
564
+ # @return [String]
565
+ def human_architecture_set(architecture_set)
566
+ abbreviations = architecture_set.map(&:abbreviation)
586
567
 
587
- # Converts strings to a human-readable set notation.
588
- #
589
- # @return [String]
590
- def human_set(strings)
591
- sorted = strings.sort
592
- comma_separated = sorted.join(', ')
568
+ human_set(abbreviations)
569
+ end
593
570
 
594
- "{#{comma_separated}}"
595
- end
571
+ # Converts a Set<Metasploit::Model::Platform> to a human-readable representation including the
572
+ # {Metasploit::Model::Platform#fully_qualified_name}.
573
+ #
574
+ # @return [String]
575
+ def human_platform_set(platform_set)
576
+ fully_qualified_names = platform_set.map(&:fully_qualified_name)
596
577
 
597
- # Validates that {#module_platforms} {Metasploit::Model::Module::Platform#platform platforms} match the
598
- # {#targets} {Metasploit::Model::Module::Target#target_platforms target_platforms}
599
- # {Metasploit::Model::Module::Target::Platform#platform platforms}.
600
- #
601
- # @return [void]
602
- def platforms_from_targets
603
- actual_platform_set = Set.new module_platforms.map(&:platform)
604
- expected_platform_set = Set.new
605
-
606
- targets.each do |module_target|
607
- module_target.target_platforms.each do |target_platform|
608
- expected_platform_set.add target_platform.platform
609
- end
610
- end
578
+ human_set(fully_qualified_names)
579
+ end
611
580
 
612
- extra_platform_set = actual_platform_set - expected_platform_set
581
+ # Converts strings to a human-readable set notation.
582
+ #
583
+ # @return [String]
584
+ def human_set(strings)
585
+ sorted = strings.sort
586
+ comma_separated = sorted.join(', ')
613
587
 
614
- unless extra_platform_set.empty?
615
- human_extra_platforms = human_platform_set(extra_platform_set)
588
+ "{#{comma_separated}}"
589
+ end
616
590
 
617
- errors.add(:platforms, :extra, extra: human_extra_platforms)
618
- end
591
+ # Validates that {#module_platforms} {Metasploit::Model::Module::Platform#platform platforms} match the
592
+ # {#targets} {Metasploit::Model::Module::Target#target_platforms target_platforms}
593
+ # {Metasploit::Model::Module::Target::Platform#platform platforms}.
594
+ #
595
+ # @return [void]
596
+ def platforms_from_targets
597
+ actual_platform_set = Set.new module_platforms.map(&:platform)
598
+ expected_platform_set = Set.new
599
+
600
+ targets.each do |module_target|
601
+ module_target.target_platforms.each do |target_platform|
602
+ expected_platform_set.add target_platform.platform
603
+ end
604
+ end
619
605
 
620
- missing_platform_set = expected_platform_set - actual_platform_set
606
+ extra_platform_set = actual_platform_set - expected_platform_set
621
607
 
622
- unless missing_platform_set.empty?
623
- human_missing_platforms = human_platform_set(missing_platform_set)
608
+ unless extra_platform_set.empty?
609
+ human_extra_platforms = human_platform_set(extra_platform_set)
624
610
 
625
- errors.add(:platforms, :missing, missing: human_missing_platforms)
626
- end
627
- end
628
- end
611
+ errors.add(:platforms, :extra, extra: human_extra_platforms)
612
+ end
613
+
614
+ missing_platform_set = expected_platform_set - actual_platform_set
615
+
616
+ unless missing_platform_set.empty?
617
+ human_missing_platforms = human_platform_set(missing_platform_set)
618
+
619
+ errors.add(:platforms, :missing, missing: human_missing_platforms)
629
620
  end
630
621
  end
631
622
  end
632
-