inspec 1.29.0 → 1.30.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/bin/inspec +1 -1
  4. data/docs/profiles.md +14 -5
  5. data/docs/resources/iptables.md.erb +12 -5
  6. data/docs/resources/mssql_session.md.erb +11 -28
  7. data/docs/resources/mysql_session.md.erb +12 -0
  8. data/docs/resources/oracledb_session.md.erb +10 -28
  9. data/docs/resources/package.md.erb +6 -0
  10. data/docs/resources/postgres_conf.md.erb +2 -0
  11. data/examples/inheritance/controls/example.rb +0 -1
  12. data/examples/meta-profile/controls/example.rb +0 -1
  13. data/examples/profile/controls/example.rb +0 -1
  14. data/examples/profile/controls/gordon.rb +0 -1
  15. data/inspec.gemspec +1 -0
  16. data/lib/bundles/inspec-compliance/api.rb +12 -10
  17. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +0 -1
  18. data/lib/inspec.rb +0 -1
  19. data/lib/inspec/backend.rb +0 -1
  20. data/lib/inspec/cli.rb +1 -1
  21. data/lib/inspec/metadata.rb +1 -1
  22. data/lib/inspec/polyfill.rb +0 -1
  23. data/lib/inspec/profile.rb +1 -1
  24. data/lib/inspec/resource.rb +1 -1
  25. data/lib/inspec/rule.rb +0 -1
  26. data/lib/inspec/runner.rb +0 -1
  27. data/lib/inspec/version.rb +1 -1
  28. data/lib/matchers/matchers.rb +0 -1
  29. data/lib/resources/apache.rb +0 -1
  30. data/lib/resources/apache_conf.rb +0 -1
  31. data/lib/resources/audit_policy.rb +0 -1
  32. data/lib/resources/auditd_conf.rb +0 -1
  33. data/lib/resources/auditd_rules.rb +0 -1
  34. data/lib/resources/command.rb +0 -1
  35. data/lib/resources/directory.rb +7 -3
  36. data/lib/resources/docker.rb +30 -3
  37. data/lib/resources/etc_group.rb +0 -1
  38. data/lib/resources/file.rb +0 -1
  39. data/lib/resources/grub_conf.rb +0 -1
  40. data/lib/resources/inetd_conf.rb +0 -1
  41. data/lib/resources/kernel_module.rb +0 -1
  42. data/lib/resources/kernel_parameter.rb +0 -1
  43. data/lib/resources/limits_conf.rb +0 -1
  44. data/lib/resources/login_def.rb +0 -1
  45. data/lib/resources/mssql_session.rb +62 -14
  46. data/lib/resources/mysql.rb +0 -1
  47. data/lib/resources/mysql_conf.rb +0 -1
  48. data/lib/resources/mysql_session.rb +15 -6
  49. data/lib/resources/nginx_conf.rb +95 -0
  50. data/lib/resources/ntp_conf.rb +0 -1
  51. data/lib/resources/oracledb_session.rb +109 -12
  52. data/lib/resources/os_env.rb +0 -1
  53. data/lib/resources/package.rb +47 -3
  54. data/lib/resources/packages.rb +0 -1
  55. data/lib/resources/parse_config.rb +0 -1
  56. data/lib/resources/passwd.rb +0 -1
  57. data/lib/resources/postgres.rb +9 -5
  58. data/lib/resources/postgres_conf.rb +12 -3
  59. data/lib/resources/postgres_session.rb +0 -1
  60. data/lib/resources/powershell.rb +0 -1
  61. data/lib/resources/processes.rb +0 -1
  62. data/lib/resources/registry_key.rb +0 -1
  63. data/lib/resources/service.rb +1 -1
  64. data/lib/resources/ssh_conf.rb +0 -1
  65. data/lib/resources/ssl.rb +0 -1
  66. data/lib/utils/database_helpers.rb +77 -0
  67. data/lib/utils/filter_array.rb +0 -1
  68. data/lib/utils/find_files.rb +0 -1
  69. data/lib/utils/nginx_parser.rb +4 -2
  70. data/lib/utils/simpleconfig.rb +0 -1
  71. metadata +18 -2
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright 2015 Dominik Richter. All rights reserved.
2
+ # Copyright 2015 Dominik Richter
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
5
 
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # copyright: 2015, Vulcano Security GmbH
3
- # license: All rights reserved
4
3
  # author: Dominik Richter
