inspec 2.1.0 → 2.1.10

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 (489) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +101 -101
  3. data/CHANGELOG.md +3024 -3004
  4. data/Gemfile +55 -55
  5. data/LICENSE +14 -14
  6. data/MAINTAINERS.md +33 -33
  7. data/MAINTAINERS.toml +52 -52
  8. data/README.md +447 -446
  9. data/Rakefile +322 -322
  10. data/bin/inspec +12 -12
  11. data/docs/.gitignore +2 -2
  12. data/docs/README.md +40 -40
  13. data/docs/dsl_inspec.md +258 -258
  14. data/docs/dsl_resource.md +100 -93
  15. data/docs/glossary.md +99 -99
  16. data/docs/habitat.md +191 -191
  17. data/docs/inspec_and_friends.md +114 -114
  18. data/docs/matchers.md +169 -169
  19. data/docs/migration.md +293 -293
  20. data/docs/platforms.md +118 -118
  21. data/docs/plugin_kitchen_inspec.md +50 -50
  22. data/docs/profiles.md +376 -376
  23. data/docs/reporters.md +105 -105
  24. data/docs/resources/aide_conf.md.erb +75 -75
  25. data/docs/resources/apache.md.erb +67 -67
  26. data/docs/resources/apache_conf.md.erb +68 -68
  27. data/docs/resources/apt.md.erb +71 -71
  28. data/docs/resources/audit_policy.md.erb +47 -47
  29. data/docs/resources/auditd.md.erb +79 -79
  30. data/docs/resources/auditd_conf.md.erb +68 -68
  31. data/docs/resources/aws_cloudtrail_trail.md.erb +140 -140
  32. data/docs/resources/aws_cloudtrail_trails.md.erb +81 -81
  33. data/docs/resources/aws_cloudwatch_alarm.md.erb +86 -86
  34. data/docs/resources/aws_cloudwatch_log_metric_filter.md.erb +151 -151
  35. data/docs/resources/aws_config_recorder.md.erb +71 -71
  36. data/docs/resources/aws_ec2_instance.md.erb +106 -106
  37. data/docs/resources/aws_iam_access_key.md.erb +123 -123
  38. data/docs/resources/aws_iam_access_keys.md.erb +198 -198
  39. data/docs/resources/aws_iam_group.md.erb +46 -46
  40. data/docs/resources/aws_iam_groups.md.erb +43 -43
  41. data/docs/resources/aws_iam_password_policy.md.erb +76 -76
  42. data/docs/resources/aws_iam_policies.md.erb +82 -82
  43. data/docs/resources/aws_iam_policy.md.erb +144 -144
  44. data/docs/resources/aws_iam_role.md.erb +63 -63
  45. data/docs/resources/aws_iam_root_user.md.erb +58 -58
  46. data/docs/resources/aws_iam_user.md.erb +64 -64
  47. data/docs/resources/aws_iam_users.md.erb +89 -89
  48. data/docs/resources/aws_kms_keys.md.erb +84 -84
  49. data/docs/resources/aws_route_table.md.erb +47 -47
  50. data/docs/resources/aws_s3_bucket.md.erb +134 -134
  51. data/docs/resources/aws_s3_bucket_object.md.erb +83 -0
  52. data/docs/resources/aws_security_group.md.erb +151 -151
  53. data/docs/resources/aws_security_groups.md.erb +91 -91
  54. data/docs/resources/aws_sns_subscription.md.erb +125 -0
  55. data/docs/resources/aws_sns_topic.md.erb +63 -63
  56. data/docs/resources/aws_sns_topics.md.erb +52 -0
  57. data/docs/resources/aws_subnet.md.erb +134 -134
  58. data/docs/resources/aws_subnets.md.erb +126 -126
  59. data/docs/resources/aws_vpc.md.erb +120 -120
  60. data/docs/resources/aws_vpcs.md.erb +48 -48
  61. data/docs/resources/azure_generic_resource.md.erb +171 -171
  62. data/docs/resources/azure_resource_group.md.erb +284 -284
  63. data/docs/resources/azure_virtual_machine.md.erb +347 -347
  64. data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -224
  65. data/docs/resources/bash.md.erb +75 -75
  66. data/docs/resources/bond.md.erb +90 -90
  67. data/docs/resources/bridge.md.erb +57 -57
  68. data/docs/resources/bsd_service.md.erb +67 -67
  69. data/docs/resources/command.md.erb +138 -138
  70. data/docs/resources/cpan.md.erb +79 -79
  71. data/docs/resources/cran.md.erb +64 -64
  72. data/docs/resources/crontab.md.erb +89 -89
  73. data/docs/resources/csv.md.erb +54 -54
  74. data/docs/resources/dh_params.md.erb +205 -205
  75. data/docs/resources/directory.md.erb +30 -30
  76. data/docs/resources/docker.md.erb +219 -219
  77. data/docs/resources/docker_container.md.erb +103 -103
  78. data/docs/resources/docker_image.md.erb +94 -94
  79. data/docs/resources/docker_service.md.erb +114 -114
  80. data/docs/resources/elasticsearch.md.erb +242 -242
  81. data/docs/resources/etc_fstab.md.erb +125 -125
  82. data/docs/resources/etc_group.md.erb +75 -75
  83. data/docs/resources/etc_hosts.md.erb +78 -78
  84. data/docs/resources/etc_hosts_allow.md.erb +74 -74
  85. data/docs/resources/etc_hosts_deny.md.erb +74 -74
  86. data/docs/resources/file.md.erb +526 -526
  87. data/docs/resources/filesystem.md.erb +41 -41
  88. data/docs/resources/firewalld.md.erb +107 -107
  89. data/docs/resources/gem.md.erb +79 -79
  90. data/docs/resources/group.md.erb +61 -61
  91. data/docs/resources/grub_conf.md.erb +101 -101
  92. data/docs/resources/host.md.erb +86 -86
  93. data/docs/resources/http.md.erb +196 -196
  94. data/docs/resources/iis_app.md.erb +122 -122
  95. data/docs/resources/iis_site.md.erb +135 -135
  96. data/docs/resources/inetd_conf.md.erb +94 -94
  97. data/docs/resources/ini.md.erb +76 -76
  98. data/docs/resources/interface.md.erb +58 -58
  99. data/docs/resources/iptables.md.erb +64 -64
  100. data/docs/resources/json.md.erb +63 -63
  101. data/docs/resources/kernel_module.md.erb +120 -120
  102. data/docs/resources/kernel_parameter.md.erb +53 -53
  103. data/docs/resources/key_rsa.md.erb +85 -85
  104. data/docs/resources/launchd_service.md.erb +57 -57
  105. data/docs/resources/limits_conf.md.erb +75 -75
  106. data/docs/resources/{login_def.md.erb → login_defs.md.erb} +71 -71
  107. data/docs/resources/mount.md.erb +69 -69
  108. data/docs/resources/mssql_session.md.erb +60 -60
  109. data/docs/resources/mysql_conf.md.erb +99 -99
  110. data/docs/resources/mysql_session.md.erb +74 -74
  111. data/docs/resources/nginx.md.erb +79 -79
  112. data/docs/resources/nginx_conf.md.erb +138 -128
  113. data/docs/resources/npm.md.erb +60 -60
  114. data/docs/resources/ntp_conf.md.erb +60 -60
  115. data/docs/resources/oneget.md.erb +53 -53
  116. data/docs/resources/oracledb_session.md.erb +52 -52
  117. data/docs/resources/os.md.erb +141 -141
  118. data/docs/resources/os_env.md.erb +78 -78
  119. data/docs/resources/package.md.erb +120 -120
  120. data/docs/resources/packages.md.erb +67 -67
  121. data/docs/resources/parse_config.md.erb +103 -103
  122. data/docs/resources/parse_config_file.md.erb +138 -138
  123. data/docs/resources/passwd.md.erb +141 -141
  124. data/docs/resources/pip.md.erb +67 -67
  125. data/docs/resources/port.md.erb +137 -137
  126. data/docs/resources/postgres_conf.md.erb +79 -79
  127. data/docs/resources/postgres_hba_conf.md.erb +93 -93
  128. data/docs/resources/postgres_ident_conf.md.erb +76 -76
  129. data/docs/resources/postgres_session.md.erb +69 -69
  130. data/docs/resources/powershell.md.erb +102 -102
  131. data/docs/resources/processes.md.erb +109 -109
  132. data/docs/resources/rabbitmq_config.md.erb +41 -41
  133. data/docs/resources/registry_key.md.erb +158 -158
  134. data/docs/resources/runit_service.md.erb +57 -57
  135. data/docs/resources/security_policy.md.erb +47 -47
  136. data/docs/resources/service.md.erb +121 -121
  137. data/docs/resources/shadow.md.erb +146 -146
  138. data/docs/resources/ssh_config.md.erb +73 -80
  139. data/docs/resources/sshd_config.md.erb +83 -83
  140. data/docs/resources/ssl.md.erb +119 -119
  141. data/docs/resources/sys_info.md.erb +42 -42
  142. data/docs/resources/systemd_service.md.erb +57 -57
  143. data/docs/resources/sysv_service.md.erb +57 -57
  144. data/docs/resources/upstart_service.md.erb +57 -57
  145. data/docs/resources/user.md.erb +140 -140
  146. data/docs/resources/users.md.erb +127 -127
  147. data/docs/resources/vbscript.md.erb +55 -55
  148. data/docs/resources/virtualization.md.erb +57 -57
  149. data/docs/resources/windows_feature.md.erb +47 -47
  150. data/docs/resources/windows_hotfix.md.erb +53 -53
  151. data/docs/resources/windows_task.md.erb +95 -95
  152. data/docs/resources/wmi.md.erb +81 -81
  153. data/docs/resources/x509_certificate.md.erb +151 -151
  154. data/docs/resources/xinetd_conf.md.erb +156 -156
  155. data/docs/resources/xml.md.erb +85 -85
  156. data/docs/resources/yaml.md.erb +69 -69
  157. data/docs/resources/yum.md.erb +98 -98
  158. data/docs/resources/zfs_dataset.md.erb +53 -53
  159. data/docs/resources/zfs_pool.md.erb +47 -47
  160. data/docs/ruby_usage.md +203 -203
  161. data/docs/shared/matcher_be.md.erb +1 -1
  162. data/docs/shared/matcher_cmp.md.erb +43 -43
  163. data/docs/shared/matcher_eq.md.erb +3 -3
  164. data/docs/shared/matcher_include.md.erb +1 -1
  165. data/docs/shared/matcher_match.md.erb +1 -1
  166. data/docs/shell.md +217 -217
  167. data/examples/README.md +8 -8
  168. data/examples/inheritance/README.md +65 -65
  169. data/examples/inheritance/controls/example.rb +14 -14
  170. data/examples/inheritance/inspec.yml +15 -15
  171. data/examples/kitchen-ansible/.kitchen.yml +25 -25
  172. data/examples/kitchen-ansible/Gemfile +19 -19
  173. data/examples/kitchen-ansible/README.md +53 -53
  174. data/examples/kitchen-ansible/files/nginx.repo +6 -6
  175. data/examples/kitchen-ansible/tasks/main.yml +16 -16
  176. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
  177. data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
  178. data/examples/kitchen-chef/.kitchen.yml +20 -20
  179. data/examples/kitchen-chef/Berksfile +3 -3
  180. data/examples/kitchen-chef/Gemfile +19 -19
  181. data/examples/kitchen-chef/README.md +27 -27
  182. data/examples/kitchen-chef/metadata.rb +7 -7
  183. data/examples/kitchen-chef/recipes/default.rb +6 -6
  184. data/examples/kitchen-chef/recipes/nginx.rb +30 -30
  185. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
  186. data/examples/kitchen-puppet/.kitchen.yml +22 -22
  187. data/examples/kitchen-puppet/Gemfile +20 -20
  188. data/examples/kitchen-puppet/Puppetfile +25 -25
  189. data/examples/kitchen-puppet/README.md +53 -53
  190. data/examples/kitchen-puppet/manifests/site.pp +33 -33
  191. data/examples/kitchen-puppet/metadata.json +11 -11
  192. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
  193. data/examples/meta-profile/README.md +37 -37
  194. data/examples/meta-profile/controls/example.rb +13 -13
  195. data/examples/meta-profile/inspec.yml +13 -13
  196. data/examples/profile-attribute.yml +2 -2
  197. data/examples/profile-attribute/README.md +14 -14
  198. data/examples/profile-attribute/controls/example.rb +11 -11
  199. data/examples/profile-attribute/inspec.yml +8 -8
  200. data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
  201. data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
  202. data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
  203. data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
  204. data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
  205. data/examples/profile-aws/inspec.yml +11 -11
  206. data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
  207. data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
  208. data/examples/profile-azure/inspec.yml +11 -11
  209. data/examples/profile-sensitive/README.md +29 -29
  210. data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
  211. data/examples/profile-sensitive/controls/sensitive.rb +9 -9
  212. data/examples/profile-sensitive/inspec.yml +8 -8
  213. data/examples/profile/README.md +48 -48
  214. data/examples/profile/controls/example.rb +23 -23
  215. data/examples/profile/controls/gordon.rb +36 -36
  216. data/examples/profile/controls/meta.rb +34 -34
  217. data/examples/profile/inspec.yml +10 -10
  218. data/examples/profile/libraries/gordon_config.rb +53 -53
  219. data/inspec.gemspec +47 -47
  220. data/lib/bundles/README.md +3 -3
  221. data/lib/bundles/inspec-artifact.rb +7 -7
  222. data/lib/bundles/inspec-artifact/README.md +1 -1
  223. data/lib/bundles/inspec-artifact/cli.rb +277 -277
  224. data/lib/bundles/inspec-compliance.rb +16 -16
  225. data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
  226. data/lib/bundles/inspec-compliance/README.md +185 -185
  227. data/lib/bundles/inspec-compliance/api.rb +316 -316
  228. data/lib/bundles/inspec-compliance/api/login.rb +152 -152
  229. data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
  230. data/lib/bundles/inspec-compliance/cli.rb +254 -254
  231. data/lib/bundles/inspec-compliance/configuration.rb +103 -103
  232. data/lib/bundles/inspec-compliance/http.rb +86 -86
  233. data/lib/bundles/inspec-compliance/support.rb +36 -36
  234. data/lib/bundles/inspec-compliance/target.rb +98 -98
  235. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
  236. data/lib/bundles/inspec-habitat.rb +12 -12
  237. data/lib/bundles/inspec-habitat/cli.rb +36 -36
  238. data/lib/bundles/inspec-habitat/log.rb +10 -10
  239. data/lib/bundles/inspec-habitat/profile.rb +390 -390
  240. data/lib/bundles/inspec-init.rb +8 -8
  241. data/lib/bundles/inspec-init/README.md +31 -31
  242. data/lib/bundles/inspec-init/cli.rb +97 -97
  243. data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
  244. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
  245. data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
  246. data/lib/bundles/inspec-supermarket.rb +13 -13
  247. data/lib/bundles/inspec-supermarket/README.md +45 -45
  248. data/lib/bundles/inspec-supermarket/api.rb +84 -84
  249. data/lib/bundles/inspec-supermarket/cli.rb +73 -73
  250. data/lib/bundles/inspec-supermarket/target.rb +34 -34
  251. data/lib/fetchers/git.rb +163 -163
  252. data/lib/fetchers/local.rb +74 -74
  253. data/lib/fetchers/mock.rb +35 -35
  254. data/lib/fetchers/url.rb +204 -204
  255. data/lib/inspec.rb +24 -24
  256. data/lib/inspec/archive/tar.rb +29 -29
  257. data/lib/inspec/archive/zip.rb +19 -19
  258. data/lib/inspec/backend.rb +93 -93
  259. data/lib/inspec/base_cli.rb +357 -355
  260. data/lib/inspec/cached_fetcher.rb +66 -66
  261. data/lib/inspec/cli.rb +292 -292
  262. data/lib/inspec/completions/bash.sh.erb +45 -45
  263. data/lib/inspec/completions/fish.sh.erb +34 -34
  264. data/lib/inspec/completions/zsh.sh.erb +61 -61
  265. data/lib/inspec/control_eval_context.rb +179 -179
  266. data/lib/inspec/dependencies/cache.rb +72 -72
  267. data/lib/inspec/dependencies/dependency_set.rb +92 -92
  268. data/lib/inspec/dependencies/lockfile.rb +115 -115
  269. data/lib/inspec/dependencies/requirement.rb +123 -123
  270. data/lib/inspec/dependencies/resolver.rb +86 -86
  271. data/lib/inspec/describe.rb +27 -27
  272. data/lib/inspec/dsl.rb +66 -66
  273. data/lib/inspec/dsl_shared.rb +33 -33
  274. data/lib/inspec/env_printer.rb +157 -157
  275. data/lib/inspec/errors.rb +13 -13
  276. data/lib/inspec/exceptions.rb +12 -12
  277. data/lib/inspec/expect.rb +45 -45
  278. data/lib/inspec/fetcher.rb +45 -45
  279. data/lib/inspec/file_provider.rb +275 -275
  280. data/lib/inspec/formatters.rb +3 -3
  281. data/lib/inspec/formatters/base.rb +250 -250
  282. data/lib/inspec/formatters/json_rspec.rb +20 -20
  283. data/lib/inspec/formatters/show_progress.rb +12 -12
  284. data/lib/inspec/library_eval_context.rb +58 -58
  285. data/lib/inspec/log.rb +11 -11
  286. data/lib/inspec/metadata.rb +247 -247
  287. data/lib/inspec/method_source.rb +24 -24
  288. data/lib/inspec/objects.rb +14 -14
  289. data/lib/inspec/objects/attribute.rb +65 -65
  290. data/lib/inspec/objects/control.rb +61 -61
  291. data/lib/inspec/objects/describe.rb +92 -92
  292. data/lib/inspec/objects/each_loop.rb +36 -36
  293. data/lib/inspec/objects/list.rb +15 -15
  294. data/lib/inspec/objects/or_test.rb +40 -40
  295. data/lib/inspec/objects/ruby_helper.rb +15 -15
  296. data/lib/inspec/objects/tag.rb +27 -27
  297. data/lib/inspec/objects/test.rb +87 -87
  298. data/lib/inspec/objects/value.rb +27 -27
  299. data/lib/inspec/plugins.rb +60 -60
  300. data/lib/inspec/plugins/cli.rb +24 -24
  301. data/lib/inspec/plugins/fetcher.rb +86 -86
  302. data/lib/inspec/plugins/resource.rb +135 -135
  303. data/lib/inspec/plugins/secret.rb +15 -15
  304. data/lib/inspec/plugins/source_reader.rb +40 -40
  305. data/lib/inspec/polyfill.rb +12 -12
  306. data/lib/inspec/profile.rb +510 -510
  307. data/lib/inspec/profile_context.rb +207 -207
  308. data/lib/inspec/profile_vendor.rb +66 -66
  309. data/lib/inspec/reporters.rb +54 -54
  310. data/lib/inspec/reporters/base.rb +24 -24
  311. data/lib/inspec/reporters/cli.rb +356 -356
  312. data/lib/inspec/reporters/json.rb +116 -116
  313. data/lib/inspec/reporters/json_min.rb +48 -48
  314. data/lib/inspec/reporters/junit.rb +77 -77
  315. data/lib/inspec/require_loader.rb +33 -33
  316. data/lib/inspec/resource.rb +186 -186
  317. data/lib/inspec/rule.rb +266 -266
  318. data/lib/inspec/runner.rb +345 -345
  319. data/lib/inspec/runner_mock.rb +41 -41
  320. data/lib/inspec/runner_rspec.rb +175 -175
  321. data/lib/inspec/runtime_profile.rb +26 -26
  322. data/lib/inspec/schema.rb +213 -213
  323. data/lib/inspec/secrets.rb +19 -19
  324. data/lib/inspec/secrets/yaml.rb +30 -30
  325. data/lib/inspec/shell.rb +220 -220
  326. data/lib/inspec/shell_detector.rb +90 -90
  327. data/lib/inspec/source_reader.rb +29 -29
  328. data/lib/inspec/version.rb +8 -8
  329. data/lib/matchers/matchers.rb +339 -339
  330. data/lib/resource_support/aws.rb +44 -41
  331. data/lib/resource_support/aws/aws_backend_base.rb +12 -12
  332. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
  333. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
  334. data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
  335. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
  336. data/lib/resources/aide_conf.rb +151 -159
  337. data/lib/resources/apache.rb +48 -48
  338. data/lib/resources/apache_conf.rb +149 -156
  339. data/lib/resources/apt.rb +149 -149
  340. data/lib/resources/audit_policy.rb +63 -63
  341. data/lib/resources/auditd.rb +231 -231
  342. data/lib/resources/auditd_conf.rb +46 -55
  343. data/lib/resources/aws/aws_cloudtrail_trail.rb +77 -77
  344. data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
  345. data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
  346. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
  347. data/lib/resources/aws/aws_config_recorder.rb +98 -98
  348. data/lib/resources/aws/aws_ec2_instance.rb +157 -157
  349. data/lib/resources/aws/aws_iam_access_key.rb +106 -106
  350. data/lib/resources/aws/aws_iam_access_keys.rb +149 -149
  351. data/lib/resources/aws/aws_iam_group.rb +56 -56
  352. data/lib/resources/aws/aws_iam_groups.rb +52 -52
  353. data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
  354. data/lib/resources/aws/aws_iam_policies.rb +53 -53
  355. data/lib/resources/aws/aws_iam_policy.rb +125 -125
  356. data/lib/resources/aws/aws_iam_role.rb +51 -51
  357. data/lib/resources/aws/aws_iam_root_user.rb +60 -60
  358. data/lib/resources/aws/aws_iam_user.rb +111 -111
  359. data/lib/resources/aws/aws_iam_users.rb +108 -108
  360. data/lib/resources/aws/aws_kms_keys.rb +53 -53
  361. data/lib/resources/aws/aws_route_table.rb +61 -61
  362. data/lib/resources/aws/aws_s3_bucket.rb +115 -115
  363. data/lib/resources/aws/aws_s3_bucket_object.rb +82 -0
  364. data/lib/resources/aws/aws_security_group.rb +93 -93
  365. data/lib/resources/aws/aws_security_groups.rb +68 -68
  366. data/lib/resources/aws/aws_sns_subscription.rb +78 -0
  367. data/lib/resources/aws/aws_sns_topic.rb +53 -53
  368. data/lib/resources/aws/aws_sns_topics.rb +56 -0
  369. data/lib/resources/aws/aws_subnet.rb +88 -88
  370. data/lib/resources/aws/aws_subnets.rb +53 -53
  371. data/lib/resources/aws/aws_vpc.rb +69 -69
  372. data/lib/resources/aws/aws_vpcs.rb +45 -45
  373. data/lib/resources/azure/azure_backend.rb +377 -377
  374. data/lib/resources/azure/azure_generic_resource.rb +59 -59
  375. data/lib/resources/azure/azure_resource_group.rb +152 -152
  376. data/lib/resources/azure/azure_virtual_machine.rb +264 -264
  377. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +136 -136
  378. data/lib/resources/bash.rb +35 -35
  379. data/lib/resources/bond.rb +69 -68
  380. data/lib/resources/bridge.rb +122 -122
  381. data/lib/resources/command.rb +73 -73
  382. data/lib/resources/cpan.rb +58 -58
  383. data/lib/resources/cran.rb +64 -64
  384. data/lib/resources/crontab.rb +169 -169
  385. data/lib/resources/csv.rb +56 -60
  386. data/lib/resources/dh_params.rb +77 -82
  387. data/lib/resources/directory.rb +25 -25
  388. data/lib/resources/docker.rb +236 -236
  389. data/lib/resources/docker_container.rb +89 -89
  390. data/lib/resources/docker_image.rb +83 -83
  391. data/lib/resources/docker_object.rb +57 -57
  392. data/lib/resources/docker_service.rb +90 -90
  393. data/lib/resources/elasticsearch.rb +169 -169
  394. data/lib/resources/etc_fstab.rb +94 -101
  395. data/lib/resources/etc_group.rb +152 -152
  396. data/lib/resources/etc_hosts.rb +66 -82
  397. data/lib/resources/etc_hosts_allow_deny.rb +112 -122
  398. data/lib/resources/file.rb +298 -298
  399. data/lib/resources/filesystem.rb +31 -31
  400. data/lib/resources/firewalld.rb +143 -143
  401. data/lib/resources/gem.rb +70 -70
  402. data/lib/resources/groups.rb +215 -215
  403. data/lib/resources/grub_conf.rb +227 -237
  404. data/lib/resources/host.rb +306 -306
  405. data/lib/resources/http.rb +251 -251
  406. data/lib/resources/iis_app.rb +101 -101
  407. data/lib/resources/iis_site.rb +148 -148
  408. data/lib/resources/inetd_conf.rb +54 -62
  409. data/lib/resources/ini.rb +29 -29
  410. data/lib/resources/interface.rb +129 -129
  411. data/lib/resources/iptables.rb +80 -80
  412. data/lib/resources/json.rb +107 -117
  413. data/lib/resources/kernel_module.rb +107 -107
  414. data/lib/resources/kernel_parameter.rb +58 -58
  415. data/lib/resources/key_rsa.rb +61 -67
  416. data/lib/resources/limits_conf.rb +46 -55
  417. data/lib/resources/login_def.rb +57 -66
  418. data/lib/resources/mount.rb +88 -88
  419. data/lib/resources/mssql_session.rb +101 -101
  420. data/lib/resources/mysql.rb +81 -81
  421. data/lib/resources/mysql_conf.rb +127 -134
  422. data/lib/resources/mysql_session.rb +85 -85
  423. data/lib/resources/nginx.rb +96 -96
  424. data/lib/resources/nginx_conf.rb +226 -227
  425. data/lib/resources/npm.rb +48 -48
  426. data/lib/resources/ntp_conf.rb +51 -58
  427. data/lib/resources/oneget.rb +71 -71
  428. data/lib/resources/oracledb_session.rb +139 -139
  429. data/lib/resources/os.rb +36 -36
  430. data/lib/resources/os_env.rb +76 -76
  431. data/lib/resources/package.rb +370 -370
  432. data/lib/resources/packages.rb +111 -111
  433. data/lib/resources/parse_config.rb +112 -116
  434. data/lib/resources/passwd.rb +76 -74
  435. data/lib/resources/pip.rb +89 -89
  436. data/lib/resources/platform.rb +109 -109
  437. data/lib/resources/port.rb +771 -771
  438. data/lib/resources/postgres.rb +130 -130
  439. data/lib/resources/postgres_conf.rb +114 -121
  440. data/lib/resources/postgres_hba_conf.rb +90 -99
  441. data/lib/resources/postgres_ident_conf.rb +79 -76
  442. data/lib/resources/postgres_session.rb +71 -71
  443. data/lib/resources/powershell.rb +53 -53
  444. data/lib/resources/processes.rb +204 -204
  445. data/lib/resources/rabbitmq_conf.rb +51 -52
  446. data/lib/resources/registry_key.rb +296 -296
  447. data/lib/resources/security_policy.rb +180 -180
  448. data/lib/resources/service.rb +790 -789
  449. data/lib/resources/shadow.rb +149 -146
  450. data/lib/resources/ssh_conf.rb +97 -102
  451. data/lib/resources/ssl.rb +99 -99
  452. data/lib/resources/sys_info.rb +28 -28
  453. data/lib/resources/toml.rb +32 -32
  454. data/lib/resources/users.rb +654 -654
  455. data/lib/resources/vbscript.rb +68 -68
  456. data/lib/resources/virtualization.rb +247 -247
  457. data/lib/resources/windows_feature.rb +84 -84
  458. data/lib/resources/windows_hotfix.rb +35 -35
  459. data/lib/resources/windows_task.rb +102 -102
  460. data/lib/resources/wmi.rb +110 -110
  461. data/lib/resources/x509_certificate.rb +137 -143
  462. data/lib/resources/xinetd.rb +106 -111
  463. data/lib/resources/xml.rb +46 -46
  464. data/lib/resources/yaml.rb +43 -47
  465. data/lib/resources/yum.rb +180 -180
  466. data/lib/resources/zfs_dataset.rb +60 -60
  467. data/lib/resources/zfs_pool.rb +49 -49
  468. data/lib/source_readers/flat.rb +39 -39
  469. data/lib/source_readers/inspec.rb +75 -75
  470. data/lib/utils/command_wrapper.rb +27 -27
  471. data/lib/utils/convert.rb +12 -12
  472. data/lib/utils/database_helpers.rb +77 -77
  473. data/lib/utils/erlang_parser.rb +192 -192
  474. data/lib/utils/file_reader.rb +25 -0
  475. data/lib/utils/filter.rb +272 -272
  476. data/lib/utils/filter_array.rb +27 -27
  477. data/lib/utils/find_files.rb +44 -44
  478. data/lib/utils/hash.rb +41 -41
  479. data/lib/utils/json_log.rb +18 -18
  480. data/lib/utils/latest_version.rb +22 -22
  481. data/lib/utils/modulator.rb +12 -12
  482. data/lib/utils/nginx_parser.rb +85 -85
  483. data/lib/utils/object_traversal.rb +49 -49
  484. data/lib/utils/parser.rb +274 -274
  485. data/lib/utils/plugin_registry.rb +93 -93
  486. data/lib/utils/simpleconfig.rb +120 -120
  487. data/lib/utils/spdx.rb +13 -13
  488. data/lib/utils/spdx.txt +343 -343
  489. metadata +12 -5
