metasploit-model 0.24.1.pre.semantic.pre.versioning.pre.2.pre.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (380) hide show
  1. checksums.yaml +15 -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 +33 -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 +748 -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