metasploit_data_models 0.17.3 → 0.18.0.pre.compatibility

Sign up to get free protection for your applications and to get access to all the features.
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