inspec 0.30.0 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -2
  3. data/Gemfile +2 -1
  4. data/docs/cli.rst +1 -17
  5. data/docs/resources.rst +128 -0
  6. data/docs/shell.rst +130 -0
  7. data/inspec.gemspec +3 -4
  8. data/lib/bundles/inspec-compliance/.kitchen.yml +0 -1
  9. data/lib/bundles/inspec-compliance/README.md +8 -3
  10. data/lib/bundles/inspec-compliance/api.rb +21 -6
  11. data/lib/bundles/inspec-compliance/bootstrap.sh +13 -9
  12. data/lib/bundles/inspec-compliance/cli.rb +23 -19
  13. data/lib/bundles/inspec-compliance/target.rb +1 -0
  14. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +42 -5
  15. data/lib/bundles/inspec-init/cli.rb +9 -0
  16. data/lib/bundles/inspec-supermarket/cli.rb +9 -0
  17. data/lib/bundles/inspec-supermarket/target.rb +2 -1
  18. data/lib/fetchers/local.rb +5 -2
  19. data/lib/fetchers/url.rb +1 -0
  20. data/lib/inspec/base_cli.rb +2 -1
  21. data/lib/inspec/cli.rb +14 -5
  22. data/lib/inspec/dependencies/dependency_set.rb +38 -0
  23. data/lib/inspec/dependencies/requirement.rb +103 -0
  24. data/lib/inspec/{dependencies.rb → dependencies/resolver.rb} +13 -132
  25. data/lib/inspec/dependencies/vendor_index.rb +98 -0
  26. data/lib/inspec/plugins/source_reader.rb +4 -0
  27. data/lib/inspec/profile.rb +2 -2
  28. data/lib/inspec/resource.rb +2 -0
  29. data/lib/inspec/runner.rb +13 -1
  30. data/lib/inspec/runner_mock.rb +4 -0
  31. data/lib/inspec/runner_rspec.rb +6 -2
  32. data/lib/inspec/shell.rb +22 -1
  33. data/lib/inspec/version.rb +1 -1
  34. data/lib/resources/iis_site.rb +107 -0
  35. data/lib/resources/port.rb +11 -4
  36. data/lib/resources/ssh_conf.rb +10 -2
  37. data/lib/resources/ssl.rb +94 -0
  38. data/lib/resources/xinetd.rb +11 -2
  39. data/lib/utils/parser.rb +6 -1
  40. metadata +17 -561
  41. data/lib/utils/hash_map.rb +0 -37
  42. data/tasks/maintainers.rb +0 -213
  43. data/test/bench/startup/startup.flat.txt +0 -1005
  44. data/test/bench/startup/startup.graph.html +0 -71958
  45. data/test/bench/startup/startup.grind.dat +0 -101602
  46. data/test/bench/startup/startup.stack.html +0 -24516
  47. data/test/bench/startup.flat.txt +0 -998
  48. data/test/bench/startup.graph.html +0 -71420
  49. data/test/bench/startup.grind.dat +0 -103554
  50. data/test/bench/startup.stack.html +0 -25015
  51. data/test/cookbooks/os_prepare/attributes/default.rb +0 -2
  52. data/test/cookbooks/os_prepare/files/empty.iso +0 -0
  53. data/test/cookbooks/os_prepare/files/example.csv +0 -7
  54. data/test/cookbooks/os_prepare/files/example.ini +0 -6
  55. data/test/cookbooks/os_prepare/files/example.json +0 -12
  56. data/test/cookbooks/os_prepare/files/example.yml +0 -7
  57. data/test/cookbooks/os_prepare/metadata.rb +0 -13
  58. data/test/cookbooks/os_prepare/recipes/_runit_service_centos.rb +0 -34
  59. data/test/cookbooks/os_prepare/recipes/_upstart_service_centos.rb +0 -25
  60. data/test/cookbooks/os_prepare/recipes/apache.rb +0 -14
  61. data/test/cookbooks/os_prepare/recipes/apt.rb +0 -20
  62. data/test/cookbooks/os_prepare/recipes/auditctl.rb +0 -8
  63. data/test/cookbooks/os_prepare/recipes/default.rb +0 -29
  64. data/test/cookbooks/os_prepare/recipes/file.rb +0 -46
  65. data/test/cookbooks/os_prepare/recipes/iptables.rb +0 -13
  66. data/test/cookbooks/os_prepare/recipes/json_yaml_csv_ini.rb +0 -34
  67. data/test/cookbooks/os_prepare/recipes/mount.rb +0 -33
  68. data/test/cookbooks/os_prepare/recipes/package.rb +0 -25
  69. data/test/cookbooks/os_prepare/recipes/postgres.rb +0 -20
  70. data/test/cookbooks/os_prepare/recipes/prep_container.rb +0 -15
  71. data/test/cookbooks/os_prepare/recipes/registry_key.rb +0 -87
  72. data/test/cookbooks/os_prepare/recipes/service.rb +0 -19
  73. data/test/cookbooks/os_prepare/templates/default/sv-default-svlog-run.erb +0 -2
  74. data/test/docker_run.rb +0 -162
  75. data/test/docker_test.rb +0 -58
  76. data/test/functional/helper.rb +0 -37
  77. data/test/functional/inheritance_test.rb +0 -62
  78. data/test/functional/inspec_archive_test.rb +0 -80
  79. data/test/functional/inspec_compliance_test.rb +0 -61
  80. data/test/functional/inspec_exec_json_test.rb +0 -122
  81. data/test/functional/inspec_exec_jsonmin_test.rb +0 -59
  82. data/test/functional/inspec_exec_test.rb +0 -123
  83. data/test/functional/inspec_json_profile_test.rb +0 -103
  84. data/test/functional/inspec_test.rb +0 -91
  85. data/test/helper.rb +0 -329
  86. data/test/integration/default/_debug_spec.rb +0 -8
  87. data/test/integration/default/apache_conf_spec.rb +0 -21
  88. data/test/integration/default/apt_spec.rb +0 -37
  89. data/test/integration/default/auditd_rules_spec.rb +0 -32
  90. data/test/integration/default/cmp_matcher_spec.rb +0 -115
  91. data/test/integration/default/csv_spec.rb +0 -11
  92. data/test/integration/default/etc_group_spec.rb +0 -29
  93. data/test/integration/default/file_spec.rb +0 -195
  94. data/test/integration/default/group_spec.rb +0 -59
  95. data/test/integration/default/ini_spec.rb +0 -11
  96. data/test/integration/default/iptables_spec.rb +0 -29
  97. data/test/integration/default/json_spec.rb +0 -11
  98. data/test/integration/default/kernel_module_spec.rb +0 -23
  99. data/test/integration/default/kernel_parameter_spec.rb +0 -60
  100. data/test/integration/default/mount_spec.rb +0 -19
  101. data/test/integration/default/os_spec.rb +0 -13
  102. data/test/integration/default/package_spec.rb +0 -30
  103. data/test/integration/default/port_spec.rb +0 -27
  104. data/test/integration/default/postgres_session_spec.rb +0 -13
  105. data/test/integration/default/powershell_spec.rb +0 -42
  106. data/test/integration/default/registry_key_spec.rb +0 -109
  107. data/test/integration/default/secpol_spec.rb +0 -11
  108. data/test/integration/default/service_spec.rb +0 -128
  109. data/test/integration/default/user_spec.rb +0 -96
  110. data/test/integration/default/vbscript_spec.rb +0 -22
  111. data/test/integration/default/wmi_spec.rb +0 -66
  112. data/test/integration/default/yaml_spec.rb +0 -11
  113. data/test/resource/command_test.rb +0 -33
  114. data/test/resource/dsl_test.rb +0 -45
  115. data/test/resource/file_test.rb +0 -146
  116. data/test/resource/ssh_config.rb +0 -9
  117. data/test/resource/sshd_config.rb +0 -9
  118. data/test/test-extra.yaml +0 -11
  119. data/test/test.yaml +0 -11
  120. data/test/unit/control_test.rb +0 -58
  121. data/test/unit/fetchers/local_test.rb +0 -67
  122. data/test/unit/fetchers/mock_test.rb +0 -43
  123. data/test/unit/fetchers/tar_test.rb +0 -36
  124. data/test/unit/fetchers/url_test.rb +0 -152
  125. data/test/unit/fetchers/zip_test.rb +0 -36
  126. data/test/unit/fetchers_test.rb +0 -65
  127. data/test/unit/metadata_test.rb +0 -137
  128. data/test/unit/mock/cmd/$env-PATH +0 -1
  129. data/test/unit/mock/cmd/Get-NetAdapter +0 -24
  130. data/test/unit/mock/cmd/GetUserAccount +0 -33
  131. data/test/unit/mock/cmd/GetWin32Group +0 -23
  132. data/test/unit/mock/cmd/Resolve-DnsName +0 -26
  133. data/test/unit/mock/cmd/Test-NetConnection +0 -4
  134. data/test/unit/mock/cmd/auditctl +0 -3
  135. data/test/unit/mock/cmd/auditctl-legacy +0 -7
  136. data/test/unit/mock/cmd/auditctl-s +0 -8
  137. data/test/unit/mock/cmd/auditpol +0 -2
  138. data/test/unit/mock/cmd/brew-info-jq +0 -1
  139. data/test/unit/mock/cmd/chage-l-root +0 -7
  140. data/test/unit/mock/cmd/dpkg-s-curl +0 -21
  141. data/test/unit/mock/cmd/dscl +0 -5
  142. data/test/unit/mock/cmd/env +0 -1
  143. data/test/unit/mock/cmd/etc-apt +0 -7
  144. data/test/unit/mock/cmd/find-apache2-conf-enabled +0 -1
  145. data/test/unit/mock/cmd/find-apache2-ports-conf +0 -1
  146. data/test/unit/mock/cmd/find-etc-rc-d-name-S +0 -12
  147. data/test/unit/mock/cmd/find-net-interface +0 -9
  148. data/test/unit/mock/cmd/find-xinetd.d +0 -2
  149. data/test/unit/mock/cmd/gem-list-local-a-q-rubocop +0 -1
  150. data/test/unit/mock/cmd/get-net-tcpconnection +0 -24
  151. data/test/unit/mock/cmd/get-netadapter-binding-bridge +0 -4
  152. data/test/unit/mock/cmd/get-package-firefox +0 -30
  153. data/test/unit/mock/cmd/get-package-ruby +0 -18
  154. data/test/unit/mock/cmd/get-service-dhcp +0 -10
  155. data/test/unit/mock/cmd/get-windows-feature +0 -7
  156. data/test/unit/mock/cmd/get-wmiobject +0 -9
  157. data/test/unit/mock/cmd/getent-hosts-example.com +0 -1
  158. data/test/unit/mock/cmd/getent-passwd-jfolmer +0 -1
  159. data/test/unit/mock/cmd/getent-passwd-root +0 -1
  160. data/test/unit/mock/cmd/hpux-netstat-inet +0 -10
  161. data/test/unit/mock/cmd/hpux-netstat-inet6 +0 -11
  162. data/test/unit/mock/cmd/id-chartmann +0 -1
  163. data/test/unit/mock/cmd/id-jfolmer +0 -1
  164. data/test/unit/mock/cmd/id-root +0 -1
  165. data/test/unit/mock/cmd/initctl--version +0 -5
  166. data/test/unit/mock/cmd/initctl-show-config-ssh +0 -3
  167. data/test/unit/mock/cmd/initctl-status-ssh +0 -1
  168. data/test/unit/mock/cmd/iptables-s +0 -6
  169. data/test/unit/mock/cmd/launchctl-list +0 -3
  170. data/test/unit/mock/cmd/logins-x +0 -4
  171. data/test/unit/mock/cmd/ls-1-etc-init.d +0 -2
  172. data/test/unit/mock/cmd/ls-sys-class-net-br +0 -2
  173. data/test/unit/mock/cmd/lsmod +0 -2
  174. data/test/unit/mock/cmd/lsof-nP-i-FpctPn +0 -63
  175. data/test/unit/mock/cmd/mount +0 -1
  176. data/test/unit/mock/cmd/mount-multiple +0 -2
  177. data/test/unit/mock/cmd/netstat-an.utf8 +0 -13
  178. data/test/unit/mock/cmd/netstat-tulpen +0 -6
  179. data/test/unit/mock/cmd/npm-ls-g--json-bower +0 -9
  180. data/test/unit/mock/cmd/pacman-qi-curl +0 -21
  181. data/test/unit/mock/cmd/ping-example.com +0 -6
  182. data/test/unit/mock/cmd/pip-show-jinja2 +0 -11
  183. data/test/unit/mock/cmd/pkg-info-system-file-system-zfs +0 -8
  184. data/test/unit/mock/cmd/pkginfo-l-SUNWzfsr +0 -7
  185. data/test/unit/mock/cmd/ps-aux +0 -5
  186. data/test/unit/mock/cmd/ps-auxZ +0 -3
  187. data/test/unit/mock/cmd/pw-usershow-root-7 +0 -1
  188. data/test/unit/mock/cmd/reg_schedule +0 -6
  189. data/test/unit/mock/cmd/rpm-qia-curl +0 -24
  190. data/test/unit/mock/cmd/s11-netstat-an-finet-finet6 +0 -32
  191. data/test/unit/mock/cmd/sbin_sysctl +0 -1
  192. data/test/unit/mock/cmd/secedit-export +0 -7
  193. data/test/unit/mock/cmd/service-e +0 -2
  194. data/test/unit/mock/cmd/service-sendmail-onestatus +0 -3
  195. data/test/unit/mock/cmd/service-sshd-status +0 -1
  196. data/test/unit/mock/cmd/sockstat +0 -5
  197. data/test/unit/mock/cmd/success +0 -0
  198. data/test/unit/mock/cmd/swlist-l-product +0 -1
  199. data/test/unit/mock/cmd/systemctl-show-all-dbus +0 -6
  200. data/test/unit/mock/cmd/systemctl-show-all-sshd +0 -7
  201. data/test/unit/mock/cmd/win32_product +0 -8
  202. data/test/unit/mock/cmd/yum-repolist-all +0 -52
  203. data/test/unit/mock/files/apache2.conf +0 -14
  204. data/test/unit/mock/files/auditd.conf +0 -4
  205. data/test/unit/mock/files/bond0 +0 -37
  206. data/test/unit/mock/files/etcgroup +0 -3
  207. data/test/unit/mock/files/example.csv +0 -6
  208. data/test/unit/mock/files/grub.conf +0 -21
  209. data/test/unit/mock/files/inetd.conf +0 -2
  210. data/test/unit/mock/files/kitchen.yml +0 -7
  211. data/test/unit/mock/files/limits.conf +0 -5
  212. data/test/unit/mock/files/login.defs +0 -5
  213. data/test/unit/mock/files/mysql.conf +0 -8
  214. data/test/unit/mock/files/mysql2.conf +0 -2
  215. data/test/unit/mock/files/ntp.conf +0 -5
  216. data/test/unit/mock/files/passwd +0 -2
  217. data/test/unit/mock/files/policyfile.lock.json +0 -12
  218. data/test/unit/mock/files/ports.conf +0 -6
  219. data/test/unit/mock/files/rootwrap.conf +0 -7
  220. data/test/unit/mock/files/serve-cgi-bin.conf +0 -20
  221. data/test/unit/mock/files/shadow +0 -2
  222. data/test/unit/mock/files/ssh_config +0 -5
  223. data/test/unit/mock/files/sshd_config +0 -7
  224. data/test/unit/mock/files/sysctl.conf +0 -7
  225. data/test/unit/mock/files/xinetd.conf +0 -9
  226. data/test/unit/mock/files/xinetd.d/.gitkeep +0 -0
  227. data/test/unit/mock/files/xinetd.d_chargen-dgram +0 -9
  228. data/test/unit/mock/files/xinetd.d_chargen-stream +0 -9
  229. data/test/unit/mock/profiles/complete-metadata/inspec.yml +0 -7
  230. data/test/unit/mock/profiles/complete-profile/controls/filesystem_spec.rb +0 -16
  231. data/test/unit/mock/profiles/complete-profile/inspec.yml +0 -10
  232. data/test/unit/mock/profiles/complete-profile/libraries/testlib.rb +0 -1
  233. data/test/unit/mock/profiles/empty-metadata/inspec.yml +0 -0
  234. data/test/unit/mock/profiles/legacy-complete-metadata/metadata.rb +0 -7
  235. data/test/unit/mock/profiles/legacy-complete-metadata/test/.gitkeep +0 -0
  236. data/test/unit/mock/profiles/legacy-empty-metadata/controls/.gitkeep +0 -0
  237. data/test/unit/mock/profiles/legacy-empty-metadata/metadata.rb +0 -0
  238. data/test/unit/mock/profiles/legacy-simple-metadata/metadata.rb +0 -1
  239. data/test/unit/mock/profiles/legacy-simple-metadata/test/.gitkeep +0 -0
  240. data/test/unit/mock/profiles/library/controls/filesystem_spec.rb +0 -7
  241. data/test/unit/mock/profiles/library/inspec.yml +0 -10
  242. data/test/unit/mock/profiles/library/libraries/gordonlib.rb +0 -2
  243. data/test/unit/mock/profiles/library/libraries/testlib.rb +0 -12
  244. data/test/unit/mock/profiles/resource-tiny/inspec.yml +0 -10
  245. data/test/unit/mock/profiles/resource-tiny/libraries/resource.rb +0 -3
  246. data/test/unit/mock/profiles/simple-metadata/inspec.yml +0 -1
  247. data/test/unit/mock/profiles/skippy-profile-os/controls/one.rb +0 -3
  248. data/test/unit/mock/profiles/skippy-profile-os/inspec.yml +0 -5
  249. data/test/unit/mock/profiles/spec_only/specfile.rb +0 -11
  250. data/test/unit/mock/profiles/supported_inspec/inspec.yml +0 -2
  251. data/test/unit/mock/profiles/unsupported_inspec/inspec.yml +0 -2
  252. data/test/unit/objects_test.rb +0 -65
  253. data/test/unit/plugin_test.rb +0 -44
  254. data/test/unit/plugins/resource_test.rb +0 -60
  255. data/test/unit/profile_context_test.rb +0 -345
  256. data/test/unit/profile_test.rb +0 -252
  257. data/test/unit/resources/apache_conf_test.rb +0 -31
  258. data/test/unit/resources/apt_test.rb +0 -46
  259. data/test/unit/resources/audit_policy_test.rb +0 -13
  260. data/test/unit/resources/auditd_conf_test.rb +0 -15
  261. data/test/unit/resources/auditd_rules_test.rb +0 -91
  262. data/test/unit/resources/bash_test.rb +0 -29
  263. data/test/unit/resources/bond_test.rb +0 -24
  264. data/test/unit/resources/bridge_test.rb +0 -56
  265. data/test/unit/resources/csv_test.rb +0 -35
  266. data/test/unit/resources/etc_group_test.rb +0 -37
  267. data/test/unit/resources/file_test.rb +0 -202
  268. data/test/unit/resources/gem_test.rb +0 -20
  269. data/test/unit/resources/group_test.rb +0 -96
  270. data/test/unit/resources/grub_conf_test.rb +0 -29
  271. data/test/unit/resources/host_test.rb +0 -38
  272. data/test/unit/resources/inetd_conf_test.rb +0 -15
  273. data/test/unit/resources/ini_test.rb +0 -16
  274. data/test/unit/resources/interface_test.rb +0 -54
  275. data/test/unit/resources/iptables_test.rb +0 -35
  276. data/test/unit/resources/json_test.rb +0 -36
  277. data/test/unit/resources/kernel_module_test.rb +0 -23
  278. data/test/unit/resources/kernel_parameter_test.rb +0 -13
  279. data/test/unit/resources/limits_conf_test.rb +0 -14
  280. data/test/unit/resources/login_def_test.rb +0 -16
  281. data/test/unit/resources/mount_test.rb +0 -26
  282. data/test/unit/resources/mysql_conf_test.rb +0 -14
  283. data/test/unit/resources/npm_test.rb +0 -20
  284. data/test/unit/resources/ntp_conf_test.rb +0 -16
  285. data/test/unit/resources/oneget_test.rb +0 -45
  286. data/test/unit/resources/os_env_test.rb +0 -18
  287. data/test/unit/resources/os_test.rb +0 -40
  288. data/test/unit/resources/package_test.rb +0 -87
  289. data/test/unit/resources/parse_config_test.rb +0 -26
  290. data/test/unit/resources/passwd_test.rb +0 -111
  291. data/test/unit/resources/pip_test.rb +0 -15
  292. data/test/unit/resources/port_test.rb +0 -165
  293. data/test/unit/resources/powershell_test.rb +0 -32
  294. data/test/unit/resources/processes_test.rb +0 -72
  295. data/test/unit/resources/registry_key_test.rb +0 -18
  296. data/test/unit/resources/security_policy_test.rb +0 -16
  297. data/test/unit/resources/service_test.rb +0 -305
  298. data/test/unit/resources/shadow_test.rb +0 -67
  299. data/test/unit/resources/ssh_conf_test.rb +0 -33
  300. data/test/unit/resources/user_test.rb +0 -124
  301. data/test/unit/resources/vbscript_test.rb +0 -18
  302. data/test/unit/resources/windows_feature.rb +0 -17
  303. data/test/unit/resources/wmi_test.rb +0 -42
  304. data/test/unit/resources/xinetd_test.rb +0 -60
  305. data/test/unit/resources/yaml_test.rb +0 -34
  306. data/test/unit/resources/yum_test.rb +0 -68
  307. data/test/unit/shell_detector_test.rb +0 -78
  308. data/test/unit/source_reader_test.rb +0 -17
  309. data/test/unit/source_readers/flat_test.rb +0 -61
  310. data/test/unit/source_readers/inspec_test.rb +0 -38
  311. data/test/unit/utils/filter_array_test.rb +0 -59
  312. data/test/unit/utils/filter_table_test.rb +0 -177
  313. data/test/unit/utils/find_files_test.rb +0 -23
  314. data/test/unit/utils/passwd_parser_test.rb +0 -32
  315. data/test/unit/utils/simpleconfig_test.rb +0 -80
  316. data/test/unit/utils/solaris_netstat_parser.rb +0 -124
