From 249c08f597a514b3a37f07ada3ba8efc2c1c86f7 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Wed, 20 Sep 2017 19:02:15 -0500 Subject: [PATCH] usability improvements ith how base options are registered This adds named parameters for all of the current array-index based options. It also allows specifying the description as the 2nd parameter, allowing the 'required' parameter to be implicitly false (the most common value). A simple parameter like: OptAddress.new('ReverseListenerBindAddress', [false, 'The specific IP address to bind to on the local system']), Can now be rewritten as: OptAddress.new('ReverseListenerBindAddress', 'The specific IP address to bind to on the local system'), More complex options are also now easier to read: OptString.new( 'HttpUserAgent', 'The user-agent that the payload should use', default: Rex::UserAgent.shortest, aliases: ['MeterpreterUserAgent'] ), This also makes dealing with enums easier because default is implicit unless specified. This: OptEnum.new('PayloadProxyType', [true, 'The proxy type, HTTP or SOCKS', 'HTTP', ['HTTP', 'SOCKS']]), Becomes: OptEnum.new('HttpProxyType', 'The proxy type, HTTP or SOCKS', required: true, enums: ['HTTP', 'SOCKS']) This maintains full backward compatibility with existing code as well. --- lib/msf/core/opt_base.rb | 43 ++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/msf/core/opt_base.rb b/lib/msf/core/opt_base.rb index 348a0eca33..a8ce71f4b4 100644 --- a/lib/msf/core/opt_base.rb +++ b/lib/msf/core/opt_base.rb @@ -22,15 +22,31 @@ module Msf # attrs[3] = possible enum values # attrs[4] = Regex to validate the option # - def initialize(in_name, attrs = [], aliases: []) + # Attrs can also be specified explicitly via named parameters, or attrs can + # also be a string as standin for the required description field. + # + def initialize(in_name, attrs = [], + required: false, desc: nil, default: nil, enums: [], regex: nil, aliases: []) self.name = in_name self.advanced = false self.evasion = false - self.required = attrs[0] || false - self.desc = attrs[1] - self.default = attrs[2] - self.enums = [ *(attrs[3]) ].map { |x| x.to_s } - regex_temp = attrs[4] || nil + self.aliases = aliases + + if attrs.is_a?(String) || attrs.length == 0 + self.required = required + self.desc = attrs.is_a?(String) ? attrs : desc + self.enums = [ *(enums) ].map { |x| x.to_s } + self.default = default || enums[0] + regex_temp = regex + else + self.required = attrs[0] || required + self.desc = attrs[1] || desc + self.default = attrs[2] || default + self.enums = attrs[3] || enums + self.enums = [ *(self.enums) ].map { |x| x.to_s } + regex_temp = attrs[4] || regex + end + if regex_temp # convert to string regex_temp = regex_temp.to_s if regex_temp.is_a? Regexp @@ -45,35 +61,34 @@ module Msf raise("Invalid Regex #{regex_temp}: #{e}") end end - self.aliases = aliases end # # Returns true if this is a required option. # def required? - return required + required end # # Returns true if this is an advanced option. # def advanced? - return advanced + advanced end # # Returns true if this is an evasion option. # def evasion? - return evasion + evasion end # # Returns true if the supplied type is equivalent to this option's type. # def type?(in_type) - return (type == in_type) + type == in_type end # @@ -94,7 +109,7 @@ module Msf if regex return !!value.match(regex) end - return true + true end # @@ -102,7 +117,7 @@ module Msf # a valid value # def empty_required_value?(value) - return (required? and value.nil?) + required? && value.nil? end # @@ -169,6 +184,4 @@ module Msf attr_writer :required, :desc, :default # :nodoc: end - end -