Skip to content

Commit a4e199a

Browse files
committed
Land rapid7#9000, enhance module option registration
2 parents 40a71af + c5cc013 commit a4e199a

File tree

4 files changed

+105
-103
lines changed

4 files changed

+105
-103
lines changed

lib/msf/core/opt.rb

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# -*- coding: binary -*-
22

33
module Msf
4-
54
#
65
# Builtin framework options with shortcut methods
76
#
@@ -51,22 +50,19 @@ def self.RPORT(default=nil, required=true, desc="The target port")
5150
Msf::OptPort.new(__method__.to_s, [ required, desc, default ])
5251
end
5352

54-
# @return [OptEnum]
55-
def self.SSLVersion
56-
Msf::OptEnum.new('SSLVersion', [ false,
57-
'Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate)', 'Auto',
58-
['Auto', 'SSL2', 'SSL3', 'SSL23', 'TLS', 'TLS1', 'TLS1.1', 'TLS1.2']])
53+
def self.ssl_supported_options
54+
@m ||= ['Auto', 'TLS'] + OpenSSL::SSL::SSLContext::METHODS \
55+
.select{|m| !m.to_s.include?('client') && !m.to_s.include?('server')} \
56+
.select{|m| OpenSSL::SSL::SSLContext.new(m) && true rescue false} \
57+
.map{|m| m.to_s.sub(/v/, '').sub('_', '.')}
5958
end
6059

61-
# These are unused but remain for historical reasons
62-
class << self
63-
alias builtin_chost CHOST
64-
alias builtin_cport CPORT
65-
alias builtin_lhost LHOST
66-
alias builtin_lport LPORT
67-
alias builtin_proxies Proxies
68-
alias builtin_rhost RHOST
69-
alias builtin_rport RPORT
60+
# @return [OptEnum]
61+
def self.SSLVersion
62+
Msf::OptEnum.new('SSLVersion',
63+
'Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate)',
64+
enums: self.ssl_supported_options
65+
)
7066
end
7167

7268
CHOST = CHOST()
@@ -78,5 +74,4 @@ class << self
7874
RPORT = RPORT()
7975
SSLVersion = SSLVersion()
8076
end
81-
8277
end

lib/msf/core/opt_base.rb

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,39 @@ class OptBase
2222
# attrs[3] = possible enum values
2323
# attrs[4] = Regex to validate the option
2424
#
25-
def initialize(in_name, attrs = [], aliases: [])
25+
# Attrs can also be specified explicitly via named parameters, or attrs can
26+
# also be a string as standin for the required description field.
27+
#
28+
def initialize(in_name, attrs = [],
29+
required: false, desc: nil, default: nil, enums: [], regex: nil, aliases: [])
2630
self.name = in_name
2731
self.advanced = false
2832
self.evasion = false
29-
self.required = attrs[0] || false
30-
self.desc = attrs[1]
31-
self.default = attrs[2]
32-
self.enums = [ *(attrs[3]) ].map { |x| x.to_s }
33-
regex_temp = attrs[4] || nil
33+
self.aliases = aliases
34+
35+
if attrs.is_a?(String) || attrs.length == 0
36+
self.required = required
37+
self.desc = attrs.is_a?(String) ? attrs : desc
38+
self.enums = [ *(enums) ].map { |x| x.to_s }
39+
if default.nil? && enums.length > 0
40+
self.default = enums[0]
41+
else
42+
self.default = default
43+
end
44+
regex_temp = regex
45+
else
46+
if attrs[0].nil?
47+
self.required = required
48+
else
49+
self.required = attrs[0]
50+
end
51+
self.desc = attrs[1] || desc
52+
self.default = attrs[2] || default
53+
self.enums = attrs[3] || enums
54+
self.enums = [ *(self.enums) ].map { |x| x.to_s }
55+
regex_temp = attrs[4] || regex
56+
end
57+
3458
if regex_temp
3559
# convert to string
3660
regex_temp = regex_temp.to_s if regex_temp.is_a? Regexp
@@ -45,35 +69,34 @@ def initialize(in_name, attrs = [], aliases: [])
4569
raise("Invalid Regex #{regex_temp}: #{e}")
4670
end
4771
end
48-
self.aliases = aliases
4972
end
5073

5174
#
5275
# Returns true if this is a required option.
5376
#
5477
def required?
55-
return required
78+
required
5679
end
5780

5881
#
5982
# Returns true if this is an advanced option.
6083
#
6184
def advanced?
62-
return advanced
85+
advanced
6386
end
6487

6588
#
6689
# Returns true if this is an evasion option.
6790
#
6891
def evasion?
69-
return evasion
92+
evasion
7093
end
7194

7295
#
7396
# Returns true if the supplied type is equivalent to this option's type.
7497
#
7598
def type?(in_type)
76-
return (type == in_type)
99+
type == in_type
77100
end
78101