data/lib/inspec/runner.rb CHANGED
@@ -66,6 +66,7 @@ module Inspec
66
66
  options['attributes'] = attributes
67
67
  end
68
68
 
69
+ # Returns the profile context used the profile at this target.
69
70
  def add_target(target, options = {})
70
71
  profile = Inspec::Profile.for_target(target, options)
71
72
  fail "Could not resolve #{target} to valid input." if profile.nil?
@@ -89,6 +90,7 @@ module Inspec
89
90
  true
90
91
  end
91
92
 
93
+ # Returns the profile context used to initialize this profile.
92
94
  def add_profile(profile, options = {})
93
95
  return if !options[:ignore_supports] && !supports_profile?(profile)
94
96
 
@@ -115,6 +117,8 @@ module Inspec
115
117
  Inspec::ProfileContext.new(profile_id, @backend, @conf.merge(options))
116
118
  end
117
119
 
120
+ # Returns the profile context used to evaluate the given content.
121
+ # Calling this method again will use a different context each time.
118
122
  def add_content(tests, libs, options = {})
119
123
  return if tests.nil? || tests.empty?
120
124
 
@@ -127,21 +131,29 @@ module Inspec
127
131
  profile.runner_context = ctx
128
132
  end
129
133
 
134
+ append_content(ctx, tests, libs, options)
135
+ end
136
+
137
+ # Returns the profile context used to evaluate the given content.
138
+ def append_content(ctx, tests, _libs, options = {})
130
139
  # evaluate the test content
