metasploit-model 0.24.1-java

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 (380) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +27 -0
  4. data/.rspec +4 -0
  5. data/.simplecov +38 -0
  6. data/.travis.yml +6 -0
  7. data/.yardopts +5 -0
  8. data/Gemfile +43 -0
  9. data/LICENSE +27 -0
  10. data/README.md +33 -0
  11. data/Rakefile +52 -0
  12. data/app/models/metasploit/model/association/reflection.rb +46 -0
  13. data/app/models/metasploit/model/module/ancestor/spec/template.rb +125 -0
  14. data/app/models/metasploit/model/module/class/spec/template.rb +92 -0
  15. data/app/models/metasploit/model/module/instance/spec/template.rb +97 -0
  16. data/app/models/metasploit/model/search/group/base.rb +21 -0
  17. data/app/models/metasploit/model/search/group/intersection.rb +4 -0
  18. data/app/models/metasploit/model/search/group/union.rb +4 -0
  19. data/app/models/metasploit/model/search/operation/base.rb +39 -0
  20. data/app/models/metasploit/model/search/operation/boolean.rb +36 -0
  21. data/app/models/metasploit/model/search/operation/date.rb +37 -0
  22. data/app/models/metasploit/model/search/operation/integer.rb +14 -0
  23. data/app/models/metasploit/model/search/operation/null.rb +26 -0
  24. data/app/models/metasploit/model/search/operation/set.rb +34 -0
  25. data/app/models/metasploit/model/search/operation/set/integer.rb +5 -0
  26. data/app/models/metasploit/model/search/operation/set/string.rb +5 -0
  27. data/app/models/metasploit/model/search/operation/string.rb +11 -0
  28. data/app/models/metasploit/model/search/operation/union.rb +59 -0
  29. data/app/models/metasploit/model/search/operator/association.rb +43 -0
  30. data/app/models/metasploit/model/search/operator/attribute.rb +60 -0
  31. data/app/models/metasploit/model/search/operator/base.rb +34 -0
  32. data/app/models/metasploit/model/search/operator/delegation.rb +40 -0
  33. data/app/models/metasploit/model/search/operator/deprecated/app.rb +27 -0
  34. data/app/models/metasploit/model/search/operator/deprecated/author.rb +33 -0
  35. data/app/models/metasploit/model/search/operator/deprecated/authority.rb +43 -0
  36. data/app/models/metasploit/model/search/operator/deprecated/platform.rb +45 -0
  37. data/app/models/metasploit/model/search/operator/deprecated/ref.rb +50 -0
  38. data/app/models/metasploit/model/search/operator/deprecated/text.rb +32 -0
  39. data/app/models/metasploit/model/search/operator/null.rb +44 -0
  40. data/app/models/metasploit/model/search/operator/single.rb +98 -0
  41. data/app/models/metasploit/model/search/operator/union.rb +33 -0
  42. data/app/models/metasploit/model/search/query.rb +171 -0
  43. data/app/models/metasploit/model/spec/template.rb +273 -0
  44. data/app/models/metasploit/model/visitation/visitor.rb +69 -0
  45. data/app/validators/derivation_validator.rb +17 -0
  46. data/app/validators/dynamic_length_validator.rb +45 -0
  47. data/app/validators/ip_format_validator.rb +31 -0
  48. data/app/validators/nil_validator.rb +16 -0
  49. data/app/validators/parameters_validator.rb +147 -0
  50. data/app/validators/password_is_strong_validator.rb +115 -0
  51. data/config/locales/en.yml +209 -0
  52. data/lib/metasploit/model.rb +38 -0
  53. data/lib/metasploit/model/architecture.rb +346 -0
  54. data/lib/metasploit/model/association.rb +49 -0
  55. data/lib/metasploit/model/association/error.rb +40 -0
  56. data/lib/metasploit/model/author.rb +58 -0
  57. data/lib/metasploit/model/authority.rb +134 -0
  58. data/lib/metasploit/model/authority/bid.rb +10 -0
  59. data/lib/metasploit/model/authority/cve.rb +10 -0
  60. data/lib/metasploit/model/authority/msb.rb +10 -0
  61. data/lib/metasploit/model/authority/osvdb.rb +10 -0
  62. data/lib/metasploit/model/authority/pmasa.rb +10 -0
  63. data/lib/metasploit/model/authority/secunia.rb +10 -0
  64. data/lib/metasploit/model/authority/us_cert_vu.rb +10 -0
  65. data/lib/metasploit/model/authority/waraxe.rb +31 -0
  66. data/lib/metasploit/model/authority/zdi.rb +10 -0
  67. data/lib/metasploit/model/base.rb +25 -0
  68. data/lib/metasploit/model/configuration.rb +72 -0
  69. data/lib/metasploit/model/configuration/autoload.rb +109 -0
  70. data/lib/metasploit/model/configuration/child.rb +12 -0
  71. data/lib/metasploit/model/configuration/error.rb +4 -0
  72. data/lib/metasploit/model/configuration/i18n.rb +54 -0
  73. data/lib/metasploit/model/configuration/parent.rb +50 -0
  74. data/lib/metasploit/model/configured.rb +46 -0
  75. data/lib/metasploit/model/derivation.rb +110 -0
  76. data/lib/metasploit/model/derivation/full_name.rb +25 -0
  77. data/lib/metasploit/model/email_address.rb +128 -0
  78. data/lib/metasploit/model/engine.rb +34 -0
  79. data/lib/metasploit/model/error.rb +7 -0
  80. data/lib/metasploit/model/file.rb +49 -0
  81. data/lib/metasploit/model/invalid.rb +17 -0
  82. data/lib/metasploit/model/module.rb +8 -0
  83. data/lib/metasploit/model/module/action.rb +58 -0
  84. data/lib/metasploit/model/module/ancestor.rb +494 -0
  85. data/lib/metasploit/model/module/architecture.rb +40 -0
  86. data/lib/metasploit/model/module/author.rb +47 -0
  87. data/lib/metasploit/model/module/class.rb +406 -0
  88. data/lib/metasploit/model/module/handler.rb +35 -0
  89. data/lib/metasploit/model/module/instance.rb +626 -0
  90. data/lib/metasploit/model/module/path.rb +165 -0
  91. data/lib/metasploit/model/module/platform.rb +38 -0
  92. data/lib/metasploit/model/module/rank.rb +91 -0
  93. data/lib/metasploit/model/module/reference.rb +38 -0
  94. data/lib/metasploit/model/module/stance.rb +22 -0
  95. data/lib/metasploit/model/module/target.rb +80 -0
  96. data/lib/metasploit/model/module/target/architecture.rb +42 -0
  97. data/lib/metasploit/model/module/target/platform.rb +42 -0
  98. data/lib/metasploit/model/module/type.rb +44 -0
  99. data/lib/metasploit/model/nilify_blanks.rb +53 -0
  100. data/lib/metasploit/model/platform.rb +250 -0
  101. data/lib/metasploit/model/real_pathname.rb +18 -0
  102. data/lib/metasploit/model/reference.rb +108 -0
  103. data/lib/metasploit/model/search.rb +63 -0
  104. data/lib/metasploit/model/search/association.rb +32 -0
  105. data/lib/metasploit/model/search/attribute.rb +51 -0
  106. data/lib/metasploit/model/search/operation.rb +31 -0
  107. data/lib/metasploit/model/search/operation/integer/value.rb +33 -0
  108. data/lib/metasploit/model/search/operation/string/value.rb +14 -0
  109. data/lib/metasploit/model/search/operator.rb +10 -0
  110. data/lib/metasploit/model/search/operator/help.rb +47 -0
  111. data/lib/metasploit/model/search/with.rb +40 -0
  112. data/lib/metasploit/model/spec.rb +140 -0
  113. data/lib/metasploit/model/spec/error.rb +9 -0
  114. data/lib/metasploit/model/spec/i18n_exception_handler.rb +19 -0
  115. data/lib/metasploit/model/spec/pathname_collision.rb +28 -0
  116. data/lib/metasploit/model/spec/template/write.rb +42 -0
  117. data/lib/metasploit/model/spec/temporary_pathname.rb +59 -0
  118. data/lib/metasploit/model/translation.rb +31 -0
  119. data/lib/metasploit/model/version.rb +31 -0
  120. data/lib/metasploit/model/visitation.rb +9 -0
  121. data/lib/metasploit/model/visitation/visit.rb +103 -0
  122. data/lib/tasks/yard.rake +30 -0
  123. data/metasploit-model.gemspec +39 -0
  124. data/script/rails +9 -0
  125. data/spec/app/models/metasploit/model/association/reflection_spec.rb +48 -0
  126. data/spec/app/models/metasploit/model/module/ancestor/spec/template_spec.rb +174 -0
  127. data/spec/app/models/metasploit/model/module/class/spec/template_spec.rb +222 -0
  128. data/spec/app/models/metasploit/model/module/instance/spec/template_spec.rb +201 -0
  129. data/spec/app/models/metasploit/model/search/group/base_spec.rb +5 -0
  130. data/spec/app/models/metasploit/model/search/group/intersection_spec.rb +5 -0
  131. data/spec/app/models/metasploit/model/search/group/union_spec.rb +5 -0
  132. data/spec/app/models/metasploit/model/search/operation/base_spec.rb +70 -0
  133. data/spec/app/models/metasploit/model/search/operation/boolean_spec.rb +56 -0
  134. data/spec/app/models/metasploit/model/search/operation/date_spec.rb +89 -0
  135. data/spec/app/models/metasploit/model/search/operation/integer_spec.rb +9 -0
  136. data/spec/app/models/metasploit/model/search/operation/null_spec.rb +64 -0
  137. data/spec/app/models/metasploit/model/search/operation/set/integer_spec.rb +7 -0
  138. data/spec/app/models/metasploit/model/search/operation/set/string_spec.rb +7 -0
  139. data/spec/app/models/metasploit/model/search/operation/set_spec.rb +126 -0
  140. data/spec/app/models/metasploit/model/search/operation/string_spec.rb +9 -0
  141. data/spec/app/models/metasploit/model/search/operation/union_spec.rb +124 -0
  142. data/spec/app/models/metasploit/model/search/operator/association_spec.rb +108 -0
  143. data/spec/app/models/metasploit/model/search/operator/attribute_spec.rb +104 -0
  144. data/spec/app/models/metasploit/model/search/operator/base_spec.rb +34 -0
  145. data/spec/app/models/metasploit/model/search/operator/delegation_spec.rb +108 -0
  146. data/spec/app/models/metasploit/model/search/operator/deprecated/app_spec.rb +62 -0
  147. data/spec/app/models/metasploit/model/search/operator/deprecated/author_spec.rb +161 -0
  148. data/spec/app/models/metasploit/model/search/operator/deprecated/authority_spec.rb +123 -0
  149. data/spec/app/models/metasploit/model/search/operator/deprecated/platform_spec.rb +112 -0
  150. data/spec/app/models/metasploit/model/search/operator/deprecated/ref_spec.rb +327 -0
  151. data/spec/app/models/metasploit/model/search/operator/deprecated/text_spec.rb +357 -0
  152. data/spec/app/models/metasploit/model/search/operator/null_spec.rb +41 -0
  153. data/spec/app/models/metasploit/model/search/operator/single_spec.rb +327 -0
  154. data/spec/app/models/metasploit/model/search/operator/union_spec.rb +92 -0
  155. data/spec/app/models/metasploit/model/search/query_spec.rb +742 -0
  156. data/spec/app/models/metasploit/model/spec/template_spec.rb +23 -0
  157. data/spec/app/models/metasploit/model/visitation/visitor_spec.rb +45 -0
  158. data/spec/app/validators/derivation_validator_spec.rb +92 -0
  159. data/spec/app/validators/dynamic_length_validator_spec.rb +293 -0
  160. data/spec/app/validators/ip_format_validator_spec.rb +124 -0
  161. data/spec/app/validators/nil_validator_spec.rb +69 -0
  162. data/spec/app/validators/parameters_validator_spec.rb +342 -0
  163. data/spec/app/validators/password_is_strong_validator_spec.rb +250 -0
  164. data/spec/dummy/Rakefile +7 -0
  165. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  166. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  167. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  168. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  169. data/spec/dummy/app/mailers/.gitkeep +0 -0
  170. data/spec/dummy/app/models/dummy/architecture.rb +92 -0
  171. data/spec/dummy/app/models/dummy/author.rb +15 -0
  172. data/spec/dummy/app/models/dummy/authority.rb +130 -0
  173. data/spec/dummy/app/models/dummy/email_address.rb +27 -0
  174. data/spec/dummy/app/models/dummy/module/action.rb +25 -0
  175. data/spec/dummy/app/models/dummy/module/ancestor.rb +67 -0
  176. data/spec/dummy/app/models/dummy/module/architecture.rb +19 -0
  177. data/spec/dummy/app/models/dummy/module/author.rb +28 -0
  178. data/spec/dummy/app/models/dummy/module/class.rb +69 -0
  179. data/spec/dummy/app/models/dummy/module/instance.rb +209 -0
  180. data/spec/dummy/app/models/dummy/module/path.rb +64 -0
  181. data/spec/dummy/app/models/dummy/module/platform.rb +19 -0
  182. data/spec/dummy/app/models/dummy/module/rank.rb +44 -0
  183. data/spec/dummy/app/models/dummy/module/reference.rb +19 -0
  184. data/spec/dummy/app/models/dummy/module/target.rb +62 -0
  185. data/spec/dummy/app/models/dummy/module/target/architecture.rb +19 -0
  186. data/spec/dummy/app/models/dummy/module/target/platform.rb +19 -0
  187. data/spec/dummy/app/models/dummy/platform.rb +58 -0
  188. data/spec/dummy/app/models/dummy/reference.rb +31 -0
  189. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  190. data/spec/dummy/config.ru +4 -0
  191. data/spec/dummy/config/application.rb +43 -0
  192. data/spec/dummy/config/boot.rb +10 -0
  193. data/spec/dummy/config/environment.rb +5 -0
  194. data/spec/dummy/config/environments/development.rb +27 -0
  195. data/spec/dummy/config/environments/production.rb +63 -0
  196. data/spec/dummy/config/environments/test.rb +29 -0
  197. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  198. data/spec/dummy/config/initializers/inflections.rb +15 -0
  199. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  200. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  201. data/spec/dummy/config/initializers/session_store.rb +3 -0
  202. data/spec/dummy/config/initializers/wrap_parameters.rb +9 -0
  203. data/spec/dummy/config/locales/en.yml +1 -0
  204. data/spec/dummy/config/routes.rb +2 -0
  205. data/spec/dummy/db/schema.rb +707 -0
  206. data/spec/dummy/lib/assets/.gitkeep +0 -0
  207. data/spec/dummy/log/.gitkeep +0 -0
  208. data/spec/dummy/public/404.html +26 -0
  209. data/spec/dummy/public/422.html +26 -0
  210. data/spec/dummy/public/500.html +25 -0
  211. data/spec/dummy/public/favicon.ico +0 -0
  212. data/spec/dummy/script/rails +6 -0
  213. data/spec/dummy/spec/factories/dummy/architectures.rb +13 -0
  214. data/spec/dummy/spec/factories/dummy/authorities.rb +32 -0
  215. data/spec/dummy/spec/factories/dummy/authors.rb +8 -0
  216. data/spec/dummy/spec/factories/dummy/email_addresses.rb +8 -0
  217. data/spec/dummy/spec/factories/dummy/module/actions.rb +13 -0
  218. data/spec/dummy/spec/factories/dummy/module/ancestors.rb +45 -0
  219. data/spec/dummy/spec/factories/dummy/module/architectures.rb +35 -0
  220. data/spec/dummy/spec/factories/dummy/module/authors.rb +10 -0
  221. data/spec/dummy/spec/factories/dummy/module/classes.rb +40 -0
  222. data/spec/dummy/spec/factories/dummy/module/instances.rb +86 -0
  223. data/spec/dummy/spec/factories/dummy/module/paths.rb +16 -0
  224. data/spec/dummy/spec/factories/dummy/module/platforms.rb +35 -0
  225. data/spec/dummy/spec/factories/dummy/module/ranks.rb +14 -0
  226. data/spec/dummy/spec/factories/dummy/module/references.rb +17 -0
  227. data/spec/dummy/spec/factories/dummy/module/target/architectures.rb +40 -0
  228. data/spec/dummy/spec/factories/dummy/module/target/platforms.rb +41 -0
  229. data/spec/dummy/spec/factories/dummy/module/targets.rb +46 -0
  230. data/spec/dummy/spec/factories/dummy/platforms.rb +3 -0
  231. data/spec/dummy/spec/factories/dummy/references.rb +26 -0
  232. data/spec/factories/metasploit/model/architectures.rb +6 -0
  233. data/spec/factories/metasploit/model/association/reflections.rb +9 -0
  234. data/spec/factories/metasploit/model/authorities.rb +28 -0
  235. data/spec/factories/metasploit/model/authors.rb +9 -0
  236. data/spec/factories/metasploit/model/bases.rb +10 -0
  237. data/spec/factories/metasploit/model/email_addresses.rb +14 -0
  238. data/spec/factories/metasploit/model/module/actions.rb +9 -0
  239. data/spec/factories/metasploit/model/module/ancestors.rb +180 -0
  240. data/spec/factories/metasploit/model/module/architectures.rb +15 -0
  241. data/spec/factories/metasploit/model/module/classes.rb +47 -0
  242. data/spec/factories/metasploit/model/module/handlers.rb +3 -0
  243. data/spec/factories/metasploit/model/module/instances.rb +83 -0
  244. data/spec/factories/metasploit/model/module/paths.rb +51 -0
  245. data/spec/factories/metasploit/model/module/platforms.rb +15 -0
  246. data/spec/factories/metasploit/model/module/ranks.rb +9 -0
  247. data/spec/factories/metasploit/model/module/references.rb +11 -0
  248. data/spec/factories/metasploit/model/module/stances.rb +3 -0
  249. data/spec/factories/metasploit/model/module/targets.rb +22 -0
  250. data/spec/factories/metasploit/model/module/types.rb +5 -0
  251. data/spec/factories/metasploit/model/references.rb +88 -0
  252. data/spec/factories/metasploit/model/search/operator/associations.rb +5 -0
  253. data/spec/factories/metasploit/model/search/operator/attributes.rb +7 -0
  254. data/spec/factories/metasploit/model/search/operator/bases.rb +5 -0
  255. data/spec/lib/metasploit/model/architecture_spec.rb +52 -0
  256. data/spec/lib/metasploit/model/association/error_spec.rb +48 -0
  257. data/spec/lib/metasploit/model/association_spec.rb +145 -0
  258. data/spec/lib/metasploit/model/author_spec.rb +6 -0
  259. data/spec/lib/metasploit/model/authority/bid_spec.rb +17 -0
  260. data/spec/lib/metasploit/model/authority/cve_spec.rb +17 -0
  261. data/spec/lib/metasploit/model/authority/msb_spec.rb +17 -0
  262. data/spec/lib/metasploit/model/authority/osvdb_spec.rb +17 -0
  263. data/spec/lib/metasploit/model/authority/pmasa_spec.rb +17 -0
  264. data/spec/lib/metasploit/model/authority/secunia_spec.rb +17 -0
  265. data/spec/lib/metasploit/model/authority/us_cert_vu_spec.rb +17 -0
  266. data/spec/lib/metasploit/model/authority/waraxe_spec.rb +51 -0
  267. data/spec/lib/metasploit/model/authority/zdi_spec.rb +21 -0
  268. data/spec/lib/metasploit/model/authority_spec.rb +10 -0
  269. data/spec/lib/metasploit/model/base_spec.rb +58 -0
  270. data/spec/lib/metasploit/model/configuration/autoload_spec.rb +165 -0
  271. data/spec/lib/metasploit/model/configuration/child_spec.rb +24 -0
  272. data/spec/lib/metasploit/model/configuration/error_spec.rb +5 -0
  273. data/spec/lib/metasploit/model/configuration/i18n_spec.rb +103 -0
  274. data/spec/lib/metasploit/model/configuration_spec.rb +106 -0
  275. data/spec/lib/metasploit/model/configured_spec.rb +41 -0
  276. data/spec/lib/metasploit/model/derivation/full_name_spec.rb +75 -0
  277. data/spec/lib/metasploit/model/derivation_spec.rb +217 -0
  278. data/spec/lib/metasploit/model/email_address_spec.rb +19 -0
  279. data/spec/lib/metasploit/model/engine_spec.rb +84 -0
  280. data/spec/lib/metasploit/model/file_spec.rb +43 -0
  281. data/spec/lib/metasploit/model/invalid_spec.rb +54 -0
  282. data/spec/lib/metasploit/model/module/action_spec.rb +6 -0
  283. data/spec/lib/metasploit/model/module/ancestor_spec.rb +6 -0
  284. data/spec/lib/metasploit/model/module/architecture_spec.rb +9 -0
  285. data/spec/lib/metasploit/model/module/author_spec.rb +6 -0
  286. data/spec/lib/metasploit/model/module/class_spec.rb +19 -0
  287. data/spec/lib/metasploit/model/module/handler_spec.rb +61 -0
  288. data/spec/lib/metasploit/model/module/instance_spec.rb +183 -0
  289. data/spec/lib/metasploit/model/module/path_spec.rb +6 -0
  290. data/spec/lib/metasploit/model/module/platform_spec.rb +9 -0
  291. data/spec/lib/metasploit/model/module/rank_spec.rb +29 -0
  292. data/spec/lib/metasploit/model/module/reference_spec.rb +9 -0
  293. data/spec/lib/metasploit/model/module/stance_spec.rb +30 -0
  294. data/spec/lib/metasploit/model/module/target/architecture_spec.rb +9 -0
  295. data/spec/lib/metasploit/model/module/target/platform_spec.rb +9 -0
  296. data/spec/lib/metasploit/model/module/target_spec.rb +9 -0
  297. data/spec/lib/metasploit/model/module/type_spec.rb +125 -0
  298. data/spec/lib/metasploit/model/nilify_blanks_spec.rb +156 -0
  299. data/spec/lib/metasploit/model/platform_spec.rb +100 -0
  300. data/spec/lib/metasploit/model/reference_spec.rb +21 -0
  301. data/spec/lib/metasploit/model/search/association_spec.rb +33 -0
  302. data/spec/lib/metasploit/model/search/attribute_spec.rb +99 -0
  303. data/spec/lib/metasploit/model/search/operation/integer/value_spec.rb +20 -0
  304. data/spec/lib/metasploit/model/search/operation/string/value_spec.rb +20 -0
  305. data/spec/lib/metasploit/model/search/operation_spec.rb +144 -0
  306. data/spec/lib/metasploit/model/search/operator/help_spec.rb +41 -0
  307. data/spec/lib/metasploit/model/search/with_spec.rb +81 -0
  308. data/spec/lib/metasploit/model/search_spec.rb +230 -0
  309. data/spec/lib/metasploit/model/spec/error_spec.rb +5 -0
  310. data/spec/lib/metasploit/model/spec/i18n_exception_handler_spec.rb +42 -0
  311. data/spec/lib/metasploit/model/spec/pathname_collision_spec.rb +55 -0
  312. data/spec/lib/metasploit/model/spec_spec.rb +114 -0
  313. data/spec/lib/metasploit/model/translation_spec.rb +82 -0
  314. data/spec/lib/metasploit/model/version_spec.rb +141 -0
  315. data/spec/lib/metasploit/model/visitation/visit_spec.rb +316 -0
  316. data/spec/lib/metasploit/model_spec.rb +68 -0
  317. data/spec/spec_helper.rb +48 -0
  318. data/spec/support/shared/contexts/metasploit/model/configuration.rb +11 -0
  319. data/spec/support/shared/contexts/metasploit/model/module/ancestor/contents/metasploit_module.rb +12 -0
  320. data/spec/support/shared/contexts/metasploit/model/module/ancestor/factory/contents.rb +10 -0
  321. data/spec/support/shared/contexts/metasploit/model/module/ancestor/factory/contents/metasploit_module.rb +15 -0
  322. data/spec/support/shared/contexts/metasploit/model/search/operator/union/children.rb +13 -0
  323. data/spec/support/shared/examples/derives.rb +115 -0
  324. data/spec/support/shared/examples/metasploit/model/architecture.rb +425 -0
  325. data/spec/support/shared/examples/metasploit/model/architecture/seed.rb +25 -0
  326. data/spec/support/shared/examples/metasploit/model/author.rb +27 -0
  327. data/spec/support/shared/examples/metasploit/model/authority.rb +124 -0
  328. data/spec/support/shared/examples/metasploit/model/authority/seed.rb +49 -0
  329. data/spec/support/shared/examples/metasploit/model/configuration/parent/child.rb +60 -0
  330. data/spec/support/shared/examples/metasploit/model/email_address.rb +220 -0
  331. data/spec/support/shared/examples/metasploit/model/module/action.rb +26 -0
  332. data/spec/support/shared/examples/metasploit/model/module/ancestor.rb +2004 -0
  333. data/spec/support/shared/examples/metasploit/model/module/ancestor/payload_factory.rb +63 -0
  334. data/spec/support/shared/examples/metasploit/model/module/architecture.rb +36 -0
  335. data/spec/support/shared/examples/metasploit/model/module/author.rb +29 -0
  336. data/spec/support/shared/examples/metasploit/model/module/class.rb +1514 -0
  337. data/spec/support/shared/examples/metasploit/model/module/handler.rb +21 -0
  338. data/spec/support/shared/examples/metasploit/model/module/instance.rb +1384 -0
  339. data/spec/support/shared/examples/metasploit/model/module/instance/class_methods.rb +537 -0
  340. data/spec/support/shared/examples/metasploit/model/module/instance/is_not_stanced_with_module_type.rb +22 -0
  341. data/spec/support/shared/examples/metasploit/model/module/instance/is_stanced_with_module_type.rb +38 -0
  342. data/spec/support/shared/examples/metasploit/model/module/instance/validates/dynamic_length_of.rb +131 -0
  343. data/spec/support/shared/examples/metasploit/model/module/path.rb +493 -0
  344. data/spec/support/shared/examples/metasploit/model/module/platform.rb +36 -0
  345. data/spec/support/shared/examples/metasploit/model/module/rank.rb +92 -0
  346. data/spec/support/shared/examples/metasploit/model/module/reference.rb +16 -0
  347. data/spec/support/shared/examples/metasploit/model/module/target.rb +29 -0
  348. data/spec/support/shared/examples/metasploit/model/module/target/architecture.rb +56 -0
  349. data/spec/support/shared/examples/metasploit/model/module/target/platform.rb +56 -0
  350. data/spec/support/shared/examples/metasploit/model/platform.rb +213 -0
  351. data/spec/support/shared/examples/metasploit/model/real_pathname.rb +29 -0
  352. data/spec/support/shared/examples/metasploit/model/reference.rb +410 -0
  353. data/spec/support/shared/examples/metasploit/model/search/operation/integer/value.rb +79 -0
  354. data/spec/support/shared/examples/metasploit/model/search/operation/string/value.rb +53 -0
  355. data/spec/support/shared/examples/metasploit/model/search/operator/help.rb +134 -0
  356. data/spec/support/shared/examples/metasploit/model/translation.rb +37 -0
  357. data/spec/support/shared/examples/search/query.rb +43 -0
  358. data/spec/support/shared/examples/search/query/metasploit/model/search/operator/deprecated/app.rb +44 -0
  359. data/spec/support/shared/examples/search/query/metasploit/model/search/operator/deprecated/authority.rb +60 -0
  360. data/spec/support/shared/examples/search_association.rb +13 -0
  361. data/spec/support/shared/examples/search_attribute.rb +27 -0
  362. data/spec/support/shared/examples/search_with.rb +36 -0
  363. data/spec/support/shared/matchers/allow_attribute.rb +17 -0
  364. data/spec/support/templates/metasploit/model/module/ancestors/_attributes.rb.erb +9 -0
  365. data/spec/support/templates/metasploit/model/module/ancestors/_methods.rb.erb +8 -0
  366. data/spec/support/templates/metasploit/model/module/ancestors/_validations.rb.erb +6 -0
  367. data/spec/support/templates/metasploit/model/module/ancestors/base.rb.erb +3 -0
  368. data/spec/support/templates/metasploit/model/module/ancestors/module_types/_auxiliary.rb.erb +1 -0
  369. data/spec/support/templates/metasploit/model/module/ancestors/module_types/_encoder.rb.erb +1 -0
  370. data/spec/support/templates/metasploit/model/module/ancestors/module_types/_exploit.rb.erb +1 -0
  371. data/spec/support/templates/metasploit/model/module/ancestors/module_types/_non_payload.rb.erb +5 -0
  372. data/spec/support/templates/metasploit/model/module/ancestors/module_types/_nop.rb.erb +1 -0
  373. data/spec/support/templates/metasploit/model/module/ancestors/module_types/_payload.rb.erb +4 -0
  374. data/spec/support/templates/metasploit/model/module/ancestors/module_types/_post.rb.erb +1 -0
  375. data/spec/support/templates/metasploit/model/module/ancestors/payload_types/_handled.rb.erb +20 -0
  376. data/spec/support/templates/metasploit/model/module/ancestors/payload_types/_single.rb.erb +1 -0
  377. data/spec/support/templates/metasploit/model/module/ancestors/payload_types/_stage.rb.erb +0 -0
  378. data/spec/support/templates/metasploit/model/module/ancestors/payload_types/_stager.rb.erb +1 -0
  379. data/spec/support/templates/metasploit/model/module/classes/_methods.rb.erb +9 -0
  380. metadata +747 -0
