inspec 1.0.0 → 1.35.1
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 +933 -101
- data/Gemfile +8 -17
- data/MAINTAINERS.md +2 -1
- data/MAINTAINERS.toml +9 -4
- data/README.md +49 -28
- data/Rakefile +54 -39
- data/bin/inspec +1 -1
- data/docs/dsl_inspec.md +17 -4
- data/docs/dsl_resource.md +1 -1
- data/docs/habitat.md +192 -0
- data/docs/inspec_and_friends.md +4 -2
- data/docs/matchers.md +11 -0
- data/docs/migration.md +293 -0
- data/docs/profiles.md +124 -76
- data/docs/resources/aide_conf.md.erb +81 -0
- data/docs/resources/apache_conf.md.erb +10 -10
- data/docs/resources/apt.md.erb +13 -13
- data/docs/resources/audit_policy.md.erb +10 -10
- data/docs/resources/auditd_conf.md.erb +10 -10
- data/docs/resources/auditd_rules.md.erb +11 -11
- data/docs/resources/bash.md.erb +12 -12
- data/docs/resources/bond.md.erb +15 -15
- data/docs/resources/bridge.md.erb +11 -11
- data/docs/resources/bsd_service.md.erb +11 -11
- data/docs/resources/command.md.erb +23 -23
- data/docs/resources/crontab.md.erb +84 -0
- data/docs/resources/csv.md.erb +10 -10
- data/docs/resources/dh_params.md +191 -0
- data/docs/resources/directory.md.erb +8 -8
- data/docs/resources/docker.md.erb +160 -0
- data/docs/resources/docker_container.md.erb +89 -0
- data/docs/resources/docker_image.md.erb +86 -0
- data/docs/resources/etc_group.md.erb +16 -16
- data/docs/resources/etc_hosts.md.erb +62 -0
- data/docs/resources/file.md.erb +80 -58
- data/docs/resources/gem.md.erb +32 -13
- data/docs/resources/group.md.erb +12 -12
- data/docs/resources/grub_conf.md.erb +11 -11
- data/docs/resources/host.md.erb +27 -18
- data/docs/resources/http.md.erb +104 -0
- data/docs/resources/iis_app.md.erb +126 -0
- data/docs/resources/iis_site.md.erb +17 -17
- data/docs/resources/inetd_conf.md.erb +10 -10
- data/docs/resources/ini.md.erb +9 -9
- data/docs/resources/interface.md.erb +13 -13
- data/docs/resources/iptables.md.erb +21 -14
- data/docs/resources/json.md.erb +11 -11
- data/docs/resources/kernel_module.md.erb +73 -12
- data/docs/resources/kernel_parameter.md.erb +12 -12
- data/docs/resources/key_rsa.md.erb +70 -0
- data/docs/resources/launchd_service.md.erb +11 -11
- data/docs/resources/limits_conf.md.erb +10 -10
- data/docs/resources/login_def.md.erb +12 -12
- data/docs/resources/mount.md.erb +14 -14
- data/docs/resources/mssql_session.md.erb +62 -0
- data/docs/resources/mysql_conf.md.erb +14 -14
- data/docs/resources/mysql_session.md.erb +22 -10
- data/docs/resources/npm.md.erb +13 -13
- data/docs/resources/ntp_conf.md.erb +9 -9
- data/docs/resources/oneget.md.erb +11 -11
- data/docs/resources/oracledb_session.md.erb +53 -0
- data/docs/resources/os.md.erb +17 -17
- data/docs/resources/os_env.md.erb +12 -12
- data/docs/resources/package.md.erb +29 -16
- data/docs/resources/parse_config.md.erb +18 -18
- data/docs/resources/parse_config_file.md.erb +29 -23
- data/docs/resources/{etc_passwd.md.erb → passwd.md.erb} +17 -17
- data/docs/resources/pip.md.erb +15 -15
- data/docs/resources/port.md.erb +23 -23
- data/docs/resources/postgres_conf.md.erb +15 -13
- data/docs/resources/postgres_hba_conf.md.erb +104 -0
- data/docs/resources/postgres_ident_conf.md.erb +87 -0
- data/docs/resources/postgres_session.md.erb +28 -21
- data/docs/resources/powershell.md.erb +14 -14
- data/docs/resources/processes.md.erb +123 -0
- data/docs/resources/rabbitmq_config.md.erb +55 -0
- data/docs/resources/registry_key.md.erb +44 -21
- data/docs/resources/runit_service.md.erb +11 -11
- data/docs/resources/security_policy.md.erb +10 -10
- data/docs/resources/service.md.erb +18 -18
- data/docs/resources/{etc_shadow.md.erb → shadow.md.erb} +19 -19
- data/docs/resources/ssh_config.md.erb +13 -13
- data/docs/resources/sshd_config.md.erb +15 -15
- data/docs/resources/ssl.md.erb +13 -13
- data/docs/resources/sys_info.md.erb +10 -10
- data/docs/resources/systemd_service.md.erb +11 -11
- data/docs/resources/sysv_service.md.erb +11 -11
- data/docs/resources/upstart_service.md.erb +11 -11
- data/docs/resources/user.md.erb +20 -20
- data/docs/resources/users.md.erb +19 -19
- data/docs/resources/vbscript.md.erb +13 -13
- data/docs/resources/virtualization.md.erb +71 -0
- data/docs/resources/windows_feature.md.erb +10 -10
- data/docs/resources/windows_task.md.erb +103 -0
- data/docs/resources/wmi.md.erb +10 -10
- data/docs/resources/x509_certificate.md.erb +146 -0
- data/docs/resources/xinetd_conf.md.erb +17 -17
- data/docs/resources/xml.md.erb +75 -0
- data/docs/resources/yaml.md.erb +25 -11
- data/docs/resources/yum.md.erb +24 -16
- data/docs/resources/zfs_dataset.md.erb +63 -0
- data/docs/resources/zfs_pool.md.erb +57 -0
- data/docs/ruby_usage.md +50 -0
- data/docs/shared/matcher_cmp.md.erb +4 -6
- data/examples/inheritance/README.md +49 -3
- data/examples/inheritance/controls/example.rb +4 -1
- data/examples/inheritance/inspec.yml +3 -1
- data/examples/meta-profile/README.md +29 -3
- data/examples/meta-profile/controls/example.rb +10 -5
- data/examples/meta-profile/inspec.yml +4 -8
- data/examples/profile/README.md +1 -1
- data/examples/profile/controls/example.rb +0 -1
- data/examples/profile/controls/gordon.rb +0 -1
- data/examples/profile/inspec.yml +1 -1
- data/examples/profile-attribute/inspec.yml +1 -1
- 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/inspec.gemspec +10 -2
- data/lib/bundles/inspec-artifact/README.md +1 -0
- data/lib/bundles/inspec-artifact/cli.rb +284 -0
- data/lib/bundles/inspec-artifact.rb +7 -0
- data/lib/bundles/inspec-compliance/README.md +44 -15
- data/lib/bundles/inspec-compliance/api.rb +135 -29
- data/lib/bundles/inspec-compliance/cli.rb +128 -21
- data/lib/bundles/inspec-compliance/configuration.rb +8 -0
- data/lib/bundles/inspec-compliance/http.rb +26 -19
- data/lib/bundles/inspec-compliance/target.rb +50 -25
- data/lib/bundles/inspec-habitat/cli.rb +31 -0
- data/lib/bundles/inspec-habitat/log.rb +10 -0
- data/lib/bundles/inspec-habitat/profile.rb +372 -0
- data/lib/bundles/inspec-habitat.rb +12 -0
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +0 -1
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +1 -1
- data/lib/bundles/inspec-supermarket/api.rb +7 -5
- data/lib/bundles/inspec-supermarket/cli.rb +2 -2
- data/lib/fetchers/git.rb +4 -2
- data/lib/fetchers/local.rb +4 -1
- data/lib/fetchers/url.rb +64 -10
- data/lib/inspec/archive/tar.rb +1 -1
- data/lib/inspec/backend.rb +26 -3
- data/lib/inspec/base_cli.rb +44 -7
- data/lib/inspec/cached_fetcher.rb +2 -2
- data/lib/inspec/cli.rb +34 -12
- data/lib/inspec/completions/fish.sh.erb +34 -0
- data/lib/inspec/control_eval_context.rb +0 -2
- data/lib/inspec/dependencies/cache.rb +0 -1
- data/lib/inspec/dependencies/dependency_set.rb +2 -2
- data/lib/inspec/dependencies/lockfile.rb +13 -6
- data/lib/inspec/dependencies/requirement.rb +6 -6
- data/lib/inspec/dependencies/resolver.rb +4 -4
- data/lib/inspec/dsl.rb +3 -5
- data/lib/inspec/env_printer.rb +9 -1
- data/lib/inspec/exceptions.rb +8 -0
- data/lib/inspec/fetcher.rb +1 -1
- data/lib/inspec/file_provider.rb +47 -11
- data/lib/inspec/library_eval_context.rb +1 -1
- data/lib/inspec/metadata.rb +62 -18
- data/lib/inspec/method_source.rb +24 -0
- data/lib/inspec/objects/attribute.rb +21 -0
- data/lib/inspec/objects/control.rb +21 -3
- data/lib/inspec/objects/each_loop.rb +2 -1
- data/lib/inspec/objects/list.rb +1 -1
- data/lib/inspec/objects/or_test.rb +17 -2
- data/lib/inspec/objects/tag.rb +27 -0
- data/lib/inspec/objects/test.rb +9 -8
- data/lib/inspec/objects.rb +1 -0
- data/lib/inspec/plugins/fetcher.rb +4 -5
- data/lib/inspec/plugins/resource.rb +1 -2
- data/lib/inspec/plugins/source_reader.rb +3 -3
- data/lib/inspec/plugins.rb +1 -1
- data/lib/inspec/polyfill.rb +0 -1
- data/lib/inspec/profile.rb +92 -23
- data/lib/inspec/profile_context.rb +1 -1
- data/lib/inspec/profile_vendor.rb +66 -0
- data/lib/inspec/resource.rb +29 -3
- data/lib/inspec/rspec_json_formatter.rb +672 -285
- data/lib/inspec/rule.rb +12 -16
- data/lib/inspec/runner.rb +26 -15
- data/lib/inspec/runner_rspec.rb +1 -0
- data/lib/inspec/runtime_profile.rb +26 -0
- data/lib/inspec/schema.rb +185 -0
- data/lib/inspec/secrets/yaml.rb +8 -1
- data/lib/inspec/secrets.rb +1 -1
- data/lib/inspec/shell.rb +92 -22
- data/lib/inspec/source_reader.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec.rb +1 -1
- data/lib/matchers/matchers.rb +67 -17
- data/lib/resources/aide_conf.rb +162 -0
- data/lib/resources/apache.rb +0 -1
- data/lib/resources/apache_conf.rb +3 -3
- data/lib/resources/apt.rb +2 -1
- data/lib/resources/audit_policy.rb +0 -1
- data/lib/resources/auditd_conf.rb +1 -2
- data/lib/resources/auditd_rules.rb +5 -5
- data/lib/resources/bond.rb +1 -1
- data/lib/resources/bridge.rb +1 -1
- data/lib/resources/command.rb +5 -3
- data/lib/resources/crontab.rb +102 -0
- data/lib/resources/csv.rb +18 -1
- data/lib/resources/dh_params.rb +84 -0
- data/lib/resources/directory.rb +7 -3
- data/lib/resources/docker.rb +198 -0
- data/lib/resources/docker_container.rb +114 -0
- data/lib/resources/docker_image.rb +96 -0
- data/lib/resources/etc_group.rb +2 -3
- data/lib/resources/etc_hosts.rb +81 -0
- data/lib/resources/file.rb +88 -30
- data/lib/resources/gem.rb +26 -6
- data/lib/resources/groups.rb +4 -5
- data/lib/resources/grub_conf.rb +3 -4
- data/lib/resources/host.rb +175 -35
- data/lib/resources/http.rb +73 -0
- data/lib/resources/iis_app.rb +103 -0
- data/lib/resources/iis_site.rb +23 -0
- data/lib/resources/inetd_conf.rb +9 -4
- data/lib/resources/interface.rb +4 -3
- data/lib/resources/json.rb +37 -14
- data/lib/resources/kernel_module.rb +77 -10
- data/lib/resources/kernel_parameter.rb +0 -1
- data/lib/resources/key_rsa.rb +67 -0
- data/lib/resources/limits_conf.rb +3 -4
- data/lib/resources/login_def.rb +2 -3
- data/lib/resources/mount.rb +34 -4
- data/lib/resources/mssql_session.rb +81 -12
- data/lib/resources/mysql.rb +0 -1
- data/lib/resources/mysql_conf.rb +1 -2
- data/lib/resources/mysql_session.rb +18 -7
- data/lib/resources/nginx_conf.rb +95 -0
- data/lib/resources/ntp_conf.rb +2 -3
- data/lib/resources/oracledb_session.rb +138 -0
- data/lib/resources/os_env.rb +7 -5
- data/lib/resources/package.rb +70 -13
- data/lib/resources/packages.rb +111 -0
- data/lib/resources/parse_config.rb +3 -4
- data/lib/resources/passwd.rb +4 -5
- data/lib/resources/pip.rb +29 -21
- data/lib/resources/port.rb +133 -14
- data/lib/resources/postgres.rb +53 -43
- data/lib/resources/postgres_conf.rb +40 -13
- data/lib/resources/postgres_hba_conf.rb +101 -0
- data/lib/resources/postgres_ident_conf.rb +79 -0
- data/lib/resources/postgres_session.rb +28 -20
- data/lib/resources/powershell.rb +2 -2
- data/lib/resources/processes.rb +61 -26
- data/lib/resources/rabbitmq_conf.rb +53 -0
- data/lib/resources/registry_key.rb +34 -11
- data/lib/resources/security_policy.rb +2 -2
- data/lib/resources/service.rb +17 -7
- data/lib/resources/ssh_conf.rb +17 -6
- data/lib/resources/ssl.rb +3 -4
- data/lib/resources/sys_info.rb +1 -1
- data/lib/resources/toml.rb +26 -0
- data/lib/resources/users.rb +41 -41
- data/lib/resources/virtualization.rb +252 -0
- data/lib/resources/windows_task.rb +106 -0
- data/lib/resources/x509_certificate.rb +143 -0
- data/lib/resources/xinetd.rb +18 -2
- data/lib/resources/xml.rb +27 -0
- data/lib/resources/yaml.rb +10 -2
- data/lib/resources/yum.rb +25 -7
- data/lib/resources/zfs_dataset.rb +60 -0
- data/lib/resources/zfs_pool.rb +49 -0
- data/lib/source_readers/flat.rb +2 -1
- data/lib/source_readers/inspec.rb +30 -11
- data/lib/utils/command_wrapper.rb +3 -3
- data/lib/utils/database_helpers.rb +77 -0
- data/lib/utils/erlang_parser.rb +192 -0
- data/lib/utils/filter.rb +2 -1
- data/lib/utils/filter_array.rb +0 -1
- data/lib/utils/find_files.rb +1 -2
- data/lib/utils/latest_version.rb +21 -0
- data/lib/utils/nginx_parser.rb +76 -0
- data/lib/utils/object_traversal.rb +5 -4
- data/lib/utils/parser.rb +23 -4
- data/lib/utils/plugin_registry.rb +3 -3
- data/lib/utils/simpleconfig.rb +25 -8
- data/lib/utils/spdx.rb +13 -0
- data/lib/utils/spdx.txt +344 -0
- metadata +168 -22
- data/docs/cli.md +0 -342
- data/docs/resources/process.md.erb +0 -73
- /data/docs/{plugin_kitchen_inspec.html.md → plugin_kitchen_inspec.md} +0 -0
|
@@ -1,33 +1,102 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# author: Nolan Davidson
|
|
2
3
|
# author: Christoph Hartmann
|
|
3
4
|
# author: Dominik Richter
|
|
4
5
|
|
|
6
|
+
require 'hashie/mash'
|
|
7
|
+
require 'utils/database_helpers'
|
|
8
|
+
|
|
5
9
|
module Inspec::Resources
|
|
10
|
+
# STABILITY: Experimental
|
|
11
|
+
# This resource needs further testing and refinement
|
|
12
|
+
#
|
|
13
|
+
# This requires the `sqlcmd` tool available on platform
|
|
14
|
+
# @see https://docs.microsoft.com/en-us/sql/relational-databases/scripting/sqlcmd-use-the-utility
|
|
15
|
+
# @see https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-connect-and-query-sqlcmd
|
|
6
16
|
class MssqlSession < Inspec.resource(1)
|
|
7
17
|
name 'mssql_session'
|
|
8
18
|
desc 'Use the mssql_session InSpec audit resource to test SQL commands run against a MS Sql Server database.'
|
|
9
19
|
example "
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
20
|
+
# Using SQL authentication
|
|
21
|
+
sql = mssql_session(user: 'myuser', pass: 'mypassword')
|
|
22
|
+
describe sql.query('SELECT * FROM table').row(0).column('columnname') do
|
|
23
|
+
its('value') { should cmp == 1 }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Passing no credentials to mssql_session forces it to use Windows authentication
|
|
27
|
+
sql_windows_auth = mssql_session
|
|
28
|
+
describe sql.query(\"SELECT SERVERPROPERTY('IsIntegratedSecurityOnly') as \\\"login_mode\\\";\").row(0).column('login_mode') do
|
|
29
|
+
its('value') { should_not be_empty }
|
|
30
|
+
its('value') { should cmp == 1 }
|
|
13
31
|
end
|
|
14
32
|
"
|
|
15
33
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@
|
|
19
|
-
|
|
34
|
+
attr_reader :user, :password, :host
|
|
35
|
+
def initialize(opts = {})
|
|
36
|
+
@user = opts[:user]
|
|
37
|
+
@password = opts[:password] || opts[:pass]
|
|
38
|
+
if opts[:pass]
|
|
39
|
+
warn '[DEPRECATED] use `password` option to supply password instead of `pass`'
|
|
40
|
+
end
|
|
41
|
+
@host = opts[:host] || 'localhost'
|
|
42
|
+
@instance = opts[:instance]
|
|
43
|
+
|
|
44
|
+
# check if sqlcmd is available
|
|
45
|
+
return skip_resource('sqlcmd is missing') if !inspec.command('sqlcmd').exist?
|
|
46
|
+
# check that database is reachable
|
|
47
|
+
return skip_resource("Can't connect to the MS SQL Server.") if !test_connection
|
|
20
48
|
end
|
|
21
49
|
|
|
22
50
|
def query(q)
|
|
23
|
-
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
51
|
+
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
|
|
52
|
+
# surpress 'x rows affected' in SQLCMD with 'set nocount on;'
|
|
53
|
+
cmd_string = "sqlcmd -Q \"set nocount on; #{escaped_query}\" -W -w 1024 -s ','"
|
|
54
|
+
cmd_string += " -U #{@user} -P '#{@password}'" unless @user.nil? || @password.nil?
|
|
55
|
+
if @instance.nil?
|
|
56
|
+
cmd_string += " -S #{@host}"
|
|
57
|
+
else
|
|
58
|
+
cmd_string += " -S #{@host}\\#{@instance}"
|
|
59
|
+
end
|
|
60
|
+
cmd = inspec.command(cmd_string)
|
|
61
|
+
out = cmd.stdout + "\n" + cmd.stderr
|
|
62
|
+
if cmd.exit_status != 0 || out =~ /Sqlcmd: Error/
|
|
63
|
+
# TODO: we need to throw an exception here
|
|
64
|
+
# change once https://github.com/chef/inspec/issues/1205 is in
|
|
65
|
+
warn "Could not execute the sql query #{out}"
|
|
66
|
+
DatabaseHelper::SQLQueryResult.new(cmd, Hashie::Mash.new({}))
|
|
67
|
+
else
|
|
68
|
+
DatabaseHelper::SQLQueryResult.new(cmd, parse_csv_result(cmd))
|
|
69
|
+
end
|
|
27
70
|
end
|
|
28
71
|
|
|
29
72
|
def to_s
|
|
30
|
-
'MSSQL'
|
|
73
|
+
'MSSQL session'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def test_connection
|
|
79
|
+
!query('select getdate()').empty?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def parse_csv_result(cmd)
|
|
83
|
+
require 'csv'
|
|
84
|
+
table = CSV.parse(cmd.stdout, { headers: true })
|
|
85
|
+
|
|
86
|
+
# remove first row, since it will be a seperator line
|
|
87
|
+
table.delete(0)
|
|
88
|
+
|
|
89
|
+
# convert to hash
|
|
90
|
+
headers = table.headers
|
|
91
|
+
|
|
92
|
+
results = table.map { |row|
|
|
93
|
+
res = {}
|
|
94
|
+
headers.each { |header|
|
|
95
|
+
res[header.downcase] = row[header]
|
|
96
|
+
}
|
|
97
|
+
Hashie::Mash.new(res)
|
|
98
|
+
}
|
|
99
|
+
results
|
|
31
100
|
end
|
|
32
101
|
end
|
|
33
102
|
end
|
data/lib/resources/mysql.rb
CHANGED
data/lib/resources/mysql_conf.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# copyright: 2015, Vulcano Security GmbH
|
|
3
3
|
# author: Dominik Richter
|
|
4
|
-
# license: All rights reserved
|
|
5
4
|
|
|
6
5
|
require 'utils/simpleconfig'
|
|
7
6
|
require 'utils/find_files'
|
|
@@ -73,7 +72,7 @@ module Inspec::Resources
|
|
|
73
72
|
return skip_resource "Can't find file \"#{@conf_path}\""
|
|
74
73
|
end
|
|
75
74
|
raw_conf = read_file(@conf_path)
|
|
76
|
-
if raw_conf.empty? && inspec.file(@conf_path).
|
|
75
|
+
if raw_conf.empty? && !inspec.file(@conf_path).empty?
|
|
77
76
|
return skip_resource("Can't read file \"#{@conf_path}\"")
|
|
78
77
|
end
|
|
79
78
|
|
|
@@ -2,22 +2,25 @@
|
|
|
2
2
|
# copyright: 2015, Vulcano Security GmbH
|
|
3
3
|
# author: Dominik Richter
|
|
4
4
|
# author: Christoph Hartmann
|
|
5
|
-
#
|
|
5
|
+
# author: Aaron Lippold
|
|
6
6
|
|
|
7
7
|
module Inspec::Resources
|
|
8
8
|
class MysqlSession < Inspec.resource(1)
|
|
9
9
|
name 'mysql_session'
|
|
10
10
|
desc 'Use the mysql_session InSpec audit resource to test SQL commands run against a MySQL database.'
|
|
11
11
|
example "
|
|
12
|
-
sql = mysql_session('my_user','password')
|
|
12
|
+
sql = mysql_session('my_user','password','host')
|
|
13
13
|
describe sql.query('show databases like \'test\';') do
|
|
14
14
|
its('stdout') { should_not match(/test/) }
|
|
15
15
|
end
|
|
16
16
|
"
|
|
17
17
|
|
|
18
|
-
def initialize(user = nil, pass = nil)
|
|
18
|
+
def initialize(user = nil, pass = nil, host = 'localhost', port = nil, socket = nil)
|
|
19
19
|
@user = user
|
|
20
20
|
@pass = pass
|
|
21
|
+
@host = host
|
|
22
|
+
@port = port
|
|
23
|
+
@socket = socket
|
|
21
24
|
init_fallback if user.nil? or pass.nil?
|
|
22
25
|
skip_resource("Can't run MySQL SQL checks without authentication") if @user.nil? or @pass.nil?
|
|
23
26
|
end
|
|
@@ -28,12 +31,20 @@ module Inspec::Resources
|
|
|
28
31
|
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
|
|
29
32
|
|
|
30
33
|
# run the query
|
|
31
|
-
|
|
34
|
+
command = "mysql -u#{@user} -p#{@pass}"
|
|
35
|
+
if !@socket.nil?
|
|
36
|
+
command += " -S #{@socket}"
|
|
37
|
+
else
|
|
38
|
+
command += " -h #{@host}"
|
|
39
|
+
end
|
|
40
|
+
command += " --port #{@port}" unless @port.nil?
|
|
41
|
+
command += " #{db} -s -e \"#{escaped_query}\""
|
|
42
|
+
|
|
43
|
+
cmd = inspec.command(command)
|
|
32
44
|
out = cmd.stdout + "\n" + cmd.stderr
|
|
33
|
-
if out =~ /Can't connect to .* MySQL server/
|
|
34
|
-
out.downcase =~ /^error/
|
|
45
|
+
if out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error/
|
|
35
46
|
# skip this test if the server can't run the query
|
|
36
|
-
|
|
47
|
+
warn("Can't connect to MySQL instance for SQL checks.")
|
|
37
48
|
end
|
|
38
49
|
|
|
39
50
|
# return the raw command output
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Dominik Richter
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
|
|
5
|
+
require 'utils/nginx_parser'
|
|
6
|
+
|
|
7
|
+
# STABILITY: Experimental
|
|
8
|
+
# This resouce needs a proper interace to the underlying data, which is currently missing.
|
|
9
|
+
# Until it is added, we will keep it experimental.
|
|
10
|
+
#
|
|
11
|
+
# TODO: Support it on Windows. To do so, we need to recognize the base os and how
|
|
12
|
+
# it combines the file path. Calling `File.join` or similar methods may lead to errors
|
|
13
|
+
# when running remotely.
|
|
14
|
+
module Inspec::Resources
|
|
15
|
+
class NginxConf < Inspec.resource(1)
|
|
16
|
+
name 'nginx_conf'
|
|
17
|
+
desc 'Use the nginx_conf InSpec resource to test configuration data '\
|
|
18
|
+
'for the NginX web server located in /etc/nginx/nginx.conf on '\
|
|
19
|
+
'Linux and UNIX platforms.'
|
|
20
|
+
example "
|
|
21
|
+
describe nginx_conf.params ...
|
|
22
|
+
describe nginx_conf('/path/to/my/nginx.conf').params ...
|
|
23
|
+
"
|
|
24
|
+
|
|
25
|
+
attr_reader :contents
|
|
26
|
+
|
|
27
|
+
def initialize(conf_path = nil)
|
|
28
|
+
@conf_path = conf_path || '/etc/nginx/nginx.conf'
|
|
29
|
+
@contents = {}
|
|
30
|
+
return skip_resource 'The `nginx_conf` resource is currently not supported on Windows.' if inspec.os.windows?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def params
|
|
34
|
+
@params ||= parse_nginx(@conf_path)
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
skip_resource e.message
|
|
37
|
+
@params = {}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def to_s
|
|
41
|
+
"nginx_conf #{@conf_path}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def read_content(path)
|
|
47
|
+
return @contents[path] if @contents.key?(path)
|
|
48
|
+
file = inspec.file(path)
|
|
49
|
+
if !file.file?
|
|
50
|
+
return skip_resource "Can't find file \"#{path}\""
|
|
51
|
+
end
|
|
52
|
+
@contents[path] = file.content
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def parse_nginx(path)
|
|
56
|
+
return nil if inspec.os.windows?
|
|
57
|
+
content = read_content(path)
|
|
58
|
+
data = NginxConfig.parse(content)
|
|
59
|
+
resolve_references(data, File.dirname(path))
|
|
60
|
+
rescue StandardError => _
|
|
61
|
+
raise "Cannot parse NginX config in #{path}."
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Cycle through the complete parsed data structure and try to find any
|
|
65
|
+
# calls to `include`. In NginX, this is used to embed data from other
|
|
66
|
+
# files into the current data structure.
|
|
67
|
+
#
|
|
68
|
+
# The method steps through the object structure that is passed in to
|
|
69
|
+
# find any calls to 'include' and returns the object structure with the
|
|
70
|
+
# included data merged in.
|
|
71
|
+
#
|
|
72
|
+
# @param data [Hash] data structure from NginxConfig.parse
|
|
73
|
+
# @param rel_path [String] the relative path from which this config is read
|
|
74
|
+
# @return [Hash] data structure with references included
|
|
75
|
+
def resolve_references(data, rel_path)
|
|
76
|
+
# Walk through all array entries to find more references
|
|
77
|
+
return data.map { |x| resolve_references(x, rel_path) } if data.is_a?(Array)
|
|
78
|
+
|
|
79
|
+
# Return any data that we cannot step into to find more `include` calls
|
|
80
|
+
return data unless data.is_a?(Hash)
|
|
81
|
+
|
|
82
|
+
# Any call to `include` gets its data read, parsed, and merged back
|
|
83
|
+
# into the current data structure
|
|
84
|
+
if data.key?('include')
|
|
85
|
+
data.delete('include').flatten
|
|
86
|
+
.map { |x| File.expand_path(x, rel_path) }
|
|
87
|
+
.map { |path| parse_nginx(path) }
|
|
88
|
+
.map { |e| data.merge!(e) }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Walk through the remaining hash fields to find more references
|
|
92
|
+
Hash[data.map { |k, v| [k, resolve_references(v, rel_path)] }]
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
data/lib/resources/ntp_conf.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
# copyright: 2015, Vulcano Security GmbH
|
|
3
3
|
# author: Christoph Hartmann
|
|
4
4
|
# author: Dominik Richter
|
|
5
|
-
# license: All rights reserved
|
|
6
5
|
|
|
7
6
|
require 'utils/simpleconfig'
|
|
8
7
|
|
|
@@ -43,7 +42,7 @@ module Inspec::Resources
|
|
|
43
42
|
end
|
|
44
43
|
|
|
45
44
|
content = inspec.file(@conf_path).content
|
|
46
|
-
if content.empty? && inspec.file(@conf_path).
|
|
45
|
+
if content.empty? && !inspec.file(@conf_path).empty?
|
|
47
46
|
skip_resource "Can't read file \"#{@conf_path}\""
|
|
48
47
|
return @params = {}
|
|
49
48
|
end
|
|
@@ -51,7 +50,7 @@ module Inspec::Resources
|
|
|
51
50
|
# parse the file
|
|
52
51
|
conf = SimpleConfig.new(
|
|
53
52
|
content,
|
|
54
|
-
|
|
53
|
+
assignment_regex: /^\s*(\S+)\s+(.*)\s*$/,
|
|
55
54
|
multiple_values: true,
|
|
56
55
|
)
|
|
57
56
|
@params = conf.params
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Nolan Davidson
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
# author: Dominik Richter
|
|
5
|
+
|
|
6
|
+
require 'hashie/mash'
|
|
7
|
+
require 'utils/database_helpers'
|
|
8
|
+
require 'htmlentities'
|
|
9
|
+
require 'rexml/document'
|
|
10
|
+
require 'csv'
|
|
11
|
+
|
|
12
|
+
module Inspec::Resources
|
|
13
|
+
# STABILITY: Experimental
|
|
14
|
+
# This resource needs further testing and refinement
|
|
15
|
+
#
|
|
16
|
+
class OracledbSession < Inspec.resource(1)
|
|
17
|
+
name 'oracledb_session'
|
|
18
|
+
desc 'Use the oracledb_session InSpec resource to test commands against an Oracle database'
|
|
19
|
+
example "
|
|
20
|
+
sql = oracledb_session(user: 'my_user', pass: 'password')
|
|
21
|
+
describe sql.query(\"SELECT UPPER(VALUE) AS VALUE FROM V$PARAMETER WHERE UPPER(NAME)='AUDIT_SYS_OPERATIONS'\").row(0).column('value') do
|
|
22
|
+
its('value') { should eq 'TRUE' }
|
|
23
|
+
end
|
|
24
|
+
"
|
|
25
|
+
|
|
26
|
+
attr_reader :user, :password, :host, :service
|
|
27
|
+
def initialize(opts = {})
|
|
28
|
+
@user = opts[:user]
|
|
29
|
+
@password = opts[:password] || opts[:pass]
|
|
30
|
+
if opts[:pass]
|
|
31
|
+
warn '[DEPRECATED] use `password` option to supply password instead of `pass`'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@host = opts[:host] || 'localhost'
|
|
35
|
+
@port = opts[:port] || '1521'
|
|
36
|
+
@service = opts[:service]
|
|
37
|
+
|
|
38
|
+
# we prefer sqlci although it is way slower than sqlplus, but it understands csv properly
|
|
39
|
+
@sqlcl_bin = 'sql'
|
|
40
|
+
@sqlplus_bin = opts[:sqlplus_bin] || 'sqlplus'
|
|
41
|
+
|
|
42
|
+
return skip_resource "Can't run Oracle checks without authentication" if @user.nil? || @password.nil?
|
|
43
|
+
return skip_resource 'You must provide a service name for the session' if @service.nil?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def query(q)
|
|
47
|
+
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"')
|
|
48
|
+
# escape tables with $
|
|
49
|
+
escaped_query = escaped_query.gsub('$', '\\$')
|
|
50
|
+
|
|
51
|
+
p = nil
|
|
52
|
+
# use sqlplus if sqlcl is not available
|
|
53
|
+
if inspec.command(@sqlcl_bin).exist?
|
|
54
|
+
bin = @sqlcl_bin
|
|
55
|
+
opts = "set sqlformat csv\nSET FEEDBACK OFF"
|
|
56
|
+
p = :parse_csv_result
|
|
57
|
+
else
|
|
58
|
+
bin = @sqlplus_bin
|
|
59
|
+
opts = "SET MARKUP HTML ON\nSET FEEDBACK OFF"
|
|
60
|
+
p = :parse_html_result
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
command = "echo \"#{opts}\n#{verify_query(escaped_query)}\nEXIT\" | #{bin} -s #{@user}/#{@password}@//#{@host}:#{@port}/#{@service}"
|
|
64
|
+
cmd = inspec.command(command)
|
|
65
|
+
|
|
66
|
+
out = cmd.stdout + "\n" + cmd.stderr
|
|
67
|
+
if out.downcase =~ /^error/
|
|
68
|
+
# TODO: we need to throw an exception here
|
|
69
|
+
# change once https://github.com/chef/inspec/issues/1205 is in
|
|
70
|
+
warn "Could not execute the sql query #{out}"
|
|
71
|
+
DatabaseHelper::SQLQueryResult.new(cmd, Hashie::Mash.new({}))
|
|
72
|
+
end
|
|
73
|
+
DatabaseHelper::SQLQueryResult.new(cmd, send(p, cmd.stdout))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def to_s
|
|
77
|
+
'Oracle Session'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def verify_query(query)
|
|
83
|
+
# ensure we have a ; at the end
|
|
84
|
+
query + ';' if !query.strip.end_with?(';')
|
|
85
|
+
query
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def parse_csv_result(stdout)
|
|
89
|
+
output = stdout.delete(/\r/)
|
|
90
|
+
table = CSV.parse(output, { headers: true })
|
|
91
|
+
|
|
92
|
+
# convert to hash
|
|
93
|
+
headers = table.headers
|
|
94
|
+
|
|
95
|
+
results = table.map { |row|
|
|
96
|
+
res = {}
|
|
97
|
+
headers.each { |header|
|
|
98
|
+
res[header.downcase] = row[header]
|
|
99
|
+
}
|
|
100
|
+
Hashie::Mash.new(res)
|
|
101
|
+
}
|
|
102
|
+
results
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def parse_html_result(stdout) # rubocop:disable Metrics/AbcSize
|
|
106
|
+
result = stdout
|
|
107
|
+
# make oracle html valid html by removing the p tag, it does not include a closing tag
|
|
108
|
+
result = result.gsub('<p>', '').gsub('</p>', '').gsub('<br>', '')
|
|
109
|
+
doc = REXML::Document.new result
|
|
110
|
+
table = doc.elements['table']
|
|
111
|
+
hash = []
|
|
112
|
+
if !table.nil?
|
|
113
|
+
rows = table.elements.to_a
|
|
114
|
+
headers = rows[0].elements.to_a('th').map { |entry| entry.text.strip }
|
|
115
|
+
rows.delete_at(0)
|
|
116
|
+
|
|
117
|
+
# iterate over each row, first row is header
|
|
118
|
+
hash = []
|
|
119
|
+
if !rows.nil? && !rows.empty?
|
|
120
|
+
hash = rows.map { |row|
|
|
121
|
+
res = {}
|
|
122
|
+
entries = row.elements.to_a('td')
|
|
123
|
+
# ignore if we have empty entries, oracle is adding th rows in between
|
|
124
|
+
return nil if entries.empty?
|
|
125
|
+
headers.each_with_index { |header, index|
|
|
126
|
+
# we need htmlentities since we do not have nokogiri
|
|
127
|
+
coder = HTMLEntities.new
|
|
128
|
+
val = coder.decode(entries[index].text).strip
|
|
129
|
+
res[header.downcase] = val
|
|
130
|
+
}
|
|
131
|
+
Hashie::Mash.new(res)
|
|
132
|
+
}.compact
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
hash
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
data/lib/resources/os_env.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
# copyright: 2015, Vulcano Security GmbH
|
|
3
3
|
# author: Christoph Hartmann
|
|
4
4
|
# author: Dominik Richter
|
|
5
|
-
# license: All rights reserved
|
|
6
5
|
|
|
7
6
|
# Usage:
|
|
8
7
|
#
|
|
@@ -26,8 +25,6 @@ module Inspec::Resources
|
|
|
26
25
|
attr_reader :content
|
|
27
26
|
def initialize(env = nil)
|
|
28
27
|
@osenv = env
|
|
29
|
-
@content = nil
|
|
30
|
-
@content = value_for(env) unless env.nil?
|
|
31
28
|
end
|
|
32
29
|
|
|
33
30
|
def split
|
|
@@ -36,7 +33,12 @@ module Inspec::Resources
|
|
|
36
33
|
path_separator = inspec.os.windows? ? ';' : ':'
|
|
37
34
|
# -1 is required to catch cases like dir1::dir2:
|
|
38
35
|
# where we have a trailing :
|
|
39
|
-
|
|
36
|
+
content.nil? ? [] : content.split(path_separator, -1)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def content
|
|
40
|
+
return @content if defined?(@content)
|
|
41
|
+
@content = value_for(@osenv) unless @osenv.nil?
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
def to_s
|
|
@@ -59,7 +61,7 @@ module Inspec::Resources
|
|
|
59
61
|
out = inspec.command(command)
|
|
60
62
|
|
|
61
63
|
unless out.exit_status == 0
|
|
62
|
-
skip_resource "Can't read environment variables on #{os
|
|
64
|
+
skip_resource "Can't read environment variables on #{inspec.os.name}. "\
|
|
63
65
|
"Tried `#{command}` which returned #{out.exit_status}"
|
|
64
66
|
end
|
|
65
67
|
|
data/lib/resources/package.rb
CHANGED
|
@@ -15,11 +15,12 @@ module Inspec::Resources
|
|
|
15
15
|
example "
|
|
16
16
|
describe package('nginx') do
|
|
17
17
|
it { should be_installed }
|
|
18
|
+
it { should_not be_held } # for dpkg platforms that support holding a version from being upgraded
|
|
18
19
|
its('version') { should eq 1.9.5 }
|
|
19
20
|
end
|
|
20
21
|
"
|
|
21
22
|
|
|
22
|
-
def initialize(package_name = nil) # rubocop:disable Metrics/AbcSize
|
|
23
|
+
def initialize(package_name = nil, opts = {}) # rubocop:disable Metrics/AbcSize
|
|
23
24
|
@package_name = package_name
|
|
24
25
|
@name = @package_name
|
|
25
26
|
@cache = nil
|
|
@@ -29,8 +30,8 @@ module Inspec::Resources
|
|
|
29
30
|
os = inspec.os
|
|
30
31
|
if os.debian?
|
|
31
32
|
@pkgman = Deb.new(inspec)
|
|
32
|
-
elsif %w{
|
|
33
|
-
@pkgman = Rpm.new(inspec)
|
|
33
|
+
elsif os.redhat? || %w{suse amazon fedora}.include?(os[:family])
|
|
34
|
+
@pkgman = Rpm.new(inspec, opts)
|
|
34
35
|
elsif ['arch'].include?(os[:family])
|
|
35
36
|
@pkgman = Pacman.new(inspec)
|
|
36
37
|
elsif ['darwin'].include?(os[:family])
|
|
@@ -46,6 +47,8 @@ module Inspec::Resources
|
|
|
46
47
|
else
|
|
47
48
|
return skip_resource 'The `package` resource is not supported on your OS yet.'
|
|
48
49
|
end
|
|
50
|
+
|
|
51
|
+
evaluate_missing_requirements
|
|
49
52
|
end
|
|
50
53
|
|
|
51
54
|
# returns true if the package is installed
|
|
@@ -54,6 +57,13 @@ module Inspec::Resources
|
|
|
54
57
|
info[:installed] == true
|
|
55
58
|
end
|
|
56
59
|
|
|
60
|
+
# returns true it the package is held (if the OS supports it)
|
|
61
|
+
def held?(_provider = nil, _version = nil)
|
|
62
|
+
return false if info.nil?
|
|
63
|
+
return false unless info.key?(:held)
|
|
64
|
+
info[:held] == true
|
|
65
|
+
end
|
|
66
|
+
|
|
57
67
|
# returns the package description
|
|
58
68
|
def info
|
|
59
69
|
return @cache if !@cache.nil?
|
|
@@ -71,6 +81,14 @@ module Inspec::Resources
|
|
|
71
81
|
def to_s
|
|
72
82
|
"System Package #{@package_name}"
|
|
73
83
|
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def evaluate_missing_requirements
|
|
88
|
+
missing_requirements_string = @pkgman.missing_requirements.uniq.join(', ')
|
|
89
|
+
return if missing_requirements_string.empty?
|
|
90
|
+
skip_resource "The following requirements are not met for this resource: #{missing_requirements_string}"
|
|
91
|
+
end
|
|
74
92
|
end
|
|
75
93
|
|
|
76
94
|
class PkgManagement
|
|
@@ -78,6 +96,12 @@ module Inspec::Resources
|
|
|
78
96
|
def initialize(inspec)
|
|
79
97
|
@inspec = inspec
|
|
80
98
|
end
|
|
99
|
+
|
|
100
|
+
def missing_requirements
|
|
101
|
+
# Each provider can provide an Array of missing requirements that will be
|
|
102
|
+
# combined into a `skip_resource` message
|
|
103
|
+
[]
|
|
104
|
+
end
|
|
81
105
|
end
|
|
82
106
|
|
|
83
107
|
# Debian / Ubuntu
|
|
@@ -88,14 +112,17 @@ module Inspec::Resources
|
|
|
88
112
|
|
|
89
113
|
params = SimpleConfig.new(
|
|
90
114
|
cmd.stdout.chomp,
|
|
91
|
-
|
|
115
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
92
116
|
multiple_values: false,
|
|
93
117
|
).params
|
|
118
|
+
# If the package is installed, Status is "install ok installed"
|
|
119
|
+
# If the package is installed and marked hold, Status is "hold ok installed"
|
|
94
120
|
# If the package is removed and not purged, Status is "deinstall ok config-files" with exit_status 0
|
|
95
121
|
# If the package is purged cmd fails with non-zero exit status
|
|
96
122
|
{
|
|
97
123
|
name: params['Package'],
|
|
98
|
-
installed: params['Status'].split(' ')
|
|
124
|
+
installed: params['Status'].split(' ')[2] == 'installed',
|
|
125
|
+
held: params['Status'].split(' ')[0] == 'hold',
|
|
99
126
|
version: params['Version'],
|
|
100
127
|
type: 'deb',
|
|
101
128
|
}
|
|
@@ -104,14 +131,31 @@ module Inspec::Resources
|
|
|
104
131
|
|
|
105
132
|
# RHEL family
|
|
106
133
|
class Rpm < PkgManagement
|
|
134
|
+
def initialize(inspec, opts)
|
|
135
|
+
super(inspec)
|
|
136
|
+
|
|
137
|
+
@dbpath = opts.fetch(:rpm_dbpath, nil)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def missing_requirements
|
|
141
|
+
missing_requirements = []
|
|
142
|
+
|
|
143
|
+
unless @dbpath.nil? || inspec.directory(@dbpath).directory?
|
|
144
|
+
missing_requirements << "RPMDB #{@dbpath} does not exist"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
missing_requirements
|
|
148
|
+
end
|
|
149
|
+
|
|
107
150
|
def info(package_name)
|
|
108
|
-
|
|
151
|
+
rpm_cmd = rpm_command(package_name)
|
|
152
|
+
cmd = inspec.command(rpm_cmd)
|
|
109
153
|
# CentOS does not return an error code if the package is not installed,
|
|
110
154
|
# therefore we need to check for emptyness
|
|
111
155
|
return nil if cmd.exit_status.to_i != 0 || cmd.stdout.chomp.empty?
|
|
112
156
|
params = SimpleConfig.new(
|
|
113
157
|
cmd.stdout.chomp,
|
|
114
|
-
|
|
158
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
115
159
|
multiple_values: false,
|
|
116
160
|
).params
|
|
117
161
|
# On some (all?) systems, the linebreak before the vendor line is missing
|
|
@@ -133,6 +177,17 @@ module Inspec::Resources
|
|
|
133
177
|
type: 'rpm',
|
|
134
178
|
}
|
|
135
179
|
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
def rpm_command(package_name)
|
|
184
|
+
cmd = ''
|
|
185
|
+
cmd += 'rpm -qia'
|
|
186
|
+
cmd += " --dbpath #{@dbpath}" if @dbpath
|
|
187
|
+
cmd += ' ' + package_name
|
|
188
|
+
|
|
189
|
+
cmd
|
|
190
|
+
end
|
|
136
191
|
end
|
|
137
192
|
|
|
138
193
|
# MacOS / Darwin implementation
|
|
@@ -143,11 +198,13 @@ module Inspec::Resources
|
|
|
143
198
|
# parse data
|
|
144
199
|
pkg = JSON.parse(cmd.stdout)[0]
|
|
145
200
|
{
|
|
146
|
-
name: pkg
|
|
201
|
+
name: pkg['name'],
|
|
147
202
|
installed: true,
|
|
148
|
-
version: pkg
|
|
203
|
+
version: pkg['installed'][0]['version'],
|
|
149
204
|
type: 'brew',
|
|
150
205
|
}
|
|
206
|
+
rescue JSON::ParserError => _e
|
|
207
|
+
return nil
|
|
151
208
|
end
|
|
152
209
|
end
|
|
153
210
|
|
|
@@ -159,7 +216,7 @@ module Inspec::Resources
|
|
|
159
216
|
|
|
160
217
|
params = SimpleConfig.new(
|
|
161
218
|
cmd.stdout.chomp,
|
|
162
|
-
|
|
219
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
163
220
|
multiple_values: false,
|
|
164
221
|
).params
|
|
165
222
|
|
|
@@ -204,7 +261,7 @@ module Inspec::Resources
|
|
|
204
261
|
# Find the package
|
|
205
262
|
cmd = inspec.command <<-EOF.gsub(/^\s*/, '')
|
|
206
263
|
Get-ItemProperty (@("#{search_paths.join('", "')}") | Where-Object { Test-Path $_ }) |
|
|
207
|
-
Where-Object { $_.DisplayName -like "#{package_name}
|
|
264
|
+
Where-Object { $_.DisplayName -like "#{package_name}" -or $_.PSChildName -like "#{package_name}" } |
|
|
208
265
|
Select-Object -Property DisplayName,DisplayVersion | ConvertTo-Json
|
|
209
266
|
EOF
|
|
210
267
|
|
|
@@ -259,7 +316,7 @@ module Inspec::Resources
|
|
|
259
316
|
|
|
260
317
|
params = SimpleConfig.new(
|
|
261
318
|
cmd.stdout.chomp,
|
|
262
|
-
|
|
319
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
263
320
|
multiple_values: false,
|
|
264
321
|
).params
|
|
265
322
|
|
|
@@ -280,7 +337,7 @@ module Inspec::Resources
|
|
|
280
337
|
|
|
281
338
|
params = SimpleConfig.new(
|
|
282
339
|
cmd.stdout.chomp,
|
|
283
|
-
|
|
340
|
+
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
|
284
341
|
multiple_values: false,
|
|
285
342
|
).params
|
|
286
343
|
|