131
140
  tests = [tests] unless tests.is_a? Array
132
141
  tests.each { |t| add_test_to_context(t, ctx) }
133
142
 
134
- # merge all collect all attributes
143
+ # merge and collect all attributes
135
144
  @attributes |= ctx.attributes
136
145
 
137
146
  # process the resulting rules
138
147
  filter_controls(ctx.rules, options[:controls]).each do |rule_id, rule|
139
148
  register_rule(rule_id, rule)
140
149
  end
150
+
151
+ ctx
141
152
  end
142
153
 
143
154
  def_delegator :@test_collector, :run
144
155
  def_delegator :@test_collector, :report
156
+ def_delegator :@test_collector, :reset
145
157
 
146
158
  private
147
159
 
@@ -7,6 +7,10 @@ module Inspec
7
7
  attr_reader :tests, :profiles
8
8
  attr_writer :backend
9
9
  def initialize
10
+ reset
11
+ end
12
+
13
+ def reset
10
14
  @tests = []
11
15
  @profiles = []
12
16
  end
@@ -15,6 +15,10 @@ module Inspec
15
15
  def initialize(conf)
16
16
  @conf = conf
17
17
  @formatter = nil
18
+ reset
19
+ end
20
+
21
+ def reset
18
22
  reset_tests
19
23
  configure_output
