metasploit-model 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a5f988847549534fae7fffc226d076ba4bd61664ec29df83d88bd063841d7a4
4
- data.tar.gz: c9e43a7f1669acf013d92202396df2e37a2225a9ddebd0d868d448891015d0d3
3
+ metadata.gz: b320d71768ecbaa1bd58ec8c2791952813cc9d36172618a5301d7c217d206e82
4
+ data.tar.gz: c0f238d48e57a6af827b928a74d6c2db31f3dcd3f808c52736a28a6799fcc021
5
5
  SHA512:
6
- metadata.gz: b3382aedd7f694cb1d1087d524763f00d0c01f505cd530cb5acf708681a78c6e94ef8725bbd07e1174d107eba468a5c4ec905c6dc30c22825afbfba74ba6fdec
7
- data.tar.gz: b86c773e1eb4789c7b32660f24bceb4a7746f0d148ef57a668ab1fd6e55eb1337a12d498414dc9e17255328e3d6efba2ab5acf4b627ca595f8eccf30805d4769
6
+ metadata.gz: d24c085fce1ec483ac68a5c69b07e04e120947327df88e899428066cce8da01ce867f1f52acb1860167cced1e3b20c547648fd65e6b7195c826cdfca3a096696
7
+ data.tar.gz: ccaef3d085307bb4b974169046dbcec8e4a9aafdcb59864bc717ab13d080f5fcbbc8c28dbad1e39f7ec2d7a37a6255df5a31934fbdc4644d2471b1ffa7ae140f
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -0,0 +1,26 @@
1
+ require 'ipaddr'
2
+
3
+ # Validates that attribute is a valid address.
4
+ class AddressFormatValidator < ActiveModel::EachValidator
5
+ # Validates that `attribute`'s `value` on `object` is a valid address.
6
+ #
7
+ # @param record [#errors, ApplicationRecord] ActiveModel or ActiveRecord
8
+ # @param attribute [Symbol] name of address attribute.
9
+ # @param value [String, nil] address.
10
+ # @return [void]
11
+ def validate_each(object, attribute, value)
12
+ error_message_block = lambda{ object.errors.add attribute, "must be a valid (IP or hostname) address" }
13
+ begin
14
+ # Checks for valid IP addresses
15
+ if value.is_a? IPAddr
16
+ potential_ip = value.dup
17
+ else
18
+ potential_ip = IPAddr.new(value)
19
+ end
20
+ error_message_block.call unless potential_ip.ipv4? || potential_ip.ipv6?
21
+ rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError, ArgumentError
22
+ # IP address resolution failed, checks for valid hostname
23
+ error_message_block.call unless (value && value.match?(/\A#{URI::PATTERN::HOSTNAME}\z/))
24
+ end
25
+ end
26
+ end
@@ -1,31 +1,25 @@
1
1
  require 'ipaddr'
2
2
 
3
- # Validates that value is an IPv4 or IPv6 address.
3
+ # Validates that value is a valid IPv4 or IPv6 address.
4
4
  class IpFormatValidator < ActiveModel::EachValidator
5
- # Validates that `value` is an IPv4 or IPv4 address. Ranges in CIDR or netmask notation are not allowed.
5
+ # Validates that `attribute`'s `value` on `object` is a valid IPv4 or IPv6 address.
6
6
  #
7
7
  # @param record [#errors, ApplicationRecord] ActiveModel or ActiveRecord
8
8
  # @param attribute [Symbol] name of IP address attribute.
9
9
  # @param value [String, nil] IP address.
10
10
  # @return [void]
11
- # @see IPAddr#ipv4?
12
- # @see IPAddr#ipv6?
13
- def validate_each(record, attribute, value)
11
+ def validate_each(object, attribute, value)
12
+ error_message_block = lambda{ object.errors.add attribute, "must be a valid IPv4 or IPv6 address" }
14
13
  begin
15
- potential_ip = IPAddr.new(value)
16
- rescue ArgumentError
17
- record.errors[attribute] << 'must be a valid IPv4 or IPv6 address'
18
- else
19
- # if it includes a netmask, then it's not an IP address, but an IP range.
20
- if potential_ip.ipv4?
21
- if potential_ip.instance_variable_get(:@mask_addr) != IPAddr::IN4MASK
22
- record.errors[attribute] << 'must be a valid IPv4 or IPv6 address and not an IPv4 address range in CIDR or netmask notation'
23
- end
24
- elsif potential_ip.ipv6?
25
- if potential_ip.instance_variable_get(:@mask_addr) != IPAddr::IN6MASK
26
- record.errors[attribute] << 'must be a valid IPv4 or IPv6 address and not an IPv6 address range in CIDR or netmask notation'
27
- end
14
+ if value.is_a? IPAddr
15
+ potential_ip = value.dup
16
+ else
17
+ potential_ip = IPAddr.new(value)
28
18
  end
19
+
20
+ error_message_block.call unless potential_ip.ipv4? || potential_ip.ipv6?
21
+ rescue ArgumentError
22
+ error_message_block.call
29
23
  end
30
24
  end
31
25
  end
@@ -10,7 +10,7 @@ class NilValidator < ActiveModel::EachValidator
10
10
  # @return [void]
11
11
  def validate_each(record, attribute, value)
12
12
  unless value.nil?
13
- record.errors[attribute] << 'must be nil'
13
+ record.errors.add attribute, 'must be nil'
14
14
  end
15
15
  end
16
16
  end
@@ -1,11 +1,19 @@
1
1
  # Validates that attribute's value is Array<Array(String, String)> which is the only valid type signature for serialized
2
2
  # parameters.
3
3
  class ParametersValidator < ActiveModel::EachValidator
4
+ #
5
+ # CONSTANTS
6
+ #
7
+
4
8
  # Sentence explaining the valid type signature for parameters.
5
9
  TYPE_SIGNATURE_SENTENCE = 'Valid parameters are an Array<Array(String, String)>.'
6
10
 
7
- # Validates that attribute's value is Array<Array(String, String)> which is the only valid type signature for
8
- # serialized parameters. Errors are specific to the how different `value` is compared to correct format.
11
+ #
12
+ # Instance Methods
13
+ #
14
+
15
+ # Validates that `attribute`'s `value` on `record` is `Array<Array(String, String)>` which is the only valid type
16
+ # signature for serialized parameters.
9
17
  #
10
18
  # @param record [#errors, ApplicationRecord] ActiveModel or ActiveRecord
11
19
  # @param attribute [Symbol] serialized parameters attribute name.
@@ -28,7 +36,7 @@ class ParametersValidator < ActiveModel::EachValidator
28
36
  :index => index
29
37
  )
30
38
 
31
- record.errors[attribute] << length_error
39
+ record.errors.add attribute, length_error
32
40
  else
33
41
  parameter_name = element.first
34
42
 
@@ -39,7 +47,7 @@ class ParametersValidator < ActiveModel::EachValidator
39
47
  :index => index,
40
48
  :prefix => "has blank parameter name"
41
49
  )
