shadowbq-threatinator 0.5.0

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 (389) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +66 -0
  3. data/CONTRIBUTING.md +119 -0
  4. data/Gemfile +38 -0
  5. data/LICENSE +165 -0
  6. data/README.md +101 -0
  7. data/Rakefile +47 -0
  8. data/VERSION +1 -0
  9. data/bin/threatinator +5 -0
  10. data/bin/threatinator_loader +21 -0
  11. data/feeds/ET_block-ip_reputation.feed +27 -0
  12. data/feeds/ET_compromised-ip_reputation.feed +20 -0
  13. data/feeds/ET_openbadlist-ip_reputation.feed +36 -0
  14. data/feeds/alienvault-ip_reputation.feed +39 -0
  15. data/feeds/arbor_fastflux-domain_reputation.feed +19 -0
  16. data/feeds/arbor_ssh-ip_reputation.feed +24 -0
  17. data/feeds/autoshun_shunlist.feed +17 -0
  18. data/feeds/bambenek_c2_masterlist-domain_reputation.feed +16 -0
  19. data/feeds/bambenek_c2_masterlist-ip_reputation.feed +16 -0
  20. data/feeds/bambenek_dga_feed-domain_reputation.feed +16 -0
  21. data/feeds/berkeley-ip_reputation.feed +25 -0
  22. data/feeds/bitcash_cz_blacklist.feed +22 -0
  23. data/feeds/blocklist_de_apache-ip_reputation.feed +26 -0
  24. data/feeds/blocklist_de_bots-ip_reputation.feed +26 -0
  25. data/feeds/blocklist_de_ftp-ip_reputation.feed +25 -0
  26. data/feeds/blocklist_de_imap-ip_reputation.feed +25 -0
  27. data/feeds/blocklist_de_pop3-ip_reputation.feed +26 -0
  28. data/feeds/blocklist_de_proftpd-ip_reputation.feed +26 -0
  29. data/feeds/blocklist_de_sip-ip_reputation.feed +25 -0
  30. data/feeds/blocklist_de_ssh-ip_reputation.feed +25 -0
  31. data/feeds/blocklist_de_strongips-ip_reputation.feed +25 -0
  32. data/feeds/botscout-ip_reputation.feed +25 -0
  33. data/feeds/cert_mxpoison-ip_reputation.feed +22 -0
  34. data/feeds/chaosreigns-ip_reputation.feed +37 -0
  35. data/feeds/ciarmy-ip_reputation.feed +20 -0
  36. data/feeds/cruzit-ip_reputation.feed +30 -0
  37. data/feeds/cydef_torexit-ip_reputation.feed +25 -0
  38. data/feeds/dan_me_uk_torlist-ip_reputation.feed +25 -0
  39. data/feeds/danger_bruteforce-ip_reputation.feed +24 -0
  40. data/feeds/dshield_attackers-top1000.feed +34 -0
  41. data/feeds/falconcrest-ip_reputation.feed +19 -0
  42. data/feeds/feodo-domain_reputation.feed +19 -0
  43. data/feeds/feodo-ip_reputation.feed +20 -0
  44. data/feeds/h3x_asprox.feed +18 -0
  45. data/feeds/hosts-file_hphostspartial-domain_reputation.feed +19 -0
  46. data/feeds/infiltrated-ip_reputation.feed +26 -0
  47. data/feeds/infiltrated_vabl-ip_reputation.feed +30 -0
  48. data/feeds/isc_suspicious_high-domain_reputation.feed +26 -0
  49. data/feeds/isc_suspicious_low-domain_reputation.feed +26 -0
  50. data/feeds/isc_suspicious_medium-domain_reputation.feed +26 -0
  51. data/feeds/malc0de-domain_reputation.feed +24 -0
  52. data/feeds/malc0de-ip_reputation.feed +26 -0
  53. data/feeds/malwaredomainlist-url_reputation.feed +18 -0
  54. data/feeds/malwaredomains-domain_reputation.feed +29 -0
  55. data/feeds/malwaredomains_dyndns-domain_reputation.feed +29 -0
  56. data/feeds/malwaredomains_justdomains-domain_reputation.feed +20 -0
  57. data/feeds/mirc-domain_reputation.feed +30 -0
  58. data/feeds/multiproxy-ip_reputation.feed +22 -0
  59. data/feeds/nothink_irc-ip_reputation.feed +23 -0
  60. data/feeds/nothink_ssh-ip_reputation.feed +21 -0
  61. data/feeds/openbl-ip_reputation.feed +21 -0
  62. data/feeds/openphish-url_reputation.feed +24 -0
  63. data/feeds/packetmail_perimeterbad-ip_reputation.feed +28 -0
  64. data/feeds/palevo-domain_reputation.feed +22 -0
  65. data/feeds/palevo-ip_reputation.feed +23 -0
  66. data/feeds/phishtank.feed +22 -0
  67. data/feeds/sigmaproject_atma.feed +27 -0
  68. data/feeds/sigmaproject_spyware.feed +28 -0
  69. data/feeds/sigmaproject_webexploit.feed +26 -0
  70. data/feeds/snort_bpf-ip_reputation.feed +19 -0
  71. data/feeds/spyeye-domain_reputation.feed +18 -0
  72. data/feeds/spyeye-ip_reputation.feed +19 -0
  73. data/feeds/steeman-ip_reputation.feed +20 -0
  74. data/feeds/t-arend-de_ssh-ip_reputation.feed +20 -0
  75. data/feeds/the_haleys_ssh-ip_reputation.feed +20 -0
  76. data/feeds/trustedsec-ip_reputation.feed +18 -0
  77. data/feeds/virbl-ip_reputation.feed +25 -0
  78. data/feeds/vxvault-url_reputation.feed +23 -0
  79. data/feeds/yourcmc_ssh-ip_reputation.feed +20 -0
  80. data/feeds/yoyo_adservers-domain_reputation.feed +17 -0
  81. data/feeds/zeus-domain_reputation.feed +19 -0
  82. data/feeds/zeus-ip_reputation.feed +21 -0
  83. data/lib/threatinator/action.rb +14 -0
  84. data/lib/threatinator/actions/list/action.rb +97 -0
  85. data/lib/threatinator/actions/list/config.rb +12 -0
  86. data/lib/threatinator/actions/list.rb +2 -0
  87. data/lib/threatinator/actions/run/action.rb +57 -0
  88. data/lib/threatinator/actions/run/config.rb +32 -0
  89. data/lib/threatinator/actions/run/coverage_observer.rb +59 -0
  90. data/lib/threatinator/actions/run/output_config.rb +59 -0
  91. data/lib/threatinator/actions/run/status_observer.rb +37 -0
  92. data/lib/threatinator/actions/run.rb +2 -0
  93. data/lib/threatinator/cli/action_builder.rb +33 -0
  94. data/lib/threatinator/cli/list_action_builder.rb +19 -0
  95. data/lib/threatinator/cli/parser.rb +123 -0
  96. data/lib/threatinator/cli/run_action_builder.rb +41 -0
  97. data/lib/threatinator/cli.rb +19 -0
  98. data/lib/threatinator/config/base.rb +35 -0
  99. data/lib/threatinator/config/feed_search.rb +25 -0
  100. data/lib/threatinator/config/logger.rb +14 -0
  101. data/lib/threatinator/config.rb +7 -0
  102. data/lib/threatinator/decoder.rb +24 -0
  103. data/lib/threatinator/decoders/gzip.rb +30 -0
  104. data/lib/threatinator/event.rb +63 -0
  105. data/lib/threatinator/event_builder.rb +70 -0
  106. data/lib/threatinator/exceptions.rb +58 -0
  107. data/lib/threatinator/feed.rb +88 -0
  108. data/lib/threatinator/feed_builder.rb +161 -0
  109. data/lib/threatinator/feed_registry.rb +47 -0
  110. data/lib/threatinator/feed_runner.rb +177 -0
  111. data/lib/threatinator/fetcher.rb +22 -0
  112. data/lib/threatinator/fetchers/http.rb +50 -0
  113. data/lib/threatinator/filter.rb +12 -0
  114. data/lib/threatinator/filters/block.rb +18 -0
  115. data/lib/threatinator/filters/comments.rb +16 -0
  116. data/lib/threatinator/filters/whitespace.rb +19 -0
  117. data/lib/threatinator/logger.rb +66 -0
  118. data/lib/threatinator/logging.rb +20 -0
  119. data/lib/threatinator/model/base.rb +23 -0
  120. data/lib/threatinator/model/collection.rb +89 -0
  121. data/lib/threatinator/model/observables/fqdn_collection.rb +15 -0
  122. data/lib/threatinator/model/observables/ipv4.rb +33 -0
  123. data/lib/threatinator/model/observables/ipv4_collection.rb +14 -0
  124. data/lib/threatinator/model/observables/url_collection.rb +16 -0
  125. data/lib/threatinator/model/validations/type.rb +21 -0
  126. data/lib/threatinator/model/validations.rb +1 -0
  127. data/lib/threatinator/output.rb +50 -0
  128. data/lib/threatinator/parser.rb +23 -0
  129. data/lib/threatinator/parsers/csv/parser.rb +77 -0
  130. data/lib/threatinator/parsers/csv.rb +7 -0
  131. data/lib/threatinator/parsers/getline/parser.rb +45 -0
  132. data/lib/threatinator/parsers/getline.rb +8 -0
  133. data/lib/threatinator/parsers/json/adapters/oj.rb +65 -0
  134. data/lib/threatinator/parsers/json/parser.rb +45 -0
  135. data/lib/threatinator/parsers/json/record.rb +20 -0
  136. data/lib/threatinator/parsers/json.rb +8 -0
  137. data/lib/threatinator/parsers/xml/node.rb +79 -0
  138. data/lib/threatinator/parsers/xml/node_builder.rb +39 -0
  139. data/lib/threatinator/parsers/xml/parser.rb +44 -0
  140. data/lib/threatinator/parsers/xml/path.rb +70 -0
  141. data/lib/threatinator/parsers/xml/pattern.rb +53 -0
  142. data/lib/threatinator/parsers/xml/record.rb +14 -0
  143. data/lib/threatinator/parsers/xml/sax_document.rb +64 -0
  144. data/lib/threatinator/parsers/xml.rb +8 -0
  145. data/lib/threatinator/plugin_loader.rb +115 -0
  146. data/lib/threatinator/plugins/output/amqp/config.rb +18 -0
  147. data/lib/threatinator/plugins/output/amqp.rb +41 -0
  148. data/lib/threatinator/plugins/output/csv.rb +58 -0
  149. data/lib/threatinator/plugins/output/json/config.rb +14 -0
  150. data/lib/threatinator/plugins/output/json.rb +53 -0
  151. data/lib/threatinator/plugins/output/null.rb +17 -0
  152. data/lib/threatinator/plugins/output/rubydebug.rb +16 -0
  153. data/lib/threatinator/record.rb +22 -0
  154. data/lib/threatinator/registry.rb +53 -0
  155. data/lib/threatinator/util.rb +15 -0
  156. data/lib/threatinator.rb +3 -0
  157. data/spec/feeds/ET_block-ip_reputation_spec.rb +50 -0
  158. data/spec/feeds/ET_compromised-ip_reputation_spec.rb +47 -0
  159. data/spec/feeds/ET_openbadlist-ip_reputation_spec.rb +56 -0
  160. data/spec/feeds/alienvault-ip_reputation_spec.rb +46 -0
  161. data/spec/feeds/arbor_fastflux-domain_reputation_spec.rb +46 -0
  162. data/spec/feeds/arbor_ssh-ip_reputation_spec.rb +46 -0
  163. data/spec/feeds/autoshun_shunlist_spec.rb +38 -0
  164. data/spec/feeds/bambenek_c2_masterlist-domain_reputation_spec.rb +38 -0
  165. data/spec/feeds/bambenek_c2_masterlist-ip_reputation_spec.rb +39 -0
  166. data/spec/feeds/bambenek_dga_feed-domain_reputation_spec.rb +39 -0
  167. data/spec/feeds/berkeley-ip_reputation_spec.rb +47 -0
  168. data/spec/feeds/bitcash_cz_blacklist-ip_reputation_spec.rb +50 -0
  169. data/spec/feeds/blocklist_de_apache-ip_reputation_spec.rb +47 -0
  170. data/spec/feeds/blocklist_de_bots-ip_reputation_spec.rb +47 -0
  171. data/spec/feeds/blocklist_de_ftp-ip_reputation_spec.rb +47 -0
  172. data/spec/feeds/blocklist_de_imap-ip_reputation_spec.rb +47 -0
  173. data/spec/feeds/blocklist_de_pop3-ip_reputation_spec.rb +47 -0
  174. data/spec/feeds/blocklist_de_proftpd-ip_reputation_spec.rb +47 -0
  175. data/spec/feeds/blocklist_de_sip-ip_reputation_spec.rb +47 -0
  176. data/spec/feeds/blocklist_de_ssh-ip_reputation_spec.rb +47 -0
  177. data/spec/feeds/blocklist_de_strongips-ip_reputation_spec.rb +47 -0
  178. data/spec/feeds/botscout-ip_reputation_spec.rb +50 -0
  179. data/spec/feeds/cert_mxpoison-ip_reputation_spec.rb +47 -0
  180. data/spec/feeds/chaosreigns-ip_reputation_spec.rb +50 -0
  181. data/spec/feeds/ciarmy-ip_reputation_spec.rb +47 -0
  182. data/spec/feeds/cruzit-ip_reputation_spec.rb +47 -0
  183. data/spec/feeds/cydef_torexit-ip_reputation_spec.rb +47 -0
  184. data/spec/feeds/dan_me_uk_torlist-ip_reputation_spec.rb +47 -0
  185. data/spec/feeds/danger_bruteforce-ip_reputation_spec.rb +47 -0
  186. data/spec/feeds/data/ET_block-ip_reputation.txt +80 -0
  187. data/spec/feeds/data/ET_compromised-ip_reputation.txt +11 -0
  188. data/spec/feeds/data/ET_openbadlist-ip_reputation.txt +62 -0
  189. data/spec/feeds/data/alienvault-ip_reputation.txt +18 -0
  190. data/spec/feeds/data/arbor_domainlist.txt +11 -0
  191. data/spec/feeds/data/arbor_ssh.txt +16 -0
  192. data/spec/feeds/data/autoshun_shunlist.csv +20 -0
  193. data/spec/feeds/data/bambenek_c2-dommasterlist.csv +30 -0
  194. data/spec/feeds/data/bambenek_c2-ipmasterlist.csv +27 -0
  195. data/spec/feeds/data/bambenek_dga_feed.csv +42 -0
  196. data/spec/feeds/data/berkeley.txt +29 -0
  197. data/spec/feeds/data/bitcash_cz_blacklist.txt +7 -0
  198. data/spec/feeds/data/blocklist_de_apache-ip-reputation.txt +17 -0
  199. data/spec/feeds/data/blocklist_de_bots-ip-reputation.txt +15 -0
  200. data/spec/feeds/data/blocklist_de_ftp-ip-reputation.txt +7 -0
  201. data/spec/feeds/data/blocklist_de_imap-ip-reputation.txt +8 -0
  202. data/spec/feeds/data/blocklist_de_pop3-ip-reputation.txt +11 -0
  203. data/spec/feeds/data/blocklist_de_proftpd-ip-reputation.txt +12 -0
  204. data/spec/feeds/data/blocklist_de_sip-ip-reputation.txt +9 -0
  205. data/spec/feeds/data/blocklist_de_ssh-ip-reputation.txt +10 -0
  206. data/spec/feeds/data/blocklist_de_strongips-ip-reputation.txt +11 -0
  207. data/spec/feeds/data/botscout-ip-reputation.txt +713 -0
  208. data/spec/feeds/data/cert_mxpoison-ip_reputation.txt +17 -0
  209. data/spec/feeds/data/chaosreigns-ip-reputation.txt +26 -0
  210. data/spec/feeds/data/ciarmy-ip-reputation.txt +11 -0
  211. data/spec/feeds/data/cruzit-ip-reputation.txt +14 -0
  212. data/spec/feeds/data/cydef_torexit-ip_reputation.txt +27 -0
  213. data/spec/feeds/data/dan_me_uk_torlist-ip-reputation.txt +11 -0
  214. data/spec/feeds/data/danger_bruteforce-ip_reputation.txt +12 -0
  215. data/spec/feeds/data/dshield_topattackers.xml +4 -0
  216. data/spec/feeds/data/falconcrest_iplist.txt +345 -0
  217. data/spec/feeds/data/feodo_domainlist.txt +18 -0
  218. data/spec/feeds/data/feodo_iplist.txt +20 -0
  219. data/spec/feeds/data/h3x_asprox.txt +20 -0
  220. data/spec/feeds/data/hosts-file_hphostspartial_domainlist.txt +24 -0
  221. data/spec/feeds/data/infiltrated_iplist.txt +16 -0
  222. data/spec/feeds/data/infiltrated_vabl_iplist.txt +33 -0
  223. data/spec/feeds/data/isc_suspicious_high_domainlist.txt +26 -0
  224. data/spec/feeds/data/isc_suspicious_low_domainlist.txt +34 -0
  225. data/spec/feeds/data/isc_suspicious_medium_domainlist.txt +32 -0
  226. data/spec/feeds/data/malc0de_domainlist.txt +18 -0
  227. data/spec/feeds/data/malc0de_iplist.txt +14 -0
  228. data/spec/feeds/data/malwaredomainlist-url-reputation.txt +8 -0
  229. data/spec/feeds/data/malwaredomains_domainlist.txt +24 -0
  230. data/spec/feeds/data/malwaredomains_dyndns_domainlist.txt +34 -0
  231. data/spec/feeds/data/malwaredomains_justdomains_domainlist.txt +18 -0
  232. data/spec/feeds/data/mirc_domainlist.txt +31 -0
  233. data/spec/feeds/data/multiproxy_iplist.txt +15 -0
  234. data/spec/feeds/data/nothink_irc_iplist.txt +14 -0
  235. data/spec/feeds/data/nothink_ssh_iplist.txt +10 -0
  236. data/spec/feeds/data/openbl_iplist.txt +12 -0
  237. data/spec/feeds/data/openphish-url-reputation.txt +16 -0
  238. data/spec/feeds/data/packetmail_perimeterbad-ip_reputation.txt +44 -0
  239. data/spec/feeds/data/palevo_domainlist.txt +25 -0
  240. data/spec/feeds/data/palevo_iplist.txt +24 -0
  241. data/spec/feeds/data/phishtank-sample.json.gz +0 -0
  242. data/spec/feeds/data/sigmaproject_atma.return.gz +0 -0
  243. data/spec/feeds/data/sigmaproject_spyware.return.gz +0 -0
  244. data/spec/feeds/data/sigmaproject_webexploit.return.gz +0 -0
  245. data/spec/feeds/data/snort_bpf-ip_reputation.txt +16 -0
  246. data/spec/feeds/data/spyeye_domainlist.txt +16 -0
  247. data/spec/feeds/data/spyeye_iplist.txt +19 -0
  248. data/spec/feeds/data/steeman-ip-reputation.txt +13 -0
  249. data/spec/feeds/data/t-arend-de_ssh_iplist.txt +17 -0
  250. data/spec/feeds/data/the_haleys_ssh_iplist.txt +12 -0
  251. data/spec/feeds/data/trustedsec-ip-reputation.txt +12 -0
  252. data/spec/feeds/data/valid.json +2908 -0
  253. data/spec/feeds/data/virbl-ip_reputation.txt +14 -0
  254. data/spec/feeds/data/vxvault-url-reputation.txt +15 -0
  255. data/spec/feeds/data/yourcmc_ssh-ip_reputation.txt +27 -0
  256. data/spec/feeds/data/yoyo_adservers.txt +25 -0
  257. data/spec/feeds/data/zeus-ip_reputation.txt +285 -0
  258. data/spec/feeds/data/zeus_domainlist.txt +27 -0
  259. data/spec/feeds/dshield_attackers-top1000_spec.rb +39 -0
  260. data/spec/feeds/falconcrest-ip_reputation_spec.rb +39 -0
  261. data/spec/feeds/feodo-domain_reputation_spec.rb +47 -0
  262. data/spec/feeds/feodo-ip_reputation_spec.rb +47 -0
  263. data/spec/feeds/h3x_asprox-ip_reputation_spec.rb +50 -0
  264. data/spec/feeds/hosts-file_hphostspartial-domain_reputation_spec.rb +47 -0
  265. data/spec/feeds/infiltrated-ip_reputation_spec.rb +47 -0
  266. data/spec/feeds/infiltrated_vabl-ip_reputation_spec.rb +47 -0
  267. data/spec/feeds/isc_suspicious_high-domain_reputation_spec.rb +47 -0
  268. data/spec/feeds/isc_suspicious_low-domain_reputation_spec.rb +47 -0
  269. data/spec/feeds/isc_suspicious_medium-domain_reputation_spec.rb +47 -0
  270. data/spec/feeds/malc0de-domain_reputation_spec.rb +47 -0
  271. data/spec/feeds/malc0de-ip_reputation_spec.rb +47 -0
  272. data/spec/feeds/malwaredomainlist_url_reputation_spec.rb +50 -0
  273. data/spec/feeds/malwaredomains-domain_reputation_spec.rb +47 -0
  274. data/spec/feeds/malwaredomains_dyndns-domain_reputation_spec.rb +47 -0
  275. data/spec/feeds/malwaredomains_justdomains-domain_reputation_spec.rb +47 -0
  276. data/spec/feeds/mirc-domain_reputation_spec.rb +47 -0
  277. data/spec/feeds/multiproxy-ip_reputation_spec.rb +47 -0
  278. data/spec/feeds/nothink_irc-ip_reputation_spec.rb +47 -0
  279. data/spec/feeds/nothink_ssh-ip_reputation_spec.rb +47 -0
  280. data/spec/feeds/openbl-ip_reputation_spec.rb +47 -0
  281. data/spec/feeds/openphish_url_reputation_spec.rb +50 -0
  282. data/spec/feeds/packetmail_perimeterbad-ip_reputation_spec.rb +47 -0
  283. data/spec/feeds/palevo-domain_reputation_spec.rb +47 -0
  284. data/spec/feeds/palevo-ip_reputation_spec.rb +47 -0
  285. data/spec/feeds/phishtank_spec.rb +41 -0
  286. data/spec/feeds/sigmaproject_atma_spec.rb +62 -0
  287. data/spec/feeds/sigmaproject_spyware_spec.rb +63 -0
  288. data/spec/feeds/sigmaproject_webexploit_spec.rb +62 -0
  289. data/spec/feeds/snort_bpf-ip_reputation_spec.rb +47 -0
  290. data/spec/feeds/spyeye-domain_reputation_spec.rb +47 -0
  291. data/spec/feeds/spyeye-ip_reputation_spec.rb +47 -0
  292. data/spec/feeds/steeman-ip_reputation_spec.rb +50 -0
  293. data/spec/feeds/t-arend-de_ssh-ip_reputation_spec.rb +47 -0
  294. data/spec/feeds/the_haleys_ssh-ip_reputation_spec.rb +47 -0
  295. data/spec/feeds/trustedsec-ip_reputation_spec.rb +47 -0
  296. data/spec/feeds/virbl-ip_reputation_spec.rb +47 -0
  297. data/spec/feeds/vxvault_url_reputation_spec.rb +50 -0
  298. data/spec/feeds/yourcmc_ssh-ip_reputation_spec.rb +47 -0
  299. data/spec/feeds/yoyo_adservers_spec.rb +47 -0
  300. data/spec/feeds/zeus-domain_reputation_spec.rb +47 -0
  301. data/spec/feeds/zeus-ip_reputation_spec.rb +47 -0
  302. data/spec/fixtures/feed/provider1/feed1.feed +6 -0
  303. data/spec/fixtures/parsers/test.xml +13 -0
  304. data/spec/fixtures/parsers/test_self_closing.xml +20 -0
  305. data/spec/fixtures/plugins/bad/threatinator/plugins/test_error1/plugin.rb +1 -0
  306. data/spec/fixtures/plugins/bad/threatinator/plugins/test_missing1/plugin.rb +0 -0
  307. data/spec/fixtures/plugins/fake.rb +19 -0
  308. data/spec/fixtures/plugins/good/threatinator/plugins/test_type1/plugin_a.rb +8 -0
  309. data/spec/fixtures/plugins/good/threatinator/plugins/test_type1/plugin_b.rb +8 -0
  310. data/spec/fixtures/plugins/good/threatinator/plugins/test_type2/plugin_c.rb +8 -0
  311. data/spec/fixtures/plugins/good/threatinator/plugins/test_type2/plugin_d.rb +8 -0
  312. data/spec/fixtures/plugins/good/threatinator/plugins/test_type3/plugin_e.rb +8 -0
  313. data/spec/fixtures/plugins/good/threatinator/plugins/test_type3/plugin_f.rb +8 -0
  314. data/spec/spec_helper.rb +54 -0
  315. data/spec/support/bad_feeds/missing_fetcher.feed +7 -0
  316. data/spec/support/bad_feeds/missing_name.feed +6 -0
  317. data/spec/support/bad_feeds/missing_parser.feed +3 -0
  318. data/spec/support/bad_feeds/missing_provider.feed +5 -0
  319. data/spec/support/factories/event.rb +31 -0
  320. data/spec/support/factories/feed.rb +59 -0
  321. data/spec/support/factories/feed_builder.rb +65 -0
  322. data/spec/support/factories/feed_registry.rb +8 -0
  323. data/spec/support/factories/ipv4.rb +36 -0
  324. data/spec/support/factories/output.rb +11 -0
  325. data/spec/support/factories/record.rb +17 -0
  326. data/spec/support/factories/url.rb +34 -0
  327. data/spec/support/factories/xml_node.rb +33 -0
  328. data/spec/support/helpers/io.rb +11 -0
  329. data/spec/support/helpers/models.rb +13 -0
  330. data/spec/support/shared/action_builder.rb +47 -0
  331. data/spec/support/shared/decoder.rb +70 -0
  332. data/spec/support/shared/feed_runner_observer.rb +136 -0
  333. data/spec/support/shared/feeds.rb +233 -0
  334. data/spec/support/shared/fetcher.rb +48 -0
  335. data/spec/support/shared/filter.rb +14 -0
  336. data/spec/support/shared/io-like.rb +7 -0
  337. data/spec/support/shared/model/collection.rb +164 -0
  338. data/spec/support/shared/output.rb +120 -0
  339. data/spec/support/shared/parsers.rb +51 -0
  340. data/spec/support/shared/record.rb +111 -0
  341. data/spec/threatinator/actions/list/action_spec.rb +148 -0
  342. data/spec/threatinator/actions/run/action_spec.rb +106 -0
  343. data/spec/threatinator/actions/run/config_spec.rb +39 -0
  344. data/spec/threatinator/actions/run/coverage_observer_spec.rb +151 -0
  345. data/spec/threatinator/actions/run/output_config_spec.rb +89 -0
  346. data/spec/threatinator/actions/run/status_observer_spec.rb +86 -0
  347. data/spec/threatinator/cli/list_action_builder_spec.rb +57 -0
  348. data/spec/threatinator/cli/run_action_builder_spec.rb +133 -0
  349. data/spec/threatinator/cli_spec.rb +175 -0
  350. data/spec/threatinator/config/base_spec.rb +39 -0
  351. data/spec/threatinator/config/feed_search_spec.rb +76 -0
  352. data/spec/threatinator/decoders/gzip_spec.rb +75 -0
  353. data/spec/threatinator/event_builder_spec.rb +123 -0
  354. data/spec/threatinator/event_spec.rb +254 -0
  355. data/spec/threatinator/event_spec.rb.new +319 -0
  356. data/spec/threatinator/feed_builder_spec.rb +633 -0
  357. data/spec/threatinator/feed_registry_spec.rb +198 -0
  358. data/spec/threatinator/feed_runner_spec.rb +372 -0
  359. data/spec/threatinator/feed_spec.rb +169 -0
  360. data/spec/threatinator/fetcher_spec.rb +12 -0
  361. data/spec/threatinator/fetchers/http_spec.rb +32 -0
  362. data/spec/threatinator/filter_spec.rb +13 -0
  363. data/spec/threatinator/filters/block_spec.rb +16 -0
  364. data/spec/threatinator/filters/comments_spec.rb +13 -0
  365. data/spec/threatinator/filters/whitespace_spec.rb +12 -0
  366. data/spec/threatinator/logger_spec.rb +29 -0
  367. data/spec/threatinator/model/observables/fqdn_collection_spec.rb +41 -0
  368. data/spec/threatinator/model/observables/ipv4_collection_spec.rb +36 -0
  369. data/spec/threatinator/model/observables/ipv4_spec.rb +75 -0
  370. data/spec/threatinator/model/observables/url_collection_spec.rb +45 -0
  371. data/spec/threatinator/model/validations/type_spec.rb +37 -0
  372. data/spec/threatinator/parser_spec.rb +13 -0
  373. data/spec/threatinator/parsers/csv/parser_spec.rb +202 -0
  374. data/spec/threatinator/parsers/getline/parser_spec.rb +83 -0
  375. data/spec/threatinator/parsers/json/parser_spec.rb +106 -0
  376. data/spec/threatinator/parsers/json/record_spec.rb +30 -0
  377. data/spec/threatinator/parsers/xml/node_spec.rb +335 -0
  378. data/spec/threatinator/parsers/xml/parser_spec.rb +263 -0
  379. data/spec/threatinator/parsers/xml/path_spec.rb +209 -0
  380. data/spec/threatinator/parsers/xml/pattern_spec.rb +72 -0
  381. data/spec/threatinator/parsers/xml/record_spec.rb +27 -0
  382. data/spec/threatinator/plugin_loader_spec.rb +238 -0
  383. data/spec/threatinator/plugins/output/csv_spec.rb +47 -0
  384. data/spec/threatinator/plugins/output/null_spec.rb +17 -0
  385. data/spec/threatinator/plugins/output/rubydebug_spec.rb +37 -0
  386. data/spec/threatinator/record_spec.rb +19 -0
  387. data/spec/threatinator/registry_spec.rb +97 -0
  388. data/spec/threatinator/runner_spec.rb +273 -0
  389. metadata +674 -0