20
24
  end
@@ -87,8 +91,6 @@ module Inspec
87
91
  reporter.output_hash
88
92
  end
89
93
 
90
- private
91
-
92
94
  # Empty the list of registered tests.
93
95
  #
94
96
  # @return [nil]
@@ -98,6 +100,8 @@ module Inspec
98
100
  RSpec.configuration.reset
99
101
  end
100
102
 
103
+ private
104
+
101
105
  FORMATTERS = {
102
106
  'json-min' => 'InspecRspecMiniJson',
103
107
  'json' => 'InspecRspecJson',
data/lib/inspec/shell.rb CHANGED
@@ -5,6 +5,9 @@
5
5
  require 'rspec/core/formatters/base_text_formatter'
6
6
 
7
7
  module Inspec
8
+ # A pry based shell for inspec. Given a runner (with a configured backend and
9
+ # all that jazz), this shell will produce a pry shell from which you can run
10
+ # inspec/ruby commands that will be run within the context of the runner.
8
11
  class Shell
9
12
  def initialize(runner)
10
13
  @runner = runner
@@ -17,7 +20,6 @@ module Inspec
17
20
  # store context to run commands in this context
18
21
  c = { content: 'binding.pry', ref: nil, line: nil }
19
22
  @runner.add_content(c, [])
20
- @runner.run
21
23
  end
22
24
 
23
25
  def configure_pry
@@ -38,6 +40,25 @@ module Inspec
38
40
  Pry.hooks.add_hook(:before_session, :intro) do
39
41
  intro
40
42
  end
43
+
44
+ # execute describe blocks
45
+ Pry.hooks.add_hook(:after_eval, 'run_controls') do |output, _binding, _pry_|
46
+ next unless output.is_a?(Inspec::Rule)
47
+ # reset tests, register the control and execute the runner
48
+ @runner.reset
49
+ @runner.method(:register_rule).call(output.id, output)
50
+ @runner.run
51
+ end
52
+
53
+ # Don't print out control class inspection when the user uses DSL methods.
54
+ # Instead produce a result of evaluating their control.
55
+ Pry.config.print = proc do |_output, value, pry_|
56
+ next if value.is_a?(Inspec::Rule)
57
+ pry_.pager.open do |pager|
58
+ pager.print pry_.config.output_prefix
59
+ Pry::ColorPrinter.pp(value, pager, Pry::Terminal.width! - 1)
60
+ end
61
+ end
41
62
  end
42
63
 
43
64
  def readline_ignore(code)
@@ -3,5 +3,5 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  module Inspec
6
- VERSION = '0.30.0'.freeze
6
+ VERSION = '0.31.0'.freeze
7
7
  end
@@ -0,0 +1,107 @@
1
+ # encoding: utf-8
2
+ # check for site in IIS
3
+ # Usage:
4
+ # describe iis_site('Default Web Site') do
5
+ # it{ should exist }
6
+ # it{ should be_running }
7
+ # it{ should be_in_app_pool('Default App Pool') }
8
+ # it{ should have_path('C:\\inetpub\wwwroot\\DefaultWebSite') }
9
+ # it{ should have_binding('https :443:www.contoso.com sslFlags=0') }
10
+ # it{ should have_binding('net.pipe *') }
11
+ # end
12
+ #
13
+ # Note: this is only supported in windows 2012 and later
14
+
15
+ module Inspec::Resources
16
+ class IisSite < Inspec.resource(1)
17
+ name 'iis_site'
18
+ desc 'Tests IIS site configuration on windows. Supported in server 2012+ only'
19
+ example "
20
+ describe iis_site('Default Web Site') do
21
+ it { should exist }
22
+ it { should be_running }
23
+ it { should have_app_pool('DefaultAppPool') }
24
+ it { should have_binding('https :443:www.contoso.com sslFlags=0') }
25
+ it { should have_binding('net.pipe *') }
26
+ it { should have_path('C:\\inetpub\\wwwroot') }
27
+ end
28
+ "
29
+
30
+ def initialize(site_name)
31
+ @site_name = site_name
32
+ @cache = nil
33
+
34
+ @site_provider = SiteProvider.new(inspec)
35
+
36
+ # verify that this resource is only supported on Windows
37
+ return skip_resource 'The `iis_site` resource is not supported on your OS.' if inspec.os[:family] != 'windows'
38
+ end
39
+
40
+ def exists?
41
+ !iis_site.nil? && !iis_site[:name].nil?
42
+ end
43
+
44
+ def running?
45
+ iis_site.nil? ? false : (iis_site[:state] == 'Started')
46
+ end
47
+
48
+ def has_app_pool?(app_pool)
49
+ iis_site.nil? ? false : iis_site[:app_pool] == app_pool
50
+ end
51
+
52
+ def has_path?(path)
53
+ iis_site.nil? ? false : iis_site[:path] == path
54
+ end
55
+
56
+ def has_binding?(binding)
57
+ iis_site.nil? ? false : (iis_site[:bindings].include? binding)
58
+ end
59
+
60
+ def to_s
61
+ "iis_site '#{@site_name}'"
62
+ end
63
+
64
+ def iis_site
65
+ return @cache if !@cache.nil?
66
+ @cache = @site_provider.iis_site(@site_name) if !@site_provider.nil?
67
+ end
68
+ end
69
+
70
+ class SiteProvider
71
+ attr_reader :inspec
72
+
73
+ def initialize(inspec)
74
+ @inspec = inspec
75
+ end
76
+
77
+ # want to populate everything using one powershell command here and spit it out as json
78
+ def iis_site(name)
79
+ command = "Get-Website '#{name}' | select-object -Property Name,State,PhysicalPath,bindings,ApplicationPool | ConvertTo-Json"
80
+ cmd = @inspec.command(command)
81
+
82
+ begin
83
+ site = JSON.parse(cmd.stdout)
84
+ rescue JSON::ParserError => _e
85
+ return nil
86
+ end
87
+
88
+ bindings_array = site['bindings']['Collection'].map { |k, _str|
89
+ k['protocol'] <<
90
+ ' ' <<
91
+ k['bindingInformation'] <<
92
+ (k['protocol'] == 'https' ? ' sslFlags=' << flags : '')
93
+ }
94
+
95
+ # map our values to a hash table
96
+ info = {
97
+ name: site['name'],
98
+ state: site['state'],
99
+ path: site['physicalPath'],
100
+ bindings: bindings_array,
101
+ app_pool: site['applicationPool'],
102
+ }
103
+
104
+ info
105
+ end
106
+ end
107
+ end
@@ -122,13 +122,13 @@ module Inspec::Resources
122
122
  # @see https://connect.microsoft.com/PowerShell/feedback/details/1349420/get-nettcpconnection-does-not-show-processid
123
123
  class WindowsPorts < PortsInfo
124
124
  def info
125
- powershell_info || netstat_info
125
+ netstat_info || powershell_info
126
126
  end
127
127
 
128
128
  private
129
129
 
130
130
  def powershell_info
131
- cmd = inspec.command('Get-NetTCPConnection | Select-Object -Property State, Caption, Description, LocalAddress, LocalPort, RemoteAddress, RemotePort, DisplayName, Status | ConvertTo-Json')
131
+ cmd = inspec.command('Get-NetTCPConnection -state Listen | Select-Object -Property State, Caption, Description, LocalAddress, LocalPort, RemoteAddress, RemotePort, DisplayName, Status | ConvertTo-Json')
132
132
  return nil if cmd.exit_status != 0
133
133
 
134
134
  entries = JSON.parse(cmd.stdout)
@@ -146,14 +146,21 @@ module Inspec::Resources
146
146
  end
147
147
 
148
148
  def netstat_info
149
- cmd = inspec.command('netstat -an')
149
+ # retrieve processes grepping by LISTENING state with 0 lines before and 1 after to catch the process name
150
+ # also UDP ports have nothing in the State column
151
+ cmd = inspec.command('netstat -anbo | Select-String -CaseSensitive -pattern "^\s+UDP|\s+LISTENING\s+\d+$" -context 0,1')
150
152
  return nil if cmd.exit_status != 0
151
- lines = cmd.stdout.scan(/^\s*(tcp\S*|udp\S*)\s+(\S+):(\d+)\s+/i)
153
+ lines = cmd.stdout.scan(/^>\s*(tcp\S*|udp\S*)\s+(\S+):(\d+)\s+(\S+)\s+(\S*)\s+(\d+)\s+(.+)/i)
152
154
  lines.map do |line|
155
+ pid = line[5].to_i
156
+ process = line[6].delete('[').delete(']').strip
157
+ process = 'System' if process == 'Can not obtain ownership information' && pid == 4
153
158
  {
154
159
  'port' => line[2].to_i,
155
160
  'address' => line[1].delete('[').delete(']'),
156
161
  'protocol' => line[0].downcase,
162
+ 'pid' => pid,
163
+ 'process' => process,
157
164
  }
158
165
  end
159
166
  end
@@ -32,8 +32,16 @@ module Inspec::Resources
32
32
  end
33
33
  end
34
34
 
35
+ def convert_hash(hash)
36
+ new_hash = {}
37
+ hash.each do |k, v|
38
+ new_hash[k.downcase] = v
39
+ end
40
+ new_hash
41
+ end
42
+
35
43
  def method_missing(name)
36
- param = read_params[name.to_s]
44
+ param = read_params[name.to_s.downcase]
37
45
  return nil if param.nil?
38
46
  # extract first value if we have only one value in array
39
47
  return param[0] if param.length == 1
@@ -69,7 +77,7 @@ module Inspec::Resources
69
77
  assignment_re: /^\s*(\S+?)\s+(.*?)\s*$/,
70
78
  multiple_values: true,
71
79
  )
