inspec-core 2.1.67
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/CHANGELOG.md +3136 -0
- data/Gemfile +56 -0
- data/LICENSE +14 -0
- data/MAINTAINERS.md +33 -0
- data/MAINTAINERS.toml +52 -0
- data/README.md +453 -0
- data/bin/inspec +12 -0
- data/docs/.gitignore +2 -0
- data/docs/README.md +40 -0
- data/docs/dev/control-eval.md +62 -0
- data/docs/dsl_inspec.md +258 -0
- data/docs/dsl_resource.md +100 -0
- data/docs/glossary.md +99 -0
- data/docs/habitat.md +192 -0
- data/docs/inspec_and_friends.md +114 -0
- data/docs/matchers.md +169 -0
- data/docs/migration.md +293 -0
- data/docs/platforms.md +119 -0
- data/docs/plugin_kitchen_inspec.md +50 -0
- data/docs/profiles.md +378 -0
- data/docs/reporters.md +105 -0
- data/docs/resources/aide_conf.md.erb +76 -0
- data/docs/resources/apache.md.erb +67 -0
- data/docs/resources/apache_conf.md.erb +68 -0
- data/docs/resources/apt.md.erb +71 -0
- data/docs/resources/audit_policy.md.erb +47 -0
- data/docs/resources/auditd.md.erb +79 -0
- data/docs/resources/auditd_conf.md.erb +68 -0
- data/docs/resources/bash.md.erb +75 -0
- data/docs/resources/bond.md.erb +90 -0
- data/docs/resources/bridge.md.erb +57 -0
- data/docs/resources/bsd_service.md.erb +67 -0
- data/docs/resources/chocolatey_package.md.erb +58 -0
- data/docs/resources/command.md.erb +138 -0
- data/docs/resources/cpan.md.erb +79 -0
- data/docs/resources/cran.md.erb +64 -0
- data/docs/resources/crontab.md.erb +89 -0
- data/docs/resources/csv.md.erb +54 -0
- data/docs/resources/dh_params.md.erb +205 -0
- data/docs/resources/directory.md.erb +30 -0
- data/docs/resources/docker.md.erb +219 -0
- data/docs/resources/docker_container.md.erb +103 -0
- data/docs/resources/docker_image.md.erb +94 -0
- data/docs/resources/docker_service.md.erb +114 -0
- data/docs/resources/elasticsearch.md.erb +242 -0
- data/docs/resources/etc_fstab.md.erb +125 -0
- data/docs/resources/etc_group.md.erb +75 -0
- data/docs/resources/etc_hosts.md.erb +78 -0
- data/docs/resources/etc_hosts_allow.md.erb +74 -0
- data/docs/resources/etc_hosts_deny.md.erb +74 -0
- data/docs/resources/file.md.erb +526 -0
- data/docs/resources/filesystem.md.erb +41 -0
- data/docs/resources/firewalld.md.erb +107 -0
- data/docs/resources/gem.md.erb +79 -0
- data/docs/resources/group.md.erb +61 -0
- data/docs/resources/grub_conf.md.erb +101 -0
- data/docs/resources/host.md.erb +86 -0
- data/docs/resources/http.md.erb +197 -0
- data/docs/resources/iis_app.md.erb +122 -0
- data/docs/resources/iis_site.md.erb +135 -0
- data/docs/resources/inetd_conf.md.erb +94 -0
- data/docs/resources/ini.md.erb +76 -0
- data/docs/resources/interface.md.erb +58 -0
- data/docs/resources/iptables.md.erb +64 -0
- data/docs/resources/json.md.erb +63 -0
- data/docs/resources/kernel_module.md.erb +120 -0
- data/docs/resources/kernel_parameter.md.erb +53 -0
- data/docs/resources/key_rsa.md.erb +85 -0
- data/docs/resources/launchd_service.md.erb +57 -0
- data/docs/resources/limits_conf.md.erb +75 -0
- data/docs/resources/login_defs.md.erb +71 -0
- data/docs/resources/mount.md.erb +69 -0
- data/docs/resources/mssql_session.md.erb +60 -0
- data/docs/resources/mysql_conf.md.erb +99 -0
- data/docs/resources/mysql_session.md.erb +74 -0
- data/docs/resources/nginx.md.erb +79 -0
- data/docs/resources/nginx_conf.md.erb +138 -0
- data/docs/resources/npm.md.erb +60 -0
- data/docs/resources/ntp_conf.md.erb +60 -0
- data/docs/resources/oneget.md.erb +53 -0
- data/docs/resources/oracledb_session.md.erb +52 -0
- data/docs/resources/os.md.erb +141 -0
- data/docs/resources/os_env.md.erb +91 -0
- data/docs/resources/package.md.erb +120 -0
- data/docs/resources/packages.md.erb +67 -0
- data/docs/resources/parse_config.md.erb +103 -0
- data/docs/resources/parse_config_file.md.erb +138 -0
- data/docs/resources/passwd.md.erb +141 -0
- data/docs/resources/pip.md.erb +67 -0
- data/docs/resources/port.md.erb +137 -0
- data/docs/resources/postgres_conf.md.erb +79 -0
- data/docs/resources/postgres_hba_conf.md.erb +93 -0
- data/docs/resources/postgres_ident_conf.md.erb +76 -0
- data/docs/resources/postgres_session.md.erb +69 -0
- data/docs/resources/powershell.md.erb +102 -0
- data/docs/resources/processes.md.erb +109 -0
- data/docs/resources/rabbitmq_config.md.erb +41 -0
- data/docs/resources/registry_key.md.erb +158 -0
- data/docs/resources/runit_service.md.erb +57 -0
- data/docs/resources/security_policy.md.erb +47 -0
- data/docs/resources/service.md.erb +121 -0
- data/docs/resources/shadow.md.erb +146 -0
- data/docs/resources/ssh_config.md.erb +73 -0
- data/docs/resources/sshd_config.md.erb +83 -0
- data/docs/resources/ssl.md.erb +119 -0
- data/docs/resources/sys_info.md.erb +42 -0
- data/docs/resources/systemd_service.md.erb +57 -0
- data/docs/resources/sysv_service.md.erb +57 -0
- data/docs/resources/upstart_service.md.erb +57 -0
- data/docs/resources/user.md.erb +140 -0
- data/docs/resources/users.md.erb +127 -0
- data/docs/resources/vbscript.md.erb +55 -0
- data/docs/resources/virtualization.md.erb +57 -0
- data/docs/resources/windows_feature.md.erb +47 -0
- data/docs/resources/windows_hotfix.md.erb +53 -0
- data/docs/resources/windows_task.md.erb +95 -0
- data/docs/resources/wmi.md.erb +81 -0
- data/docs/resources/x509_certificate.md.erb +151 -0
- data/docs/resources/xinetd_conf.md.erb +156 -0
- data/docs/resources/xml.md.erb +85 -0
- data/docs/resources/yaml.md.erb +69 -0
- data/docs/resources/yum.md.erb +98 -0
- data/docs/resources/zfs_dataset.md.erb +53 -0
- data/docs/resources/zfs_pool.md.erb +47 -0
- data/docs/ruby_usage.md +203 -0
- data/docs/shared/matcher_be.md.erb +1 -0
- data/docs/shared/matcher_cmp.md.erb +43 -0
- data/docs/shared/matcher_eq.md.erb +3 -0
- data/docs/shared/matcher_include.md.erb +1 -0
- data/docs/shared/matcher_match.md.erb +1 -0
- data/docs/shell.md +217 -0
- data/examples/README.md +8 -0
- data/examples/inheritance/README.md +65 -0
- data/examples/inheritance/controls/example.rb +14 -0
- data/examples/inheritance/inspec.yml +15 -0
- data/examples/kitchen-ansible/.kitchen.yml +25 -0
- data/examples/kitchen-ansible/Gemfile +19 -0
- data/examples/kitchen-ansible/README.md +53 -0
- data/examples/kitchen-ansible/files/nginx.repo +6 -0
- data/examples/kitchen-ansible/tasks/main.yml +16 -0
- data/examples/kitchen-ansible/test/integration/default/default.yml +5 -0
- data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-chef/.kitchen.yml +20 -0
- data/examples/kitchen-chef/Berksfile +3 -0
- data/examples/kitchen-chef/Gemfile +19 -0
- data/examples/kitchen-chef/README.md +27 -0
- data/examples/kitchen-chef/metadata.rb +7 -0
- data/examples/kitchen-chef/recipes/default.rb +6 -0
- data/examples/kitchen-chef/recipes/nginx.rb +30 -0
- data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-puppet/.kitchen.yml +23 -0
- data/examples/kitchen-puppet/Gemfile +20 -0
- data/examples/kitchen-puppet/Puppetfile +25 -0
- data/examples/kitchen-puppet/README.md +53 -0
- data/examples/kitchen-puppet/manifests/site.pp +33 -0
- data/examples/kitchen-puppet/metadata.json +11 -0
- data/examples/kitchen-puppet/modules/.gitkeep +0 -0
- data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -0
- data/examples/meta-profile/README.md +37 -0
- data/examples/meta-profile/controls/example.rb +13 -0
- data/examples/meta-profile/inspec.yml +13 -0
- data/examples/profile-attribute.yml +2 -0
- data/examples/profile-attribute/README.md +14 -0
- data/examples/profile-attribute/controls/example.rb +11 -0
- data/examples/profile-attribute/inspec.yml +8 -0
- data/examples/profile-sensitive/README.md +29 -0
- data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -0
- data/examples/profile-sensitive/controls/sensitive.rb +9 -0
- data/examples/profile-sensitive/inspec.yml +8 -0
- data/examples/profile/README.md +48 -0
- data/examples/profile/controls/example.rb +23 -0
- data/examples/profile/controls/gordon.rb +36 -0
- data/examples/profile/controls/meta.rb +34 -0
- data/examples/profile/inspec.yml +10 -0
- data/examples/profile/libraries/gordon_config.rb +59 -0
- data/inspec-core.gemspec +43 -0
- data/lib/bundles/README.md +3 -0
- data/lib/bundles/inspec-artifact.rb +7 -0
- data/lib/bundles/inspec-artifact/README.md +1 -0
- data/lib/bundles/inspec-artifact/cli.rb +277 -0
- data/lib/bundles/inspec-compliance.rb +16 -0
- data/lib/bundles/inspec-compliance/.kitchen.yml +20 -0
- data/lib/bundles/inspec-compliance/README.md +193 -0
- data/lib/bundles/inspec-compliance/api.rb +360 -0
- data/lib/bundles/inspec-compliance/api/login.rb +193 -0
- data/lib/bundles/inspec-compliance/bootstrap.sh +41 -0
- data/lib/bundles/inspec-compliance/cli.rb +260 -0
- data/lib/bundles/inspec-compliance/configuration.rb +103 -0
- data/lib/bundles/inspec-compliance/http.rb +125 -0
- data/lib/bundles/inspec-compliance/images/cc-token.png +0 -0
- data/lib/bundles/inspec-compliance/support.rb +36 -0
- data/lib/bundles/inspec-compliance/target.rb +106 -0
- data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -0
- data/lib/bundles/inspec-habitat.rb +12 -0
- data/lib/bundles/inspec-habitat/cli.rb +36 -0
- data/lib/bundles/inspec-habitat/log.rb +10 -0
- data/lib/bundles/inspec-habitat/profile.rb +391 -0
- data/lib/bundles/inspec-init.rb +8 -0
- data/lib/bundles/inspec-init/README.md +31 -0
- data/lib/bundles/inspec-init/cli.rb +97 -0
- data/lib/bundles/inspec-init/templates/profile/README.md +3 -0
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -0
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -0
- data/lib/bundles/inspec-init/templates/profile/libraries/.gitkeep +0 -0
- data/lib/bundles/inspec-supermarket.rb +13 -0
- data/lib/bundles/inspec-supermarket/README.md +45 -0
- data/lib/bundles/inspec-supermarket/api.rb +84 -0
- data/lib/bundles/inspec-supermarket/cli.rb +73 -0
- data/lib/bundles/inspec-supermarket/target.rb +34 -0
- data/lib/fetchers/git.rb +163 -0
- data/lib/fetchers/local.rb +74 -0
- data/lib/fetchers/mock.rb +35 -0
- data/lib/fetchers/url.rb +247 -0
- data/lib/inspec.rb +24 -0
- data/lib/inspec/archive/tar.rb +29 -0
- data/lib/inspec/archive/zip.rb +19 -0
- data/lib/inspec/backend.rb +93 -0
- data/lib/inspec/base_cli.rb +368 -0
- data/lib/inspec/cached_fetcher.rb +66 -0
- data/lib/inspec/cli.rb +292 -0
- data/lib/inspec/completions/bash.sh.erb +45 -0
- data/lib/inspec/completions/fish.sh.erb +34 -0
- data/lib/inspec/completions/zsh.sh.erb +61 -0
- data/lib/inspec/control_eval_context.rb +179 -0
- data/lib/inspec/dependencies/cache.rb +72 -0
- data/lib/inspec/dependencies/dependency_set.rb +92 -0
- data/lib/inspec/dependencies/lockfile.rb +115 -0
- data/lib/inspec/dependencies/requirement.rb +123 -0
- data/lib/inspec/dependencies/resolver.rb +86 -0
- data/lib/inspec/describe.rb +27 -0
- data/lib/inspec/dsl.rb +66 -0
- data/lib/inspec/dsl_shared.rb +33 -0
- data/lib/inspec/env_printer.rb +157 -0
- data/lib/inspec/errors.rb +14 -0
- data/lib/inspec/exceptions.rb +12 -0
- data/lib/inspec/expect.rb +45 -0
- data/lib/inspec/fetcher.rb +45 -0
- data/lib/inspec/file_provider.rb +275 -0
- data/lib/inspec/formatters.rb +3 -0
- data/lib/inspec/formatters/base.rb +259 -0
- data/lib/inspec/formatters/json_rspec.rb +20 -0
- data/lib/inspec/formatters/show_progress.rb +12 -0
- data/lib/inspec/library_eval_context.rb +58 -0
- data/lib/inspec/log.rb +11 -0
- data/lib/inspec/metadata.rb +247 -0
- data/lib/inspec/method_source.rb +24 -0
- data/lib/inspec/objects.rb +14 -0
- data/lib/inspec/objects/attribute.rb +75 -0
- data/lib/inspec/objects/control.rb +61 -0
- data/lib/inspec/objects/describe.rb +92 -0
- data/lib/inspec/objects/each_loop.rb +36 -0
- data/lib/inspec/objects/list.rb +15 -0
- data/lib/inspec/objects/or_test.rb +40 -0
- data/lib/inspec/objects/ruby_helper.rb +15 -0
- data/lib/inspec/objects/tag.rb +27 -0
- data/lib/inspec/objects/test.rb +87 -0
- data/lib/inspec/objects/value.rb +27 -0
- data/lib/inspec/plugins.rb +60 -0
- data/lib/inspec/plugins/cli.rb +24 -0
- data/lib/inspec/plugins/fetcher.rb +86 -0
- data/lib/inspec/plugins/resource.rb +135 -0
- data/lib/inspec/plugins/secret.rb +15 -0
- data/lib/inspec/plugins/source_reader.rb +40 -0
- data/lib/inspec/polyfill.rb +12 -0
- data/lib/inspec/profile.rb +513 -0
- data/lib/inspec/profile_context.rb +208 -0
- data/lib/inspec/profile_vendor.rb +66 -0
- data/lib/inspec/reporters.rb +60 -0
- data/lib/inspec/reporters/automate.rb +76 -0
- data/lib/inspec/reporters/base.rb +25 -0
- data/lib/inspec/reporters/cli.rb +356 -0
- data/lib/inspec/reporters/json.rb +116 -0
- data/lib/inspec/reporters/json_min.rb +48 -0
- data/lib/inspec/reporters/junit.rb +78 -0
- data/lib/inspec/require_loader.rb +33 -0
- data/lib/inspec/resource.rb +190 -0
- data/lib/inspec/rule.rb +280 -0
- data/lib/inspec/runner.rb +345 -0
- data/lib/inspec/runner_mock.rb +41 -0
- data/lib/inspec/runner_rspec.rb +175 -0
- data/lib/inspec/runtime_profile.rb +26 -0
- data/lib/inspec/schema.rb +213 -0
- data/lib/inspec/secrets.rb +19 -0
- data/lib/inspec/secrets/yaml.rb +30 -0
- data/lib/inspec/shell.rb +220 -0
- data/lib/inspec/shell_detector.rb +90 -0
- data/lib/inspec/source_reader.rb +29 -0
- data/lib/inspec/version.rb +8 -0
- data/lib/matchers/matchers.rb +339 -0
- data/lib/resources/aide_conf.rb +151 -0
- data/lib/resources/apache.rb +48 -0
- data/lib/resources/apache_conf.rb +149 -0
- data/lib/resources/apt.rb +149 -0
- data/lib/resources/audit_policy.rb +63 -0
- data/lib/resources/auditd.rb +231 -0
- data/lib/resources/auditd_conf.rb +46 -0
- data/lib/resources/bash.rb +35 -0
- data/lib/resources/bond.rb +69 -0
- data/lib/resources/bridge.rb +122 -0
- data/lib/resources/chocolatey_package.rb +78 -0
- data/lib/resources/command.rb +73 -0
- data/lib/resources/cpan.rb +58 -0
- data/lib/resources/cran.rb +64 -0
- data/lib/resources/crontab.rb +169 -0
- data/lib/resources/csv.rb +56 -0
- data/lib/resources/dh_params.rb +77 -0
- data/lib/resources/directory.rb +25 -0
- data/lib/resources/docker.rb +236 -0
- data/lib/resources/docker_container.rb +89 -0
- data/lib/resources/docker_image.rb +83 -0
- data/lib/resources/docker_object.rb +57 -0
- data/lib/resources/docker_service.rb +90 -0
- data/lib/resources/elasticsearch.rb +169 -0
- data/lib/resources/etc_fstab.rb +94 -0
- data/lib/resources/etc_group.rb +154 -0
- data/lib/resources/etc_hosts.rb +66 -0
- data/lib/resources/etc_hosts_allow_deny.rb +112 -0
- data/lib/resources/file.rb +298 -0
- data/lib/resources/filesystem.rb +31 -0
- data/lib/resources/firewalld.rb +143 -0
- data/lib/resources/gem.rb +70 -0
- data/lib/resources/groups.rb +215 -0
- data/lib/resources/grub_conf.rb +227 -0
- data/lib/resources/host.rb +306 -0
- data/lib/resources/http.rb +253 -0
- data/lib/resources/iis_app.rb +101 -0
- data/lib/resources/iis_site.rb +148 -0
- data/lib/resources/inetd_conf.rb +54 -0
- data/lib/resources/ini.rb +29 -0
- data/lib/resources/interface.rb +129 -0
- data/lib/resources/iptables.rb +80 -0
- data/lib/resources/json.rb +111 -0
- data/lib/resources/kernel_module.rb +107 -0
- data/lib/resources/kernel_parameter.rb +58 -0
- data/lib/resources/key_rsa.rb +63 -0
- data/lib/resources/limits_conf.rb +46 -0
- data/lib/resources/login_def.rb +57 -0
- data/lib/resources/mount.rb +88 -0
- data/lib/resources/mssql_session.rb +101 -0
- data/lib/resources/mysql.rb +82 -0
- data/lib/resources/mysql_conf.rb +127 -0
- data/lib/resources/mysql_session.rb +85 -0
- data/lib/resources/nginx.rb +96 -0
- data/lib/resources/nginx_conf.rb +226 -0
- data/lib/resources/npm.rb +48 -0
- data/lib/resources/ntp_conf.rb +51 -0
- data/lib/resources/oneget.rb +71 -0
- data/lib/resources/oracledb_session.rb +139 -0
- data/lib/resources/os.rb +36 -0
- data/lib/resources/os_env.rb +86 -0
- data/lib/resources/package.rb +370 -0
- data/lib/resources/packages.rb +111 -0
- data/lib/resources/parse_config.rb +112 -0
- data/lib/resources/passwd.rb +76 -0
- data/lib/resources/pip.rb +130 -0
- data/lib/resources/platform.rb +109 -0
- data/lib/resources/port.rb +771 -0
- data/lib/resources/postgres.rb +131 -0
- data/lib/resources/postgres_conf.rb +114 -0
- data/lib/resources/postgres_hba_conf.rb +90 -0
- data/lib/resources/postgres_ident_conf.rb +79 -0
- data/lib/resources/postgres_session.rb +71 -0
- data/lib/resources/powershell.rb +67 -0
- data/lib/resources/processes.rb +204 -0
- data/lib/resources/rabbitmq_conf.rb +51 -0
- data/lib/resources/registry_key.rb +297 -0
- data/lib/resources/security_policy.rb +180 -0
- data/lib/resources/service.rb +794 -0
- data/lib/resources/shadow.rb +159 -0
- data/lib/resources/ssh_conf.rb +97 -0
- data/lib/resources/ssl.rb +99 -0
- data/lib/resources/sys_info.rb +28 -0
- data/lib/resources/toml.rb +32 -0
- data/lib/resources/users.rb +654 -0
- data/lib/resources/vbscript.rb +68 -0
- data/lib/resources/virtualization.rb +247 -0
- data/lib/resources/windows_feature.rb +84 -0
- data/lib/resources/windows_hotfix.rb +35 -0
- data/lib/resources/windows_task.rb +102 -0
- data/lib/resources/wmi.rb +110 -0
- data/lib/resources/x509_certificate.rb +137 -0
- data/lib/resources/xinetd.rb +106 -0
- data/lib/resources/xml.rb +46 -0
- data/lib/resources/yaml.rb +43 -0
- data/lib/resources/yum.rb +180 -0
- data/lib/resources/zfs_dataset.rb +60 -0
- data/lib/resources/zfs_pool.rb +49 -0
- data/lib/source_readers/flat.rb +39 -0
- data/lib/source_readers/inspec.rb +75 -0
- data/lib/utils/command_wrapper.rb +27 -0
- data/lib/utils/convert.rb +12 -0
- data/lib/utils/database_helpers.rb +77 -0
- data/lib/utils/enumerable_delegation.rb +9 -0
- data/lib/utils/erlang_parser.rb +192 -0
- data/lib/utils/file_reader.rb +25 -0
- data/lib/utils/filter.rb +273 -0
- data/lib/utils/filter_array.rb +27 -0
- data/lib/utils/find_files.rb +47 -0
- data/lib/utils/hash.rb +41 -0
- data/lib/utils/json_log.rb +18 -0
- data/lib/utils/latest_version.rb +22 -0
- data/lib/utils/modulator.rb +12 -0
- data/lib/utils/nginx_parser.rb +105 -0
- data/lib/utils/object_traversal.rb +49 -0
- data/lib/utils/parser.rb +274 -0
- data/lib/utils/pkey_reader.rb +15 -0
- data/lib/utils/plugin_registry.rb +93 -0
- data/lib/utils/simpleconfig.rb +120 -0
- data/lib/utils/spdx.rb +13 -0
- data/lib/utils/spdx.txt +344 -0
- metadata +713 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Inspec::Resources
|
4
|
+
class NpmPackage < Inspec.resource(1)
|
5
|
+
name 'npm'
|
6
|
+
supports platform: 'unix'
|
7
|
+
supports platform: 'windows'
|
8
|
+
desc 'Use the npm InSpec audit resource to test if a global npm package is installed. npm is the the package manager for Nodejs packages, such as bower and StatsD.'
|
9
|
+
example "
|
10
|
+
describe npm('bower') do
|
11
|
+
it { should be_installed }
|
12
|
+
end
|
13
|
+
"
|
14
|
+
|
15
|
+
def initialize(package_name)
|
16
|
+
@package_name = package_name
|
17
|
+
@cache = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def info
|
21
|
+
return @info if defined?(@info)
|
22
|
+
|
23
|
+
cmd = inspec.command("npm ls -g --json #{@package_name}")
|
24
|
+
@info = {
|
25
|
+
name: @package_name,
|
26
|
+
type: 'npm',
|
27
|
+
installed: cmd.exit_status == 0,
|
28
|
+
}
|
29
|
+
return @info unless @info[:installed]
|
30
|
+
|
31
|
+
pkgs = JSON.parse(cmd.stdout)
|
32
|
+
@info[:version] = pkgs['dependencies'][@package_name]['version']
|
33
|
+
@info
|
34
|
+
end
|
35
|
+
|
36
|
+
def installed?
|
37
|
+
info[:installed] == true
|
38
|
+
end
|
39
|
+
|
40
|
+
def version
|
41
|
+
info[:version]
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
"Npm Package #{@package_name}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# copyright: 2015, Vulcano Security GmbH
|
3
|
+
|
4
|
+
require 'utils/simpleconfig'
|
5
|
+
require 'utils/file_reader'
|
6
|
+
|
7
|
+
module Inspec::Resources
|
8
|
+
class NtpConf < Inspec.resource(1)
|
9
|
+
name 'ntp_conf'
|
10
|
+
supports platform: 'unix'
|
11
|
+
desc 'Use the ntp_conf InSpec audit resource to test the synchronization settings defined in the ntp.conf file. This file is typically located at /etc/ntp.conf.'
|
12
|
+
example "
|
13
|
+
describe ntp_conf do
|
14
|
+
its('server') { should_not eq nil }
|
15
|
+
its('restrict') { should include '-4 default kod notrap nomodify nopeer noquery'}
|
16
|
+
end
|
17
|
+
"
|
18
|
+
|
19
|
+
include FileReader
|
20
|
+
|
21
|
+
def initialize(path = nil)
|
22
|
+
@conf_path = path || '/etc/ntp.conf'
|
23
|
+
@content = read_file_content(@conf_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(name)
|
27
|
+
param = read_params[name.to_s]
|
28
|
+
# extract first value if we have only one value in array
|
29
|
+
return param[0] if param.is_a?(Array) and param.length == 1
|
30
|
+
param
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
'ntp.conf'
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def read_params
|
40
|
+
return @params if defined?(@params)
|
41
|
+
|
42
|
+
# parse the file
|
43
|
+
conf = SimpleConfig.new(
|
44
|
+
@content,
|
45
|
+
assignment_regex: /^\s*(\S+)\s+(.*)\s*$/,
|
46
|
+
multiple_values: true,
|
47
|
+
)
|
48
|
+
@params = conf.params
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This resource talks with OneGet (https://github.com/OneGet/oneget)
|
4
|
+
# Its part of Windows Management Framework 5.0 and part of Windows 10
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
# describe oneget('zoomit') do
|
8
|
+
# it { should be_installed }
|
9
|
+
# end
|
10
|
+
module Inspec::Resources
|
11
|
+
class OneGetPackage < Inspec.resource(1)
|
12
|
+
name 'oneget'
|
13
|
+
supports platform: 'windows'
|
14
|
+
desc 'Use the oneget InSpec audit resource to test if the named package and/or package version is installed on the system. This resource uses OneGet, which is part of the Windows Management Framework 5.0 and Windows 10. This resource uses the Get-Package cmdlet to return all of the package names in the OneGet repository.'
|
15
|
+
example "
|
16
|
+
describe oneget('zoomit') do
|
17
|
+
it { should be_installed }
|
18
|
+
its('version') { should eq '1.2.3' }
|
19
|
+
end
|
20
|
+
"
|
21
|
+
|
22
|
+
def initialize(package_name)
|
23
|
+
@package_name = package_name
|
24
|
+
|
25
|
+
# verify that this resource is only supported on Windows
|
26
|
+
return skip_resource 'The `oneget` resource is not supported on your OS.' if !inspec.os.windows?
|
27
|
+
end
|
28
|
+
|
29
|
+
def info
|
30
|
+
return @info if defined?(@info)
|
31
|
+
|
32
|
+
@info = {}
|
33
|
+
@info[:type] = 'oneget'
|
34
|
+
@info[:installed] = false
|
35
|
+
|
36
|
+
cmd = inspec.command("Get-Package -Name '#{@package_name}' | ConvertTo-Json")
|
37
|
+
# cannot rely on exit code for now, successful command returns exit code 1
|
38
|
+
# return nil if cmd.exit_status != 0
|
39
|
+
# try to parse json
|
40
|
+
|
41
|
+
begin
|
42
|
+
pkgs = JSON.parse(cmd.stdout)
|
43
|
+
@info[:installed] = true
|
44
|
+
|
45
|
+
# sometimes we get multiple values
|
46
|
+
if pkgs.is_a?(Array)
|
47
|
+
# select the first entry
|
48
|
+
pkgs = pkgs.first
|
49
|
+
end
|
50
|
+
rescue JSON::ParserError => _e
|
51
|
+
return @info
|
52
|
+
end
|
53
|
+
|
54
|
+
@info[:name] = pkgs['Name'] if pkgs.key?('Name')
|
55
|
+
@info[:version] = pkgs['Version'] if pkgs.key?('Version')
|
56
|
+
@info
|
57
|
+
end
|
58
|
+
|
59
|
+
def installed?
|
60
|
+
info[:installed] == true
|
61
|
+
end
|
62
|
+
|
63
|
+
def version
|
64
|
+
info[:version]
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_s
|
68
|
+
"OneGet Package #{@package_name}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'hashie/mash'
|
4
|
+
require 'utils/database_helpers'
|
5
|
+
require 'htmlentities'
|
6
|
+
require 'rexml/document'
|
7
|
+
require 'csv'
|
8
|
+
|
9
|
+
module Inspec::Resources
|
10
|
+
# STABILITY: Experimental
|
11
|
+
# This resource needs further testing and refinement
|
12
|
+
#
|
13
|
+
class OracledbSession < Inspec.resource(1)
|
14
|
+
name 'oracledb_session'
|
15
|
+
supports platform: 'unix'
|
16
|
+
supports platform: 'windows'
|
17
|
+
desc 'Use the oracledb_session InSpec resource to test commands against an Oracle database'
|
18
|
+
example "
|
19
|
+
sql = oracledb_session(user: 'my_user', pass: 'password')
|
20
|
+
describe sql.query(\"SELECT UPPER(VALUE) AS VALUE FROM V$PARAMETER WHERE UPPER(NAME)='AUDIT_SYS_OPERATIONS'\").row(0).column('value') do
|
21
|
+
its('value') { should eq 'TRUE' }
|
22
|
+
end
|
23
|
+
"
|
24
|
+
|
25
|
+
attr_reader :user, :password, :host, :service
|
26
|
+
def initialize(opts = {})
|
27
|
+
@user = opts[:user]
|
28
|
+
@password = opts[:password] || opts[:pass]
|
29
|
+
if opts[:pass]
|
30
|
+
warn '[DEPRECATED] use `password` option to supply password instead of `pass`'
|
31
|
+
end
|
32
|
+
|
33
|
+
@host = opts[:host] || 'localhost'
|
34
|
+
@port = opts[:port] || '1521'
|
35
|
+
@service = opts[:service]
|
36
|
+
|
37
|
+
# we prefer sqlci although it is way slower than sqlplus, but it understands csv properly
|
38
|
+
@sqlcl_bin = 'sql'
|
39
|
+
@sqlplus_bin = opts[:sqlplus_bin] || 'sqlplus'
|
40
|
+
|
41
|
+
return skip_resource "Can't run Oracle checks without authentication" if @user.nil? || @password.nil?
|
42
|
+
return skip_resource 'You must provide a service name for the session' if @service.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def query(q)
|
46
|
+
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"')
|
47
|
+
# escape tables with $
|
48
|
+
escaped_query = escaped_query.gsub('$', '\\$')
|
49
|
+
|
50
|
+
p = nil
|
51
|
+
# use sqlplus if sqlcl is not available
|
52
|
+
if inspec.command(@sqlcl_bin).exist?
|
53
|
+
bin = @sqlcl_bin
|
54
|
+
opts = "set sqlformat csv\nSET FEEDBACK OFF"
|
55
|
+
p = :parse_csv_result
|
56
|
+
else
|
57
|
+
bin = @sqlplus_bin
|
58
|
+
opts = "SET MARKUP HTML ON\nSET FEEDBACK OFF"
|
59
|
+
p = :parse_html_result
|
60
|
+
end
|
61
|
+
|
62
|
+
query = verify_query(escaped_query)
|
63
|
+
query += ';' unless query.end_with?(';')
|
64
|
+
command = %{echo "#{opts}\n#{query}\nEXIT" | #{bin} "#{@user}"/"#{@password}"@#{@host}:#{@port}/#{@service}}
|
65
|
+
cmd = inspec.command(command)
|
66
|
+
|
67
|
+
out = cmd.stdout + "\n" + cmd.stderr
|
68
|
+
if out.downcase =~ /^error/
|
69
|
+
# TODO: we need to throw an exception here
|
70
|
+
# change once https://github.com/chef/inspec/issues/1205 is in
|
71
|
+
warn "Could not execute the sql query #{out}"
|
72
|
+
DatabaseHelper::SQLQueryResult.new(cmd, Hashie::Mash.new({}))
|
73
|
+
end
|
74
|
+
DatabaseHelper::SQLQueryResult.new(cmd, send(p, cmd.stdout))
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_s
|
78
|
+
'Oracle Session'
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def verify_query(query)
|
84
|
+
# ensure we have a ; at the end
|
85
|
+
query + ';' if !query.strip.end_with?(';')
|
86
|
+
query
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_csv_result(stdout)
|
90
|
+
output = stdout.delete(/\r/)
|
91
|
+
table = CSV.parse(output, { headers: true })
|
92
|
+
|
93
|
+
# convert to hash
|
94
|
+
headers = table.headers
|
95
|
+
|
96
|
+
results = table.map { |row|
|
97
|
+
res = {}
|
98
|
+
headers.each { |header|
|
99
|
+
res[header.downcase] = row[header]
|
100
|
+
}
|
101
|
+
Hashie::Mash.new(res)
|
102
|
+
}
|
103
|
+
results
|
104
|
+
end
|
105
|
+
|
106
|
+
def parse_html_result(stdout) # rubocop:disable Metrics/AbcSize
|
107
|
+
result = stdout
|
108
|
+
# make oracle html valid html by removing the p tag, it does not include a closing tag
|
109
|
+
result = result.gsub('<p>', '').gsub('</p>', '').gsub('<br>', '')
|
110
|
+
doc = REXML::Document.new result
|
111
|
+
table = doc.elements['table']
|
112
|
+
hash = []
|
113
|
+
if !table.nil?
|
114
|
+
rows = table.elements.to_a
|
115
|
+
headers = rows[0].elements.to_a('th').map { |entry| entry.text.strip }
|
116
|
+
rows.delete_at(0)
|
117
|
+
|
118
|
+
# iterate over each row, first row is header
|
119
|
+
hash = []
|
120
|
+
if !rows.nil? && !rows.empty?
|
121
|
+
hash = rows.map { |row|
|
122
|
+
res = {}
|
123
|
+
entries = row.elements.to_a('td')
|
124
|
+
# ignore if we have empty entries, oracle is adding th rows in between
|
125
|
+
return nil if entries.empty?
|
126
|
+
headers.each_with_index { |header, index|
|
127
|
+
# we need htmlentities since we do not have nokogiri
|
128
|
+
coder = HTMLEntities.new
|
129
|
+
val = coder.decode(entries[index].text).strip
|
130
|
+
res[header.downcase] = val
|
131
|
+
}
|
132
|
+
Hashie::Mash.new(res)
|
133
|
+
}.compact
|
134
|
+
end
|
135
|
+
end
|
136
|
+
hash
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/lib/resources/os.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'resources/platform'
|
4
|
+
|
5
|
+
module Inspec::Resources
|
6
|
+
class OSResource < PlatformResource
|
7
|
+
name 'os'
|
8
|
+
supports platform: 'unix'
|
9
|
+
supports platform: 'windows'
|
10
|
+
desc 'Use the os InSpec audit resource to test the platform on which the system is running.'
|
11
|
+
example "
|
12
|
+
describe os[:family] do
|
13
|
+
it { should eq 'redhat' }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe os.redhat? do
|
17
|
+
it { should eq true }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe os.linux? do
|
21
|
+
it { should eq true }
|
22
|
+
end
|
23
|
+
"
|
24
|
+
|
25
|
+
# reuse helper methods from backend
|
26
|
+
%w{aix? redhat? debian? suse? bsd? solaris? linux? unix? windows? hpux? darwin?}.each do |os_family|
|
27
|
+
define_method(os_family.to_sym) do
|
28
|
+
@platform.send(os_family)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
'Operating System Detection'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# copyright: 2015, Vulcano Security GmbH
|
3
|
+
|
4
|
+
# Usage:
|
5
|
+
#
|
6
|
+
# describe os_env('PATH') do
|
7
|
+
# its('split') { should_not include('') }
|
8
|
+
# its('split') { should_not include('.') }
|
9
|
+
# end
|
10
|
+
|
11
|
+
require 'utils/simpleconfig'
|
12
|
+
|
13
|
+
module Inspec::Resources
|
14
|
+
class OsEnv < Inspec.resource(1)
|
15
|
+
name 'os_env'
|
16
|
+
supports platform: 'unix'
|
17
|
+
supports platform: 'windows'
|
18
|
+
desc 'Use the os_env InSpec audit resource to test the environment variables for the platform on which the system is running.'
|
19
|
+
example "
|
20
|
+
describe os_env('VARIABLE') do
|
21
|
+
its('matcher') { should eq 1 }
|
22
|
+
end
|
23
|
+
"
|
24
|
+
|
25
|
+
def initialize(env = nil, target = nil)
|
26
|
+
@osenv = env
|
27
|
+
@target = unless target.nil?
|
28
|
+
if target.casecmp('system') == 0
|
29
|
+
'Machine'
|
30
|
+
else
|
31
|
+
'User'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def split
|
37
|
+
# we can't take advantage of `File::PATH_SEPARATOR` as code is
|
38
|
+
# evaluated on the host machine
|
39
|
+
path_separator = inspec.os.windows? ? ';' : ':'
|
40
|
+
# -1 is required to catch cases like dir1::dir2:
|
41
|
+
# where we have a trailing :
|
42
|
+
content.nil? ? [] : content.split(path_separator, -1)
|
43
|
+
end
|
44
|
+
|
45
|
+
def content
|
46
|
+
return @content if defined?(@content)
|
47
|
+
@content = value_for(@osenv, @target) unless @osenv.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
if @osenv.nil?
|
52
|
+
'Environment variables'
|
53
|
+
else
|
54
|
+
"Environment variable #{@osenv}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def value_for(env, target = nil)
|
61
|
+
command = if inspec.os.windows?
|
62
|
+
if target.nil?
|
63
|
+
"${Env:#{env}}"
|
64
|
+
else
|
65
|
+
"[System.Environment]::GetEnvironmentVariable('#{env}', [System.EnvironmentVariableTarget]::#{target})"
|
66
|
+
end
|
67
|
+
else
|
68
|
+
'env'
|
69
|
+
end
|
70
|
+
|
71
|
+
out = inspec.command(command)
|
72
|
+
|
73
|
+
unless out.exit_status == 0
|
74
|
+
skip_resource "Can't read environment variables on #{inspec.os.name}. "\
|
75
|
+
"Tried `#{command}` which returned #{out.exit_status}"
|
76
|
+
end
|
77
|
+
|
78
|
+
if inspec.os.windows?
|
79
|
+
out.stdout.strip
|
80
|
+
else
|
81
|
+
params = SimpleConfig.new(out.stdout).params
|
82
|
+
params[env]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,370 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Resource to determine package information
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# describe package('nginx') do
|
7
|
+
# it { should be_installed }
|
8
|
+
# end
|
9
|
+
module Inspec::Resources
|
10
|
+
class Package < Inspec.resource(1)
|
11
|
+
name 'package'
|
12
|
+
supports platform: 'unix'
|
13
|
+
supports platform: 'windows'
|
14
|
+
desc 'Use the package InSpec audit resource to test if the named package and/or package version is installed on the system.'
|
15
|
+
example "
|
16
|
+
describe package('nginx') do
|
17
|
+
it { should be_installed }
|
18
|
+
it { should_not be_held } # for dpkg platforms that support holding a version from being upgraded
|
19
|
+
its('version') { should eq 1.9.5 }
|
20
|
+
end
|
21
|
+
"
|
22
|
+
|
23
|
+
def initialize(package_name, opts = {}) # rubocop:disable Metrics/AbcSize
|
24
|
+
@package_name = package_name
|
25
|
+
@name = @package_name
|
26
|
+
@cache = nil
|
27
|
+
# select package manager
|
28
|
+
@pkgman = nil
|
29
|
+
|
30
|
+
os = inspec.os
|
31
|
+
if os.debian?
|
32
|
+
@pkgman = Deb.new(inspec)
|
33
|
+
elsif os.redhat? || %w{suse amazon fedora}.include?(os[:family])
|
34
|
+
@pkgman = Rpm.new(inspec, opts)
|
35
|
+
elsif ['arch'].include?(os[:name])
|
36
|
+
@pkgman = Pacman.new(inspec)
|
37
|
+
elsif ['darwin'].include?(os[:family])
|
38
|
+
@pkgman = Brew.new(inspec)
|
39
|
+
elsif os.windows?
|
40
|
+
@pkgman = WindowsPkg.new(inspec)
|
41
|
+
elsif ['aix'].include?(os[:family])
|
42
|
+
@pkgman = BffPkg.new(inspec)
|
43
|
+
elsif os.solaris?
|
44
|
+
@pkgman = SolarisPkg.new(inspec)
|
45
|
+
elsif ['hpux'].include?(os[:family])
|
46
|
+
@pkgman = HpuxPkg.new(inspec)
|
47
|
+
else
|
48
|
+
raise Inspec::Exceptions::ResourceSkipped, 'The `package` resource is not supported on your OS yet.'
|
49
|
+
end
|
50
|
+
|
51
|
+
evaluate_missing_requirements
|
52
|
+
end
|
53
|
+
|
54
|
+
# returns true if the package is installed
|
55
|
+
def installed?(_provider = nil, _version = nil)
|
56
|
+
info[:installed] == true
|
57
|
+
end
|
58
|
+
|
59
|
+
# returns true it the package is held (if the OS supports it)
|
60
|
+
def held?(_provider = nil, _version = nil)
|
61
|
+
info[:held] == true
|
62
|
+
end
|
63
|
+
|
64
|
+
# returns the package description
|
65
|
+
def info
|
66
|
+
return @cache if !@cache.nil?
|
67
|
+
# All `@pkgman.info` methods return `{}`. This matches that
|
68
|
+
# behavior if `@pkgman` can't be determined, thus avoiding the
|
69
|
+
# `undefined method 'info' for nil:NilClass` error
|
70
|
+
return {} if @pkgman.nil?
|
71
|
+
@pkgman.info(@package_name)
|
72
|
+
end
|
73
|
+
|
74
|
+
# return the package version
|
75
|
+
def version
|
76
|
+
info = @pkgman.info(@package_name)
|
77
|
+
info[:version]
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_s
|
81
|
+
"System Package #{@package_name}"
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def evaluate_missing_requirements
|
87
|
+
missing_requirements_string = @pkgman.missing_requirements.uniq.join(', ')
|
88
|
+
return if missing_requirements_string.empty?
|
89
|
+
raise Inspec::Exceptions::ResourceSkipped, "The following requirements are not met for this resource: #{missing_requirements_string}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class PkgManagement
|
94
|
+
attr_reader :inspec
|
95
|
+
def initialize(inspec)
|
96
|
+
@inspec = inspec
|
97
|
+
end
|
98
|
+
|
99
|
+
def missing_requirements
|
100
|
+
# Each provider can provide an Array of missing requirements that will be
|
101
|
+
# combined into a `ResourceSkipped` exception message.
|
102
|
+
[]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Debian / Ubuntu
|
107
|
+
class Deb < PkgManagement
|
108
|
+
def info(package_name)
|
109
|
+
cmd = inspec.command("dpkg -s #{package_name}")
|
110
|
+
return {} if cmd.exit_status.to_i != 0
|
111
|
+
|
112
|
+
params = SimpleConfig.new(
|
113
|
+
cmd.stdout.chomp,
|
114
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
115
|
+
multiple_values: false,
|
116
|
+
).params
|
117
|
+
# If the package is installed, Status is "install ok installed"
|
118
|
+
# If the package is installed and marked hold, Status is "hold ok installed"
|
119
|
+
# If the package is removed and not purged, Status is "deinstall ok config-files" with exit_status 0
|
120
|
+
# If the package is purged cmd fails with non-zero exit status
|
121
|
+
{
|
122
|
+
name: params['Package'],
|
123
|
+
installed: params['Status'].split(' ')[2] == 'installed',
|
124
|
+
held: params['Status'].split(' ')[0] == 'hold',
|
125
|
+
version: params['Version'],
|
126
|
+
type: 'deb',
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# RHEL family
|
132
|
+
class Rpm < PkgManagement
|
133
|
+
def initialize(inspec, opts)
|
134
|
+
super(inspec)
|
135
|
+
|
136
|
+
@dbpath = opts.fetch(:rpm_dbpath, nil)
|
137
|
+
end
|
138
|
+
|
139
|
+
def missing_requirements
|
140
|
+
missing_requirements = []
|
141
|
+
|
142
|
+
unless @dbpath.nil? || inspec.directory(@dbpath).directory?
|
143
|
+
missing_requirements << "RPMDB #{@dbpath} does not exist"
|
144
|
+
end
|
145
|
+
|
146
|
+
missing_requirements
|
147
|
+
end
|
148
|
+
|
149
|
+
def info(package_name)
|
150
|
+
rpm_cmd = rpm_command(package_name)
|
151
|
+
cmd = inspec.command(rpm_cmd)
|
152
|
+
# CentOS does not return an error code if the package is not installed,
|
153
|
+
# therefore we need to check for emptyness
|
154
|
+
return {} if cmd.exit_status.to_i != 0 || cmd.stdout.chomp.empty?
|
155
|
+
params = SimpleConfig.new(
|
156
|
+
cmd.stdout.chomp,
|
157
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
158
|
+
multiple_values: false,
|
159
|
+
).params
|
160
|
+
# On some (all?) systems, the linebreak before the vendor line is missing
|
161
|
+
if params['Version'] =~ /\s*Vendor:/
|
162
|
+
v = params['Version'].split(' ')[0]
|
163
|
+
else
|
164
|
+
v = params['Version']
|
165
|
+
end
|
166
|
+
# On some (all?) systems, the linebreak before the build line is missing
|
167
|
+
if params['Release'] =~ /\s*Build Date:/
|
168
|
+
r = params['Release'].split(' ')[0]
|
169
|
+
else
|
170
|
+
r = params['Release']
|
171
|
+
end
|
172
|
+
{
|
173
|
+
name: params['Name'],
|
174
|
+
installed: true,
|
175
|
+
version: "#{v}-#{r}",
|
176
|
+
type: 'rpm',
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
private
|
181
|
+
|
182
|
+
def rpm_command(package_name)
|
183
|
+
cmd = ''
|
184
|
+
cmd += 'rpm -qia'
|
185
|
+
cmd += " --dbpath #{@dbpath}" if @dbpath
|
186
|
+
cmd += ' ' + package_name
|
187
|
+
|
188
|
+
cmd
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# MacOS / Darwin implementation
|
193
|
+
class Brew < PkgManagement
|
194
|
+
def info(package_name)
|
195
|
+
brew_path = inspec.command('brew').exist? ? 'brew' : '/usr/local/bin/brew'
|
196
|
+
cmd = inspec.command("#{brew_path} info --json=v1 #{package_name}")
|
197
|
+
|
198
|
+
# If no available formula exists, then `brew` will exit non-zero
|
199
|
+
return {} if cmd.exit_status.to_i != 0
|
200
|
+
|
201
|
+
pkg = JSON.parse(cmd.stdout)[0]
|
202
|
+
|
203
|
+
# If package exists but is not installed, then `brew` output will not
|
204
|
+
# contain `pkg['installed'][0]['version']
|
205
|
+
return {} unless pkg.dig('installed', 0, 'version')
|
206
|
+
|
207
|
+
{
|
208
|
+
name: pkg['name'],
|
209
|
+
installed: true,
|
210
|
+
version: pkg['installed'][0]['version'],
|
211
|
+
type: 'brew',
|
212
|
+
}
|
213
|
+
rescue JSON::ParserError => e
|
214
|
+
raise Inspec::Exceptions::ResourceFailed,
|
215
|
+
'Failed to parse JSON from `brew` command. ' \
|
216
|
+
"Error: #{e}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Arch Linux
|
221
|
+
class Pacman < PkgManagement
|
222
|
+
def info(package_name)
|
223
|
+
cmd = inspec.command("pacman -Qi #{package_name}")
|
224
|
+
return {} if cmd.exit_status.to_i != 0
|
225
|
+
|
226
|
+
params = SimpleConfig.new(
|
227
|
+
cmd.stdout.chomp,
|
228
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
229
|
+
multiple_values: false,
|
230
|
+
).params
|
231
|
+
|
232
|
+
{
|
233
|
+
name: params['Name'],
|
234
|
+
installed: true,
|
235
|
+
version: params['Version'],
|
236
|
+
type: 'pacman',
|
237
|
+
}
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
class HpuxPkg < PkgManagement
|
242
|
+
def info(package_name)
|
243
|
+
cmd = inspec.command("swlist -l product | grep #{package_name}")
|
244
|
+
return {} if cmd.exit_status.to_i != 0
|
245
|
+
pkg = cmd.stdout.strip.split(' ')
|
246
|
+
{
|
247
|
+
name: pkg[0],
|
248
|
+
installed: true,
|
249
|
+
version: pkg[1],
|
250
|
+
type: 'pkg',
|
251
|
+
}
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# Determines the installed packages on Windows using the Windows package registry entries.
|
256
|
+
# @see: http://blogs.technet.com/b/heyscriptingguy/archive/2013/11/15/use-powershell-to-find-installed-software.aspx
|
257
|
+
class WindowsPkg < PkgManagement
|
258
|
+
def info(package_name)
|
259
|
+
search_paths = [
|
260
|
+
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
|
261
|
+
'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
|
262
|
+
]
|
263
|
+
|
264
|
+
# add 64 bit search paths
|
265
|
+
if inspec.os.arch == 'x86_64'
|
266
|
+
search_paths << 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
267
|
+
search_paths << 'HKCU:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
268
|
+
end
|
269
|
+
|
270
|
+
# Find the package
|
271
|
+
cmd = inspec.command <<-EOF.gsub(/^\s*/, '')
|
272
|
+
Get-ItemProperty (@("#{search_paths.join('", "')}") | Where-Object { Test-Path $_ }) |
|
273
|
+
Where-Object { $_.DisplayName -like "#{package_name}" -or $_.PSChildName -like "#{package_name}" } |
|
274
|
+
Select-Object -Property DisplayName,DisplayVersion | ConvertTo-Json
|
275
|
+
EOF
|
276
|
+
|
277
|
+
# We cannot rely on `exit_status` since PowerShell always exits 0 from the
|
278
|
+
# above command. Instead, if no package is found the output of the command
|
279
|
+
# will be `''` so we can use that to return `{}` to match the behavior of
|
280
|
+
# other package managers.
|
281
|
+
return {} if cmd.stdout == ''
|
282
|
+
|
283
|
+
begin
|
284
|
+
package = JSON.parse(cmd.stdout)
|
285
|
+
rescue JSON::ParserError => e
|
286
|
+
raise Inspec::Exceptions::ResourceFailed,
|
287
|
+
'Failed to parse JSON from PowerShell. ' \
|
288
|
+
"Error: #{e}"
|
289
|
+
end
|
290
|
+
|
291
|
+
# What if we match multiple packages? just pick the first one for now.
|
292
|
+
package = package[0] if package.is_a?(Array)
|
293
|
+
|
294
|
+
{
|
295
|
+
name: package['DisplayName'],
|
296
|
+
installed: true,
|
297
|
+
version: package['DisplayVersion'],
|
298
|
+
type: 'windows',
|
299
|
+
}
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# AIX
|
304
|
+
class BffPkg < PkgManagement
|
305
|
+
def info(package_name)
|
306
|
+
cmd = inspec.command("lslpp -cL #{package_name}")
|
307
|
+
return {} if cmd.exit_status.to_i != 0
|
308
|
+
|
309
|
+
bff_pkg = cmd.stdout.split("\n").last.split(':')
|
310
|
+
{
|
311
|
+
name: bff_pkg[1],
|
312
|
+
installed: true,
|
313
|
+
version: bff_pkg[2],
|
314
|
+
type: 'bff',
|
315
|
+
}
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Solaris
|
320
|
+
class SolarisPkg < PkgManagement
|
321
|
+
def info(package_name)
|
322
|
+
if inspec.os[:release].to_i <= 10
|
323
|
+
solaris10_info(package_name)
|
324
|
+
else
|
325
|
+
solaris11_info(package_name)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# solaris 10
|
330
|
+
def solaris10_info(package_name)
|
331
|
+
cmd = inspec.command("pkginfo -l #{package_name}")
|
332
|
+
return {} if cmd.exit_status.to_i != 0
|
333
|
+
|
334
|
+
params = SimpleConfig.new(
|
335
|
+
cmd.stdout.chomp,
|
336
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
337
|
+
multiple_values: false,
|
338
|
+
).params
|
339
|
+
|
340
|
+
# parse 11.10.0,REV=2006.05.18.01.46
|
341
|
+
v = params['VERSION'].split(',')
|
342
|
+
{
|
343
|
+
name: params['PKGINST'],
|
344
|
+
installed: true,
|
345
|
+
version: v[0] + '-' + v[1].split('=')[1],
|
346
|
+
type: 'pkg',
|
347
|
+
}
|
348
|
+
end
|
349
|
+
|
350
|
+
# solaris 11
|
351
|
+
def solaris11_info(package_name)
|
352
|
+
cmd = inspec.command("pkg info #{package_name}")
|
353
|
+
return {} if cmd.exit_status.to_i != 0
|
354
|
+
|
355
|
+
params = SimpleConfig.new(
|
356
|
+
cmd.stdout.chomp,
|
357
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
358
|
+
multiple_values: false,
|
359
|
+
).params
|
360
|
+
|
361
|
+
{
|
362
|
+
name: params['Name'],
|
363
|
+
installed: true,
|
364
|
+
# 0.5.11-0.175.3.1.0.5.0
|
365
|
+
version: "#{params['Version']}-#{params['Branch']}",
|
366
|
+
type: 'pkg',
|
367
|
+
}
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|