5
4
  # author: Christoph Hartmann
6
5
  require 'inspec/plugins'
@@ -112,6 +111,7 @@ require 'resources/mssql_session'
112
111
  require 'resources/mysql'
113
112
  require 'resources/mysql_conf'
114
113
  require 'resources/mysql_session'
114
+ require 'resources/nginx_conf'
115
115
  require 'resources/npm'
116
116
  require 'resources/ntp_conf'
117
117
  require 'resources/oneget'
data/lib/inspec/rule.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # copyright: 2015, Dominik Richter
3
- # license: All rights reserved
4
3
  # author: Dominik Richter
5
4
  # author: Christoph Hartmann
6
5
 
data/lib/inspec/runner.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # copyright: 2015, Dominik Richter
3
- # license: All rights reserved
4
3
  # author: Dominik Richter
5
4
  # author: Christoph Hartmann
6
5
 
@@ -4,5 +4,5 @@
4
4
  # author: Christoph Hartmann
5
5
 
6
6
  module Inspec
7
- VERSION = '1.29.0'.freeze
7
+ VERSION = '1.30.0'.freeze
8
8
  end
@@ -2,7 +2,6 @@
2
2
  # copyright: 2015, Vulcano Security GmbH
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
- # license: All rights reserved
6
5
 
7
6
  RSpec::Matchers.define :be_readable do
8
7
  match do |file|
@@ -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 Apache < Inspec.resource(1)
@@ -2,7 +2,6 @@
2
2
  # copyright: 2015, Vulcano Security GmbH
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
- # license: All rights reserved
6
5
 
7
6
  require 'utils/simpleconfig'
8
7
  require 'utils/find_files'
@@ -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
  # Advanced Auditing:
8
7
  # As soon as you start applying Advanced Audit Configuration Policy, legacy policies will be completely ignored.
@@ -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
 
@@ -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 'forwardable'
8
7
  require 'utils/filter_array'
@@ -2,7 +2,6 @@
2
2
  # copyright: 2015, Vulcano Security GmbH
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
- # license: All rights reserved
6
5
 
7
6
  module Inspec::Resources
8
7
  class Cmd < Inspec.resource(1)
@@ -13,9 +13,13 @@ module Inspec::Resources
13
13
  it { should be_directory }
14
14
  end
15
15
  "
16
- end
17
16
 
18
- def to_s
19
- "Directory #{@path}"
17
+ def exist?
18
+ file.exist? && file.directory?
19
+ end
20
+
21
+ def to_s
22
+ "Directory #{source_path}"
23
+ end
20
24
  end
21
25
  end
@@ -107,7 +107,9 @@ module Inspec::Resources
107
107
 
108
108
  def version
109
109
  return @version if defined?(@version)
110
- data = JSON.parse(inspec.command('docker version --format \'{{ json . }}\'').stdout)
110
+ data = {}
111
+ cmd = inspec.command('docker version --format \'{{ json . }}\'')
112
+ data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
111
113
  @version = Hashie::Mash.new(data)
112
114
  rescue JSON::ParserError => _e
113
115
  return Hashie::Mash.new({})
@@ -115,7 +117,10 @@ module Inspec::Resources
115
117
 
116
118
  def info
117
119
  return @info if defined?(@info)
118
- data = JSON.parse(inspec.command('docker info --format \'{{ json . }}\'').stdout)
120
+ data = {}
121
+ # docke info format is only supported for Docker 17.03+
122
+ cmd = inspec.command('docker info --format \'{{ json . }}\'')
123
+ data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
119
124
  @info = Hashie::Mash.new(data)
