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
|
@@ -2,7 +2,7 @@
|
|
|
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
|
require 'utils/simpleconfig'
|
|
8
8
|
require 'utils/find_files'
|
|
@@ -19,9 +19,13 @@ module Inspec::Resources
|
|
|
19
19
|
"
|
|
20
20
|
|
|
21
21
|
include FindFiles
|
|
22
|
+
include ObjectTraverser
|
|
22
23
|
|
|
23
24
|
def initialize(conf_path = nil)
|
|
24
25
|
@conf_path = conf_path || inspec.postgres.conf_path
|
|
26
|
+
if @conf_path.nil?
|
|
27
|
+
return skip_resource 'PostgreSQL conf path is not set'
|
|
28
|
+
end
|
|
25
29
|
@conf_dir = File.expand_path(File.dirname(@conf_path))
|
|
26
30
|
@files_contents = {}
|
|
27
31
|
@content = nil
|
|
@@ -42,6 +46,25 @@ module Inspec::Resources
|
|
|
42
46
|
res
|
|
43
47
|
end
|
|
44
48
|
|
|
49
|
+
def value(key)
|
|
50
|
+
extract_value(key, @params)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def method_missing(*keys)
|
|
54
|
+
keys.shift if keys.is_a?(Array) && keys[0] == :[]
|
|
55
|
+
param = value(keys)
|
|
56
|
+
return nil if param.nil?
|
|
57
|
+
# extract first value if we have only one value in array
|
|
58
|
+
return param[0] if param.length == 1
|
|
59
|
+
param
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_s
|
|
63
|
+
'PostgreSQL Configuration'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
45
68
|
def read_content
|
|
46
69
|
@content = ''
|
|
47
70
|
@params = {}
|
|
@@ -51,34 +74,42 @@ module Inspec::Resources
|
|
|
51
74
|
return skip_resource "Can't find file \"#{@conf_path}\""
|
|
52
75
|
end
|
|
53
76
|
raw_conf = read_file(@conf_path)
|
|
54
|
-
if raw_conf.empty? && inspec.file(@conf_path).
|
|
77
|
+
if raw_conf.empty? && !inspec.file(@conf_path).empty?
|
|
55
78
|
return skip_resource("Can't read file \"#{@conf_path}\"")
|
|
56
79
|
end
|
|
57
80
|
|
|
58
81
|
to_read = [@conf_path]
|
|
59
82
|
until to_read.empty?
|
|
83
|
+
base_dir = File.dirname(to_read[0])
|
|
60
84
|
raw_conf = read_file(to_read[0])
|
|
61
85
|
@content += raw_conf
|
|
62
86
|
|
|
63
|
-
|
|
87
|
+
opts = {
|
|
88
|
+
assignment_regex: /^\s*([^=]*?)\s*=\s*[']?\s*(.*?)\s*[']?\s*$/,
|
|
89
|
+
}
|
|
90
|
+
params = SimpleConfig.new(raw_conf, opts).params
|
|
64
91
|
@params.merge!(params)
|
|
65
92
|
|
|
66
93
|
to_read = to_read.drop(1)
|
|
67
94
|
# see if there is more config files to include
|
|
68
95
|
|
|
69
|
-
to_read += include_files(params).find_all do |fp|
|
|
96
|
+
to_read += include_files(params, base_dir).find_all do |fp|
|
|
70
97
|
not @files_contents.key? fp
|
|
71
98
|
end
|
|
72
99
|
end
|
|
73
100
|
@content
|
|
74
101
|
end
|
|
75
102
|
|
|
76
|
-
def include_files(params)
|
|
77
|
-
include_files = params['include'] || []
|
|
78
|
-
include_files += params['include_if_exists'] || []
|
|
79
|
-
|
|
103
|
+
def include_files(params, base_dir)
|
|
104
|
+
include_files = Array(params['include']) || []
|
|
105
|
+
include_files += Array(params['include_if_exists']) || []
|
|
106
|
+
include_files.map! do |f|
|
|
107
|
+
Pathname.new(f).absolute? ? f : File.join(base_dir, f)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
dirs = Array(params['include_dir']) || []
|
|
80
111
|
dirs.each do |dir|
|
|
81
|
-
dir = File.join(
|
|
112
|
+
dir = File.join(base_dir, dir) if dir[0] != '/'
|
|
82
113
|
include_files += find_files(dir, depth: 1, type: 'file')
|
|
83
114
|
end
|
|
84
115
|
include_files
|
|
@@ -87,9 +118,5 @@ module Inspec::Resources
|
|
|
87
118
|
def read_file(path)
|
|
88
119
|
@files_contents[path] ||= inspec.file(path).content
|
|
89
120
|
end
|
|
90
|
-
|
|
91
|
-
def to_s
|
|
92
|
-
'PostgreSQL Configuration'
|
|
93
|
-
end
|
|
94
121
|
end
|
|
95
122
|
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Rony Xavier,rx294@nyu.edu
|
|
3
|
+
# author: Aaron Lippold, lippold@gmail.com
|
|
4
|
+
|
|
5
|
+
require 'resources/postgres'
|
|
6
|
+
|
|
7
|
+
module Inspec::Resources
|
|
8
|
+
class PostgresHbaConf < Inspec.resource(1)
|
|
9
|
+
name 'postgres_hba_conf'
|
|
10
|
+
desc 'Use the `postgres_hba_conf` InSpec audit resource to test the client
|
|
11
|
+
authentication data defined in the pg_hba.conf file.'
|
|
12
|
+
example "
|
|
13
|
+
describe postgres_hba_conf.where { type == 'local' } do
|
|
14
|
+
its('auth_method') { should eq ['peer'] }
|
|
15
|
+
end
|
|
16
|
+
"
|
|
17
|
+
|
|
18
|
+
attr_reader :conf_file, :params
|
|
19
|
+
|
|
20
|
+
# @todo add checks to ensure that we have data in our file
|
|
21
|
+
def initialize(hba_conf_path = nil)
|
|
22
|
+
return skip_resource 'The `postgres_hba_conf` resource is not supported on your OS.' unless inspec.os.linux?
|
|
23
|
+
@conf_file = hba_conf_path || File.expand_path('pg_hba.conf', inspec.postgres.conf_dir)
|
|
24
|
+
@content = ''
|
|
25
|
+
@params = {}
|
|
26
|
+
read_content
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
filter = FilterTable.create
|
|
30
|
+
filter.add_accessor(:where)
|
|
31
|
+
.add_accessor(:entries)
|
|
32
|
+
.add(:type, field: 'type')
|
|
33
|
+
.add(:database, field: 'database')
|
|
34
|
+
.add(:user, field: 'user')
|
|
35
|
+
.add(:address, field: 'address')
|
|
36
|
+
.add(:auth_method, field: 'auth_method')
|
|
37
|
+
.add(:auth_params, field: 'auth_params')
|
|
38
|
+
|
|
39
|
+
filter.connect(self, :params)
|
|
40
|
+
|
|
41
|
+
def to_s
|
|
42
|
+
"Postgres Hba Config #{@conf_file}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def clean_conf_file(conf_file = @conf_file)
|
|
48
|
+
data = inspec.file(conf_file).content.to_s.lines
|
|
49
|
+
content = []
|
|
50
|
+
data.each do |line|
|
|
51
|
+
line.chomp!
|
|
52
|
+
content << line unless line.match(/^\s*#/) || line.empty?
|
|
53
|
+
end
|
|
54
|
+
content
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def read_content(config_file = @conf_file)
|
|
58
|
+
file = inspec.file(config_file)
|
|
59
|
+
|
|
60
|
+
if !file.file?
|
|
61
|
+
return skip_resource "Can't find file \"#{@conf_file}\""
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
raw_conf = file.content
|
|
65
|
+
|
|
66
|
+
if raw_conf.empty? && !file.empty?
|
|
67
|
+
return skip_resource("Can't read the contents of \"#{@conf_file}\"")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @todo use SimpleConfig here if we can
|
|
71
|
+
# ^\s*(\S+)\s+(\S+)\s+(\S+)\s(?:(\d*.\d*.\d*.\d*\/\d*)|(::\/\d+))\s+(\S+)\s*(.*)?\s*$
|
|
72
|
+
|
|
73
|
+
@content = clean_conf_file(@conf_file)
|
|
74
|
+
@params = parse_conf(@content)
|
|
75
|
+
@params.each do |line|
|
|
76
|
+
if line['type'] == 'local'
|
|
77
|
+
line['auth_method'] = line['address']
|
|
78
|
+
line['address'] = ''
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def parse_conf(content)
|
|
84
|
+
content.map do |line|
|
|
85
|
+
parse_line(line)
|
|
86
|
+
end.compact
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def parse_line(line)
|
|
90
|
+
x = line.split(/\s+/)
|
|
91
|
+
{
|
|
92
|
+
'type' => x[0],
|
|
93
|
+
'database' => x[1],
|
|
94
|
+
'user' => x[2],
|
|
95
|
+
'address' => x[3],
|
|
96
|
+
'auth_method' => x[4],
|
|
97
|
+
'auth_params' => ('' if x.length == 4) || x[5..-1].join(' '),
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Rony Xavier, rx294@nyu.edu
|
|
3
|
+
# author: Aaron Lippold, lippold@gmail.com
|
|
4
|
+
|
|
5
|
+
require 'resources/postgres'
|
|
6
|
+
|
|
7
|
+
module Inspec::Resources
|
|
8
|
+
class PostgresIdentConf < Inspec.resource(1)
|
|
9
|
+
name 'postgres_ident_conf'
|
|
10
|
+
desc 'Use the postgres_ident_conf InSpec audit resource to test the client
|
|
11
|
+
authentication data is controlled by a pg_ident.conf file.'
|
|
12
|
+
example "
|
|
13
|
+
describe postgres_ident_conf.where { pg_username == 'acme_user' } do
|
|
14
|
+
its('map_name') { should eq ['ssl-test'] }
|
|
15
|
+
end
|
|
16
|
+
"
|
|
17
|
+
|
|
18
|
+
attr_reader :params, :conf_file
|
|
19
|
+
|
|
20
|
+
def initialize(ident_conf_path = nil)
|
|
21
|
+
return skip_resource 'The `postgres_ident_conf` resource is not supported on your OS.' unless inspec.os.linux?
|
|
22
|
+
@conf_file = ident_conf_path || File.expand_path('pg_ident.conf', inspec.postgres.conf_dir)
|
|
23
|
+
@content = nil
|
|
24
|
+
@params = nil
|
|
25
|
+
read_content
|
|
26
|
+
return skip_resource '`pg_ident_conf` is not yet supported on your OS' if inspec.os.windows?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
filter = FilterTable.create
|
|
30
|
+
filter.add_accessor(:where)
|
|
31
|
+
.add_accessor(:entries)
|
|
32
|
+
.add(:map_name, field: 'map_name')
|
|
33
|
+
.add(:system_username, field: 'system_username')
|
|
34
|
+
.add(:pg_username, field: 'pg_username')
|
|
35
|
+
|
|
36
|
+
filter.connect(self, :params)
|
|
37
|
+
|
|
38
|
+
def to_s
|
|
39
|
+
"PostgreSQL Ident Config #{@conf_file}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def filter_comments(data)
|
|
45
|
+
content = []
|
|
46
|
+
data.each do |line|
|
|
47
|
+
line.chomp!
|
|
48
|
+
content << line unless line.match(/^\s*#/) || line.empty?
|
|
49
|
+
end
|
|
50
|
+
content
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def read_content
|
|
54
|
+
@content = ''
|
|
55
|
+
@params = {}
|
|
56
|
+
@content = filter_comments(read_file(@conf_file))
|
|
57
|
+
@params = parse_conf(@content)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def parse_conf(content)
|
|
61
|
+
content.map do |line|
|
|
62
|
+
parse_line(line)
|
|
63
|
+
end.compact
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def parse_line(line)
|
|
67
|
+
x = line.split(/\s+/)
|
|
68
|
+
{
|
|
69
|
+
'map_name' => x[0],
|
|
70
|
+
'system_username' => x[1],
|
|
71
|
+
'pg_username' => x[2],
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def read_file(conf_file = @conf_file)
|
|
76
|
+
inspec.file(conf_file).content.lines
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
# copyright: 2015, Vulcano Security GmbH
|
|
3
3
|
# author: Dominik Richter
|
|
4
4
|
# author: Christoph Hartmann
|
|
5
|
-
#
|
|
5
|
+
# author: Aaron Lippold
|
|
6
|
+
|
|
7
|
+
require 'shellwords'
|
|
6
8
|
|
|
7
9
|
module Inspec::Resources
|
|
8
10
|
class Lines
|
|
@@ -26,39 +28,45 @@ module Inspec::Resources
|
|
|
26
28
|
name 'postgres_session'
|
|
27
29
|
desc 'Use the postgres_session InSpec audit resource to test SQL commands run against a PostgreSQL database.'
|
|
28
30
|
example "
|
|
29
|
-
sql = postgres_session('username', 'password')
|
|
31
|
+
sql = postgres_session('username', 'password', 'host')
|
|
32
|
+
query('sql_query', ['database_name'])` contains the query and (optional) database to execute
|
|
33
|
+
|
|
34
|
+
# default values:
|
|
35
|
+
# username: 'postgres'
|
|
36
|
+
# host: 'localhost'
|
|
37
|
+
# db: databse == db_user running the sql query
|
|
30
38
|
|
|
31
39
|
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
|
|
32
|
-
its('output') { should eq
|
|
40
|
+
its('output') { should eq '' }
|
|
33
41
|
end
|
|
34
42
|
"
|
|
35
43
|
|
|
36
|
-
def initialize(user, pass)
|
|
44
|
+
def initialize(user, pass, host = nil)
|
|
37
45
|
@user = user || 'postgres'
|
|
38
46
|
@pass = pass
|
|
47
|
+
@host = host || 'localhost'
|
|
39
48
|
end
|
|
40
49
|
|
|
41
50
|
def query(query, db = [])
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# that does this securely
|
|
45
|
-
escaped_query = query.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
|
|
46
|
-
# run the query
|
|
47
|
-
cmd = inspec.command("PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h localhost -c \"#{escaped_query}\"")
|
|
51
|
+
psql_cmd = create_psql_cmd(query, db)
|
|
52
|
+
cmd = inspec.command(psql_cmd)
|
|
48
53
|
out = cmd.stdout + "\n" + cmd.stderr
|
|
49
|
-
if cmd.exit_status != 0
|
|
50
|
-
out =~ /could not connect to .*/ or
|
|
51
|
-
out.downcase =~ /^error/
|
|
52
|
-
# skip this test if the server can't run the query
|
|
54
|
+
if cmd.exit_status != 0 || out =~ /could not connect to .*/ || out.downcase =~ /^error:.*/
|
|
53
55
|
skip_resource "Can't read run query #{query.inspect} on postgres_session: #{out}"
|
|
54
56
|
else
|
|
55
|
-
|
|
56
|
-
# remove the tail
|
|
57
|
-
lines = cmd.stdout
|
|
58
|
-
.sub(/(.*\n)+([-]+[+])*[-]+\n/, '')
|
|
59
|
-
.sub(/\n[^\n]*\n\n$/, '')
|
|
60
|
-
Lines.new(lines.strip, "PostgreSQL query: #{query}")
|
|
57
|
+
Lines.new(cmd.stdout.strip, "PostgreSQL query: #{query}")
|
|
61
58
|
end
|
|
62
59
|
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def escaped_query(query)
|
|
64
|
+
Shellwords.escape(query)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def create_psql_cmd(query, db = [])
|
|
68
|
+
dbs = db.map { |x| "-d #{x}" }.join(' ')
|
|
69
|
+
"PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{escaped_query(query)}"
|
|
70
|
+
end
|
|
63
71
|
end
|
|
64
72
|
end
|
data/lib/resources/powershell.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
|
module Inspec::Resources
|
|
8
7
|
class PowershellScript < Cmd
|
|
@@ -10,7 +9,7 @@ module Inspec::Resources
|
|
|
10
9
|
desc 'Use the powershell InSpec audit resource to test a Windows PowerShell script on the Microsoft Windows platform.'
|
|
11
10
|
example "
|
|
12
11
|
script = <<-EOH
|
|
13
|
-
#
|
|
12
|
+
# your powershell script
|
|
14
13
|
EOH
|
|
15
14
|
|
|
16
15
|
describe powershell(script) do
|
|
@@ -20,6 +19,7 @@ module Inspec::Resources
|
|
|
20
19
|
|
|
21
20
|
def initialize(script)
|
|
22
21
|
unless inspec.os.windows?
|
|
22
|
+
super('')
|
|
23
23
|
return skip_resource 'The `script` resource is not supported on your OS yet.'
|
|
24
24
|
end
|
|
25
25
|
# since WinRM 2.0 and the default use of powershell for local execution in
|
data/lib/resources/processes.rb
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
# copyright: 2015, Vulcano Security GmbH
|
|
3
3
|
# author: Dominik Richter
|
|
4
4
|
# author: Christoph Hartmann
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
require 'utils/filter'
|
|
6
7
|
|
|
7
8
|
module Inspec::Resources
|
|
8
9
|
class Processes < Inspec.resource(1)
|
|
@@ -10,72 +11,106 @@ module Inspec::Resources
|
|
|
10
11
|
desc 'Use the processes InSpec audit resource to test properties for programs that are running on the system.'
|
|
11
12
|
example "
|
|
12
13
|
describe processes('mysqld') do
|
|
13
|
-
its('
|
|
14
|
+
its('entries.length') { should eq 1 }
|
|
14
15
|
its('users') { should eq ['mysql'] }
|
|
15
16
|
its('states') { should include 'S' }
|
|
16
17
|
end
|
|
18
|
+
describe processes(/.+/).where { label != 'unconfined' && pid < 1000 } do
|
|
19
|
+
its('users') { should cmp [] }
|
|
20
|
+
end
|
|
17
21
|
"
|
|
18
22
|
|
|
19
|
-
attr_reader :list,
|
|
20
|
-
:users,
|
|
21
|
-
:states
|
|
22
|
-
|
|
23
23
|
def initialize(grep)
|
|
24
|
+
@grep = grep
|
|
24
25
|
# turn into a regexp if it isn't one yet
|
|
25
26
|
if grep.class == String
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
# if windows ignore case as we can't make up our minds
|
|
28
|
+
if inspec.os.windows?
|
|
29
|
+
grep = '(?i)' + grep
|
|
30
|
+
else
|
|
31
|
+
grep = '(/[^/]*)*' + grep unless grep[0] == '/'
|
|
32
|
+
grep = '^' + grep + '(\s|$)'
|
|
33
|
+
end
|
|
34
|
+
grep = Regexp.new(grep)
|
|
28
35
|
end
|
|
29
|
-
|
|
36
|
+
|
|
37
|
+
all_cmds = ps_axo
|
|
30
38
|
@list = all_cmds.find_all do |hm|
|
|
31
39
|
hm[:command] =~ grep
|
|
32
40
|
end
|
|
41
|
+
end
|
|
33
42
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
instance_variable_set("@#{var}", @list.map { |l| l[key] }.uniq)
|
|
37
|
-
end
|
|
43
|
+
def exists?
|
|
44
|
+
!@list.empty?
|
|
38
45
|
end
|
|
39
46
|
|
|
40
47
|
def to_s
|
|
41
|
-
|
|
48
|
+
"Processes #{@grep.class == String ? @grep : @grep.inspect}"
|
|
42
49
|
end
|
|
43
50
|
|
|
51
|
+
def list
|
|
52
|
+
warn '[DEPRECATION] `processes.list` is deprecated. Please use `processes.entries` instead. It will be removed in version 2.0.0.'
|
|
53
|
+
@list
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
filter = FilterTable.create
|
|
57
|
+
filter.add_accessor(:where)
|
|
58
|
+
.add_accessor(:entries)
|
|
59
|
+
.add(:labels, field: 'label')
|
|
60
|
+
.add(:pids, field: 'pid')
|
|
61
|
+
.add(:cpus, field: 'cpu')
|
|
62
|
+
.add(:mem, field: 'mem')
|
|
63
|
+
.add(:vsz, field: 'vsz')
|
|
64
|
+
.add(:rss, field: 'rss')
|
|
65
|
+
.add(:tty, field: 'tty')
|
|
66
|
+
.add(:states, field: 'stat')
|
|
67
|
+
.add(:start, field: 'start')
|
|
68
|
+
.add(:time, field: 'time')
|
|
69
|
+
.add(:users, field: 'user')
|
|
70
|
+
.add(:commands, field: 'command')
|
|
71
|
+
.connect(self, :filtered_processes)
|
|
72
|
+
|
|
44
73
|
private
|
|
45
74
|
|
|
46
|
-
def
|
|
75
|
+
def filtered_processes
|
|
76
|
+
@list
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def ps_axo
|
|
47
80
|
os = inspec.os
|
|
48
81
|
|
|
49
82
|
if os.linux?
|
|
50
|
-
command = 'ps
|
|
51
|
-
regex = /^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(
|
|
83
|
+
command = 'ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command'
|
|
84
|
+
regex = /^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(\w{3} \d{2}|\d{2}:\d{2}:\d{2})\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
|
85
|
+
elsif os.windows?
|
|
86
|
+
command = '$Proc = Get-Process -IncludeUserName | Where-Object {$_.Path -ne $null } | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")'
|
|
87
|
+
# Wanted to use /(?:^|,)([^,]*)/; works on rubular.com not sure why here?
|
|
88
|
+
regex = /^(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+)$/
|
|
52
89
|
else
|
|
53
|
-
command = 'ps
|
|
54
|
-
regex =
|
|
90
|
+
command = 'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command'
|
|
91
|
+
regex = /^\s*([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
|
55
92
|
end
|
|
56
93
|
build_process_list(command, regex, os)
|
|
57
94
|
end
|
|
58
95
|
|
|
59
|
-
Process = Struct.new(:label, :
|
|
96
|
+
Process = Struct.new(:label, :pid,
|
|
60
97
|
:cpu, :mem, :vsz,
|
|
61
98
|
:rss, :tty, :stat,
|
|
62
|
-
:start, :time, :command)
|
|
99
|
+
:start, :time, :user, :command)
|
|
63
100
|
|
|
64
101
|
def build_process_list(command, regex, os)
|
|
65
102
|
cmd = inspec.command(command)
|
|
66
103
|
all = cmd.stdout.split("\n")[1..-1]
|
|
67
104
|
return [] if all.nil?
|
|
68
|
-
|
|
69
105
|
lines = all.map do |line|
|
|
70
106
|
line.match(regex)
|
|
71
107
|
end.compact
|
|
72
|
-
|
|
73
108
|
lines.map do |m|
|
|
74
109
|
a = m.to_a[1..-1] # grab all matching groups
|
|
75
|
-
a.unshift(nil) unless os.linux?
|
|
76
|
-
a[
|
|
110
|
+
a.unshift(nil) unless os.linux? || os.windows?
|
|
111
|
+
a[1] = a[1].to_i
|
|
112
|
+
a[4] = a[4].to_i
|
|
77
113
|
a[5] = a[5].to_i
|
|
78
|
-
a[6] = a[6].to_i
|
|
79
114
|
Process.new(*a)
|
|
80
115
|
end
|
|
81
116
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Dominik Richter
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
|
|
5
|
+
require 'utils/erlang_parser'
|
|
6
|
+
|
|
7
|
+
module Inspec::Resources
|
|
8
|
+
class RabbitmqConf < Inspec.resource(1)
|
|
9
|
+
name 'rabbitmq_config'
|
|
10
|
+
desc 'Use the rabbitmq_config InSpec resource to test configuration data '\
|
|
11
|
+
'for the RabbitMQ service located in /etc/rabbitmq/rabbitmq.config on '\
|
|
12
|
+
'Linux and UNIX platforms.'
|
|
13
|
+
example "
|
|
14
|
+
describe rabbitmq_config.params('rabbit', 'ssl_listeners') do
|
|
15
|
+
it { should cmp 5671 }
|
|
16
|
+
end
|
|
17
|
+
"
|
|
18
|
+
|
|
19
|
+
def initialize(conf_path = nil)
|
|
20
|
+
@conf_path = conf_path || '/etc/rabbitmq/rabbitmq.config'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def params(*opts)
|
|
24
|
+
opts.inject(read_params) do |res, nxt|
|
|
25
|
+
res.respond_to?(:key) ? res[nxt] : nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_s
|
|
30
|
+
"rabbitmq_config #{@conf_path}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def read_content
|
|
36
|
+
return @content if defined?(@content)
|
|
37
|
+
file = inspec.file(@conf_path)
|
|
38
|
+
if !file.file?
|
|
39
|
+
return skip_resource "Can't find file \"#{@conf_path}\""
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@content = file.content
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def read_params
|
|
46
|
+
return @params if defined?(@params)
|
|
47
|
+
return @params = {} if read_content.nil?
|
|
48
|
+
@params = ErlangConfigFile.parse(read_content)
|
|
49
|
+
rescue Parslet::ParseFailed
|
|
50
|
+
raise "Cannot parse RabbitMQ config: \"#{read_content}\""
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# copyright: 2015, Vulcano Security GmbH
|
|
3
3
|
# author: Christoph Hartmann
|
|
4
|
-
# license: All rights reserved
|
|
5
4
|
|
|
6
5
|
require 'json'
|
|
7
6
|
|
|
@@ -20,7 +19,7 @@ require 'json'
|
|
|
20
19
|
# describe registry_key({
|
|
21
20
|
# name: 'Task Scheduler',
|
|
22
21
|
# hive: 'HKEY_LOCAL_MACHINE',
|
|
23
|
-
# key: '
|
|
22
|
+
# key: '\SYSTEM\CurrentControlSet\services\Schedule'
|
|
24
23
|
# }) do
|
|
25
24
|
# its('Start') { should eq 2 }
|
|
26
25
|
# end
|
|
@@ -63,15 +62,15 @@ module Inspec::Resources
|
|
|
63
62
|
@options = {}
|
|
64
63
|
if reg_key && reg_key.is_a?(Hash)
|
|
65
64
|
@options = @options.merge!(reg_key)
|
|
65
|
+
|
|
66
66
|
# generate registry_key if we do not have a regular expression
|
|
67
|
-
@options[:path] =
|
|
68
|
-
# add optional key path
|
|
69
|
-
@options[:path] += '\\' + @options[:key] if @options[:key]
|
|
67
|
+
@options[:path] = generate_registry_key_path_from_options
|
|
70
68
|
@options[:name] ||= @options[:path]
|
|
71
69
|
else
|
|
72
70
|
@options[:name] = name
|
|
73
71
|
@options[:path] = reg_key
|
|
74
72
|
end
|
|
73
|
+
|
|
75
74
|
return skip_resource 'The `registry_key` resource is not supported on your OS yet.' if !inspec.os.windows?
|
|
76
75
|
end
|
|
77
76
|
|
|
@@ -147,6 +146,11 @@ module Inspec::Resources
|
|
|
147
146
|
script = <<-EOH
|
|
148
147
|
Function InSpec-GetRegistryKey($path) {
|
|
149
148
|
$reg = Get-Item ('Registry::' + $path)
|
|
149
|
+
if ($reg -eq $null) {
|
|
150
|
+
Write-Error "InSpec: Failed to find registry key"
|
|
151
|
+
exit 1001
|
|
152
|
+
}
|
|
153
|
+
|
|
150
154
|
$properties = New-Object -Type PSObject
|
|
151
155
|
$reg.Property | ForEach-Object {
|
|
152
156
|
$key = $_
|
|
@@ -160,18 +164,23 @@ module Inspec::Resources
|
|
|
160
164
|
$properties
|
|
161
165
|
}
|
|
162
166
|
$path = '#{path}'
|
|
163
|
-
InSpec-GetRegistryKey($path) | ConvertTo-Json
|
|
167
|
+
InSpec-GetRegistryKey($path) | ConvertTo-Json -Compress
|
|
164
168
|
EOH
|
|
165
169
|
|
|
166
170
|
cmd = inspec.powershell(script)
|
|
167
171
|
# cannot rely on exit code for now, successful command returns exit code 1
|
|
168
172
|
# return nil if cmd.exit_status != 0, try to parse json
|
|
169
173
|
begin
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
if cmd.exit_status == 1001 && cmd.stderr =~ /InSpec: Failed to find registry key/
|
|
175
|
+
# TODO: provide the stderr output
|
|
176
|
+
@registry_cache = nil
|
|
177
|
+
else
|
|
178
|
+
@registry_cache = JSON.parse(cmd.stdout)
|
|
179
|
+
# convert keys to lower case
|
|
180
|
+
@registry_cache = Hash[@registry_cache.map do |key, value|
|
|
181
|
+
[key.downcase, value]
|
|
182
|
+
end]
|
|
183
|
+
end
|
|
175
184
|
rescue JSON::ParserError => _e
|
|
176
185
|
@registry_cache = nil
|
|
177
186
|
end
|
|
@@ -245,6 +254,20 @@ module Inspec::Resources
|
|
|
245
254
|
|
|
246
255
|
options[symbol]
|
|
247
256
|
end
|
|
257
|
+
|
|
258
|
+
def generate_registry_key_path_from_options
|
|
259
|
+
path = @options[:hive]
|
|
260
|
+
path += format_key_from_options
|
|
261
|
+
|
|
262
|
+
path
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def format_key_from_options
|
|
266
|
+
key = @options[:key]
|
|
267
|
+
return '' unless key
|
|
268
|
+
|
|
269
|
+
key.start_with?('\\') ? key : "\\#{key}"
|
|
270
|
+
end
|
|
248
271
|
end
|
|
249
272
|
|
|
250
273
|
# for compatability with serverspec
|