42
- record.errors[attribute] << error
50
+ record.errors.add attribute, error
43
51
  end
44
52
  else
45
53
  error = error_at(
@@ -47,7 +55,7 @@ class ParametersValidator < ActiveModel::EachValidator
47
55
  :index => index,
48
56
  :prefix => "has non-String parameter name (#{parameter_name.inspect})"
49
57
  )
50
- record.errors[attribute] << error
58
+ record.errors.add attribute, error
51
59
  end
52
60
 
53
61
  parameter_value = element.second
@@ -58,7 +66,7 @@ class ParametersValidator < ActiveModel::EachValidator
58
66
  :index => index,
59
67
  :prefix => "has non-String parameter value (#{parameter_value.inspect})"
60
68
  )
61
- record.errors[attribute] << error
69
+ record.errors.add attribute, error
62
70
  end
63
71
  end
64
72
  else
@@ -67,11 +75,11 @@ class ParametersValidator < ActiveModel::EachValidator
67
75
  :index => index,
68
76
  :prefix => 'has non-Array'
69
77
  )
70
- record.errors[attribute] << error
78
+ record.errors.add attribute, error
71
79
  end
72
80
  end
73
81
  else
74
- record.errors[attribute] << "is not an Array. #{TYPE_SIGNATURE_SENTENCE}"
82
+ record.errors.add attribute, "is not an Array. #{TYPE_SIGNATURE_SENTENCE}"
75
83
  end