@@ -1,215 +1,215 @@
1
- # encoding: utf-8
2
-
3
- require 'utils/filter'
4
-
5
- module Inspec::Resources
6
- # This file contains two resources, the `group` and `groups` resource.
7
- # The `group` resource is optimized for requests that verify specific groups
8
- # that you know upfront for testing. If you need to query all groups or search
9
- # specific groups with certain properties, use the `groups` resource.
10
- module GroupManagementSelector
11
- # select group provider based on the operating system
12
- # returns nil, if no group manager was found for the operating system
13
- def select_group_manager(os)
14
- @group_provider = if os.darwin?
15
- DarwinGroup.new(inspec)
16
- elsif os.unix?
17
- UnixGroup.new(inspec)
18
- elsif os.windows?
19
- WindowsGroup.new(inspec)
20
- end
21
- end
22
- end
23
-
24
- class Groups < Inspec.resource(1)
25
- include GroupManagementSelector
26
-
27
- name 'groups'
28
- supports platform: 'unix'
29
- supports platform: 'windows'
30
- desc 'Use the group InSpec audit resource to test groups on the system. Groups can be filtered.'
31
- example "
32
- describe groups.where { name == 'root'} do
33
- its('names') { should eq ['root'] }
34
- its('gids') { should eq [0] }
35
- end
36
-
37
- describe groups.where { name == 'Administrators'} do
38
- its('names') { should eq ['Administrators'] }
39
- its('gids') { should eq ['S-1-5-32-544'] }
40
- end
41
- "
42
-
43
- def initialize
44
- # select group manager
45
- @group_provider = select_group_manager(inspec.os)
46
- return skip_resource 'The `groups` resource is not supported on your OS yet.' if @group_provider.nil?
47
- end
48
-
49
- filter = FilterTable.create
50
- filter.add_accessor(:where)
51
- .add_accessor(:entries)
52
- .add(:names, field: 'name')
53
- .add(:gids, field: 'gid')
54
- .add(:domains, field: 'domain')
55
- .add(:exists?) { |x| !x.entries.empty? }
56
- filter.connect(self, :collect_group_details)
57
-
58
- def to_s
59
- 'Groups'
60
- end
61
-
62
- private
63
-
64
- # collects information about every group
65
- def collect_group_details
66
- return @groups_cache ||= @group_provider.groups unless @group_provider.nil?
67
- []
68
- end
69
- end
70
-
71
- # Usage:
72
- # describe group('root') do
73
- # it { should exist }
74
- # its('gid') { should eq 0 }
75
- # end
76
- #
77
- # deprecated has matcher
78
- # describe group('root') do
79
- # it { should have_gid 0 }
80
- # end
81
- class Group < Inspec.resource(1)
82
- include GroupManagementSelector
83
-
84
- name 'group'
85
- supports platform: 'unix'
86
- supports platform: 'windows'
87
- desc 'Use the group InSpec audit resource to test groups on the system.'
88
- example "
89
- describe group('root') do
90
- it { should exist }
91
- its('gid') { should eq 0 }
92
- end
93
- "
94
-
95
- def initialize(groupname)
96
- @group = groupname
97
-
98
- # select group manager
99
- @group_provider = select_group_manager(inspec.os)
100
- return skip_resource 'The `group` resource is not supported on your OS yet.' if @group_provider.nil?
101
- end
102
-
103
- # verifies if a group exists
104
- def exists?
105
- !group_info.entries.empty?
106
- end
107
-
108
- def gid
109
- gids = group_info.gids
110
- if gids.empty?
111
- nil
112
- # the default case should be one group
113
- elsif gids.size == 1
114
- gids.entries[0]
115
- else
116
- raise 'found more than one group with the same name, please use `groups` resource'
117
- end
118
- end
119
-
120
- # implements rspec has matcher, to be compatible with serverspec
121
- def has_gid?(compare_gid)
122
- gid == compare_gid
123
- end
124
-
125
- def local
126
- # at this point the implementation only returns local groups
127
- true
128
- end
129
-
130
- def to_s
131
- "Group #{@group}"
132
- end
133
-
134
- private
135
-
136
- def group_info
137
- # we need a local copy for the block
138
- group = @group.dup
139
- @groups_cache ||= inspec.groups.where { name == group }
140
- end
141
- end
142
-
143
- class GroupInfo
144
- attr_reader :inspec
145
- def initialize(inspec)
146
- @inspec = inspec
147
- end
148
-
149
- def groups
150
- raise 'group provider must implement the `groups` method'
151
- end
152
- end
153
-
154
- # implements generic unix groups via /etc/group
155
- class UnixGroup < GroupInfo
156
- def groups
157
- inspec.etc_group.entries
158
- end
159
- end
160
-
161
- # OSX uses opendirectory for groups, so `/etc/group` may not be fully accurate
162
- # This uses `dscacheutil` to get the group info instead of `etc_group`
163
- class DarwinGroup < GroupInfo
164
- def groups
165
- group_info = inspec.command('dscacheutil -q group').stdout.split("\n\n")
166
-
167
- groups = []
168
- regex = /^([^:]*?)\s*:\s(.*?)\s*$/
169
- group_info.each do |data|
170
- groups << inspec.parse_config(data, assignment_regex: regex).params
171
- end
172
-
173
- # Convert the `dscacheutil` groups to match `inspec.etc_group.entries`
174
- groups.each { |g| g['gid'] = g['gid'].to_i }
175
- groups.each do |g|
176
- next if g['users'].nil?
177
- g['members'] = g.delete('users')
178
- g['members'].tr!(' ', ',')
179
- end
180
- end
181
- end
182
-
183
- class WindowsGroup < GroupInfo
184
- # returns all local groups
185
- def groups
186
- script = <<~EOH
187
- Function ConvertTo-SID { Param([byte[]]$BinarySID)
188
- (New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value
189
- }
190
-
191
- $Computername = $Env:Computername
192
- $adsi = [ADSI]"WinNT://$Computername"
193
- $groups = $adsi.Children | where {$_.SchemaClassName -eq 'group'} | ForEach {
194
- $name = $_.Name[0]
195
- $sid = ConvertTo-SID -BinarySID $_.ObjectSID[0]
196
- $group =[ADSI]$_.Path
197
- new-object psobject -property @{name = $group.Name[0]; gid = $sid; domain=$Computername}
198
- }
199
- $groups | ConvertTo-Json -Depth 3
200
- EOH
201
- cmd = inspec.powershell(script)
202
- # cannot rely on exit code for now, successful command returns exit code 1
203
- # return nil if cmd.exit_status != 0, try to parse json
204
- begin
205
- groups = JSON.parse(cmd.stdout)
206
- rescue JSON::ParserError => _e
207
- return []
208
- end
209
-
210
- # ensure we have an array of groups
211
- groups = [groups] if !groups.is_a?(Array)
212
- groups
213
- end
214
- end
215
- end
1
+ # encoding: utf-8
2
+
3
+ require 'utils/filter'
4
+
5
+ module Inspec::Resources
6
+ # This file contains two resources, the `group` and `groups` resource.
7
+ # The `group` resource is optimized for requests that verify specific groups
8
+ # that you know upfront for testing. If you need to query all groups or search
9
+ # specific groups with certain properties, use the `groups` resource.
10
+ module GroupManagementSelector
11
+ # select group provider based on the operating system
12
+ # returns nil, if no group manager was found for the operating system
13
+ def select_group_manager(os)
14
+ @group_provider = if os.darwin?
15
+ DarwinGroup.new(inspec)
16
+ elsif os.unix?
17
+ UnixGroup.new(inspec)
18
+ elsif os.windows?
19
+ WindowsGroup.new(inspec)
20
+ end
21
+ end
22
+ end
23
+
24
+ class Groups < Inspec.resource(1)
25
+ include GroupManagementSelector
26
+
27
+ name 'groups'
28
+ supports platform: 'unix'
29
+ supports platform: 'windows'
30
+ desc 'Use the group InSpec audit resource to test groups on the system. Groups can be filtered.'
31
+ example "
32
+ describe groups.where { name == 'root'} do
33
+ its('names') { should eq ['root'] }
34
+ its('gids') { should eq [0] }
35
+ end
36
+
37
+ describe groups.where { name == 'Administrators'} do
38
+ its('names') { should eq ['Administrators'] }
39
+ its('gids') { should eq ['S-1-5-32-544'] }
40
+ end
41
+ "
42
+
43
+ def initialize
44
+ # select group manager
45
+ @group_provider = select_group_manager(inspec.os)
46
+ return skip_resource 'The `groups` resource is not supported on your OS yet.' if @group_provider.nil?
47
+ end
48
+
49
+ filter = FilterTable.create
50
+ filter.add_accessor(:where)
51
+ .add_accessor(:entries)
52
+ .add(:names, field: 'name')
53
+ .add(:gids, field: 'gid')
54
+ .add(:domains, field: 'domain')
55
+ .add(:exists?) { |x| !x.entries.empty? }
56
+ filter.connect(self, :collect_group_details)
57
+
58
+ def to_s
59
+ 'Groups'
60
+ end
61
+
62
+ private
63
+
64
+ # collects information about every group
65
+ def collect_group_details
66
+ return @groups_cache ||= @group_provider.groups unless @group_provider.nil?
67
+ []
68
+ end
69
+ end
70
+
71
+ # Usage:
72
+ # describe group('root') do
73
+ # it { should exist }
74
+ # its('gid') { should eq 0 }
75
+ # end
76
+ #
77
+ # deprecated has matcher
78
+ # describe group('root') do
79
+ # it { should have_gid 0 }
80
+ # end
81
+ class Group < Inspec.resource(1)
82
+ include GroupManagementSelector
83
+
84
+ name 'group'
85
+ supports platform: 'unix'
86
+ supports platform: 'windows'
87
+ desc 'Use the group InSpec audit resource to test groups on the system.'
88
+ example "
89
+ describe group('root') do
90
+ it { should exist }
91
+ its('gid') { should eq 0 }
92
+ end
93
+ "
94
+
95
+ def initialize(groupname)
96
+ @group = groupname
97
+
98
+ # select group manager
99
+ @group_provider = select_group_manager(inspec.os)
100
+ return skip_resource 'The `group` resource is not supported on your OS yet.' if @group_provider.nil?
101
+ end
102
+
103
+ # verifies if a group exists
104
+ def exists?
105
+ !group_info.entries.empty?
106
+ end
107
+
108
+ def gid
109
+ gids = group_info.gids
110
+ if gids.empty?
111
+ nil
112
+ # the default case should be one group
113
+ elsif gids.size == 1
114
+ gids.entries[0]
115
+ else
116
+ raise 'found more than one group with the same name, please use `groups` resource'
117
+ end
118
+ end
119
+
120
+ # implements rspec has matcher, to be compatible with serverspec
121
+ def has_gid?(compare_gid)
122
+ gid == compare_gid
123
+ end
124
+
125
+ def local
126
+ # at this point the implementation only returns local groups
127
+ true
128
+ end
129
+
130
+ def to_s
131
+ "Group #{@group}"
132
+ end
133
+
134
+ private
135
+
136
+ def group_info
137
+ # we need a local copy for the block
138
+ group = @group.dup
139
+ @groups_cache ||= inspec.groups.where { name == group }
140
+ end
141
+ end
142
+
143
+ class GroupInfo
144
+ attr_reader :inspec
145
+ def initialize(inspec)
146
+ @inspec = inspec
147
+ end
148
+
149
+ def groups
150
+ raise 'group provider must implement the `groups` method'
151
+ end
152
+ end
153
+
154
+ # implements generic unix groups via /etc/group
155
+ class UnixGroup < GroupInfo
156
+ def groups
157
+ inspec.etc_group.entries
158
+ end
159
+ end
160
+
161
+ # OSX uses opendirectory for groups, so `/etc/group` may not be fully accurate
162
+ # This uses `dscacheutil` to get the group info instead of `etc_group`
163
+ class DarwinGroup < GroupInfo
164
+ def groups
165
+ group_info = inspec.command('dscacheutil -q group').stdout.split("\n\n")
166
+
167
+ groups = []
168
+ regex = /^([^:]*?)\s*:\s(.*?)\s*$/
169
+ group_info.each do |data|
170
+ groups << inspec.parse_config(data, assignment_regex: regex).params
171
+ end
172
+
173
+ # Convert the `dscacheutil` groups to match `inspec.etc_group.entries`
174
+ groups.each { |g| g['gid'] = g['gid'].to_i }
175
+ groups.each do |g|
176
+ next if g['users'].nil?
177
+ g['members'] = g.delete('users')
178
+ g['members'].tr!(' ', ',')
179
+ end
180
+ end
181
+ end
182
+
183
+ class WindowsGroup < GroupInfo
184
+ # returns all local groups
185
+ def groups
186
+ script = <<~EOH
187
+ Function ConvertTo-SID { Param([byte[]]$BinarySID)
188
+ (New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value
189
+ }
190
+
191
+ $Computername = $Env:Computername
192
+ $adsi = [ADSI]"WinNT://$Computername"
193
+ $groups = $adsi.Children | where {$_.SchemaClassName -eq 'group'} | ForEach {
194
+ $name = $_.Name[0]
195
+ $sid = ConvertTo-SID -BinarySID $_.ObjectSID[0]
196
+ $group =[ADSI]$_.Path
197
+ new-object psobject -property @{name = $group.Name[0]; gid = $sid; domain=$Computername}
198
+ }
199
+ $groups | ConvertTo-Json -Depth 3
200
+ EOH
201
+ cmd = inspec.powershell(script)
202
+ # cannot rely on exit code for now, successful command returns exit code 1
203
+ # return nil if cmd.exit_status != 0, try to parse json
204
+ begin
205
+ groups = JSON.parse(cmd.stdout)
206
+ rescue JSON::ParserError => _e
207
+ return []
208
+ end
209
+
210
+ # ensure we have an array of groups
211
+ groups = [groups] if !groups.is_a?(Array)
212
+ groups
213
+ end
214
+ end
215
+ end
@@ -1,237 +1,227 @@
1
- # encoding: utf-8
2
-
3
- require 'utils/simpleconfig'
4
-
5
- class GrubConfig < Inspec.resource(1)
6
- name 'grub_conf'
7
- supports platform: 'unix'
8
- desc 'Use the grub_conf InSpec audit resource to test the boot config of Linux systems that use Grub.'
9
- example "
10
- describe grub_conf('/etc/grub.conf', 'default') do
11
- its('kernel') { should include '/vmlinuz-2.6.32-573.7.1.el6.x86_64' }
12
- its('initrd') { should include '/initramfs-2.6.32-573.el6.x86_64.img=1' }
13
- its('default') { should_not eq '1' }
14
- its('timeout') { should eq '5' }
15
- end
16
-
17
- also check specific kernels
18
- describe grub_conf('/etc/grub.conf', 'CentOS (2.6.32-573.12.1.el6.x86_64)') do
19
- its('kernel') { should include 'audit=1' }
20
- end
21
- "
22
-
23
- class UnknownGrubConfig < StandardError; end
24
-
25
- def initialize(path = nil, kernel = nil)
26
- config_for_platform(path)
27
- @kernel = kernel || 'default'
28
- rescue UnknownGrubConfig
29
- return skip_resource 'The `grub_config` resource is not supported on your OS yet.'
30
- end
31
-
32
- def config_for_platform(path)
33
- os = inspec.os
34
- if os.redhat? || os[:name] == 'fedora'
35
- config_for_redhatish(path)
36
- elsif os.debian?
37
- @conf_path = path || '/boot/grub/grub.cfg'
38
- @defaults_path = '/etc/default/grub'
39
- @grubenv_path = '/boot/grub2/grubenv'
40
- @version = 'grub2'
41
- elsif os[:name] == 'amazon'
42
- @conf_path = path || '/etc/grub.conf'
43
- @version = 'legacy'
44
- else
45
- raise UnknownGrubConfig
46
- end
47
- end
48
-
49
- def config_for_redhatish(path)
50
- if inspec.os[:release].to_f < 7
51
- @conf_path = path || '/etc/grub.conf'
52
- @version = 'legacy'
53
- else
54
- @conf_path = path || '/boot/grub2/grub.cfg'
55
- @defaults_path = '/etc/default/grub'
56
- @grubenv_path = '/boot/grub2/grubenv'
57
- @version = 'grub2'
58
- end
59
- end
60
-
61
- def method_missing(name)
62
- read_params[name.to_s]
63
- end
64
-
65
- def to_s
66
- 'Grub Config'
67
- end
68
-
69
- private
70
-
71
- ######################################################################
72
- # Grub2 This is used by all supported versions of Ubuntu and Rhel 7+ #
73
- ######################################################################
74
-
75
- def grub2_parse_kernel_lines(content, conf)
76
- menu_entries = extract_menu_entries(content)
77
-
78
- if @kernel == 'default'
79
- default_menu_entry(menu_entries, conf['GRUB_DEFAULT'])
80
- else
81
- menu_entries.find { |entry| entry['name'] == @kernel }
82
- end
83
- end
84
-
85
- def extract_menu_entries(content)
86
- menu_entries = []
87
-
88
- lines = content.split("\n")
89
- lines.each_with_index do |line, index|
90
- next unless line =~ /^menuentry\s+.*/
91
- entry = {}
92
- entry['insmod'] = []
93
-
94
- # Extract name from menuentry line
95
- capture_data = line.match(/(?:^|\s+).*menuentry\s*['|"](.*)['|"]\s*--/)
96
- if capture_data.nil? || capture_data.captures[0].nil?
97
- raise Inspec::Exceptions::ResourceFailed "Failed to extract menuentry name from #{line}"
98
- end
99
-
100
- entry['name'] = capture_data.captures[0]
101
-
102
- # Begin processing from index forward until a `}` line is met
103
- lines.drop(index+1).each do |mline|
104
- break if mline =~ /^\s*}\s*$/
105
- case mline
106
- when /(?:^|\s*)initrd.*/
107
- entry['initrd'] = mline.split(' ')[1]
108
- when /(?:^|\s*)linux.*/
109
- entry['kernel'] = mline.split
110
- when /(?:^|\s*)set root=.*/
111
- entry['root'] = mline.split('=')[1].tr('\'', '')
112
- when /(?:^|\s*)insmod.*/
113
- entry['insmod'] << mline.split(' ')[1]
114
- end
115
- end
116
-
117
- menu_entries << entry
118
- end
119
-
120
- menu_entries
121
- end
122
-
123
- def default_menu_entry(menu_entries, default)
124
- # If the default entry isn't `saved` then a number is used as an index.
125
- # By default this is `0`, which would be the first item in the list.
126
- return menu_entries[default.to_i] unless default == 'saved'
127
-
128
- grubenv_contents = inspec.file(@grubenv_path).content
129
-
130
- # The location of the grubenv file is not guaranteed. In the case that
131
- # the file does not exist this will return the 0th entry. This will also
132
- # return the 0th entry if InSpec lacks permission to read the file. Both
133
- # of these reflect the default Grub2 behavior.
134
- return menu_entries[0] if grubenv_contents.nil?
135
-
136
- default_name = SimpleConfig.new(grubenv_contents).params['saved_entry']
137
- default_entry = menu_entries.select { |k| k['name'] == default_name }[0]
138
- return default_entry unless default_entry.nil?
139
-
140
- # It is possible for the saved entry to not be valid . For example, grubenv
141
- # not being up to date. If so, the 0th entry is the default.
142
- menu_entries[0]
143
- end
144
-
145
- ###################################################################
146
- # Grub1 aka legacy-grub config. Primarily used by Centos/Rhel 6.x #
147
- ###################################################################
148
-
149
- def parse_kernel_lines(content, conf)
150
- # Find all "title" lines and then parse them into arrays
151
- menu_entry = 0
152
- lines = content.split("\n")
153
- kernel_opts = {}
154
- lines.each_with_index do |file_line, index|
155
- next unless file_line =~ /^title.*/
156
- current_kernel = file_line.split(' ', 2)[1]
157
- lines.drop(index+1).each do |kernel_line|
158
- if kernel_line =~ /^\s.*/
159
- option_type = kernel_line.split(' ')[0]
160
- line_options = kernel_line.split(' ').drop(1)
161
- if (menu_entry == conf['default'].to_i && @kernel == 'default') || current_kernel == @kernel
162
- if option_type == 'kernel'
163
- kernel_opts['kernel'] = line_options
164
- else
165
- kernel_opts[option_type] = line_options[0]
166
- end
167
- end
168
- else
169
- menu_entry += 1
170
- break
171
- end
172
- end
173
- end
174
- kernel_opts
175
- end
176
-
177
- def read_file(config_file)
178
- file = inspec.file(config_file)
179
-
180
- if !file.file? && !file.symlink?
181
- skip_resource "Can't find file '#{@conf_path}'"
182
- return @params = {}
183
- end
184
-
185
- content = file.content
186
-
187
- if content.empty? && !file.empty?
188
- skip_resource "Can't read file '#{@conf_path}'"
189
- return @params = {}
190
- end
191
-
192
- content
193
- end
194
-
195
- def read_params
196
- return @params if defined?(@params)
197
-
198
- content = read_file(@conf_path)
199
-
200
- if @version == 'legacy'
201
- # parse the file
202
- conf = SimpleConfig.new(
203
- content,
204
- multiple_values: true,
205
- ).params
206
- # convert single entry arrays into strings
207
- conf.each do |key, value|
208
- if value.size == 1
209
- conf[key] = conf[key][0].to_s
210
- end
211
- end
212
- kernel_opts = parse_kernel_lines(content, conf)
213
- @params = conf.merge(kernel_opts)
214
- end
215
-
216
- if @version == 'grub2'
217
- # read defaults
218
- defaults = read_file(@defaults_path)
219
-
220
- conf = SimpleConfig.new(
221
- defaults,
222
- multiple_values: true,
223
- ).params
224
-
225
- # convert single entry arrays into strings
226
- conf.each do |key, value|
227
- if value.size == 1
228
- conf[key] = conf[key][0].to_s
229
- end
230
- end
231
-
232
- kernel_opts = grub2_parse_kernel_lines(content, conf)
233
- @params = conf.merge(kernel_opts)
234
- end
235
- @params
236
- end
237
- end
1
+ # encoding: utf-8
2
+
3
+ require 'utils/simpleconfig'
4
+ require 'utils/file_reader'
5
+
6
+ class GrubConfig < Inspec.resource(1)
7
+ name 'grub_conf'
8
+ supports platform: 'unix'
9
+ desc 'Use the grub_conf InSpec audit resource to test the boot config of Linux systems that use Grub.'
10
+ example "
11
+ describe grub_conf('/etc/grub.conf', 'default') do
12
+ its('kernel') { should include '/vmlinuz-2.6.32-573.7.1.el6.x86_64' }
13
+ its('initrd') { should include '/initramfs-2.6.32-573.el6.x86_64.img=1' }
14
+ its('default') { should_not eq '1' }
15
+ its('timeout') { should eq '5' }
16
+ end
17
+
18
+ also check specific kernels
19
+ describe grub_conf('/etc/grub.conf', 'CentOS (2.6.32-573.12.1.el6.x86_64)') do
20
+ its('kernel') { should include 'audit=1' }
21
+ end
22
+ "
23
+
24
+ include FileReader
25
+
26
+ class UnknownGrubConfig < StandardError; end
27
+
28
+ def initialize(path = nil, kernel = nil)
29
+ config_for_platform(path)
30
+ @content = read_file(@conf_path)
31
+ @kernel = kernel || 'default'
32
+ rescue UnknownGrubConfig
33
+ return skip_resource 'The `grub_config` resource is not supported on your OS yet.'
34
+ end
35
+
36
+ def config_for_platform(path)
37
+ os = inspec.os
38
+ if os.redhat? || os[:name] == 'fedora'
39
+ config_for_redhatish(path)
40
+ elsif os.debian?
41
+ @conf_path = path || '/boot/grub/grub.cfg'
42
+ @defaults_path = '/etc/default/grub'
43
+ @grubenv_path = '/boot/grub2/grubenv'
44
+ @version = 'grub2'
45
+ elsif os[:name] == 'amazon'
46
+ @conf_path = path || '/etc/grub.conf'
47
+ @version = 'legacy'
48
+ else
49
+ raise UnknownGrubConfig
50
+ end
51
+ end
52
+
53
+ def config_for_redhatish(path)
54
+ if inspec.os[:release].to_f < 7
55
+ @conf_path = path || '/etc/grub.conf'
56
+ @version = 'legacy'
57
+ else
58
+ @conf_path = path || '/boot/grub2/grub.cfg'
59
+ @defaults_path = '/etc/default/grub'
60
+ @grubenv_path = '/boot/grub2/grubenv'
61
+ @version = 'grub2'
62
+ end
63
+ end
64
+
65
+ def method_missing(name)
66
+ read_params[name.to_s]
67
+ end
68
+
69
+ def to_s
70
+ 'Grub Config'
71
+ end
72
+
73
+ private
74
+
75
+ ######################################################################
76
+ # Grub2 This is used by all supported versions of Ubuntu and Rhel 7+ #
77
+ ######################################################################
78
+
79
+ def grub2_parse_kernel_lines(content, conf)
80
+ menu_entries = extract_menu_entries(content)
81
+
82
+ if @kernel == 'default'
83
+ default_menu_entry(menu_entries, conf['GRUB_DEFAULT'])
84
+ else
85
+ menu_entries.find { |entry| entry['name'] == @kernel }
86
+ end
87
+ end
88
+
89
+ def extract_menu_entries(content)
90
+ menu_entries = []
91
+
92
+ lines = content.split("\n")
93
+ lines.each_with_index do |line, index|
94
+ next unless line =~ /^menuentry\s+.*/
95
+ entry = {}
96
+ entry['insmod'] = []
97
+
98
+ # Extract name from menuentry line
99
+ capture_data = line.match(/(?:^|\s+).*menuentry\s*['|"](.*)['|"]\s*--/)
100
+ if capture_data.nil? || capture_data.captures[0].nil?
101
+ raise Inspec::Exceptions::ResourceFailed "Failed to extract menuentry name from #{line}"
102
+ end
103
+
104
+ entry['name'] = capture_data.captures[0]
105
+
106
+ # Begin processing from index forward until a `}` line is met
107
+ lines.drop(index+1).each do |mline|
108
+ break if mline =~ /^\s*}\s*$/
109
+ case mline
110
+ when /(?:^|\s*)initrd.*/
111
+ entry['initrd'] = mline.split(' ')[1]
112
+ when /(?:^|\s*)linux.*/
113
+ entry['kernel'] = mline.split
114
+ when /(?:^|\s*)set root=.*/
115
+ entry['root'] = mline.split('=')[1].tr('\'', '')
116
+ when /(?:^|\s*)insmod.*/
117
+ entry['insmod'] << mline.split(' ')[1]
118
+ end
119
+ end
120
+
121
+ menu_entries << entry
122
+ end
123
+
124
+ menu_entries
125
+ end
126
+
127
+ def default_menu_entry(menu_entries, default)
128
+ # If the default entry isn't `saved` then a number is used as an index.
129
+ # By default this is `0`, which would be the first item in the list.
130
+ return menu_entries[default.to_i] unless default == 'saved'
131
+
132
+ grubenv_contents = inspec.file(@grubenv_path).content
133
+
134
+ # The location of the grubenv file is not guaranteed. In the case that
135
+ # the file does not exist this will return the 0th entry. This will also
136
+ # return the 0th entry if InSpec lacks permission to read the file. Both
137
+ # of these reflect the default Grub2 behavior.
138
+ return menu_entries[0] if grubenv_contents.nil?
139
+
140
+ default_name = SimpleConfig.new(grubenv_contents).params['saved_entry']
141
+ default_entry = menu_entries.select { |k| k['name'] == default_name }[0]
142
+ return default_entry unless default_entry.nil?
143
+
144
+ # It is possible for the saved entry to not be valid . For example, grubenv
145
+ # not being up to date. If so, the 0th entry is the default.
146
+ menu_entries[0]
147
+ end
148
+
149
+ ###################################################################
150
+ # Grub1 aka legacy-grub config. Primarily used by Centos/Rhel 6.x #
151
+ ###################################################################
152
+
153
+ def parse_kernel_lines(content, conf)
154
+ # Find all "title" lines and then parse them into arrays
155
+ menu_entry = 0
156
+ lines = content.split("\n")
157
+ kernel_opts = {}
158
+ lines.each_with_index do |file_line, index|
159
+ next unless file_line =~ /^title.*/
160
+ current_kernel = file_line.split(' ', 2)[1]
161
+ lines.drop(index+1).each do |kernel_line|
162
+ if kernel_line =~ /^\s.*/
163
+ option_type = kernel_line.split(' ')[0]
164
+ line_options = kernel_line.split(' ').drop(1)
165
+ if (menu_entry == conf['default'].to_i && @kernel == 'default') || current_kernel == @kernel
166
+ if option_type == 'kernel'
167
+ kernel_opts['kernel'] = line_options
168
+ else
169
+ kernel_opts[option_type] = line_options[0]
170
+ end
171
+ end
172
+ else
173
+ menu_entry += 1
174
+ break
175
+ end
176
+ end
177
+ end
178
+ kernel_opts
179
+ end
180
+
181
+ def read_file(config_file)
182
+ read_file_content(config_file)
183
+ end
184
+
185
+ def read_params
186
+ return @params if defined?(@params)
187
+
188
+ content = read_file(@conf_path)
189
+
190
+ if @version == 'legacy'
191
+ # parse the file
192
+ conf = SimpleConfig.new(
193
+ content,
194
+ multiple_values: true,
195
+ ).params
196
+ # convert single entry arrays into strings
197
+ conf.each do |key, value|
198
+ if value.size == 1
199
+ conf[key] = conf[key][0].to_s
200
+ end
201
+ end
202
+ kernel_opts = parse_kernel_lines(content, conf)
203
+ @params = conf.merge(kernel_opts)
204
+ end
205
+
206
+ if @version == 'grub2'
207
+ # read defaults
208
+ defaults = read_file(@defaults_path)
209
+
210
+ conf = SimpleConfig.new(
211
+ defaults,
212
+ multiple_values: true,
213
+ ).params
214
+
215
+ # convert single entry arrays into strings
216
+ conf.each do |key, value|
217
+ if value.size == 1
218
+ conf[key] = conf[key][0].to_s
219
+ end
220
+ end
221
+
222
+ kernel_opts = grub2_parse_kernel_lines(content, conf)
223
+ @params = conf.merge(kernel_opts)
224
+ end
225
+ @params
226
+ end
227
+ end