inspec 0.30.0 → 0.31.0
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 +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
|