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,59 @@
1
+ require 'threatinator/config/base'
2
+ require 'threatinator/exceptions'
3
+
4
+ module Threatinator
5
+ module Actions
6
+ module Run
7
+ module OutputConfigClassMethods
8
+ def set_plugin_loader(pl)
9
+ @plugin_loader = pl
10
+ pl.each(:output) do |type, name, plugin|
11
+ self.attribute name, plugin::Config, default: lambda { |c,a| plugin::Config.new }
12
+ end
13
+ end
14
+
15
+ def get_plugin(name)
16
+ @plugin_loader.get(:output, name)
17
+ end
18
+
19
+ def formats
20
+ @plugin_loader.each(:output).map { |t, k, p| k.to_s }
21
+ end
22
+
23
+ def formats_str
24
+ formats.sort.join(', ')
25
+ end
26
+
27
+ end
28
+
29
+ module OutputConfigMethods
30
+ def build_output
31
+ oc = self.class.get_plugin(self.format)
32
+ if oc.nil?
33
+ raise Threatinator::Exceptions::UnknownPlugin.new("Unknown output plugin: '#{format}'")
34
+ end
35
+ output_config = self[format]
36
+
37
+ if output_config.nil?
38
+ raise Threatinator::Exceptions::CouldNotFindOutputConfigError.new("Could not find output config for '#{format}'. Perhaps there's some load-order issues?")
39
+ end
40
+
41
+ oc.new(output_config)
42
+ end
43
+ end
44
+
45
+ module OutputConfig
46
+ def self.generate(plugin_loader)
47
+ anonymous_class = Class.new(Threatinator::Config::Base) do
48
+ extend OutputConfigClassMethods
49
+ include OutputConfigMethods
50
+ set_plugin_loader(plugin_loader)
51
+ attribute :format, Symbol, default: lambda { |c,a| :csv },
52
+ description: lambda { |c, a| "Output format (#{c.formats_str})" }
53
+ end
54
+ anonymous_class
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ module Threatinator
2
+ module Actions
3
+ module Run
4
+ class StatusObserver
5
+ attr_reader :missed, :filtered, :parsed, :errors
6
+ def initialize
7
+ @missed = @filtered = @parsed = @errors = 0
8
+ end
9
+
10
+ def total
11
+ @missed + @filtered + @parsed + @errors
12
+ end
13
+
14
+ # Handles FeedRunner observations
15
+ def update(message, *args)
16
+ case message
17
+ when :record_missed
18
+ @missed += 1
19
+ when :record_filtered
20
+ @filtered += 1
21
+ when :record_parsed
22
+ @parsed += 1
23
+ when :record_error
24
+ @errors += 1
25
+ end
26
+ end
27
+
28
+ def missed?; @missed > 0; end
29
+ def parsed?; @parsed > 0; end
30
+ def filtered?; @filtered > 0; end
31
+ def errors?; @errors > 0; end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,2 @@
1
+ require 'threatinator/actions/run/action'
2
+ require 'threatinator/actions/run/config'
@@ -0,0 +1,33 @@
1
+ require 'threatinator/config'
2
+ require 'threatinator/feed_registry'
3
+
4
+ module Threatinator
5
+ module CLI
6
+ class ActionBuilder
7
+ attr_reader :extra_args, :config_hash
8
+
9
+ def initialize(config_hash, extra_args)
10
+ @extra_args = extra_args
11
+ @config_hash = config_hash
12
+ @feed_registry = nil
13
+ end
14
+
15
+ def build
16
+ #:nocov:
17
+ raise NotImplementedError.new("#{self.class}#build not implemented")
18
+ #:nocov:
19
+ end
20
+
21
+ def feed_registry
22
+ return @feed_registry unless @feed_registry.nil?
23
+
24
+ feed_search_hash = config_hash["feed_search"] || {}
25
+ feed_search_config = Threatinator::Config::FeedSearch.new(feed_search_hash)
26
+
27
+ @feed_registry = Threatinator::FeedRegistry.build(feed_search_config)
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+
@@ -0,0 +1,19 @@
1
+ require 'threatinator/cli/action_builder'
2
+ require 'threatinator/actions/list'
3
+
4
+ module Threatinator
5
+ module CLI
6
+ class ListActionBuilder < ActionBuilder
7
+ def build
8
+ Threatinator::Actions::List::Action.new(feed_registry, config)
9
+ end
10
+
11
+ def config
12
+ list_hash = config_hash["list"] || {}
13
+ Threatinator::Actions::List::Config.new(list_hash)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,123 @@
1
+ require 'gli'
2
+ require 'threatinator/actions/run'
3
+ require 'threatinator/actions/list'
4
+ require 'threatinator/config/feed_search'
5
+ require 'threatinator/config/logger'
6
+ require 'threatinator/cli/list_action_builder'
7
+ require 'threatinator/cli/run_action_builder'
8
+ require 'threatinator/plugin_loader'
9
+
10
+ module Threatinator
11
+ module CLI
12
+ module Helpers
13
+ def add_cli_args(gli, config_properties)
14
+ config_properties.each do |key, args|
15
+ desc, type, default_value = args
16
+ if type.base == Axiom::Types::Boolean
17
+ gli.switch key, desc: desc
18
+ elsif type.base ==Axiom::Types::Array
19
+ gli.flag key, desc: desc, type: Array
20
+ else
21
+ gli.flag key, desc: desc
22
+ end
23
+ end
24
+ end
25
+
26
+ def clean_opts(opts)
27
+ opts.delete_if {|k, v| k.kind_of?(::Symbol) or (k == 'help') or v.nil? }
28
+ opts
29
+ end
30
+
31
+ def nest_opts(opts)
32
+ config_hash = {}
33
+ opts.each_pair do |key, val|
34
+ key_path = key.to_s.split('.')
35
+ final_key = key_path.pop
36
+ nested_hash = config_hash
37
+ while key_path.length > 0
38
+ part = key_path.shift
39
+ nested_hash[part] ||= {}
40
+ nested_hash = nested_hash[part]
41
+ end
42
+ nested_hash[final_key] = val
43
+ end
44
+ config_hash
45
+ end
46
+
47
+ def fix_opts(opts)
48
+ nest_opts(clean_opts(opts))
49
+ end
50
+ end
51
+
52
+ class Parser
53
+ include Helpers
54
+
55
+ attr_accessor :builder
56
+ attr_reader :config_hash, :extra_args
57
+ attr_reader :run_action_config_class
58
+
59
+ def initialize
60
+ @builder = nil
61
+ @plugin_loader = Threatinator::PluginLoader.new
62
+ @plugin_loader.load_all_plugins
63
+ @run_action_config_class = Threatinator::Actions::Run::Config.generate(@plugin_loader)
64
+ @mod = _init_mod
65
+ end
66
+
67
+ def parse(args)
68
+ @mod.run(args)
69
+ end
70
+
71
+ def set_opts(global_options, options, args)
72
+ @config_hash = fix_opts(global_options.merge(options))
73
+ @extra_args = args
74
+ end
75
+
76
+ def _init_mod
77
+ parser = self
78
+ Module.new do
79
+ extend Helpers
80
+ extend GLI::App
81
+
82
+ program_desc 'Threatinator!'
83
+
84
+ add_cli_args(self, Threatinator::Config::Logger.properties('logger'))
85
+ add_cli_args(self, Threatinator::Config::FeedSearch.properties('feed_search'))
86
+
87
+ desc "fetch and parse a feed"
88
+ command :run do |c|
89
+ c.flag 'run.coverage_output', type: String, desc: "Write coverage analysis to the specified file (CSV format)"
90
+
91
+ add_cli_args(c, parser.run_action_config_class.properties('run'))
92
+ c.action do |global_options, options, args|
93
+ if options["run.feed_provider"].nil?
94
+ options["run.feed_provider"] = args.shift
95
+ end
96
+
97
+ if options["run.feed_name"].nil?
98
+ options["run.feed_name"] = args.shift
99
+ end
100
+
101
+ parser.set_opts(global_options, options, args)
102
+
103
+ builder = Threatinator::CLI::RunActionBuilder.new(parser.config_hash, parser.extra_args, parser.run_action_config_class)
104
+ parser.builder = builder
105
+ end
106
+ end
107
+
108
+ desc 'list out all the feeds'
109
+ command :list do |c|
110
+ add_cli_args(c, Threatinator::Actions::List::Config.properties('list'))
111
+ c.action do |global_options, options, args|
112
+ parser.set_opts(global_options, options, args)
113
+ parser.builder = Threatinator::CLI::ListActionBuilder.new(parser.config_hash, parser.extra_args)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ end # _init_mod
120
+ end
121
+
122
+ end
123
+
@@ -0,0 +1,41 @@
1
+ require 'threatinator/cli/action_builder'
2
+ require 'threatinator/actions/run'
3
+ require 'threatinator/actions/run/coverage_observer'
4
+ require 'csv'
5
+
6
+ module Threatinator
7
+ module CLI
8
+ class RunActionBuilder < ActionBuilder
9
+ def initialize(opts, args, config_class)
10
+ super(opts, args)
11
+ @config_class = config_class
12
+ end
13
+
14
+ def build
15
+ Threatinator::Actions::Run::Action.new(feed_registry, config)
16
+ end
17
+
18
+ def config
19
+ run_hash = config_hash["run"] || {}
20
+ run_hash['observers'] ||= []
21
+
22
+ if filename = run_hash['coverage_output']
23
+ observer = Threatinator::Actions::Run::CoverageObserver.new(filename)
24
+ run_hash['observers'] << observer
25
+ end
26
+
27
+ config = @config_class.new(run_hash)
28
+
29
+ if config.feed_provider.nil? && provider = extra_args.shift
30
+ config.feed_provider = provider
31
+ end
32
+
33
+ if config.feed_name.nil? && name = extra_args.shift
34
+ config.feed_name = name
35
+ end
36
+ config
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ require 'threatinator/cli/parser'
2
+ require 'threatinator/config/logger'
3
+ require 'threatinator/logger'
4
+ module Threatinator
5
+ module CLI
6
+ def self.process!(args)
7
+ parser = Parser.new
8
+ ret = parser.parse(args)
9
+ builder = parser.builder
10
+ return ret if builder.nil?
11
+
12
+ conf = Threatinator::Config::Logger.new(parser.config_hash['logger'])
13
+ Threatinator::Logger.configure_logger(conf)
14
+
15
+ builder.build.exec
16
+ ret
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ require 'virtus'
2
+ module Threatinator
3
+ module Config
4
+ class Base
5
+ include Virtus.model
6
+
7
+ def self.properties(namespace = nil)
8
+ ret = {}
9
+ self.attribute_set.each do |attribute|
10
+ name = attribute.name.to_s
11
+ unless namespace.nil?
12
+ name = [namespace, name].join('.')
13
+ end
14
+
15
+ if attribute.primitive.ancestors.include?(Threatinator::Config::Base)
16
+ ret.merge!(attribute.primitive.properties(name))
17
+ next
18
+ end
19
+
20
+ desc = attribute.options[:description]
21
+ case desc
22
+ when nil
23
+ next
24
+ when ::Proc
25
+ desc = desc.call(self, attribute)
26
+ end
27
+ ret[name] = [desc, attribute.type]
28
+ end
29
+ ret
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+
@@ -0,0 +1,25 @@
1
+ require 'threatinator/config/base'
2
+
3
+ module Threatinator
4
+ module Config
5
+ class FeedSearch < Threatinator::Config::Base
6
+ DEFAULT_FEED_PATH = File.expand_path("../../../../feeds", __FILE__)
7
+
8
+ attribute :exclude_default, Boolean, default: false,
9
+ description: 'Exclude default path from feed search path'
10
+
11
+ attribute :path, Array[String],
12
+ description: 'The paths to search for feeds'
13
+
14
+ # @return [Array<String>] An array of paths to search
15
+ def search_path
16
+ ret = self.path
17
+ if self.exclude_default == false
18
+ ret = ret + [DEFAULT_FEED_PATH]
19
+ end
20
+ ret
21
+ end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,14 @@
1
+ require 'threatinator/config/base'
2
+ require 'threatinator/logger'
3
+
4
+ module Threatinator
5
+ module Config
6
+ class Logger < Threatinator::Config::Base
7
+ attribute :level, String, default: Threatinator::Logger.level_string,
8
+ coercer: lambda { |v| v.to_s.upcase },
9
+ description: "Set the logging level: #{::Threatinator::Logger.levels.join(',')}"
10
+ end
11
+ end
12
+ end
13
+
14
+
@@ -0,0 +1,7 @@
1
+ module Threatinator
2
+ module Config
3
+ require 'threatinator/config/feed_search'
4
+ require 'threatinator/config/logger'
5
+ end
6
+ end
7
+
@@ -0,0 +1,24 @@
1
+ module Threatinator
2
+ # Decodes/Extracts data from an input IO, producing a new IO. The decoder is
3
+ # initialized with a configuration, and then #decode is called upon an IO
4
+ # object.
5
+ class Decoder
6
+ attr_reader :encoding
7
+
8
+ # @param [Hash] opts An options hash
9
+ # @option opts [String] :encoding The encoding for the output IO. Defaults
10
+ # to "utf-8"
11
+ def initialize(opts = {})
12
+ @encoding = opts[:encoding] || "utf-8"
13
+ end
14
+
15
+ # Decodes an input IO, returning a brand new IO.
16
+ # @param [IO] io The IO to decode
17
+ # @return [IO] A new IO.
18
+ def decode(io)
19
+ #:nocov:
20
+ raise NotImplementedError.new("#{self.class}#decode not implemented!")
21
+ #:nocov:
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ require 'threatinator/decoder'
2
+ require 'threatinator/exceptions'
3
+ require 'zlib'
4
+ require 'tempfile'
5
+ require 'pp'
6
+
7
+ module Threatinator
8
+ module Decoders
9
+ class Gzip < Threatinator::Decoder
10
+ # Decompresses the io using Gzip.
11
+ # @param (see Threatinator::Decoder#decode)
12
+ def decode(io)
13
+ zio = Zlib::GzipReader.new(io, encoding: "binary")
14
+ tempfile = Tempfile.new("threatinator", encoding: "binary")
15
+ while chunk = zio.read(10240)
16
+ tempfile.write(chunk)
17
+ end
18
+
19
+ zio.close
20
+ io.close unless io.closed?
21
+ tempfile.rewind
22
+ tempfile.set_encoding(self.encoding)
23
+ tempfile
24
+ rescue Zlib::GzipFile::Error => e
25
+ raise Threatinator::Exceptions::DecoderError.new
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,63 @@
1
+ require 'threatinator/model/base'
2
+ require 'threatinator/model/observables/ipv4_collection'
3
+ require 'threatinator/model/observables/fqdn_collection'
4
+ require 'threatinator/model/observables/url_collection'
5
+ require 'equalizer'
6
+ require 'set'
7
+
8
+ module Threatinator
9
+ class Event < Threatinator::Model::Base
10
+ include Equalizer.new(:feed_provider, :feed_name, :type, :ipv4s, :fqdns, :urls)
11
+ attr_reader :feed_provider, :feed_name, :type, :ipv4s, :fqdns, :urls
12
+
13
+ VALID_TYPES = Set.new([:c2, :attacker, :malware_host, :spamming, :scanning, :phishing])
14
+
15
+ validates :feed_provider, :feed_name, type: ::String
16
+ validates :type, type: ::Symbol, allow_nil: false, inclusion: {in: VALID_TYPES}
17
+ validates :ipv4s, type: Threatinator::Model::Observables::Ipv4Collection
18
+ validates :fqdns, type: Threatinator::Model::Observables::FqdnCollection
19
+ validates :urls, type: Threatinator::Model::Observables::UrlCollection
20
+
21
+ EventHeader = Struct.new(:feed_provider, :feed_name, :type)
22
+
23
+ # @param [Hash] opts
24
+ # @option opts [String] :feed_provider The name of the feed provider
25
+ # @option opts [String] :feed_name The name of the feed
26
+ # @option opts [Symbol] :type The 'type' of feed.
27
+ # @option opts [#each] :ipv4s A collection of ipv4s
28
+ # @option opts [#each] :fqdns A collection of FQDNs
29
+ # @option opts [#each] :urls A collection of Urls
30
+ def initialize(opts = {})
31
+ @feed_provider = opts[:feed_provider]
32
+ @feed_name = opts[:feed_name]
33
+ @type = opts[:type]
34
+ @ipv4s = Threatinator::Model::Observables::Ipv4Collection.new(opts[:ipv4s] || [])
35
+ @fqdns = Threatinator::Model::Observables::FqdnCollection.new(opts[:fqdns] || [])
36
+ @urls = Threatinator::Model::Observables::UrlCollection.new(opts[:urls] || [])
37
+ super()
38
+ end
39
+
40
+ def header
41
+ event_header = EventHeader.new(@feed_provider, @feed_name, @type)
42
+ end
43
+
44
+ def to_serializable_hash
45
+
46
+ ret = {
47
+ import_time: Time.now.utc.to_i,
48
+ feed_provider: @feed_provider,
49
+ feed_name: @feed_name,
50
+ source: 'threatinator'
51
+ }
52
+ if @type
53
+ ret[:tags] = @type.to_s
54
+ end
55
+
56
+ ret[:ipv4s] = @ipv4s.list
57
+ ret[:fqdns] = @fqdns.list
58
+ ret[:urls] = @urls.list
59
+ ret
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,70 @@
1
+ require 'threatinator/event'
2
+ require 'threatinator/exceptions'
3
+ require 'threatinator/model/observables/ipv4'
4
+ require 'ip'
5
+
6
+ module Threatinator
7
+ class EventBuilder
8
+ attr_writer :type
9
+
10
+ def initialize(feed_provider, feed_name)
11
+ @feed_provider = feed_provider
12
+ @feed_name = feed_name
13
+ self.reset
14
+ end
15
+
16
+ def reset
17
+ @type = nil
18
+ @ipv4s = []
19
+ @fqdns = []
20
+ @urls = []
21
+ end
22
+
23
+ def build
24
+ opts = {
25
+ feed_provider: @feed_provider,
26
+ feed_name: @feed_name,
27
+ }
28
+ opts[:type] = @type unless @type.nil?
29
+
30
+ ret = Threatinator::Event.new(opts)
31
+
32
+ @ipv4s.each do |ipv4, opts|
33
+ opts = opts.dup
34
+ if ipv4.is_a?(::String)
35
+ ipv4 = ::IP::V4.parse(ipv4)
36
+ end
37
+ opts[:ipv4] = ipv4
38
+ ret.ipv4s << Threatinator::Model::Observables::Ipv4.new(opts)
39
+ end
40
+ @fqdns.each do |fqdn|
41
+ ret.fqdns << fqdn
42
+ end
43
+ @urls.each do |url|
44
+ url = begin
45
+ ::Addressable::URI.parse(url)
46
+ rescue TypeError => e
47
+ raise Threatinator::Exceptions::EventBuildError, "Failed to parse URL"
48
+ end
49
+ ret.urls << url
50
+ end
51
+ ret
52
+ rescue Threatinator::Exceptions::InvalidAttributeError => e
53
+ raise Threatinator::Exceptions::EventBuildError, e.message
54
+ end
55
+
56
+ def add_fqdn(fqdn)
57
+ @fqdns << fqdn
58
+ end
59
+
60
+ def add_ipv4(ipv4, opts = {})
61
+ @ipv4s << [ipv4, opts]
62
+ end
63
+
64
+ def add_url(url)
65
+ @urls << url
66
+ end
67
+ end
68
+ end
69
+
70
+
@@ -0,0 +1,58 @@
1
+ module Threatinator
2
+ module Exceptions
3
+ # Indicates that a fetch failed.
4
+ class FetchFailed < StandardError
5
+ end
6
+
7
+ # Indicates that the decode operation failed
8
+ class DecoderError < StandardError
9
+ end
10
+
11
+ class ParseError < StandardError
12
+ end
13
+
14
+ class PluginLoadError < StandardError
15
+ attr_reader :cause
16
+ def initialize(message, cause = nil)
17
+ @cause = cause
18
+ unless cause.nil?
19
+ message = "#{message} : #{cause.class} : #{cause}"
20
+ self.set_backtrace cause.backtrace
21
+ end
22
+ super(message)
23
+ end
24
+ end
25
+
26
+ class UnknownPlugin < StandardError
27
+ end
28
+
29
+ class CouldNotFindOutputConfigError < StandardError
30
+ end
31
+
32
+ class InvalidAttributeError < StandardError
33
+ end
34
+
35
+ class EventBuildError < StandardError
36
+ end
37
+
38
+ class AlreadyRegisteredError < StandardError
39
+ end
40
+
41
+ class UnknownFeed < StandardError
42
+ attr_reader :provider, :name
43
+ def initialize(provider, name)
44
+ @provider = provider
45
+ @name = name
46
+ super("Failed to find feed with provider '#{provider}' and name '#{name}'")
47
+ end
48
+ end
49
+
50
+ class FeedFileNotFoundError < StandardError
51
+ def initialize(filename)
52
+ @filename = filename
53
+ super("Failed to open/read feed file '#{filename}'")
54
+ end
55
+ end
56
+ end
57
+ end
58
+