inspec 2.0.16 → 2.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (480) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +101 -101
  3. data/CHANGELOG.md +2949 -2944
  4. data/Gemfile +55 -55
  5. data/LICENSE +14 -14
  6. data/MAINTAINERS.md +31 -31
  7. data/MAINTAINERS.toml +47 -47
  8. data/README.md +438 -438
  9. data/Rakefile +284 -284
  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 +93 -93
  15. data/docs/glossary.md +99 -99
  16. data/docs/habitat.md +191 -191
  17. data/docs/inspec_and_friends.md +107 -107
  18. data/docs/matchers.md +165 -165
  19. data/docs/migration.md +293 -293
  20. data/docs/platforms.md +118 -118
  21. data/docs/plugin_kitchen_inspec.md +49 -49
  22. data/docs/profiles.md +370 -370
  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_ec2_instance.md.erb +106 -106
  36. data/docs/resources/aws_iam_access_key.md.erb +123 -123
  37. data/docs/resources/aws_iam_access_keys.md.erb +198 -198
  38. data/docs/resources/aws_iam_group.md.erb +46 -46
  39. data/docs/resources/aws_iam_groups.md.erb +43 -43
  40. data/docs/resources/aws_iam_password_policy.md.erb +76 -76
  41. data/docs/resources/aws_iam_policies.md.erb +82 -82
  42. data/docs/resources/aws_iam_policy.md.erb +146 -146
  43. data/docs/resources/aws_iam_role.md.erb +65 -65
  44. data/docs/resources/aws_iam_root_user.md.erb +58 -58
  45. data/docs/resources/aws_iam_user.md.erb +64 -64
  46. data/docs/resources/aws_iam_users.md.erb +89 -89
  47. data/docs/resources/aws_kms_keys.md.erb +84 -84
  48. data/docs/resources/aws_route_table.md.erb +47 -47
  49. data/docs/resources/aws_s3_bucket.md.erb +134 -134
  50. data/docs/resources/aws_security_group.md.erb +152 -152
  51. data/docs/resources/aws_security_groups.md.erb +92 -92
  52. data/docs/resources/aws_sns_topic.md.erb +62 -62
  53. data/docs/resources/aws_subnet.md.erb +133 -133
  54. data/docs/resources/aws_subnets.md.erb +126 -126
  55. data/docs/resources/aws_vpc.md.erb +120 -120
  56. data/docs/resources/aws_vpcs.md.erb +48 -48
  57. data/docs/resources/azure_generic_resource.md.erb +170 -139
  58. data/docs/resources/azure_resource_group.md.erb +284 -284
  59. data/docs/resources/azure_virtual_machine.md.erb +347 -314
  60. data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -182
  61. data/docs/resources/bash.md.erb +75 -75
  62. data/docs/resources/bond.md.erb +90 -90
  63. data/docs/resources/bridge.md.erb +57 -57
  64. data/docs/resources/bsd_service.md.erb +67 -67
  65. data/docs/resources/command.md.erb +138 -138
  66. data/docs/resources/cpan.md.erb +79 -79
  67. data/docs/resources/cran.md.erb +64 -64
  68. data/docs/resources/crontab.md.erb +88 -88
  69. data/docs/resources/csv.md.erb +54 -54
  70. data/docs/resources/dh_params.md.erb +217 -217
  71. data/docs/resources/directory.md.erb +30 -30
  72. data/docs/resources/docker.md.erb +164 -164
  73. data/docs/resources/docker_container.md.erb +104 -104
  74. data/docs/resources/docker_image.md.erb +94 -94
  75. data/docs/resources/docker_service.md.erb +114 -114
  76. data/docs/resources/elasticsearch.md.erb +242 -242
  77. data/docs/resources/etc_fstab.md.erb +125 -125
  78. data/docs/resources/etc_group.md.erb +75 -75
  79. data/docs/resources/etc_hosts.md.erb +78 -78
  80. data/docs/resources/etc_hosts_allow.md.erb +74 -74
  81. data/docs/resources/etc_hosts_deny.md.erb +74 -74
  82. data/docs/resources/file.md.erb +515 -515
  83. data/docs/resources/filesystem.md.erb +41 -41
  84. data/docs/resources/firewalld.md.erb +107 -107
  85. data/docs/resources/gem.md.erb +79 -79
  86. data/docs/resources/group.md.erb +61 -61
  87. data/docs/resources/grub_conf.md.erb +101 -101
  88. data/docs/resources/host.md.erb +78 -78
  89. data/docs/resources/http.md.erb +101 -101
  90. data/docs/resources/iis_app.md.erb +122 -122
  91. data/docs/resources/iis_site.md.erb +135 -135
  92. data/docs/resources/inetd_conf.md.erb +94 -94
  93. data/docs/resources/ini.md.erb +76 -76
  94. data/docs/resources/interface.md.erb +58 -58
  95. data/docs/resources/iptables.md.erb +64 -64
  96. data/docs/resources/json.md.erb +62 -62
  97. data/docs/resources/kernel_module.md.erb +107 -107
  98. data/docs/resources/kernel_parameter.md.erb +53 -53
  99. data/docs/resources/key_rsa.md.erb +85 -85
  100. data/docs/resources/launchd_service.md.erb +57 -57
  101. data/docs/resources/limits_conf.md.erb +75 -75
  102. data/docs/resources/login_def.md.erb +71 -71
  103. data/docs/resources/mount.md.erb +69 -69
  104. data/docs/resources/mssql_session.md.erb +60 -60
  105. data/docs/resources/mysql_conf.md.erb +99 -99
  106. data/docs/resources/mysql_session.md.erb +74 -74
  107. data/docs/resources/nginx.md.erb +79 -79
  108. data/docs/resources/nginx_conf.md.erb +128 -128
  109. data/docs/resources/npm.md.erb +60 -60
  110. data/docs/resources/ntp_conf.md.erb +60 -60
  111. data/docs/resources/oneget.md.erb +53 -53
  112. data/docs/resources/oracledb_session.md.erb +52 -52
  113. data/docs/resources/os.md.erb +141 -141
  114. data/docs/resources/os_env.md.erb +78 -78
  115. data/docs/resources/package.md.erb +120 -120
  116. data/docs/resources/packages.md.erb +67 -67
  117. data/docs/resources/parse_config.md.erb +103 -103
  118. data/docs/resources/parse_config_file.md.erb +138 -138
  119. data/docs/resources/passwd.md.erb +141 -141
  120. data/docs/resources/pip.md.erb +67 -67
  121. data/docs/resources/port.md.erb +137 -137
  122. data/docs/resources/postgres_conf.md.erb +79 -79
  123. data/docs/resources/postgres_hba_conf.md.erb +93 -93
  124. data/docs/resources/postgres_ident_conf.md.erb +76 -76
  125. data/docs/resources/postgres_session.md.erb +69 -69
  126. data/docs/resources/powershell.md.erb +102 -102
  127. data/docs/resources/processes.md.erb +109 -109
  128. data/docs/resources/rabbitmq_config.md.erb +41 -41
  129. data/docs/resources/registry_key.md.erb +158 -158
  130. data/docs/resources/runit_service.md.erb +57 -57
  131. data/docs/resources/security_policy.md.erb +47 -47
  132. data/docs/resources/service.md.erb +121 -121
  133. data/docs/resources/shadow.md.erb +144 -144
  134. data/docs/resources/ssh_config.md.erb +80 -80
  135. data/docs/resources/sshd_config.md.erb +83 -83
  136. data/docs/resources/ssl.md.erb +119 -119
  137. data/docs/resources/sys_info.md.erb +42 -42
  138. data/docs/resources/systemd_service.md.erb +57 -57
  139. data/docs/resources/sysv_service.md.erb +57 -57
  140. data/docs/resources/upstart_service.md.erb +57 -57
  141. data/docs/resources/user.md.erb +140 -140
  142. data/docs/resources/users.md.erb +127 -127
  143. data/docs/resources/vbscript.md.erb +55 -55
  144. data/docs/resources/virtualization.md.erb +57 -57
  145. data/docs/resources/windows_feature.md.erb +47 -47
  146. data/docs/resources/windows_hotfix.md.erb +53 -53
  147. data/docs/resources/windows_task.md.erb +95 -95
  148. data/docs/resources/wmi.md.erb +81 -81
  149. data/docs/resources/x509_certificate.md.erb +151 -151
  150. data/docs/resources/xinetd_conf.md.erb +156 -156
  151. data/docs/resources/xml.md.erb +85 -85
  152. data/docs/resources/yaml.md.erb +69 -69
  153. data/docs/resources/yum.md.erb +98 -98
  154. data/docs/resources/zfs_dataset.md.erb +53 -53
  155. data/docs/resources/zfs_pool.md.erb +47 -47
  156. data/docs/ruby_usage.md +203 -203
  157. data/docs/shared/matcher_be.md.erb +1 -1
  158. data/docs/shared/matcher_cmp.md.erb +43 -43
  159. data/docs/shared/matcher_eq.md.erb +3 -3
  160. data/docs/shared/matcher_include.md.erb +1 -1
  161. data/docs/shared/matcher_match.md.erb +1 -1
  162. data/docs/shell.md +172 -172
  163. data/examples/README.md +8 -8
  164. data/examples/inheritance/README.md +65 -65
  165. data/examples/inheritance/controls/example.rb +14 -14
  166. data/examples/inheritance/inspec.yml +15 -15
  167. data/examples/kitchen-ansible/.kitchen.yml +25 -25
  168. data/examples/kitchen-ansible/Gemfile +19 -19
  169. data/examples/kitchen-ansible/README.md +53 -53
  170. data/examples/kitchen-ansible/files/nginx.repo +6 -6
  171. data/examples/kitchen-ansible/tasks/main.yml +16 -16
  172. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
  173. data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
  174. data/examples/kitchen-chef/.kitchen.yml +20 -20
  175. data/examples/kitchen-chef/Berksfile +3 -3
  176. data/examples/kitchen-chef/Gemfile +19 -19
  177. data/examples/kitchen-chef/README.md +27 -27
  178. data/examples/kitchen-chef/metadata.rb +7 -7
  179. data/examples/kitchen-chef/recipes/default.rb +6 -6
  180. data/examples/kitchen-chef/recipes/nginx.rb +30 -30
  181. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
  182. data/examples/kitchen-puppet/.kitchen.yml +22 -22
  183. data/examples/kitchen-puppet/Gemfile +20 -20
  184. data/examples/kitchen-puppet/Puppetfile +25 -25
  185. data/examples/kitchen-puppet/README.md +53 -53
  186. data/examples/kitchen-puppet/manifests/site.pp +33 -33
  187. data/examples/kitchen-puppet/metadata.json +11 -11
  188. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
  189. data/examples/meta-profile/README.md +37 -37
  190. data/examples/meta-profile/controls/example.rb +13 -13
  191. data/examples/meta-profile/inspec.yml +13 -13
  192. data/examples/profile-attribute.yml +2 -2
  193. data/examples/profile-attribute/README.md +14 -14
  194. data/examples/profile-attribute/controls/example.rb +11 -11
  195. data/examples/profile-attribute/inspec.yml +8 -8
  196. data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
  197. data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
  198. data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
  199. data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
  200. data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
  201. data/examples/profile-aws/inspec.yml +11 -11
  202. data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
  203. data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
  204. data/examples/profile-azure/inspec.yml +11 -11
  205. data/examples/profile-sensitive/README.md +29 -29
  206. data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
  207. data/examples/profile-sensitive/controls/sensitive.rb +9 -9
  208. data/examples/profile-sensitive/inspec.yml +8 -8
  209. data/examples/profile/README.md +48 -48
  210. data/examples/profile/controls/example.rb +23 -23
  211. data/examples/profile/controls/gordon.rb +36 -36
  212. data/examples/profile/controls/meta.rb +34 -34
  213. data/examples/profile/inspec.yml +10 -10
  214. data/examples/profile/libraries/gordon_config.rb +53 -53
  215. data/inspec.gemspec +47 -47
  216. data/lib/bundles/README.md +3 -3
  217. data/lib/bundles/inspec-artifact.rb +7 -7
  218. data/lib/bundles/inspec-artifact/README.md +1 -1
  219. data/lib/bundles/inspec-artifact/cli.rb +277 -277
  220. data/lib/bundles/inspec-compliance.rb +16 -16
  221. data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
  222. data/lib/bundles/inspec-compliance/README.md +185 -185
  223. data/lib/bundles/inspec-compliance/api.rb +316 -316
  224. data/lib/bundles/inspec-compliance/api/login.rb +152 -152
  225. data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
  226. data/lib/bundles/inspec-compliance/cli.rb +254 -254
  227. data/lib/bundles/inspec-compliance/configuration.rb +103 -103
  228. data/lib/bundles/inspec-compliance/http.rb +86 -86
  229. data/lib/bundles/inspec-compliance/support.rb +36 -36
  230. data/lib/bundles/inspec-compliance/target.rb +98 -98
  231. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
  232. data/lib/bundles/inspec-habitat.rb +12 -12
  233. data/lib/bundles/inspec-habitat/cli.rb +36 -36
  234. data/lib/bundles/inspec-habitat/log.rb +10 -10
  235. data/lib/bundles/inspec-habitat/profile.rb +390 -390
  236. data/lib/bundles/inspec-init.rb +8 -8
  237. data/lib/bundles/inspec-init/README.md +31 -31
  238. data/lib/bundles/inspec-init/cli.rb +97 -97
  239. data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
  240. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
  241. data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
  242. data/lib/bundles/inspec-supermarket.rb +13 -13
  243. data/lib/bundles/inspec-supermarket/README.md +45 -45
  244. data/lib/bundles/inspec-supermarket/api.rb +84 -84
  245. data/lib/bundles/inspec-supermarket/cli.rb +73 -73
  246. data/lib/bundles/inspec-supermarket/target.rb +34 -34
  247. data/lib/fetchers/git.rb +163 -163
  248. data/lib/fetchers/local.rb +74 -74
  249. data/lib/fetchers/mock.rb +35 -35
  250. data/lib/fetchers/url.rb +204 -204
  251. data/lib/inspec.rb +24 -24
  252. data/lib/inspec/archive/tar.rb +29 -29
  253. data/lib/inspec/archive/zip.rb +19 -19
  254. data/lib/inspec/backend.rb +92 -92
  255. data/lib/inspec/base_cli.rb +350 -333
  256. data/lib/inspec/cached_fetcher.rb +66 -66
  257. data/lib/inspec/cli.rb +292 -302
  258. data/lib/inspec/completions/bash.sh.erb +45 -45
  259. data/lib/inspec/completions/fish.sh.erb +34 -34
  260. data/lib/inspec/completions/zsh.sh.erb +61 -61
  261. data/lib/inspec/control_eval_context.rb +179 -179
  262. data/lib/inspec/dependencies/cache.rb +72 -72
  263. data/lib/inspec/dependencies/dependency_set.rb +92 -92
  264. data/lib/inspec/dependencies/lockfile.rb +115 -115
  265. data/lib/inspec/dependencies/requirement.rb +123 -123
  266. data/lib/inspec/dependencies/resolver.rb +86 -86
  267. data/lib/inspec/describe.rb +27 -27
  268. data/lib/inspec/dsl.rb +66 -66
  269. data/lib/inspec/dsl_shared.rb +33 -33
  270. data/lib/inspec/env_printer.rb +157 -157
  271. data/lib/inspec/errors.rb +13 -13
  272. data/lib/inspec/exceptions.rb +12 -12
  273. data/lib/inspec/expect.rb +45 -45
  274. data/lib/inspec/fetcher.rb +45 -45
  275. data/lib/inspec/file_provider.rb +275 -275
  276. data/lib/inspec/formatters.rb +3 -3
  277. data/lib/inspec/formatters/base.rb +250 -250
  278. data/lib/inspec/formatters/json_rspec.rb +20 -20
  279. data/lib/inspec/formatters/show_progress.rb +12 -12
  280. data/lib/inspec/library_eval_context.rb +58 -58
  281. data/lib/inspec/log.rb +11 -11
  282. data/lib/inspec/metadata.rb +247 -247
  283. data/lib/inspec/method_source.rb +24 -24
  284. data/lib/inspec/objects.rb +14 -14
  285. data/lib/inspec/objects/attribute.rb +65 -65
  286. data/lib/inspec/objects/control.rb +61 -61
  287. data/lib/inspec/objects/describe.rb +92 -92
  288. data/lib/inspec/objects/each_loop.rb +36 -36
  289. data/lib/inspec/objects/list.rb +15 -15
  290. data/lib/inspec/objects/or_test.rb +40 -40
  291. data/lib/inspec/objects/ruby_helper.rb +15 -15
  292. data/lib/inspec/objects/tag.rb +27 -27
  293. data/lib/inspec/objects/test.rb +87 -87
  294. data/lib/inspec/objects/value.rb +27 -27
  295. data/lib/inspec/plugins.rb +60 -60
  296. data/lib/inspec/plugins/cli.rb +24 -24
  297. data/lib/inspec/plugins/fetcher.rb +86 -86
  298. data/lib/inspec/plugins/resource.rb +133 -133
  299. data/lib/inspec/plugins/secret.rb +15 -15
  300. data/lib/inspec/plugins/source_reader.rb +40 -40
  301. data/lib/inspec/polyfill.rb +12 -12
  302. data/lib/inspec/profile.rb +510 -510
  303. data/lib/inspec/profile_context.rb +207 -207
  304. data/lib/inspec/profile_vendor.rb +66 -66
  305. data/lib/inspec/reporters.rb +50 -50
  306. data/lib/inspec/reporters/base.rb +24 -24
  307. data/lib/inspec/reporters/cli.rb +356 -356
  308. data/lib/inspec/reporters/json.rb +116 -116
  309. data/lib/inspec/reporters/json_min.rb +48 -48
  310. data/lib/inspec/reporters/junit.rb +77 -77
  311. data/lib/inspec/require_loader.rb +33 -33
  312. data/lib/inspec/resource.rb +186 -186
  313. data/lib/inspec/rule.rb +266 -266
  314. data/lib/inspec/runner.rb +344 -344
  315. data/lib/inspec/runner_mock.rb +41 -41
  316. data/lib/inspec/runner_rspec.rb +174 -174
  317. data/lib/inspec/runtime_profile.rb +26 -26
  318. data/lib/inspec/schema.rb +213 -213
  319. data/lib/inspec/secrets.rb +19 -19
  320. data/lib/inspec/secrets/yaml.rb +30 -30
  321. data/lib/inspec/shell.rb +220 -223
  322. data/lib/inspec/shell_detector.rb +90 -90
  323. data/lib/inspec/source_reader.rb +29 -29
  324. data/lib/inspec/version.rb +8 -8
  325. data/lib/matchers/matchers.rb +339 -339
  326. data/lib/resource_support/aws.rb +40 -40
  327. data/lib/resource_support/aws/aws_backend_base.rb +12 -12
  328. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
  329. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
  330. data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
  331. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
  332. data/lib/resources/aide_conf.rb +160 -160
  333. data/lib/resources/apache.rb +48 -48
  334. data/lib/resources/apache_conf.rb +156 -156
  335. data/lib/resources/apt.rb +149 -149
  336. data/lib/resources/audit_policy.rb +63 -63
  337. data/lib/resources/auditd.rb +231 -231
  338. data/lib/resources/auditd_conf.rb +55 -55
  339. data/lib/resources/aws/aws_cloudtrail_trail.rb +77 -77
  340. data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
  341. data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
  342. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
  343. data/lib/resources/aws/aws_ec2_instance.rb +157 -157
  344. data/lib/resources/aws/aws_iam_access_key.rb +106 -106
  345. data/lib/resources/aws/aws_iam_access_keys.rb +144 -144
  346. data/lib/resources/aws/aws_iam_group.rb +56 -56
  347. data/lib/resources/aws/aws_iam_groups.rb +45 -45
  348. data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
  349. data/lib/resources/aws/aws_iam_policies.rb +46 -46
  350. data/lib/resources/aws/aws_iam_policy.rb +119 -119
  351. data/lib/resources/aws/aws_iam_role.rb +51 -51
  352. data/lib/resources/aws/aws_iam_root_user.rb +60 -60
  353. data/lib/resources/aws/aws_iam_user.rb +111 -111
  354. data/lib/resources/aws/aws_iam_users.rb +96 -96
  355. data/lib/resources/aws/aws_kms_keys.rb +46 -46
  356. data/lib/resources/aws/aws_route_table.rb +61 -61
  357. data/lib/resources/aws/aws_s3_bucket.rb +115 -115
  358. data/lib/resources/aws/aws_security_group.rb +93 -93
  359. data/lib/resources/aws/aws_security_groups.rb +68 -68
  360. data/lib/resources/aws/aws_sns_topic.rb +53 -53
  361. data/lib/resources/aws/aws_subnet.rb +88 -88
  362. data/lib/resources/aws/aws_subnets.rb +53 -53
  363. data/lib/resources/aws/aws_vpc.rb +69 -69
  364. data/lib/resources/aws/aws_vpcs.rb +45 -45
  365. data/lib/resources/azure/azure_backend.rb +377 -377
  366. data/lib/resources/azure/azure_generic_resource.rb +59 -59
  367. data/lib/resources/azure/azure_resource_group.rb +152 -152
  368. data/lib/resources/azure/azure_virtual_machine.rb +264 -264
  369. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +136 -136
  370. data/lib/resources/bash.rb +35 -35
  371. data/lib/resources/bond.rb +68 -68
  372. data/lib/resources/bridge.rb +122 -122
  373. data/lib/resources/command.rb +69 -69
  374. data/lib/resources/cpan.rb +58 -58
  375. data/lib/resources/cran.rb +64 -64
  376. data/lib/resources/crontab.rb +170 -170
  377. data/lib/resources/csv.rb +60 -60
  378. data/lib/resources/dh_params.rb +82 -82
  379. data/lib/resources/directory.rb +25 -25
  380. data/lib/resources/docker.rb +236 -236
  381. data/lib/resources/docker_container.rb +89 -89
  382. data/lib/resources/docker_image.rb +83 -83
  383. data/lib/resources/docker_object.rb +57 -57
  384. data/lib/resources/docker_service.rb +90 -90
  385. data/lib/resources/elasticsearch.rb +169 -169
  386. data/lib/resources/etc_fstab.rb +102 -102
  387. data/lib/resources/etc_group.rb +156 -156
  388. data/lib/resources/etc_hosts.rb +81 -81
  389. data/lib/resources/etc_hosts_allow_deny.rb +123 -123
  390. data/lib/resources/file.rb +298 -298
  391. data/lib/resources/filesystem.rb +31 -31
  392. data/lib/resources/firewalld.rb +144 -144
  393. data/lib/resources/gem.rb +70 -70
  394. data/lib/resources/groups.rb +215 -215
  395. data/lib/resources/grub_conf.rb +237 -237
  396. data/lib/resources/host.rb +300 -300
  397. data/lib/resources/http.rb +250 -250
  398. data/lib/resources/iis_app.rb +104 -104
  399. data/lib/resources/iis_site.rb +148 -148
  400. data/lib/resources/inetd_conf.rb +62 -62
  401. data/lib/resources/ini.rb +29 -29
  402. data/lib/resources/interface.rb +129 -129
  403. data/lib/resources/iptables.rb +69 -69
  404. data/lib/resources/json.rb +117 -117
  405. data/lib/resources/kernel_module.rb +107 -107
  406. data/lib/resources/kernel_parameter.rb +58 -58
  407. data/lib/resources/key_rsa.rb +67 -67
  408. data/lib/resources/limits_conf.rb +55 -55
  409. data/lib/resources/login_def.rb +66 -66
  410. data/lib/resources/mount.rb +88 -88
  411. data/lib/resources/mssql_session.rb +101 -101
  412. data/lib/resources/mysql.rb +81 -81
  413. data/lib/resources/mysql_conf.rb +134 -134
  414. data/lib/resources/mysql_session.rb +71 -71
  415. data/lib/resources/nginx.rb +96 -96
  416. data/lib/resources/nginx_conf.rb +227 -227
  417. data/lib/resources/npm.rb +48 -48
  418. data/lib/resources/ntp_conf.rb +58 -58
  419. data/lib/resources/oneget.rb +71 -71
  420. data/lib/resources/oracledb_session.rb +139 -139
  421. data/lib/resources/os.rb +36 -36
  422. data/lib/resources/os_env.rb +76 -76
  423. data/lib/resources/package.rb +363 -363
  424. data/lib/resources/packages.rb +111 -111
  425. data/lib/resources/parse_config.rb +116 -116
  426. data/lib/resources/passwd.rb +74 -74
  427. data/lib/resources/pip.rb +89 -89
  428. data/lib/resources/platform.rb +109 -109
  429. data/lib/resources/port.rb +771 -771
  430. data/lib/resources/postgres.rb +130 -130
  431. data/lib/resources/postgres_conf.rb +121 -121
  432. data/lib/resources/postgres_hba_conf.rb +100 -100
  433. data/lib/resources/postgres_ident_conf.rb +78 -78
  434. data/lib/resources/postgres_session.rb +71 -71
  435. data/lib/resources/powershell.rb +57 -57
  436. data/lib/resources/processes.rb +204 -204
  437. data/lib/resources/rabbitmq_conf.rb +52 -52
  438. data/lib/resources/registry_key.rb +296 -296
  439. data/lib/resources/security_policy.rb +180 -180
  440. data/lib/resources/service.rb +789 -789
  441. data/lib/resources/shadow.rb +140 -140
  442. data/lib/resources/ssh_conf.rb +102 -102
  443. data/lib/resources/ssl.rb +99 -99
  444. data/lib/resources/sys_info.rb +28 -28
  445. data/lib/resources/toml.rb +32 -32
  446. data/lib/resources/users.rb +654 -654
  447. data/lib/resources/vbscript.rb +69 -69
  448. data/lib/resources/virtualization.rb +251 -251
  449. data/lib/resources/windows_feature.rb +84 -84
  450. data/lib/resources/windows_hotfix.rb +35 -35
  451. data/lib/resources/windows_task.rb +105 -105
  452. data/lib/resources/wmi.rb +113 -113
  453. data/lib/resources/x509_certificate.rb +143 -143
  454. data/lib/resources/xinetd.rb +111 -111
  455. data/lib/resources/xml.rb +46 -46
  456. data/lib/resources/yaml.rb +47 -47
  457. data/lib/resources/yum.rb +180 -180
  458. data/lib/resources/zfs_dataset.rb +60 -60
  459. data/lib/resources/zfs_pool.rb +49 -49
  460. data/lib/source_readers/flat.rb +39 -39
  461. data/lib/source_readers/inspec.rb +75 -75
  462. data/lib/utils/command_wrapper.rb +27 -27
  463. data/lib/utils/convert.rb +12 -12
  464. data/lib/utils/database_helpers.rb +77 -77
  465. data/lib/utils/erlang_parser.rb +192 -192
  466. data/lib/utils/filter.rb +272 -272
  467. data/lib/utils/filter_array.rb +27 -27
  468. data/lib/utils/find_files.rb +44 -44
  469. data/lib/utils/hash.rb +41 -41
  470. data/lib/utils/json_log.rb +18 -18
  471. data/lib/utils/latest_version.rb +22 -22
  472. data/lib/utils/modulator.rb +12 -12
  473. data/lib/utils/nginx_parser.rb +85 -85
  474. data/lib/utils/object_traversal.rb +49 -49
  475. data/lib/utils/parser.rb +274 -274
  476. data/lib/utils/plugin_registry.rb +93 -93
  477. data/lib/utils/simpleconfig.rb +120 -120
  478. data/lib/utils/spdx.rb +13 -13
  479. data/lib/utils/spdx.txt +343 -343
  480. metadata +1 -1
