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/mysql.rb
CHANGED
@@ -4,78 +4,80 @@
|
|
4
4
|
# author: Christoph Hartmann
|
5
5
|
# license: All rights reserved
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Inspec::Resources
|
8
|
+
class Mysql < Inspec.resource(1)
|
9
|
+
name 'mysql'
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
11
|
+
attr_reader :package, :service, :conf_dir, :conf_path, :data_dir, :log_dir, :log_path, :log_group, :log_dir_group
|
12
|
+
def initialize
|
13
|
+
# set OS-dependent filenames and paths
|
14
|
+
case inspec.os[:family]
|
15
|
+
when 'ubuntu', 'debian'
|
16
|
+
init_ubuntu
|
17
|
+
when 'redhat', 'fedora'
|
18
|
+
init_redhat
|
19
|
+
when 'arch'
|
20
|
+
init_arch
|
21
|
+
else
|
22
|
+
# TODO: could not detect
|
23
|
+
init_default
|
24
|
+
end
|
23
25
|
end
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
27
|
+
def init_ubuntu
|
28
|
+
@package = 'mysql-server'
|
29
|
+
@service = 'mysql'
|
30
|
+
@conf_path = '/etc/mysql/my.cnf'
|
31
|
+
@conf_dir = '/etc/mysql/'
|
32
|
+
@data_dir = '/var/lib/mysql/'
|
33
|
+
@log_dir = '/var/log/'
|
34
|
+
@log_path = '/var/log/mysql.log'
|
35
|
+
@log_group = 'adm'
|
36
|
+
case os[:release]
|
37
|
+
when '14.04'
|
38
|
+
@log_dir_group = 'syslog'
|
39
|
+
else
|
40
|
+
@log_dir_group = 'root'
|
41
|
+
end
|
40
42
|
end
|
41
|
-
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
def init_redhat
|
45
|
+
@package = 'mysql-server'
|
46
|
+
@service = 'mysqld'
|
47
|
+
@conf_path = '/etc/my.cnf'
|
48
|
+
@conf_dir = '/etc/'
|
49
|
+
@data_dir = '/var/lib/mysql/'
|
50
|
+
@log_dir = '/var/log/'
|
51
|
+
@log_path = '/var/log/mysqld.log'
|
52
|
+
@log_group = 'mysql'
|
53
|
+
@log_dir_group = 'root'
|
54
|
+
end
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
56
|
+
def init_arch
|
57
|
+
@package = 'mariadb'
|
58
|
+
@service = 'mysql'
|
59
|
+
@conf_path = '/etc/mysql/my.cnf'
|
60
|
+
@conf_dir = '/etc/mysql/'
|
61
|
+
@data_dir = '/var/lib/mysql/'
|
62
|
+
@log_dir = '/var/log/'
|
63
|
+
@log_path = '/var/log/mysql.log'
|
64
|
+
@log_group = 'mysql'
|
65
|
+
@log_dir_group = 'root'
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
68
|
+
def init_default
|
69
|
+
@service = 'mysqld'
|
70
|
+
@conf_path = '/etc/my.cnf'
|
71
|
+
@conf_dir = '/etc/'
|
72
|
+
@data_dir = '/var/lib/mysql/'
|
73
|
+
@log_dir = '/var/log/'
|
74
|
+
@log_path = '/var/log/mysqld.log'
|
75
|
+
@log_group = 'mysql'
|
76
|
+
@log_dir_group = 'root'
|
77
|
+
end
|
77
78
|
|
78
|
-
|
79
|
-
|
79
|
+
def to_s
|
80
|
+
'MySQL'
|
81
|
+
end
|
80
82
|
end
|
81
83
|
end
|
data/lib/resources/mysql_conf.rb
CHANGED
@@ -8,115 +8,117 @@ require 'utils/find_files'
|
|
8
8
|
require 'utils/hash'
|
9
9
|
require 'resources/mysql'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
module Inspec::Resources
|
12
|
+
class MysqlConfEntry
|
13
|
+
def initialize(path, params)
|
14
|
+
@params = params
|
15
|
+
@path = path
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
def method_missing(name, *_)
|
19
|
+
k = name.to_s
|
20
|
+
res = @params[k]
|
21
|
+
return true if res.nil? && @params.key?(k)
|
22
|
+
@params[k]
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
def to_s
|
26
|
+
"MySQL Config entry [#{@path.join(' ')}]"
|
27
|
+
end
|
26
28
|
end
|
27
|
-
end
|
28
29
|
|
29
|
-
class MysqlConf < Inspec.resource(1)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
class MysqlConf < Inspec.resource(1)
|
31
|
+
name 'mysql_conf'
|
32
|
+
desc 'Use the mysql_conf InSpec audit resource to test the contents of the configuration file for MySQL, typically located at /etc/mysql/my.cnf or /etc/my.cnf.'
|
33
|
+
example "
|
34
|
+
describe mysql_conf('path') do
|
35
|
+
its('setting') { should eq 'value' }
|
36
|
+
end
|
37
|
+
"
|
37
38
|
|
38
|
-
|
39
|
+
include FindFiles
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
def initialize(conf_path = nil)
|
42
|
+
@conf_path = conf_path || inspec.mysql.conf_path
|
43
|
+
@files_contents = {}
|
44
|
+
@content = nil
|
45
|
+
@params = nil
|
46
|
+
read_content
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def content
|
50
|
+
@content ||= read_content
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
def params(*opts)
|
54
|
+
@params || read_content
|
55
|
+
res = @params
|
56
|
+
opts.each do |opt|
|
57
|
+
res = res[opt] unless res.nil?
|
58
|
+
end
|
59
|
+
MysqlConfEntry.new(opts, res)
|
57
60
|
end
|
58
|
-
MysqlConfEntry.new(opts, res)
|
59
|
-
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
def method_missing(name)
|
63
|
+
@params || read_content
|
64
|
+
@params[name.to_s]
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
def read_content
|
68
|
+
@content = ''
|
69
|
+
@params = {}
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
# skip if the main configuration file doesn't exist
|
72
|
+
if !inspec.file(@conf_path).file?
|
73
|
+
return skip_resource "Can't find file \"#{@conf_path}\""
|
74
|
+
end
|
75
|
+
raw_conf = read_file(@conf_path)
|
76
|
+
if raw_conf.empty? && inspec.file(@conf_path).size > 0
|
77
|
+
return skip_resource("Can't read file \"#{@conf_path}\"")
|
78
|
+
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
to_read = [@conf_path]
|
81
|
+
until to_read.empty?
|
82
|
+
cur_file = to_read[0]
|
83
|
+
raw_conf = read_file(cur_file)
|
84
|
+
@content += raw_conf
|
84
85
|
|
85
|
-
|
86
|
-
|
86
|
+
params = SimpleConfig.new(raw_conf).params
|
87
|
+
@params = @params.deep_merge(params)
|
87
88
|
|
88
|
-
|
89
|
-
|
89
|
+
to_read = to_read.drop(1)
|
90
|
+
# see if there is more stuff to include
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
92
|
+
dir = File.dirname(cur_file)
|
93
|
+
to_read += include_files(dir, raw_conf).find_all do |fp|
|
94
|
+
not @files_contents.key? fp
|
95
|
+
end
|
94
96
|
end
|
97
|
+
#
|
98
|
+
@content
|
95
99
|
end
|
96
|
-
#
|
97
|
-
@content
|
98
|
-
end
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
101
|
+
def include_files(reldir, conf)
|
102
|
+
files = conf.scan(/^!include\s+(.*)\s*/).flatten.compact.map { |x| abs_path(reldir, x) }
|
103
|
+
dirs = conf.scan(/^!includedir\s+(.*)\s*/).flatten.compact.map { |x| abs_path(reldir, x) }
|
104
|
+
dirs.map do |dir|
|
105
|
+
# @TODO: non local glob
|
106
|
+
files += find_files(dir, depth: 1, type: 'file')
|
107
|
+
end
|
108
|
+
files
|
106
109
|
end
|
107
|
-
files
|
108
|
-
end
|
109
110
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
def abs_path(dir, f)
|
112
|
+
return f if f.start_with? '/'
|
113
|
+
File.join(dir, f)
|
114
|
+
end
|
114
115
|
|
115
|
-
|
116
|
-
|
117
|
-
|
116
|
+
def read_file(path)
|
117
|
+
@files_contents[path] ||= inspec.file(path).content
|
118
|
+
end
|
118
119
|
|
119
|
-
|
120
|
-
|
120
|
+
def to_s
|
121
|
+
'MySQL Configuration'
|
122
|
+
end
|
121
123
|
end
|
122
124
|
end
|
@@ -4,56 +4,58 @@
|
|
4
4
|
# author: Christoph Hartmann
|
5
5
|
# license: All rights reserved
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
module Inspec::Resources
|
8
|
+
class MysqlSession < Inspec.resource(1)
|
9
|
+
name 'mysql_session'
|
10
|
+
desc 'Use the mysql_session InSpec audit resource to test SQL commands run against a MySQL database.'
|
11
|
+
example "
|
12
|
+
sql = mysql_session('my_user','password')
|
13
|
+
describe sql.query('show databases like \'test\';') do
|
14
|
+
its(:stdout) { should_not match(/test/) }
|
15
|
+
end
|
16
|
+
"
|
17
|
+
|
18
|
+
def initialize(user = nil, pass = nil)
|
19
|
+
@user = user
|
20
|
+
@pass = pass
|
21
|
+
init_fallback if user.nil? or pass.nil?
|
22
|
+
skip_resource("Can't run MySQL SQL checks without authentication") if @user.nil? or @pass.nil?
|
14
23
|
end
|
15
|
-
"
|
16
24
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
out.downcase =~ /^error/
|
34
|
-
# skip this test if the server can't run the query
|
35
|
-
skip_resource("Can't connect to MySQL instance for SQL checks.")
|
25
|
+
def query(q, db = '')
|
26
|
+
# TODO: simple escape, must be handled by a library
|
27
|
+
# that does this securely
|
28
|
+
escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
|
29
|
+
|
30
|
+
# run the query
|
31
|
+
cmd = inspec.command("mysql -u#{@user} -p#{@pass} #{db} -s -e \"#{escaped_query}\"")
|
32
|
+
out = cmd.stdout + "\n" + cmd.stderr
|
33
|
+
if out =~ /Can't connect to .* MySQL server/ or
|
34
|
+
out.downcase =~ /^error/
|
35
|
+
# skip this test if the server can't run the query
|
36
|
+
skip_resource("Can't connect to MySQL instance for SQL checks.")
|
37
|
+
end
|
38
|
+
|
39
|
+
# return the raw command output
|
40
|
+
cmd
|
36
41
|
end
|
37
42
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def to_s
|
43
|
-
'MySQL Session'
|
44
|
-
end
|
43
|
+
def to_s
|
44
|
+
'MySQL Session'
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
+
private
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
def init_fallback
|
50
|
+
# support debian mysql administration login
|
51
|
+
debian = inspec.command('test -f /etc/mysql/debian.cnf && cat /etc/mysql/debian.cnf').stdout
|
52
|
+
return if debian.empty?
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
user = debian.match(/^\s*user\s*=\s*([^ ]*)\s*$/)
|
55
|
+
pass = debian.match(/^\s*password\s*=\s*([^ ]*)\s*$/)
|
56
|
+
return if user.nil? or pass.nil?
|
57
|
+
@user = user[1]
|
58
|
+
@pass = pass[1]
|
59
|
+
end
|
58
60
|
end
|
59
61
|
end
|