120
125
  rescue JSON::ParserError => _e
121
126
  return Hashie::Mash.new({})
@@ -138,7 +143,19 @@ module Inspec::Resources
138
143
  private
139
144
 
140
145
  def parse_containers
141
- raw_containers = inspec.command('docker ps -a --no-trunc --format \'{{ json . }}\'').stdout
146
+ # @see https://github.com/moby/moby/issues/20625, works for docker 1.13+
147
+ # raw_containers = inspec.command('docker ps -a --no-trunc --format \'{{ json . }}\'').stdout
148
+ # therefore we stick with older approach
149
+ labels = %w{Command CreatedAt ID Image Labels Mounts Names Ports RunningFor Size Status}
150
+
151
+ # Networks LocalVolumes work with 1.13+ only
152
+ if !version.empty? && Gem::Version.new(version['Client']['Version']) >= Gem::Version.new('1.13')
153
+ labels.push('Networks')
154
+ labels.push('LocalVolumes')
155
+ end
156
+ # build command
157
+ format = labels.map { |label| "\"#{label}\": {{json .#{label}}}" }
158
+ raw_containers = inspec.command("docker ps -a --no-trunc --format '{#{format.join(', ')}}'").stdout
142
159
  ps = []
143
160
  # since docker is not outputting valid json, we need to parse each row
144
161
  raw_containers.each_line { |entry|
@@ -147,6 +164,9 @@ module Inspec::Resources
147
164
  j = j.map { |k, v|
148
165
  [k.downcase, v]
149
166
  }.to_h
167
+
168
+ # ensure all keys are there
169
+ j = ensure_container_keys(j)
150
170
  ps.push(j)
151
171
  }
152
172
  ps
@@ -155,6 +175,13 @@ module Inspec::Resources
155
175
  []
156
176
  end
157
177
 
178
+ def ensure_container_keys(entry)
179
+ %w{Command CreatedAt ID Image Labels Mounts Names Ports RunningFor Size Status Networks LocalVolumes}.each { |key|
180
+ entry[key.downcase] = nil if !entry.key?(key.downcase)
181
+ }
182
+ entry
183
+ end
184
+
158
185
  def parse_images
159
186
  # docker does not support the `json .` function here, therefore we need to emulate that behavior.
160
187
  raw_images = inspec.command('docker images -a --no-trunc --format \'{ "id": {{json .ID}}, "repository": {{json .Repository}}, "tag": {{json .Tag}}, "size": {{json .Size}}, "digest": {{json .Digest}}, "createdat": {{json .CreatedAt}}, "createdsize": {{json .CreatedSince}} }\'').stdout
@@ -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
  # The file format consists of
8
7
  # - group name
@@ -2,7 +2,6 @@
2
2
  # copyright: 2015, Vulcano Security GmbH
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
- # license: All rights reserved
6
5
 
7
6
  require 'shellwords'
8
7
 
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # author: Thomas Cate
3
- # license: All rights reserved
4
3
 
5
4
  require 'utils/simpleconfig'
6
5
 
@@ -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
 
@@ -1,7 +1,6 @@
1
1
  # encoding: utf-8
2
2
  # author: Christoph Hartmann
3
3
  # author: Dominik Richter
4
- # license: All rights reserved
5
4
 
6
5
  module Inspec::Resources
7
6
  class KernelModule < Inspec.resource(1)
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # author: Christoph Hartmann
3
- # license: All rights reserved
4
3
 
5
4
  module Inspec::Resources
6
5
  class KernelParameter < Inspec.resource(1)
@@ -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
 
@@ -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
 
@@ -1,54 +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
20
  # Using SQL authentication
11
21
  sql = mssql_session(user: 'myuser', pass: 'mypassword')