@@ -1,23 +1,23 @@
1
- # encoding: utf-8
2
- # copyright: 2015, Chef Software, Inc.
3
-
4
- title '/tmp profile'
5
-
6
- # you add controls here
7
- control "tmp-1.0" do # A unique ID for this control
8
- impact 0.7 # The criticality, if this control fails.
9
- title "Create /tmp directory" # A human-readable title
10
- desc "An optional description..." # Describe why this is needed
11
- tag data: "temp data" # A tag allows you to associate key information
12
- tag "security" # to the test
13
- ref "Document A-12", url: 'http://...' # Additional references
14
-
15
- describe file('/tmp') do # The actual test
16
- it { should be_directory }
17
- end
18
- end
19
-
20
- # you can also use plain tests
21
- describe file('/tmp') do
22
- it { should be_directory }
23
- end
1
+ # encoding: utf-8
2
+ # copyright: 2015, Chef Software, Inc.
3
+
4
+ title '/tmp profile'
5
+
6
+ # you add controls here
7
+ control "tmp-1.0" do # A unique ID for this control
8
+ impact 0.7 # The criticality, if this control fails.
9
+ title "Create /tmp directory" # A human-readable title
10
+ desc "An optional description..." # Describe why this is needed
11
+ tag data: "temp data" # A tag allows you to associate key information
12
+ tag "security" # to the test
13
+ ref "Document A-12", url: 'http://...' # Additional references
14
+
15
+ describe file('/tmp') do # The actual test
16
+ it { should be_directory }
17
+ end
18
+ end
19
+
20
+ # you can also use plain tests
21
+ describe file('/tmp') do
22
+ it { should be_directory }
23
+ end
@@ -1,36 +1,36 @@
1
- # encoding: utf-8
2
- # copyright: 2016, Chef Software, Inc.
3
-
4
- title 'Gordon Config Checks'
5
-
6
- # To pass the test, create the following file
7
- # ```bash
8
- # mkdir -p /tmp/gordon
9
- # cat <<EOF > /tmp/gordon/config.yaml
10
- # version: '1.0'
11
- # EOF
12
- # ```
13
- control 'gordon-1.0' do
14
- impact 0.7
15
- title 'Verify the version number of Gordon'
16
- desc 'An optional description...'
17
- tag 'gordon'
18
- ref 'Gordon Requirements 1.0', uri: 'http://...'
19
-
20
- # Test using the custom gordon_config Inspec resource
21
- # Find the resource content here: ../libraries/
22
- describe gordon_config do
23
- it { should exist }
24
- its('version') { should eq('1.0') }
25
- its('file_size') { should <= 20 }
26
- its('comma_count') { should eq 0 }
27
- end
28
-
29
- # Test the version again to showcase variables
30
- g = gordon_config
31
- g_path = g.file_path
32
- g_version = g.version
33
- describe file(g_path) do
34
- its('content') { should match g_version }
35
- end
36
- end
1
+ # encoding: utf-8
2
+ # copyright: 2016, Chef Software, Inc.
3
+
4
+ title 'Gordon Config Checks'
5
+
6
+ # To pass the test, create the following file
7
+ # ```bash
8
+ # mkdir -p /tmp/gordon
9
+ # cat <<EOF > /tmp/gordon/config.yaml
10
+ # version: '1.0'
11
+ # EOF
12
+ # ```
13
+ control 'gordon-1.0' do
14
+ impact 0.7
15
+ title 'Verify the version number of Gordon'
16
+ desc 'An optional description...'
17
+ tag 'gordon'
18
+ ref 'Gordon Requirements 1.0', uri: 'http://...'
19
+
20
+ # Test using the custom gordon_config Inspec resource
21
+ # Find the resource content here: ../libraries/
22
+ describe gordon_config do
23
+ it { should exist }
24
+ its('version') { should eq('1.0') }
25
+ its('file_size') { should <= 20 }
26
+ its('comma_count') { should eq 0 }
27
+ end
28
+
29
+ # Test the version again to showcase variables
30
+ g = gordon_config
31
+ g_path = g.file_path
32
+ g_version = g.version
33
+ describe file(g_path) do
34
+ its('content') { should match g_version }
35
+ end
36
+ end
@@ -1,34 +1,34 @@
1
- title 'SSH Server Configuration'
2
-
3
- control 'ssh-1' do
4
- impact 1.0
5
-
6
- title 'Allow only SSH Protocol 2'
7
- desc 'Only SSH protocol version 2 connections should be permitted.
8
- The default setting in /etc/ssh/sshd_config is correct, and can be
9
- verified by ensuring that the following line appears: Protocol 2'
10
-
11
- tag 'production','development'
12
- tag 'ssh','sshd','openssh-server'
13
-
14
- tag cce: 'CCE-27072-8'
15
- tag disa: 'RHEL-06-000227'
16
-
17
- tag nist: 'AC-3(10).i'
18
- tag nist: 'IA-5(1)'
19
-
20
- tag cci: 'CCI-000776'
21
- tag cci: 'CCI-000774'
22
- tag cci: 'CCI-001436'
23
-
24
- tag remediation: 'stig_rhel6/recipes/sshd-config.rb'
25
- tag remediation: 'https://supermarket.chef.io/cookbooks/ssh-hardening'
26
-
27
- ref 'NSA-RH6-STIG - Section 3.5.2.1', url: 'https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf'
28
- ref 'DISA-RHEL6-SG - Section 9.2.1', url: 'http://iasecontent.disa.mil/stigs/zip/Jan2016/U_RedHat_6_V1R10_STIG.zip'
29
- ref 'http://people.redhat.com/swells/scap-security-guide/RHEL/6/output/ssg-centos6-guide-C2S.html'
30
-
31
- describe file('/bin/sh') do
32
- it { should be_owned_by 'root' }
33
- end
34
- end
1
+ title 'SSH Server Configuration'
2
+
3
+ control 'ssh-1' do
4
+ impact 1.0
5
+
6
+ title 'Allow only SSH Protocol 2'
7
+ desc 'Only SSH protocol version 2 connections should be permitted.
8
+ The default setting in /etc/ssh/sshd_config is correct, and can be
9
+ verified by ensuring that the following line appears: Protocol 2'
10
+
11
+ tag 'production','development'
12
+ tag 'ssh','sshd','openssh-server'
13
+
14
+ tag cce: 'CCE-27072-8'
15
+ tag disa: 'RHEL-06-000227'
16
+
17
+ tag nist: 'AC-3(10).i'
18
+ tag nist: 'IA-5(1)'
19
+
20
+ tag cci: 'CCI-000776'
21
+ tag cci: 'CCI-000774'
22
+ tag cci: 'CCI-001436'
23
+
24
+ tag remediation: 'stig_rhel6/recipes/sshd-config.rb'
25
+ tag remediation: 'https://supermarket.chef.io/cookbooks/ssh-hardening'
26
+
27
+ ref 'NSA-RH6-STIG - Section 3.5.2.1', url: 'https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf'
28
+ ref 'DISA-RHEL6-SG - Section 9.2.1', url: 'http://iasecontent.disa.mil/stigs/zip/Jan2016/U_RedHat_6_V1R10_STIG.zip'
29
+ ref 'http://people.redhat.com/swells/scap-security-guide/RHEL/6/output/ssg-centos6-guide-C2S.html'
30
+
31
+ describe file('/bin/sh') do
32
+ it { should be_owned_by 'root' }
33
+ end
34
+ end
@@ -1,10 +1,10 @@
1
- name: profile
2
- title: InSpec Example Profile
3
- maintainer: Chef Software, Inc.
4
- copyright: Chef Software, Inc.
5
- copyright_email: support@chef.io
6
- license: Apache-2.0
7
- summary: Demonstrates the use of InSpec Compliance Profile
8
- version: 1.0.0
9
- supports:
10
- - os-family: unix
1
+ name: profile
2
+ title: InSpec Example Profile
3
+ maintainer: Chef Software, Inc.
4
+ copyright: Chef Software, Inc.
5
+ copyright_email: support@chef.io
6
+ license: Apache-2.0
7
+ summary: Demonstrates the use of InSpec Compliance Profile
8
+ version: 1.0.0
9
+ supports:
10
+ - os-family: unix
@@ -1,53 +1,53 @@
1
- require 'yaml'
2
-
3
- # Custom resource based on the InSpec resource DSL
4
- class GordonConfig < Inspec.resource(1)
5
- name 'gordon_config'
6
-
7
- desc "
8
- Gordon's resource description ...
9
- "
10
-
11
- example "
12
- describe gordon_config do
13
- its('version') { should eq('1.0') }
14
- its('file_size') { should > 1 }
15
- end
16
- "
17
-
18
- # Load the configuration file on initialization
19
- def initialize
20
- @params = {}
21
- @path = '/tmp/gordon/config.yaml'
22
- @file = inspec.file(@path)
23
- return skip_resource "Can't find file \"#{@path}\"" if !@file.file?
24
-
25
- # Protect from invalid YAML content
26
- begin
27
- @params = YAML.load(@file.content)
28
- # Add two extra matchers
29
- @params['file_size'] = @file.size
30
- @params['file_path'] = @path
31
- @params['ruby'] = 'RUBY IS HERE TO HELP ME!'
32
- rescue Exception
33
- return skip_resource "#{@file}: #{$!}"
34
- end
35
- end
36
-
37
- # Example method called by 'it { should exist }'
38
- # Returns true or false from the 'File.exists?' method
39
- def exists?
40
- return File.exists?(@path)
41
- end
42
-
43
- # Example matcher for the number of commas in the file
44
- def comma_count
45
- text = @file.content
46
- return text.count(',')
47
- end
48
-
49
- # Expose all parameters
50
- def method_missing(name)
51
- return @params[name.to_s]
52
- end
53
- end
1
+ require 'yaml'
2
+
3
+ # Custom resource based on the InSpec resource DSL
4
+ class GordonConfig < Inspec.resource(1)
5
+ name 'gordon_config'
6
+
7
+ desc "
8
+ Gordon's resource description ...
9
+ "
10
+
11
+ example "
12
+ describe gordon_config do
13
+ its('version') { should eq('1.0') }
14
+ its('file_size') { should > 1 }
15
+ end
16
+ "
17
+
18
+ # Load the configuration file on initialization
19
+ def initialize
20
+ @params = {}
21
+ @path = '/tmp/gordon/config.yaml'
22
+ @file = inspec.file(@path)
23
+ return skip_resource "Can't find file \"#{@path}\"" if !@file.file?
24
+
25
+ # Protect from invalid YAML content
26
+ begin
27
+ @params = YAML.load(@file.content)
28
+ # Add two extra matchers
29
+ @params['file_size'] = @file.size
30
+ @params['file_path'] = @path
31
+ @params['ruby'] = 'RUBY IS HERE TO HELP ME!'
32
+ rescue Exception
33
+ return skip_resource "#{@file}: #{$!}"
34
+ end
35
+ end
36
+
37
+ # Example method called by 'it { should exist }'
38
+ # Returns true or false from the 'File.exists?' method
39
+ def exists?
40
+ return File.exists?(@path)
41
+ end
42
+
43
+ # Example matcher for the number of commas in the file
44
+ def comma_count
45
+ text = @file.content
46
+ return text.count(',')
47
+ end
48
+
49
+ # Expose all parameters
50
+ def method_missing(name)
51
+ return @params[name.to_s]
52
+ end
53
+ end
@@ -1,47 +1,47 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'inspec/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'inspec'
8
- spec.version = Inspec::VERSION
9
- spec.authors = ['Dominik Richter']
10
- spec.email = ['dominik.richter@gmail.com']
11
- spec.summary = 'Infrastructure and compliance testing.'
12
- spec.description = 'InSpec provides a framework for creating end-to-end infrastructure tests. You can use it for integration or even compliance testing. Create fully portable test profiles and use them in your workflow to ensure stability and security. Integrate InSpec in your change lifecycle for local testing, CI/CD, and deployment verification.'
13
- spec.homepage = 'https://github.com/chef/inspec'
14
- spec.license = 'Apache-2.0'
15
-
16
- spec.files = %w{
17
- README.md Rakefile MAINTAINERS.toml MAINTAINERS.md LICENSE inspec.gemspec
18
- Gemfile CHANGELOG.md .rubocop.yml
19
- } + Dir.glob(
20
- '{bin,docs,examples,lib}/**/*', File::FNM_DOTMATCH
21
- ).reject { |f| File.directory?(f) }
22
-
23
- spec.executables = %w{inspec}
24
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
- spec.require_paths = ['lib']
26
-
27
- spec.required_ruby_version = '>= 2.3'
28
-
29
- spec.add_dependency 'train', '~> 1.1'
30
- spec.add_dependency 'thor', '~> 0.19'
31
- spec.add_dependency 'json', '>= 1.8', '< 3.0'
32
- spec.add_dependency 'method_source', '~> 0.8'
33
- spec.add_dependency 'rubyzip', '~> 1.1'
34
- spec.add_dependency 'rspec', '~> 3'
35
- spec.add_dependency 'rspec-its', '~> 1.2'
36
- spec.add_dependency 'pry', '~> 0'
37
- spec.add_dependency 'hashie', '~> 3.4'
38
- spec.add_dependency 'mixlib-log'
39
- spec.add_dependency 'sslshake', '~> 1.2'
40
- spec.add_dependency 'parallel', '~> 1.9'
41
- spec.add_dependency 'faraday', '>=0.9.0'
42
- spec.add_dependency 'tomlrb', '~> 1.2'
43
- spec.add_dependency 'addressable', '~> 2.4'
44
- spec.add_dependency 'parslet', '~> 1.5'
45
- spec.add_dependency 'semverse'
46
- spec.add_dependency 'htmlentities'
47
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'inspec/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'inspec'
8
+ spec.version = Inspec::VERSION
9
+ spec.authors = ['Dominik Richter']
10
+ spec.email = ['dominik.richter@gmail.com']
11
+ spec.summary = 'Infrastructure and compliance testing.'
12
+ spec.description = 'InSpec provides a framework for creating end-to-end infrastructure tests. You can use it for integration or even compliance testing. Create fully portable test profiles and use them in your workflow to ensure stability and security. Integrate InSpec in your change lifecycle for local testing, CI/CD, and deployment verification.'
13
+ spec.homepage = 'https://github.com/chef/inspec'
14
+ spec.license = 'Apache-2.0'
15
+
16
+ spec.files = %w{
17
+ README.md Rakefile MAINTAINERS.toml MAINTAINERS.md LICENSE inspec.gemspec
18
+ Gemfile CHANGELOG.md .rubocop.yml
19
+ } + Dir.glob(
20
+ '{bin,docs,examples,lib}/**/*', File::FNM_DOTMATCH
21
+ ).reject { |f| File.directory?(f) }
22
+
23
+ spec.executables = %w{inspec}
24
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.required_ruby_version = '>= 2.3'
28
+
29
+ spec.add_dependency 'train', '~> 1.1'
30
+ spec.add_dependency 'thor', '~> 0.19'
31
+ spec.add_dependency 'json', '>= 1.8', '< 3.0'
32
+ spec.add_dependency 'method_source', '~> 0.8'
33
+ spec.add_dependency 'rubyzip', '~> 1.1'
34
+ spec.add_dependency 'rspec', '~> 3'
35
+ spec.add_dependency 'rspec-its', '~> 1.2'
36
+ spec.add_dependency 'pry', '~> 0'
37
+ spec.add_dependency 'hashie', '~> 3.4'
38
+ spec.add_dependency 'mixlib-log'
39
+ spec.add_dependency 'sslshake', '~> 1.2'
40
+ spec.add_dependency 'parallel', '~> 1.9'
41
+ spec.add_dependency 'faraday', '>=0.9.0'
42
+ spec.add_dependency 'tomlrb', '~> 1.2'
43
+ spec.add_dependency 'addressable', '~> 2.4'
44
+ spec.add_dependency 'parslet', '~> 1.5'
45
+ spec.add_dependency 'semverse'
46
+ spec.add_dependency 'htmlentities'
47
+ end
@@ -1,3 +1,3 @@
1
- # InSpec Bundled Plugins
2
-
3
- This directory contains bundled InSpec plugins. Those plugins are shipped with InSpec temporarily only. Over the next months we are going to stabilize the InSpec Plugin API. Once this API reached stability, all bundled plugins will be externalized.
1
+ # InSpec Bundled Plugins
2
+
3
+ This directory contains bundled InSpec plugins. Those plugins are shipped with InSpec temporarily only. Over the next months we are going to stabilize the InSpec Plugin API. Once this API reached stability, all bundled plugins will be externalized.
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
2
- # author: Dave Parfitt
3
-
4
- libdir = File.dirname(__FILE__)
5
- $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
6
-
7
- require 'inspec-artifact/cli'
1
+ # encoding: utf-8
2
+ # author: Dave Parfitt
3
+
4
+ libdir = File.dirname(__FILE__)
5
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
6
+
7
+ require 'inspec-artifact/cli'
@@ -1 +1 @@
1
- # TODO
1
+ # TODO
@@ -1,277 +1,277 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
- require 'base64'
4
- require 'openssl'
5
- require 'pathname'
6
- require 'set'
7
- require 'tempfile'
8
- require 'yaml'
9
-
10
- # Notes:
11
- #
12
- # Generate keys
13
- # The initial implementation uses 2048 bit RSA key pairs (public + private).
14
- # Public keys must be available for a customer to install and verify an artifact.
15
- # Private keys should be stored in a secure location and NOT be distributed.
16
- # (They're only for creating artifacts).
17
- #
18
- #
19
- # .IAF file format
20
- # .iaf = "Inspec Artifact File", easy to rename if you'd like something more appropriate.
21
- # The iaf file wraps a binary artifact with some metadata. The first implementation
22
- # looks like this:
23
- #
24
- # INSPEC-PROFILE-1
25
- # name_of_signing_key
26
- # algorithm
27
- # signature
28
- # <empty line>
29
- # binary-blob
30
- # <eof>
31
- #
32
- # Let's look at each line:
33
- # INSPEC-PROFILE-1:
34
- # This is the artifact version descriptor. It should't change unless the
35
- # format of the archive changes.
36
- #
37
- # name_of_signing_key
38
- # The name of the public key that can be used to verify an artifact
39
- #
40
- # algorithm
41
- # The digest used to sign, I picked SHA512 to start with.
42
- # If we support multiple digests, we'll need to have the verify() method
43
- # support each digest.
44
- #
45
- # signature
46
- # The result of passing the binary artifact through the digest algorithm above.
47
- # Result is base64 encoded.
48
- #
49
- # <empty line>
50
- # We use an empty line to separate artifact header from artifact body (binary blob).
51
- # The artifact body can be anything you like.
52
- #
53
- # binary-blob
54
- # A binary blob, most likely a .tar.gz or tar.xz file. We'll need to pick one and
55
- # stick with it as part of the "INSPEC-PROFILE-1" artifact version. If we change block
56
- # format, the artifact version descriptor must be incremented, and the sign()
57
- # and verify() methods must be updated to support a newer version.
58
- #
59
- #
60
- # Key revocation
61
- # This implementation doesn't support key revocation. However, a customer
62
- # can remove the public cert file before installation, and artifacts will then
63
- # fail verification.
64
- #
65
- # Key locations
66
- # This implementation uses the current working directory to find public and
67
- # private keys. We should establish a common key directory (similar to /hab/cache/keys
68
- # or ~/.hab/cache/keys in Habitat).
69
- #
70
- # Extracting artifacts outside of Inspec
71
- # As in Habitat, the artifact format for Inspec allows the use of common
72
- # Unix tools to read the header and body of an artifact.
73
- # To extract the header from a .iaf:
74
- # sed '/^$/q' foo.iaf
75
- # To extract the raw content from a .iaf:
76
- # sed '1,/^$/d' foo.iaf
77
-
78
- module Artifact
79
- KEY_BITS=2048
80
- KEY_ALG=OpenSSL::PKey::RSA
81
-
82
- INSPEC_PROFILE_VERSION_1='INSPEC-PROFILE-1'
83
- INSPEC_REPORT_VERSION_1='INSPEC-REPORT-1'
84
-
85
- ARTIFACT_DIGEST=OpenSSL::Digest::SHA512
86
- ARTIFACT_DIGEST_NAME='SHA512'
87
-
88
- VALID_PROFILE_VERSIONS=Set.new [INSPEC_PROFILE_VERSION_1]
89
- VALID_PROFILE_DIGESTS=Set.new [ARTIFACT_DIGEST_NAME]
90
-
91
- SIGNED_PROFILE_SUFFIX='iaf'
92
- SIGNED_REPORT_SUFFIX='iar'
93
- class CLI < Inspec::BaseCLI
94
- namespace 'artifact'
95
-
96
- # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
97
- def self.banner(command, _namespace = nil, _subcommand = false)
98
- "#{basename} #{subcommand_prefix} #{command.usage}"
99
- end
100
-
101
- def self.subcommand_prefix
102
- namespace
103
- end
104
-
105
- desc 'generate', 'Generate a RSA key pair for signing and verification'
106
- option :keyname, type: :string, required: true,
107
- desc: 'Desriptive name of key'
108
- option :keydir, type: :string, default: './',
109
- desc: 'Directory to search for keys'
110
- def generate_keys
111
- puts 'Generating keys'
112
- keygen
113
- end
114
-
115
- desc 'sign-profile', 'Create a signed .iaf artifact'
116
- option :profile, type: :string, required: true,
117
- desc: 'Path to profile directory'
118
- option :keyname, type: :string, required: true,
119
- desc: 'Desriptive name of key'
120
- def sign_profile
121
- profile_sign
122
- end
123
-
124
- desc 'verify-profile', 'Verify a signed .iaf artifact'
125
- option :infile, type: :string, required: true,
126
- desc: '.iaf file to verify'
127
- def verify_profile
128
- profile_verify
129
- end
130
-
131
- desc 'install-profile', 'Verify and install a signed .iaf artifact'
132
- option :infile, type: :string, required: true,
133
- desc: '.iaf file to install'
134
- option :destdir, type: :string, required: true,
135
- desc: 'Installation directory'
136
- def install_profile
137
- profile_install
138
- end
139
-
140
- private
141
-
142
- def keygen
143
- key = KEY_ALG.new KEY_BITS
144
- puts 'Generating private key'
145
- open "#{options['keyname']}.pem.key", 'w' do |io| io.write key.to_pem end
146
- puts 'Generating public key'
147
- open "#{options['keyname']}.pem.pub", 'w' do |io| io.write key.public_key.to_pem end
148
- end
149
-
150
- def read_profile_metadata(path_to_profile)
151
- begin
152
- p = Pathname.new(path_to_profile)
153
- p = p.join('inspec.yml')
154
- if not p.exist?
155
- raise "#{path_to_profile} doesn't appear to be a valid Inspec profile"
156
- end
157
- yaml = YAML.load_file(p.to_s)
158
- yaml = yaml.to_hash
159
-
160
- if not yaml.key? 'name'
161
- raise 'Profile is invalid, name is not defined'
162
- end
163
-
164
- if not yaml.key? 'version'
165
- raise 'Profile is invalid, version is not defined'
166
- end
167
- rescue => e
168
- # rewrap it and pass it up to the CLI
169
- raise "Error reading Inspec profile metadata: #{e}"
170
- end
171
-
172
- yaml
173
- end
174
-
175
- def profile_compress(path_to_profile, profile_md, workdir)
176
- profile_name = profile_md['name']
177
- profile_version = profile_md['version']
178
- outfile_name = "#{workdir}/#{profile_name}-#{profile_version}.tar.gz"
179
- `tar czf #{outfile_name} -C #{path_to_profile} .`
180
- outfile_name
181
- end
182
-
183
- def profile_sign
184
- Dir.mktmpdir do |workdir|
185
- puts "Signing #{options['profile']} with key #{options['keyname']}"
186
- path_to_profile = options['profile']
187
- profile_md = read_profile_metadata(path_to_profile)
188
- artifact_filename = "#{profile_md['name']}-#{profile_md['version']}.#{SIGNED_PROFILE_SUFFIX}"
189
- tarfile = profile_compress(path_to_profile, profile_md, workdir)
190
- content = IO.binread(tarfile)
191
- signing_key = KEY_ALG.new File.read "#{options['keyname']}.pem.key"
192
- sha = ARTIFACT_DIGEST.new
193
- signature = signing_key.sign sha, content
194
- # convert the signature to Base64
195
- signature_base64 = Base64.encode64(signature)
196
- tar_content = IO.binread(tarfile)
197
- File.open(artifact_filename, 'wb') do |f|
198
- f.puts(INSPEC_PROFILE_VERSION_1)
199
- f.puts(options['keyname'])
200
- f.puts(ARTIFACT_DIGEST_NAME)
201
- f.puts(signature_base64)
202
- f.puts('') # newline separates artifact header with body
203
- f.write(tar_content)
204
- end
205
- puts "Successfully generated #{artifact_filename}"
206
- end
207
- end
208
-
209
- def valid_header?(file_alg, file_version, file_keyname)
210
- public_keyfile = "#{file_keyname}.pem.pub"
211
- puts "Looking for #{public_keyfile} to verify artifact"
212
- if !File.exist? public_keyfile
213
- raise "Can't find #{public_keyfile}"
214
- end
215
-
216
- raise 'Invalid artifact digest algorithm detected' if !VALID_PROFILE_DIGESTS.member?(file_alg)
217
- raise 'Invalid artifact version detected' if !VALID_PROFILE_VERSIONS.member?(file_version)
218
- end
219
-
220
- def verify(file_to_verifiy, &content_block)
221
- f = File.open(file_to_verifiy, 'r')
222
- file_version = f.readline.strip!
223
- file_keyname = f.readline.strip!
224
- file_alg = f.readline.strip!
225
-
226
- file_sig = ''
227
- # the signature is multi-line
228
- while (line = f.readline) != "\n"
229
- file_sig += line
230
- end
231
- file_sig.strip!
232
- f.close
233
-
234
- valid_header?(file_alg, file_version, file_keyname)
235
-
236
- public_keyfile = "#{file_keyname}.pem.pub"
237
- verification_key = KEY_ALG.new File.read public_keyfile
238
-
239
- f = File.open(file_to_verifiy, 'r')
240
- while f.readline != "\n" do end
241
- content = f.read
242
-
243
- signature = Base64.decode64(file_sig)
244
- digest = ARTIFACT_DIGEST.new
245
- if verification_key.verify digest, signature, content
246
- content_block.yield(content)
247
- else
248
- puts 'Artifact is invalid'
249
- end
250
- end
251
-
252
- def profile_verify
253
- file_to_verifiy = options['infile']
254
- puts "Verifying #{file_to_verifiy}"
255
- verify(file_to_verifiy) do ||
256
- puts 'Artifact is valid'
257
- end
258
- end
259
-
260
- def profile_install
261
- puts 'Installing profile'
262
- file_to_verifiy = options['infile']
263
- dest_dir = options['destdir']
264
- verify(file_to_verifiy) do |content|
265
- Dir.mktmpdir do |workdir|
266
- tmpfile = Pathname.new(workdir).join('artifact_to_install.tar.gz')
267
- File.write(tmpfile, content)
268
- puts "Installing to #{dest_dir}"
269
- `tar xzf #{tmpfile} -C #{dest_dir}`
270
- end
271
- end
272
- end
273
- end
274
-
275
- # register the subcommand to Inspec CLI registry
276
- Inspec::Plugins::CLI.add_subcommand(Artifact::CLI, 'artifact', 'artifact SUBCOMMAND ...', 'Sign, verify and install artifacts', {})
277
- end
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'base64'
4
+ require 'openssl'
5
+ require 'pathname'
6
+ require 'set'
7
+ require 'tempfile'
8
+ require 'yaml'
9
+
10
+ # Notes:
11
+ #
12
+ # Generate keys
13
+ # The initial implementation uses 2048 bit RSA key pairs (public + private).
14
+ # Public keys must be available for a customer to install and verify an artifact.
15
+ # Private keys should be stored in a secure location and NOT be distributed.
16
+ # (They're only for creating artifacts).
17
+ #
18
+ #
19
+ # .IAF file format
20
+ # .iaf = "Inspec Artifact File", easy to rename if you'd like something more appropriate.
21
+ # The iaf file wraps a binary artifact with some metadata. The first implementation
22
+ # looks like this:
23
+ #
24
+ # INSPEC-PROFILE-1
25
+ # name_of_signing_key
26
+ # algorithm
27
+ # signature
28
+ # <empty line>
29
+ # binary-blob
30
+ # <eof>
31
+ #
32
+ # Let's look at each line:
33
+ # INSPEC-PROFILE-1:
34
+ # This is the artifact version descriptor. It should't change unless the
35
+ # format of the archive changes.
36
+ #
37
+ # name_of_signing_key
38
+ # The name of the public key that can be used to verify an artifact
39
+ #
40
+ # algorithm
41
+ # The digest used to sign, I picked SHA512 to start with.
42
+ # If we support multiple digests, we'll need to have the verify() method
43
+ # support each digest.
44
+ #
45
+ # signature
46
+ # The result of passing the binary artifact through the digest algorithm above.
47
+ # Result is base64 encoded.
48
+ #
49
+ # <empty line>
50
+ # We use an empty line to separate artifact header from artifact body (binary blob).
51
+ # The artifact body can be anything you like.
52
+ #
53
+ # binary-blob
54
+ # A binary blob, most likely a .tar.gz or tar.xz file. We'll need to pick one and
55
+ # stick with it as part of the "INSPEC-PROFILE-1" artifact version. If we change block
56
+ # format, the artifact version descriptor must be incremented, and the sign()
57
+ # and verify() methods must be updated to support a newer version.
58
+ #
59
+ #
60
+ # Key revocation
61
+ # This implementation doesn't support key revocation. However, a customer
62
+ # can remove the public cert file before installation, and artifacts will then
63
+ # fail verification.
64
+ #
65
+ # Key locations
66
+ # This implementation uses the current working directory to find public and
67
+ # private keys. We should establish a common key directory (similar to /hab/cache/keys
68
+ # or ~/.hab/cache/keys in Habitat).
69
+ #
70
+ # Extracting artifacts outside of Inspec
71
+ # As in Habitat, the artifact format for Inspec allows the use of common
72
+ # Unix tools to read the header and body of an artifact.
73
+ # To extract the header from a .iaf:
74
+ # sed '/^$/q' foo.iaf
75
+ # To extract the raw content from a .iaf:
76
+ # sed '1,/^$/d' foo.iaf
77
+
78
+ module Artifact
79
+ KEY_BITS=2048
80
+ KEY_ALG=OpenSSL::PKey::RSA
81
+
82
+ INSPEC_PROFILE_VERSION_1='INSPEC-PROFILE-1'
83
+ INSPEC_REPORT_VERSION_1='INSPEC-REPORT-1'
84
+
85
+ ARTIFACT_DIGEST=OpenSSL::Digest::SHA512
86
+ ARTIFACT_DIGEST_NAME='SHA512'
87
+
88
+ VALID_PROFILE_VERSIONS=Set.new [INSPEC_PROFILE_VERSION_1]
89
+ VALID_PROFILE_DIGESTS=Set.new [ARTIFACT_DIGEST_NAME]
90
+
91
+ SIGNED_PROFILE_SUFFIX='iaf'
92
+ SIGNED_REPORT_SUFFIX='iar'
93
+ class CLI < Inspec::BaseCLI
94
+ namespace 'artifact'
95
+
96
+ # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
97
+ def self.banner(command, _namespace = nil, _subcommand = false)
98
+ "#{basename} #{subcommand_prefix} #{command.usage}"
99
+ end
100
+
101
+ def self.subcommand_prefix
102
+ namespace
103
+ end
104
+
105
+ desc 'generate', 'Generate a RSA key pair for signing and verification'
106
+ option :keyname, type: :string, required: true,
107
+ desc: 'Desriptive name of key'
108
+ option :keydir, type: :string, default: './',
109
+ desc: 'Directory to search for keys'
110
+ def generate_keys
111
+ puts 'Generating keys'
112
+ keygen
113
+ end
114
+
115
+ desc 'sign-profile', 'Create a signed .iaf artifact'
116
+ option :profile, type: :string, required: true,
117
+ desc: 'Path to profile directory'
118
+ option :keyname, type: :string, required: true,
119
+ desc: 'Desriptive name of key'
120
+ def sign_profile
121
+ profile_sign
122
+ end
123
+
124
+ desc 'verify-profile', 'Verify a signed .iaf artifact'
125
+ option :infile, type: :string, required: true,
126
+ desc: '.iaf file to verify'
127
+ def verify_profile
128
+ profile_verify
129
+ end
130
+
131
+ desc 'install-profile', 'Verify and install a signed .iaf artifact'
132
+ option :infile, type: :string, required: true,
133
+ desc: '.iaf file to install'
134
+ option :destdir, type: :string, required: true,
135
+ desc: 'Installation directory'
136
+ def install_profile
137
+ profile_install
138
+ end
139
+
140
+ private
141
+
142
+ def keygen
143
+ key = KEY_ALG.new KEY_BITS
144
+ puts 'Generating private key'
145
+ open "#{options['keyname']}.pem.key", 'w' do |io| io.write key.to_pem end
146
+ puts 'Generating public key'
147
+ open "#{options['keyname']}.pem.pub", 'w' do |io| io.write key.public_key.to_pem end
148
+ end
149
+
150
+ def read_profile_metadata(path_to_profile)
151
+ begin
152
+ p = Pathname.new(path_to_profile)
153
+ p = p.join('inspec.yml')
154
+ if not p.exist?
155
+ raise "#{path_to_profile} doesn't appear to be a valid Inspec profile"
156
+ end
157
+ yaml = YAML.load_file(p.to_s)
158
+ yaml = yaml.to_hash
159
+
160
+ if not yaml.key? 'name'
161
+ raise 'Profile is invalid, name is not defined'
162
+ end
163
+
164
+ if not yaml.key? 'version'
165
+ raise 'Profile is invalid, version is not defined'
166
+ end
167
+ rescue => e
168
+ # rewrap it and pass it up to the CLI
169
+ raise "Error reading Inspec profile metadata: #{e}"
170
+ end
171
+
172
+ yaml
173
+ end
174
+
175
+ def profile_compress(path_to_profile, profile_md, workdir)
176
+ profile_name = profile_md['name']
177
+ profile_version = profile_md['version']
178
+ outfile_name = "#{workdir}/#{profile_name}-#{profile_version}.tar.gz"
179
+ `tar czf #{outfile_name} -C #{path_to_profile} .`
180
+ outfile_name
181
+ end
182
+
183
+ def profile_sign
184
+ Dir.mktmpdir do |workdir|
185
+ puts "Signing #{options['profile']} with key #{options['keyname']}"
186
+ path_to_profile = options['profile']
187
+ profile_md = read_profile_metadata(path_to_profile)
188
+ artifact_filename = "#{profile_md['name']}-#{profile_md['version']}.#{SIGNED_PROFILE_SUFFIX}"
189
+ tarfile = profile_compress(path_to_profile, profile_md, workdir)
190
+ content = IO.binread(tarfile)
191
+ signing_key = KEY_ALG.new File.read "#{options['keyname']}.pem.key"
192
+ sha = ARTIFACT_DIGEST.new
193
+ signature = signing_key.sign sha, content
194
+ # convert the signature to Base64
195
+ signature_base64 = Base64.encode64(signature)
196
+ tar_content = IO.binread(tarfile)
197
+ File.open(artifact_filename, 'wb') do |f|
198
+ f.puts(INSPEC_PROFILE_VERSION_1)
199
+ f.puts(options['keyname'])
200
+ f.puts(ARTIFACT_DIGEST_NAME)
201
+ f.puts(signature_base64)
202
+ f.puts('') # newline separates artifact header with body
203
+ f.write(tar_content)
204
+ end
205
+ puts "Successfully generated #{artifact_filename}"
206
+ end
207
+ end
208
+
209
+ def valid_header?(file_alg, file_version, file_keyname)
210
+ public_keyfile = "#{file_keyname}.pem.pub"
211
+ puts "Looking for #{public_keyfile} to verify artifact"
212
+ if !File.exist? public_keyfile
213
+ raise "Can't find #{public_keyfile}"
214
+ end
215
+
216
+ raise 'Invalid artifact digest algorithm detected' if !VALID_PROFILE_DIGESTS.member?(file_alg)
217
+ raise 'Invalid artifact version detected' if !VALID_PROFILE_VERSIONS.member?(file_version)
218
+ end
219
+
220
+ def verify(file_to_verifiy, &content_block)
221
+ f = File.open(file_to_verifiy, 'r')
222
+ file_version = f.readline.strip!
223
+ file_keyname = f.readline.strip!
224
+ file_alg = f.readline.strip!
225
+
226
+ file_sig = ''
227
+ # the signature is multi-line
228
+ while (line = f.readline) != "\n"
229
+ file_sig += line
230
+ end
231
+ file_sig.strip!
232
+ f.close
233
+
234
+ valid_header?(file_alg, file_version, file_keyname)
235
+
236
+ public_keyfile = "#{file_keyname}.pem.pub"
237
+ verification_key = KEY_ALG.new File.read public_keyfile
238
+
239
+ f = File.open(file_to_verifiy, 'r')
240
+ while f.readline != "\n" do end
241
+ content = f.read
242
+
243
+ signature = Base64.decode64(file_sig)
244
+ digest = ARTIFACT_DIGEST.new
245
+ if verification_key.verify digest, signature, content
246
+ content_block.yield(content)
247
+ else
248
+ puts 'Artifact is invalid'
249
+ end
250
+ end
251
+
252
+ def profile_verify
253
+ file_to_verifiy = options['infile']
254
+ puts "Verifying #{file_to_verifiy}"
255
+ verify(file_to_verifiy) do ||
256
+ puts 'Artifact is valid'
257
+ end
258
+ end
259
+
260
+ def profile_install
261
+ puts 'Installing profile'
262
+ file_to_verifiy = options['infile']
263
+ dest_dir = options['destdir']
264
+ verify(file_to_verifiy) do |content|
265
+ Dir.mktmpdir do |workdir|
266
+ tmpfile = Pathname.new(workdir).join('artifact_to_install.tar.gz')
267
+ File.write(tmpfile, content)
268
+ puts "Installing to #{dest_dir}"
269
+ `tar xzf #{tmpfile} -C #{dest_dir}`
270
+ end
271
+ end
272
+ end
273
+ end
274
+
275
+ # register the subcommand to Inspec CLI registry
276
+ Inspec::Plugins::CLI.add_subcommand(Artifact::CLI, 'artifact', 'artifact SUBCOMMAND ...', 'Sign, verify and install artifacts', {})
277
+ end