Module: Msf::Modules::External::CLI

Defined in:
lib/msf/core/modules/external/cli.rb

Class Method Summary collapse

Class Method Details

.choose_type(t) ⇒ Object


93
94
95
96
97
98
99
100
101
102
103
# File 'lib/msf/core/modules/external/cli.rb', line 93

def self.choose_type(t)
  if t == 'int' or t == 'port'
    Integer
  elsif t == 'float'
    Float
  elsif t.match /range$/
    Array
  else # XXX TODO add validation for addresses and other MSF option types
    String
  end
end

.make_options(parser, out, args) ⇒ Object


105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/msf/core/modules/external/cli.rb', line 105

def self.make_options(parser, out, args)
  args.each do |n, opt|
    name = n.tr('_', '-')
    desc = if opt['default']
      "#{opt['description']}, (default: #{opt['default']})"
    else
      opt['description']
    end
    parser.on "--#{name} #{n.upcase}", choose_type(opt['type']), desc do |arg|
      out[n] = arg
    end
  end
end

.parse_options(mod) ⇒ Object


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/msf/core/modules/external/cli.rb', line 7

def self.parse_options(mod)
  action = 'run'
  actions = ['run'] + mod.meta['capabilities']
  args = mod.meta['options'].reduce({}) do |defaults, (n, opt)|
    if opt['default'].nil?
      if opt['required']
        defaults
      else
        defaults[n] = nil
        defaults
      end
    else
      defaults[n] = opt['default']
      defaults
    end
  end

  op = OptionParser.new do |opts|
    if $0 != mod.path
      opts.banner = "Usage: #{$0} #{mod.path} [OPTIONS] [ACTION]"
    end
    opts.separator ""

    opts.separator mod.meta['description']
    opts.separator ""

    opts.separator "Postitional arguments:"
    opts.separator "  ACTION:    The action to take (#{actions.inspect})"
    opts.separator ""

    opts.separator "Required arguments:"
    make_options opts, args, mod.meta['options'].select {|n, o| o['required'] && o['default'].nil?}
    opts.separator ""

    opts.separator "Optional arguments:"
    make_options opts, args, mod.meta['options'].select {|n, o| !o['required'] || !o['default'].nil?}

    opts.on '-h', '--help', 'Prints this help' do
      $stderr.puts opts
      exit
    end
  end

  begin
    extra = op.permute *ARGV
    # If no extra args are given we use the default action
    if extra.length == 1
      action = extra.shift
    elsif extra.length > 1
      action = extra.shift
      $stderr.puts "WARNING: unrecognized arguments #{extra.inspect}"
    end
  rescue OptionParser::InvalidArgument => e
    $stderr.puts e.message
    abort
  rescue OptionParser::MissingArgument => e
    $stderr.puts e.message
    abort
  end

  required = mod.meta['options'].select {|_, o| o['required']}.map {|n, _| n}.sort

  # Were we run with any non-module options if we need them?
  if args.empty? && !required.empty?
    $stderr.puts op
    exit
  # Did someone forget to add some options we need?
  elsif (args.keys & required).sort != required
    missing = required - (args.keys & required)
    abort "Missing required option(s): #{missing.map {|o| '--' + o}.join ', '}"
  end

  unless action == 'run' || mod.meta['capabilities'].include?(action)
    $stderr.puts "Invalid ACTION choice #{action.inspect} (choose from #{actions.inspect})"
    abort
  end

  action =
    case action
    when 'run'; :run
    when 'soft_check'; :soft_check
    when 'hard_check'; :hard_check
    end
  [args, action]
end