@@ -0,0 +1,26 @@
1
+ Metasploit::Model::Spec.shared_examples_for 'Module::Action' do
2
+ context 'factories' do
3
+ context module_action_factory do
4
+ let(module_action_factory) do
5
+ FactoryGirl.build(module_action_factory)
6
+ end
7
+
8
+ it { should be_valid }
9
+ end
10
+ end
11
+
12
+ context 'mass assignment security' do
13
+ it { should allow_mass_assignment_of(:name) }
14
+ end
15
+
16
+ context 'search' do
17
+ context 'attributes' do
18
+ it_should_behave_like 'search_attribute', :name, :type => :string
19
+ end
20
+ end
21
+
22
+ context 'validations' do
23
+ it { should validate_presence_of(:module_instance) }
24
+ it { should validate_presence_of(:name) }
25
+ end
26
+ end
@@ -0,0 +1,2004 @@
1
+ Metasploit::Model::Spec.shared_examples_for 'Module::Ancestor' do
2
+ #
3
+ # Module::Ancestor factories
4
+ #
5
+
6
+ payload_module_ancestor_factory = "payload_#{module_ancestor_factory}".to_sym
7
+ single_payload_module_ancestor_factory = "single_#{payload_module_ancestor_factory}".to_sym
8
+ stage_payload_module_ancestor_factory = "stage_#{payload_module_ancestor_factory}".to_sym
9
+ stager_payload_module_ancestor_factory = "stager_#{payload_module_ancestor_factory}".to_sym
10
+
11
+ #
12
+ # Module::Path factories
13
+ #
14
+
15
+ module_path_factory = "#{factory_namespace}_module_path".to_sym
16
+
17
+ it_should_behave_like 'Metasploit::Model::RealPathname' do
18
+ let(:base_instance) do
19
+ FactoryGirl.build(module_ancestor_factory)
20
+ end
21
+ end
22
+
23
+ context 'CONSTANTS' do
24
+ context 'DIRECTORY_BY_MODULE_TYPE' do
25
+ subject(:directory_by_module_type) do
26
+ described_class::DIRECTORY_BY_MODULE_TYPE
27
+ end
28
+
29
+ its(['auxiliary']) { should == 'auxiliary' }
30
+ its(['encoder']) { should == 'encoders' }
31
+ its(['exploit']) { should == 'exploits' }
32
+ its(['nop']) { should == 'nops' }
33
+ its(['payload']) { should == 'payloads' }
34
+ its(['post']) { should == 'post' }
35
+
36
+ it 'should have same module types as Metasploit::Model::Module::Type::ALL' do
37
+ directory_by_module_type.keys.should =~ Metasploit::Model::Module::Type::ALL
38
+ end
39
+ end
40
+
41
+ context 'EXTENSION' do
42
+ subject(:extension) do
43
+ described_class::EXTENSION
44
+ end
45
+
46
+ it 'should be ruby source extension' do
47
+ extension.should == '.rb'
48
+ end
49
+
50
+ it "should start with '.'" do
51
+ extension.should start_with('.')
52
+ end
53
+ end
54
+
55
+ context 'HANDLED_TYPES' do
56
+ subject(:handled_types) do
57
+ described_class::HANDLED_TYPES
58
+ end
59
+
60
+ it { should include('single') }
61
+ it { should_not include('stage') }
62
+ it { should include('stager') }
63
+
64
+ it 'should be a subset of PAYLOAD_TYPES' do
65
+ handled_type_set = Set.new(handled_types)
66
+ payload_type_set = Set.new(described_class::PAYLOAD_TYPES)
67
+
68
+ handled_type_set.should be_a_subset(payload_type_set)
69
+ end
70
+ end
71
+
72
+ context 'MODULE_TYPE_BY_DIRECTORY' do
73
+ subject(:module_type_by_directory) do
74
+ described_class::MODULE_TYPE_BY_DIRECTORY
75
+ end
76
+
77
+ its(['auxiliary']) { should == 'auxiliary' }
78
+ its(['encoders']) { should == 'encoder' }
79
+ its(['exploits']) { should == 'exploit' }
80
+ its(['nops']) { should == 'nop' }
81
+ its(['payloads']) { should == 'payload' }
82
+ its(['post']) { should == 'post' }
83
+
84
+ it 'should have same module types as Metasploit::Model::Module::Type::ALL' do
85
+ module_type_by_directory.values.should =~ Metasploit::Model::Module::Type::ALL
86
+ end
87
+ end
88
+
89
+ context 'PAYLOAD_TYPES' do
90
+ subject(:payload_types) do
91
+ described_class::PAYLOAD_TYPES
92
+ end
93
+
94
+ it { should include('single') }
95
+ it { should include('stage') }
96
+ it { should include('stager') }
97
+ end
98
+
99
+ # pattern is tested in validation tests below
100
+ it 'should define REFERENCE_NAME_REGEXP' do
101
+ described_class::REFERENCE_NAME_REGEXP.should be_a Regexp
102
+ end
103
+
104
+ context 'REFERENCE_NAME_SEPARATOR' do
105
+ subject(:reference_name_separator) do
106
+ described_class::REFERENCE_NAME_SEPARATOR
107
+ end
108
+
109
+ it { should == '/' }
110
+ end
111
+
112
+ # pattern is tested in validation tests below
113
+ it 'should define SHA_HEX_DIGEST_REGEXP' do
114
+ described_class::SHA1_HEX_DIGEST_REGEXP.should be_a Regexp
115
+ end
116
+ end
117
+
118
+ context 'derivation' do
119
+ def attribute_type(attribute)
120
+ type_by_attribute = {
121
+ :full_name => :text,
122
+ :module_type => :string,
123
+ :payload_type => :string,
124
+ :real_path => :text,
125
+ :real_path_modified_at => :datetime,
126
+ :real_path_sha1_hex_digest => :string,
127
+ :reference_name => :text
128
+ }
129
+
130
+ type_by_attribute.fetch(attribute)
131
+ end
132
+
133
+ it_should_behave_like 'derives', :full_name, :validates => true
134
+ it_should_behave_like 'derives', :real_path, :validates => true
135
+
136
+ context 'with only module_path and real_path' do
137
+ subject(:module_ancestor) do
138
+ # make sure real_path is derived
139
+ real_path_creator.should be_valid
140
+
141
+ module_ancestor = module_ancestor_class.new
142
+
143
+ # work-around mass-assignment security
144
+ module_ancestor.parent_path = real_path_creator.parent_path
145
+ module_ancestor.real_path = real_path_creator.real_path
146
+
147
+ module_ancestor
148
+ end
149
+
150
+ before(:each) do
151
+ # run before validation callbacks to trigger derivations
152
+ module_ancestor.valid?
153
+ end
154
+
155
+ context 'with payload' do
156
+ let(:real_path_creator) do
157
+ FactoryGirl.build(
158
+ module_ancestor_factory,
159
+ module_type: 'payload',
160
+ payload_type: payload_type
161
+ )
162
+ end
163
+
164
+ context 'with single' do
165
+ let(:payload_type) do
166
+ 'single'
167
+ end
168
+
169
+ it 'should be handled' do
170
+ module_ancestor.should be_handled
171
+ end
172
+
173
+ it { should_not be_valid }
174
+
175
+ it 'should be valid for loading' do
176
+ module_ancestor.valid?(:loading)
177
+ end
178
+ end
179
+
180
+ context 'with stage' do
181
+ let(:payload_type) do
182
+ 'stage'
183
+ end
184
+
185
+ it 'should not be handled' do
186
+ module_ancestor.should_not be_handled
187
+ end
188
+
189
+ it { should be_valid }
190
+
191
+ it 'should be valid for loading' do
192
+ module_ancestor.valid?(:loading)
193
+ end
194
+ end
195
+
196
+ context 'with stager' do
197
+ let(:payload_type) do
198
+ 'stager'
199
+ end
200
+
201
+ it 'should be handled' do
202
+ module_ancestor.should be_handled
203
+ end
204
+
205
+ it { should_not be_valid }
206
+
207
+ it 'should be valid for loading' do
208
+ module_ancestor.valid?(:loading)
209
+ end
210
+ end
211
+ end
212
+
213
+ context 'without payload' do
214
+ let(:real_path_creator) do
215
+ FactoryGirl.build(
216
+ module_ancestor_factory,
217
+ module_type: module_type
218
+ )
219
+ end
220
+
221
+ let(:module_type) do
222
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
223
+ end
224
+
225
+ it 'should not be handled' do
226
+ module_ancestor.should_not be_handled
227
+ end
228
+
229
+ it { should be_valid }
230
+
231
+ it 'should be valid for loading' do
232
+ module_ancestor.valid?(:loading)
233
+ end
234
+ end
235
+ end
236
+
237
+ context 'with payload' do
238
+ subject(:module_ancestor) do
239
+ FactoryGirl.build(
240
+ module_ancestor_factory,
241
+ # {Mdm::Module::Ancestor#derived_payload_type} will be `nil` unless {Mdm::Module::Ancestor#module_type} is
242
+ # `'payload'`
243
+ :module_type => 'payload',
244
+ # Ensure {Mdm::Module::Ancestor#derived_payload} will be a valid {Mdm::Module::Ancestor#payload_type}.
245
+ :reference_name => reference_name
246
+ )
247
+ end
248
+
249
+ let(:reference_name) do
250
+ FactoryGirl.generate :metasploit_model_module_ancestor_payload_reference_name
251
+ end
252
+
253
+ it_should_behave_like 'derives', :payload_type, :validates => true
254
+ end
255
+
256
+ context 'with real_path' do
257
+ before(:each) do
258
+ # {Metasploit::Model::Module::Ancestor#derived_real_path_modified_at} and
259
+ # {Metasploit::Model::Module::Ancestor#derived_real_path_sha1_hex_digest} both depend on real_path being
260
+ # populated or they will return nil, so need set real_path = derived_real_path before testing as would happen
261
+ # with the normal order of before validation callbacks.
262
+ module_ancestor.real_path = module_ancestor.derived_real_path
263
+
264
+ # blank out {Metasploit::Model::Module::Ancestor#module_type} and
265
+ # {Metasploit::Model::Module::Ancestor#reference_name} so they will be rederived from
266
+ # {Metasploit::Model::Module::Ancestor#real_path} to simulate module cache construction usage.
267
+ module_ancestor.module_type = nil
268
+ module_ancestor.reference_name = nil
269
+ end
270
+
271
+ it_should_behave_like 'derives', :module_type, :validates => false
272
+ it_should_behave_like 'derives', :real_path_modified_at, :validates => false
273
+ it_should_behave_like 'derives', :real_path_sha1_hex_digest, :validates => false
274
+ it_should_behave_like 'derives', :reference_name, :validates => false
275
+ end
276
+ end
277
+
278
+ context 'factories' do
279
+ context module_ancestor_factory.to_s do
280
+ subject(module_ancestor_factory) do
281
+ FactoryGirl.build(module_ancestor_factory)
282
+ end
283
+
284
+ it { should be_valid }
285
+
286
+ context 'contents' do
287
+ include_context 'Metasploit::Model::Module::Ancestor factory contents'
288
+
289
+ let(:module_ancestor) do
290
+ send(module_ancestor_factory)
291
+ end
292
+
293
+ context 'metasploit_module' do
294
+ include_context 'Metasploit::Model::Module::Ancestor factory contents metasploit_module'
295
+
296
+ # Classes are Modules, so this checks that it is either a Class or a Module.
297
+ it { should be_a Module }
298
+
299
+ context '#module_type' do
300
+ let(:module_ancestor) do
301
+ FactoryGirl.build(
302
+ module_ancestor_factory,
303
+ module_type: module_type
304
+ )
305
+ end
306
+
307
+ context 'with payload' do
308
+ let(:module_type) do
309
+ Metasploit::Model::Module::Type::PAYLOAD
310
+ end
311
+
312
+ it { should_not be_a Class }
313
+
314
+ it 'should define #initalize that takes an option hash' do
315
+ begin
316
+ unbound_method = metasploit_module.instance_method(:initialize)
317
+ rescue NameError
318
+ unbound_method = nil
319
+ end
320
+
321
+ unbound_method.should_not be_nil
322
+ unbound_method.should have(1).parameters
323
+ unbound_method.parameters[0][0].should == :opt
324
+ end
325
+ end
326
+
327
+ context 'without payload' do
328
+ let(:module_type) do
329
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
330
+ end
331
+
332
+ it { should be_a Class }
333
+
334
+ context '#initialize' do
335
+ subject(:instance) do
336
+ metasploit_module.new(attributes)
337
+ end
338
+
339
+ context 'with :framework' do
340
+ let(:attributes) do
341
+ {
342
+ framework: framework
343
+ }
344
+ end
345
+
346
+ let(:framework) do
347
+ double('Msf::Framework')
348
+ end
349
+
350
+ it 'should set #framework' do
351
+ instance.framework.should == framework
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end
359
+ end
360
+
361
+ context payload_module_ancestor_factory.to_s do
362
+ subject(payload_module_ancestor_factory) do
363
+ FactoryGirl.build(payload_module_ancestor_factory)
364
+ end
365
+
366
+ it { should be_valid }
367
+
368
+ its(:derived_payload_type) { should_not be_nil }
369
+
370
+ it_should_behave_like 'Metasploit::Model::Module::Ancestor payload factory' do
371
+ let(:module_ancestor) do
372
+ send(payload_module_ancestor_factory)
373
+ end
374
+ end
375
+ end
376
+
377
+ context single_payload_module_ancestor_factory.to_s do
378
+ subject(single_payload_module_ancestor_factory) do
379
+ FactoryGirl.build(single_payload_module_ancestor_factory)
380
+ end
381
+
382
+ it { should be_valid }
383
+
384
+ its(:derived_payload_type) { should == 'single' }
385
+
386
+ it_should_behave_like 'Metasploit::Model::Module::Ancestor payload factory', handler_type: true do
387
+ let(:module_ancestor) do
388
+ send(single_payload_module_ancestor_factory)
389
+ end
390
+ end
391
+ end
392
+
393
+ context stage_payload_module_ancestor_factory.to_s do
394
+ subject(stage_payload_module_ancestor_factory) do
395
+ FactoryGirl.build(stage_payload_module_ancestor_factory)
396
+ end
397
+
398
+ it { should be_valid }
399
+
400
+ its(:derived_payload_type) { should == 'stage' }
401
+
402
+ it_should_behave_like 'Metasploit::Model::Module::Ancestor payload factory', handler_type: false do
403
+ let(:module_ancestor) do
404
+ send(stage_payload_module_ancestor_factory)
405
+ end
406
+ end
407
+ end
408
+
409
+ context 'stager_payload_module_ancestor_factory' do
410
+ subject(stager_payload_module_ancestor_factory) do
411
+ FactoryGirl.build(stager_payload_module_ancestor_factory)
412
+ end
413
+
414
+ it { should be_valid }
415
+
416
+ its(:derived_payload_type) { should == 'stager' }
417
+
418
+ it_should_behave_like 'Metasploit::Model::Module::Ancestor payload factory', handler_type: true do
419
+ let(:module_ancestor) do
420
+ send(stager_payload_module_ancestor_factory)
421
+ end
422
+ end
423
+ end
424
+ end
425
+
426
+ context 'mass assignment security' do
427
+ it 'should not allow mass assignment of full_name since it must match derived_full_name' do
428
+ module_ancestor.should_not allow_mass_assignment_of(:full_name)
429
+ end
430
+
431
+ it { should allow_mass_assignment_of(:handler_type) }
432
+ it { should allow_mass_assignment_of(:module_type) }
433
+
434
+ it 'should not allow mass assignment of payload_type since it must match derived_payload_type' do
435
+ module_ancestor.should_not allow_mass_assignment_of(:payload_type)
436
+ end
437
+
438
+ it 'should allow mass assignment of real_path to allow derivation of module_type and reference_name' do
439
+ module_ancestor.should allow_mass_assignment_of(:real_path)
440
+ end
441
+
442
+ it 'should not allow mass assignment of real_path_modified_at since it is derived' do
443
+ module_ancestor.should_not allow_mass_assignment_of(:real_path_modified_at)
444
+ end
445
+
446
+ it 'should not allow mass assignment of real_path_sha1_hex_digest since it is derived' do
447
+ module_ancestor.should_not allow_mass_assignment_of(:real_path_sha1_hex_digest)
448
+ end
449
+
450
+ it { should_not allow_mass_assignment_of(:parent_path_id) }
451
+ end
452
+
453
+ context 'validations' do
454
+ subject(:module_ancestor) do
455
+ # Don't use factory so that nil values can be tested without the nil being replaced with derived value
456
+ module_ancestor_class.new
457
+ end
458
+
459
+ context 'handler_type' do
460
+ subject(:module_ancestor) do
461
+ FactoryGirl.build(
462
+ module_ancestor_factory,
463
+ :handler_type => handler_type,
464
+ :module_type => module_type,
465
+ :payload_type => payload_type
466
+ )
467
+ end
468
+
469
+ context 'with payload' do
470
+ let(:module_type) do
471
+ 'payload'
472
+ end
473
+
474
+ context 'with payload_type' do
475
+ context 'single' do
476
+ let(:payload_type) do
477
+ 'single'
478
+ end
479
+
480
+ context 'with handler_type' do
481
+ let(:handler_type) do
482
+ FactoryGirl.generate :metasploit_model_module_handler_type
483
+ end
484
+
485
+ it { should be_valid }
486
+ end
487
+
488
+ context 'without handler_type' do
489
+ let(:handler_type) do
490
+ nil
491
+ end
492
+
493
+ context 'with :loading validation_context' do
494
+ let(:validation_context) do
495
+ :loading
496
+ end
497
+
498
+ it 'should be valid' do
499
+ module_ancestor.valid?(validation_context).should be_true
500
+ end
501
+ end
502
+
503
+ context 'without validation_context' do
504
+ it { should_not be_valid }
505
+
506
+ it 'should record error on handler_type' do
507
+ module_ancestor.valid?
508
+
509
+ module_ancestor.errors[:handler_type].should include(I18n.translate!('errors.messages.blank'))
510
+ end
511
+ end
512
+ end
513
+ end
514
+
515
+ context 'stage' do
516
+ let(:payload_type) do
517
+ 'stage'
518
+ end
519
+
520
+ context 'with handler_type' do
521
+ let(:handler_type) do
522
+ FactoryGirl.generate :metasploit_model_module_handler_type
523
+ end
524
+
525
+ it { should_not be_valid }
526
+
527
+ it 'should record error on handler_type' do
528
+ module_ancestor.valid?
529
+
530
+ module_ancestor.errors[:handler_type].should include('must be nil')
531
+ end
532
+ end
533
+
534
+ context 'without handler_type' do
535
+ let(:handler_type) do
536
+ nil
537
+ end
538
+
539
+ it { should be_valid }
540
+ end
541
+ end
542
+
543
+ context 'stager' do
544
+ let(:payload_type) do
545
+ 'stager'
546
+ end
547
+
548
+ context 'with handler_type' do
549
+ let(:handler_type) do
550
+ FactoryGirl.generate :metasploit_model_module_handler_type
551
+ end
552
+
553
+ it { should be_valid }
554
+ end
555
+
556
+ context 'without handler_type' do
557
+ let(:handler_type) do
558
+ nil
559
+ end
560
+
561
+ it { should_not be_valid }
562
+
563
+ it 'should record error on handler_type' do
564
+ module_ancestor.valid?
565
+
566
+ module_ancestor.errors[:handler_type].should include(I18n.translate!('errors.messages.blank'))
567
+ end
568
+ end
569
+ end
570
+ end
571
+ end
572
+
573
+ context 'without payload' do
574
+ let(:module_type) do
575
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
576
+ end
577
+
578
+ context 'with payload_type' do
579
+ # force payload_type to NOT be derived to check invalid setups
580
+ before(:each) do
581
+ module_ancestor.payload_type = payload_type
582
+ end
583
+
584
+ context 'single' do
585
+ let(:payload_type) do
586
+ 'single'
587
+ end
588
+
589
+ context 'with handler_type' do
590
+ let(:handler_type) do
591
+ FactoryGirl.generate :metasploit_model_module_handler_type
592
+ end
593
+
594
+ it { should be_invalid }
595
+
596
+ it 'should record error on handler_type' do
597
+ module_ancestor.valid?
598
+
599
+ module_ancestor.errors[:handler_type].should include('must be nil')
600
+ end
601
+ end
602
+
603
+ context 'without handler_type' do
604
+ let(:handler_type) do
605
+ nil
606
+ end
607
+
608
+ it 'should not record error on handler_type' do
609
+ module_ancestor.valid?
610
+
611
+ module_ancestor.errors[:handler_type].should be_empty
612
+ end
613
+ end
614
+ end
615
+
616
+ context 'stage' do
617
+ let(:payload_type) do
618
+ 'stage'
619
+ end
620
+
621
+ context 'with handler_type' do
622
+ let(:handler_type) do
623
+ FactoryGirl.generate :metasploit_model_module_handler_type
624
+ end
625
+
626
+ it { should_not be_valid }
627
+
628
+ it 'should record error on handler_type' do
629
+ module_ancestor.valid?
630
+
631
+ module_ancestor.errors[:handler_type].should include('must be nil')
632
+ end
633
+ end
634
+
635
+ context 'without handler_type' do
636
+ let(:handler_type) do
637
+ nil
638
+ end
639
+
640
+ it 'should not record error on handler_type' do
641
+ module_ancestor.valid?
642
+
643
+ module_ancestor.errors[:handler_type].should be_empty
644
+ end
645
+ end
646
+ end
647
+
648
+ context 'stager' do
649
+ let(:payload_type) do
650
+ 'stager'
651
+ end
652
+
653
+ context 'with handler_type' do
654
+ let(:handler_type) do
655
+ FactoryGirl.generate :metasploit_model_module_handler_type
656
+ end
657
+
658
+ it { should_not be_valid }
659
+
660
+ it 'should record error on handler_type' do
661
+ module_ancestor.valid?
662
+
663
+ module_ancestor.errors[:handler_type].should include('must be nil')
664
+ end
665
+ end
666
+
667
+ context 'without handler_type' do
668
+ let(:handler_type) do
669
+ nil
670
+ end
671
+
672
+ it 'should not record error on handler_type' do
673
+ module_ancestor.valid?
674
+
675
+ module_ancestor.errors[:handler_type].should be_empty
676
+ end
677
+ end
678
+ end
679
+ end
680
+
681
+ context 'without payload_type' do
682
+ let(:payload_type) do
683
+ nil
684
+ end
685
+
686
+ context 'with handler_type' do
687
+ let(:handler_type) do
688
+ FactoryGirl.generate :metasploit_model_module_handler_type
689
+ end
690
+
691
+ it { should_not be_valid }
692
+
693
+ it 'should record error on handler_type' do
694
+ module_ancestor.valid?
695
+
696
+ module_ancestor.errors[:handler_type].should include('must be nil')
697
+ end
698
+ end
699
+
700
+ context 'without handler_type' do
701
+ let(:handler_type) do
702
+ nil
703
+ end
704
+
705
+ it { should be_valid }
706
+ end
707
+ end
708
+ end
709
+ end
710
+
711
+ it { should ensure_inclusion_of(:module_type).in_array(Metasploit::Model::Module::Type::ALL) }
712
+ it { should validate_presence_of(:parent_path) }
713
+
714
+ context 'payload_type' do
715
+ subject(:module_ancestor) do
716
+ FactoryGirl.build(
717
+ module_ancestor_factory,
718
+ :module_type => module_type,
719
+ :reference_name => reference_name
720
+ )
721
+ end
722
+
723
+ before(:each) do
724
+ # payload is ignored in metasploit_model_module_ancestor trait so need set it directly
725
+ module_ancestor.payload_type = payload_type
726
+ end
727
+
728
+ context 'with payload?' do
729
+ let(:module_type) do
730
+ 'payload'
731
+ end
732
+
733
+ context 'with payload_type' do
734
+ Metasploit::Model::Module::Ancestor::PAYLOAD_TYPES.each do |allowed_payload_type|
735
+ context "with #{allowed_payload_type}" do
736
+ let(:payload_type) do
737
+ nil
738
+ end
739
+
740
+ let(:payload_type_directory) do
741
+ allowed_payload_type.pluralize
742
+ end
743
+
744
+ let(:reference_name) do
745
+ "#{payload_type_directory}/name"
746
+ end
747
+
748
+ it { should be_valid }
749
+ end
750
+ end
751
+ end
752
+
753
+ context 'without payload_type' do
754
+ let(:payload_type) do
755
+ nil
756
+ end
757
+
758
+ let(:reference_name) do
759
+ FactoryGirl.generate :metasploit_model_module_ancestor_non_payload_reference_name
760
+ end
761
+
762
+ it { should_not be_valid }
763
+
764
+ it 'should record error on payload_type' do
765
+ module_ancestor.valid?
766
+
767
+ module_ancestor.errors[:payload_type].should include('is not included in the list')
768
+ end
769
+ end
770
+ end
771
+
772
+ context 'without payload?' do
773
+ let(:module_type) do
774
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
775
+ end
776
+
777
+ context 'with payload_type' do
778
+ # force payload to not be nil so that derive_payload_type is not called.
779
+ let(:payload_type) do
780
+ FactoryGirl.generate :metasploit_model_module_ancestor_payload_type
781
+ end
782
+
783
+ let(:reference_name) do
784
+ "#{payload_type.pluralize}/name"
785
+ end
786
+
787
+ it { should_not be_valid }
788
+
789
+ it 'should record error on payload_type' do
790
+ module_ancestor.valid?
791
+
792
+ module_ancestor.errors[:payload_type].should include('must be nil')
793
+ end
794
+ end
795
+
796
+ context 'without payload_type' do
797
+ let(:payload_type) do
798
+ nil
799
+ end
800
+
801
+ let(:reference_name) do
802
+ FactoryGirl.generate :metasploit_model_module_ancestor_non_payload_reference_name
803
+ end
804
+
805
+ it { should be_valid }
806
+ end
807
+ end
808
+ end
809
+
810
+ it { should validate_presence_of(:real_path_modified_at) }
811
+
812
+ context 'real_path_sha1_hex_digest' do
813
+ context 'validates format with SHA1_HEX_DIGEST_REGEXP' do
814
+ let(:hexdigest) do
815
+ Digest::SHA1.hexdigest('')
816
+ end
817
+
818
+ it 'should allow a Digest::SHA1.hexdigest' do
819
+ module_ancestor.should allow_value(hexdigest).for(:real_path_sha1_hex_digest)
820
+ end
821
+
822
+ it 'should not allow a truncated Digest::SHA1.hexdigest' do
823
+ module_ancestor.should_not allow_value(hexdigest[0, 39]).for(:real_path_sha1_hex_digest)
824
+ end
825
+
826
+ it 'should not allow upper case hex to maintain normalization' do
827
+ module_ancestor.should_not allow_value(hexdigest.upcase).for(:real_path_sha1_hex_digest)
828
+ end
829
+
830
+ it { should_not allow_value(nil).for(:real_path_sha1_hex_digest) }
831
+ end
832
+ end
833
+
834
+ context 'reference_name' do
835
+ context 'validates format with REFERENCE_NAME_REGEXP' do
836
+ context 'without slashes' do
837
+ context 'first character' do
838
+ it 'should not allow space' do
839
+ module_ancestor.should_not allow_value(' ').for(:reference_name)
840
+ end
841
+
842
+ it 'should allow dash' do
843
+ module_ancestor.should allow_value('-').for(:reference_name)
844
+ end
845
+
846
+ it 'should allow digit' do
847
+ module_ancestor.should allow_value('0').for(:reference_name)
848
+ end
849
+
850
+ it 'should allow uppercase letter' do
851
+ module_ancestor.should allow_value('A').for(:reference_name)
852
+ end
853
+
854
+ it 'should allow underscore' do
855
+ module_ancestor.should allow_value('_').for(:reference_name)
856
+ end
857
+
858
+ it 'should allow lowercase letter' do
859
+ module_ancestor.should allow_value('a').for(:reference_name)
860
+ end
861
+ end
862
+
863
+ context 'later letters' do
864
+ let(:lowercase_letters) do
865
+ ('a'..'z').to_a
866
+ end
867
+
868
+ let(:first_letter) do
869
+ lowercase_letters.sample
870
+ end
871
+
872
+ it 'should not allow space' do
873
+ module_ancestor.should_not allow_value("#{first_letter} ").for(:reference_name)
874
+ end
875
+
876
+ it 'should allow dash' do
877
+ module_ancestor.should allow_value("#{first_letter}-").for(:reference_name)
878
+ end
879
+
880
+ it 'should allow digit' do
881
+ module_ancestor.should allow_value("#{first_letter}1").for(:reference_name)
882
+ end
883
+
884
+ it 'should allow uppercase letter' do
885
+ module_ancestor.should allow_value("#{first_letter}A").for(:reference_name)
886
+ end
887
+
888
+ it 'should allow underscore' do
889
+ module_ancestor.should allow_value("#{first_letter}_").for(:reference_name)
890
+ end
891
+
892
+ it 'should allow lowercase letter' do
893
+ module_ancestor.should allow_value("#{first_letter}a").for(:reference_name)
894
+ end
895
+ end
896
+ end
897
+
898
+ context 'with slashes' do
899
+ let(:section) do
900
+ "-_0a"
901
+ end
902
+
903
+ context 'leading' do
904
+ it "should not allow '/'" do
905
+ module_ancestor.should_not allow_value("/#{section}").for(:reference_name)
906
+ end
907
+
908
+ it "should not allow '\\'" do
909
+ module_ancestor.should_not allow_value("\\#{section}").for(:reference_name)
910
+ end
911
+ end
912
+
913
+ context 'infix' do
914
+ it "should allow '/'" do
915
+ module_ancestor.should allow_value("#{section}/#{section}").for(:reference_name)
916
+ end
917
+
918
+ it "should not allow '\\'" do
919
+ module_ancestor.should_not allow_value("#{section}\\#{section}").for(:reference_name)
920
+ end
921
+ end
922
+
923
+ context 'trailing' do
924
+ it "should not allow '/'" do
925
+ module_ancestor.should_not allow_value("#{section}/").for(:reference_name)
926
+ end
927
+
928
+ it "should not allow '\\'" do
929
+ module_ancestor.should_not allow_value("#{section}\\").for(:reference_name)
930
+ end
931
+ end
932
+ end
933
+
934
+ context 'real-world examples' do
935
+ it { should allow_value('admin/2wire/xslt_password_reset').for(:reference_name) }
936
+ it { should allow_value('dos/http/3com_superstack_switch').for(:reference_name) }
937
+ it { should allow_value('windows/brightstor/tape_engine_8A').for(:reference_name) }
938
+ it { should allow_value('windows/fileformat/a-pdf_wav_to_mp3').for(:reference_name) }
939
+ it { should allow_value('windows/ftp/32bitftp_list_reply').for(:reference_name) }
940
+ it { should allow_value('windows/ftp/3cdaemon_ftp_user').for(:reference_name) }
941
+ end
942
+ end
943
+ end
944
+ end
945
+
946
+ context '#contents' do
947
+ subject(:contents) do
948
+ module_ancestor.contents
949
+ end
950
+
951
+ before(:each) do
952
+ module_ancestor.real_path = real_path
953
+ end
954
+
955
+ context 'with #real_path' do
956
+ let(:real_path) do
957
+ module_ancestor.derived_real_path
958
+ end
959
+
960
+ context 'with file' do
961
+ let(:file_contents) do
962
+ "# Contents"
963
+ end
964
+
965
+ before(:each) do
966
+ File.open(real_path, 'wb') do |f|
967
+ f.write(file_contents)
968
+ end
969
+ end
970
+
971
+ it 'should be contents of file' do
972
+ contents.should == file_contents
973
+ end
974
+ end
975
+
976
+ context 'without file' do
977
+ before(:each) do
978
+ File.delete(real_path)
979
+ end
980
+
981
+ it { should be_nil }
982
+ end
983
+ end
984
+
985
+ context 'without #real_path' do
986
+ let(:real_path) do
987
+ nil
988
+ end
989
+
990
+ it { should be_nil }
991
+ end
992
+ end
993
+
994
+ context '#derived_full_name' do
995
+ subject(:derived_full_name) do
996
+ module_ancestor.derived_full_name
997
+ end
998
+
999
+ let(:module_ancestor) do
1000
+ FactoryGirl.build(
1001
+ module_ancestor_factory,
1002
+ :module_type => module_type,
1003
+ # don't create parent_path since it's unneeded for tests
1004
+ :parent_path => nil
1005
+ )
1006
+ end
1007
+
1008
+ context 'with module_type' do
1009
+ let(:module_type) do
1010
+ FactoryGirl.generate :metasploit_model_module_type
1011
+ end
1012
+
1013
+ it "should equal <module_type>/<reference_name>" do
1014
+ derived_full_name.should == "#{module_ancestor.module_type}/#{module_ancestor.reference_name}"
1015
+ end
1016
+ end
1017
+
1018
+ context 'without module_type' do
1019
+ let(:module_type) do
1020
+ nil
1021
+ end
1022
+
1023
+ it { should be_nil }
1024
+ end
1025
+ end
1026
+
1027
+ context '#derived_module_type' do
1028
+ subject(:derived_module_type) do
1029
+ module_ancestor.derived_module_type
1030
+ end
1031
+
1032
+ before(:each) do
1033
+ module_ancestor.real_path = real_path
1034
+ end
1035
+
1036
+ context 'with #real_path' do
1037
+ let(:real_path) do
1038
+ module_ancestor.derived_real_path
1039
+ end
1040
+
1041
+ before(:each) do
1042
+ module_ancestor.parent_path = module_path
1043
+ end
1044
+
1045
+ context 'with Metasploit::Model::Module::Path' do
1046
+ let(:module_path) do
1047
+ module_ancestor.parent_path
1048
+ end
1049
+
1050
+ before(:each) do
1051
+ module_path.real_path = module_path_real_path
1052
+ end
1053
+
1054
+ context 'with Metasploit::Model::Module::Path#real_path' do
1055
+ let(:module_path_real_path) do
1056
+ module_path.real_path
1057
+ end
1058
+
1059
+ it { should_not be_nil }
1060
+ end
1061
+
1062
+ context 'without Metasploit::Model::Module::Path#real_path' do
1063
+ let(:module_path_real_path) do
1064
+ nil
1065
+ end
1066
+
1067
+ it { should be_nil }
1068
+ end
1069
+ end
1070
+
1071
+ context 'without Metasploit::Model::Module::Path' do
1072
+ let(:module_path) do
1073
+ nil
1074
+ end
1075
+
1076
+ it { should be_nil }
1077
+ end
1078
+ end
1079
+
1080
+ context 'without #real_path' do
1081
+ let(:real_path) do
1082
+ nil
1083
+ end
1084
+
1085
+ it { should be_nil }
1086
+ end
1087
+ end
1088
+
1089
+ context '#derived_payload_type' do
1090
+ subject(:derived_payload_type) do
1091
+ module_ancestor.derived_payload_type
1092
+ end
1093
+
1094
+ let(:module_ancestor) do
1095
+ FactoryGirl.build(
1096
+ module_ancestor_factory,
1097
+ :module_type => module_type
1098
+ )
1099
+ end
1100
+
1101
+ context 'with payload' do
1102
+ let(:module_type) do
1103
+ 'payload'
1104
+ end
1105
+
1106
+ it 'should singularize payload_type_directory' do
1107
+ derived_payload_type.should == module_ancestor.payload_type_directory.singularize
1108
+ end
1109
+ end
1110
+
1111
+ context 'without payload' do
1112
+ let(:module_type) do
1113
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
1114
+ end
1115
+
1116
+ it { should be_nil }
1117
+ end
1118
+ end
1119
+
1120
+ context '#derived_real_path' do
1121
+ subject(:derived_real_path) do
1122
+ module_ancestor.derived_real_path
1123
+ end
1124
+
1125
+ let(:module_ancestor) do
1126
+ FactoryGirl.build(
1127
+ module_ancestor_factory,
1128
+ :module_type => module_type,
1129
+ :parent_path => parent_path,
1130
+ :reference_name => reference_name
1131
+ )
1132
+ end
1133
+
1134
+ let(:module_type) do
1135
+ nil
1136
+ end
1137
+
1138
+ let(:parent_path) do
1139
+ nil
1140
+ end
1141
+
1142
+ let(:reference_name) do
1143
+ nil
1144
+ end
1145
+
1146
+ context 'with parent_path' do
1147
+ let(:parent_path) do
1148
+ FactoryGirl.build(
1149
+ module_path_factory,
1150
+ :real_path => parent_path_real_path
1151
+ )
1152
+ end
1153
+
1154
+ context 'with parent_path.real_path' do
1155
+ let(:parent_path_real_path) do
1156
+ FactoryGirl.generate :metasploit_model_module_path_real_path
1157
+ end
1158
+
1159
+ context 'with module_type' do
1160
+ let(:module_type) do
1161
+ FactoryGirl.generate :metasploit_model_module_type
1162
+ end
1163
+
1164
+ context 'with reference_name' do
1165
+ let(:reference_name) do
1166
+ FactoryGirl.generate :metasploit_model_module_ancestor_non_payload_reference_name
1167
+ end
1168
+
1169
+ it 'should be full path including parent_path.real_path, type_directory, and reference_path' do
1170
+ derived_real_path.should == File.join(
1171
+ parent_path_real_path,
1172
+ module_ancestor.module_type_directory,
1173
+ module_ancestor.reference_path
1174
+ )
1175
+ end
1176
+ end
1177
+
1178
+ context 'without reference_name' do
1179
+ let(:reference_name) do
1180
+ nil
1181
+ end
1182
+
1183
+ it { should be_nil }
1184
+ end
1185
+ end
1186
+
1187
+ context 'without module_type' do
1188
+ let(:module_type) do
1189
+ nil
1190
+ end
1191
+
1192
+ it { should be_nil }
1193
+ end
1194
+ end
1195
+
1196
+ context 'without parent_path.real_path' do
1197
+ let(:parent_path_real_path) do
1198
+ nil
1199
+ end
1200
+
1201
+ it { should be_nil }
1202
+ end
1203
+ end
1204
+
1205
+ context 'without parent_path' do
1206
+ let(:parent_path) do
1207
+ nil
1208
+ end
1209
+
1210
+ it { should be_nil }
1211
+ end
1212
+ end
1213
+
1214
+ context '#derived_real_path_modified_at' do
1215
+ subject(:derived_real_path_modified_at) do
1216
+ module_ancestor.derived_real_path_modified_at
1217
+ end
1218
+
1219
+ let(:module_ancestor) do
1220
+ FactoryGirl.build(module_ancestor_factory)
1221
+ end
1222
+
1223
+ context 'with real_path' do
1224
+ before(:each) do
1225
+ module_ancestor.real_path = real_path
1226
+ end
1227
+
1228
+ context 'that exists' do
1229
+ let(:real_path) do
1230
+ # derived real path will have been created by factory's after(:build)
1231
+ module_ancestor.derived_real_path
1232
+ end
1233
+
1234
+ it 'should be modification time of file' do
1235
+ derived_real_path_modified_at.should == File.mtime(real_path)
1236
+ end
1237
+
1238
+ it 'should be in UTC' do
1239
+ derived_real_path_modified_at.zone.should == 'UTC'
1240
+ end
1241
+ end
1242
+
1243
+ context 'that does not exist' do
1244
+ let(:real_path) do
1245
+ 'non/existent/path'
1246
+ end
1247
+
1248
+ it { should be_nil }
1249
+ end
1250
+ end
1251
+
1252
+ context 'without real_path' do
1253
+ before(:each) do
1254
+ module_ancestor.real_path = nil
1255
+ end
1256
+
1257
+ it 'should have nil for real_path' do
1258
+ module_ancestor.real_path.should be_nil
1259
+ end
1260
+
1261
+ it { should be_nil }
1262
+ end
1263
+ end
1264
+
1265
+ context '#derived_real_path_sha1_hex_digest' do
1266
+ subject(:derived_real_path_sha1_hex_digest) do
1267
+ module_ancestor.derived_real_path_sha1_hex_digest
1268
+ end
1269
+
1270
+ let(:module_ancestor) do
1271
+ FactoryGirl.build(module_ancestor_factory)
1272
+ end
1273
+
1274
+ context 'with real_path' do
1275
+ before(:each) do
1276
+ module_ancestor.real_path = module_ancestor.derived_real_path
1277
+ end
1278
+
1279
+ context 'that exists' do
1280
+ it 'should read the using Digest::SHA1.file' do
1281
+ Digest::SHA1.should_receive(:file).with(module_ancestor.real_path).and_call_original
1282
+
1283
+ derived_real_path_sha1_hex_digest
1284
+ end
1285
+
1286
+ context 'with content' do
1287
+ let(:content_sha1_hex_digest) do
1288
+ Digest::SHA1.hexdigest(content)
1289
+ end
1290
+
1291
+ before(:each) do
1292
+ File.open(module_ancestor.real_path, 'wb') do |f|
1293
+ f.write(content)
1294
+ end
1295
+ end
1296
+
1297
+ context 'that is empty' do
1298
+ let(:content) do
1299
+ ''
1300
+ end
1301
+
1302
+ it 'should have empty file at real_path' do
1303
+ File.size(module_ancestor.real_path).should be_zero
1304
+ end
1305
+
1306
+ it 'should have SHA1 hex digest for empty string' do
1307
+ derived_real_path_sha1_hex_digest.should == content_sha1_hex_digest
1308
+ end
1309
+ end
1310
+
1311
+ context 'that is not empty' do
1312
+ let(:content) do
1313
+ "# Non-empty content"
1314
+ end
1315
+
1316
+ it 'should have SHA1 hex digest for content' do
1317
+ derived_real_path_sha1_hex_digest.should == content_sha1_hex_digest
1318
+ end
1319
+ end
1320
+ end
1321
+ end
1322
+
1323
+ context 'that does not exist' do
1324
+ before(:each) do
1325
+ File.delete(module_ancestor.real_path)
1326
+ end
1327
+
1328
+ it { should be_nil }
1329
+ end
1330
+ end
1331
+
1332
+ context 'without real_path' do
1333
+ before(:each) do
1334
+ module_ancestor.real_path = nil
1335
+ end
1336
+
1337
+ it 'should have nil for real_path' do
1338
+ module_ancestor.real_path.should be_nil
1339
+ end
1340
+
1341
+ it { should be_nil }
1342
+ end
1343
+ end
1344
+
1345
+ context '#derived_reference_name' do
1346
+ subject(:derived_reference_name) do
1347
+ module_ancestor.derived_reference_name
1348
+ end
1349
+
1350
+ before(:each) do
1351
+ module_ancestor.stub(relative_file_names: relative_file_names)
1352
+ end
1353
+
1354
+ context 'with empty #relative_file_names' do
1355
+ let(:relative_file_names) do
1356
+ Enumerator.new { }
1357
+ end
1358
+
1359
+ it { should be_nil }
1360
+ end
1361
+
1362
+ context 'without empty #relative_file_names' do
1363
+ context 'with one element' do
1364
+ let(:relative_file_names) do
1365
+ ['a'].each
1366
+ end
1367
+ end
1368
+
1369
+ context 'with more than one element' do
1370
+ context 'with EXTENSION' do
1371
+ let(:relative_file_names) do
1372
+ ['a', 'b', "c#{described_class::EXTENSION}"].each
1373
+ end
1374
+
1375
+ it 'should not include first file name' do
1376
+ derived_reference_name.split(described_class::REFERENCE_NAME_SEPARATOR).should_not include('a')
1377
+ end
1378
+
1379
+ it 'should match REFERENCE_NAME_REGEXP' do
1380
+ derived_reference_name.should match(described_class::REFERENCE_NAME_REGEXP)
1381
+ end
1382
+
1383
+ it 'should not include EXTENSION' do
1384
+ derived_reference_name.should_not end_with(described_class::EXTENSION)
1385
+ end
1386
+
1387
+ it 'should be all file names except the first joined with the REFERENCE_NAME_SEPARATOR with EXTENSION' do
1388
+ derived_reference_name.should == "b#{described_class::REFERENCE_NAME_SEPARATOR}c"
1389
+ end
1390
+ end
1391
+
1392
+ context 'without EXTENSION' do
1393
+ let(:relative_file_names) do
1394
+ ['a', 'b', 'c'].each
1395
+ end
1396
+
1397
+ it { should be_nil }
1398
+ end
1399
+ end
1400
+ end
1401
+ end
1402
+
1403
+ # class method
1404
+ context 'handled?' do
1405
+ subject(:handled?) do
1406
+ module_ancestor_class.handled?(
1407
+ :module_type => module_type,
1408
+ :payload_type => payload_type
1409
+ )
1410
+ end
1411
+
1412
+ context 'with module_type' do
1413
+ context 'payload' do
1414
+ let(:module_type) do
1415
+ 'payload'
1416
+ end
1417
+
1418
+ context 'with payload_type' do
1419
+ context 'single' do
1420
+ let(:payload_type) do
1421
+ 'single'
1422
+ end
1423
+
1424
+ it { should be_true }
1425
+ end
1426
+
1427
+ context 'stage' do
1428
+ let(:payload_type) do
1429
+ 'stage'
1430
+ end
1431
+
1432
+ it { should be_false }
1433
+ end
1434
+
1435
+ context 'stager' do
1436
+ let(:payload_type) do
1437
+ 'stager'
1438
+ end
1439
+
1440
+ it { should be_true }
1441
+ end
1442
+ end
1443
+
1444
+ context 'without payload_type' do
1445
+ let(:payload_type) do
1446
+ nil
1447
+ end
1448
+
1449
+ it { should be_false }
1450
+ end
1451
+ end
1452
+
1453
+ context 'non-payload' do
1454
+ let(:module_type) do
1455
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
1456
+ end
1457
+
1458
+ context 'with payload_type' do
1459
+ context 'single' do
1460
+ let(:payload_type) do
1461
+ 'single'
1462
+ end
1463
+
1464
+ it { should be_false }
1465
+ end
1466
+
1467
+ context 'stage' do
1468
+ let(:payload_type) do
1469
+ 'stage'
1470
+ end
1471
+
1472
+ it { should be_false }
1473
+ end
1474
+
1475
+ context 'stager' do
1476
+ let(:payload_type) do
1477
+ 'stager'
1478
+ end
1479
+
1480
+ it { should be_false }
1481
+ end
1482
+ end
1483
+
1484
+ context 'without payload_type' do
1485
+ let(:payload_type) do
1486
+ nil
1487
+ end
1488
+
1489
+ it { should be_false }
1490
+ end
1491
+ end
1492
+ end
1493
+
1494
+ context 'without module_type' do
1495
+ let(:module_type) do
1496
+ nil
1497
+ end
1498
+
1499
+ context 'with payload_type' do
1500
+ context 'single' do
1501
+ let(:payload_type) do
1502
+ 'single'
1503
+ end
1504
+
1505
+ it { should be_false }
1506
+ end
1507
+
1508
+ context 'stage' do
1509
+ let(:payload_type) do
1510
+ 'stage'
1511
+ end
1512
+
1513
+ it { should be_false }
1514
+ end
1515
+
1516
+ context 'stager' do
1517
+ let(:payload_type) do
1518
+ 'stager'
1519
+ end
1520
+
1521
+ it { should be_false }
1522
+ end
1523
+ end
1524
+
1525
+ context 'without payload_type' do
1526
+ let(:payload_type) do
1527
+ nil
1528
+ end
1529
+
1530
+ it { should be_false }
1531
+ end
1532
+ end
1533
+ end
1534
+
1535
+ # instance method
1536
+ context '#handled?' do
1537
+ subject(:handled?) do
1538
+ module_ancestor.handled?
1539
+ end
1540
+
1541
+ let(:module_ancestor) do
1542
+ FactoryGirl.build(
1543
+ module_ancestor_factory,
1544
+ :module_type => module_type,
1545
+ :payload_type => payload_type
1546
+ )
1547
+ end
1548
+
1549
+ let(:module_type) do
1550
+ 'payload'
1551
+ end
1552
+
1553
+ let(:payload_type) do
1554
+ FactoryGirl.generate :metasploit_model_module_ancestor_payload_type
1555
+ end
1556
+
1557
+ before(:each) do
1558
+ module_ancestor.payload_type = module_ancestor.derived_payload_type
1559
+ end
1560
+
1561
+ it 'should delegate to class method' do
1562
+ module_ancestor_class.should_receive(:handled?).with(
1563
+ :module_type => module_type,
1564
+ :payload_type => payload_type
1565
+ )
1566
+
1567
+ handled?
1568
+ end
1569
+ end
1570
+
1571
+ context '#loading_context?' do
1572
+ subject(:loading_context?) do
1573
+ module_ancestor.send(:loading_context?)
1574
+ end
1575
+
1576
+ context 'with valid?' do
1577
+ it 'should be false' do
1578
+ module_ancestor.should_receive(:run_validations!) do
1579
+ loading_context?.should be_false
1580
+ end
1581
+
1582
+ module_ancestor.valid?
1583
+ end
1584
+ end
1585
+
1586
+ context 'with valid?(:loading)' do
1587
+ it 'should be true' do
1588
+ module_ancestor.should_receive(:run_validations!) do
1589
+ loading_context?.should be_true
1590
+ end
1591
+
1592
+ module_ancestor.valid?(:loading)
1593
+ end
1594
+ end
1595
+ end
1596
+
1597
+ context '#payload?' do
1598
+ subject(:module_ancestor) do
1599
+ module_ancestor_class.new(:module_type => module_type)
1600
+ end
1601
+
1602
+ context "with 'payload' module_type" do
1603
+ let(:module_type) do
1604
+ 'payload'
1605
+ end
1606
+
1607
+ it { should be_payload }
1608
+ end
1609
+
1610
+ context "without 'payload' module_type" do
1611
+ let(:module_type) do
1612
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
1613
+ end
1614
+
1615
+ it { should_not be_payload }
1616
+ end
1617
+ end
1618
+
1619
+ context '#payload_name' do
1620
+ subject(:payload_name) do
1621
+ module_ancestor.payload_name
1622
+ end
1623
+
1624
+ let(:module_ancestor) do
1625
+ FactoryGirl.build(
1626
+ module_ancestor_factory,
1627
+ handler_type: handler_type,
1628
+ module_type: module_type,
1629
+ payload_type: payload_type
1630
+ )
1631
+ end
1632
+
1633
+ context '#module_type' do
1634
+ context 'with payload' do
1635
+ #
1636
+ # Shared examples
1637
+ #
1638
+
1639
+ shared_examples_for 'prefix payload_name' do
1640
+ let(:handler_type) do
1641
+ nil
1642
+ end
1643
+
1644
+ context 'with #reference_name' do
1645
+ #
1646
+ # lets
1647
+ #
1648
+
1649
+ let(:expected_payload_name) do
1650
+ 'expected/payload/name'
1651
+ end
1652
+
1653
+ let(:reference_name) do
1654
+ "#{payload_type_directory}/#{expected_payload_name}"
1655
+ end
1656
+
1657
+ #
1658
+ # Callbacks
1659
+ #
1660
+
1661
+ before(:each) do
1662
+ module_ancestor.reference_name = reference_name
1663
+ end
1664
+
1665
+ it "strips #payload_type_directory and '/' from #reference_name" do
1666
+ expect(payload_name).to eq(expected_payload_name)
1667
+ end
1668
+ end
1669
+
1670
+ context 'without #reference_name' do
1671
+ before(:each) do
1672
+ module_ancestor.reference_name = nil
1673
+ end
1674
+
1675
+ it { should be_nil }
1676
+ end
1677
+ end
1678
+
1679
+ #
1680
+ # lets
1681
+ #
1682
+
1683
+ let(:module_type) do
1684
+ 'payload'
1685
+ end
1686
+
1687
+ context '#payload_type' do
1688
+ context 'with single' do
1689
+ let(:payload_type) do
1690
+ 'single'
1691
+ end
1692
+
1693
+ it_should_behave_like 'prefix payload_name' do
1694
+ let(:payload_type_directory) do
1695
+ 'singles'
1696
+ end
1697
+ end
1698
+ end
1699
+
1700
+ context 'with stage' do
1701
+ let(:payload_type) do
1702
+ 'stage'
1703
+ end
1704
+
1705
+ it_should_behave_like 'prefix payload_name' do
1706
+ let(:payload_type_directory) do
1707
+ 'stages'
1708
+ end
1709
+ end
1710
+ end
1711
+
1712
+ context 'with stager' do
1713
+ let(:payload_type) do
1714
+ 'stager'
1715
+ end
1716
+
1717
+ context 'with #handler_type' do
1718
+ let(:handler_type) do
1719
+ FactoryGirl.generate :metasploit_model_module_handler_type
1720
+ end
1721
+
1722
+ it 'uses #handler_type' do
1723
+ expect(payload_name).to eq(handler_type)
1724
+ end
1725
+ end
1726
+
1727
+ context 'without #handler_type' do
1728
+ let(:handler_type) do
1729
+ nil
1730
+ end
1731
+
1732
+ it { should be_nil }
1733
+ end
1734
+ end
1735
+
1736
+ context 'with other' do
1737
+ let(:handler_type) do
1738
+ nil
1739
+ end
1740
+
1741
+ let(:payload_type) do
1742
+ 'unknown_payload_type'
1743
+ end
1744
+
1745
+ it { should be_nil }
1746
+ end
1747
+ end
1748
+ end
1749
+
1750
+ context 'without payload' do
1751
+ let(:handler_type) do
1752
+ nil
1753
+ end
1754
+
1755
+ let(:module_type) do
1756
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
1757
+ end
1758
+
1759
+ let(:payload_type) do
1760
+ nil
1761
+ end
1762
+
1763
+ it { should be_nil }
1764
+ end
1765
+ end
1766
+ end
1767
+
1768
+ context '#payload_type_directory' do
1769
+ subject(:payload_type_directory) do
1770
+ module_ancestor.payload_type_directory
1771
+ end
1772
+
1773
+ let(:module_ancestor) do
1774
+ FactoryGirl.build(
1775
+ module_ancestor_factory,
1776
+ module_type: module_type
1777
+ )
1778
+ end
1779
+
1780
+ context 'with payload' do
1781
+ let(:module_type) do
1782
+ 'payload'
1783
+ end
1784
+
1785
+ before(:each) do
1786
+ module_ancestor.reference_name = reference_name
1787
+ end
1788
+
1789
+ context 'with #reference_name' do
1790
+ let(:expected_payload_type_directory) do
1791
+ payload_type_directories.sample
1792
+ end
1793
+
1794
+ let(:payload_type_directories) do
1795
+ [
1796
+ 'singles',
1797
+ 'stages',
1798
+ 'stagers'
1799
+ ]
1800
+ end
1801
+
1802
+ let(:reference_name) do
1803
+ "#{expected_payload_type_directory}/reference/name/tail"
1804
+ end
1805
+
1806
+ it 'is name before REFERENCE_NAME_SEPARATOR' do
1807
+ expect(payload_type_directory).to eq(expected_payload_type_directory)
1808
+ end
1809
+ end
1810
+
1811
+ context 'without #reference_name' do
1812
+ let(:reference_name) do
1813
+ nil
1814
+ end
1815
+
1816
+ it { should be_nil }
1817
+ end
1818
+ end
1819
+
1820
+ context 'without payload' do
1821
+ let(:module_type) do
1822
+ FactoryGirl.generate :metasploit_model_non_payload_module_type
1823
+ end
1824
+
1825
+ it { should be_nil }
1826
+ end
1827
+ end
1828
+
1829
+ context '#relative_file_names' do
1830
+ subject(:relative_file_names) do
1831
+ module_ancestor.relative_file_names
1832
+ end
1833
+
1834
+ before(:each) do
1835
+ module_ancestor.stub(relative_pathname: relative_pathname)
1836
+ end
1837
+
1838
+ context 'with #relative_pathnames' do
1839
+ let(:file_names) do
1840
+ [
1841
+ 'a',
1842
+ 'b',
1843
+ 'c'
1844
+ ]
1845
+ end
1846
+
1847
+ let(:relative_pathname) do
1848
+ Pathname.new(file_names.join('/'))
1849
+ end
1850
+
1851
+ it { should be_an Enumerator }
1852
+
1853
+ it 'should include all file names, in order' do
1854
+ relative_file_names.to_a.should == file_names
1855
+ end
1856
+ end
1857
+
1858
+ context 'without #relative_pathnames' do
1859
+ let(:relative_pathname) do
1860
+ nil
1861
+ end
1862
+
1863
+ it { should be_an Enumerator }
1864
+ its(:to_a) { should be_empty }
1865
+ end
1866
+ end
1867
+
1868
+ context '#relative_pathname' do
1869
+ subject(:relative_pathname) do
1870
+ module_ancestor.relative_pathname
1871
+ end
1872
+
1873
+ before(:each) do
1874
+ module_ancestor.stub(real_pathname: real_pathname)
1875
+ end
1876
+
1877
+ context 'with #real_pathname' do
1878
+ let(:real_pathname) do
1879
+ Pathname.new('a/b/c')
1880
+ end
1881
+
1882
+ before(:each) do
1883
+ module_ancestor.parent_path = parent_path
1884
+ end
1885
+
1886
+ context 'with #parent_path' do
1887
+ let(:parent_path) do
1888
+ module_ancestor.parent_path
1889
+ end
1890
+
1891
+ before(:each) do
1892
+ parent_path.stub(real_pathname: parent_path_real_pathname)
1893
+ end
1894
+
1895
+ context 'with Metasploit::Model::Module::Path#real_pathname' do
1896
+ let(:parent_path_real_pathname) do
1897
+ Pathname.new('a')
1898
+ end
1899
+
1900
+ it { should be_a Pathname }
1901
+ it { should be_relative }
1902
+
1903
+ it 'should be relative to parent_path.real_pathname' do
1904
+ relative_pathname.should == Pathname.new('b/c')
1905
+ end
1906
+ end
1907
+
1908
+ context 'without Metasploit::Model::Module::Path#real_pathname' do
1909
+ let(:parent_path_real_pathname) do
1910
+ nil
1911
+ end
1912
+
1913
+ it { should be_nil }
1914
+ end
1915
+ end
1916
+
1917
+ context 'without #parent_path' do
1918
+ let(:parent_path) do
1919
+ nil
1920
+ end
1921
+
1922
+ it { should be_nil }
1923
+ end
1924
+ end
1925
+
1926
+ context 'without #real_pathname' do
1927
+ let(:real_pathname) do
1928
+ nil
1929
+ end
1930
+
1931
+ it { should be_nil }
1932
+ end
1933
+ end
1934
+
1935
+ context '#reference_path' do
1936
+ subject(:reference_path) do
1937
+ module_ancestor.reference_path
1938
+ end
1939
+
1940
+ let(:module_ancestor) do
1941
+ module_ancestor_class.new(
1942
+ :reference_name => reference_name
1943
+ )
1944
+ end
1945
+
1946
+ context 'with reference_name' do
1947
+ let(:reference_name) do
1948
+ FactoryGirl.generate :metasploit_model_module_ancestor_non_payload_reference_name
1949
+ end
1950
+
1951
+ it 'should be reference_name + EXTENSION' do
1952
+ reference_path.should == "#{reference_name}#{Metasploit::Model::Module::Ancestor::EXTENSION}"
1953
+ end
1954
+ end
1955
+
1956
+ context 'without reference_name' do
1957
+ let(:reference_name) do
1958
+ nil
1959
+ end
1960
+
1961
+ it { should be_nil }
1962
+ end
1963
+ end
1964
+
1965
+ context '#module_type_directory' do
1966
+ subject(:module_type_directory) do
1967
+ module_ancestor.module_type_directory
1968
+ end
1969
+
1970
+ let(:module_ancestor) do
1971
+ module_ancestor_class.new(
1972
+ :module_type => module_type
1973
+ )
1974
+ end
1975
+
1976
+ context 'with module_type' do
1977
+ context 'in known types' do
1978
+ let(:module_type) do
1979
+ FactoryGirl.generate :metasploit_model_module_type
1980
+ end
1981
+
1982
+ it 'should use Metasploit::Model::Module::Ancestor::DIRECTORY_BY_MODULE_TYPE' do
1983
+ module_type_directory.should == Metasploit::Model::Module::Ancestor::DIRECTORY_BY_MODULE_TYPE[module_type]
1984
+ end
1985
+ end
1986
+
1987
+ context 'in unknown types' do
1988
+ let(:module_type) do
1989
+ 'not_a_type'
1990
+ end
1991
+
1992
+ it { should be_nil }
1993
+ end
1994
+ end
1995
+
1996
+ context 'without module_type' do
1997
+ let(:module_type) do
1998
+ nil
1999
+ end
2000
+
2001
+ it { should be_nil }
2002
+ end
2003
+ end
2004
+ end