inspec 0.30.0 → 0.31.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -2
- data/Gemfile +2 -1
- data/docs/cli.rst +1 -17
- data/docs/resources.rst +128 -0
- data/docs/shell.rst +130 -0
- data/inspec.gemspec +3 -4
- data/lib/bundles/inspec-compliance/.kitchen.yml +0 -1
- data/lib/bundles/inspec-compliance/README.md +8 -3
- data/lib/bundles/inspec-compliance/api.rb +21 -6
- data/lib/bundles/inspec-compliance/bootstrap.sh +13 -9
- data/lib/bundles/inspec-compliance/cli.rb +23 -19
- data/lib/bundles/inspec-compliance/target.rb +1 -0
- data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +42 -5
- data/lib/bundles/inspec-init/cli.rb +9 -0
- data/lib/bundles/inspec-supermarket/cli.rb +9 -0
- data/lib/bundles/inspec-supermarket/target.rb +2 -1
- data/lib/fetchers/local.rb +5 -2
- data/lib/fetchers/url.rb +1 -0
- data/lib/inspec/base_cli.rb +2 -1
- data/lib/inspec/cli.rb +14 -5
- data/lib/inspec/dependencies/dependency_set.rb +38 -0
- data/lib/inspec/dependencies/requirement.rb +103 -0
- data/lib/inspec/{dependencies.rb → dependencies/resolver.rb} +13 -132
- data/lib/inspec/dependencies/vendor_index.rb +98 -0
- data/lib/inspec/plugins/source_reader.rb +4 -0
- data/lib/inspec/profile.rb +2 -2
- data/lib/inspec/resource.rb +2 -0
- data/lib/inspec/runner.rb +13 -1
- data/lib/inspec/runner_mock.rb +4 -0
- data/lib/inspec/runner_rspec.rb +6 -2
- data/lib/inspec/shell.rb +22 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/iis_site.rb +107 -0
- data/lib/resources/port.rb +11 -4
- data/lib/resources/ssh_conf.rb +10 -2
- data/lib/resources/ssl.rb +94 -0
- data/lib/resources/xinetd.rb +11 -2
- data/lib/utils/parser.rb +6 -1
- metadata +17 -561
- data/lib/utils/hash_map.rb +0 -37
- data/tasks/maintainers.rb +0 -213
- data/test/bench/startup/startup.flat.txt +0 -1005
- data/test/bench/startup/startup.graph.html +0 -71958
- data/test/bench/startup/startup.grind.dat +0 -101602
- data/test/bench/startup/startup.stack.html +0 -24516
- data/test/bench/startup.flat.txt +0 -998
- data/test/bench/startup.graph.html +0 -71420
- data/test/bench/startup.grind.dat +0 -103554
- data/test/bench/startup.stack.html +0 -25015
- data/test/cookbooks/os_prepare/attributes/default.rb +0 -2
- data/test/cookbooks/os_prepare/files/empty.iso +0 -0
- data/test/cookbooks/os_prepare/files/example.csv +0 -7
- data/test/cookbooks/os_prepare/files/example.ini +0 -6
- data/test/cookbooks/os_prepare/files/example.json +0 -12
- data/test/cookbooks/os_prepare/files/example.yml +0 -7
- data/test/cookbooks/os_prepare/metadata.rb +0 -13
- data/test/cookbooks/os_prepare/recipes/_runit_service_centos.rb +0 -34
- data/test/cookbooks/os_prepare/recipes/_upstart_service_centos.rb +0 -25
- data/test/cookbooks/os_prepare/recipes/apache.rb +0 -14
- data/test/cookbooks/os_prepare/recipes/apt.rb +0 -20
- data/test/cookbooks/os_prepare/recipes/auditctl.rb +0 -8
- data/test/cookbooks/os_prepare/recipes/default.rb +0 -29
- data/test/cookbooks/os_prepare/recipes/file.rb +0 -46
- data/test/cookbooks/os_prepare/recipes/iptables.rb +0 -13
- data/test/cookbooks/os_prepare/recipes/json_yaml_csv_ini.rb +0 -34
- data/test/cookbooks/os_prepare/recipes/mount.rb +0 -33
- data/test/cookbooks/os_prepare/recipes/package.rb +0 -25
- data/test/cookbooks/os_prepare/recipes/postgres.rb +0 -20
- data/test/cookbooks/os_prepare/recipes/prep_container.rb +0 -15
- data/test/cookbooks/os_prepare/recipes/registry_key.rb +0 -87
- data/test/cookbooks/os_prepare/recipes/service.rb +0 -19
- data/test/cookbooks/os_prepare/templates/default/sv-default-svlog-run.erb +0 -2
- data/test/docker_run.rb +0 -162
- data/test/docker_test.rb +0 -58
- data/test/functional/helper.rb +0 -37
- data/test/functional/inheritance_test.rb +0 -62
- data/test/functional/inspec_archive_test.rb +0 -80
- data/test/functional/inspec_compliance_test.rb +0 -61
- data/test/functional/inspec_exec_json_test.rb +0 -122
- data/test/functional/inspec_exec_jsonmin_test.rb +0 -59
- data/test/functional/inspec_exec_test.rb +0 -123
- data/test/functional/inspec_json_profile_test.rb +0 -103
- data/test/functional/inspec_test.rb +0 -91
- data/test/helper.rb +0 -329
- data/test/integration/default/_debug_spec.rb +0 -8
- data/test/integration/default/apache_conf_spec.rb +0 -21
- data/test/integration/default/apt_spec.rb +0 -37
- data/test/integration/default/auditd_rules_spec.rb +0 -32
- data/test/integration/default/cmp_matcher_spec.rb +0 -115
- data/test/integration/default/csv_spec.rb +0 -11
- data/test/integration/default/etc_group_spec.rb +0 -29
- data/test/integration/default/file_spec.rb +0 -195
- data/test/integration/default/group_spec.rb +0 -59
- data/test/integration/default/ini_spec.rb +0 -11
- data/test/integration/default/iptables_spec.rb +0 -29
- data/test/integration/default/json_spec.rb +0 -11
- data/test/integration/default/kernel_module_spec.rb +0 -23
- data/test/integration/default/kernel_parameter_spec.rb +0 -60
- data/test/integration/default/mount_spec.rb +0 -19
- data/test/integration/default/os_spec.rb +0 -13
- data/test/integration/default/package_spec.rb +0 -30
- data/test/integration/default/port_spec.rb +0 -27
- data/test/integration/default/postgres_session_spec.rb +0 -13
- data/test/integration/default/powershell_spec.rb +0 -42
- data/test/integration/default/registry_key_spec.rb +0 -109
- data/test/integration/default/secpol_spec.rb +0 -11
- data/test/integration/default/service_spec.rb +0 -128
- data/test/integration/default/user_spec.rb +0 -96
- data/test/integration/default/vbscript_spec.rb +0 -22
- data/test/integration/default/wmi_spec.rb +0 -66
- data/test/integration/default/yaml_spec.rb +0 -11
- data/test/resource/command_test.rb +0 -33
- data/test/resource/dsl_test.rb +0 -45
- data/test/resource/file_test.rb +0 -146
- data/test/resource/ssh_config.rb +0 -9
- data/test/resource/sshd_config.rb +0 -9
- data/test/test-extra.yaml +0 -11
- data/test/test.yaml +0 -11
- data/test/unit/control_test.rb +0 -58
- data/test/unit/fetchers/local_test.rb +0 -67
- data/test/unit/fetchers/mock_test.rb +0 -43
- data/test/unit/fetchers/tar_test.rb +0 -36
- data/test/unit/fetchers/url_test.rb +0 -152
- data/test/unit/fetchers/zip_test.rb +0 -36
- data/test/unit/fetchers_test.rb +0 -65
- data/test/unit/metadata_test.rb +0 -137
- data/test/unit/mock/cmd/$env-PATH +0 -1
- data/test/unit/mock/cmd/Get-NetAdapter +0 -24
- data/test/unit/mock/cmd/GetUserAccount +0 -33
- data/test/unit/mock/cmd/GetWin32Group +0 -23
- data/test/unit/mock/cmd/Resolve-DnsName +0 -26
- data/test/unit/mock/cmd/Test-NetConnection +0 -4
- data/test/unit/mock/cmd/auditctl +0 -3
- data/test/unit/mock/cmd/auditctl-legacy +0 -7
- data/test/unit/mock/cmd/auditctl-s +0 -8
- data/test/unit/mock/cmd/auditpol +0 -2
- data/test/unit/mock/cmd/brew-info-jq +0 -1
- data/test/unit/mock/cmd/chage-l-root +0 -7
- data/test/unit/mock/cmd/dpkg-s-curl +0 -21
- data/test/unit/mock/cmd/dscl +0 -5
- data/test/unit/mock/cmd/env +0 -1
- data/test/unit/mock/cmd/etc-apt +0 -7
- data/test/unit/mock/cmd/find-apache2-conf-enabled +0 -1
- data/test/unit/mock/cmd/find-apache2-ports-conf +0 -1
- data/test/unit/mock/cmd/find-etc-rc-d-name-S +0 -12
- data/test/unit/mock/cmd/find-net-interface +0 -9
- data/test/unit/mock/cmd/find-xinetd.d +0 -2
- data/test/unit/mock/cmd/gem-list-local-a-q-rubocop +0 -1
- data/test/unit/mock/cmd/get-net-tcpconnection +0 -24
- data/test/unit/mock/cmd/get-netadapter-binding-bridge +0 -4
- data/test/unit/mock/cmd/get-package-firefox +0 -30
- data/test/unit/mock/cmd/get-package-ruby +0 -18
- data/test/unit/mock/cmd/get-service-dhcp +0 -10
- data/test/unit/mock/cmd/get-windows-feature +0 -7
- data/test/unit/mock/cmd/get-wmiobject +0 -9
- data/test/unit/mock/cmd/getent-hosts-example.com +0 -1
- data/test/unit/mock/cmd/getent-passwd-jfolmer +0 -1
- data/test/unit/mock/cmd/getent-passwd-root +0 -1
- data/test/unit/mock/cmd/hpux-netstat-inet +0 -10
- data/test/unit/mock/cmd/hpux-netstat-inet6 +0 -11
- data/test/unit/mock/cmd/id-chartmann +0 -1
- data/test/unit/mock/cmd/id-jfolmer +0 -1
- data/test/unit/mock/cmd/id-root +0 -1
- data/test/unit/mock/cmd/initctl--version +0 -5
- data/test/unit/mock/cmd/initctl-show-config-ssh +0 -3
- data/test/unit/mock/cmd/initctl-status-ssh +0 -1
- data/test/unit/mock/cmd/iptables-s +0 -6
- data/test/unit/mock/cmd/launchctl-list +0 -3
- data/test/unit/mock/cmd/logins-x +0 -4
- data/test/unit/mock/cmd/ls-1-etc-init.d +0 -2
- data/test/unit/mock/cmd/ls-sys-class-net-br +0 -2
- data/test/unit/mock/cmd/lsmod +0 -2
- data/test/unit/mock/cmd/lsof-nP-i-FpctPn +0 -63
- data/test/unit/mock/cmd/mount +0 -1
- data/test/unit/mock/cmd/mount-multiple +0 -2
- data/test/unit/mock/cmd/netstat-an.utf8 +0 -13
- data/test/unit/mock/cmd/netstat-tulpen +0 -6
- data/test/unit/mock/cmd/npm-ls-g--json-bower +0 -9
- data/test/unit/mock/cmd/pacman-qi-curl +0 -21
- data/test/unit/mock/cmd/ping-example.com +0 -6
- data/test/unit/mock/cmd/pip-show-jinja2 +0 -11
- data/test/unit/mock/cmd/pkg-info-system-file-system-zfs +0 -8
- data/test/unit/mock/cmd/pkginfo-l-SUNWzfsr +0 -7
- data/test/unit/mock/cmd/ps-aux +0 -5
- data/test/unit/mock/cmd/ps-auxZ +0 -3
- data/test/unit/mock/cmd/pw-usershow-root-7 +0 -1
- data/test/unit/mock/cmd/reg_schedule +0 -6
- data/test/unit/mock/cmd/rpm-qia-curl +0 -24
- data/test/unit/mock/cmd/s11-netstat-an-finet-finet6 +0 -32
- data/test/unit/mock/cmd/sbin_sysctl +0 -1
- data/test/unit/mock/cmd/secedit-export +0 -7
- data/test/unit/mock/cmd/service-e +0 -2
- data/test/unit/mock/cmd/service-sendmail-onestatus +0 -3
- data/test/unit/mock/cmd/service-sshd-status +0 -1
- data/test/unit/mock/cmd/sockstat +0 -5
- data/test/unit/mock/cmd/success +0 -0
- data/test/unit/mock/cmd/swlist-l-product +0 -1
- data/test/unit/mock/cmd/systemctl-show-all-dbus +0 -6
- data/test/unit/mock/cmd/systemctl-show-all-sshd +0 -7
- data/test/unit/mock/cmd/win32_product +0 -8
- data/test/unit/mock/cmd/yum-repolist-all +0 -52
- data/test/unit/mock/files/apache2.conf +0 -14
- data/test/unit/mock/files/auditd.conf +0 -4
- data/test/unit/mock/files/bond0 +0 -37
- data/test/unit/mock/files/etcgroup +0 -3
- data/test/unit/mock/files/example.csv +0 -6
- data/test/unit/mock/files/grub.conf +0 -21
- data/test/unit/mock/files/inetd.conf +0 -2
- data/test/unit/mock/files/kitchen.yml +0 -7
- data/test/unit/mock/files/limits.conf +0 -5
- data/test/unit/mock/files/login.defs +0 -5
- data/test/unit/mock/files/mysql.conf +0 -8
- data/test/unit/mock/files/mysql2.conf +0 -2
- data/test/unit/mock/files/ntp.conf +0 -5
- data/test/unit/mock/files/passwd +0 -2
- data/test/unit/mock/files/policyfile.lock.json +0 -12
- data/test/unit/mock/files/ports.conf +0 -6
- data/test/unit/mock/files/rootwrap.conf +0 -7
- data/test/unit/mock/files/serve-cgi-bin.conf +0 -20
- data/test/unit/mock/files/shadow +0 -2
- data/test/unit/mock/files/ssh_config +0 -5
- data/test/unit/mock/files/sshd_config +0 -7
- data/test/unit/mock/files/sysctl.conf +0 -7
- data/test/unit/mock/files/xinetd.conf +0 -9
- data/test/unit/mock/files/xinetd.d/.gitkeep +0 -0
- data/test/unit/mock/files/xinetd.d_chargen-dgram +0 -9
- data/test/unit/mock/files/xinetd.d_chargen-stream +0 -9
- data/test/unit/mock/profiles/complete-metadata/inspec.yml +0 -7
- data/test/unit/mock/profiles/complete-profile/controls/filesystem_spec.rb +0 -16
- data/test/unit/mock/profiles/complete-profile/inspec.yml +0 -10
- data/test/unit/mock/profiles/complete-profile/libraries/testlib.rb +0 -1
- data/test/unit/mock/profiles/empty-metadata/inspec.yml +0 -0
- data/test/unit/mock/profiles/legacy-complete-metadata/metadata.rb +0 -7
- data/test/unit/mock/profiles/legacy-complete-metadata/test/.gitkeep +0 -0
- data/test/unit/mock/profiles/legacy-empty-metadata/controls/.gitkeep +0 -0
- data/test/unit/mock/profiles/legacy-empty-metadata/metadata.rb +0 -0
- data/test/unit/mock/profiles/legacy-simple-metadata/metadata.rb +0 -1
- data/test/unit/mock/profiles/legacy-simple-metadata/test/.gitkeep +0 -0
- data/test/unit/mock/profiles/library/controls/filesystem_spec.rb +0 -7
- data/test/unit/mock/profiles/library/inspec.yml +0 -10
- data/test/unit/mock/profiles/library/libraries/gordonlib.rb +0 -2
- data/test/unit/mock/profiles/library/libraries/testlib.rb +0 -12
- data/test/unit/mock/profiles/resource-tiny/inspec.yml +0 -10
- data/test/unit/mock/profiles/resource-tiny/libraries/resource.rb +0 -3
- data/test/unit/mock/profiles/simple-metadata/inspec.yml +0 -1
- data/test/unit/mock/profiles/skippy-profile-os/controls/one.rb +0 -3
- data/test/unit/mock/profiles/skippy-profile-os/inspec.yml +0 -5
- data/test/unit/mock/profiles/spec_only/specfile.rb +0 -11
- data/test/unit/mock/profiles/supported_inspec/inspec.yml +0 -2
- data/test/unit/mock/profiles/unsupported_inspec/inspec.yml +0 -2
- data/test/unit/objects_test.rb +0 -65
- data/test/unit/plugin_test.rb +0 -44
- data/test/unit/plugins/resource_test.rb +0 -60
- data/test/unit/profile_context_test.rb +0 -345
- data/test/unit/profile_test.rb +0 -252
- data/test/unit/resources/apache_conf_test.rb +0 -31
- data/test/unit/resources/apt_test.rb +0 -46
- data/test/unit/resources/audit_policy_test.rb +0 -13
- data/test/unit/resources/auditd_conf_test.rb +0 -15
- data/test/unit/resources/auditd_rules_test.rb +0 -91
- data/test/unit/resources/bash_test.rb +0 -29
- data/test/unit/resources/bond_test.rb +0 -24
- data/test/unit/resources/bridge_test.rb +0 -56
- data/test/unit/resources/csv_test.rb +0 -35
- data/test/unit/resources/etc_group_test.rb +0 -37
- data/test/unit/resources/file_test.rb +0 -202
- data/test/unit/resources/gem_test.rb +0 -20
- data/test/unit/resources/group_test.rb +0 -96
- data/test/unit/resources/grub_conf_test.rb +0 -29
- data/test/unit/resources/host_test.rb +0 -38
- data/test/unit/resources/inetd_conf_test.rb +0 -15
- data/test/unit/resources/ini_test.rb +0 -16
- data/test/unit/resources/interface_test.rb +0 -54
- data/test/unit/resources/iptables_test.rb +0 -35
- data/test/unit/resources/json_test.rb +0 -36
- data/test/unit/resources/kernel_module_test.rb +0 -23
- data/test/unit/resources/kernel_parameter_test.rb +0 -13
- data/test/unit/resources/limits_conf_test.rb +0 -14
- data/test/unit/resources/login_def_test.rb +0 -16
- data/test/unit/resources/mount_test.rb +0 -26
- data/test/unit/resources/mysql_conf_test.rb +0 -14
- data/test/unit/resources/npm_test.rb +0 -20
- data/test/unit/resources/ntp_conf_test.rb +0 -16
- data/test/unit/resources/oneget_test.rb +0 -45
- data/test/unit/resources/os_env_test.rb +0 -18
- data/test/unit/resources/os_test.rb +0 -40
- data/test/unit/resources/package_test.rb +0 -87
- data/test/unit/resources/parse_config_test.rb +0 -26
- data/test/unit/resources/passwd_test.rb +0 -111
- data/test/unit/resources/pip_test.rb +0 -15
- data/test/unit/resources/port_test.rb +0 -165
- data/test/unit/resources/powershell_test.rb +0 -32
- data/test/unit/resources/processes_test.rb +0 -72
- data/test/unit/resources/registry_key_test.rb +0 -18
- data/test/unit/resources/security_policy_test.rb +0 -16
- data/test/unit/resources/service_test.rb +0 -305
- data/test/unit/resources/shadow_test.rb +0 -67
- data/test/unit/resources/ssh_conf_test.rb +0 -33
- data/test/unit/resources/user_test.rb +0 -124
- data/test/unit/resources/vbscript_test.rb +0 -18
- data/test/unit/resources/windows_feature.rb +0 -17
- data/test/unit/resources/wmi_test.rb +0 -42
- data/test/unit/resources/xinetd_test.rb +0 -60
- data/test/unit/resources/yaml_test.rb +0 -34
- data/test/unit/resources/yum_test.rb +0 -68
- data/test/unit/shell_detector_test.rb +0 -78
- data/test/unit/source_reader_test.rb +0 -17
- data/test/unit/source_readers/flat_test.rb +0 -61
- data/test/unit/source_readers/inspec_test.rb +0 -38
- data/test/unit/utils/filter_array_test.rb +0 -59
- data/test/unit/utils/filter_table_test.rb +0 -177
- data/test/unit/utils/find_files_test.rb +0 -23
- data/test/unit/utils/passwd_parser_test.rb +0 -32
- data/test/unit/utils/simpleconfig_test.rb +0 -80
- data/test/unit/utils/solaris_netstat_parser.rb +0 -124
data/lib/inspec/runner.rb
CHANGED
@@ -66,6 +66,7 @@ module Inspec
|
|
66
66
|
options['attributes'] = attributes
|
67
67
|
end
|
68
68
|
|
69
|
+
# Returns the profile context used the profile at this target.
|
69
70
|
def add_target(target, options = {})
|
70
71
|
profile = Inspec::Profile.for_target(target, options)
|
71
72
|
fail "Could not resolve #{target} to valid input." if profile.nil?
|
@@ -89,6 +90,7 @@ module Inspec
|
|
89
90
|
true
|
90
91
|
end
|
91
92
|
|
93
|
+
# Returns the profile context used to initialize this profile.
|
92
94
|
def add_profile(profile, options = {})
|
93
95
|
return if !options[:ignore_supports] && !supports_profile?(profile)
|
94
96
|
|
@@ -115,6 +117,8 @@ module Inspec
|
|
115
117
|
Inspec::ProfileContext.new(profile_id, @backend, @conf.merge(options))
|
116
118
|
end
|
117
119
|
|
120
|
+
# Returns the profile context used to evaluate the given content.
|
121
|
+
# Calling this method again will use a different context each time.
|
118
122
|
def add_content(tests, libs, options = {})
|
119
123
|
return if tests.nil? || tests.empty?
|
120
124
|
|
@@ -127,21 +131,29 @@ module Inspec
|
|
127
131
|
profile.runner_context = ctx
|
128
132
|
end
|
129
133
|
|
134
|
+
append_content(ctx, tests, libs, options)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Returns the profile context used to evaluate the given content.
|
138
|
+
def append_content(ctx, tests, _libs, options = {})
|
130
139
|
# evaluate the test content
|
131
140
|
tests = [tests] unless tests.is_a? Array
|
132
141
|
tests.each { |t| add_test_to_context(t, ctx) }
|
133
142
|
|
134
|
-
# merge
|
143
|
+
# merge and collect all attributes
|
135
144
|
@attributes |= ctx.attributes
|
136
145
|
|
137
146
|
# process the resulting rules
|
138
147
|
filter_controls(ctx.rules, options[:controls]).each do |rule_id, rule|
|
139
148
|
register_rule(rule_id, rule)
|
140
149
|
end
|
150
|
+
|
151
|
+
ctx
|
141
152
|
end
|
142
153
|
|
143
154
|
def_delegator :@test_collector, :run
|
144
155
|
def_delegator :@test_collector, :report
|
156
|
+
def_delegator :@test_collector, :reset
|
145
157
|
|
146
158
|
private
|
147
159
|
|
data/lib/inspec/runner_mock.rb
CHANGED
data/lib/inspec/runner_rspec.rb
CHANGED
@@ -15,6 +15,10 @@ module Inspec
|
|
15
15
|
def initialize(conf)
|
16
16
|
@conf = conf
|
17
17
|
@formatter = nil
|
18
|
+
reset
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset
|
18
22
|
reset_tests
|
19
23
|
configure_output
|
20
24
|
end
|
@@ -87,8 +91,6 @@ module Inspec
|
|
87
91
|
reporter.output_hash
|
88
92
|
end
|
89
93
|
|
90
|
-
private
|
91
|
-
|
92
94
|
# Empty the list of registered tests.
|
93
95
|
#
|
94
96
|
# @return [nil]
|
@@ -98,6 +100,8 @@ module Inspec
|
|
98
100
|
RSpec.configuration.reset
|
99
101
|
end
|
100
102
|
|
103
|
+
private
|
104
|
+
|
101
105
|
FORMATTERS = {
|
102
106
|
'json-min' => 'InspecRspecMiniJson',
|
103
107
|
'json' => 'InspecRspecJson',
|
data/lib/inspec/shell.rb
CHANGED
@@ -5,6 +5,9 @@
|
|
5
5
|
require 'rspec/core/formatters/base_text_formatter'
|
6
6
|
|
7
7
|
module Inspec
|
8
|
+
# A pry based shell for inspec. Given a runner (with a configured backend and
|
9
|
+
# all that jazz), this shell will produce a pry shell from which you can run
|
10
|
+
# inspec/ruby commands that will be run within the context of the runner.
|
8
11
|
class Shell
|
9
12
|
def initialize(runner)
|
10
13
|
@runner = runner
|
@@ -17,7 +20,6 @@ module Inspec
|
|
17
20
|
# store context to run commands in this context
|
18
21
|
c = { content: 'binding.pry', ref: nil, line: nil }
|
19
22
|
@runner.add_content(c, [])
|
20
|
-
@runner.run
|
21
23
|
end
|
22
24
|
|
23
25
|
def configure_pry
|
@@ -38,6 +40,25 @@ module Inspec
|
|
38
40
|
Pry.hooks.add_hook(:before_session, :intro) do
|
39
41
|
intro
|
40
42
|
end
|
43
|
+
|
44
|
+
# execute describe blocks
|
45
|
+
Pry.hooks.add_hook(:after_eval, 'run_controls') do |output, _binding, _pry_|
|
46
|
+
next unless output.is_a?(Inspec::Rule)
|
47
|
+
# reset tests, register the control and execute the runner
|
48
|
+
@runner.reset
|
49
|
+
@runner.method(:register_rule).call(output.id, output)
|
50
|
+
@runner.run
|
51
|
+
end
|
52
|
+
|
53
|
+
# Don't print out control class inspection when the user uses DSL methods.
|
54
|
+
# Instead produce a result of evaluating their control.
|
55
|
+
Pry.config.print = proc do |_output, value, pry_|
|
56
|
+
next if value.is_a?(Inspec::Rule)
|
57
|
+
pry_.pager.open do |pager|
|
58
|
+
pager.print pry_.config.output_prefix
|
59
|
+
Pry::ColorPrinter.pp(value, pager, Pry::Terminal.width! - 1)
|
60
|
+
end
|
61
|
+
end
|
41
62
|
end
|
42
63
|
|
43
64
|
def readline_ignore(code)
|
data/lib/inspec/version.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# check for site in IIS
|
3
|
+
# Usage:
|
4
|
+
# describe iis_site('Default Web Site') do
|
5
|
+
# it{ should exist }
|
6
|
+
# it{ should be_running }
|
7
|
+
# it{ should be_in_app_pool('Default App Pool') }
|
8
|
+
# it{ should have_path('C:\\inetpub\wwwroot\\DefaultWebSite') }
|
9
|
+
# it{ should have_binding('https :443:www.contoso.com sslFlags=0') }
|
10
|
+
# it{ should have_binding('net.pipe *') }
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Note: this is only supported in windows 2012 and later
|
14
|
+
|
15
|
+
module Inspec::Resources
|
16
|
+
class IisSite < Inspec.resource(1)
|
17
|
+
name 'iis_site'
|
18
|
+
desc 'Tests IIS site configuration on windows. Supported in server 2012+ only'
|
19
|
+
example "
|
20
|
+
describe iis_site('Default Web Site') do
|
21
|
+
it { should exist }
|
22
|
+
it { should be_running }
|
23
|
+
it { should have_app_pool('DefaultAppPool') }
|
24
|
+
it { should have_binding('https :443:www.contoso.com sslFlags=0') }
|
25
|
+
it { should have_binding('net.pipe *') }
|
26
|
+
it { should have_path('C:\\inetpub\\wwwroot') }
|
27
|
+
end
|
28
|
+
"
|
29
|
+
|
30
|
+
def initialize(site_name)
|
31
|
+
@site_name = site_name
|
32
|
+
@cache = nil
|
33
|
+
|
34
|
+
@site_provider = SiteProvider.new(inspec)
|
35
|
+
|
36
|
+
# verify that this resource is only supported on Windows
|
37
|
+
return skip_resource 'The `iis_site` resource is not supported on your OS.' if inspec.os[:family] != 'windows'
|
38
|
+
end
|
39
|
+
|
40
|
+
def exists?
|
41
|
+
!iis_site.nil? && !iis_site[:name].nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
def running?
|
45
|
+
iis_site.nil? ? false : (iis_site[:state] == 'Started')
|
46
|
+
end
|
47
|
+
|
48
|
+
def has_app_pool?(app_pool)
|
49
|
+
iis_site.nil? ? false : iis_site[:app_pool] == app_pool
|
50
|
+
end
|
51
|
+
|
52
|
+
def has_path?(path)
|
53
|
+
iis_site.nil? ? false : iis_site[:path] == path
|
54
|
+
end
|
55
|
+
|
56
|
+
def has_binding?(binding)
|
57
|
+
iis_site.nil? ? false : (iis_site[:bindings].include? binding)
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_s
|
61
|
+
"iis_site '#{@site_name}'"
|
62
|
+
end
|
63
|
+
|
64
|
+
def iis_site
|
65
|
+
return @cache if !@cache.nil?
|
66
|
+
@cache = @site_provider.iis_site(@site_name) if !@site_provider.nil?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class SiteProvider
|
71
|
+
attr_reader :inspec
|
72
|
+
|
73
|
+
def initialize(inspec)
|
74
|
+
@inspec = inspec
|
75
|
+
end
|
76
|
+
|
77
|
+
# want to populate everything using one powershell command here and spit it out as json
|
78
|
+
def iis_site(name)
|
79
|
+
command = "Get-Website '#{name}' | select-object -Property Name,State,PhysicalPath,bindings,ApplicationPool | ConvertTo-Json"
|
80
|
+
cmd = @inspec.command(command)
|
81
|
+
|
82
|
+
begin
|
83
|
+
site = JSON.parse(cmd.stdout)
|
84
|
+
rescue JSON::ParserError => _e
|
85
|
+
return nil
|
86
|
+
end
|
87
|
+
|
88
|
+
bindings_array = site['bindings']['Collection'].map { |k, _str|
|
89
|
+
k['protocol'] <<
|
90
|
+
' ' <<
|
91
|
+
k['bindingInformation'] <<
|
92
|
+
(k['protocol'] == 'https' ? ' sslFlags=' << flags : '')
|
93
|
+
}
|
94
|
+
|
95
|
+
# map our values to a hash table
|
96
|
+
info = {
|
97
|
+
name: site['name'],
|
98
|
+
state: site['state'],
|
99
|
+
path: site['physicalPath'],
|
100
|
+
bindings: bindings_array,
|
101
|
+
app_pool: site['applicationPool'],
|
102
|
+
}
|
103
|
+
|
104
|
+
info
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/resources/port.rb
CHANGED
@@ -122,13 +122,13 @@ module Inspec::Resources
|
|
122
122
|
# @see https://connect.microsoft.com/PowerShell/feedback/details/1349420/get-nettcpconnection-does-not-show-processid
|
123
123
|
class WindowsPorts < PortsInfo
|
124
124
|
def info
|
125
|
-
|
125
|
+
netstat_info || powershell_info
|
126
126
|
end
|
127
127
|
|
128
128
|
private
|
129
129
|
|
130
130
|
def powershell_info
|
131
|
-
cmd = inspec.command('Get-NetTCPConnection | Select-Object -Property State, Caption, Description, LocalAddress, LocalPort, RemoteAddress, RemotePort, DisplayName, Status | ConvertTo-Json')
|
131
|
+
cmd = inspec.command('Get-NetTCPConnection -state Listen | Select-Object -Property State, Caption, Description, LocalAddress, LocalPort, RemoteAddress, RemotePort, DisplayName, Status | ConvertTo-Json')
|
132
132
|
return nil if cmd.exit_status != 0
|
133
133
|
|
134
134
|
entries = JSON.parse(cmd.stdout)
|
@@ -146,14 +146,21 @@ module Inspec::Resources
|
|
146
146
|
end
|
147
147
|
|
148
148
|
def netstat_info
|
149
|
-
|
149
|
+
# retrieve processes grepping by LISTENING state with 0 lines before and 1 after to catch the process name
|
150
|
+
# also UDP ports have nothing in the State column
|
151
|
+
cmd = inspec.command('netstat -anbo | Select-String -CaseSensitive -pattern "^\s+UDP|\s+LISTENING\s+\d+$" -context 0,1')
|
150
152
|
return nil if cmd.exit_status != 0
|
151
|
-
lines = cmd.stdout.scan(
|
153
|
+
lines = cmd.stdout.scan(/^>\s*(tcp\S*|udp\S*)\s+(\S+):(\d+)\s+(\S+)\s+(\S*)\s+(\d+)\s+(.+)/i)
|
152
154
|
lines.map do |line|
|
155
|
+
pid = line[5].to_i
|
156
|
+
process = line[6].delete('[').delete(']').strip
|
157
|
+
process = 'System' if process == 'Can not obtain ownership information' && pid == 4
|
153
158
|
{
|
154
159
|
'port' => line[2].to_i,
|
155
160
|
'address' => line[1].delete('[').delete(']'),
|
156
161
|
'protocol' => line[0].downcase,
|
162
|
+
'pid' => pid,
|
163
|
+
'process' => process,
|
157
164
|
}
|
158
165
|
end
|
159
166
|
end
|
data/lib/resources/ssh_conf.rb
CHANGED
@@ -32,8 +32,16 @@ module Inspec::Resources
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
def convert_hash(hash)
|
36
|
+
new_hash = {}
|
37
|
+
hash.each do |k, v|
|
38
|
+
new_hash[k.downcase] = v
|
39
|
+
end
|
40
|
+
new_hash
|
41
|
+
end
|
42
|
+
|
35
43
|
def method_missing(name)
|
36
|
-
param = read_params[name.to_s]
|
44
|
+
param = read_params[name.to_s.downcase]
|
37
45
|
return nil if param.nil?
|
38
46
|
# extract first value if we have only one value in array
|
39
47
|
return param[0] if param.length == 1
|
@@ -69,7 +77,7 @@ module Inspec::Resources
|
|
69
77
|
assignment_re: /^\s*(\S+?)\s+(.*?)\s*$/,
|
70
78
|
multiple_values: true,
|
71
79
|
)
|
72
|
-
@params = conf.params
|
80
|
+
@params = convert_hash(conf.params)
|
73
81
|
end
|
74
82
|
end
|
75
83
|
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# copyright: 2015, Chef Software Inc.
|
3
|
+
# license: All rights reserved
|
4
|
+
# author: Dominik Richter
|
5
|
+
# author: Christoph Hartmann
|
6
|
+
|
7
|
+
require 'sslshake'
|
8
|
+
require 'utils/filter'
|
9
|
+
|
10
|
+
# Custom resource based on the InSpec resource DSL
|
11
|
+
class SSL < Inspec.resource(1)
|
12
|
+
name 'ssl'
|
13
|
+
|
14
|
+
desc "
|
15
|
+
SSL test resource
|
16
|
+
"
|
17
|
+
|
18
|
+
example "
|
19
|
+
describe ssl(port: 443) do
|
20
|
+
it { should be_enabled }
|
21
|
+
end
|
22
|
+
|
23
|
+
# protocols: ssl2, ssl3, tls1.0, tls1.1, tls1.2
|
24
|
+
describe ssl(port: 443).protocols('ssl2') do
|
25
|
+
it { should_not be_enabled }
|
26
|
+
end
|
27
|
+
|
28
|
+
# any ciphers, filter by name or regex
|
29
|
+
describe ssl(port: 443).ciphers(/rc4/i) do
|
30
|
+
it { should_not be_enabled }
|
31
|
+
end
|
32
|
+
"
|
33
|
+
|
34
|
+
VERSIONS = [
|
35
|
+
'ssl2',
|
36
|
+
'ssl3',
|
37
|
+
'tls1.0',
|
38
|
+
'tls1.1',
|
39
|
+
'tls1.2',
|
40
|
+
].freeze
|
41
|
+
|
42
|
+
attr_reader :host, :port
|
43
|
+
|
44
|
+
def initialize(opts = {})
|
45
|
+
@host = opts[:host] ||
|
46
|
+
inspec.backend.instance_variable_get(:@hostname)
|
47
|
+
if @host.nil? && inspec.backend.class.to_s == 'Train::Transports::Local::Connection'
|
48
|
+
@host = 'localhost'
|
49
|
+
end
|
50
|
+
if @host.nil?
|
51
|
+
fail 'Cannot determine host for SSL test. Please specify it or use a different target.'
|
52
|
+
end
|
53
|
+
@port = opts[:port] || 443
|
54
|
+
@timeout = opts[:timeout]
|
55
|
+
@retries = opts[:retries]
|
56
|
+
end
|
57
|
+
|
58
|
+
filter = FilterTable.create
|
59
|
+
filter.add_accessor(:where)
|
60
|
+
.add_accessor(:entries)
|
61
|
+
.add(:ciphers, field: 'cipher')
|
62
|
+
.add(:protocols, field: 'protocol')
|
63
|
+
.add(:enabled?) { |x| x.handshake.values.any? { |i| i['success'] } }
|
64
|
+
.add(:handshake) { |x|
|
65
|
+
groups = x.entries.group_by(&:protocol)
|
66
|
+
res = groups.map do |proto, e|
|
67
|
+
[proto, SSLShake.hello(x.resource.host, port: x.resource.port,
|
68
|
+
protocol: proto, ciphers: e.map(&:cipher),
|
69
|
+
timeout: @timeout, retries: @retries)]
|
70
|
+
end
|
71
|
+
Hash[res]
|
72
|
+
}
|
73
|
+
.connect(self, :scan_config)
|
74
|
+
|
75
|
+
def to_s
|
76
|
+
"SSL/TLS on #{@host}:#{@port}"
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def scan_config
|
82
|
+
[
|
83
|
+
{ 'protocol' => 'ssl2', 'ciphers' => SSLShake::SSLv2::CIPHERS.keys },
|
84
|
+
{ 'protocol' => 'ssl3', 'ciphers' => SSLShake::TLS::SSL3_CIPHERS.keys },
|
85
|
+
{ 'protocol' => 'tls1.0', 'ciphers' => SSLShake::TLS::TLS10_CIPHERS.keys },
|
86
|
+
{ 'protocol' => 'tls1.1', 'ciphers' => SSLShake::TLS::TLS10_CIPHERS.keys },
|
87
|
+
{ 'protocol' => 'tls1.2', 'ciphers' => SSLShake::TLS::TLS_CIPHERS.keys },
|
88
|
+
].map do |line|
|
89
|
+
line['ciphers'].map do |cipher|
|
90
|
+
{ 'protocol' => line['protocol'], 'cipher' => cipher }
|
91
|
+
end
|
92
|
+
end.flatten
|
93
|
+
end
|
94
|
+
end
|
data/lib/resources/xinetd.rb
CHANGED
@@ -66,17 +66,26 @@ module Inspec::Resources
|
|
66
66
|
def read_params
|
67
67
|
return {} if read_content.nil?
|
68
68
|
flat_params = parse_xinetd(read_content)
|
69
|
+
# we need to map service data in order to use it with filtertable
|
69
70
|
params = { 'services' => {} }
|
70
71
|
|
71
|
-
#
|
72
|
+
# map services that were defined and map it to the service hash
|
72
73
|
flat_params.each do |k, v|
|
73
74
|
name = k[/^service (.+)$/, 1]
|
75
|
+
# its not a service, no change required
|
74
76
|
if name.nil?
|
75
77
|
params[k] = v
|
78
|
+
# handle service entries
|
76
79
|
else
|
80
|
+
# store service
|
77
81
|
params['services'][name] = v
|
82
|
+
|
78
83
|
# add the service identifier to its parameters
|
79
|
-
v.
|
84
|
+
if v.is_a?(Array)
|
85
|
+
v.each { |service| service.params['service'] = name }
|
86
|
+
else
|
87
|
+
v.params['service'] = name
|
88
|
+
end
|
80
89
|
end
|
81
90
|
end
|
82
91
|
params
|
data/lib/utils/parser.rb
CHANGED
@@ -9,8 +9,9 @@ module PasswdParser
|
|
9
9
|
# @return [Array] Collection of passwd entries
|
10
10
|
def parse_passwd(content)
|
11
11
|
content.to_s.split("\n").map do |line|
|
12
|
+
next if line[0] == '#'
|
12
13
|
parse_passwd_line(line)
|
13
|
-
end
|
14
|
+
end.compact
|
14
15
|
end
|
15
16
|
|
16
17
|
# Parse a line of /etc/passwd
|
@@ -178,6 +179,7 @@ module SolarisNetstatParser
|
|
178
179
|
end
|
179
180
|
end
|
180
181
|
|
182
|
+
# This parser for xinetd (extended Internet daemon) configuration files
|
181
183
|
module XinetdParser
|
182
184
|
def xinetd_include_dir(dir)
|
183
185
|
return [] if dir.nil?
|
@@ -197,10 +199,12 @@ module XinetdParser
|
|
197
199
|
simple_conf = []
|
198
200
|
rest = raw
|
199
201
|
until rest.empty?
|
202
|
+
# extract content line
|
200
203
|
nl = rest.index("\n") || (rest.length-1)
|
201
204
|
comment = rest.index('#') || (rest.length-1)
|
202
205
|
dst_idx = (comment < nl) ? comment : nl
|
203
206
|
inner_line = (dst_idx == 0) ? '' : rest[0..dst_idx-1].strip
|
207
|
+
# update unparsed content
|
204
208
|
rest = rest[nl+1..-1]
|
205
209
|
next if inner_line.empty?
|
206
210
|
|
@@ -212,6 +216,7 @@ module XinetdParser
|
|
212
216
|
simple_conf = []
|
213
217
|
rest = rest[rest.index("\n")+1..-1]
|
214
218
|
elsif cur_group.nil?
|
219
|
+
# parse all included files
|
215
220
|
others = xinetd_include_dir(inner_line[/includedir (.+)/, 1])
|
216
221
|
|
217
222
|
# complex merging of included configurations, as multiple services
|