metasploit_data_models 0.17.3 → 0.18.0.pre.compatibility

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 (36) hide show
  1. checksums.yaml +8 -8
  2. data/CONTRIBUTING.md +164 -0
  3. data/README.md +6 -2
  4. data/app/models/mdm/host.rb +18 -0
  5. data/app/models/mdm/service.rb +12 -1
  6. data/app/models/metasploit_data_models/search/operation/port/number.rb +25 -0
  7. data/app/models/metasploit_data_models/search/operation/port/range.rb +79 -0
  8. data/app/models/metasploit_data_models/search/operation/range.rb +56 -0
  9. data/app/models/metasploit_data_models/search/operator/multitext.rb +73 -0
  10. data/app/models/metasploit_data_models/search/operator/port/list.rb +67 -0
  11. data/app/models/metasploit_data_models/search/visitor/attribute.rb +2 -1
  12. data/app/models/metasploit_data_models/search/visitor/includes.rb +3 -2
  13. data/app/models/metasploit_data_models/search/visitor/joins.rb +5 -3
  14. data/app/models/metasploit_data_models/search/visitor/method.rb +3 -2
  15. data/app/models/metasploit_data_models/search/visitor/where.rb +8 -2
  16. data/config/locales/en.yml +17 -1
  17. data/lib/metasploit_data_models.rb +1 -9
  18. data/lib/metasploit_data_models/version.rb +29 -6
  19. data/metasploit_data_models.gemspec +2 -2
  20. data/spec/app/models/metasploit_data_models/search/operation/port/number_spec.rb +41 -0
  21. data/spec/app/models/metasploit_data_models/search/operation/port/range_spec.rb +140 -0
  22. data/spec/app/models/metasploit_data_models/search/operation/range_spec.rb +235 -0
  23. data/spec/app/models/metasploit_data_models/search/operator/multitext_spec.rb +162 -0
  24. data/spec/app/models/metasploit_data_models/search/operator/port/list_spec.rb +164 -0
  25. data/spec/app/models/metasploit_data_models/search/visitor/attribute_spec.rb +48 -26
  26. data/spec/app/models/metasploit_data_models/search/visitor/includes_spec.rb +10 -7
  27. data/spec/app/models/metasploit_data_models/search/visitor/joins_spec.rb +44 -30
  28. data/spec/app/models/metasploit_data_models/search/visitor/method_spec.rb +16 -0
  29. data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +273 -65
  30. data/spec/app/models/metasploit_data_models/search/visitor/where_spec.rb +42 -2
  31. data/spec/factories/mdm/services.rb +1 -2
  32. data/spec/lib/metasploit_data_models/version_spec.rb +141 -0
  33. data/spec/support/shared/examples/metasploit_data_models/search/visitor/where/visit/with_metasploit_model_search_group_base.rb +1 -1
  34. metadata +27 -11
  35. data/lib/metasploit_data_models/models.rb +0 -21
  36. data/lib/metasploit_data_models/validators.rb +0 -19
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MzNkMmMwMGZkMTQ0NzU2ODE5NWRjMjdjMDM3MTRhNGYxMWFkNjdiMQ==
4
+ YzFjM2E3OTA2OGRhM2RiYTgxZTBiMTViYWU3ODBlOTRlMzFkYmUxNg==
5
5
  data.tar.gz: !binary |-
6
- MmZkYmE1ODdiYWY2ZTRlYzkxNWUyNWJmOGU5MjMyMWEwMzFjNDcxNg==
6
+ ZjIyNmQwMGJlODQxMjA1Njg3YWQyZmY4NWI5NGIzOTNhYTI5ZDI0NA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OWM0NDdmZTQ2OTdiOWI2YjQ5OGFmOThlYzE2M2FhZWEwYjQ1MzU1OTI1N2Rm
10
- NmE3OTViMWY0YTg2YmNkMzAyYmJjZDY1MDM1MzI1MjNmMWE1N2JkNzZmMTE0
11
- N2RjMTdjYWNkYzI3ODhlOTU0Mzg0NWYyY2YxMzg4ODNjMmI0NzU=
9
+ NWI5MjUyNTVkZGNkMjM5MmZjNjU2ZWYxMGRjZTUzOGFlMTMwZjA4ZGI2Mzlk
10
+ OWMxMTc4OThlYmYwNzM0MmM2OTMzY2FlNDY0ODdjMWUwMjhiNTY1M2U4ZGM0
11
+ ZDY5ZWU2Y2FiNmMxNzQ4ODJmZjcwYmMxZDhmZjAwZmU0NTkyMGI=
12
12
  data.tar.gz: !binary |-
