diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/glsa_repository.rb | 55 | ||||
-rw-r--r-- | lib/glsav1.rb | 37 | ||||
-rw-r--r-- | lib/helpers.rb | 62 |
3 files changed, 154 insertions, 0 deletions
diff --git a/lib/glsa_repository.rb b/lib/glsa_repository.rb new file mode 100644 index 0000000..90c9899 --- /dev/null +++ b/lib/glsa_repository.rb @@ -0,0 +1,55 @@ +require_relative 'glsav1.rb' +require 'date' + +class GLSARepository + include Singleton + + CACHE_SECONDS = 3600 + DATA_PATH = File.join(File.dirname(__FILE__), '../data/glsa/') + + def initialize + update! + end + + def update! + advisories = {} + + Dir.glob(DATA_PATH + '*.xml').each do |glsa_file| + f = File.open(glsa_file) + glsa = Nokogiri::XML(f) + f.close + + if glsa.root.key? 'version' + # Future extension: GLSAv2 + else + begin + advisories[glsa.root['id']] = GLSAv1.new.parse(glsa) + rescue + next + end + end + end + + @load_date = DateTime.now + @advisories = advisories.freeze + end + + def get + @advisories + end + + def[](id) + @advisories[id] + end + + def has?(id) + @advisories.has_key? id + end + + private + def update? + if ((DateTime.now - @load_date) * 60 * 60 * 24).to_i > CACHE_SECONDS + update! + end + end +end
\ No newline at end of file diff --git a/lib/glsav1.rb b/lib/glsav1.rb new file mode 100644 index 0000000..789de2b --- /dev/null +++ b/lib/glsav1.rb @@ -0,0 +1,37 @@ +# A version 1 GLSA +class GLSAv1 + attr_reader :id, :title, :synopsis, :product, :date, :revised, :revision, :bugs, :access, :packages, + :background, :description, :severity, :impact, :workaround, :resolution, :references + + def parse(xml) + @id = xml.root['id'] + @title = xml.xpath('/glsa/title/text()').first.content + @synopsis = xml.xpath('/glsa/synopsis/text()').first.content + @product = xml.xpath('/glsa/product/text()').first.content + @date = xml.xpath('/glsa/announced/text()').first.content + @revised, + @revision = xml.xpath('/glsa/revised/text()').first.content.split(': ') + + @bugs = xml.xpath('/glsa/bug/text()').map {|bug_node| bug_node.content.to_i } + @access = xml.xpath('/glsa/access/text()').first.content + + @packages = {} + xml.xpath('/glsa/affected/package').each do |package| + @packages[package['name'] + ':' + package['arch']] = { + auto: package['auto'] == 'yes', + unaffected: package.xpath('./unaffected').map {|ver| [ver['range'], ver.content] }, + vulnerable: package.xpath('./vulnerable').map {|ver| [ver['range'], ver.content] } + } + end + + @background = xml.xpath('/glsa/background').first.children.to_xml.strip + @description = xml.xpath('/glsa/description').first.children.to_xml.strip + @severity = xml.xpath('/glsa/impact').first['type'] + @impact = xml.xpath('/glsa/impact').first.children.to_xml.strip + @workaround = xml.xpath('/glsa/workaround').first.children.to_xml.strip + @resolution = xml.xpath('/glsa/resolution').first.children.to_xml.strip + @references = xml.xpath('/glsa/references/uri').map {|uri| [uri.content, uri['link']] } + + self + end +end
\ No newline at end of file diff --git a/lib/helpers.rb b/lib/helpers.rb new file mode 100644 index 0000000..34ed17f --- /dev/null +++ b/lib/helpers.rb @@ -0,0 +1,62 @@ +require 'sanitize' +require 'erb' +require 'rss' + +COMP_MAP = { + '>=' => 'ge', + '>' => 'gt', + '=' => 'eq', + '<=' => 'le', + '<' => 'lt', + 'revision <' => 'rlt', + 'revision <=' => 'rle', + 'revision >' => 'rgt', + 'revision >=' => 'rge' +}.freeze + +helpers do + def h(text) + Rack::Utils.escape_html(text) + end + + def u(text) + ERB::Util::url_encode(text) + end + + def h2(text) + Sanitize.clean(text, Sanitize::Config::BASIC) + end + + def code2pre(text) + text.gsub('<code>', '<pre>').gsub('</code>', '</pre>').gsub(/ +/, ' ').chomp + end + + # Returns the comparator in the format needed for the XML + def xml_comp(val) + COMP_MAP[val] + end + + def reverse_xml_comp(val) + COMP_MAP.invert[val] + end + + def feed(type, items) + RSS::Maker.make(type) do |maker| + maker.channel.author = "Gentoo Security Team" + maker.channel.about = "https://security.gentoo.org/glsa" + maker.channel.link = "https://security.gentoo.org/glsa" + maker.channel.description = "This feed contains new Gentoo Linux Security Advisories. Contact security@gentoo.org with questions." + maker.channel.title = "Gentoo Linux Security Advisories" + maker.channel.updated = Time.now.to_s + + items.each do |input_item| + maker.items.new_item do |item| + item.link = BASE_URL + 'glsa/' + input_item.id + item.title = "GLSA %s: %s" % [input_item.id, input_item.title] + item.updated = Time.now.to_s + end + end + end.to_s + end + +end
\ No newline at end of file |