72
- @params = conf.params
80
+ @params = convert_hash(conf.params)
73
81
  end
74
82
  end
75
83
 
@@ -0,0 +1,94 @@
1
+ # encoding: utf-8
2
+ # copyright: 2015, Chef Software Inc.
3
+ # license: All rights reserved
4
+ # author: Dominik Richter
5
+ # author: Christoph Hartmann
6
+
7
+ require 'sslshake'
8
+ require 'utils/filter'
9
+
10
+ # Custom resource based on the InSpec resource DSL
11
+ class SSL < Inspec.resource(1)
12
+ name 'ssl'
13
+
14
+ desc "
15
+ SSL test resource
16
+ "
17
+
18
+ example "
19
+ describe ssl(port: 443) do
20
+ it { should be_enabled }
21
+ end
22
+
23
+ # protocols: ssl2, ssl3, tls1.0, tls1.1, tls1.2
24
+ describe ssl(port: 443).protocols('ssl2') do
25
+ it { should_not be_enabled }
26
+ end
27
+
28
+ # any ciphers, filter by name or regex
29
+ describe ssl(port: 443).ciphers(/rc4/i) do
30
+ it { should_not be_enabled }
31
+ end
32
+ "
33
+
34
+ VERSIONS = [
35
+ 'ssl2',
36
+ 'ssl3',
37
+ 'tls1.0',
38
+ 'tls1.1',
39
+ 'tls1.2',
40
+ ].freeze
41
+
42
+ attr_reader :host, :port
43
+
44
+ def initialize(opts = {})
45
+ @host = opts[:host] ||
46
+ inspec.backend.instance_variable_get(:@hostname)
47
+ if @host.nil? && inspec.backend.class.to_s == 'Train::Transports::Local::Connection'
48
+ @host = 'localhost'
49
+ end
50
+ if @host.nil?
51
+ fail 'Cannot determine host for SSL test. Please specify it or use a different target.'
52
+ end
53
+ @port = opts[:port] || 443
54
+ @timeout = opts[:timeout]
55
+ @retries = opts[:retries]
56
+ end
57
+
58
+ filter = FilterTable.create
59
+ filter.add_accessor(:where)
60
+ .add_accessor(:entries)
61
+ .add(:ciphers, field: 'cipher')
62
+ .add(:protocols, field: 'protocol')
63
+ .add(:enabled?) { |x| x.handshake.values.any? { |i| i['success'] } }
64
+ .add(:handshake) { |x|
65
+ groups = x.entries.group_by(&:protocol)
66
+ res = groups.map do |proto, e|
67
+ [proto, SSLShake.hello(x.resource.host, port: x.resource.port,
68
+ protocol: proto, ciphers: e.map(&:cipher),
69
+ timeout: @timeout, retries: @retries)]
70
+ end
71
+ Hash[res]
72
+ }
73
+ .connect(self, :scan_config)
74
+
75
+ def to_s
76
+ "SSL/TLS on #{@host}:#{@port}"
77
+ end
78
+
79
+ private
80
+
81
+ def scan_config
82
+ [
83
+ { 'protocol' => 'ssl2', 'ciphers' => SSLShake::SSLv2::CIPHERS.keys },
84
+ { 'protocol' => 'ssl3', 'ciphers' => SSLShake::TLS::SSL3_CIPHERS.keys },
85
+ { 'protocol' => 'tls1.0', 'ciphers' => SSLShake::TLS::TLS10_CIPHERS.keys },
86
+ { 'protocol' => 'tls1.1', 'ciphers' => SSLShake::TLS::TLS10_CIPHERS.keys },
87
+ { 'protocol' => 'tls1.2', 'ciphers' => SSLShake::TLS::TLS_CIPHERS.keys },
88
+ ].map do |line|
89
+ line['ciphers'].map do |cipher|
90
+ { 'protocol' => line['protocol'], 'cipher' => cipher }
91
+ end
92
+ end.flatten
93
+ end
94
+ end
@@ -66,17 +66,26 @@ module Inspec::Resources
66
66
  def read_params
