summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tasks/cve.rake')
-rw-r--r--lib/tasks/cve.rake366
1 files changed, 0 insertions, 366 deletions
diff --git a/lib/tasks/cve.rake b/lib/tasks/cve.rake
deleted file mode 100644
index dbdc7a8..0000000
--- a/lib/tasks/cve.rake
+++ /dev/null
@@ -1,366 +0,0 @@
-# ===GLSAMaker v2
-# Copyright (C) 2010–15 Alex Legler <a3li@gentoo.org>
-# Copyright (C) 2020 Max Magorsch <arzano@gentoo.org>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# For more information, see the LICENSE file.
-libs = %w( json nokogiri zlib stringio )
-libs << File.join(File.dirname(__FILE__), '..', 'bugzilla')
-libs << File.join(File.dirname(__FILE__), '..', 'glsamaker')
-libs << File.join(File.dirname(__FILE__), 'utils')
-
-libs.each { |lib| require lib }
-
-TMPDIR = File.join(File.dirname(__FILE__), '..', '..', 'tmp')
-# What year are the first CVEs from?
-YEAR = (ENV['START_YEAR'] || 2004).to_i
-BASEURL = 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-%s.json.gz'
-
-DEBUG = ENV.key? 'DEBUG'
-VERBOSE = (ENV.key?('VERBOSE') || DEBUG)
-QUIET = ENV.key? 'QUIET'
-
-fail "I can't be quiet and verbose at the same time..." if QUIET && VERBOSE
-
-namespace :cve do
-
- desc 'Destroy all CVEs and CPEs'
- task destroy_all: [:environment, 'db:load_config'] do
- CveReference.destroy_all
- Cve.destroy_all
- Cpe.destroy_all
- end
-
-
- desc 'Print all CVEs'
- task print_all: [:environment, 'db:load_config'] do
- Cve.find_each do |cve|
- puts cve.cve_id + ",\"" + cve.summary + "\"," + (cve.cvss || "") + "," + cve.state + "," + cve.published_at.to_formatted_s(:iso8601) + "," + cve.last_changed_at.to_formatted_s(:iso8601) + "," + cve.created_at.to_formatted_s(:iso8601) + "," + cve.updated_at.to_formatted_s(:iso8601)
- end
- end
-
-
- desc 'Full CVE data import'
- task full_import: [:environment, 'db:load_config'] do
- Rails.cache.write(CVE_CACHE_LAST_IMPORT, Time.now.utc)
- start_ts = Time.now
-
- (YEAR..Date.today.year).each do |year|
- info 'Processing CVEs from '.bold + year.to_s.purple
-
- jsondata = status 'Downloading' do
- gunzip_str Glsamaker::HTTP.get(BASEURL % year)
- end
-
- json = status 'Loading JSON' do
- JSON.parse(jsondata)
- end
-
- cves = json["CVE_Items"]
- create_cves(cves)
-
- puts
- end
-
- info 'done'.green
- info "(#{Time.now - start_ts} seconds)"
- end
-
-
- desc 'Incrementally update last CVEs'
- task update: :environment do
- Rails.cache.write(CVE_CACHE_LAST_IMPORT, Time.now.utc)
- info 'Running incremental CVE data update...'
-
- jsondata = status 'Downloading' do
- gunzip_str Glsamaker::HTTP.get(BASEURL % 'modified')
- end
-
- json = status 'Loading JSON' do
- JSON.parse(jsondata)
- end
-
- cves = json["CVE_Items"]
- update_cves(cves)
- end
-
-
- desc 'Update all CVEs'
- task update_all: :environment do
- Rails.cache.write(CVE_CACHE_LAST_IMPORT, Time.now.utc)
- info 'Running complete CVE data update...'
-
- (YEAR..Date.today.year).each do |year|
- info 'Processing CVEs from '.bold + year.to_s.purple
-
- jsondata = status 'Downloading' do
- gunzip_str Glsamaker::HTTP.get(BASEURL % year)
- end
-
- json = status 'Loading JSON' do
- JSON.parse(jsondata)
- end
-
- cves = json["CVE_Items"]
- update_cves(cves)
- end
- end
-
-end
-
-
-#
-# Update the given cve
-#
-def create_cve(cve)
- summary = cve.dig('cve', 'description', 'description_data', 0, 'value')
- _cve = Cve.create(
- :cve_id => cve.dig('cve', 'CVE_data_meta', 'ID'),
- :summary => summary,
- :cvss => cve.dig('impact', 'baseMetricV2', 'cvssV2', 'vectorString'),
- :published_at => DateTime.parse(cve['publishedDate']),
- :last_changed_at => DateTime.parse(cve['lastModifiedDate']),
- :state => (summary =~ /^\*\* REJECT \*\*/ ? 'REJECTED' : 'NEW')
- )
-
- if cve.dig('references', 'reference_data')
- cve.dig('references', 'reference_data').each do |ref|
- CveReference.create(
- :cve => _cve,
- :source => ref['refsource'],
- :title => ref['name'],
- :uri => ref['url']
- )
- end
- end
-
- cve.dig('configurations', 'nodes').each do |node|
- if node.key?('cpe_match')
- node['cpe_match'].each do |cpe_match|
- cpe_str = cpe_match['cpe23Uri']
-
- cpe = Cpe.where(:cpe => cpe_str).first
- cpe ||= Cpe.create(:cpe => cpe_str)
-
- _cve.cpes << cpe
- end
- elsif node.key?('children')
- node['children'].each do |child|
- if child.key?('cpe_match')
- child['cpe_match'].each do |cpe_match|
- cpe_str = cpe_match['cpe23Uri']
-
- cpe = Cpe.where(:cpe => cpe_str).first
- cpe ||= Cpe.create(:cpe => cpe_str)
-
- _cve.cpes << cpe
- end
- end
- end
- end
- end
-end
-
-
-#
-# Create the all given cves
-#
-def create_cves(cves)
- processed_cves = 0
- info "#{cves.size.to_s.purple} CVEs (one dot equals 100, purple dot equals 500)"
-
- cves.each do |cve|
- unless VERBOSE || QUIET
-
- if processed_cves % 500 == 0
- print '.'.purple
- else
- print '.' if processed_cves % 100 == 0
- end
- end
-
- puts cve.dig('cve', 'CVE_data_meta', 'ID').to_s.purple if VERBOSE
-
- begin
- create_cve(cve)
- rescue ActiveRecord::StatementInvalid => e
- # Ignore dupes, ONLY do that for the full db update!
- raise e unless e.message =~ /Duplicate entry/
- end
-
- processed_cves += 1
- STDOUT.flush
- end
-end
-
-
-#
-# Update the all given cves
-#
-def update_cves(cves)
- start_ts = Time.now
- processed_cves = created_cves = updated_cves = 0
-
- info "#{cves.size.to_s.purple} CVEs (one dot equals 100, purple dot equals 500)"
-
- cves.each do |cve|
- unless VERBOSE || QUIET
- if processed_cves % 500 == 0
- print '.'.purple
- else
- print '.' if processed_cves % 100 == 0
- end
- end
-
- puts cve.dig('cve', 'CVE_data_meta', 'ID').to_s.purple if VERBOSE
-
- c = Cve.find_by_cve_id cve.dig('cve', 'CVE_data_meta', 'ID')
-
- if c.nil?
- debug 'Creating CVE.'
- create_cve(cve)
- created_cves += 1
- else
- last_changed_at = Time.parse(cve['lastModifiedDate']).utc
-
- if last_changed_at.to_i > c.last_changed_at.to_i
- debug 'Updating CVE. Timestamp changed.'
- summary = cve.dig('cve', 'description', 'description_data', 0, 'value')
- c.attributes = {
- cve_id: cve.dig('cve','CVE_data_meta','ID'),
- summary: summary,
- cvss: cve.dig('impact', 'baseMetricV2', 'cvssV2', 'vectorString'),
- published_at: DateTime.parse(cve['publishedDate']),
- last_changed_at: DateTime.parse(cve['lastModifiedDate']),
- }
-
- c.state = 'REJECTED' if summary =~ /^\*\* REJECT \*\*/
- c.save!
-
- db_references = []
- xml_references = []
-
- if cve.dig 'references', 'reference_data'
- cve.dig('references', 'reference_data').each do |ref|
- xml_references << [
- :source => ref['refsource'],
- :title => ref['name'],
- :uri => ref['url']
- ]
- end
- end
-
- c.references.each do |ref|
- db_references << [ref.source, ref.title, ref.uri]
- end
-
- rem = db_references - xml_references
- debug "Removing references: #{rem.inspect}"
-
- rem.each do |item|
- ref = c.references.where(['source = ? AND title = ? AND uri = ?', *item]).first
- debug ref
- c.references.delete(ref)
- ref.destroy
- end
-
- add = xml_references - db_references
- debug "Ading references: #{add.inspect}"
-
- add.each do |item|
- c.references.create(
- source: item[0],
- title: item[1],
- uri: item[2]
- )
- end
-
- db_cpes = []
- xml_cpes = []
-
- cve.dig('configurations', 'nodes').each do |node|
- if node.key?('cpe_match')
- node['cpe_match'].each do |cpe_match|
- xml_cpes << cpe_match['cpe23Uri']
- end
- elsif node.key?('children')
- node['children'].each do |child|
- if child.key?('cpe_match')
- child['cpe_match'].each do |cpe_match|
- xml_cpes << cpe_match['cpe23Uri']
- end
- end
- end
- end
- end
-
- c.cpes.each do |prod|
- db_cpes << prod.cpe
- end
-
- rem = db_cpes - xml_cpes
- debug "Removing CPEs: #{rem.inspect}"
-
- rem.each do |item|
- c.cpes.delete(Cpe.find_by_cpe(item))
- end
-
- add = xml_cpes - db_cpes
- debug "Ading CPEs: #{add.inspect}"
-
- add.each do |item|
- cpe = Cpe.where(cpe: item).first
- cpe ||= Cpe.create(cpe: item)
-
- c.cpes << cpe
- end
-
- c.save!
- updated_cves += 1
- end
- end
-
- processed_cves += 1
- STDOUT.flush
- end
-
- info ''
-
- info "(#{Time.now - start_ts} seconds, #{created_cves} new CVE entries, #{updated_cves} updated CVE entries)"
-end
-
-
-#
-# Run something, and display a status info around it
-#
-def status(message)
- fail ArgumentError, 'I want a block :(' unless block_given?
-
- print "#{message}....." unless QUIET
- STDOUT.flush
-
- stuff = yield
- print "\b" * 5 + ' done.'.green + "\n" unless QUIET
- stuff
-end
-
-
-def debug(msg)
- $stderr.puts msg if DEBUG
-end
-
-
-def info(msg)
- puts msg unless QUIET
-end
-
-#
-# unzip the given string
-#
-def gunzip_str(str)
- Zlib::GzipReader.new(StringIO.new(str)).read
-end