76
84
  end
77
85
 
@@ -4,20 +4,18 @@ class PasswordIsStrongValidator < ActiveModel::EachValidator
4
4
  # CONSTANTS
5
5
  #
6
6
 
7
- # Password that are used too often and will be easily guessed.
7
+ # Known passwords that should NOT be allowed and should be considered weak.
8
8
  COMMON_PASSWORDS = %w{
9
- password pass root admin metasploit
10
- msf 123456 qwerty abc123 letmein monkey link182 demo
11
- changeme test1234 rapid7
12
- }
13
-
14
- # Validates that `value` is a strong password. A password is strong if it meets the following rules:
15
- # * SHOULD contain at least one letter.
16
- # * SHOULD contain at least one digit.
17
- # * SHOULD contain at least one special character.
18
- # * SHOULD NOT contain `record.username` (case-insensitive).
19
- # * SHOULD NOT be in {COMMON_PASSWORDS}.
20
- # * SHOULD NOT repetitions.
9
+ password pass root admin metasploit
10
+ msf 123456 qwerty abc123 letmein monkey link182 demo
11
+ changeme test1234 rapid7
12
+ }
13
+
14
+ # Special characters that are considered to strength passwords and are required once in a strong password.
15
+ SPECIAL_CHARS = %q{!@"#$%&'()*+,-./:;<=>?[\\]^_`{|}~ }
16
+
17
+ # Validates that the `attribute`'s `value` on `record` contains letters, numbers, and at least one special character
18
+ # without containing the `record.username`, any {COMMON_PASSWORDS} or repetition.
21
19
  #
22
20
  # @param record [#errors, #username, ApplicationRecord] ActiveModel or ActiveRecord that supports #username method.
23
21
  # @param attribute [Symbol] password attribute name.
@@ -27,30 +25,101 @@ class PasswordIsStrongValidator < ActiveModel::EachValidator
27
25
  return if value.blank?
28
26
 
29
27
  if is_simple?(value)
30
- record.errors[attribute] << 'must contain letters, numbers, and at least one special character'
28
+ record.errors.add attribute, 'must contain letters, numbers, and at least one special character'
31
29
  end
32
30
 
33
- if contains_username?(record.username, value)
34
- record.errors[attribute] << 'must not contain the username'
31
+ if !record.username.blank? && contains_username?(record.username, value)
32
+ record.errors.add attribute, 'must not contain the username'
35
33
  end
36
34
 
37
35
  if is_common_password?(value)
38
- record.errors[attribute] << 'must not be a common password'
36
+ record.errors.add attribute, 'must not be a common password'
39
37
  end
40
38
 
41
- if contains_repetition?(value)
42
- record.errors[attribute] << 'must not be a predictable sequence of characters'
39
+ if is_only_repetition?(value)
40
+ record.errors.add attribute, 'must not be a predictable sequence of characters'
43
41
  end
44
42
  end
45
43
 
46
44
  private
47
45
 
48
- # Password repetition (quite basic) -- no "aaaaaa" or "ababab" or "abcabc" or
49
- # "abcdabcd" (but note that the user can use "aaaaaab" or something).
46
+ # Returns whether the password is simple.
47
+ #
48
+ # @return [false] if password contains a letter, digit and special character.
49
+ # @return [true] otherwise
50
+ def is_simple?(password)
51
+ not (password =~ /[A-Za-z]/ and password =~ /[0-9]/ and password =~ /[#{Regexp.escape(SPECIAL_CHARS)}]/)
52
+ end
53
+
54
+ # Returns whether username is in password (case-insensitively).
55
+ #
56
+ # @return [true] if `username` is in `password`.
57
+ # @return [false] unless `username` is in `password`.
58
+ def contains_username?(username, password)
59
+ !!(password =~ /#{username}/i)
60
+ end
61
+
62
+ # Returns whether `password` is in {COMMON_PASSWORDS} or a simple variation of a password in {COMMON_PASSWORDS}.
63
+ #
64
+ # @param password [String]
65
+ # @return [Boolean]
66
+ def is_common_password?(password)
67
+ COMMON_PASSWORDS.each do |pw|
68
+ common_pw = [pw] # pw + "!", pw + "1", pw + "12", pw + "123", pw + "1234"]
69
+ common_pw += mutate_pass(pw)
70
+ common_pw.each do |common_pass|
71
+ if password.downcase =~ /#{common_pass}[\d!]*/
72
+ return true
73
+ end
74
+ end
75
+ end
76
+ false
77
+ end
78
+
79
+ # Returns a leet mutated variant of the original password
80
+ #
81
+ # @param password [String]
82
+ # @return [String] containing the password with leet mutations
83
+ def mutate_pass(password)
84
+ mutations = {
85
+ 'a' => '@',
86
+ 'o' => '0',
87
+ 'e' => '3',
88
+ 's' => '$',
89
+ 't' => '7',
90
+ 'l' => '1'
91
+ }
92
+
93
+ iterations = mutations.keys.dup
94
+ results = []
95
+
96
+ # Find PowerSet of all possible mutation combinations
97
+ iterations = iterations.inject([[]]){|c,y|r=[];c.each{|i|r<<i;r<<i+[y]};r}
98
+
99
+ # Iterate through combinations to create each possible mutation
100
+ iterations.each do |iteration|
101
+ next if iteration.flatten.empty?
102
+ first = iteration.shift
103
+ intermediate = password.gsub(/#{first}/i, mutations[first])
104
+ iteration.each do |mutator|
105
+ next unless mutator.kind_of? String
106
+ intermediate.gsub!(/#{mutator}/i, mutations[mutator])
107
+ end
108
+ results << intermediate
109
+ end
110
+
111
+ return results
112
+ end
113
+
114
+
115
+ # Returns whether `password` is only composed of repetitions
50
116
  #
51
117
  # @param password [String]
52
118
  # @return [Boolean]
53
- def contains_repetition?(password)
119
+ def is_only_repetition?(password)
120
+ # Password repetition (quite basic) -- no "aaaaaa" or "ababab" or "abcabc" or
121
+ # "abcdabcd" (but note that the user can use "aaaaaab" or something).
122
+
54
123
  if password.scan(/./).uniq.size < 2
55
124
  return true
56
125
  end
@@ -69,47 +138,4 @@ class PasswordIsStrongValidator < ActiveModel::EachValidator
69
138
 
70
139
  false
71
140
  end
72
-
73
- # Whether username is in password (case-insensitively).
74
- #
75
- # @return [false] if `password` is blank.
76
- # @return [false] if `username` is blank.
77
- # @return [false] unless `username` is in `password`.
78
- # @return [true] if `username` is in `password`.
79
- def contains_username?(username, password)
80
- contains = false
81
-
82
- unless password.blank? or username.blank?
83
- escaped_username = Regexp.escape(username)
84
- username_regexp = Regexp.new(escaped_username, Regexp::IGNORECASE)
85
-
86
- if username_regexp.match(password)
87
- contains = true
88
- end
89
- end
90
-
91
- contains
92
- end
93
-
94
- # Whether `password` is in {COMMON_PASSWORDS} or a simple variation of a password in {COMMON_PASSWORDS}.
95
- #
96
- # @param password [String]
97
- # @return [Boolean]
98
- def is_common_password?(password)
99
- COMMON_PASSWORDS.each do |pw|
100
- common_pw = [pw, pw + "!", pw + "1", pw + "12", pw + "123", pw + "1234"]
101
- if common_pw.include?(password.downcase)
102
- return true
103
- end
104
- end
105
- false
106
- end
107
-
108
- # Returns whether the password is simple.
109
- #
110
- # @return [false] if password contains a letter, digit and special character.
111
- # @return [true] otherwise
112
- def is_simple?(password)
113
- not (password =~ /[A-Za-z]/ and password =~ /[0-9]/ and password =~ /[\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5c\x5d\x5e\x5f\x60\x7b\x7c\x7d\x7e]/)
114
- end
115
141
  end
@@ -9,6 +9,7 @@
9
9
  require 'active_model'
10
10
  require 'active_support'
11
11
 
12
+ autoload :AddressFormatValidator, 'address_format_validator'
12
13
  autoload :IpFormatValidator, 'ip_format_validator'
13
14
  autoload :NilValidator, 'nil_validator'
14
15
  autoload :ParametersValidator, 'parameters_validator'
@@ -1,7 +1,7 @@
1
1
  module Metasploit
2
2
  module Model
3
3
  # VERSION is managed by GemRelease
4
- VERSION = '3.0.0'
4
+ VERSION = '3.1.0'
5
5
 
6
6
  # @return [String]
7
7
  #
@@ -0,0 +1,136 @@
1
+ RSpec.describe AddressFormatValidator do
2
+ subject(:address_format_validator) do
3
+ described_class.new(
4
+ :attributes => attributes
5
+ )
6
+ end
7
+
8
+ let(:attribute) do
9
+ :address
10
+ end
11
+
12
+ let(:attributes) do
13
+ [
14
+ attribute
15
+ ]
16
+ end
17
+
18
+ context '#validate_each' do
19
+ subject(:validate_each) do
20
+ address_format_validator.validate_each(record, attribute, value)
21
+ end
22
+
23
+ let(:error) do
24
+ 'must be a valid (IP or hostname) address'
25
+ end
26
+
27
+ let(:record) do
28
+ record_class.new
29
+ end
30
+
31
+ let(:record_class) do
32
+ # capture for Class.new scope
33
+ attribute = self.attribute
34
+
35
+ Class.new do
36
+ include ActiveModel::Validations
37
+
38
+ #
39
+ # Validations
40
+ #
41
+
42
+ validates attribute,
43
+ :address_format => true
44
+ end
45
+ end
46
+
47
+ context 'address' do
48
+ context 'in IPv4 format' do
49
+ let(:value) do
50
+ '192.168.0.1'
51
+ end
52
+
53
+ it 'should not record any errors' do
54
+ validate_each
55
+
56
+ expect(record.errors).to be_empty
57
+ end
58
+ end
59
+
60
+ context 'in IPv6 format' do
61
+ let(:value) do
62
+ '::1'
63
+ end
64
+
65
+ it 'should not record any errors' do
66
+ validate_each
67
+
68
+ expect(record.errors).to be_empty
69
+ end
70
+ end
71
+
72
+ context 'with a valid hostname' do
73
+ let(:value) do
74
+ 'testvalue.test.com'
75
+ end
76
+
77
+ it 'should not record any errors' do
78
+ validate_each
79
+
80
+ expect(record.errors).to be_empty
81
+ end
82
+ end
83
+
84
+ context 'with localhost' do
85
+ let(:value) do
86
+ 'localhost'
87
+ end
88
+
89
+ it 'should not record any errors' do
90
+ validate_each
91
+
92
+ expect(record.errors).to be_empty
93
+ end
94
+ end
95
+
96
+ context 'with blank address' do
97
+ let(:value) do
98
+ ''
99
+ end
100
+
101
+ it 'should record error' do
102
+ validate_each
103
+
104
+ expect(record.errors[attribute]).to include(error)
105
+ end
106
+ end
107
+
108
+ context 'with nil value' do
109
+ let(:value) do
110
+ nil
111
+ end
112
+
113
+ it 'should record error on attribute' do
114
+ validate_each
115
+
116
+ expect(record.errors[attribute]).to include(error)
117
+ end
118
+ end
119
+
120
+ context 'with a malformed hostname should record an error' do
121
+ invalid_hostnames = ['testvalue.test.com:', 'testvalue-.test.com', '[testvalue.test.com]']
122
+ invalid_hostnames.each do | entry |
123
+ let(:value) do
124
+ entry
125
+ end
126
+
127
+ it 'should record an error on attribute' do
128
+ validate_each
129
+ expect(record.errors[attribute]).to include(error)
130
+ end
131
+ end
132
+
133
+ end
134
+ end
135
+ end
136
+ end
@@ -69,30 +69,6 @@ RSpec.describe IpFormatValidator do
69
69
  end
70
70
  end
71
71
 
72
- context 'with IPv4 range' do
73
- let(:value) do
74
- '127.0.0.1/8'
75
- end
76
-
77
- it 'should record error' do
78
- validate_each
79
-
80
- expect(record.errors[attribute]).to include("#{error} and not an IPv4 address range in CIDR or netmask notation")
81
- end
82
- end
83
-
84
- context 'with IPv6 range' do
85
- let(:value) do
86
- '3ffe:505:2::1/48'
87
- end
88
-
89
- it 'should record error' do
90
- validate_each
91
-
92
- expect(record.errors[attribute]).to include("#{error} and not an IPv6 address range in CIDR or netmask notation")
93
- end
94
- end
95
-
96
72
  context 'without IPv4 or IPv6 address' do
97
73
  let(:value) do
98
74
  'localhost'
@@ -15,9 +15,9 @@ RSpec.describe PasswordIsStrongValidator do
15
15
  ]
16
16
  end
17
17
 
18
- context '#contains_repetition' do
19
- subject(:contains_repetition?) do
20
- password_is_strong_validator.send(:contains_repetition?, password)
18
+ context '#is_only_repetition' do
19
+ subject(:is_only_repetition?) do
20
+ password_is_strong_validator.send(:is_only_repetition?, password)
21
21
  end
22
22
 
23
23
  context 'with all the same character' do
@@ -56,8 +56,8 @@ RSpec.describe PasswordIsStrongValidator do
56
56
  let(:password) do
57
57
  'abcdefgh'
58
58
  end
59
-
60
59
  it { is_expected.to eq(false) }
60
+
61
61
  end
62
62
  end
63
63
 
@@ -66,59 +66,48 @@ RSpec.describe PasswordIsStrongValidator do
66
66
  password_is_strong_validator.send(:contains_username?, username, password)
67
67
  end
68
68
 
69
- let(:username) do
70
- ''
71
- end
72
-
73
- context 'with blank password' do
74
- let(:password) do
75
- ''
76
- end
77
-
78
- it { is_expected.to eq(false) }
79
- end
80
-
81
- context 'without blank password' do
82
- let(:password) do
83
- 'password'
69
+ context 'without blank username' do
70
+ let(:username) do
71
+ 'username'
84
72
  end
85
73
 
86
- context 'with blank username' do
87
- let(:username) do
74
+ context 'with blank password' do
75
+ let(:password) do
88
76
  ''
89
77
  end
90
-
91
78
  it { is_expected.to eq(false) }
92
79
  end
93
80
 
94
- context 'without blank username' do
81
+ context 'with reserved regex characters in username' do
95
82
  let(:username) do
96
- 'username'
83
+ "user(with)regex"
97
84
  end
98
85
 
99
- it 'should escape username' do
100
- expect(Regexp).to receive(:escape).with(username).and_call_original
101
-
102
- contains_username?
86
+ context 'with username in password' do
87
+ let(:password) do
88
+ "myPassworduser(with)regexValue"
89
+ end
90
+ it { is_expected.to eq(false)}
103
91
  end
92
+ end
104
93
 
105
- context 'with matching password' do
106
- context 'of different case' do
107
- let(:password) do
108
- username.titleize
109
- end
110
-
111
- it { is_expected.to eq(true) }
94
+ context 'with matching password' do
95
+ context 'of different case' do
96
+ let(:password) do
97
+ username.titleize
112
98
  end
113
99
 
114
- context 'of same case' do
115
- let(:password) do
116
- username
117
- end
100
+ it { is_expected.to eq(true) }
101
+ end
118
102
 
119
- it { is_expected.to eq(true) }
103
+ context 'of same case' do
104
+ let(:password) do
105
+ username
120
106
  end
107
+
108
+ it { is_expected.to eq(true) }
121
109
  end
110
+
122
111
  end
123
112
  end
124
113
  end
@@ -231,7 +220,7 @@ RSpec.describe PasswordIsStrongValidator do
231
220
 
232
221
  context 'without repetition' do
233
222
  let(:value) do
234
- 'A$uperg00dp@ssw0rd'
223
+ 'A$uperg00dp@sw0rd'
235
224
  end
236
225
 
237
226
  it 'should not record any errors' do
@@ -245,4 +234,4 @@ RSpec.describe PasswordIsStrongValidator do
245
234
  end
246
235
  end
247
236
  end
248
- end
237
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metasploit-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Imhoff
@@ -93,7 +93,7 @@ cert_chain:
93
93
  JI/W23RbIRksG2pioMhd4dCXq3FLLlkOV1YfCwWixNB+iIhQPPZVaPNfgPhCn4Dt
94
94
  DeGjje/qA4fkLtRmOtb9PUBq3ToRDE4=
95
95
  -----END CERTIFICATE-----
96
- date: 2020-02-01 00:00:00.000000000 Z
96
+ date: 2020-10-05 00:00:00.000000000 Z
97
97
  dependencies:
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: metasploit-yard
@@ -263,6 +263,7 @@ files:
263
263
  - app/models/metasploit/model/search/operator/single.rb
264
264
  - app/models/metasploit/model/search/query.rb
265
265
  - app/models/metasploit/model/visitation/visitor.rb
266
+ - app/validators/address_format_validator.rb
266
267
  - app/validators/ip_format_validator.rb
267
268
  - app/validators/nil_validator.rb
268
269
  - app/validators/parameters_validator.rb
@@ -337,6 +338,7 @@ files:
337
338
  - spec/app/models/metasploit/model/search/operator/single_spec.rb
338
339
  - spec/app/models/metasploit/model/search/query_spec.rb
339
340
  - spec/app/models/metasploit/model/visitation/visitor_spec.rb
341
+ - spec/app/validators/address_format_validator_spec.rb
340
342
  - spec/app/validators/ip_format_validator_spec.rb
341
343
  - spec/app/validators/nil_validator_spec.rb
342
344
  - spec/app/validators/parameters_validator_spec.rb
@@ -476,6 +478,7 @@ test_files:
476
478
  - spec/app/models/metasploit/model/search/operator/single_spec.rb
477
479
  - spec/app/models/metasploit/model/search/query_spec.rb
478
480
  - spec/app/models/metasploit/model/visitation/visitor_spec.rb
481
+ - spec/app/validators/address_format_validator_spec.rb
479
482
  - spec/app/validators/ip_format_validator_spec.rb
480
483
  - spec/app/validators/nil_validator_spec.rb
481
484
  - spec/app/validators/parameters_validator_spec.rb
metadata.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- -|6L[8nc�A?N,�H�, .t�D�;d��D��u�:��Ix� ��_U81��>��!oS㦠N���c15f��'}%E��{��'_'?�)k����[�,��S�u��|��z� ��t���-@��H�QAGo7R�S�G� �eL1#F���(4)d))�}��������%{#Wi�3���#�^��=��s�W&$$<n�T��q�g>�h�a&n��p�Q͇�Ѻ�C9� ��MŚ���� �R+��B W
2
- g���6;
1
+ !��^+���8+�J
2
+ 7��Tl�����fݮ