67
67
  return {} if read_content.nil?
68
68
  flat_params = parse_xinetd(read_content)
69
+ # we need to map service data in order to use it with filtertable
69
70
  params = { 'services' => {} }
70
71
 
71
- # parse services that were defined:
72
+ # map services that were defined and map it to the service hash
72
73
  flat_params.each do |k, v|
73
74
  name = k[/^service (.+)$/, 1]
75
+ # its not a service, no change required
74
76
  if name.nil?
75
77
  params[k] = v
78
+ # handle service entries
76
79
  else
80
+ # store service
77
81
  params['services'][name] = v
82
+
78
83
  # add the service identifier to its parameters
79
- v.each { |service| service.params['service'] = name }
84
+ if v.is_a?(Array)
85
+ v.each { |service| service.params['service'] = name }
86
+ else
87
+ v.params['service'] = name
88
+ end
80
89
  end
81
90
  end
82
91
  params
data/lib/utils/parser.rb CHANGED
@@ -9,8 +9,9 @@ module PasswdParser
9
9
  # @return [Array] Collection of passwd entries
10
10
  def parse_passwd(content)
11
11
  content.to_s.split("\n").map do |line|
12
+ next if line[0] == '#'
12
13
  parse_passwd_line(line)
13
- end
14
+ end.compact
14
15
  end
