inspec 0.14.8 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -2
- data/bin/inspec +3 -4
- data/examples/inheritance/README.md +19 -0
- data/examples/inheritance/controls/example.rb +11 -0
- data/examples/inheritance/inspec.yml +10 -0
- data/lib/bundles/inspec-compliance/cli.rb +1 -4
- data/lib/bundles/inspec-supermarket/cli.rb +1 -4
- data/lib/inspec/dsl.rb +48 -55
- data/lib/inspec/profile.rb +6 -2
- data/lib/inspec/profile_context.rb +21 -8
- data/lib/inspec/runner.rb +17 -12
- data/lib/inspec/runner_rspec.rb +1 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/apache.rb +20 -18
- data/lib/resources/apache_conf.rb +92 -90
- data/lib/resources/apt.rb +92 -90
- data/lib/resources/audit_policy.rb +35 -33
- data/lib/resources/auditd_conf.rb +41 -39
- data/lib/resources/auditd_rules.rb +155 -153
- data/lib/resources/bond.rb +1 -1
- data/lib/resources/bridge.rb +97 -95
- data/lib/resources/command.rb +47 -45
- data/lib/resources/csv.rb +23 -21
- data/lib/resources/directory.rb +1 -1
- data/lib/resources/etc_group.rb +116 -114
- data/lib/resources/file.rb +1 -1
- data/lib/resources/gem.rb +39 -37
- data/lib/resources/group.rb +100 -98
- data/lib/resources/host.rb +103 -101
- data/lib/resources/inetd_conf.rb +42 -40
- data/lib/resources/ini.rb +15 -13
- data/lib/resources/interface.rb +106 -104
- data/lib/resources/iptables.rb +36 -34
- data/lib/resources/json.rb +64 -62
- data/lib/resources/kernel_module.rb +30 -28
- data/lib/resources/kernel_parameter.rb +44 -42
- data/lib/resources/limits_conf.rb +41 -39
- data/lib/resources/login_def.rb +38 -36
- data/lib/resources/mount.rb +43 -41
- data/lib/resources/mysql.rb +67 -65
- data/lib/resources/mysql_conf.rb +89 -87
- data/lib/resources/mysql_session.rb +46 -44
- data/lib/resources/npm.rb +35 -33
- data/lib/resources/ntp_conf.rb +44 -42
- data/lib/resources/oneget.rb +46 -44
- data/lib/resources/os.rb +22 -20
- data/lib/resources/os_env.rb +47 -45
- data/lib/resources/package.rb +213 -211
- data/lib/resources/parse_config.rb +59 -57
- data/lib/resources/passwd.rb +89 -87
- data/lib/resources/pip.rb +60 -58
- data/lib/resources/port.rb +352 -350
- data/lib/resources/postgres.rb +26 -24
- data/lib/resources/postgres_conf.rb +66 -64
- data/lib/resources/postgres_session.rb +47 -45
- data/lib/resources/processes.rb +56 -54
- data/lib/resources/registry_key.rb +150 -148
- data/lib/resources/script.rb +30 -28
- data/lib/resources/security_policy.rb +56 -54
- data/lib/resources/service.rb +638 -636
- data/lib/resources/shadow.rb +98 -96
- data/lib/resources/ssh_conf.rb +58 -56
- data/lib/resources/user.rb +363 -361
- data/lib/resources/windows_feature.rb +46 -44
- data/lib/resources/xinetd.rb +111 -109
- data/lib/resources/yaml.rb +16 -14
- data/lib/resources/yum.rb +107 -105
- data/lib/utils/base_cli.rb +18 -0
- data/test/helper.rb +2 -2
- data/test/unit/profile_context_test.rb +1 -1
- data/test/unit/resources/file_test.rb +1 -1
- data/test/unit/resources/mount_test.rb +1 -1
- metadata +5 -2
data/lib/resources/postgres.rb
CHANGED
@@ -4,34 +4,36 @@
|
|
4
4
|
# author: Christoph Hartmann
|
5
5
|
# license: All rights reserved
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Inspec::Resources
|
8
|
+
class Postgres < Inspec.resource(1)
|
9
|
+
name 'postgres'
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
attr_reader :service, :data_dir, :conf_dir, :conf_path
|
12
|
+
def initialize
|
13
|
+
case inspec.os[:family]
|
14
|
+
when 'ubuntu', 'debian'
|
15
|
+
@service = 'postgresql'
|
16
|
+
@data_dir = '/var/lib/postgresql'
|
17
|
+
@version = inspec.command('ls /etc/postgresql/').stdout.chomp
|
18
|
+
@conf_dir = "/etc/postgresql/#{@version}/main"
|
19
|
+
@conf_path = File.join @conf_dir, 'postgresql.conf'
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
when 'arch'
|
22
|
+
@service = 'postgresql'
|
23
|
+
@data_dir = '/var/lib/postgres/data'
|
24
|
+
@conf_dir = '/var/lib/postgres/data'
|
25
|
+
@conf_path = File.join @conf_dir, 'postgresql.conf'
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
else
|
28
|
+
@service = 'postgresql'
|
29
|
+
@data_dir = '/var/lib/postgresql'
|
30
|
+
@conf_dir = '/var/lib/pgsql/data'
|
31
|
+
@conf_path = File.join @conf_dir, 'postgresql.conf'
|
32
|
+
end
|
31
33
|
end
|
32
|
-
end
|
33
34
|
|
34
|
-
|
35
|
-
|
35
|
+
def to_s
|
36
|
+
'PostgreSQL'
|
37
|
+
end
|
36
38
|
end
|
37
39
|
end
|
@@ -8,86 +8,88 @@ require 'utils/simpleconfig'
|
|
8
8
|
require 'utils/find_files'
|
9
9
|
require 'resources/postgres'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
module Inspec::Resources
|
12
|
+
class PostgresConf < Inspec.resource(1)
|
13
|
+
name 'postgres_conf'
|
14
|
+
desc 'Use the postgres_conf InSpec audit resource to test the contents of the configuration file for PostgreSQL, typically located at /etc/postgresql/<version>/main/postgresql.conf or /var/lib/postgres/data/postgresql.conf, depending on the platform.'
|
15
|
+
example "
|
16
|
+
describe postgres_conf do
|
17
|
+
its('max_connections') { should eq '5' }
|
18
|
+
end
|
19
|
+
"
|
19
20
|
|
20
|
-
|
21
|
+
include FindFiles
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
def initialize(conf_path = nil)
|
24
|
+
@conf_path = conf_path || inspec.postgres.conf_path
|
25
|
+
@conf_dir = File.expand_path(File.dirname(@conf_path))
|
26
|
+
@files_contents = {}
|
27
|
+
@content = nil
|
28
|
+
@params = nil
|
29
|
+
read_content
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
def content
|
33
|
+
@content ||= read_content
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
def params(*opts)
|
37
|
+
@params || read_content
|
38
|
+
res = @params
|
39
|
+
opts.each do |opt|
|
40
|
+
res = res[opt] unless res.nil?
|
41
|
+
end
|
42
|
+
res
|
40
43
|
end
|
41
|
-
res
|
42
|
-
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def read_content
|
46
|
+
@content = ''
|
47
|
+
@params = {}
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
# skip if the main configuration file doesn't exist
|
50
|
+
if !inspec.file(@conf_path).file?
|
51
|
+
return skip_resource "Can't find file \"#{@conf_path}\""
|
52
|
+
end
|
53
|
+
raw_conf = read_file(@conf_path)
|
54
|
+
if raw_conf.empty? && inspec.file(@conf_path).size > 0
|
55
|
+
return skip_resource("Can't read file \"#{@conf_path}\"")
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
to_read = [@conf_path]
|
59
|
+
until to_read.empty?
|
60
|
+
raw_conf = read_file(to_read[0])
|
61
|
+
@content += raw_conf
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
params = SimpleConfig.new(raw_conf).params
|
64
|
+
@params.merge!(params)
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
to_read = to_read.drop(1)
|
67
|
+
# see if there is more config files to include
|
67
68
|
|
68
|
-
|
69
|
-
|
69
|
+
to_read += include_files(params).find_all do |fp|
|
70
|
+
not @files_contents.key? fp
|
71
|
+
end
|
70
72
|
end
|
73
|
+
@content
|
71
74
|
end
|
72
|
-
@content
|
73
|
-
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
76
|
+
def include_files(params)
|
77
|
+
include_files = params['include'] || []
|
78
|
+
include_files += params['include_if_exists'] || []
|
79
|
+
dirs = params['include_dir'] || []
|
80
|
+
dirs.each do |dir|
|
81
|
+
dir = File.join(@conf_dir, dir) if dir[0] != '/'
|
82
|
+
include_files += find_files(dir, depth: 1, type: 'file')
|
83
|
+
end
|
84
|
+
include_files
|
82
85
|
end
|
83
|
-
include_files
|
84
|
-
end
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
def read_file(path)
|
88
|
+
@files_contents[path] ||= inspec.file(path).content
|
89
|
+
end
|
89
90
|
|
90
|
-
|
91
|
-
|
91
|
+
def to_s
|
92
|
+
'PostgreSQL Configuration'
|
93
|
+
end
|
92
94
|
end
|
93
95
|
end
|
@@ -4,59 +4,61 @@
|
|
4
4
|
# author: Christoph Hartmann
|
5
5
|
# license: All rights reserved
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Inspec::Resources
|
8
|
+
class Lines
|
9
|
+
attr_reader :output
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def initialize(raw, desc)
|
12
|
+
@output = raw
|
13
|
+
@desc = desc
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def lines
|
17
|
+
output.split("\n")
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
def to_s
|
21
|
+
@desc
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
class PostgresSession < Inspec.resource(1)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
class PostgresSession < Inspec.resource(1)
|
26
|
+
name 'postgres_session'
|
27
|
+
desc 'Use the postgres_session InSpec audit resource to test SQL commands run against a PostgreSQL database.'
|
28
|
+
example "
|
29
|
+
sql = postgres_session('username', 'password')
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
|
32
|
+
its('output') { should eq('') }
|
33
|
+
end
|
34
|
+
"
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def initialize(user, pass)
|
37
|
+
@user = user || 'postgres'
|
38
|
+
@pass = pass
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
41
|
+
def query(query, db = [])
|
42
|
+
dbs = db.map { |x| "-d #{x}" }.join(' ')
|
43
|
+
# TODO: simple escape, must be handled by a library
|
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}\"")
|
48
|
+
out = cmd.stdout + "\n" + cmd.stderr
|
49
|
+
if cmd.exit_status != 0 or
|
50
|
+
out =~ /could not connect to .*/ or
|
51
|
+
out.downcase =~ /^error/
|
52
|
+
# skip this test if the server can't run the query
|
53
|
+
skip_resource "Can't read run query #{query.inspect} on postgres_session: #{out}"
|
54
|
+
else
|
55
|
+
# remove the whole header (i.e. up to the first ^-----+------+------$)
|
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}")
|
61
|
+
end
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
data/lib/resources/processes.rb
CHANGED
@@ -4,70 +4,72 @@
|
|
4
4
|
# author: Christoph Hartmann
|
5
5
|
# license: All rights reserved
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
module Inspec::Resources
|
8
|
+
class Processes < Inspec.resource(1)
|
9
|
+
name 'processes'
|
10
|
+
desc 'Use the processes InSpec audit resource to test properties for programs that are running on the system.'
|
11
|
+
example "
|
12
|
+
describe processes('mysqld') do
|
13
|
+
its('list.length') { should eq 1 }
|
14
|
+
its('users') { should eq ['mysql'] }
|
15
|
+
its('states') { should include 'S' }
|
16
|
+
end
|
17
|
+
"
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
attr_reader :list,
|
20
|
+
:users,
|
21
|
+
:states
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
def initialize(grep)
|
24
|
+
# turn into a regexp if it isn't one yet
|
25
|
+
if grep.class == String
|
26
|
+
grep = '(/[^/]*)*'+grep if grep[0] != '/'
|
27
|
+
grep = Regexp.new('^' + grep + '(\s|$)')
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
all_cmds = ps_aux
|
31
|
+
@list = all_cmds.find_all do |hm|
|
32
|
+
hm[:command] =~ grep
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
{ users: :user,
|
36
|
+
states: :stat }.each do |var, key|
|
37
|
+
instance_variable_set("@#{var}", @list.map { |l| l[key] }.uniq)
|
38
|
+
end
|
37
39
|
end
|
38
|
-
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
def to_s
|
42
|
+
'Processes'
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
+
private
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
def ps_aux
|
48
|
+
# get all running processes
|
49
|
+
cmd = inspec.command('ps aux')
|
50
|
+
all = cmd.stdout.split("\n")[1..-1]
|
51
|
+
return [] if all.nil?
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
lines = all.map do |line|
|
54
|
+
# user 32296 0.0 0.0 42592 7972 pts/15 Ss+ Apr06 0:00 zsh
|
55
|
+
line.match(/^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(.*)$/)
|
56
|
+
end.compact
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
58
|
+
lines.map do |m|
|
59
|
+
{
|
60
|
+
user: m[1],
|
61
|
+
pid: m[2],
|
62
|
+
cpu: m[3],
|
63
|
+
mem: m[4],
|
64
|
+
vsz: m[5],
|
65
|
+
rss: m[6],
|
66
|
+
tty: m[7],
|
67
|
+
stat: m[8],
|
68
|
+
start: m[9],
|
69
|
+
time: m[10],
|
70
|
+
command: m[11],
|
71
|
+
}
|
72
|
+
end
|
71
73
|
end
|
72
74
|
end
|
73
75
|
end
|
@@ -10,174 +10,176 @@ require 'json'
|
|
10
10
|
# its('Start') { should eq 2 }
|
11
11
|
# end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
module Inspec::Resources
|
14
|
+
class RegistryKey < Inspec.resource(1)
|
15
|
+
name 'registry_key'
|
16
|
+
desc 'Use the registry_key InSpec audit resource to test key values in the Microsoft Windows registry.'
|
17
|
+
example "
|
18
|
+
describe registry_key('path\to\key') do
|
19
|
+
its('name') { should eq 'value' }
|
20
|
+
end
|
21
|
+
"
|
22
|
+
|
23
|
+
attr_accessor :reg_key
|
24
|
+
|
25
|
+
def initialize(name, reg_key = nil)
|
26
|
+
# if we have one parameter, we use it as name
|
27
|
+
reg_key ||= name
|
28
|
+
@name = name
|
29
|
+
@reg_key = reg_key
|
30
|
+
|
31
|
+
return skip_resource 'The `registry_key` resource is not supported on your OS yet.' if !inspec.os.windows?
|
19
32
|
end
|
20
|
-
"
|
21
33
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# if we have one parameter, we use it as name
|
26
|
-
reg_key ||= name
|
27
|
-
@name = name
|
28
|
-
@reg_key = reg_key
|
29
|
-
|
30
|
-
return skip_resource 'The `registry_key` resource is not supported on your OS yet.' if !inspec.os.windows?
|
31
|
-
end
|
32
|
-
|
33
|
-
def exists?
|
34
|
-
!registry_key(@reg_key).nil?
|
35
|
-
end
|
36
|
-
|
37
|
-
def has_value?(value)
|
38
|
-
val = registry_key(@reg_key)
|
39
|
-
!val.nil? && registry_property_value(val, '(default)') == value ? true : false
|
40
|
-
end
|
34
|
+
def exists?
|
35
|
+
!registry_key(@reg_key).nil?
|
36
|
+
end
|
41
37
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
def has_value?(value)
|
39
|
+
val = registry_key(@reg_key)
|
40
|
+
!val.nil? && registry_property_value(val, '(default)') == value ? true : false
|
41
|
+
end
|
46
42
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
val = registry_key(@reg_key)
|
43
|
+
def has_property?(property_name, property_type = nil)
|
44
|
+
val = registry_key(@reg_key)
|
45
|
+
!val.nil? && registry_property_exists(val, property_name) && (property_type.nil? || registry_property_type(val, property_name) == map2type(property_type)) ? true : false
|
46
|
+
end
|
52
47
|
|
53
|
-
#
|
54
|
-
|
48
|
+
# deactivate rubocop, because we need to stay compatible with Serverspe
|
49
|
+
# rubocop:disable Style/OptionalArguments
|
50
|
+
def has_property_value?(property_name, property_type = nil, value)
|
51
|
+
# rubocop:enable Style/OptionalArguments
|
52
|
+
val = registry_key(@reg_key)
|
55
53
|
|
56
|
-
|
57
|
-
|
54
|
+
# convert value to binary if required
|
55
|
+
value = value.bytes if !property_type.nil? && map2type(property_type) == 3 && !value.is_a?(Array)
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
# get data
|
62
|
-
val = registry_key(@reg_key)
|
63
|
-
registry_property_value(val, meth)
|
64
|
-
end
|
57
|
+
!val.nil? && registry_property_value(val, property_name) == value && (property_type.nil? || registry_property_type(val, property_name) == map2type(property_type)) ? true : false
|
58
|
+
end
|
65
59
|
|
66
|
-
|
67
|
-
|
68
|
-
|
60
|
+
# returns nil, if not existant or value
|
61
|
+
def method_missing(meth)
|
62
|
+
# get data
|
63
|
+
val = registry_key(@reg_key)
|
64
|
+
registry_property_value(val, meth)
|
65
|
+
end
|
69
66
|
|
70
|
-
|
67
|
+
def to_s
|
68
|
+
"Registry Key #{@name}"
|
69
|
+
end
|
71
70
|
|
72
|
-
|
73
|
-
property.to_s.downcase
|
74
|
-
end
|
71
|
+
private
|
75
72
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
!regkey[prep_prop(property)].nil?
|
80
|
-
end
|
73
|
+
def prep_prop(property)
|
74
|
+
property.to_s.downcase
|
75
|
+
end
|
81
76
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
77
|
+
def registry_property_exists(regkey, property)
|
78
|
+
return false if regkey.nil? || property.nil?
|
79
|
+
# always ensure the key is lower case
|
80
|
+
!regkey[prep_prop(property)].nil?
|
81
|
+
end
|
87
82
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
83
|
+
def registry_property_value(regkey, property)
|
84
|
+
return nil if !registry_property_exists(regkey, property)
|
85
|
+
# always ensure the key is lower case
|
86
|
+
regkey[prep_prop(property)]['value']
|
87
|
+
end
|
93
88
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
script = <<-EOH
|
99
|
-
$reg = Get-Item 'Registry::#{path}'
|
100
|
-
$object = New-Object -Type PSObject
|
101
|
-
$reg.Property | ForEach-Object {
|
102
|
-
$key = $_
|
103
|
-
if ("(default)".Equals($key)) { $key = '' }
|
104
|
-
$value = New-Object psobject -Property @{
|
105
|
-
"value" = $reg.GetValue($key);
|
106
|
-
"type" = $reg.GetValueKind($key);
|
107
|
-
}
|
108
|
-
$object | Add-Member –MemberType NoteProperty –Name $_ –Value $value
|
109
|
-
}
|
110
|
-
$object | ConvertTo-Json
|
111
|
-
EOH
|
112
|
-
|
113
|
-
cmd = inspec.script(script)
|
114
|
-
|
115
|
-
# cannot rely on exit code for now, successful command returns exit code 1
|
116
|
-
# return nil if cmd.exit_status != 0, try to parse json
|
117
|
-
begin
|
118
|
-
@registry_cache = JSON.parse(cmd.stdout)
|
119
|
-
# convert keys to lower case
|
120
|
-
@registry_cache = Hash[@registry_cache.map do |key, value|
|
121
|
-
[key.downcase, value]
|
122
|
-
end]
|
123
|
-
rescue JSON::ParserError => _e
|
124
|
-
@registry_cache = nil
|
89
|
+
def registry_property_type(regkey, property)
|
90
|
+
return nil if !registry_property_exists(regkey, property)
|
91
|
+
# always ensure the key is lower case
|
92
|
+
regkey[prep_prop(property)]['type']
|
125
93
|
end
|
126
94
|
|
127
|
-
|
128
|
-
|
95
|
+
def registry_key(path)
|
96
|
+
return @registry_cache if defined?(@registry_cache)
|
97
|
+
|
98
|
+
# load registry key and all properties
|
99
|
+
script = <<-EOH
|
100
|
+
$reg = Get-Item 'Registry::#{path}'
|
101
|
+
$object = New-Object -Type PSObject
|
102
|
+
$reg.Property | ForEach-Object {
|
103
|
+
$key = $_
|
104
|
+
if ("(default)".Equals($key)) { $key = '' }
|
105
|
+
$value = New-Object psobject -Property @{
|
106
|
+
"value" = $reg.GetValue($key);
|
107
|
+
"type" = $reg.GetValueKind($key);
|
108
|
+
}
|
109
|
+
$object | Add-Member –MemberType NoteProperty –Name $_ –Value $value
|
110
|
+
}
|
111
|
+
$object | ConvertTo-Json
|
112
|
+
EOH
|
113
|
+
|
114
|
+
cmd = inspec.script(script)
|
115
|
+
|
116
|
+
# cannot rely on exit code for now, successful command returns exit code 1
|
117
|
+
# return nil if cmd.exit_status != 0, try to parse json
|
118
|
+
begin
|
119
|
+
@registry_cache = JSON.parse(cmd.stdout)
|
120
|
+
# convert keys to lower case
|
121
|
+
@registry_cache = Hash[@registry_cache.map do |key, value|
|
122
|
+
[key.downcase, value]
|
123
|
+
end]
|
124
|
+
rescue JSON::ParserError => _e
|
125
|
+
@registry_cache = nil
|
126
|
+
end
|
127
|
+
|
128
|
+
@registry_cache
|
129
|
+
end
|
129
130
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
131
|
+
# Registry key value types
|
132
|
+
# @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884(v=vs.85).aspx
|
133
|
+
# REG_NONE 0
|
134
|
+
# REG_SZ 1
|
135
|
+
# REG_EXPAND_SZ 2
|
136
|
+
# REG_BINARY 3
|
137
|
+
# REG_DWORD 4
|
138
|
+
# REG_DWORD_LITTLE_ENDIAN 4
|
139
|
+
# REG_DWORD_BIG_ENDIAN 5
|
140
|
+
# REG_LINK 6
|
141
|
+
# REG_MULTI_SZ 7
|
142
|
+
# REG_RESOURCE_LIST 8
|
143
|
+
# REG_FULL_RESOURCE_DESCRIPTOR 9
|
144
|
+
# REG_RESOURCE_REQUIREMENTS_LIST 10
|
145
|
+
# REG_QWORD 11
|
146
|
+
# REG_QWORD_LITTLE_ENDIAN 11
|
147
|
+
def map2type(symbol)
|
148
|
+
options = {}
|
149
|
+
|
150
|
+
# chef symbols, we prefer those
|
151
|
+
options[:binary] = 3
|
152
|
+
options[:string] = 1
|
153
|
+
options[:multi_string] = 7
|
154
|
+
options[:expand_string] = 2
|
155
|
+
options[:dword] = 4
|
156
|
+
options[:dword_big_endian] = 5
|
157
|
+
options[:qword] = 11
|
158
|
+
|
159
|
+
# serverspec symbols
|
160
|
+
options[:type_string] = 1
|
161
|
+
options[:type_binary] = 3
|
162
|
+
options[:type_dword] = 4
|
163
|
+
options[:type_qword] = 11
|
164
|
+
options[:type_multistring] = 7
|
165
|
+
options[:type_expandstring] = 2
|
166
|
+
|
167
|
+
options[symbol]
|
168
|
+
end
|
167
169
|
end
|
168
|
-
end
|
169
170
|
|
170
|
-
# for compatability with serverspec
|
171
|
-
# this is deprecated syntax and will be removed in future versions
|
172
|
-
class WindowsRegistryKey < RegistryKey
|
173
|
-
|
171
|
+
# for compatability with serverspec
|
172
|
+
# this is deprecated syntax and will be removed in future versions
|
173
|
+
class WindowsRegistryKey < RegistryKey
|
174
|
+
name 'windows_registry_key'
|
174
175
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
176
|
+
def initialize(name)
|
177
|
+
deprecated
|
178
|
+
super(name)
|
179
|
+
end
|
179
180
|
|
180
|
-
|
181
|
-
|
181
|
+
def deprecated
|
182
|
+
warn '[DEPRECATION] `windows_registry_key(reg_key)` is deprecated. Please use `registry_key(\'path\to\key\')` instead.'
|
183
|
+
end
|
182
184
|
end
|
183
185
|
end
|