13
- MDc5NDJjYTFkMTdjNTkzOGZhMGM1NjE2YWU0NTA2YTM3Yjg5ZjNkNWRkY2Ri
14
- NTIwMmRmNDdiMTg3MzMyYTI5MGJlODliYjFmZTFhZTEyZDc4OWVlZjIwNmQ0
15
- YjM2ZmVlYzQwNzhlZmUzNDBkMjA4MzA3NmEwMjBhMDk2MGY3MTI=
13
+ NWFmZWFhMTc2NDMyYTQ5YzE3YzRhMWJjMjM4N2MyNDViNmJlMmU2OTJkYTM4
14
+ NWQ2YjYxOWUwMDBkNjgwZTE1YTY0YmU2ZGVmMGE2NWZkZmMzODkwNTAwOGVl
15
+ MjQwZGQxNTBlOWM2NWIzZDlkZGRhN2RkMzA5NDc0NWM0MmMwYWE=
@@ -0,0 +1,164 @@
1
+ # Contributing
2
+
3
+ ## Forking
4
+
5
+ [Fork this repository](https://github.com/rapid7/metasploit_data_models/fork)
6
+
7
+ ## Branching
8
+
9
+ Branch names follow the format `TYPE/ISSUE/SUMMARY`. You can create it with `git checkout -b TYPE/ISSUE/SUMMARY`.
10
+
11
+ ### `TYPE`
12
+
13
+ `TYPE` can be `bug`, `chore`, or `feature`.
14
+
15
+ ### `ISSUE`
16
+
17
+ `ISSUE` is either a [Github issue](https://github.com/rapid7/metasploit_data_models/issues) or an issue from some other
18
+ issue tracking software.
19
+
20
+ ### `SUMMARY`
21
+
22
+ `SUMMARY` is is short summary of the purpose of the branch composed of lower case words separated by '-' so that it is a valid `PRERELEASE` for the Gem version.
23
+
24
+ ## Changes
25
+
26
+ ### `PRERELEASE`
27
+
28
+ 1. Update `PRERELEASE` to match the `SUMMARY` in the branch name. If you branched from `master`, and [version.rb](lib/metasploit_data_models/version.rb) does not have `PRERELEASE` defined, then adding the following lines after `PATCH`:
29
+ ```
30
+ # The prerelease version, scoped to the {PATCH} version number.
31
+ PRERELEASE = '<SUMMARY>'
32
+ ```
33
+ 2. `rake spec`
34
+ 3. Verify the specs pass, which indicates that `PRERELEASE` was updated correctly.
35
+ 4. Commit the change `git commit -a`
36
+
37
+
38
+ ### Your changes
39
+
40
+ Make your changes or however many commits you like, commiting each with `git commit`.
41
+
42
+ ### Pre-Pull Request Testing
43
+
44
+ 1. Run specs one last time before opening the Pull Request: `rake spec`
45
+ 2. Verify there was no failures.
46
+
47
+ ### Push
48
+
49
+ Push your branch to your fork on gitub: `git push push TYPE/ISSUE/SUMMARY`
50
+
51
+ ### Pull Request
52
+
53
+ * [Create new Pull Request](https://github.com/rapid7/metasploit_data_models/compare/)
54
+ * Add a Verification Steps comment
55
+
56
+ ```
57
+ # Verification Steps
58
+
59
+ - [ ] `bundle install`
60
+
61
+ ## `rake spec`
62
+ - [ ] `rake spec`
63
+ - [ ] VERIFY no failures
64
+ ```
65
+ You should also include at least one scenario to manually check the changes outside of specs.
66
+
67
+ * Add a Post-merge Steps comment
68
+
69
+ The 'Post-merge Steps' are a reminder to the reviewer of the Pull Request of how to update the [`PRERELEASE`](lib/metasploit_data_models/version.rb) so that [version_spec.rb](spec/lib/metasploit_data_models/version_spec.rb) passes on the target branch after the merge.
70
+
71
+ DESTINATION is the name of the destination branch into which the merge is being made. SOURCE_SUMMARY is the SUMMARY from TYPE/ISSUE/SUMMARY branch name for the SOURCE branch that is being made.
72
+
73
+ When merging to `master`:
74
+
75
+ ```
76
+ # Post-merge Steps
77
+
78
+ Perform these steps prior to pushing to master or the build will be broke on master.
79
+
80
+ ## Version
81
+ - [ ] Edit `lib/metasploit_data_models/version.rb`
82
+ - [ ] Remove `PRERELEASE` and its comment as `PRERELEASE` is not defined on master.
83
+
84
+ ## Gem build
85
+ - [ ] gem build *.gemspec
86
+ - [ ] VERIFY the gem has no '.pre' version suffix.
87
+
88
+ ## RSpec
89
+ - [ ] `rake spec`
90
+ - [ ] VERIFY version examples pass without failures
91
+
92
+ ## Commit & Push
93
+ - [ ] `git commit -a`
94
+ - [ ] `git push origin master`
95
+ ```
96
+
97
+ When merging to DESTINATION other than `master`:
98
+
99
+ ```
100
+ # Post-merge Steps
101
+
102
+ Perform these steps prior to pushing to DESTINATION or the build will be broke on DESTINATION.
103
+
104
+ ## Version
105
+ - [ ] Edit `lib/metasploit_data_models/version.rb`
106
+ - [ ] Change `PRERELEASE` from `SOURCE_SUMMARY` to `DESTINATION_SUMMARY` to match the branch (DESTINATION) summary (DESTINATION_SUMMARY)
107
+
108
+ ## Gem build
109
+ - [ ] gem build *.gemspec
110
+ - [ ] VERIFY the prerelease suffix has change on the gem.
111
+
112
+ ## RSpec
113
+ - [ ] `rake spec`
114
+ - [ ] VERIFY version examples pass without failures
115
+
116
+ ## Commit & Push
117
+ - [ ] `git commit -a`
118
+ - [ ] `git push origin DESTINATION`
119
+ ```
120
+
121
+ * Add a 'Release Steps' comment
122
+
123
+ The 'Release Steps' are a reminder to the reviewer of the Pull Request of how to release the gem.
124
+
125
+ ```
126
+ # Release
127
+
128
+ Complete these steps on DESTINATION
129
+
130
+ ## Version
131
+
132
+ ### Compatible changes
133
+
134
+ If the change are compatible with the previous branch's API, then increment [`PATCH`](lib/metasploit_data_models/version.rb).
135
+
136
+ ### Incompatible changes
137
+
138
+ If your changes are incompatible with the previous branch's API, then increment
139
+ [`MINOR`](lib/metasploit_data_models/version.rb) and reset [`PATCH`](lib/metasploit_data_models/version.rb) to `0`.
140
+
141
+ - [ ] Following the rules for [semantic versioning 2.0](http://semver.org/spec/v2.0.0.html), update
142
+ [`MINOR`](lib/metasploit_data_models/version.rb) and [`PATCH`](lib/metasploit_data_models/version.rb) and commit the changes.
143
+
144
+ ## JRuby
145
+ - [ ] `rvm use jruby@metasploit_data_models`
146
+ - [ ] `rm Gemfile.lock`
147
+ - [ ] `bundle install`
148
+ - [ ] `rake release`
149
+
150
+ ## MRI Ruby
151
+ - [ ] `rvm use ruby-1.9.3@metasploit_data_models`
152
+ - [ ] `rm Gemfile.lock`
153
+ - [ ] `bundle install`
154
+ - [ ] `rake release`
155
+ ```
156
+
157
+ ### Downstream dependencies
158
+
159
+ When releasing new versions, the following projects may need to be updated:
160
+
161
+ * [metasploit-credential](https://github.com/rapid7/metasploit-credential)
162
+ * [metasploit-framework](https://github.com/rapid7/metasploit-framework)
163
+ * [metasploit-pro-ui](https://github.com/rapid7/pro/tree/master/ui)
164
+ * [metasploit-pro-engine](https://github.com/rapid7/pro/tree/master/engine)
data/README.md CHANGED
@@ -40,8 +40,8 @@ different on_load name, which is just the class name converted to an underscored
40
40
 
41
41
  ### Metasploit Framework
42
42
 
43
- In Metasploit Framework, `MetasploitDataModels.require_models` is called by the `Msf::DbManager` to use the data models
44
- only if the user wants to use the database.
43
+ In Metasploit Framework, `MetasploitDataModels::Engine` is loaded, but the data models are only if the user wants to use
44
+ the database.
45
45
 
46
46
  ### Elsewhere
47
47
 
@@ -58,3 +58,7 @@ Give it a path to a working MSF database.yml file for full
58
58
  ActiveRecord-based access to your data.
59
59
 
60
60
  __Note:__ "development" mode is hardcoded into the console currently.
61
+
62
+ ## Contributing
63
+
64
+ See [CONTRIBUTING.md](CONTRIBUTING.md)
@@ -481,6 +481,24 @@ class Mdm::Host < ActiveRecord::Base
481
481
 
482
482
  search_attribute :name,
483
483
  type: :string
484
+ search_attribute :os_flavor,
485
+ type: :string
486
+ search_attribute :os_name,
487
+ type: :string
488
+ search_attribute :os_sp,
489
+ type: :string
490
+
491
+ #
492
+ # Search Withs
493
+ #
494
+
495
+ search_with MetasploitDataModels::Search::Operator::Multitext,
496
+ name: :os,
497
+ operator_names: [
498
+ :os_name,
499
+ :os_flavor,
500
+ :os_sp
501
+ ]
484
502
 
485
503
  #
486
504
  # Instance Methods
@@ -176,6 +176,12 @@ class Mdm::Service < ActiveRecord::Base
176
176
  ])
177
177
  }
178
178
 
179
+ #
180
+ #
181
+ # Search
182
+ #
183
+ #
184
+
179
185
  #
180
186
  # Search Attributes
181
187
  #
@@ -183,6 +189,12 @@ class Mdm::Service < ActiveRecord::Base
183
189
  search_attribute :name,
184
190
  type: :string
185
191
 
192
+ #
193
+ # Search Withs
194
+ #
195
+
196
+ search_with MetasploitDataModels::Search::Operator::Port::List
197
+
186
198
  #
187
199
  # Validations
188
200
  #
@@ -204,4 +216,3 @@ class Mdm::Service < ActiveRecord::Base
204
216
 
205
217
  Metasploit::Concern.run(self)
206
218
  end
207
-
@@ -0,0 +1,25 @@
1
+ # Search operation on an attribute that holds a port number and is being searched with a single Integer port number.
2
+ class MetasploitDataModels::Search::Operation::Port::Number < Metasploit::Model::Search::Operation::Integer
3
+ #
4
+ # CONSTANTS
5
+ #
6
+
7
+ # The number of bits in a port number
8
+ BITS = 16
9
+ # The maximum port number
10
+ MAXIMUM = (1 << BITS) - 1
11
+ # The minimum port number
12
+ MINIMUM = 0
13
+
14
+ # The range of valid port numbers from {MINIMUM} to {MAXIMUM}, inclusive.
15
+ RANGE = (MINIMUM..MAXIMUM)
16
+
17
+ #
18
+ # Validations
19
+ #
20
+
21
+ validates :value,
22
+ inclusion: {
23
+ in: RANGE
24
+ }
25
+ end
@@ -0,0 +1,79 @@
1
+ # Search operation on an attribute that holds a port number and is being search with a range of port numbers. The
2
+ # range is specified as `<min>-<max>` with `<min>` being less than `<max>` and both being within
3
+ # {MetasploitDataModels::Search::Operation::Port::Range the valid port range}.
4
+ class MetasploitDataModels::Search::Operation::Port::Range < MetasploitDataModels::Search::Operation::Range
5
+ #
6
+ # Validations
7
+ #
8
+
9
+ validate :ports
10
+
11
+ #
12
+ # Instance Methods
13
+ #
14
+
15
+ # Sets `#value` to a range of ports.
16
+ #
17
+ # @param formatted_value [#to_s] '\d+-\d+'
18
+ def value=(formatted_value)
19
+ super(formatted_value)
20
+
21
+ # could not be a `Range` if super conversion failed
22
+ # setters return the argument, not the return value from the method, so access `#value` directly
23
+ if value.is_a? Range
24
+ begin
25
+ # use Integer() instead of String#to_i as String#to_i will ignore trailing letters (i.e. '1two' -> 1) and turn all
26
+ # string without an integer in it to 0.
27
+ integer_begin = Integer(value.begin.to_s)
28
+ integer_end = Integer(value.end.to_s)
29
+ rescue ArgumentError
30
+ # setter returned is ignored in MRI, but do it anyway for other implementation
31
+ @value
32
+ else
33
+ @value = Range.new(integer_begin, integer_end)
34
+ end
35
+ else
36
+ # setter returned is ignored in MRI, but do it anyway for other implementation
37
+ # return unconvertible value from `super`
38
+ @value
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ # @note `#value` should be check to be a `Range` before calling {#port}.
45
+ #
46
+ # Validate that either `Range#begin` or `Range#end` is a valid port number in `#value`
47
+ #
48
+ # @param extreme [:begin, :end] Which extreme of the `Range` in `value` to validate.
49
+ # @return [void]
50
+ def port(extreme)
51
+ extreme_value = value.send(extreme)
52
+
53
+ if extreme_value.is_a? Integer
54
+ unless MetasploitDataModels::Search::Operation::Port::Number::RANGE.cover?(extreme_value)
55
+ errors.add(
56
+ :value,
57
+ :port_range_extreme_inclusion,
58
+ extreme: extreme,
59
+ extreme_value: extreme_value,
60
+ maximum: MetasploitDataModels::Search::Operation::Port::Number::MAXIMUM,
61
+ minimum: MetasploitDataModels::Search::Operation::Port::Number::MINIMUM
62
+ )
63
+ end
64
+ else
65
+ errors.add(:value, :port_range_extreme_not_an_integer, extreme: extreme, extreme_value: extreme_value)
66
+ end
67
+ end
68
+
69
+ # Validates that the `Range#begin` and `Range#end` of `#value` are valid port numbers.
70
+ #
71
+ # @return [void]
72
+ def ports
73
+ if value.is_a? Range
74
+ [:begin, :end].each do |extreme|
75
+ port(extreme)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,56 @@
1
+ # Search operation on a `Range`.
2
+ class MetasploitDataModels::Search::Operation::Range < Metasploit::Model::Search::Operation::Base
3
+ #
4
+ # CONSTANTS
5
+ #
6
+
7
+ # Separates beginning from end of the range.
8
+ SEPARATOR = '-'
9
+
10
+ #
11
+ # Validation
12
+ #
13
+
14
+ validate :ordered
15
+ validate :range
16
+
17
+ #
18
+ # Instance Methods
19
+ #
20
+
21
+ # Sets `#value` to a `Range` composed by separating `formatted_value` by `-`.
22
+ #
23
+ # @param formatted_value [#to_s]
24
+ # @return [Range<String>]
25
+ def value=(formatted_value)
26
+ range_arguments = formatted_value.to_s.split(SEPARATOR, 2)
27
+
28
+ begin
29
+ @value = Range.new(*range_arguments)
30
+ rescue ArgumentError
31
+ @value = formatted_value
32
+ end
33
+
34
+ @value
35
+ end
36
+
37
+ private
38
+
39
+ # Validates that `#value` is a `Range` with `Range#begin` less than or equal to `Range#begin`
40
+ #
41
+ # @return [void]
42
+ def ordered
43
+ if value.is_a?(Range) && value.begin > value.end
44
+ errors.add(:value, :order, begin: value.begin.inspect, end: value.end.inspect)
45
+ end
46
+ end
47
+
48
+ # Validates that `#value` is a `Range`
49
+ #
50
+ # @return [void]
51
+ def range
52
+ unless value.is_a? Range
53
+ errors.add(:value, :range)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,73 @@
1
+ require 'shellwords'
2
+
3
+ # Searches multiple text fields by breaking up the formatted value into words and doing text search for each word across
4
+ # each operator named in {#operator_names}.
5
+ class MetasploitDataModels::Search::Operator::Multitext < Metasploit::Model::Search::Operator::Group::Intersection
6
+ #
7
+ # Attributes
8
+ #
9
+
10
+ # @!attribute name
11
+ # The name of this operator.
12
+ #
13
+ # @return [Symbol]
14
+ attr_accessor :name
15
+
16
+ # @!attribute operator_names
17
+ # The name of the operators to search across.
18
+ #
19
+ # @return [Array<Symbol>]
20
+ attr_writer :operator_names
21
+
22
+ #
23
+ # Validations
24
+ #
25
+
26
+ validates :operator_names,
27
+ length: {
28
+ minimum: 2
29
+ }
30
+ validates :name,
31
+ presence: true
32
+
33
+ #
34
+ # Instance Methods
35
+ #
36
+
37
+ # Breaks `formatted_value` into words using `Shellwords.split`. Each word is then searched across all {#operators},
38
+ # where any operator can match for that word. The search for multiple multiple is intersected, so that additional
39
+ # words can refine the search.
40
+ #
41
+ # @param formatted_value [#to_s]
42
+ # @return [Array<Metasploit::Model::Search::Operation::Group::Union>] Unions to be intersected.
43
+ def children(formatted_value)
44
+ words = Shellwords.split formatted_value.to_s
45
+
46
+ words.map { |word|
47
+ child_operators = operators.map { |operator|
48
+ operator.operate_on(word)
49
+ }
50
+
51
+ Metasploit::Model::Search::Operation::Group::Union.new(
52
+ children: child_operators,
53
+ operator: self
54
+ )
55
+ }
56
+ end
57
+
58
+ # The name of the operators to search for each word.
59
+ #
60
+ # @return [Array<Symbol>] Default to `[]`
61
+ def operator_names
62
+ @operator_names ||= []
63
+ end
64
+
65
+ # Operators with {#operator_names}.
66
+ #
67
+ # @return [Array<Metasploit::Model::Search::Operator::Base>]
68
+ def operators
69
+ @operators ||= operator_names.map { |operator_name|
70
+ operator(operator_name)
71
+ }
72
+ end
73
+ end