@@ -0,0 +1,39 @@
1
+ require 'threatinator/parsers/xml/node'
2
+
3
+ module Threatinator
4
+ module Parsers
5
+ module XML
6
+ class NodeBuilder
7
+ def initialize(name, attributes)
8
+ @name = name
9
+ @attributes = {}
10
+ @children = []
11
+ @text = ""
12
+
13
+ unless attributes.empty?
14
+ attributes.each { |attr| self.add_attribute(attr.localname, attr.value) }
15
+ end
16
+ end
17
+
18
+ def append_text(chars)
19
+ @text << chars
20
+ end
21
+
22
+ def add_attribute(name, value)
23
+ @attributes[name.to_sym] = value
24
+ end
25
+
26
+ def add_child(node)
27
+ @children << node
28
+ end
29
+
30
+ def build
31
+ Threatinator::Parsers::XML::Node.new(@name,
32
+ attrs: @attributes,
33
+ text: @text.strip,
34
+ children: @children)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,44 @@
1
+ require 'threatinator/parser'
2
+ require 'nokogiri'
3
+
4
+ module Threatinator
5
+ module Parsers
6
+ module XML
7
+ class Parser < Threatinator::Parser
8
+ require 'threatinator/parsers/xml/path'
9
+ require 'threatinator/parsers/xml/record'
10
+ require 'threatinator/parsers/xml/sax_document'
11
+
12
+ attr_reader :pattern
13
+ # @param [Hash] opts Parameters hash
14
+ # @option opts [Threatinator::Parsers::XML::Pattern] :pattern The pattern
15
+ # object to use for matching chunks of XML
16
+ def initialize(opts = {})
17
+ @pattern = opts.delete(:pattern) or raise ArgumentError.new("Missing argument :pattern")
18
+ @max_cursor_depth = @pattern.max_depth - 1
19
+ super(opts)
20
+ end
21
+
22
+ def ==(other)
23
+ @pattern == other.pattern &&
24
+ super(other)
25
+ end
26
+
27
+ # @param [IO] io
28
+ # @yield [record] Gives one line to the block
29
+ # @yieldparam record [Threatinator::Parser::XML::Record] a record
30
+ def run(io)
31
+ stack = Path.new
32
+ callback = lambda do |element|
33
+ yield(Threatinator::Parsers::XML::Record.new(element))
34
+ end
35
+
36
+ doc = SAXDocument.new(@pattern, callback)
37
+ parser = Nokogiri::XML::SAX::Parser.new(doc)
38
+ parser.parse(io)
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,70 @@
1
+ module Threatinator
2
+ module Parsers
3
+ module XML
4
+ class Path
5
+ attr_reader :parts
6
+
7
+ # @param [String, Array, nil] str_or_parts ([]) If set to a String, splits
8
+ # the string by '/' into an array. If set to an Array, sets parts to a
9
+ # duplicate of the array. If set to nil or not specified, defaults to
10
+ # a new array.
11
+ # @raise [TypeError] if something other than a String, Array, or nil is
12
+ # specified for str_or_parts.
13
+ def initialize(str_or_parts = nil)
14
+ @parts =
15
+ case str_or_parts
16
+ when ::String
17
+ if str_or_parts.length == 0 or !str_or_parts.start_with?('/')
18
+ raise ArgumentError.new('str_or_parts must be a String beginning with "/"')
19
+ end
20
+ r = str_or_parts.split('/')
21
+ r.shift
22
+ r
23
+ when ::Array
24
+ str_or_parts.dup
25
+ when nil
26
+ []
27
+ else
28
+ raise TypeError.new("Expected argument must be a String, Array, or nil")
29
+ end
30
+ end
31
+
32
+ def ==(other)
33
+ @parts == other.parts
34
+ end
35
+
36
+ def eql?(other)
37
+ other.kind_of?(self.class) &&
38
+ self == other
39
+ end
40
+
41
+ # length = 5
42
+ # 0 1 2 3 4
43
+ # /a/b/c/d/e
44
+ # 0 1
45
+ # /d/e
46
+ def end_with?(other_path)
47
+ return false if other_path.length > self.length
48
+ return true if other_path.length == 0
49
+ pos = length - other_path.length
50
+ other_path.parts.each_with_index do |other_part, idx|
51
+ return false unless @parts[(pos + idx)] == other_part
52
+ end
53
+ true
54
+ end
55
+
56
+ def push(name)
57
+ @parts.push(name)
58
+ end
59
+
60
+ def pop
61
+ @parts.pop
62
+ end
63
+
64
+ def length
65
+ @parts.length
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,53 @@
1
+ require 'threatinator/parsers/xml/path'
2
+
3
+ module Threatinator
4
+ module Parsers
5
+ module XML
6
+ # Implements path matching behavior for use with the XML parser. Aims to support
7
+ # a small subset of XPath behaviors, specifically for matching elements.
8
+ class Pattern
9
+ # @param [String] pathspec A specification of a path match.
10
+ def initialize(pathspec)
11
+ parts = pathspec.split('/')
12
+ leader_count = 0
13
+ while parts[0] == ''
14
+ leader_count += 1
15
+ parts.shift
16
+ end
17
+ @path = Threatinator::Parsers::XML::Path.new(parts)
18
+ @anchored = true
19
+
20
+ if leader_count == 1
21
+ @anchored = true
22
+ elsif leader_count == 2
23
+ @anchored = false
24
+ else
25
+ raise ArgumentError.new('pathspec must begin with "/" or "//"')
26
+ end
27
+ end
28
+
29
+ def max_depth
30
+ @anchored == true ? @path.length : Float::INFINITY
31
+ end
32
+
33
+ # @param [Threatinator::Parsers::XML::Path] path
34
+ # @return [Boolean] true if the pattern matches, false otherwise.
35
+ def match?(path)
36
+ if @anchored == true
37
+ @path == path
38
+ else
39
+ path.end_with?(@path)
40
+ end
41
+ end
42
+
43
+ def _internal_data
44
+ [@path, @anchored]
45
+ end
46
+
47
+ def ==(other)
48
+ _internal_data == other._internal_data
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,14 @@
1
+ require 'threatinator/record'
2
+
3
+ module Threatinator
4
+ module Parsers
5
+ module XML
6
+ class Record < Threatinator::Record
7
+ alias_method :node, :data
8
+ def initialize(node, opts = {})
9
+ super(node, opts)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,64 @@
1
+ require 'threatinator/parsers/xml/node_builder'
2
+ require 'threatinator/parsers/xml/path'
3
+ require 'nokogiri'
4
+
5
+ module Threatinator
6
+ module Parsers
7
+ module XML
8
+ class SAXDocument < Nokogiri::XML::SAX::Document
9
+ def initialize(pattern, cb)
10
+ @pattern = pattern
11
+ @max_depth = @pattern.max_depth
12
+ @cb = cb
13
+ @element_stack = Threatinator::Parsers::XML::Path.new
14
+ @parsing_stack = []
15
+ @current_node = nil
16
+ super()
17
+ end
18
+
19
+ def start_parsing(name, attributes)
20
+ @current_node = Threatinator::Parsers::XML::NodeBuilder.new(name, attributes)
21
+ @parsing_stack.push(@current_node)
22
+ end
23
+
24
+ def characters(str)
25
+ return if @current_node.nil?
26
+ @current_node.append_text(str)
27
+ end
28
+
29
+ alias_method :cdata_block, :characters
30
+
31
+ def start_element_namespace(name, attrs = [], prefix = nil, uri = nil, ns = [])
32
+ @element_stack.push(name)
33
+
34
+ if @parsing_stack.empty?
35
+ if @element_stack.length > @max_depth
36
+ return
37
+ end
38
+
39
+ if @pattern.match?(@element_stack)
40
+ start_parsing(name, attrs)
41
+ end
42
+ else
43
+ start_parsing(name, attrs)
44
+ end
45
+ end
46
+
47
+ def end_element_namespace(name, prefix = nil, uri = nil)
48
+ name_sym = name.to_sym
49
+ @element_stack.pop
50
+ return if @parsing_stack.empty?
51
+ @parsing_stack.pop
52
+
53
+ if parent = @parsing_stack.last
54
+ parent.add_child(@current_node.build)
55
+ @current_node = parent
56
+ else
57
+ @cb.call(@current_node.build)
58
+ @current_node = nil
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,8 @@
1
+ module Threatinator
2
+ module Parsers
3
+ module XML
4
+ require 'threatinator/parsers/xml/parser'
5
+ require 'threatinator/parsers/xml/pattern'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,115 @@
1
+ require 'rubygems'
2
+ require 'threatinator/util'
3
+ require 'threatinator/registry'
4
+
5
+ module Threatinator
6
+ class PluginLoader
7
+ def initialize()
8
+ @plugin_types_registry = Threatinator::Registry.new
9
+ end
10
+
11
+ # Loads all plugins
12
+ # @return [Threatinator::PluginLoader] self
13
+ def load_all_plugins()
14
+ load_plugins(:*)
15
+ return self
16
+ end
17
+
18
+ # Loads all plugins of the specified type
19
+ # @param [#to_sym] type
20
+ # @return [Threatinator::PluginLoader] self
21
+ def load_plugins(type)
22
+ load_files(find_plugin_files(type.to_sym))
23
+ return self
24
+ end
25
+
26
+ # Retrieves a loaded plugin by type and name.
27
+ # @param [#to_sym] type
28
+ # @param [#to_sym] name
29
+ # @return [Object] plugin
30
+ def get(type, name)
31
+ type_registry = @plugin_types_registry.get(type.to_sym)
32
+ return nil if type_registry.nil?
33
+ return type_registry.get(name.to_sym)
34
+ end
35
+
36
+ # Enumerates through all plugins, optionally filtered by type.
37
+ # @yield [type, name, plugin]
38
+ # @yieldparam [Symbol] type
39
+ # @yieldparam [Symbol] name
40
+ # @yieldparam [Object] plugin
41
+ def each(type = nil)
42
+ return enum_for(:each, type) unless block_given?
43
+ @plugin_types_registry.each do |t, type_registry|
44
+ unless type.nil?
45
+ next unless type.to_sym == t
46
+ end
47
+ type_registry.each do |name, plugin|
48
+ yield(t, name, plugin)
49
+ end
50
+ end
51
+ end
52
+
53
+ # Returns an array of all the types of plugins that are loaded.
54
+ # @return [Array<Symbol>]
55
+ def types
56
+ @plugin_types_registry.keys
57
+ end
58
+
59
+ # Registers a plugin with the provided type and name.
60
+ # @param [#to_sym] type
61
+ # @param [#to_sym] name
62
+ # @param [Object] plugin
63
+ # @raise [Threatinator::Exceptions::AlreadyRegisteredError
64
+ def register_plugin(type, name, plugin)
65
+ type = type.to_sym
66
+ unless type_registry = @plugin_types_registry.get(type)
67
+ type_registry = @plugin_types_registry.register(type, Threatinator::Registry.new)
68
+ end
69
+ type_registry.register(name.to_sym, plugin)
70
+ end
71
+
72
+ private
73
+
74
+ def find_plugin_files(type)
75
+ Gem.find_files("threatinator/plugins/#{type}/*.rb")
76
+ end
77
+
78
+ def register_plugin_by_name(type, name)
79
+ plugin_name = "Threatinator::Plugins::#{Threatinator::Util.underscore2cc(type)}::#{Threatinator::Util.underscore2cc(name)}"
80
+ begin
81
+ type_obj = Threatinator::Plugins.const_get(Threatinator::Util.underscore2cc(type))
82
+ plugin = type_obj.const_get(Threatinator::Util.underscore2cc(name))
83
+ register_plugin(type, name, plugin)
84
+ rescue ::NameError => e
85
+ raise Threatinator::Exceptions::PluginLoadError.new("Failed to load plugin '#{plugin_name}'", e)
86
+ end
87
+ end
88
+
89
+ def load_files(file_names)
90
+ file_names.each do |file_name|
91
+ path, type, name = split_file_name(file_name)
92
+ next if path.nil?
93
+ # Don't try to load unit tests as plugins :)
94
+ next if name.end_with?("_spec")
95
+ begin
96
+ require path
97
+ rescue ::LoadError
98
+ # TODO: Handle plugins inside of gems a bit better. We should try
99
+ # using only the latest version of a given Gem.
100
+ next
101
+ end
102
+
103
+ register_plugin_by_name(type, name)
104
+ end
105
+ end
106
+
107
+ # @return [Array, nil] an array containing the path, type, and name of the
108
+ # plugin
109
+ def split_file_name(file_name)
110
+ m = file_name.match(/(?<=(\A|\/))(?<path>threatinator\/plugins\/(?<type>[^\/]+)\/(?<name>[^\/\.]+))\.rb$/)
111
+ return nil if m.nil?
112
+ [m[:path], m[:type], m[:name]]
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,18 @@
1
+ require 'threatinator/output'
2
+
3
+ module Threatinator
4
+ module Plugins
5
+ module Output
6
+ require 'threatinator/plugins/output/amqp'
7
+ class Amqp
8
+ class Config < Threatinator::Output::Config
9
+ attribute :url, String, description: "The hostname/ip of the RabbitMQ server"
10
+
11
+ attribute :routing_key, String, default: lambda { |c,a| 'amqp.event' },
12
+ description: "Routing key for Amqp events"
13
+
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ require 'threatinator/output'
2
+ require 'bunny'
3
+ require 'multi_json'
4
+ require 'pry'
5
+ # bundle exec threatinator run --run.output.amqp.url=#{ENV['RABBITMQ_URL']} --run.output.format=amqp #{provider} #{name}"
6
+ # --run.output.amqp.routing_key=arg - Routing key for Amqp events (default: none)
7
+ # --run.output.amqp.url=arg - The hostname/ip of the RabbitMQ server (default: none)
8
+
9
+
10
+ module Threatinator
11
+ module Plugins
12
+ module Output
13
+ class Amqp < Threatinator::Output
14
+ require 'threatinator/plugins/output/amqp/config'
15
+
16
+ def initialize(config)
17
+ bunny_config = {
18
+ recover_from_connection_close: true,
19
+ network_recovery_interval: 5.0
20
+ }
21
+ @bunny = Bunny.new(config.url, bunny_config)
22
+ @bunny.start
23
+ @channel = @bunny.create_channel
24
+ @exchange = @channel.topic("threats")
25
+ end
26
+
27
+ def handle_event(event)
28
+ @routing_key = 'threatinator.' + event.type.to_s
29
+ @exchange.publish(MultiJson.dump(event.to_serializable_hash),
30
+ routing_key: @routing_key)
31
+ end
32
+
33
+ def finish
34
+ @exchange = nil
35
+ @bunny.close
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,58 @@
1
+ require 'threatinator/output'
2
+ require 'csv'
3
+ module Threatinator
4
+ module Plugins
5
+ module Output
6
+ class Csv < Threatinator::FileBasedOutput
7
+ class Config < superclass::Config
8
+ end
9
+
10
+ def initialize(config)
11
+ super(config)
12
+ @csv = ::CSV.new(self.output_io,
13
+ :write_headers => true,
14
+ :headers => [
15
+ :provider,
16
+ :feed_name,
17
+ :type,
18
+ :ipv4_1,
19
+ :ipv4_2,
20
+ :ipv4_3,
21
+ :ipv4_4,
22
+ :fqdn_1,
23
+ :fqdn_2,
24
+ :fqdn_3,
25
+ :fqdn_4,
26
+ :url_1,
27
+ :url_2,
28
+ :url_3,
29
+ :url_4
30
+ ])
31
+ end
32
+
33
+ def handle_event(event)
34
+ ipv4s = event.ipv4s.to_a[0..3].map { |o| o.nil? ? nil : o.ipv4.to_addr }
35
+ fqdns = event.fqdns.to_a[0..3]
36
+ urls = event.urls.to_a[0..3].map {|x| x.to_s }
37
+ @csv.add_row([
38
+ event.feed_provider,
39
+ event.feed_name,
40
+ event.type,
41
+ ipv4s[0],
42
+ ipv4s[1],
43
+ ipv4s[2],
44
+ ipv4s[3],
45
+ fqdns[0],
46
+ fqdns[1],
47
+ fqdns[2],
48
+ fqdns[3],
49
+ urls[0],
50
+ urls[1],
51
+ urls[2],
52
+ urls[3],
53
+ ])
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ require 'threatinator/output'
2
+
3
+ module Threatinator
4
+ module Plugins
5
+ module Output
6
+ require 'threatinator/plugins/output/json'
7
+ class Json
8
+ class Config < Threatinator::Output::Config
9
+ attribute :file, String, description: "The hostname/ip of the RabbitMQ server"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ require 'threatinator/output'
2
+ require 'multi_json'
3
+ #require 'pry'
4
+ module Threatinator
5
+ module Plugins
6
+ module Output
7
+
8
+ class Json < Threatinator::Output
9
+ #include JSONHelpers
10
+ require 'threatinator/plugins/output/json/config'
11
+
12
+ def initialize(config)
13
+ @output_file = config.file
14
+ @first = true
15
+ puts "{"
16
+ end
17
+
18
+ def handle_event(event)
19
+ if @first
20
+ puts "\"header\" : #{MultiJson.dump(event.header.to_h)}"
21
+ puts ",\"items\" : ["
22
+ puts "{"
23
+ @first = false
24
+ else
25
+ puts ",{"
26
+ end
27
+ delim = ""
28
+ if event.ipv4s.size > 0
29
+ puts "#{delim}\"ipv4s\" : #{MultiJson.dump(event.ipv4s.list)}"
30
+ delim = ","
31
+ end
32
+ if event.fqdns.size > 0
33
+ puts "#{delim}\"fqdns\" : #{MultiJson.dump(event.fqdns.list)}"
34
+ delim = ","
35
+ end
36
+ if event.urls.size > 0
37
+ puts "#{delim}\"urls\" : #{MultiJson.dump(event.urls.list)}"
38
+ delim = ","
39
+ end
40
+ puts "}"
41
+
42
+ end
43
+
44
+ def finish
45
+ puts "]}"
46
+ end
47
+
48
+
49
+
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,17 @@
1
+ require 'threatinator/output'
2
+ module Threatinator
3
+ module Plugins
4
+ module Output
5
+ class Null < Threatinator::Output
6
+ class Config < superclass::Config
7
+ end
8
+
9
+ def handle_event(event)
10
+ end
11
+
12
+ def finish
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ require 'threatinator/output'
2
+ require 'pp'
3
+ module Threatinator
4
+ module Plugins
5
+ module Output
6
+ class Rubydebug < Threatinator::FileBasedOutput
7
+ class Config < superclass::Config
8
+ end
9
+
10
+ def handle_event(event)
11
+ ::PP.pp(event, self.output_io); nil
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ module Threatinator
2
+ class Record
3
+ attr_reader :data, :line_number, :pos_start, :pos_end
4
+ def initialize(data, opts = {})
5
+ @data = data
6
+ @line_number = opts[:line_number]
7
+ @pos_start = opts[:pos_start]
8
+ @pos_end = opts[:pos_end]
9
+ end
10
+
11
+ def ==(other)
12
+ @data == other.data &&
13
+ @line_number == other.line_number &&
14
+ @pos_start == other.pos_start &&
15
+ @pos_end == other.pos_end
16
+ end
17
+
18
+ def eql?(other)
19
+ other.kind_of?(self.class) && self == other
20
+ end
21
+ end
22
+ end