Module: RailsCVE::Utils
Instance Method Summary collapse
-
#allitems_source(basename) ⇒ Object
Source of full CVE list.
-
#data_path(target) ⇒ Object
Path for downloads, needs to be writeable.
- #download(url, to: nil) ⇒ Object
-
#fetch_all_entries(&block) ⇒ Object
Downloads latest allitems.cvs(.gz) from cve.mitre.org and yields name, description and references list of every CVE entry.
-
#fetch_updates(year, month, &block) ⇒ Object
Fetches the updates for a given year/month from Cassandra and yields name, desc.
-
#updates_source(basename) ⇒ Object
Source for updates.
Instance Method Details
#allitems_source(basename) ⇒ Object
Source of full CVE list
13 14 15 |
# File 'lib/rails_cve/utils.rb', line 13 def allitems_source(basename) "http://cve.mitre.org/data/downloads/#{basename}.gz" end |
#data_path(target) ⇒ Object
Path for downloads, needs to be writeable
23 24 25 |
# File 'lib/rails_cve/utils.rb', line 23 def data_path(target) RailsCVE::Entry::DATA_PATH.join(target).tap {|path| path.dirname.mkpath } end |
#download(url, to: nil) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rails_cve/utils.rb', line 83 def download(url, to: nil) unless to.present? && Pathname === to raise UnknownTarget, '"to" parameter needs to be Pathname instance' end response = HTTParty.get(url, verify: false) return false if response.code != 200 data = response.body.encode(Encoding::UTF_8, invalid: :replace, undef: :replace) to.open('w') {|f| f.write data } true rescue HTTParty::Error, Net::HTTPError return false end |
#fetch_all_entries(&block) ⇒ Object
Downloads latest allitems.cvs(.gz) from cve.mitre.org and yields name, description and references list of every CVE entry
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/rails_cve/utils.rb', line 29 def fetch_all_entries(&block) file = data_path('allitems.csv') download allitems_source(file.basename), to: file latch_locked = true result = [] CSV.parse(file.read) do |row| # there are some comments prefacing the entry list latch_locked = false if row[0].nil? next if latch_locked || row[0].nil? name, _, description, references, _, _, _ = row if block_given? result << yield(name, description, references) else result << [name, description, references] end end result end |
#fetch_updates(year, month, &block) ⇒ Object
Fetches the updates for a given year/month from Cassandra and yields name, desc. and refs. for each CVE change
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/rails_cve/utils.rb', line 55 def fetch_updates(year, month, &block) list = data_path('CVE.%4d.%02d.html' % [year.to_i, month.to_i]) download updates_source(list.basename), to: list # Sadly, there is only little structure in the downloaded list. Nokogiri::HTML(list.read).css('a').map do |a| url = URI.parse(a[:href]) next unless url.host == 'cve.mitre.org' next unless url.query =~ /name=(\d{4})-(\d{4,})/ y,id = $1, $2 name = "CVE-#{y}-#{id}" # max. 2 digits per dirname → max. 100 subdirs per directory parts = id.to_s.scan(/\d\d/).join('/') # for now, we fetch *each* embedded link, which could take a while… file = data_path("entries/#{y}/#{parts}/#{name}.html") download a[:href], to: file table = Nokogiri::HTML(file.read).xpath('//div[@id="GeneratedTable"]/table') description = table.xpath('.//tr[4]/td').text references = table.xpath('.//tr[7]//li').map(&:text) yield name, description, references end end |
#updates_source(basename) ⇒ Object
Source for updates
18 19 20 |
# File 'lib/rails_cve/utils.rb', line 18 def updates_source(basename) "https://cassandra.cerias.purdue.edu/CVE_changes/#{basename}" end |