metasploit-yard 1.0.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.simplecov +42 -0
- data/.travis.yml +21 -0
- data/.yardopts +7 -0
- data/CONTRIBUTING.md +178 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +29 -0
- data/README.md +114 -0
- data/Rakefile +19 -0
- data/config/cucumber.yml +6 -0
- data/features/rake_task.feature +90 -0
- data/features/step_definitions/project.rb +25 -0
- data/features/step_definitions/rvm.rb +46 -0
- data/features/support/env.rb +8 -0
- data/lib/metasploit/yard.rb +20 -0
- data/lib/metasploit/yard/aruba.rb +12 -0
- data/lib/metasploit/yard/aruba/rvm_env.rb +105 -0
- data/lib/metasploit/yard/aruba/rvm_env/export.rb +75 -0
- data/lib/metasploit/yard/aruba/rvm_env/prepend.rb +35 -0
- data/lib/metasploit/yard/aruba/rvm_env/unset.rb +44 -0
- data/lib/metasploit/yard/aruba/rvm_env/variable.rb +32 -0
- data/lib/metasploit/yard/railtie.rb +10 -0
- data/lib/metasploit/yard/version.rb +43 -0
- data/lib/tasks/yard.rake +58 -0
- data/metasploit-yard.gemspec +50 -0
- data/spec/metasploit/yard/aruba/rvm_env/export_spec.rb +95 -0
- data/spec/metasploit/yard/aruba/rvm_env/prepend_spec.rb +95 -0
- data/spec/metasploit/yard/version_spec.rb +143 -0
- data/spec/metasploit/yard_spec.rb +15 -0
- data/spec/spec_helper.rb +77 -0
- metadata +240 -0
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'cucumber'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
Cucumber::Rake::Task.new(:cucumber) do |t|
|
7
|
+
t.cucumber_opts = "features --format pretty"
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
|
+
|
12
|
+
# Use find_all_by_name instead of find_by_name as find_all_by_name will return pre-release versions
|
13
|
+
gem_specification = Gem::Specification.find_all_by_name('metasploit-yard').first
|
14
|
+
|
15
|
+
Dir[File.join(gem_specification.gem_dir, 'lib', 'tasks', '**', '*.rake')].each do |rake|
|
16
|
+
load rake
|
17
|
+
end
|
18
|
+
|
19
|
+
task :default => :spec
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
Feature: yard.rake
|
2
|
+
|
3
|
+
In order to generate documentation for metasploit projects, but not end up with multiple actions for the `yard` rake tasks
|
4
|
+
As a developer calling `rake yard`
|
5
|
+
I want `yard.rake` loaded from `metasploit-yard`
|
6
|
+
|
7
|
+
Scenario: Without Rails
|
8
|
+
Given I create a clean gemset "without_rails_use_metasploit_yard"
|
9
|
+
And I use gemset "without_rails_use_metasploit_yard"
|
10
|
+
And I successfully run `bundle gem without_rails_use_metasploit_yard`
|
11
|
+
And I cd to "without_rails_use_metasploit_yard"
|
12
|
+
And I overwrite "without_rails_use_metasploit_yard.gemspec" with:
|
13
|
+
"""
|
14
|
+
# coding: utf-8
|
15
|
+
lib = File.expand_path('../lib', __FILE__)
|
16
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
17
|
+
require 'without_rails_use_metasploit_yard/version'
|
18
|
+
|
19
|
+
Gem::Specification.new do |spec|
|
20
|
+
spec.name = 'without_rails_use_metasploit_yard'
|
21
|
+
spec.version = WithoutRailsUseMetasploitYard::VERSION
|
22
|
+
spec.authors = ['Luke Imhoff']
|
23
|
+
spec.email = ['luke_imhoff@rapid7.com']
|
24
|
+
spec.summary = 'Uses metasploit-yard without Rails'
|
25
|
+
spec.license = 'BSD-3-Clause'
|
26
|
+
|
27
|
+
spec.files = `git ls-files -z`.split("\x0")
|
28
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
29
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
30
|
+
spec.require_paths = ['lib']
|
31
|
+
|
32
|
+
spec.add_development_dependency 'bundler'
|
33
|
+
spec.add_development_dependency 'rake'
|
34
|
+
spec.add_development_dependency 'metasploit-yard'
|
35
|
+
end
|
36
|
+
"""
|
37
|
+
And I append to "Rakefile" with:
|
38
|
+
"""
|
39
|
+
# Use find_all_by_name instead of find_by_name as find_all_by_name will return pre-release versions
|
40
|
+
gem_specification = Gem::Specification.find_all_by_name('metasploit-yard').first
|
41
|
+
|
42
|
+
Dir[File.join(gem_specification.gem_dir, 'lib', 'tasks', '**', '*.rake')].each do |rake|
|
43
|
+
load rake
|
44
|
+
end
|
45
|
+
"""
|
46
|
+
And I install the project gem locally
|
47
|
+
And I successfully run `bundle install`
|
48
|
+
When I run `rake yard`
|
49
|
+
Then the output should contain:
|
50
|
+
"""
|
51
|
+
Undocumented Objects:
|
52
|
+
WithoutRailsUseMetasploitYard (lib/without_rails_use_metasploit_yard.rb:3)
|
53
|
+
WithoutRailsUseMetasploitYard::VERSION (lib/without_rails_use_metasploit_yard/version.rb:2)
|
54
|
+
"""
|
55
|
+
And the stderr from "rake yard" should contain:
|
56
|
+
"""
|
57
|
+
Documentation percentage (0.00%) below threshold (100.00%)
|
58
|
+
"""
|
59
|
+
# Don't do this in a different scenario because it takes minutes to setup a new gem project
|
60
|
+
Given a file named "config/yard-stats-threshold" with:
|
61
|
+
"""
|
62
|
+
0.0
|
63
|
+
"""
|
64
|
+
When I successfully run `rake yard`
|
65
|
+
Then the output from "rake yard" should not contain "below threshold"
|
66
|
+
|
67
|
+
@travis-ci-wip
|
68
|
+
Scenario: With a Rails Application
|
69
|
+
Given I create a clean gemset "rails_application_use_metasploit_yard"
|
70
|
+
And I use gemset "rails_application_use_metasploit_yard"
|
71
|
+
And I successfully run `gem install rails`
|
72
|
+
And I successfully run `rails new rails_application_use_metasploit_yard --skip-action-view --skip-active-record --skip-javascript --skip-spring --skip-sprockets --skip-test-unit`
|
73
|
+
And I cd to "rails_application_use_metasploit_yard"
|
74
|
+
And I append to "Gemfile" with:
|
75
|
+
"""
|
76
|
+
gem 'metasploit-yard', group: :development
|
77
|
+
"""
|
78
|
+
And I install the project gem locally
|
79
|
+
And I successfully run `bundle install`
|
80
|
+
And a file named "config/yard-stats-threshold" with:
|
81
|
+
"""
|
82
|
+
0.0
|
83
|
+
"""
|
84
|
+
When I successfully run `rake yard`
|
85
|
+
Then the output should contain:
|
86
|
+
"""
|
87
|
+
Undocumented Objects:
|
88
|
+
ApplicationController (app/controllers/application_controller.rb:1)
|
89
|
+
ApplicationHelper (app/helpers/application_helper.rb:1)
|
90
|
+
"""
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Given(/^I install the project gem locally$/) do
|
2
|
+
process_name = "gem build metasploit-yard.gemspec"
|
3
|
+
root = Pathname.new(__FILE__).parent.parent.parent
|
4
|
+
current_pathname = Pathname.new(current_dir).expand_path
|
5
|
+
root_relative_to_current = root.relative_path_from(current_pathname)
|
6
|
+
current_relative_to_root = current_pathname.relative_path_from(root)
|
7
|
+
|
8
|
+
cd(root_relative_to_current)
|
9
|
+
run_simple(process_name)
|
10
|
+
cd(current_relative_to_root)
|
11
|
+
|
12
|
+
gem_build_output = get_process(process_name).output
|
13
|
+
match = gem_build_output.match(/^ File: (?<gem_file>.*)$/)
|
14
|
+
|
15
|
+
unless match
|
16
|
+
fail "Cannot parse gem build output for built gem name:\n#{gem_build_output}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# need to include root as this is back in tmp/aruba
|
20
|
+
gem_pathname = root.join(match[:gem_file])
|
21
|
+
|
22
|
+
run_simple("gem install #{gem_pathname}")
|
23
|
+
|
24
|
+
gem_pathname.delete
|
25
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Before do
|
2
|
+
@gemsets_to_delete = []
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^I create a clean gemset "(.*?)"$/ do |gemset|
|
6
|
+
run_simple("rvm gemset create #{gemset}")
|
7
|
+
@gemsets_to_delete << gemset
|
8
|
+
end
|
9
|
+
|
10
|
+
Given /^I use gemset "(.*?)"$/ do |gemset|
|
11
|
+
current_rvm_env_process_name = 'rvm env'
|
12
|
+
run_simple(current_rvm_env_process_name)
|
13
|
+
current_rvm_env = get_process(current_rvm_env_process_name).stdout
|
14
|
+
current_parsed = Metasploit::Yard::Aruba::RvmEnv.parse(current_rvm_env)
|
15
|
+
|
16
|
+
new_rvm_env_process_name = "rvm @#{gemset} do rvm env"
|
17
|
+
run_simple(new_rvm_env_process_name)
|
18
|
+
new_rvm_env = get_process(new_rvm_env_process_name).stdout
|
19
|
+
new_parsed = Metasploit::Yard::Aruba::RvmEnv.parse(new_rvm_env)
|
20
|
+
|
21
|
+
Metasploit::Yard::Aruba::RvmEnv.change(
|
22
|
+
from: current_parsed,
|
23
|
+
to: new_parsed,
|
24
|
+
world: self
|
25
|
+
)
|
26
|
+
|
27
|
+
#
|
28
|
+
# Remove this gem's bin from path so the gemset is required to declare the gem as a dependency to get access to the
|
29
|
+
# bins
|
30
|
+
#
|
31
|
+
|
32
|
+
directories = ENV['PATH'].split(File::PATH_SEPARATOR)
|
33
|
+
directories.shift
|
34
|
+
path = directories.join(File::PATH_SEPARATOR)
|
35
|
+
|
36
|
+
set_env('PATH', path)
|
37
|
+
|
38
|
+
unset_bundler_env_vars
|
39
|
+
end
|
40
|
+
|
41
|
+
After('~@no-clobber') do
|
42
|
+
@gemsets_to_delete.each do |gemset|
|
43
|
+
# --force to prevent confirmation prompt
|
44
|
+
run_simple("rvm gemset delete --force #{gemset}")
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Project
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'metasploit/yard/version'
|
7
|
+
|
8
|
+
# The namespace shared between all gems related to
|
9
|
+
# [Metasploit Framework](https://github.com/rapid7/metasploit-framework) and
|
10
|
+
# [Metasploit Commercial Editions](https://metasploit.com)
|
11
|
+
module Metasploit
|
12
|
+
# Namespace for this gem.
|
13
|
+
module Yard
|
14
|
+
autoload :Aruba, 'metasploit/yard/aruba'
|
15
|
+
|
16
|
+
if defined?(Rails)
|
17
|
+
require 'metasploit/yard/railtie'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
#
|
2
|
+
# Gems
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'active_support/dependencies/autoload'
|
6
|
+
require 'active_support/core_ext/hash/keys'
|
7
|
+
|
8
|
+
#
|
9
|
+
# Project
|
10
|
+
#
|
11
|
+
|
12
|
+
# Helpers for parsing `rvm env` output
|
13
|
+
module Metasploit::Yard::Aruba::RvmEnv
|
14
|
+
extend ActiveSupport::Autoload
|
15
|
+
|
16
|
+
autoload :Export
|
17
|
+
autoload :Prepend
|
18
|
+
autoload :Unset
|
19
|
+
autoload :Variable
|
20
|
+
|
21
|
+
#
|
22
|
+
# CONSTANTS
|
23
|
+
#
|
24
|
+
|
25
|
+
# Class for parsing lines for `rvm env` in order of precedence
|
26
|
+
LINE_PARSER_PRECEDENCE = [
|
27
|
+
# must be before `Metasploit::Yard::Aruba::RvmEnv::Export` because
|
28
|
+
# `Metasploit::Yard::Aruba::RvmEnv::Export::REGEXP` matches a superset of
|
29
|
+
# `Metasploit::Yard::Aruba::RvmEnv::Prepend::REGEXP`
|
30
|
+
Metasploit::Yard::Aruba::RvmEnv::Prepend,
|
31
|
+
Metasploit::Yard::Aruba::RvmEnv::Export,
|
32
|
+
Metasploit::Yard::Aruba::RvmEnv::Unset
|
33
|
+
]
|
34
|
+
|
35
|
+
# Changes from one `rvm env [@<gemset>]` to another.
|
36
|
+
#
|
37
|
+
# @param options [Hash{Symbol => Array<Metasploit::Yard::Aruba::RvmEnv::Variable>}]
|
38
|
+
# @option options :from [Array<Metasploit::Yard::Aruba::RvmEnv::Variable>] the current rvm env; usually the output of
|
39
|
+
# parsing `rvm env`.
|
40
|
+
# @option options :to [Array<Metasploit::Yard::Aruba::RvmEnv::Variable>] the new rvm env; usualy the output of parsing
|
41
|
+
# `rvm env @<gemset>`
|
42
|
+
# @option options [Object] :world the cucumber World instance for the current scenario.
|
43
|
+
def self.change(options={})
|
44
|
+
options.assert_valid_keys(:from, :to, :world)
|
45
|
+
|
46
|
+
from_by_name = parsed_to_hash(options.fetch(:from))
|
47
|
+
to_by_name = parsed_to_hash(options.fetch(:to))
|
48
|
+
world = options.fetch(:world)
|
49
|
+
|
50
|
+
to_by_name.each do |name, to_variable|
|
51
|
+
from_variable = from_by_name[name]
|
52
|
+
|
53
|
+
# ignore variables that didn't change
|
54
|
+
unless to_variable == from_variable
|
55
|
+
to_variable.change(
|
56
|
+
from: from_variable,
|
57
|
+
world: world
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Parses the output of `rvm env`.
|
64
|
+
#
|
65
|
+
# @return [Array<Metasploit::Yard::Aruba::RvmEnv::Variable, #apply>]
|
66
|
+
def self.parse(rvm_env)
|
67
|
+
rvm_env.each_line.map { |line|
|
68
|
+
parse_line(line)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
# Parses an individual line of `rvm env`
|
73
|
+
#
|
74
|
+
# @return [Metasploit::Yard::Aruba::RvmEnv::Variable, #apply]
|
75
|
+
# @raise [ArgumentError] if no `Class` in {LINE_PARSER_PRECEDENCE} returns a parsed instance.
|
76
|
+
def self.parse_line(line)
|
77
|
+
parsed = nil
|
78
|
+
|
79
|
+
LINE_PARSER_PRECEDENCE.each do |line_parser|
|
80
|
+
parsed = line_parser.parse(line)
|
81
|
+
|
82
|
+
if parsed
|
83
|
+
break
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
unless parsed
|
88
|
+
raise ArgumentError, "No line parser could parse #{line.inspect}"
|
89
|
+
end
|
90
|
+
|
91
|
+
parsed
|
92
|
+
end
|
93
|
+
|
94
|
+
# Converts output of {parse} into Hash that maps {Metasploit::Yard::Aruba::RvmEnv::Variable#name} to the
|
95
|
+
# {Metasploit::Yard::Aruba::RvmEnv::Variable}.
|
96
|
+
#
|
97
|
+
# @param parsed [Array<Metasploit::Yard::Aruba::RvmEnv::Variable>] output of {parse}.
|
98
|
+
# @return [Hash{String => Metasploit::Yard::Aruba::RvmEnv::Variable}] Map of
|
99
|
+
# {Metasploit::Yard::Aruba::RvmEnv::Variable#name} to the {Metasploit::Yard::Aruba::RvmEnv::Variable}.
|
100
|
+
def self.parsed_to_hash(parsed)
|
101
|
+
parsed.each_with_object({}) { |variable, variable_by_name|
|
102
|
+
variable_by_name[variable.name] = variable
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Recognizes `export`s of a variable
|
2
|
+
class Metasploit::Yard::Aruba::RvmEnv::Export < Metasploit::Yard::Aruba::RvmEnv::Variable
|
3
|
+
#
|
4
|
+
# CONSTANTS
|
5
|
+
#
|
6
|
+
|
7
|
+
# Matches line with format `export <name>=<quote><value><quote>`
|
8
|
+
REGEXP = /\Aexport (?<name>\S+?)(\s+;\s+\k<name>)?=(?<quote>"|')(?<value>.*?)\k<quote>\Z/
|
9
|
+
|
10
|
+
#
|
11
|
+
# Attributes
|
12
|
+
#
|
13
|
+
|
14
|
+
# @!attribute value
|
15
|
+
# The value to which {Metasploit::Yard::Aruba::RvmEnv::Variable#name} should be set
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
attr_accessor :value
|
19
|
+
|
20
|
+
#
|
21
|
+
# Class Methods
|
22
|
+
#
|
23
|
+
|
24
|
+
# Parses line of `rvm env` output into an {Export} if it matches {REGEXP}.
|
25
|
+
#
|
26
|
+
# @param line [String] a line of `rvm env` output
|
27
|
+
# @return [Export] if line contains `export`.
|
28
|
+
# @return [nil] otherwise
|
29
|
+
def self.parse(line)
|
30
|
+
# use self:: so subclasses can override
|
31
|
+
match = self::REGEXP.match(line)
|
32
|
+
|
33
|
+
if match
|
34
|
+
new(
|
35
|
+
name: match[:name],
|
36
|
+
value: match[:value]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Instance Methods
|
43
|
+
#
|
44
|
+
|
45
|
+
# @param attributes [Hash{Symbol=>String}]
|
46
|
+
# @option attributes [String] :name (see Metasploit::Yard::Aruba::RvmEnv::Variable#name})
|
47
|
+
# @option attributes [String] :value (see #value)
|
48
|
+
def initialize(attributes={})
|
49
|
+
attributes.assert_valid_keys(:name, :value)
|
50
|
+
|
51
|
+
super(name: attributes[:name])
|
52
|
+
@value = attributes[:value]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Whether this export is the same class and has the same {#value} as `other`.
|
56
|
+
#
|
57
|
+
# @return [true] if `other.class` is `Metasploit::Yard::Aruba::RvmEnv::Export` and `other.value` is {#value}.
|
58
|
+
# @return [false] otherwise
|
59
|
+
def ==(other)
|
60
|
+
super(other) && other.value == self.value
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set {Metasploit::Yard::Aruba::RvmEnv::Variable#name} to {#value}.
|
64
|
+
#
|
65
|
+
# @param options [Hash{Symbol => Object}]
|
66
|
+
# @option options [Metasploit::Yard::Aruba::RvmEnv::Unset] :from the old state of this variable
|
67
|
+
# @option options [Object] :world the cucumber world instance for the current scenario
|
68
|
+
def change(options={})
|
69
|
+
options.assert_valid_keys(:from, :world)
|
70
|
+
|
71
|
+
world = options.fetch(:world)
|
72
|
+
|
73
|
+
world.set_env(name, value)
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Recognizes `export`s that are actually prepending values to the pre-existing value as is the case with `PATH`.
|
2
|
+
class Metasploit::Yard::Aruba::RvmEnv::Prepend < Metasploit::Yard::Aruba::RvmEnv::Export
|
3
|
+
#
|
4
|
+
# CONSTANTS
|
5
|
+
#
|
6
|
+
|
7
|
+
# Matches line with format `export <name>=<quote><value>$<name><quote>`. `<value>` will contain trailing
|
8
|
+
# `File::PATH_SEPARATOR`, so it can be directly prepended to the current value of `<name>` to get the value to set
|
9
|
+
# the environment variable.
|
10
|
+
REGEXP = /\Aexport (?<name>\S+?)(\s+;\s+\k<name>)?=(?<quote>"|')(?<value>.*?#{File::PATH_SEPARATOR})\$\k<name>\k<quote>\Z/
|
11
|
+
|
12
|
+
# Replaces {Metasploit::Yard::Aruba::RvmEnv::Export#value `:from` value} with
|
13
|
+
# {Metasploit::Yard::Aruba::RvmEnv::Export#value this variable's value}.
|
14
|
+
#
|
15
|
+
# @param options [Hash{Symbol => Object}]
|
16
|
+
# @option options [Metasploit::Yard::Aruba::RvmEnv::Unset] :from the old state of this variable.
|
17
|
+
# @option options [Object] :world the cucumber world instance for the current scenario
|
18
|
+
def change(options={})
|
19
|
+
options.assert_valid_keys(:from, :world)
|
20
|
+
|
21
|
+
from = options.fetch(:from)
|
22
|
+
world = options.fetch(:world)
|
23
|
+
|
24
|
+
from_directories = from.value.split(File::PATH_SEPARATOR)
|
25
|
+
to_directories = value.split(File::PATH_SEPARATOR)
|
26
|
+
|
27
|
+
path = ENV[name]
|
28
|
+
|
29
|
+
to_directories.zip(from_directories) do |to_directory, from_directory|
|
30
|
+
path = path.gsub(from_directory, to_directory)
|
31
|
+
end
|
32
|
+
|
33
|
+
world.set_env(name, path)
|
34
|
+
end
|
35
|
+
end
|