From 89d7e430fd821dc2c2fb5f52e179f4ccb169da2c Mon Sep 17 00:00:00 2001 From: Stephen Kapp Date: Mon, 4 Jun 2012 09:18:20 +0100 Subject: [PATCH] Initial Commit --- .gitignore | 4 ++ Gemfile | 4 ++ Rakefile | 1 + lib/veracode.rb | 10 +++++ lib/veracode/admin.rb | 4 ++ lib/veracode/api/builds.rb | 56 +++++++++++++++++++++++ lib/veracode/api/detailed.rb | 83 ++++++++++++++++++++++++++++++++++ lib/veracode/api/parse.rb | 87 ++++++++++++++++++++++++++++++++++++ lib/veracode/base.rb | 28 ++++++++++++ lib/veracode/config.rb | 20 +++++++++ lib/veracode/results.rb | 43 ++++++++++++++++++ lib/veracode/upload.rb | 4 ++ lib/veracode/version.rb | 3 ++ veracode.gemspec | 24 ++++++++++ 14 files changed, 371 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Rakefile create mode 100644 lib/veracode.rb create mode 100644 lib/veracode/admin.rb create mode 100644 lib/veracode/api/builds.rb create mode 100644 lib/veracode/api/detailed.rb create mode 100644 lib/veracode/api/parse.rb create mode 100644 lib/veracode/base.rb create mode 100644 lib/veracode/config.rb create mode 100644 lib/veracode/results.rb create mode 100644 lib/veracode/upload.rb create mode 100644 lib/veracode/version.rb create mode 100644 veracode.gemspec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4040c6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.gem +.bundle +Gemfile.lock +pkg/* diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..b85f28e --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source "http://rubygems.org" + +# Specify your gem's dependencies in veracode.gemspec +gemspec diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..2995527 --- /dev/null +++ b/Rakefile @@ -0,0 +1 @@ +require "bundler/gem_tasks" diff --git a/lib/veracode.rb b/lib/veracode.rb new file mode 100644 index 0000000..130217d --- /dev/null +++ b/lib/veracode.rb @@ -0,0 +1,10 @@ +require "veracode/version" +require "veracode/config" +require "veracode/base" +require "veracode/upload" +require "veracode/admin" +require "veracode/results" + +module Veracode + extend Veracode::Config +end \ No newline at end of file diff --git a/lib/veracode/admin.rb b/lib/veracode/admin.rb new file mode 100644 index 0000000..e9bcd26 --- /dev/null +++ b/lib/veracode/admin.rb @@ -0,0 +1,4 @@ +module Veracode + class Admin + end +end \ No newline at end of file diff --git a/lib/veracode/api/builds.rb b/lib/veracode/api/builds.rb new file mode 100644 index 0000000..87bf9be --- /dev/null +++ b/lib/veracode/api/builds.rb @@ -0,0 +1,56 @@ +require 'veracode/api/parse' + +module Veracode + module Result + module Builds + class Applications + include Veracode::Parser + attr_accessor :applications + + @applications + + def initialize + @applications = [] + end + + class Application + VALID_ATTRIBUTE_KEYS = [ :app_name, :app_id, :industry_vertical, :assurance_level, + :business_criticality, :origin, :cots, :business_unit, :tags ].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + + attr_accessor :builds + + def initialize(attributes) + @builds = [] + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + end + + class Build + VALID_ATTRIBUTE_KEYS = [ :version, :build_id, :submitter, :platform, :lifecycle_stage, :results_ready, :policy_name, + :policy_version, :policy_compliance_status, :rules_status, :grace_period_expired, + :scan_overdue ].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + attr_accessor :units + + def initialize(attributes) + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + @units = [] + end + + class AnalysisUnit + VALID_ATTRIBUTE_KEYS = [ :analysis_type, :status, :published_date ].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + + def initialize(attributes) + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + end + end + end + end + end + end + end +end diff --git a/lib/veracode/api/detailed.rb b/lib/veracode/api/detailed.rb new file mode 100644 index 0000000..9098904 --- /dev/null +++ b/lib/veracode/api/detailed.rb @@ -0,0 +1,83 @@ +require 'veracode/api/parse' + +module Veracode + module Result + class DetailedReport + include Veracode::Parser + + VALID_ATTRIBUTE_KEYS = [ :report_format_version, :app_name, :app_id, :first_build_submitted_date, :version, :build_id, + :submitter, :platform, :assurance_level, :business_criticality, :generation_date, :veracode_level, + :total_flaws, :flaws_not_mitigated, :teams, :life_cycle_stage, :planned_deployment_date, :last_update_time, + :is_latest_build, :policy_name, :policy_version, :policy_compliance_status, :policy_rules_status, + :scan_overdue, :any_type_scan_due, :business_owner, :business_unit, :tags, :grace_period_expired].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + + attr_accessor :analysis + + def initialize(attributes=nil) + if !attributes.nil? + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + end + @analysis = [] + end + + def assign(attributes=nil) + if !attributes.nil? + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + end + end + + class StaticAnalysis + VALID_ATTRIBUTE_KEYS = [ :rating, :score, :submitted_date, :published_date, :analysis_size_bytes].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + attr_accessor :modules + + def initialize(attributes) + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + @modules = [] + end + end + + class DynamicAnalysis + VALID_ATTRIBUTE_KEYS = [ :rating, :score, :submitted_date, :published_date, :analysis_size_bytes].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + attr_accessor :modules + + def initialize(attributes) + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + @modules = [] + end + end + + class ManualAnalysis + VALID_ATTRIBUTE_KEYS = [ :rating, :score, :submitted_date, :published_date, :analysis_size_bytes].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + attr_accessor :modules, :cia_adjustment + + def initialize(attributes) + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + @modules = [] + end + end + + class Modules + VALID_ATTRIBUTE_KEYS = [ :name, :compiler, :os, :architecture, :score, :numflawssev0, :numflawssev1, + :numflawssev2, :numflawssev3, :numflawssev4, :numflawssev5].freeze + + attr_accessor *VALID_ATTRIBUTE_KEYS + + def initialize(attributes) + VALID_ATTRIBUTE_KEYS.each{|k| self.send("#{k}=", Hash[attributes][k.to_s]) } + end + end + + class Severity + + end + end + end +end \ No newline at end of file diff --git a/lib/veracode/api/parse.rb b/lib/veracode/api/parse.rb new file mode 100644 index 0000000..aa28dba --- /dev/null +++ b/lib/veracode/api/parse.rb @@ -0,0 +1,87 @@ +module Veracode + module Parser + def parse(xml_text, on_error = nil, on_warning = nil) + sax_handler = Handler.new(self, on_error, on_warning) + parser = Nokogiri::XML::SAX::Parser.new(sax_handler) + parser.parse(xml_text) + self + end + end + + class Handler < Nokogiri::XML::SAX::Document + attr_reader :stack + + def initialize(object, on_error = nil, on_warning = nil) + @stack = [[object, nil, String.new]] + @parsed_configs = {} + @on_error = on_error + @on_warning = on_warning + end + + def characters(string) + object, config, value = stack.last + + value << string + end + + def cdata_block(string) + characters(string) + end + + def start_element name, attrs = [] + object, config, value = stack.last + + case name + when "application" + app = Veracode::Result::Builds::Applications::Application.new(attrs) + object.applications.push(app) + when "build" + build = Veracode::Result::Builds::Applications::Application::Build.new(attrs) + object.applications.last.builds.push(build) + when "analysis_unit" + analysis = Veracode::Result::Builds::Applications::Application::Build::AnalysisUnit.new(attrs) + object.applications.last.builds.last.units.push(analysis) + when "detailedreport" + object.assign(attrs) + when "static-analysis" + analysis = Veracode::Result::DetailedReport::StaticAnalysis.new(attrs) + object.analysis.push(analysis) + when "dynamic-analysis" + analysis = Veracode::Result::DetailedReport::DynamicAnalysis.new(attrs) + object.analysis.push(analysis) + when "manual-analysis" + analysis = Veracode::Result::DetailedReport::ManualAnalysis.new(attrs) + object.analysis.push(analysis) + when "cia_adjustment" + object.analysis.last.cia_adjustment = nil + when "module" + mod = Veracode::Result::DetailedReport::Modules.new(attrs) + object.analysis.last.modules.push(mod) + else + end + end + + def warning string + if @on_warning + @on_warning.call(string) + end + end + + def error string + if @on_error + @on_error.call(string) + end + end + + def end_element name + object, config, value = stack.last + + case name + when "screen" + when "cia_adjustment" + object.analysis.last.cia_adjustment = value.to_i + else + end + end +end +end \ No newline at end of file diff --git a/lib/veracode/base.rb b/lib/veracode/base.rb new file mode 100644 index 0000000..78b1711 --- /dev/null +++ b/lib/veracode/base.rb @@ -0,0 +1,28 @@ +require "net/http" +require "net/https" +require "uri" + +module Veracode + class Base + attr_accessor *Config::VALID_OPTIONS_KEYS + + def initialize(options={}) + attrs = Veracode.options.merge(options) + Config::VALID_OPTIONS_KEYS.each do |key| + send("#{key}=", options[key]) + end + end + + def getXML(path, username, password, debug=false) + url = URI.parse(path) + req = Net::HTTP::Get.new(url.request_uri) + req.basic_auth username, password + + site = Net::HTTP.new(url.host, url.port) + site.use_ssl = true + site.set_debug_output $stderr if debug + resp = site.start {|http| http.request(req) } + end + + end +end \ No newline at end of file diff --git a/lib/veracode/config.rb b/lib/veracode/config.rb new file mode 100644 index 0000000..2f027ea --- /dev/null +++ b/lib/veracode/config.rb @@ -0,0 +1,20 @@ +module Veracode + module Config + VALID_OPTIONS_KEYS = [ + :username, + :password].freeze + + attr_accessor *VALID_OPTIONS_KEYS + + def configure + yield self + end + + # Create a hash of options and their values + def options + options = {} + VALID_OPTIONS_KEYS.each{|k| options[k] = send(k) } + options + end + end +end \ No newline at end of file diff --git a/lib/veracode/results.rb b/lib/veracode/results.rb new file mode 100644 index 0000000..c307661 --- /dev/null +++ b/lib/veracode/results.rb @@ -0,0 +1,43 @@ +require 'nokogiri' +require 'veracode/api/builds' +require 'veracode/api/detailed' +require 'veracode/api/parse' +require 'rubygems' +require 'xmlsimple' + +require 'pp' + +module Veracode + class Results < Veracode::Base + GET_APP_BUILDS_URI = "https://analysiscenter.veracode.com/api/2.0/getappbuilds.do"; + DETAILED_REPORT_URI = "https://analysiscenter.veracode.com/api/2.0/detailedreport.do"; + DETAILED_REPORT_PDF_URI = "https://analysiscenter.veracode.com/api/2.0/detailedreportpdf.do"; + SUMMARY_REPORT_URI = "https://analysiscenter.veracode.com/api/2.0/summaryreport.do"; + SUMMARY_REPORT_PDF_URI = "https://analysiscenter.veracode.com/api/2.0/summaryreportpdf.do"; + THIRD_PARTY_REPORT_PDF_URI = "https://analysiscenter.veracode.com/api/2.0/thirdpartyreportpdf.do"; + + def get_application_builds + xml = getXML(GET_APP_BUILDS_URI, @username, @password) + if xml.is_a?(Net::HTTPSuccess) + parser = Veracode::Result::Builds::Applications.new + + builds = parser.parse(xml.body) + else + xml.error! + end + end + + def get_detailed_report(build_id) + xml = getXML(DETAILED_REPORT_URI + "?build_id=" + build_id, @username, @password) + if xml.is_a?(Net::HTTPSuccess) + parser = Veracode::Result::DetailedReport.new + + #puts xml.body + # XmlSimple.xml_in(xml.body) + report = parser.parse(xml.body) + else + xml.error! + end + end + end +end \ No newline at end of file diff --git a/lib/veracode/upload.rb b/lib/veracode/upload.rb new file mode 100644 index 0000000..74ed437 --- /dev/null +++ b/lib/veracode/upload.rb @@ -0,0 +1,4 @@ +module Veracode + class Upload + end +end \ No newline at end of file diff --git a/lib/veracode/version.rb b/lib/veracode/version.rb new file mode 100644 index 0000000..0ade6ac --- /dev/null +++ b/lib/veracode/version.rb @@ -0,0 +1,3 @@ +module Veracode + VERSION = "0.0.1" +end diff --git a/veracode.gemspec b/veracode.gemspec new file mode 100644 index 0000000..dbd3475 --- /dev/null +++ b/veracode.gemspec @@ -0,0 +1,24 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) +require "veracode/version" + +Gem::Specification.new do |s| + s.name = "veracode" + s.version = Veracode::VERSION + s.authors = ["Stephen Kapp"] + s.email = ["mort666@virus.org"] + s.homepage = "" + s.summary = %q{TODO: Write a gem summary} + s.description = %q{TODO: Write a gem description} + + s.rubyforge_project = "veracode" + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.require_paths = ["lib"] + + # specify any dependencies here; for example: + # s.add_development_dependency "rspec" + # s.add_runtime_dependency "rest-client" +end