79102
#
@@ -94,15 +117,15 @@ def valid?(value, check_empty: true)
94117
if regex
95118
return !!value.match(regex)
96119
end
97-
return true
120+
true
98121
end
99122

100123
#
101124
# Returns true if the value supplied is nil and it's required to be
102125
# a valid value
103126
#
104127
def empty_required_value?(value)
105-
return (required? and value.nil?)
128+
required? && value.nil?
106129
end
107130

108131
#
@@ -169,6 +192,4 @@ def display_value(value)
169192

170193
attr_writer :required, :desc, :default # :nodoc:
171194
end
172-
173195
end
174-

lib/msf/core/opt_bool.rb

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,33 @@
11
# -*- coding: binary -*-
22

33
module Msf
4+
# Boolean option type
5+
class OptBool < OptBase
6+
TRUE_REGEX = /^(y|yes|t|1|true)$/i
7+
ANY_REGEX = /^(y|yes|n|no|t|f|0|1|true|false)$/i
8+
9+
# This overrides default from 'nil' to 'false'
10+
def initialize(in_name, attrs = [],
11+
required: true, desc: nil, default: false, aliases: [])
12+
super
13+
end
414

5-
###
6-
#
7-
# Boolean option.
8-
#
9-
###
10-
class OptBool < OptBase
11-
12-
TrueRegex = /^(y|yes|t|1|true)$/i
13-
14-
def type
15-
return 'bool'
16-
end
17-
18-
def valid?(value, check_empty: true)
19-
return false if empty_required_value?(value)
20-
21-
if ((value != nil and
22-
(value.to_s.empty? == false) and
23-
(value.to_s.match(/^(y|yes|n|no|t|f|0|1|true|false)$/i) == nil)))
24-
return false
15+
def type
16+
return 'bool'
2517
end
2618

27-
true
28-
end
19+
def valid?(value, check_empty: true)
20+
return false if check_empty && empty_required_value?(value)
21+
return true if value.nil? && !required?
2922

30-
def normalize(value)
31-
if(value.nil? or value.to_s.match(TrueRegex).nil?)
32-
false
33-
else
34-
true
23+
!(value.nil? ||
24+
value.to_s.empty? ||
25+
value.to_s.match(ANY_REGEX).nil?)
3526
end
36-
end
37-
38-
def is_true?(value)
39-
return normalize(value)
40-
end
4127

42-
def is_false?(value)
43-
return !is_true?(value)
28+
def normalize(value)
29+
!(value.nil? ||
30+
value.to_s.match(TRUE_REGEX).nil?)
31+
end
4432
end
45-
46-
end
47-
4833
end

lib/msf/core/opt_enum.rb

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,49 @@
11
# -*- coding: binary -*-
22

33
module Msf
4+
###
5+
#
6+
# Enum option.
7+
#
8+
###
9+
class OptEnum < OptBase
10+
def type
11+
return 'enum'
12+
end
413

5-
###
6-
#
7-
# Enum option.
8-
#
9-
###
10-
class OptEnum < OptBase
11-
12-
def type
13-
return 'enum'
14-
end
15-
16-
def valid?(value=self.value, check_empty: true)
17-
return false if check_empty && empty_required_value?(value)
18-
return true if value.nil? and !required?
19-
20-
(value and self.enums.include?(value.to_s))
21-
end
22-
23-
def normalize(value=self.value)
24-
return nil if not self.valid?(value)
25-
return value.to_s
26-
end
27-
28-
def desc=(value)
29-
self.desc_string = value
14+
# This overrides required default from 'false' to 'true'
15+
def initialize(in_name, attrs = [],
16+
required: true, desc: nil, default: nil, enums: [], aliases: [])
17+
super
18+
end
3019

31-
self.desc
32-
end
20+
def valid?(value = self.value, check_empty: true)
21+
return false if check_empty && empty_required_value?(value)
22+
return true if value.nil? && !required?
3323

34-
def desc
35-
if self.enums
36-
str = self.enums.join(', ')
24+
!value.nil? && enums.include?(value.to_s)
3725
end
38-
"#{self.desc_string || ''} (Accepted: #{str})"
39-
end
4026

27+
def normalize(value = self.value)
28+
if valid?(value)
29+
value.to_s
30+
else
31+
nil
32+
end
33+
end
4134

42-
protected
35+
def desc=(value)
36+
self.desc_string = value
37+
desc
38+
end
4339

44-
attr_accessor :desc_string # :nodoc:
40+
def desc
41+
str = enums.join(', ') if enums
42+
"#{desc_string || ''} (Accepted: #{str})"
43+
end
4544

46-
end
45+
protected
4746

47+
attr_accessor :desc_string # :nodoc:
48+
end
4849
end

0 commit comments

Comments
 (0)