diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/assets/.gitkeep | 0 | ||||
-rw-r--r-- | lib/authentication.rb | 111 | ||||
-rw-r--r-- | lib/authorization.rb | 49 | ||||
-rw-r--r-- | lib/bugzilla.rb | 195 | ||||
-rw-r--r-- | lib/bugzilla/bug.rb | 143 | ||||
-rw-r--r-- | lib/bugzilla/comment.rb | 22 | ||||
-rw-r--r-- | lib/bugzilla/history.rb | 104 | ||||
-rw-r--r-- | lib/glsamaker.rb | 23 | ||||
-rw-r--r-- | lib/glsamaker/bugs.rb | 182 | ||||
-rw-r--r-- | lib/glsamaker/diff.rb | 53 | ||||
-rw-r--r-- | lib/glsamaker/helpers.rb | 21 | ||||
-rw-r--r-- | lib/glsamaker/http.rb | 37 | ||||
-rw-r--r-- | lib/glsamaker/mail.rb | 106 | ||||
-rw-r--r-- | lib/glsamaker/portage.rb | 194 | ||||
-rw-r--r-- | lib/glsamaker/spelling.rb | 48 | ||||
-rw-r--r-- | lib/glsamaker/xml.rb | 31 | ||||
-rw-r--r-- | lib/kramdown_ext.rb | 20 | ||||
-rw-r--r-- | lib/tasks/.gitkeep | 0 | ||||
-rw-r--r-- | lib/tasks/cve.rake | 366 | ||||
-rw-r--r-- | lib/tasks/import.rake | 256 | ||||
-rw-r--r-- | lib/tasks/rcov.rake | 81 | ||||
-rw-r--r-- | lib/tasks/utils.rb | 35 |
22 files changed, 0 insertions, 2077 deletions
diff --git a/lib/assets/.gitkeep b/lib/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/lib/assets/.gitkeep +++ /dev/null diff --git a/lib/authentication.rb b/lib/authentication.rb deleted file mode 100644 index 6f162e3..0000000 --- a/lib/authentication.rb +++ /dev/null @@ -1,111 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@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. - -# Authentication module -module Authentication - protected - # Login filter to be applied to *all* pages on GLSAMaker - def login_required - # Production authentication via REMOTE_USER - if Rails.env.production? or GLSAMAKER_FORCE_PRODUCTION_AUTH - # REMOTE_USER should be there in FCGI or Passenger - env_user_name = user_name - - # Autentication system most likely broken - if env_user_name.nil? - logger.warn "Neither REMOTE_USER nor HTTP_AUTHORIZATION set in environment." - redirect_to :controller => 'index', :action => 'error', :type => 'system' - return - end - - user = User.find_by_login(env_user_name) - - # User not known to GLSAMaker - if user == nil - logger.warn "Unknown user #{env_user_name} tried to log in from #{request.remote_ip}" - redirect_to :controller => 'index', :action => 'error', :type => 'user' - return - end - - # User is marked as disabled in the DB - if user.disabled - logger.warn "Disabled user #{env_user_name} tried to log in from #{request.remote_ip}" - redirect_to :controller => 'index', :action => 'error', :type => 'disabled' - return - end - - # Auth is fine now. - logger.debug "Environment username: #{env_user_name}" - - # For all other environments request, HTTP auth by ourselves - # The password can be set in config/initializers/glsamaker.rb - else - authenticate_or_request_with_http_basic("GLSAMaker testing environment") do |username, password| - logger.debug "Environment username: #{username}" - check_auth(username, password) - end - end - end - - # Filter for admin pages - def admin_access_required - unless current_user.is_el_jefe? - deny_access "Admin interface" - false - end - end - - # Returns the ActiveRecord object of the currently logged in user - def current_user - User.find_by_login(user_name) - end - - # Populate user to views, shamelessly stolen from restful auth. ;) - def self.included(base) - base.send :helper_method, :current_user if base.respond_to? :helper_method - end - - private - # Tries to find out the user name used for HTTP auth from two sources - def user_name - if request.env.include?('REMOTE_USER') then - u = request.env['REMOTE_USER'] - return u unless u.nil? - else - auth = http_authorization_data - return auth[0] unless auth.nil? - end - return nil - end - - def check_auth(username, password) - user = User.find_by_login(username) - - return false if user.nil? - return false if user.disabled - - password == GLSAMAKER_DEVEL_PASSWORD - end - - def http_authorization_data - return nil unless request.env.include?('HTTP_AUTHORIZATION') - return nil if request.env['HTTP_AUTHORIZATION'].nil? - - auth_info = request.env['HTTP_AUTHORIZATION'].split - - if auth_info[0] == "Basic" - auth_info[1].unpack("m*").first.split(/:/, 2) - else - logger.fatal "Non-Basic HTTP authentication given. I can't process that" - raise RuntimeError, "Cannot process this type of HTTP authentication" - end - end -end diff --git a/lib/authorization.rb b/lib/authorization.rb deleted file mode 100644 index 5341709..0000000 --- a/lib/authorization.rb +++ /dev/null @@ -1,49 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2011 Alex Legler <a3li@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. - -# Authorization module -module Authorization - # Checks access to a given GLSA - def check_object_access(glsa) - # Contributor, no foreign drafts - if current_user.access == 0 - unless glsa.is_owner? current_user - return false - end - elsif current_user.access < 3 - if glsa.restricted - return false - end - end - - true - end - - # Checks access to a given GLSA, and aborts the request if the user does not have sufficient permissions - def check_object_access!(glsa) - unless check_object_access(glsa) - deny_access "Access to restricted GLSA #{glsa.id} (#{params[:action]})" - return false - end - - true - end - - # Redirects the user to a 'Access Denied' screen and logs the incident - def deny_access(msg) - log_unauthorized_access msg - redirect_to :controller => '/index', :action => 'error', :type => 'access' - end - - # Logs an unauthorized access attempt - def log_unauthorized_access(msg) - logger.warn "[#{Time.now.rfc2822}] UNAUTHORIZED ACCESS by #{current_user.login} from #{request.remote_ip} to #{request.url}: #{msg}" - end -end diff --git a/lib/bugzilla.rb b/lib/bugzilla.rb deleted file mode 100644 index d6af1b3..0000000 --- a/lib/bugzilla.rb +++ /dev/null @@ -1,195 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@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. - -require 'nokogiri' -require 'fileutils' -require 'xmlrpc/client' - -module Bugzilla ; end - -%w[ comment history bug ].each {|lib| require File.join(File.dirname(__FILE__), "bugzilla/#{lib}")} - -# Bugzilla module -module Bugzilla - module_function - # Adds a comment to a bug. Returns the comment id on success, raises an exception on failure. - def add_comment(bug, comment) - if GLSAMAKER_BUGZIE_SKIP - Rails.logger.info 'Skipped Bugzilla.add_comment' - return - end - - Rails.logger.debug 'Called Bugzilla.add_comment' - did_retry = false - - begin - client, token = xmlrpc_client - - result = client.call('Bug.add_comment', { - 'id' => bug.to_i, - 'comment' => comment, - 'Bugzilla_token' => token, - }) - result['id'] - rescue XMLRPC::FaultException => e - if did_retry - raise "Could not add the comment: #{e.faultString} (code #{e.faultCode})" - end - - # If we need to log in first - if e.faultCode == 410 - Rails.logger.debug "Not logged in, doing that now." - log_in - did_retry = true - retry - else - raise "Could not add the comment: #{e.faultString} (code #{e.faultCode})" - end - end - - end - - # Updates a bug. Returns an array of changes that were done on the bug. - def update_bug(bug, changes = {}) - if GLSAMAKER_BUGZIE_SKIP - Rails.logger.info 'Skipped Bugzilla.update_bug' - return - end - - Rails.logger.debug 'Called Bugzilla.update_bug' - did_retry = false - - begin - client, token = xmlrpc_client - - rpc_data = {} - rpc_data['ids'] = [bug] - rpc_data['component'] = changes[:component] if changes.has_key?(:component) - rpc_data['product'] = changes[:product] if changes.has_key?(:product) - rpc_data['summary'] = changes[:summary] if changes.has_key?(:summary) - rpc_data['version'] = changes[:version] if changes.has_key?(:version) - rpc_data['comment'] = {'body' => changes[:comment]} if changes.has_key?(:comment) - rpc_data['priority'] = changes[:priority] if changes.has_key?(:priority) - rpc_data['severity'] = changes[:severity] if changes.has_key?(:severity) - rpc_data['alias'] = changes[:alias] if changes.has_key?(:alias) - rpc_data['assigned_to'] = changes[:assignee] if changes.has_key?(:assignee) - #rpc_data['cc'] = changes[:cc].to_a if changes.has_key?(:cc) TODO: add and remove - rpc_data['status'] = changes[:status] if changes.has_key?(:status) - rpc_data['whiteboard'] = changes[:whiteboard] if changes.has_key?(:whiteboard) - rpc_data['url'] = changes[:url] if changes.has_key?(:url) - rpc_data['resolution'] = changes[:resolution] if changes.has_key?(:resolution) - rpc_data['Bugzilla_token'] = token - - result = client.call('Bug.update', rpc_data) - result['bugs'].first - rescue XMLRPC::FaultException => e - if did_retry - raise "Could not file the bug: #{e.faultString} (code #{e.faultCode})" - end - - # If we need to log in first - if e.faultCode == 410 - Rails.logger.debug "Not logged in, doing that now." - log_in - did_retry = true - retry - else - raise "Could not file the bug: #{e.faultString} (code #{e.faultCode})" - end - end - end - - # Files a bug, and returns the id of the filed bug - def file_bug(data) - if GLSAMAKER_BUGZIE_SKIP - Rails.logger.info 'Skipped Bugzilla.file_bug' - return - end - - Rails.logger.debug 'Called Bugzilla.file_bug' - did_retry = false - - begin - client, token = xmlrpc_client - - rpc_data = {} - rpc_data['component'] = data[:component] if data.has_key?(:component) - rpc_data['product'] = data[:product] if data.has_key?(:product) - rpc_data['summary'] = data[:summary] if data.has_key?(:summary) - rpc_data['version'] = data[:version] if data.has_key?(:version) - rpc_data['description'] = data[:comment] if data.has_key?(:comment) - rpc_data['priority'] = data[:priority] if data.has_key?(:priority) - rpc_data['severity'] = data[:severity] if data.has_key?(:severity) - rpc_data['alias'] = data[:alias] if data.has_key?(:alias) - rpc_data['assigned_to'] = data[:assignee] if data.has_key?(:assignee) - rpc_data['cc'] = data[:cc].to_a if data.has_key?(:cc) - rpc_data['status'] = data[:status] if data.has_key?(:status) - rpc_data['Bugzilla_token'] = token - - result = client.call('Bug.create', rpc_data) - result['id'] - rescue XMLRPC::FaultException => e - if did_retry - raise "Could not file the bug: #{e.faultString} (code #{e.faultCode})" - end - - # If we need to log in first - if e.faultCode == 410 - Rails.logger.debug "Not logged in, doing that now." - log_in - did_retry = true - retry - else - raise "Could not file the bug: #{e.faultString} (code #{e.faultCode})" - end - end - end - - def log_in - Rails.logger.debug "Called Bugzilla.log_in" - raise unless GLSAMAKER_BUGZIE_USER and GLSAMAKER_BUGZIE_PW - - client, token = xmlrpc_client - - begin - result = client.call('User.login', { - 'login' => GLSAMAKER_BUGZIE_USER, - 'password' => GLSAMAKER_BUGZIE_PW - }) - - Rails.logger.debug "Successfully logged in. UID: #{result['id']}" - - token_file = File.join(Rails.root, 'tmp', 'bugzie-token.txt') - FileUtils.rm(token_file) if File.exist?(token_file) - FileUtils.touch(token_file) - File.chmod(0600, token_file) - File.open(token_file, 'w') {|f| f.write result['token'] } - - return true - rescue XMLRPC::FaultException => e - Rails.logger.warn "Failure logging in: #{e.message}" - return false - end - end - - def xmlrpc_client - client = XMLRPC::Client.new(GLSAMAKER_BUGZIE_HOST, '/xmlrpc.cgi', 443, nil, nil, nil, nil, true) - client.http_header_extra = {'User-Agent' => "GLSAMaker/#{GLSAMAKER_VERSION} (https://security.gentoo.org/)"} - - token = '' - token_file = File.join(Rails.root, 'tmp', 'bugzie-token.txt') - if File.readable? token_file - token = File.read(token_file) - end - - [client, token] - end -end diff --git a/lib/bugzilla/bug.rb b/lib/bugzilla/bug.rb deleted file mode 100644 index 7f6b20b..0000000 --- a/lib/bugzilla/bug.rb +++ /dev/null @@ -1,143 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2010 Alex Legler <a3li@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. - -# Encapsulates a Bugzilla Bug -module Bugzilla - class Bug - attr_reader :summary, :created_at, :reporter, :alias, :assigned_to, :cc, :status_whiteboard, - :product, :component, :status, :resolution, :url, :comments, :bug_id, :restricted, - :severity, :priority, :depends, :blocks - - alias :title :summary - - # Creates a new +Bug+ object from the Gentoo bug referenced as #+bugid+ - def self.load_from_id(bugid) - begin - id = Integer(bugid) - - raise ArgumentError if id == 0 - rescue ArgumentError => e - raise ArgumentError, "Invalid Bug ID" - end - - begin - xml = Nokogiri::XML(Glsamaker::HTTP.get("https://#{GLSAMAKER_BUGZIE_HOST}/show_bug.cgi?ctype=xml&id=#{id}")) - rescue SocketError => e - raise SocketError, "Bugzilla is unreachable: #{e.message}" - rescue Exception => e - raise ArgumentError, "Couldn't load bug: #{e.message}" - end - - self.new(xml.root.xpath("bug").first, bugid) - end - - # Returns the URL for the bug, set +secure+ to false to get a http:-URL - def url(secure = true) - if secure - "https://#{GLSAMAKER_BUGZIE_HOST}/show_bug.cgi?id=#{@bug_id}" - else - "http://#{GLSAMAKER_BUGZIE_HOST}/show_bug.cgi?id=#{@bug_id}" - end - end - - def history() - @history ||= History.new(self) - end - - def initialize(bug, id) - unless bug.is_a? Nokogiri::XML::Element - raise ArgumentError, "Nokogiri failure" - end - - if bug["error"] == "NotFound" - raise ArgumentError, "Bug not found" - elsif bug["error"] == "NotPermitted" - @bug_id = id - @restricted = true - return - end - - @restricted = false - @cc = [] - @depends = [] - @blocks = [] - @comments = [] - - bug.children.each do |node| - # Ignore whitespace - next if node.type == Nokogiri::XML::Node::TEXT_NODE - # Ignore empty nodes - next if node.children.size == 0 - - case node.name - when "bug_id" then - @bug_id = content_in node - when "short_desc" then - @summary = content_in node - when "creation_ts" then - @created_at = Time.parse(content_in(node)) - when "reporter" then - @reporter = content_in node - when "alias" then - @alias = content_in node - when "assigned_to" then - @assigned_to = content_in node - when "cc" then - @cc << content_in(node) - when "status_whiteboard" then - @status_whiteboard = content_in node - when "product" then - @product = content_in node - when "component" then - @component = content_in node - when "bug_status" then - @status = content_in node - when "resolution" then - @resolution = content_in node - when "bug_file_loc" then - @url = content_in node - when "bug_severity" then - @severity = content_in node - when "priority" then - @priority = content_in node - when "dependson" then - @depends << content_in(node) - when "blocked" then - @blocks << content_in(node) - when "long_desc" then - @comments << Bugzilla::Comment.new( - node.xpath("who").first.children.first.to_s, - node.xpath("thetext").first.children.first.to_s, - node.xpath("bug_when").first.children.first.to_s - ) - end - end - end - - # Returns the initial bug description - def description - @comments.first.text - end - - # Splits a String +str+ into an array of valid bug IDs - def self.str2bugIDs(str) - bug_ids = str.split(/,\s*/) - - bug_ids.map do |bug| - bug.gsub(/\D/, '') - end - end - - private - def content_in(node) - node.children.first.content.strip - end - end -end diff --git a/lib/bugzilla/comment.rb b/lib/bugzilla/comment.rb deleted file mode 100644 index 2cd9236..0000000 --- a/lib/bugzilla/comment.rb +++ /dev/null @@ -1,22 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2010 Alex Legler <a3li@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. - -# Encapsulates a comment to a Bug -module Bugzilla - class Comment - attr_reader :author, :text, :date - - def initialize(by, text, date) - @author = by - @text = text - @date = Time.parse(date) - end - end -end diff --git a/lib/bugzilla/history.rb b/lib/bugzilla/history.rb deleted file mode 100644 index 04188e4..0000000 --- a/lib/bugzilla/history.rb +++ /dev/null @@ -1,104 +0,0 @@ -# Encapsulates a bug's history -module Bugzilla - class History - attr_reader :changes - - # Creates a new History for the Bug object +bug+. - def initialize(bug) - unless bug.respond_to? :bug_id - raise ArgumentError, "Need a bug (or something that at least looks like a bug)" - end - - begin - html = Nokogiri::HTML(Glsamaker::HTTP.get("https://bugs.gentoo.org/show_activity.cgi?id=#{bug.bug_id}")) - rescue Exception => e - raise ArgumentError, "Couldn't load the bug history: #{e.message}" - end - - @changes = [] - change_cache = nil - - html.xpath("/html/body/table/tr").each do |change| - # ignore header line - next if change.children.first.name == "th" - - # First line in a multi-change set - unless (chcount = change.children.first["rowspan"]) == nil - change_cache = Change.new(change.children.first.content.strip, change.children[2].content.strip) - - change_cache.add_change( - change.children[4].content.strip.downcase.to_sym, - change.children[6].content.strip, - change.children[8].content.strip - ) - - @changes << change_cache - else - change_cache.add_change( - change.children[0].content.strip.downcase.to_sym, - change.children[2].content.strip, - change.children[4].content.strip - ) - end - end - end - - # Returns an Array of Changes made to the field +field+ - def by_field(field) - raise(ArgumentError, "Symbol expected") unless field.is_a? Symbol - - changes = [] - - @changes.each do |change| - if change.changes.has_key?(field) - changes << change - end - end - - changes - end - - # Returns an Array of Changes made by the user +user+ - def by_user(user) - changes = [] - - @changes.each do |change| - if change.user == user - changes << change - end - end - - changes - end - end - - # This represents a single Change made to a Bug - class Bugzilla::Change - attr_reader :user, :time, :changes - - # Creates a new Change made by +user+ at +time+. - def initialize(user, time) - @user = user || "" - @time = Time.parse(time) - @changes = {} - end - - # Adds a changed +field+ to the Change object. +removed+ denotes the removed text - # and +added+ is the new text - def add_change(field, removed, added) - raise(ArgumentError, "field has to be a symbol") unless field.is_a? Symbol - - if @changes.has_key?(field) - @changes[field][0] += " #{removed}" - @changes[field][1] += " #{added}" - else - @changes[field] = [removed, added] - end - end - - # Returns a string representation - def to_s - "#{@user} changed at #{@time.to_s}: #{@changes.inspect}" - end - end -end diff --git a/lib/glsamaker.rb b/lib/glsamaker.rb deleted file mode 100644 index fdc93d8..0000000 --- a/lib/glsamaker.rb +++ /dev/null @@ -1,23 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@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. - -require 'glsamaker/http' -require 'glsamaker/portage' -require 'glsamaker/diff' -require 'glsamaker/xml' -require 'glsamaker/bugs' -require 'glsamaker/mail' - -#FIXME: spelling module is developed with dead 'runspell' gem. -# -#require 'glsamaker/spelling' - -# require 'glsamaker/helpers' DO NOT REQUIRE or else the rake tasks will blow up diff --git a/lib/glsamaker/bugs.rb b/lib/glsamaker/bugs.rb deleted file mode 100644 index 567624e..0000000 --- a/lib/glsamaker/bugs.rb +++ /dev/null @@ -1,182 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@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. - -require 'bugzilla' - -module Glsamaker - module Bugs - - module StatusMixin - def secbug_status - if whiteboard =~ /([A-C~?][0-4?]\??)\s+\[(.*?)\]\s*?(.*?)$/ - st = [] - - $2.split("/").each do |status| - st << Status.new(status) - end - - return st - else - [Status.new('?')] - end - end - end - - module ArchesMixin - # Returns an array of all arch teams in CC - def arch_cc - @arch_cc ||= _arch_cc - end - - private - def _arch_cc - ccd_arches = [] - our_arches = %w[ alpha@gentoo.org amd64@gentoo.org arm@gentoo.org bsd@gentoo.org hppa@gentoo.org - ia64@gentoo.org m68k@gentoo.org mips@gentoo.org ppc64@gentoo.org ppc@gentoo.org release@gentoo.org - s390@gentoo.org sh@gentoo.org sparc@gentoo.org x86@gentoo.org ] - - if cc.is_a? String - _cc = cc.split(/,\s*/) - elsif cc.nil? - _cc = [] - else - _cc = cc - end - - _cc.each do |cc_member| - if our_arches.include? cc_member - ccd_arches << cc_member - end - end - - ccd_arches - end - end - - module BugReadyMixin - # Indicates whether this bug has been handled and is in the correct - # state for sending a GLSA assigned to it. - def bug_ready? - secbug_status.each do |s| - return false unless s.status == :glsa and not s.pending? - end - - return arch_cc == [] - rescue Exception => e - return false - end - end - - # Extends Bugzilla::Bug with the Status and Arches functionality - class Bug < Bugzilla::Bug - def whiteboard - @status_whiteboard - end - - def cc - @cc - end - - # Returns the Gentoo Bugzilla URI for the bug. - # Set +secure+ to false to get a HTTP instead of a HTTPS URI - def bug_url(secure = true) - if secure - "https://#{GLSAMAKER_BUGZIE_HOST}/show_bug.cgi?id=#{self.bug_id}" - else - "http://#{GLSAMAKER_BUGZIE_HOST}/show_bug.cgi?id=#{self.bug_id}" - end - end - - include StatusMixin - include ArchesMixin - include BugReadyMixin - end - - # This baby is a bug status, one of the things you see in squared brackets in whiteboards. - class Status - include Comparable - - attr_reader :status - - # Creates a new Status object by parsing +str+ as a single status string - def initialize(str) - if str == '?' - @status = '?'.to_sym - @blocked = @overdue = @pending = false - return - end - - cmp = str.strip.split(/\s+/) - - if cmp.length == 2 - @blocked = (cmp[1] == "blocked") - end - - if cmp[0] =~ /^(upstream|ebuild|stable|glsa|noglsa)(\+|\?|\+\?|\?\+)?$/ - @overdue = ($2 != nil and $2.include? "+") - @pending = ($2 != nil and $2.include? "?") - - @status = $1.downcase.to_sym - else - raise ArgumentError, "Malformed Status string: #{str}" - end - end - - # Returns +true+ if the bug is blocked by another (c.f. +'blocked'+ in whiteboards) - def blocked? - @blocked - end - - # Returns +true+ if the bug is overdue (cf. +'+'+ in whiteboards) - def overdue? - @overdue - end - - # Returns +true+ if the bug is pending action (cf. +'?'+ in whiteboards) - def pending? - @pending - end - - # Returns a string representation (like you would find it in the whiteboard) - def to_s - @status.to_s + (@overdue ? "+" : "") + (@pending ? "?" : "") + (@blocked ? " blocked" : "") - end - - # Comparison - def <=>(other) - raise(ArgumentError, "Cannot compare to #{other.class}") unless other.is_a? Status - - s = ['?'.to_sym, :upstream, :ebuild, :stable, :glsa, :noglsa] - - if other.status == @status - if other.pending? == @pending and other.overdue? == @overdue - 0 - else - if other.overdue? and not @overdue - -1 - elsif @overdue and not other.overdue? - 1 - else - if @pending and not other.pending? - -1 - else - 1 - end - end - end - else - (s.index(@status) - s.index(other.status)) < 0 ? -1 : 1 - end - end - - end - end -end diff --git a/lib/glsamaker/diff.rb b/lib/glsamaker/diff.rb deleted file mode 100644 index 18e10f6..0000000 --- a/lib/glsamaker/diff.rb +++ /dev/null @@ -1,53 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@gentoo.org> -# Copyright (C) 2006-2007 Jean-Philippe Lang -# -# 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. - -require 'diff/lcs' -require 'diff/lcs/hunk' - -module Glsamaker - # Module providing diff support - module Diff - module_function - - # Returns a unified diff for two strings - # Adapted from the O'Reilly Ruby Cookbook - def diff(str_old, str_new, format = :unified, context_lines = 3) - str_old = str_old.split(/\r?\n/).map! { |l| l.chomp } - str_new = str_new.split(/\r?\n/).map! { |l| l.chomp } - - output = "" - diffs = ::Diff::LCS.diff(str_old, str_new) - return output if diffs.empty? - - oldhunk = hunk = nil - file_length_difference = 0 - diffs.each do |piece| - begin - hunk = ::Diff::LCS::Hunk.new(str_old, str_new, piece, context_lines, file_length_difference) - next unless oldhunk - - if (context_lines > 0) and hunk.overlaps?(oldhunk) - hunk.unshift(oldhunk) - else - output << oldhunk.diff(format) - end - ensure - oldhunk = hunk - output << "\n" - end - end - - output << oldhunk.diff(format) << "\n" - end - - end -end diff --git a/lib/glsamaker/helpers.rb b/lib/glsamaker/helpers.rb deleted file mode 100644 index aca09ab..0000000 --- a/lib/glsamaker/helpers.rb +++ /dev/null @@ -1,21 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2010 Alex Legler <a3li@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. - -module Glsamaker - module_function - def help - Helper.instance - end - - class Helper - include Singleton - include ::ActionView::Helpers::TextHelper - end -end diff --git a/lib/glsamaker/http.rb b/lib/glsamaker/http.rb deleted file mode 100644 index 5f63096..0000000 --- a/lib/glsamaker/http.rb +++ /dev/null @@ -1,37 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@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. - -require 'net/http' -require 'net/https' - -# GLSAMaker library -module Glsamaker - # GLSAMaker HTTP utilities - module HTTP - # Tries to fetch +url+ via HTTP GET, sending a GLSAMaker custom User-Agent header. - # The body part is returned. - def get(url) - uri = URI.parse(url) - - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true if uri.scheme == "https" - res = http.start { - http.request_get(uri.request_uri, {'User-Agent' => "GLSAMaker/#{GLSAMAKER_VERSION} (https://security.gentoo.org/)"}) - } - - # Raises an exception if HTTP status suggests something went wrong - res.value - res.body - end - - module_function :get - end -end diff --git a/lib/glsamaker/mail.rb b/lib/glsamaker/mail.rb deleted file mode 100644 index b749193..0000000 --- a/lib/glsamaker/mail.rb +++ /dev/null @@ -1,106 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2010-11 Alex Legler <a3li@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. - -module Glsamaker - module Mail - module_function - def edit_notification(glsa, diff, user) - if GLSAMAKER_NO_EMAIL - Rails.logger.info "Not sending email." - return false - end - - if glsa.restricted - Rails.logger.info "Not sending email, confidential item." - return false - end - - User.active.each do |rcpt| - next unless rcpt.can_access? glsa - - unless rcpt.get_pref_category(:mail)[:edit] == false - GlsaMailer.edit(rcpt, glsa, diff, user).deliver - end - end - end - - def request_notification(glsa, user) - if GLSAMAKER_NO_EMAIL - Rails.logger.info "Not sending email." - return false - end - - if glsa.restricted - Rails.logger.info "Not sending email, confidential item." - return false - end - - User.active.each do |rcpt| - next unless rcpt.can_access? glsa - - unless rcpt.get_pref_category(:mail)[:request] == false - GlsaMailer.new_request(rcpt, glsa, user).deliver - end - end - end - - def comment_notification(glsa, comment, user) - if GLSAMAKER_NO_EMAIL - Rails.logger.info "Not sending email." - return false - end - - # Nothing to do if there's no submitter yet - return if glsa.status == 'request' - - if glsa.restricted - Rails.logger.info "Not sending email, confidential item." - return false - end - - rcpt = glsa.submitter - return unless rcpt.can_access? glsa - return if rcpt == user - - unless rcpt.get_pref_category(:mail)[:comment] == false - GlsaMailer.comment(rcpt, glsa, comment, user).deliver - end - end - - def approval_notification(glsa) - if GLSAMAKER_NO_EMAIL - Rails.logger.info "Not sending email." - return false - end - - if glsa.restricted - Rails.logger.info "Not sending email, confidential item." - return false - end - - rcpt = glsa.submitter - return unless rcpt.can_access? glsa - - unless rcpt.get_pref_category(:mail)[:comment] == false - GlsaMailer.approval(rcpt, glsa).deliver - end - end - - def send_text(text, subject, user, footer = true) - if GLSAMAKER_NO_EMAIL - Rails.logger.info "Not sending email." - return false - end - - GlsaMailer.text(user, subject, text, footer).deliver - end - - end -end diff --git a/lib/glsamaker/portage.rb b/lib/glsamaker/portage.rb deleted file mode 100644 index f49e93e..0000000 --- a/lib/glsamaker/portage.rb +++ /dev/null @@ -1,194 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@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. - -require 'nokogiri' - -module Glsamaker - # Helper functions for Portage tree interaction - module Portage - - # Package description helper - class Description - class << self - # Tries to fetch the description for the package +atom+ from - # an ebuild's entry (works if running on Gentoo) - def ebuild(atom) - raise(ArgumentError, "Invalid package atom") unless Portage.valid_atom?(atom) - nil - end - - def eix(atom) - nil - end - - # Loads a description for +atom+ from packages.gentoo.org - def pgo(atom) - raise(ArgumentError, "Invalid package atom") unless Portage.valid_atom?(atom) - - n = Nokogiri::XML(Glsamaker::HTTP.get("https://packages.gentoo.org/package/#{atom}")) - - node = n.css('p.description').first.children.first - if node.type == Nokogiri::XML::Node::TEXT_NODE - node.to_s - else - raise ArgumentError, "XML parse error" - end - end - - # Loads a description for +atom+ from Google - def google(atom) - nil - end - end - end - - module_function - # Returns the location of the portage dir, or raises an exception if it cannot be found - def portdir - unless File.directory? GLSAMAKER_PORTDIR - raise "GLSAMAKER_PORTDIR is not a directory" - end - - GLSAMAKER_PORTDIR - end - - # Validates the atom +atom+ - def valid_atom?(atom) - atom =~ /^[+a-zA-Z0-9_-]+\/[+a-zA-Z0-9_-]+$/ - end - - # Checks if there are any ebuilds for the +atom+ - def has_ebuilds?(atom) - return false unless valid_atom? atom - - Dir.chdir("#{portdir}/#{atom}") do - Dir.glob('*.ebuild') do |ebuild| - return true - end - end - - false - rescue Errno::ENOENT - false - end - - # Gets a description - def get_description(atom) - Description.eix(atom) || - Description.ebuild(atom) || - Description.pgo(atom) || - Description.google(atom) || - "[could not get a description]" - end - - # Returns package atoms that match +re+ - def find_packages(re) - results = [] - - Dir.chdir(portdir) do - Dir.glob('*-*') do |cat| - Dir.chdir(cat) do - Dir.glob("*") do |pkg| - pkg =~ re and results << "#{cat}/#{pkg}" - end - end - end - end - - results - end - - # Returns an array of maintainer email addresses for the package +atom+ - def get_maintainers(atom) - raise(ArgumentError, "Invalid package atom") unless Portage.valid_atom?(atom) - raise(ArgumentError, "Cannot find metadata") unless File.exist? File.join(portdir, atom, 'metadata.xml') - - x = Nokogiri::XML(File.read(File.join(portdir, atom, 'metadata.xml'))) - - maintainers = [] - - x.xpath('/pkgmetadata/maintainer/email').each {|m| maintainers << m.content } - - if maintainers.empty? - if x.path('/pkgmetadata/comment()').text.include? "maintainer-needed" - maintainers = "maintainer-needed@gentoo.org" - else - raise(ArgumentError, "No Maintainer Information Found") - end - end - - maintainers - end - - # Returns information from the portage metadata cache - # Values: :depend, :rdepend, :slot, :src_uri, :restrict, :homepage, - # :license, :description, :keywords, :iuse, :required_use, - # :pdepend, :provide, :eapi, :properties, :defined_phases - # as per portage/pym/portage/cache/metadata.py (database.auxdbkey_order) - # - # @param [String] atom Package atom (without version, see next parameter) - # @param [String] version Desired version, tries to use the last available one (as decided by a rather stupid technique) - # @return [Hash{Symbol => String, Array}] A hash with all available metadata (see above for keys) - def get_metadata(atom, version = :latest) - raise(ArgumentError, "Invalid package atom") unless Portage.valid_atom?(atom) - raise(ArgumentError, "Invalid version string") if version.to_s.include? '..' - - items = { - 'DEFINED_PHASES' => :defined_phases, - 'DEPEND' => :depend, - 'DESCRIPTION' => :description, - 'EAPI' => :eapi, - 'HOMEPAGE' => :homepage, - 'IUSE' => :iuse, - 'KEYWORDS' => :keywords, - 'LICENSE' => :license, - 'PDEPEND' => :pdepend, - 'PROPERTIES' => :properties, - 'RDEPEND' => :rdepend, - 'RESTRICT' => :restrict, - 'REQUIRED_USE' => :required_use, - 'SLOT' => :slot, - 'SRC_URI' => :src_uri - } - - valid_keys = items.keys - - # List of metadata items to split at space - split_keys = ['SRC_URI', 'IUSE', 'KEYWORDS', 'PROPERTIES', 'DEFINED_PHASES'] - - cat, pkg = atom.split('/', 2) - r = Regexp.compile('^(\\w+)=([^\n]*)') - result = {} - - Dir.chdir(File.join(Glsamaker::Portage.portdir, 'metadata', 'md5-cache', cat)) do - if version == :latest - f = File.open(Dir.glob("#{pkg}-[0-9]*").last, 'r') - else - f = File.open(File.join("#{pkg}-#{version}"), 'r') - end - - while f.gets - if (match = r.match($_)) != nil and valid_keys.include? match[1] - if split_keys.include? match[1] - result[items[match[1]]] = match[2].split(' ') - else - result[items[match[1]]] = match[2] - end - end - end - - f.close - end - result - end - end - -end diff --git a/lib/glsamaker/spelling.rb b/lib/glsamaker/spelling.rb deleted file mode 100644 index cc30cc8..0000000 --- a/lib/glsamaker/spelling.rb +++ /dev/null @@ -1,48 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@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. - -module Glsamaker - class Spelling - class << self - def init - dic = File.join(Rails.root, 'vendor', 'dictionaries', 'en_US.dic') - aff = File.join(Rails.root, 'vendor', 'dictionaries', 'en_US.aff') - - @runspell = Runspell.new(aff, dic) - end - - def check(word) - init if @runspell.nil? - @runspell.check(word) - end - - def suggest(word) - init if @runspell.nil? - @runspell.suggest(word) - end - - # Checks a string for spelling, <tt>before_marker</tt> and <tt>after_maker</tt> are put around the misspelled words - def check_string(string, before_marker, after_marker) - result = [] - string.split(/\b/).each do |word| - if word =~ /^[\s,.-:(){}\[\]<>]*$/ - result << word - elsif check(word) - result << word - else - result << before_marker.html_safe + word + after_marker.html_safe - end - end - - result.join - end - end - end -end diff --git a/lib/glsamaker/xml.rb b/lib/glsamaker/xml.rb deleted file mode 100644 index 2b0e375..0000000 --- a/lib/glsamaker/xml.rb +++ /dev/null @@ -1,31 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2010 Alex Legler <a3li@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. - -module Glsamaker - module XML - module_function - def indent(xml, options = {:indent => 2}) - command = GLSAMAKER_XMLINDENT - raise "xmlindent either does not exist or is not executable." unless File.executable? command.split(' ', 2)[0] - - command += " -i#{Integer options[:indent]}" if options.has_key? :indent - command += " -l#{Integer options[:maxcols]}" if options.has_key? :maxcols - - # \r\n will make problems while converting - xml.gsub!("\r", "") - - IO.popen(command, 'r+') do |io| - io.write xml - io.close_write - io.read - end - end - end -end diff --git a/lib/kramdown_ext.rb b/lib/kramdown_ext.rb deleted file mode 100644 index e41013e..0000000 --- a/lib/kramdown_ext.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Kramdown - module Converter - class Xml < Html - NOENTITY_MAP = { - :mdash => '---', - :ndash => '--', - :hellip => '...', - :laquo_space => '<< ', - :raquo_space => ' >>', - :laquo => '<', - :raquo => '>' - } - - # Overriding to do nothing. We don't want typographic symbols replaced - def convert_typographic_sym(el, opts) - NOENTITY_MAP[el.value] - end - end - end -end diff --git a/lib/tasks/.gitkeep b/lib/tasks/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/lib/tasks/.gitkeep +++ /dev/null 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 diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake deleted file mode 100644 index ec34f91..0000000 --- a/lib/tasks/import.rake +++ /dev/null @@ -1,256 +0,0 @@ -require 'rexml/document' -require 'nokogiri' -require 'net/http' -require 'uri' -require 'date' - -namespace :import do - - desc "Import Request Files" - task :requests => :environment do - info "Importing GLSA requests" - - glsa_req_dir = ENV['GLSA_REQ_DIR'] - if glsa_req_dir == nil - puts "Please, set GLSA_REQ_DIR" - exit(-1) - end - - glsa_list = Array.new - Glsa.all.each do |glsa| - glsa_list.push glsa.glsa_id - end - - default_user = User.first - if default_user == nil - raise "No users defined!" - end - - Dir.glob(glsa_req_dir + "/*.xml").each do |filename| - req_f = File.new(filename) - doc = REXML::Document.new req_f - - root = doc.root - glsa_req_id = root.attributes['id'][0..7] - - if not glsa_list.include? glsa_req_id - puts "Processing GLSA Request #{glsa_req_id}" - - glsa = Glsa.new - glsa.glsa_id = glsa_req_id - glsa.status = 'request' - - root.elements.each('metadata') do |meta| - user = meta.text.strip - user = User.where(:login => user) - - if user.length > 0 - user = user[0] - else - user = default_user - end - - glsa.requester = user if meta.attributes['tag'] == 'requester' - - end - - unless glsa.save - raise "Errors occurred while saving the GLSA object: #{glsa.errors.full_messages.join ', '}" - end - - root.elements.each('metadata/metadata/metadata') do |comm| - puts comm.text.strip() - - comment = glsa.comments.new - comment.user_id = glsa.requester - comment.rating = 'neutral' - comment.text = comm.text.strip - - unless comment.save - raise "Error. #{comment.errors.full_messages.join ', '}" - end - end - - #It's time for the revision - revision = glsa.revisions.new - revision.revid = 1 - revision.user = glsa.requester - revision.title = root.elements['title'].text - revision.impact = root.elements['impact'].attributes['type'] - revision.product = root.elements['product'].attributes['type'] - revision.resolution = root.elements['resolution'].text - revision.workaround = root.elements['workaround'].text - revision.description = root.elements['description'].text - revision.is_release = false - revision.severity = root.elements['impact'].attributes['type'] - - unless revision.save - #Clean up - glsa.delete - raise "Errors occurred while saving the Revision object: #{revision.errors.full_messages.join ', '}" - end - - #Let's grab the bugs - root.elements.each('bug') do |bug| - Bug.create( - :bug_id => bug.text, - :revision_id => revision - ) - end - - end - end - end - - desc "Import Advisory Files" - task :advisories => :environment do - info "Importing old GLSAs from www.gentoo.org" - - #Lets grab the IDs we have in the DB, the see - #if we already processed them - glsa_list = Array.new - Glsa.all.each do |glsa| - glsa_list.push glsa.glsa_id - end - - GLSA_URL = "https://www.gentoo.org/rdf/en/glsa-index.rdf" - GLSA_URL_BASE = "https://www.gentoo.org/security/en/glsa/glsa-%s.xml?passthru=1" - - default_user = User.first - if default_user == nil - raise "No users defined!" - end - - #Let's parse the XML and get the advisories ID - index = Nokogiri::XML(Glsamaker::HTTP.get(GLSA_URL)) - index.remove_namespaces! - root_idx = index.root - ids = Array.new - - root_idx.xpath('item').each do |elem| - url = elem.at_xpath('./link').content - elem.at_xpath('./title').content =~ /GLSA\s(\d{6})-(\d{1,3})\s\(.*/ - id = "#{$1}-#{$2}" - ids << id - end - - ids.reverse_each do |id| - #if id no in glsa_list, then process the url - if not glsa_list.include? id - puts "Processing GLSA Advisory #{id}" - - xml = index = Nokogiri::XML(Glsamaker::HTTP.get(GLSA_URL_BASE % id)) - root = xml.root - - #Lets create the GLSA in the DB - glsa = Glsa.new - glsa.glsa_id = id - glsa.status = 'release' - glsa.first_released_at = DateTime.parse(root.at_xpath('./announced').content) - - #Lets take a look at users in Metadata - root.xpath('metadata').each do |meta| - user = meta.content.strip() - user = User.where(:login => user) - - if user.length > 0 - user = user[0] - else - user = default_user - end - - glsa.submitter = user if meta['tag'] == 'submitter' - glsa.requester = user if meta['tag'] == 'requester' - glsa.bugreadymaker = user if meta['tag'] == 'bugReady' - end - - #For old GLSAs with no metadata - if glsa.submitter == nil - glsa.submitter = default_user - end - - if glsa.requester == nil - glsa.requester = default_user - end - - unless glsa.save - raise "Errors occurred while saving the GLSA object: #{glsa.errors.full_messages.join ', '}" - end - - #Lets create the Revision in the DB - revision = Revision.new - - revision.glsa = glsa - revision.user = glsa.submitter - revision.revid = 1 - revision.release_revision = root.at_xpath('./revised').content.split(':')[1].strip.to_i - revision.title = root.at_xpath('./title').content - revision.impact = root.at_xpath('./impact').children.to_xml(:indent => 0) - revision.product = root.at_xpath('./product').content - revision.synopsis = root.at_xpath('./synopsis').children.to_xml(:indent => 0) - revision.resolution = root.at_xpath('./resolution').children.to_xml(:indent => 0) - revision.workaround = root.at_xpath('./workaround').children.to_xml(:indent => 0) - revision.description = root.at_xpath('./description').children.to_xml(:indent => 0) - revision.is_release = true - revision.severity = root.at_xpath('./impact')['type'] - - #Old GLSAs may not have a background tag - begin - revision.background = root.at_xpath('./background').content.strip - rescue - revision.background = nil - end - - #Old GLSAs may not have an access tag - begin - revision.access = root.at_xpath('./access').content.strip - rescue - revision.access = nil - end - - unless revision.save - #Clean up - glsa.delete - raise "Errors occurred while saving the Revision object: #{revision.errors.full_messages.join ', '}" - end - - #Let's grab the bugs - root.xpath('bug').each do |bug| - revision.bugs.create( - :bug_id => bug.content.to_i - ) - end - - #Let's grab the references - root.xpath('references/uri').each do |uri| - revision.references.create( - :url => uri['link'], - :title => uri.content - ) - end - - #Let's grab the packages - root.xpath('affected/package').each do |pkg_info| - pkg_info.children.each do |inner| - if inner.is_a? Nokogiri::XML::Node - auto = true - if inner['auto'] == 'n' - auto = false - end - - revision.packages.create( - :my_type => inner.node_name, - :atom => pkg_info['name'], - :version => inner.content, - :comp => Package.reverse_comp(inner['range']), - :arch => pkg_info['arch'], - :automatic => auto - ) - - end - end - end - end - end - end -end diff --git a/lib/tasks/rcov.rake b/lib/tasks/rcov.rake deleted file mode 100644 index bb602e4..0000000 --- a/lib/tasks/rcov.rake +++ /dev/null @@ -1,81 +0,0 @@ -def run_coverage(files) - rm_f "coverage" - rm_f "coverage.data" - - # turn the files we want to run into a string - if files.empty? - puts "No files were specified for testing" - return - end - - files = files.join(" ") - - if RUBY_PLATFORM =~ /darwin/ - exclude = '--exclude "gems/*" --exclude "Library/Frameworks/*"' - elsif RUBY_PLATFORM =~ /java/ - exclude = '--exclude "rubygems/*,jruby/*,parser*,gemspec*,_DELEGATION*,eval*,recognize_optimized*,yaml,yaml/*,fcntl"' - else - exclude = '--exclude "gems/*"' - end - # rake test:units:rcov SHOW_ONLY=models,controllers,lib,helpers - # rake test:units:rcov SHOW_ONLY=m,c,l,h - if ENV['SHOW_ONLY'] - params = String.new - show_only = ENV['SHOW_ONLY'].to_s.split(',').map{|x|x.strip} - if show_only.any? - reg_exp = [] - for show_type in show_only - reg_exp << case show_type - when 'm', 'models' then 'app\/models' - when 'c', 'controllers' then 'app\/controllers' - when 'h', 'helpers' then 'app\/helpers' - when 'l', 'lib' then 'lib' - else - show_type - end - end - reg_exp.map!{ |m| "(#{m})" } - params << " --exclude \"^(?!#{reg_exp.join('|')})\"" - end - exclude = exclude + params - end - - rcov_bin = RUBY_PLATFORM =~ /java/ ? "jruby -S rcov" : "rcov" - rcov = "#{rcov_bin} --rails -Ilib:test --sort coverage --text-report #{exclude}" - puts - puts - puts "Running tests..." - cmd = "#{rcov} #{files}" - puts cmd - begin - sh cmd - rescue Exception => e - $stderr.puts "#{e.message}" - $stderr.puts "The tests likely failed. Not aborting to not break Hudson builds" - end -end - -namespace :test do - - desc "Measures unit, functional, and integration test coverage" - task :coverage do - run_coverage Dir["test/unit/**/*.rb", "test/functional/**/*.rb", "test/integration/**/*.rb"] - end - - namespace :coverage do - desc "Runs coverage on unit tests" - task :units do - run_coverage Dir["test/unit/**/*.rb"] - end - - desc "Runs coverage on functional tests" - task :functionals do - run_coverage Dir["test/functional/**/*.rb"] - end - - desc "Runs coverage on integration tests" - task :integration do - run_coverage Dir["test/integration/**/*.rb"] - end - end -end diff --git a/lib/tasks/utils.rb b/lib/tasks/utils.rb deleted file mode 100644 index 3e49702..0000000 --- a/lib/tasks/utils.rb +++ /dev/null @@ -1,35 +0,0 @@ -# ===GLSAMaker v2 -# Copyright (C) 2009-2011 Alex Legler <a3li@gentoo.org> -# Copyright (C) 2009 Pierre-Yves Rofes <py@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. -# - -class String - def purple - ansi 35 - end - - def red - ansi 31 - end - - def green - ansi 32 - end - - def bold - ansi 1 - end - - private - def ansi(code) - code = Integer(code) - "\033[1;#{code}m#{self}\033[0m" - end -end |