15
16
 
16
17
  # Parse a line of /etc/passwd
@@ -178,6 +179,7 @@ module SolarisNetstatParser
178
179
  end
179
180
  end
180
181
 
182
+ # This parser for xinetd (extended Internet daemon) configuration files
181
183
  module XinetdParser
182
184
  def xinetd_include_dir(dir)
183
185
  return [] if dir.nil?
@@ -197,10 +199,12 @@ module XinetdParser
197
199
  simple_conf = []
198
200
  rest = raw
199
201
  until rest.empty?
202
+ # extract content line
200
203
  nl = rest.index("\n") || (rest.length-1)
201
204
  comment = rest.index('#') || (rest.length-1)
202
205
  dst_idx = (comment < nl) ? comment : nl
203
206
  inner_line = (dst_idx == 0) ? '' : rest[0..dst_idx-1].strip
207
+ # update unparsed content
204
208
  rest = rest[nl+1..-1]
205
209
  next if inner_line.empty?
206
210
 
@@ -212,6 +216,7 @@ module XinetdParser
212
216
  simple_conf = []
213
217
  rest = rest[rest.index("\n")+1..-1]
214
218
  elsif cur_group.nil?
219
+ # parse all included files
215
220
  others = xinetd_include_dir(inner_line[/includedir (.+)/, 1])
216
221
 
217
222
  # complex merging of included configurations, as multiple services