inspec 2.1.21 → 2.1.30

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 (502) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +101 -101
  3. data/CHANGELOG.md +3062 -3045
  4. data/Gemfile +56 -56
  5. data/LICENSE +14 -14
  6. data/MAINTAINERS.md +33 -33
  7. data/MAINTAINERS.toml +52 -52
  8. data/README.md +447 -447
  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 -100
  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_delivery_channel.md +79 -79
  36. data/docs/resources/aws_config_recorder.md.erb +71 -71
  37. data/docs/resources/aws_ec2_instance.md.erb +106 -106
  38. data/docs/resources/aws_iam_access_key.md.erb +123 -123
  39. data/docs/resources/aws_iam_access_keys.md.erb +198 -198
  40. data/docs/resources/aws_iam_group.md.erb +46 -46
  41. data/docs/resources/aws_iam_groups.md.erb +43 -43
  42. data/docs/resources/aws_iam_password_policy.md.erb +76 -76
  43. data/docs/resources/aws_iam_policies.md.erb +82 -82
  44. data/docs/resources/aws_iam_policy.md.erb +144 -144
  45. data/docs/resources/aws_iam_role.md.erb +63 -63
  46. data/docs/resources/aws_iam_root_user.md.erb +70 -58
  47. data/docs/resources/aws_iam_user.md.erb +64 -64
  48. data/docs/resources/aws_iam_users.md.erb +89 -89
  49. data/docs/resources/aws_kms_key.md.erb +171 -171
  50. data/docs/resources/aws_kms_keys.md.erb +84 -84
  51. data/docs/resources/aws_rds_instance.md.erb +60 -60
  52. data/docs/resources/aws_route_table.md.erb +47 -47
  53. data/docs/resources/aws_route_tables.md.erb +49 -0
  54. data/docs/resources/aws_s3_bucket.md.erb +134 -134
  55. data/docs/resources/aws_s3_bucket_object.md.erb +83 -83
  56. data/docs/resources/aws_s3_buckets.md.erb +53 -0
  57. data/docs/resources/aws_security_group.md.erb +151 -151
  58. data/docs/resources/aws_security_groups.md.erb +91 -91
  59. data/docs/resources/aws_sns_subscription.md.erb +124 -124
  60. data/docs/resources/aws_sns_topic.md.erb +63 -63
  61. data/docs/resources/aws_sns_topics.md.erb +52 -52
  62. data/docs/resources/aws_subnet.md.erb +134 -134
  63. data/docs/resources/aws_subnets.md.erb +126 -126
  64. data/docs/resources/aws_vpc.md.erb +120 -120
  65. data/docs/resources/aws_vpcs.md.erb +48 -48
  66. data/docs/resources/azure_generic_resource.md.erb +171 -171
  67. data/docs/resources/azure_resource_group.md.erb +284 -284
  68. data/docs/resources/azure_virtual_machine.md.erb +347 -347
  69. data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -224
  70. data/docs/resources/bash.md.erb +75 -75
  71. data/docs/resources/bond.md.erb +90 -90
  72. data/docs/resources/bridge.md.erb +57 -57
  73. data/docs/resources/bsd_service.md.erb +67 -67
  74. data/docs/resources/chocolatey_package.md.erb +58 -0
  75. data/docs/resources/command.md.erb +138 -138
  76. data/docs/resources/cpan.md.erb +79 -79
  77. data/docs/resources/cran.md.erb +64 -64
  78. data/docs/resources/crontab.md.erb +89 -89
  79. data/docs/resources/csv.md.erb +54 -54
  80. data/docs/resources/dh_params.md.erb +205 -205
  81. data/docs/resources/directory.md.erb +30 -30
  82. data/docs/resources/docker.md.erb +219 -219
  83. data/docs/resources/docker_container.md.erb +103 -103
  84. data/docs/resources/docker_image.md.erb +94 -94
  85. data/docs/resources/docker_service.md.erb +114 -114
  86. data/docs/resources/elasticsearch.md.erb +242 -242
  87. data/docs/resources/etc_fstab.md.erb +125 -125
  88. data/docs/resources/etc_group.md.erb +75 -75
  89. data/docs/resources/etc_hosts.md.erb +78 -78
  90. data/docs/resources/etc_hosts_allow.md.erb +74 -74
  91. data/docs/resources/etc_hosts_deny.md.erb +74 -74
  92. data/docs/resources/file.md.erb +526 -526
  93. data/docs/resources/filesystem.md.erb +41 -41
  94. data/docs/resources/firewalld.md.erb +107 -107
  95. data/docs/resources/gem.md.erb +79 -79
  96. data/docs/resources/group.md.erb +61 -61
  97. data/docs/resources/grub_conf.md.erb +101 -101
  98. data/docs/resources/host.md.erb +86 -86
  99. data/docs/resources/http.md.erb +196 -196
  100. data/docs/resources/iis_app.md.erb +122 -122
  101. data/docs/resources/iis_site.md.erb +135 -135
  102. data/docs/resources/inetd_conf.md.erb +94 -94
  103. data/docs/resources/ini.md.erb +76 -76
  104. data/docs/resources/interface.md.erb +58 -58
  105. data/docs/resources/iptables.md.erb +64 -64
  106. data/docs/resources/json.md.erb +63 -63
  107. data/docs/resources/kernel_module.md.erb +120 -120
  108. data/docs/resources/kernel_parameter.md.erb +53 -53
  109. data/docs/resources/key_rsa.md.erb +85 -85
  110. data/docs/resources/launchd_service.md.erb +57 -57
  111. data/docs/resources/limits_conf.md.erb +75 -75
  112. data/docs/resources/login_defs.md.erb +71 -71
  113. data/docs/resources/mount.md.erb +69 -69
  114. data/docs/resources/mssql_session.md.erb +60 -60
  115. data/docs/resources/mysql_conf.md.erb +99 -99
  116. data/docs/resources/mysql_session.md.erb +74 -74
  117. data/docs/resources/nginx.md.erb +79 -79
  118. data/docs/resources/nginx_conf.md.erb +138 -138
  119. data/docs/resources/npm.md.erb +60 -60
  120. data/docs/resources/ntp_conf.md.erb +60 -60
  121. data/docs/resources/oneget.md.erb +53 -53
  122. data/docs/resources/oracledb_session.md.erb +52 -52
  123. data/docs/resources/os.md.erb +141 -141
  124. data/docs/resources/os_env.md.erb +78 -78
  125. data/docs/resources/package.md.erb +120 -120
  126. data/docs/resources/packages.md.erb +67 -67
  127. data/docs/resources/parse_config.md.erb +103 -103
  128. data/docs/resources/parse_config_file.md.erb +138 -138
  129. data/docs/resources/passwd.md.erb +141 -141
  130. data/docs/resources/pip.md.erb +67 -67
  131. data/docs/resources/port.md.erb +137 -137
  132. data/docs/resources/postgres_conf.md.erb +79 -79
  133. data/docs/resources/postgres_hba_conf.md.erb +93 -93
  134. data/docs/resources/postgres_ident_conf.md.erb +76 -76
  135. data/docs/resources/postgres_session.md.erb +69 -69
  136. data/docs/resources/powershell.md.erb +102 -102
  137. data/docs/resources/processes.md.erb +109 -109
  138. data/docs/resources/rabbitmq_config.md.erb +41 -41
  139. data/docs/resources/registry_key.md.erb +158 -158
  140. data/docs/resources/runit_service.md.erb +57 -57
  141. data/docs/resources/security_policy.md.erb +47 -47
  142. data/docs/resources/service.md.erb +121 -121
  143. data/docs/resources/shadow.md.erb +146 -146
  144. data/docs/resources/ssh_config.md.erb +73 -73
  145. data/docs/resources/sshd_config.md.erb +83 -83
  146. data/docs/resources/ssl.md.erb +119 -119
  147. data/docs/resources/sys_info.md.erb +42 -42
  148. data/docs/resources/systemd_service.md.erb +57 -57
  149. data/docs/resources/sysv_service.md.erb +57 -57
  150. data/docs/resources/upstart_service.md.erb +57 -57
  151. data/docs/resources/user.md.erb +140 -140
  152. data/docs/resources/users.md.erb +127 -127
  153. data/docs/resources/vbscript.md.erb +55 -55
  154. data/docs/resources/virtualization.md.erb +57 -57
  155. data/docs/resources/windows_feature.md.erb +47 -47
  156. data/docs/resources/windows_hotfix.md.erb +53 -53
  157. data/docs/resources/windows_task.md.erb +95 -95
  158. data/docs/resources/wmi.md.erb +81 -81
  159. data/docs/resources/x509_certificate.md.erb +151 -151
  160. data/docs/resources/xinetd_conf.md.erb +156 -156
  161. data/docs/resources/xml.md.erb +85 -85
  162. data/docs/resources/yaml.md.erb +69 -69
  163. data/docs/resources/yum.md.erb +98 -98
  164. data/docs/resources/zfs_dataset.md.erb +53 -53
  165. data/docs/resources/zfs_pool.md.erb +47 -47
  166. data/docs/ruby_usage.md +203 -203
  167. data/docs/shared/matcher_be.md.erb +1 -1
  168. data/docs/shared/matcher_cmp.md.erb +43 -43
  169. data/docs/shared/matcher_eq.md.erb +3 -3
  170. data/docs/shared/matcher_include.md.erb +1 -1
  171. data/docs/shared/matcher_match.md.erb +1 -1
  172. data/docs/shell.md +217 -217
  173. data/examples/README.md +8 -8
  174. data/examples/inheritance/README.md +65 -65
  175. data/examples/inheritance/controls/example.rb +14 -14
  176. data/examples/inheritance/inspec.yml +15 -15
  177. data/examples/kitchen-ansible/.kitchen.yml +25 -25
  178. data/examples/kitchen-ansible/Gemfile +19 -19
  179. data/examples/kitchen-ansible/README.md +53 -53
  180. data/examples/kitchen-ansible/files/nginx.repo +6 -6
  181. data/examples/kitchen-ansible/tasks/main.yml +16 -16
  182. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
  183. data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
  184. data/examples/kitchen-chef/.kitchen.yml +20 -20
  185. data/examples/kitchen-chef/Berksfile +3 -3
  186. data/examples/kitchen-chef/Gemfile +19 -19
  187. data/examples/kitchen-chef/README.md +27 -27
  188. data/examples/kitchen-chef/metadata.rb +7 -7
  189. data/examples/kitchen-chef/recipes/default.rb +6 -6
  190. data/examples/kitchen-chef/recipes/nginx.rb +30 -30
  191. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
  192. data/examples/kitchen-puppet/.kitchen.yml +22 -22
  193. data/examples/kitchen-puppet/Gemfile +20 -20
  194. data/examples/kitchen-puppet/Puppetfile +25 -25
  195. data/examples/kitchen-puppet/README.md +53 -53
  196. data/examples/kitchen-puppet/manifests/site.pp +33 -33
  197. data/examples/kitchen-puppet/metadata.json +11 -11
  198. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
  199. data/examples/meta-profile/README.md +37 -37
  200. data/examples/meta-profile/controls/example.rb +13 -13
  201. data/examples/meta-profile/inspec.yml +13 -13
  202. data/examples/profile-attribute.yml +2 -2
  203. data/examples/profile-attribute/README.md +14 -14
  204. data/examples/profile-attribute/controls/example.rb +11 -11
  205. data/examples/profile-attribute/inspec.yml +8 -8
  206. data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
  207. data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
  208. data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
  209. data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
  210. data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
  211. data/examples/profile-aws/inspec.yml +11 -11
  212. data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
  213. data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
  214. data/examples/profile-azure/inspec.yml +11 -11
  215. data/examples/profile-sensitive/README.md +29 -29
  216. data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
  217. data/examples/profile-sensitive/controls/sensitive.rb +9 -9
  218. data/examples/profile-sensitive/inspec.yml +8 -8
  219. data/examples/profile/README.md +48 -48
  220. data/examples/profile/controls/example.rb +23 -23
  221. data/examples/profile/controls/gordon.rb +36 -36
  222. data/examples/profile/controls/meta.rb +34 -34
  223. data/examples/profile/inspec.yml +10 -10
  224. data/examples/profile/libraries/gordon_config.rb +59 -53
  225. data/inspec.gemspec +47 -47
  226. data/lib/bundles/README.md +3 -3
  227. data/lib/bundles/inspec-artifact.rb +7 -7
  228. data/lib/bundles/inspec-artifact/README.md +1 -1
  229. data/lib/bundles/inspec-artifact/cli.rb +277 -277
  230. data/lib/bundles/inspec-compliance.rb +16 -16
  231. data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
  232. data/lib/bundles/inspec-compliance/README.md +185 -185
  233. data/lib/bundles/inspec-compliance/api.rb +316 -316
  234. data/lib/bundles/inspec-compliance/api/login.rb +152 -152
  235. data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
  236. data/lib/bundles/inspec-compliance/cli.rb +254 -254
  237. data/lib/bundles/inspec-compliance/configuration.rb +103 -103
  238. data/lib/bundles/inspec-compliance/http.rb +86 -86
  239. data/lib/bundles/inspec-compliance/support.rb +36 -36
  240. data/lib/bundles/inspec-compliance/target.rb +98 -98
  241. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
  242. data/lib/bundles/inspec-habitat.rb +12 -12
  243. data/lib/bundles/inspec-habitat/cli.rb +36 -36
  244. data/lib/bundles/inspec-habitat/log.rb +10 -10
  245. data/lib/bundles/inspec-habitat/profile.rb +391 -391
  246. data/lib/bundles/inspec-init.rb +8 -8
  247. data/lib/bundles/inspec-init/README.md +31 -31
  248. data/lib/bundles/inspec-init/cli.rb +97 -97
  249. data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
  250. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
  251. data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
  252. data/lib/bundles/inspec-supermarket.rb +13 -13
  253. data/lib/bundles/inspec-supermarket/README.md +45 -45
  254. data/lib/bundles/inspec-supermarket/api.rb +84 -84
  255. data/lib/bundles/inspec-supermarket/cli.rb +73 -73
  256. data/lib/bundles/inspec-supermarket/target.rb +34 -34
  257. data/lib/fetchers/git.rb +163 -163
  258. data/lib/fetchers/local.rb +74 -74
  259. data/lib/fetchers/mock.rb +35 -35
  260. data/lib/fetchers/url.rb +204 -204
  261. data/lib/inspec.rb +24 -24
  262. data/lib/inspec/archive/tar.rb +29 -29
  263. data/lib/inspec/archive/zip.rb +19 -19
  264. data/lib/inspec/backend.rb +93 -93
  265. data/lib/inspec/base_cli.rb +363 -357
  266. data/lib/inspec/cached_fetcher.rb +66 -66
  267. data/lib/inspec/cli.rb +292 -292
  268. data/lib/inspec/completions/bash.sh.erb +45 -45
  269. data/lib/inspec/completions/fish.sh.erb +34 -34
  270. data/lib/inspec/completions/zsh.sh.erb +61 -61
  271. data/lib/inspec/control_eval_context.rb +179 -179
  272. data/lib/inspec/dependencies/cache.rb +72 -72
  273. data/lib/inspec/dependencies/dependency_set.rb +92 -92
  274. data/lib/inspec/dependencies/lockfile.rb +115 -115
  275. data/lib/inspec/dependencies/requirement.rb +123 -123
  276. data/lib/inspec/dependencies/resolver.rb +86 -86
  277. data/lib/inspec/describe.rb +27 -27
  278. data/lib/inspec/dsl.rb +66 -66
  279. data/lib/inspec/dsl_shared.rb +33 -33
  280. data/lib/inspec/env_printer.rb +157 -157
  281. data/lib/inspec/errors.rb +14 -13
  282. data/lib/inspec/exceptions.rb +12 -12
  283. data/lib/inspec/expect.rb +45 -45
  284. data/lib/inspec/fetcher.rb +45 -45
  285. data/lib/inspec/file_provider.rb +275 -275
  286. data/lib/inspec/formatters.rb +3 -3
  287. data/lib/inspec/formatters/base.rb +259 -250
  288. data/lib/inspec/formatters/json_rspec.rb +20 -20
  289. data/lib/inspec/formatters/show_progress.rb +12 -12
  290. data/lib/inspec/library_eval_context.rb +58 -58
  291. data/lib/inspec/log.rb +11 -11
  292. data/lib/inspec/metadata.rb +247 -247
  293. data/lib/inspec/method_source.rb +24 -24
  294. data/lib/inspec/objects.rb +14 -14
  295. data/lib/inspec/objects/attribute.rb +65 -65
  296. data/lib/inspec/objects/control.rb +61 -61
  297. data/lib/inspec/objects/describe.rb +92 -92
  298. data/lib/inspec/objects/each_loop.rb +36 -36
  299. data/lib/inspec/objects/list.rb +15 -15
  300. data/lib/inspec/objects/or_test.rb +40 -40
  301. data/lib/inspec/objects/ruby_helper.rb +15 -15
  302. data/lib/inspec/objects/tag.rb +27 -27
  303. data/lib/inspec/objects/test.rb +87 -87
  304. data/lib/inspec/objects/value.rb +27 -27
  305. data/lib/inspec/plugins.rb +60 -60
  306. data/lib/inspec/plugins/cli.rb +24 -24
  307. data/lib/inspec/plugins/fetcher.rb +86 -86
  308. data/lib/inspec/plugins/resource.rb +135 -135
  309. data/lib/inspec/plugins/secret.rb +15 -15
  310. data/lib/inspec/plugins/source_reader.rb +40 -40
  311. data/lib/inspec/polyfill.rb +12 -12
  312. data/lib/inspec/profile.rb +513 -513
  313. data/lib/inspec/profile_context.rb +208 -208
  314. data/lib/inspec/profile_vendor.rb +66 -66
  315. data/lib/inspec/reporters.rb +60 -54
  316. data/lib/inspec/reporters/automate.rb +76 -0
  317. data/lib/inspec/reporters/base.rb +25 -24
  318. data/lib/inspec/reporters/cli.rb +356 -356
  319. data/lib/inspec/reporters/json.rb +116 -116
  320. data/lib/inspec/reporters/json_min.rb +48 -48
  321. data/lib/inspec/reporters/junit.rb +77 -77
  322. data/lib/inspec/require_loader.rb +33 -33
  323. data/lib/inspec/resource.rb +187 -186
  324. data/lib/inspec/rule.rb +266 -266
  325. data/lib/inspec/runner.rb +345 -345
  326. data/lib/inspec/runner_mock.rb +41 -41
  327. data/lib/inspec/runner_rspec.rb +175 -175
  328. data/lib/inspec/runtime_profile.rb +26 -26
  329. data/lib/inspec/schema.rb +213 -213
  330. data/lib/inspec/secrets.rb +19 -19
  331. data/lib/inspec/secrets/yaml.rb +30 -30
  332. data/lib/inspec/shell.rb +220 -220
  333. data/lib/inspec/shell_detector.rb +90 -90
  334. data/lib/inspec/source_reader.rb +29 -29
  335. data/lib/inspec/version.rb +8 -8
  336. data/lib/matchers/matchers.rb +339 -339
  337. data/lib/resource_support/aws.rb +49 -47
  338. data/lib/resource_support/aws/aws_backend_base.rb +12 -12
  339. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
  340. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
  341. data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
  342. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
  343. data/lib/resources/aide_conf.rb +151 -151
  344. data/lib/resources/apache.rb +48 -48
  345. data/lib/resources/apache_conf.rb +149 -149
  346. data/lib/resources/apt.rb +149 -149
  347. data/lib/resources/audit_policy.rb +63 -63
  348. data/lib/resources/auditd.rb +231 -231
  349. data/lib/resources/auditd_conf.rb +46 -46
  350. data/lib/resources/aws/aws_cloudtrail_trail.rb +77 -77
  351. data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
  352. data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
  353. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
  354. data/lib/resources/aws/aws_config_delivery_channel.rb +76 -76
  355. data/lib/resources/aws/aws_config_recorder.rb +98 -98
  356. data/lib/resources/aws/aws_ec2_instance.rb +157 -157
  357. data/lib/resources/aws/aws_iam_access_key.rb +106 -106
  358. data/lib/resources/aws/aws_iam_access_keys.rb +149 -149
  359. data/lib/resources/aws/aws_iam_group.rb +56 -56
  360. data/lib/resources/aws/aws_iam_groups.rb +52 -52
  361. data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
  362. data/lib/resources/aws/aws_iam_policies.rb +53 -53
  363. data/lib/resources/aws/aws_iam_policy.rb +125 -125
  364. data/lib/resources/aws/aws_iam_role.rb +51 -51
  365. data/lib/resources/aws/aws_iam_root_user.rb +78 -60
  366. data/lib/resources/aws/aws_iam_user.rb +111 -111
  367. data/lib/resources/aws/aws_iam_users.rb +108 -108
  368. data/lib/resources/aws/aws_kms_key.rb +96 -96
  369. data/lib/resources/aws/aws_kms_keys.rb +53 -53
  370. data/lib/resources/aws/aws_rds_instance.rb +71 -71
  371. data/lib/resources/aws/aws_route_table.rb +63 -63
  372. data/lib/resources/aws/aws_route_tables.rb +60 -0
  373. data/lib/resources/aws/aws_s3_bucket.rb +115 -115
  374. data/lib/resources/aws/aws_s3_bucket_object.rb +82 -82
  375. data/lib/resources/aws/aws_s3_buckets.rb +51 -0
  376. data/lib/resources/aws/aws_security_group.rb +93 -93
  377. data/lib/resources/aws/aws_security_groups.rb +68 -68
  378. data/lib/resources/aws/aws_sns_subscription.rb +78 -78
  379. data/lib/resources/aws/aws_sns_topic.rb +53 -53
  380. data/lib/resources/aws/aws_sns_topics.rb +56 -56
  381. data/lib/resources/aws/aws_subnet.rb +88 -88
  382. data/lib/resources/aws/aws_subnets.rb +53 -53
  383. data/lib/resources/aws/aws_vpc.rb +69 -69
  384. data/lib/resources/aws/aws_vpcs.rb +45 -45
  385. data/lib/resources/azure/azure_backend.rb +377 -377
  386. data/lib/resources/azure/azure_generic_resource.rb +59 -59
  387. data/lib/resources/azure/azure_resource_group.rb +152 -152
  388. data/lib/resources/azure/azure_virtual_machine.rb +264 -264
  389. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +134 -134
  390. data/lib/resources/bash.rb +35 -35
  391. data/lib/resources/bond.rb +69 -69
  392. data/lib/resources/bridge.rb +122 -122
  393. data/lib/resources/chocolatey_package.rb +78 -0
  394. data/lib/resources/command.rb +73 -73
  395. data/lib/resources/cpan.rb +58 -58
  396. data/lib/resources/cran.rb +64 -64
  397. data/lib/resources/crontab.rb +169 -169
  398. data/lib/resources/csv.rb +56 -56
  399. data/lib/resources/dh_params.rb +77 -77
  400. data/lib/resources/directory.rb +25 -25
  401. data/lib/resources/docker.rb +236 -236
  402. data/lib/resources/docker_container.rb +89 -89
  403. data/lib/resources/docker_image.rb +83 -83
  404. data/lib/resources/docker_object.rb +57 -57
  405. data/lib/resources/docker_service.rb +90 -90
  406. data/lib/resources/elasticsearch.rb +169 -169
  407. data/lib/resources/etc_fstab.rb +94 -94
  408. data/lib/resources/etc_group.rb +152 -152
  409. data/lib/resources/etc_hosts.rb +66 -66
  410. data/lib/resources/etc_hosts_allow_deny.rb +112 -112
  411. data/lib/resources/file.rb +298 -298
  412. data/lib/resources/filesystem.rb +31 -31
  413. data/lib/resources/firewalld.rb +143 -143
  414. data/lib/resources/gem.rb +70 -70
  415. data/lib/resources/groups.rb +215 -215
  416. data/lib/resources/grub_conf.rb +227 -227
  417. data/lib/resources/host.rb +306 -306
  418. data/lib/resources/http.rb +253 -253
  419. data/lib/resources/iis_app.rb +101 -101
  420. data/lib/resources/iis_site.rb +148 -148
  421. data/lib/resources/inetd_conf.rb +54 -54
  422. data/lib/resources/ini.rb +29 -29
  423. data/lib/resources/interface.rb +129 -129
  424. data/lib/resources/iptables.rb +80 -80
  425. data/lib/resources/json.rb +107 -107
  426. data/lib/resources/kernel_module.rb +107 -107
  427. data/lib/resources/kernel_parameter.rb +58 -58
  428. data/lib/resources/key_rsa.rb +61 -61
  429. data/lib/resources/limits_conf.rb +46 -46
  430. data/lib/resources/login_def.rb +57 -57
  431. data/lib/resources/mount.rb +88 -88
  432. data/lib/resources/mssql_session.rb +101 -101
  433. data/lib/resources/mysql.rb +82 -81
  434. data/lib/resources/mysql_conf.rb +127 -127
  435. data/lib/resources/mysql_session.rb +85 -85
  436. data/lib/resources/nginx.rb +96 -96
  437. data/lib/resources/nginx_conf.rb +226 -226
  438. data/lib/resources/npm.rb +48 -48
  439. data/lib/resources/ntp_conf.rb +51 -51
  440. data/lib/resources/oneget.rb +71 -71
  441. data/lib/resources/oracledb_session.rb +139 -139
  442. data/lib/resources/os.rb +36 -36
  443. data/lib/resources/os_env.rb +75 -75
  444. data/lib/resources/package.rb +370 -370
  445. data/lib/resources/packages.rb +111 -111
  446. data/lib/resources/parse_config.rb +112 -112
  447. data/lib/resources/passwd.rb +76 -76
  448. data/lib/resources/pip.rb +130 -130
  449. data/lib/resources/platform.rb +109 -109
  450. data/lib/resources/port.rb +771 -771
  451. data/lib/resources/postgres.rb +131 -130
  452. data/lib/resources/postgres_conf.rb +114 -114
  453. data/lib/resources/postgres_hba_conf.rb +90 -90
  454. data/lib/resources/postgres_ident_conf.rb +79 -79
  455. data/lib/resources/postgres_session.rb +71 -71
  456. data/lib/resources/powershell.rb +66 -66
  457. data/lib/resources/processes.rb +204 -204
  458. data/lib/resources/rabbitmq_conf.rb +51 -51
  459. data/lib/resources/registry_key.rb +297 -297
  460. data/lib/resources/security_policy.rb +180 -180
  461. data/lib/resources/service.rb +794 -790
  462. data/lib/resources/shadow.rb +149 -149
  463. data/lib/resources/ssh_conf.rb +97 -97
  464. data/lib/resources/ssl.rb +99 -99
  465. data/lib/resources/sys_info.rb +28 -28
  466. data/lib/resources/toml.rb +32 -32
  467. data/lib/resources/users.rb +654 -654
  468. data/lib/resources/vbscript.rb +68 -68
  469. data/lib/resources/virtualization.rb +247 -247
  470. data/lib/resources/windows_feature.rb +84 -84
  471. data/lib/resources/windows_hotfix.rb +35 -35
  472. data/lib/resources/windows_task.rb +102 -102
  473. data/lib/resources/wmi.rb +110 -110
  474. data/lib/resources/x509_certificate.rb +137 -137
  475. data/lib/resources/xinetd.rb +106 -106
  476. data/lib/resources/xml.rb +46 -46
  477. data/lib/resources/yaml.rb +43 -43
  478. data/lib/resources/yum.rb +180 -180
  479. data/lib/resources/zfs_dataset.rb +60 -60
  480. data/lib/resources/zfs_pool.rb +49 -49
  481. data/lib/source_readers/flat.rb +39 -39
  482. data/lib/source_readers/inspec.rb +75 -75
  483. data/lib/utils/command_wrapper.rb +27 -27
  484. data/lib/utils/convert.rb +12 -12
  485. data/lib/utils/database_helpers.rb +77 -77
  486. data/lib/utils/erlang_parser.rb +192 -192
  487. data/lib/utils/file_reader.rb +25 -25
  488. data/lib/utils/filter.rb +273 -273
  489. data/lib/utils/filter_array.rb +27 -27
  490. data/lib/utils/find_files.rb +44 -44
  491. data/lib/utils/hash.rb +41 -41
  492. data/lib/utils/json_log.rb +18 -18
  493. data/lib/utils/latest_version.rb +22 -22
  494. data/lib/utils/modulator.rb +12 -12
  495. data/lib/utils/nginx_parser.rb +85 -85
  496. data/lib/utils/object_traversal.rb +49 -49
  497. data/lib/utils/parser.rb +274 -274
  498. data/lib/utils/plugin_registry.rb +93 -93
  499. data/lib/utils/simpleconfig.rb +120 -120
  500. data/lib/utils/spdx.rb +13 -13
  501. data/lib/utils/spdx.txt +343 -343
  502. metadata +9 -2
@@ -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,227 +1,227 @@
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
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