12
- describe sql.query('select * from sys.databases where name like \'*test*\') do
13
- its('stdout') { should_not match(/test/) }
22
+ describe sql.query('SELECT * FROM table').row(0).column('columnname') do
23
+ its('value') { should cmp == 1 }
14
24
  end
15
25
 
16
26
  # Passing no credentials to mssql_session forces it to use Windows authentication
17
27
  sql_windows_auth = mssql_session
18
- describe sql_window_auth.query('select * from sys.databases where name like \'*test*\') do
19
- its('stdout') { should_not match(/test/) }
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 }
20
31
  end
21
32
  "
22
33
 
23
- attr_reader :user, :pass, :host
24
-
34
+ attr_reader :user, :password, :host
25
35
  def initialize(opts = {})
26
36
  @user = opts[:user]
27
- @pass = opts[:pass]
37
+ @password = opts[:password] || opts[:pass]
38
+ if opts[:pass]
39
+ warn '[DEPRECATED] use `password` option to supply password instead of `pass`'
40
+ end
28
41
  @host = opts[:host] || 'localhost'
29
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
30
48
  end
31
49
 
32
50
  def query(q)
33
- escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$').gsub(/\@/, '`@')
34
- cmd_string = "sqlcmd -Q \"#{escaped_query}\""
35
- cmd_string += " -U #{@user} -P #{@pass}" unless @user.nil? or @pass.nil?
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?
36
55
  if @instance.nil?
37
56
  cmd_string += " -S #{@host}"
38
57
  else
39
58
  cmd_string += " -S #{@host}\\#{@instance}"
40
59
  end
41
- puts cmd_string
42
60
  cmd = inspec.command(cmd_string)
43
61
  out = cmd.stdout + "\n" + cmd.stderr
44
- if out =~ /Sqlcmd: Error/
45
- skip_resource("Can't connect to the MS SQL Server.")
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))
46
69
  end
47
- cmd
48
70
  end
49
71
 
50
72
  def to_s
51
73
  'MSSQL session'
52
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
100
+ end
53
101
  end
54
102
  end
@@ -2,7 +2,6 @@
2
2
  # copyright: 2015, Vulcano Security GmbH
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
- # license: All rights reserved
6
5
 
7
6
  module Inspec::Resources
8
7
  class Mysql < Inspec.resource(1)
@@ -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'
@@ -3,7 +3,6 @@
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
5
  # author: Aaron Lippold
6
- # license: All rights reserved
7
6
 
8
7
  module Inspec::Resources
9
8
  class MysqlSession < Inspec.resource(1)
@@ -16,10 +15,12 @@ module Inspec::Resources
16
15
  end
17
16
  "
18
17
 
19
- def initialize(user = nil, pass = nil, host = 'localhost')
18
+ def initialize(user = nil, pass = nil, host = 'localhost', port = nil, socket = nil)
20
19
  @user = user
21
20
  @pass = pass
22
21
  @host = host
22
+ @port = port
23
+ @socket = socket
23
24
  init_fallback if user.nil? or pass.nil?
24
25
  skip_resource("Can't run MySQL SQL checks without authentication") if @user.nil? or @pass.nil?
25
26
  end
@@ -30,12 +31,20 @@ module Inspec::Resources
30
31
  escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
31
32
 
32
33
  # run the query
33
- cmd = inspec.command("mysql -u#{@user} -p#{@pass} -h #{@host} #{db} -s -e \"#{escaped_query}\"")
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 -S #{@socket} -e \"#{escaped_query}\""
42
+
43
+ cmd = inspec.command(command)
34
44
  out = cmd.stdout + "\n" + cmd.stderr
35
- if out =~ /Can't connect to .* MySQL server/ or
36
- out.downcase =~ /^error/
45
+ if out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error/
37
46
  # skip this test if the server can't run the query
38
- skip_resource("Can't connect to MySQL instance for SQL checks.")
47
+ warn("Can't connect to MySQL instance for SQL checks.")
39
48
  end
40
49
 
41
50
  # return the raw command output