From a5fc1fc89357b71b2e905bd6f2d99cb7accc1b08 Mon Sep 17 00:00:00 2001 From: lavender Date: Tue, 22 Apr 2014 20:25:38 -0500 Subject: [PATCH 01/10] porting to version omp v. 4 testing reports --- .gitignore | 4 + Gemfile | 9 +- LICENSE.txt | 4 + examples/basic-scan.rb | 27 +- examples/common.rb | 5 + examples/list_stuff.rb | 59 ++ lib/openvas-omp.rb | 1803 +++++++++++++++++++++------------------- 7 files changed, 1038 insertions(+), 873 deletions(-) create mode 100644 examples/common.rb create mode 100644 examples/list_stuff.rb diff --git a/.gitignore b/.gitignore index 2288186..c232a6e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,10 @@ doc # jeweler generated pkg +.idea +examples/reports + + # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore: # # * Create a file at ~/.gitignore diff --git a/Gemfile b/Gemfile index bdb0a5f..4f7c601 100644 --- a/Gemfile +++ b/Gemfile @@ -5,9 +5,10 @@ source "http://rubygems.org" # Add dependencies to develop your gem here. # Include everything needed to run rake, tests, features, etc. + group :development do - gem "shoulda", ">= 0" - gem "bundler", "~> 1.0.0" - gem "jeweler", "~> 1.5.2" - gem "rcov", ">= 0" + gem "shoulda" + gem "bundler" + gem "jeweler" + gem "simplecov" end diff --git a/LICENSE.txt b/LICENSE.txt index 7321331..c5b89df 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -18,3 +18,7 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The header says MIT, this is different than MIT... +investigate my options. I prefer MIT. \ No newline at end of file diff --git a/examples/basic-scan.rb b/examples/basic-scan.rb index 3b0d73d..c680a6b 100755 --- a/examples/basic-scan.rb +++ b/examples/basic-scan.rb @@ -1,14 +1,19 @@ #!/usr/bin/env ruby -# Basic example of openvas-omp usage -# in case you're using Ruby 1.8 and using gem, you should uncomment line below -# require 'rubygems' -require 'openvas-omp' +require_relative "./common" +require_relative '../lib/openvas-omp' + +ov = OpenVASOMP::OpenVASOMP.new("user"=>USER,"password"=>PASS,"host"=>URI,"debug"=>0) + +config = ov.config_get().index("Full and fast") +puts "Config: #{config}" + +target = ov.target_create({"name"=>"t", "hosts"=>"127.0.0.1", "comment"=>"t"}) +puts "Target: #{target}" + +taskid = ov.task_create({"name"=>"t","comment"=>"t", "target"=>target, "config"=>config}) +puts "Taskid: #{taskid}" -ov=OpenVASOMP::OpenVASOMP.new("user"=>'openvas',"password"=>'openvas') -config=ov.config_get().index("Full and fast") -target=ov.target_create({"name"=>"t", "hosts"=>"127.0.0.1", "comment"=>"t"}) -taskid=ov.task_create({"name"=>"t","comment"=>"t", "target"=>target, "config"=>config}) ov.task_start(taskid) while not ov.task_finished(taskid) do stat=ov.task_get_byid(taskid) @@ -16,6 +21,8 @@ sleep 10 end stat=ov.task_get_byid(taskid) -content=ov.report_get_byid(stat["lastreport"],'HTML') -File.open('report.html', 'w') {|f| f.write(content) } + +# this is broken in version 4 +# content=ov.report_get_byid(stat["lastreport"],'HTML') +# File.open('report.html', 'w') {|f| f.write(content) } diff --git a/examples/common.rb b/examples/common.rb new file mode 100644 index 0000000..c730f5b --- /dev/null +++ b/examples/common.rb @@ -0,0 +1,5 @@ +# store access info for testing + +USER = 'tester' +PASS = 'tester' +URI = '192.168.101.115' \ No newline at end of file diff --git a/examples/list_stuff.rb b/examples/list_stuff.rb new file mode 100644 index 0000000..ba27cc4 --- /dev/null +++ b/examples/list_stuff.rb @@ -0,0 +1,59 @@ +#!/usr/bin/env ruby + +require_relative "./common" +require_relative '../lib/openvas-omp' + +ov = OpenVASOMP::OpenVASOMP.new("user"=>USER,"password"=>PASS,"host"=>URI,"debug"=>0) + +puts "Openvas Version #{ov.version_get}" + +targets = ov.target_get_all +puts "\nTargets:" +targets.each { |k,v| puts "#{k} => #{v}"} + +tasks = ov.task_get_all +puts "\nTasks" +puts tasks + +configs = ov.config_get_all +puts "\nConfigs" +puts configs + + + +formats = ov.format_get_all +puts "\nFormats" +puts formats + +x = 'HTML' +puts "\nID for #{x} is #{ov.format_get_by_name(x)}" +x = 'NBE' +puts "\nID for #{x} is #{ov.format_get_by_name(x)}" + + +reports = ov.report_get_all +puts "\nReports" +puts reports + +x = (reports.first)['id'] + +content=ov.report_get_byid(x,'HTML') +File.open('reports/report.html', 'w') {|f| f.write(content) } + +content=ov.report_get_byid(x,'XML') +File.open('reports/report.xml', 'w') {|f| f.write(content) } + +content=ov.report_get_byid(x,'ARF') +File.open('reports/report_arf.xml', 'w') {|f| f.write(content) } + +content=ov.report_get_byid(x,'CPE') +File.open('reports/report_cpe.csv','w') {|f| f.write(content) } + +content=ov.report_get_byid(x,'NBE') +File.open('reports/report_nbe.txt','w') {|f| f.write(content) } + +content=ov.report_get_byid(x,'TXT') +File.open('reports/report_txt.txt','w') {|f| f.write(content) } + +content=ov.report_get_byid(x,'LaTeX') +File.open('reports/report.tex','w') {|f| f.write(content) } diff --git a/lib/openvas-omp.rb b/lib/openvas-omp.rb index 21e8bd1..c1cc79c 100644 --- a/lib/openvas-omp.rb +++ b/lib/openvas-omp.rb @@ -34,8 +34,12 @@ # stat=ov.task_get_byid(taskid) # content=ov.report_get_byid(stat["lastreport"],'HTML') # File.open('report.html', 'w') {|f| f.write(content) } +# +# +# Modified for version 4 per http://www.openvas.org/protocol-doc.html +# -require 'socket' +require 'socket' require 'timeout' require 'openssl' require 'rexml/document' @@ -52,864 +56,945 @@ module OpenVASOMP - class OMPError < :: RuntimeError - attr_accessor :req, :reason - def initialize(req, reason = '') - self.req = req - self.reason = reason - end - def to_s - "OpenVAS OMP: #{self.reason}" - end - end - - class OMPResponseError < OMPError - def initialize - self.reason = "Error in OMP request/response" - end - end - - class OMPAuthError < OMPError - def initialize - self.reason = "Authentication failed" - end - end - - class XMLParsingError < OMPError - def initialize - self.reason = "XML parsing failed" - end - end - - # Core class for OMP communication protocol - class OpenVASOMP - # initialize object: try to connect to OpenVAS using URL, user and password - # - # Usage: - # - # ov=OpenVASOMP.new(user=>'user',password=>'pass') - # # default: host=>'localhost', port=>'9390' - # - def initialize(p={}) - if p.has_key?("host") - @host=p["host"] - else - @host="localhost" - end - if p.has_key?("port") - @port=p["port"] - else - @port=9390 - end - if p.has_key?("user") - @user=p["user"] - else - @user="openvas" - end - if p.has_key?("password") - @password=p["password"] - else - @password="openvas" - end - if p.has_key?("bufsize") - @bufsize=p["bufsize"] - else - @bufsize=16384 - end - if p.has_key?("debug") - @debug=p["debug"] - else - @debug=0 - end - - if @debug>3 - puts "Host: "+@host - puts "Port: "+@port.to_s() - puts "User: "+@user - end - if @debug>99 - puts "Password: "+@password - end - @areq='' - @read_timeout=3 - if defined? p["noautoconnect"] and not p["noautoconnect"] - connect() - if defined? p["noautologin"] and not p["noautologin"] - login() - end - end - end - - # Sets debug level - # - # Usage: - # - # ov.debug(3) - # - def debug (level) - @debug=level - end - - # Low level method - Connect to SSL socket - # - # Usage: - # - # ov.connect() - # - def connect - @plain_socket=TCPSocket.open(@host, @port) - ssl_context = OpenSSL::SSL::SSLContext.new() - @socket = OpenSSL::SSL::SSLSocket.new(@plain_socket, ssl_context) - @socket.sync_close = true - @socket.connect - end - - # Low level method - Disconnect SSL socket - # - # Usage: - # - # ov.disconnect() - # - def disconnect - if @socket - @socket.close - end - end - - # Low level method: Send request and receive response - socket - # - # Usage: - # - # ov.connect(); - # puts ov.sendrecv("") - # ov.disconnect(); - # - def sendrecv (tosend) - if not @socket - connect - end - - if @debug>3 then - puts "SENDING: "+tosend - end - @socket.puts(tosend) - - @rbuf='' - size=0 - begin - begin - timeout(@read_timeout) { - a = @socket.sysread(@bufsize) - size=a.length - # puts "sysread #{size} bytes" - @rbuf << a - } - rescue Timeout::Error - size=0 - rescue EOFError - raise OMPResponseError - end - end while size>=@bufsize - response=@rbuf - - if @debug>3 then - puts "RECEIVED: "+response - end - return response - end - - # get OMP version (you don't need to be authenticated) - # - # Usage: - # - # ov.version_get() - # - def version_get - vreq="" - resp=sendrecv(vreq) - resp = ""+resp+"" - begin - docxml = REXML::Document.new(resp) - version='' - version=docxml.root.elements['get_version_response'].elements['version'].text - return version - rescue - raise XMLParsingError - end - end - - # produce single XML element with attributes specified as hash - # low-level function - # - # Usage: - # - # ov.xml_attr() - # - def xml_attr(name, opts={}) - xml = REXML::Element.new(name) - opts.keys.each do |k| - xml.attributes[k] = opts[k] - end - return xml - end - - # produce multiple XML elements with text specified as hash - # low-level function - # - # Usage: - # - # ov.xml_ele() - # - def xml_ele(name, child={}) - xml = REXML::Element.new(name) - child.keys.each do |k| - xml.add_element(k) - xml.elements[k].text = child[k] - end - return xml - end - - # produce multiple XML elements with text specified as hash - # also produce multiple XML elements with attributes - # low-level function - # - # Usage: - # - # ov.xml_mix() - # - def xml_mix(name, child, attr, elem) - xml = REXML::Element.new(name) - child.keys.each do |k| - xml.add_element(k) - xml.elements[k].text = child[k] - end - elem.keys.each do |k| - xml.add_element(k) - xml.elements[k].attributes[attr] = elem[k] - end - return xml - end - - # login to OpenVAS server. - # if successful returns authentication XML for further usage - # if unsuccessful returns empty string - # - # Usage: - # - # ov.login() - # - def login - areq=""+xml_ele("credentials", {"username"=>@user, "password"=>@password}).to_s()+"" - resp=sendrecv(areq+"") - # wrap it inside tags, so rexml does not complain - resp = ""+resp+"" - - begin - docxml = REXML::Document.new(resp) - status=docxml.root.elements['authenticate_response'].attributes['status'].to_i() - rescue - raise XMLParsingError - end - if status == 200 - @areq=areq - else - raise OMPAuthError - end - end - - # check if we're successful logged in - # if successful returns true - # if unsuccessful returns false - # - # Usage: - # - # if ov.logged_in() then - # puts "logged in" - # end - # - def logged_in - if @areq == '' - return false - else - return true - end - end - - # logout from OpenVAS server. - # it actually just sets internal authentication XML to empty str - # (as in OMP you have to send username/password each time) - # (i.e. there is no session id) - # - # Usage: - # - # ov.logout() - # - def logout - disconnect() - @areq = '' - end - - # OMP low level method - Send string request wrapped with - # authentication XML and return response as string - # - # Usage: - # - # ov.request_xml("" - - begin - docxml = REXML::Document.new(resp) - status=docxml.root.elements['authenticate_response'].attributes['status'].to_i - if status<200 and status>299 - raise OMPAuthError - end - return docxml.root - rescue - raise XMLParsingError - end - end - - # OMP - Create target for scanning - # - # Usage: - # - # target_id = ov.target_create("name"=>"localhost", - # "hosts"=>"127.0.0.1","comment"=>"yes") - # - def target_create (p={}) - xmlreq=xml_ele("create_target", p).to_s() - - begin - xr=omp_request_xml(xmlreq) - id=xr.elements['create_target_response'].attributes['id'] - rescue - raise OMPResponseError - end - return id - end - - # OMP - Delete target - # - # Usage: - # - # ov.target_delete(target_id) - # - def target_delete (id) - xmlreq=xml_attr("delete_target",{"target_id" => id}).to_s() - begin - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - # OMP - Get target for scanning and returns rexml object - # - # Usage: - # rexmlobject = target_get_raw("target_id"=>target_id) - # - def target_get_raw (p={}) - xmlreq=xml_attr("get_targets", p).to_s() - - begin - xr=omp_request_xml(xmlreq) - return xr - rescue - raise OMPResponseError - end - end - - # OMP - Get all targets for scanning and returns array of hashes - # with following keys: id,name,comment,hosts,max_hosts,in_use - # - # Usage: - # array_of_hashes = target_get_all() - # - def target_get_all (p={}) - begin - xr=target_get_raw(p) - list=Array.new - xr.elements.each('//get_targets_response/target') do |target| - td=Hash.new - td["id"]=target.attributes["id"] - td["name"]=target.elements["name"].text - td["comment"]=target.elements["comment"].text - td["hosts"]=target.elements["hosts"].text - td["max_hosts"]=target.elements["max_hosts"].text - td["in_use"]=target.elements["in_use"].text - list.push td - end - return list - rescue - raise OMPResponseError - end - end - - def target_get_byid (id) - begin - xr=target_get_raw("target_id"=>id) - xr.elements.each('//get_targets_response/target') do |target| - td=Hash.new - td["id"]=target.attributes["id"] - td["name"]=target.elements["name"].text - td["comment"]=target.elements["comment"].text - td["hosts"]=target.elements["hosts"].text - td["max_hosts"]=target.elements["max_hosts"].text - td["in_use"]=target.elements["in_use"].text - return td - end - return list - rescue - raise OMPResponseError - end - end - - # OMP - get reports and returns raw rexml object as response - # - # Usage: - # - # rexmlobject=ov.report_get_raw("format"=>"PDF") - # - # rexmlobject=ov.report_get_raw( - # "report_id" => "", - # "format"=>"PDF") - # - def report_get_raw (p={}) - xmlreq=xml_attr("get_reports",p).to_s() - begin - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - # OMP - get report by id and format, returns report - # (already base64 decoded if needed) - # - # format can be: HTML, NBE, PDF, ... - # - # Usage: - # - # pdf_content=ov.report_get_byid(id,"PDF") - # File.open('report.pdf', 'w') {|f| f.write(pdf_content) } - # - def report_get_byid (id,format) - decode=Array["HTML","NBE","PDF"] - xr=report_get_raw("report_id"=>id,"format"=>format) - resp=xr.elements['get_reports_response'].elements['report'].text - if decode.include?(format) - resp=Base64.decode64(resp) - end - return resp - end - - # OMP - get report all, returns report - # - # Usage: - # - # pdf_content=ov.report_get_all() - # - def report_get_all () - begin - xr=report_get_raw("format"=>"NBE") - list=Array.new - xr.elements.each('//get_reports_response/report') do |report| - td=Hash.new - td["id"]=target.attributes["id"] - td["name"]=target.elements["name"].text - td["comment"]=target.elements["comment"].text - td["hosts"]=target.elements["hosts"].text - td["max_hosts"]=target.elements["max_hosts"].text - td["in_use"]=target.elements["in_use"].text - list.push td - end - return list - rescue - raise OMPResponseError - end - end - - # OMP - get reports and returns raw rexml object as response - # - # Usage: - # - # rexmlobject=ov.result_get_raw("notes"=>0) - # - def result_get_raw (p={}) - begin - xmlreq=xml_attr("get_results",p).to_s() - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - # OMP - get configs and returns rexml object as response - # - # Usage: - # - # rexmldocument=ov.config_get_raw() - # - def config_get_raw (p={}) - xmlreq=xml_attr("get_configs",p).to_s() - begin - xr=omp_request_xml(xmlreq) - return xr - rescue - raise OMPResponseError - end - return false - end - - # OMP - get configs and returns hash as response - # hash[config_id]=config_name - # - # Usage: - # - # array_of_hashes=ov.config_get_all() - # - def config_get_all (p={}) - begin - xr=config_get_raw(p) - tc=Array.new - xr.elements.each('//get_configs_response/config') do |config| - c=Hash.new - c["id"]=config.attributes["id"] - c["name"]=config.elements["name"].text - c["comment"]=config.elements["comment"].text - tc.push c - end - return tc - rescue - raise OMPResponseError - end - return false - end - - # OMP - get configs and returns hash as response - # hash[config_id]=config_name - # - # Usage: - # - # all_configs_hash=ov.config.get() - # - # config_id=ov.config_get().index("Full and fast") - # - def config_get (p={}) - begin - xr=config_get_raw(p) - list=Hash.new - xr.elements.each('//get_configs_response/config') do |config| - id=config.attributes["id"] - name=config.elements["name"].text - list[id]=name - end - return list - rescue - raise OMPResponseError - end - return false - end - - # OMP - copy config with new name and returns new id - # - # Usage: - # - # new_config_id=config_copy(config_id,"new_name"); - # - def config_copy (config_id,name) - xmlreq=xml_attr("create_config", - {"copy"=>config_id,"name"=>name}).to_s() - begin - xr=omp_request_xml(xmlreq) - id=xr.elements['create_config_response'].attributes['id'] - return id - rescue - raise OMPResponseError - end - end - - # OMP - create config with specified RC file and returns new id - # name = name of new config - # rcfile = base64 encoded OpenVAS rcfile - # - # Usage: - # - # config_id=config_create("name",rcfile); - # - def config_create (name,rcfile) - xmlreq=xml_attr("create_config", - {"name"=>name,"rcfile"=>rcfile}).to_s() - begin - xr=omp_request_xml(xmlreq) - id=xr.elements['create_config_response'].attributes['id'] - return id - rescue - raise OMPResponseError - end - end - - # OMP - creates task and returns id of created task - # - # Parameters which usually fit in p hash and i hash: - # p = name,comment,rcfile - # i = config,target,escalator,schedule - # - # Usage: - # - # task_id=ov.task_create_raw() - # - def task_create_raw (p={}, i={}) - xmlreq=xml_mix("create_task",p,"id",i).to_s() - begin - xr=omp_request_xml(xmlreq) - id=xr.elements['create_task_response'].attributes['id'] - return id - rescue - raise OMPResponseError - end - end - - # OMP - creates task and returns id of created task - # - # parameters = name,comment,rcfile,config,target,escalator, - # schedule - # - # Usage: - # - # config_id=o.config_get().index("Full and fast") - # target_id=o.target_create( - # {"name"=>"localtarget", "hosts"=>"127.0.0.1", "comment"=>"t"}) - # task_id=ov.task_create( - # {"name"=>"testlocal","comment"=>"test", "target"=>target_id, - # "config"=>config_id} - # - def task_create (p={}) - specials=Array["config","target","escalator","schedule"] - ids = Hash.new - specials.each do |spec| - if p.has_key?(spec) - ids[spec]=p[spec] - p.delete(spec) - end - end - return task_create_raw(p,ids) - end - - # OMP - deletes task specified by task_id - # - # Usage: - # - # ov.task_delete(task_id) - # - def task_delete (task_id) - xmlreq=xml_attr("delete_task",{"task_id" => task_id}).to_s() - begin - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - # OMP - get task and returns raw rexml object as response - # - # Usage: - # - # rexmlobject=ov.task_get_raw("details"=>"0") - # - def task_get_raw (p={}) - xmlreq=xml_attr("get_tasks",p).to_s() - begin - xr=omp_request_xml(xmlreq) - return xr - rescue - raise OMPResponseError - end - end - - # OMP - get all tasks and returns array with hashes with - # following content: - # id,name,comment,status,progress,first_report,last_report - # - # Usage: - # - # array_of_hashes=ov.task_get_all() - # - def task_get_all (p={}) - xr=task_get_raw(p) - t=Array.new - xr.elements.each('//get_tasks_response/task') do |task| - td=Hash.new - td["id"]=task.attributes["id"] - td["name"]=task.elements["name"].text - td["comment"]=task.elements["comment"].text - td["status"]=task.elements["status"].text - td["progress"]=task.elements["progress"].text - if defined? task.elements["first_report"].elements["report"].attributes["id"] then - td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"] - else - td["firstreport"]=nil - end - if defined? task.elements["last_report"].elements["report"].attributes["id"] then - td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"] - else - td["lastreport"]=nil - end - t.push td - end - return t - end - - # OMP - get task specified by task_id and returns hash with - # following content: - # id,name,comment,status,progress,first_report,last_report - # - # Usage: - # - # hash=ov.task_get_byid(task_id) - # - def task_get_byid (id) - xr=task_get_raw("task_id"=>id,"details"=>0) - xr.elements.each('//get_tasks_response/task') do |task| - td=Hash.new - td["id"]=task.attributes["id"] - td["name"]=task.elements["name"].text - td["comment"]=task.elements["comment"].text - td["status"]=task.elements["status"].text - td["progress"]=task.elements["progress"].text - if defined? task.elements["first_report"].elements["report"].attributes["id"] then - td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"] - else - td["firstreport"]=nil - end - if defined? task.elements["last_report"].elements["report"].attributes["id"] then - td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"] - else - td["lastreport"]=nil - end - return (td) - end - end - - # OMP - check if task specified by task_id is finished - # (it checks if task status is "Done" in OMP) - # - # Usage: - # - # if ov.task_finished(task_id) - # puts "Task finished" - # end - # - def task_finished (id) - xr=task_get_raw("task_id"=>id,"details"=>0) - xr.elements.each('//get_tasks_response/task') do |task| - if status=task.elements["status"].text == "Done" - return true - else - return false - end - end - end - - # OMP - check progress of task specified by task_id - # (OMP returns -1 if task is finished, not started, etc) - # - # Usage: - # - # print "Progress: " - # puts ov.task_progress(task_id) - # - def task_progress (id) - xr=task_get_raw("task_id"=>id,"details"=>0) - xr.elements.each('//get_tasks_response/task') do |task| - return task.elements["progress"].text.to_i() - end - end - - # OMP - starts task specified by task_id - # - # Usage: - # - # ov.task_start(task_id) - # - def task_start (task_id) - xmlreq=xml_attr("start_task",{"task_id" => task_id}).to_s() - begin - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - # OMP - stops task specified by task_id - # - # Usage: - # - # ov.task_stop(task_id) - # - def task_stop (task_id) - xmlreq=xml_attr("stop_task",{"task_id" => task_id}).to_s() - begin - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - # OMP - pauses task specified by task_id - # - # Usage: - # - # ov.task_pause(task_id) - # - def task_pause (task_id) - xmlreq=xml_attr("pause_task",{"task_id" => task_id}).to_s() - begin - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - # OMP - resumes (or starts) task specified by task_id - # - # Usage: - # - # ov.task_resume_or_start(task_id) - # - def task_resume_or_start (task_id) - xmlreq=xml_attr("resume_or_start_task",{"task_id" => task_id}).to_s() - begin - xr=omp_request_xml(xmlreq) - rescue - raise OMPResponseError - end - return xr - end - - end # end of Class + class OMPError < :: RuntimeError + attr_accessor :req, :reason + + def initialize(req, reason = '') + self.req = req + self.reason = reason + end + + def to_s + "OpenVAS OMP: #{self.reason}" + end + end + + class OMPResponseError < OMPError + def initialize + self.reason = "Error in OMP request/response" + end + end + + class OMPAuthError < OMPError + def initialize + self.reason = "Authentication failed" + end + end + + class XMLParsingError < OMPError + def initialize + self.reason = "XML parsing failed" + end + end + + # Core class for OMP communication protocol + class OpenVASOMP + # initialize object: try to connect to OpenVAS using URL, user and password + # + # Usage: + # + # ov=OpenVASOMP.new(user=>'user',password=>'pass') + # # default: host=>'localhost', port=>'9390' + # + def initialize(p={}) + if p.has_key?("host") + @host=p["host"] + else + @host="localhost" + end + if p.has_key?("port") + @port=p["port"] + else + @port=9390 + end + if p.has_key?("user") + @user=p["user"] + else + @user="openvas" + end + if p.has_key?("password") + @password=p["password"] + else + @password="openvas" + end + if p.has_key?("bufsize") + @bufsize=p["bufsize"] + else + @bufsize=16384 + end + if p.has_key?("debug") + @debug=p["debug"] + else + @debug=0 + end + + if @debug>3 + puts "Host: "+@host + puts "Port: "+@port.to_s() + puts "User: "+@user + end + if @debug>99 + puts "Password: "+@password + end + @areq='' + @read_timeout=3 + if defined? p["noautoconnect"] and not p["noautoconnect"] + connect() + if defined? p["noautologin"] and not p["noautologin"] + login() + end + end + end + + # Sets debug level + # + # Usage: + # + # ov.debug(3) + # + def debug (level) + @debug=level + end + + # Low level method - Connect to SSL socket + # + # Usage: + # + # ov.connect() + # + def connect + @plain_socket=TCPSocket.open(@host, @port) + ssl_context = OpenSSL::SSL::SSLContext.new() + @socket = OpenSSL::SSL::SSLSocket.new(@plain_socket, ssl_context) + @socket.sync_close = true + @socket.connect + end + + # Low level method - Disconnect SSL socket + # + # Usage: + # + # ov.disconnect() + # + def disconnect + if @socket + @socket.close + end + end + + # Low level method: Send request and receive response - socket + # + # Usage: + # + # ov.connect(); + # puts ov.sendrecv("") + # ov.disconnect(); + # + def sendrecv (tosend) + if not @socket + connect + end + + if @debug>3 then + puts "SENDING: "+tosend + end + @socket.puts(tosend) + + @rbuf='' + size=0 + begin + begin + timeout(@read_timeout) { + a = @socket.sysread(@bufsize) + size=a.length + # puts "sysread #{size} bytes" + @rbuf << a + } + rescue Timeout::Error + size=0 + rescue EOFError + raise OMPResponseError + end + end while size>=@bufsize + response=@rbuf + + if @debug>3 then + puts "RECEIVED: "+response + end + return response + end + + # get OMP version (you don't need to be authenticated) + # + # Usage: + # + # ov.version_get() + # + def version_get + vreq="" + resp=sendrecv(vreq) + resp = ""+resp+"" + begin + docxml = REXML::Document.new(resp) + version='' + version=docxml.root.elements['get_version_response'].elements['version'].text + return version + rescue + raise XMLParsingError + end + end + + # produce single XML element with attributes specified as hash + # low-level function + # + # Usage: + # + # ov.xml_attr() + # + def xml_attr(name, opts={}) + xml = REXML::Element.new(name) + opts.keys.each do |k| + xml.attributes[k] = opts[k] + end + return xml + end + + # produce multiple XML elements with text specified as hash + # low-level function + # + # Usage: + # + # ov.xml_ele() + # + def xml_ele(name, child={}) + xml = REXML::Element.new(name) + child.keys.each do |k| + xml.add_element(k) + xml.elements[k].text = child[k] + end + return xml + end + + # produce multiple XML elements with text specified as hash + # also produce multiple XML elements with attributes + # low-level function + # + # Usage: + # + # ov.xml_mix() + # + def xml_mix(name, child, attr, elem) + xml = REXML::Element.new(name) + child.keys.each do |k| + xml.add_element(k) + xml.elements[k].text = child[k] + end + elem.keys.each do |k| + xml.add_element(k) + xml.elements[k].attributes[attr] = elem[k] + end + return xml + end + + # login to OpenVAS server. + # if successful returns authentication XML for further usage + # if unsuccessful returns empty string + # + # Usage: + # + # ov.login() + # + def login + areq=""+xml_ele("credentials", {"username" => @user, "password" => @password}).to_s()+"" + resp=sendrecv(areq+"") + # wrap it inside tags, so rexml does not complain + resp = ""+resp+"" + + begin + docxml = REXML::Document.new(resp) + status=docxml.root.elements['authenticate_response'].attributes['status'].to_i() + rescue + raise XMLParsingError + end + if status == 200 + @areq=areq + else + raise OMPAuthError + end + end + + # check if we're successful logged in + # if successful returns true + # if unsuccessful returns false + # + # Usage: + # + # if ov.logged_in() then + # puts "logged in" + # end + # + def logged_in + if @areq == '' + return false + else + return true + end + end + + # logout from OpenVAS server. + # it actually just sets internal authentication XML to empty str + # (as in OMP you have to send username/password each time) + # (i.e. there is no session id) + # + # Usage: + # + # ov.logout() + # + def logout + disconnect + @areq = '' + end + + # OMP low level method - Send string request wrapped with + # authentication XML and return response as string + # + # Usage: + # + # ov.request_xml("" + + begin + docxml = REXML::Document.new(resp) + status=docxml.root.elements['authenticate_response'].attributes['status'].to_i + if status<200 and status>299 + raise OMPAuthError + end + return docxml.root + rescue + raise XMLParsingError + end + end + + # OMP - Create target for scanning + # + # Usage: + # + # target_id = ov.target_create("name"=>"localhost", + # "hosts"=>"127.0.0.1","comment"=>"yes") + # + def target_create (p={}) + xmlreq=xml_ele("create_target", p).to_s() + + begin + xr=omp_request_xml(xmlreq) + id=xr.elements['create_target_response'].attributes['id'] + rescue + raise OMPResponseError + end + return id + end + + # OMP - Delete target + # + # Usage: + # + # ov.target_delete(target_id) + # + def target_delete (id) + xmlreq=xml_attr("delete_target", {"target_id" => id}).to_s() + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + # OMP - Get target for scanning and returns rexml object + # + # Usage: + # rexmlobject = target_get_raw("target_id"=>target_id) + # + def target_get_raw (p={}) + xmlreq=xml_attr("get_targets", p).to_s() + + begin + xr=omp_request_xml(xmlreq) + return xr + rescue + raise OMPResponseError + end + end + + # OMP - Get all targets for scanning and returns array of hashes + # with following keys: id,name,comment,hosts,max_hosts,in_use + # + # Usage: + # array_of_hashes = target_get_all() + # + def target_get_all (p={}) + begin + xr=target_get_raw(p) + list=Array.new + xr.elements.each('//get_targets_response/target') do |target| + td=Hash.new + td["id"]=target.attributes["id"] + td["name"]=target.elements["name"].text + td["comment"]=target.elements["comment"].text + td["hosts"]=target.elements["hosts"].text + td["max_hosts"]=target.elements["max_hosts"].text + td["in_use"]=target.elements["in_use"].text + list.push td + end + return list + rescue + raise OMPResponseError + end + end + + def target_get_byid (id) + begin + xr=target_get_raw("target_id" => id) + xr.elements.each('//get_targets_response/target') do |target| + td=Hash.new + td["id"]=target.attributes["id"] + td["name"]=target.elements["name"].text + td["comment"]=target.elements["comment"].text + td["hosts"]=target.elements["hosts"].text + td["max_hosts"]=target.elements["max_hosts"].text + td["in_use"]=target.elements["in_use"].text + return td + end + return list + rescue + raise OMPResponseError + end + end + + # OMP - get reports and returns raw rexml object as response + # + # Usage: + # + # rexmlobject=ov.report_get_raw("format"=>"PDF") + # + # rexmlobject=ov.report_get_raw( + # "report_id" => "", + # "format"=>"PDF") + # + def report_get_raw (p={}) + xmlreq=xml_attr("get_reports", p).to_s() + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + # OMP - get report by id and format, returns report + # (already base64 decoded if needed) + # + # format can be: HTML, NBE, PDF, ... + # + # Usage: + # + # pdf_content=ov.report_get_byid(id,"PDF") + # File.open('report.pdf', 'w') {|f| f.write(pdf_content) } + # + def report_get_byid (id, format) + format_id = format_get_by_name(format) + decode=Array['HTML', 'NBE', 'PDF', 'ARF', 'TXT', 'LaTeX'] + xr=report_get_raw('report_id' => id, 'format_id' => format_id) + + if decode.include?(format) + resp=xr.elements['//get_reports_response/report'].text + else + # puts xr + resp=xr.elements['//get_reports_response/report'].to_s + # puts resp + end + + if decode.include?(format) + resp=Base64.decode64(resp) + end + resp + end + + # OMP - get report all, returns report + # + # Usage: + # + # pdf_content=ov.report_get_all() + # + def report_get_all () + format_id = format_get_by_name('XML') + begin + xr=report_get_raw('format_id' => format_id) + rescue + raise OMPResponseError + end + + list=Array.new + xr.elements.each('//get_reports_response/report') do |target| + # puts target + td=Hash.new + td['id']=target.attributes['id'] + # td["name"]=target.elements["name"].text + # td["comment"]=target.elements["comment"].text + # td["hosts"]=target.elements["hosts"].text + # td["max_hosts"]=target.elements["max_hosts"].text + # td["in_use"]=target.elements["in_use"].text + list.push td + end + list + end + + # OMP - get reports and returns raw rexml object as response + # + # Usage: + # + # rexmlobject=ov.result_get_raw("notes"=>0) + # + def result_get_raw (p={}) + begin + xmlreq=xml_attr("get_results", p).to_s() + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + # OMP - get configs and returns rexml object as response + # + # Usage: + # + # rexmldocument=ov.config_get_raw() + # + def config_get_raw (p={}) + xmlreq=xml_attr("get_configs", p).to_s() + begin + xr=omp_request_xml(xmlreq) + return xr + rescue + raise OMPResponseError + end + return false + end + + # OMP - get configs and returns hash as response + # hash[config_id]=config_name + # + # Usage: + # + # array_of_hashes=ov.config_get_all() + # + def config_get_all (p={}) + begin + xr=config_get_raw(p) + tc=Array.new + xr.elements.each('//get_configs_response/config') do |config| + c=Hash.new + c["id"]=config.attributes["id"] + c["name"]=config.elements["name"].text + c["comment"]=config.elements["comment"].text + tc.push c + end + return tc + rescue + raise OMPResponseError + end + return false + end + + # OMP - get configs and returns hash as response + # hash[config_id]=config_name + # + # Usage: + # + # all_configs_hash=ov.config.get() + # + # config_id=ov.config_get().index("Full and fast") + # + def config_get (p={}) + begin + xr=config_get_raw(p) + list=Hash.new + xr.elements.each('//get_configs_response/config') do |config| + id=config.attributes["id"] + name=config.elements["name"].text + list[id]=name + end + return list + rescue + raise OMPResponseError + end + return false + end + + # OMP - copy config with new name and returns new id + # + # Usage: + # + # new_config_id=config_copy(config_id,"new_name"); + # + def config_copy (config_id, name) + xmlreq=xml_attr("create_config", + {"copy" => config_id, "name" => name}).to_s() + begin + xr=omp_request_xml(xmlreq) + id=xr.elements['create_config_response'].attributes['id'] + return id + rescue + raise OMPResponseError + end + end + + # OMP - create config with specified RC file and returns new id + # name = name of new config + # rcfile = base64 encoded OpenVAS rcfile + # + # Usage: + # + # config_id=config_create("name",rcfile); + # + def config_create (name, rcfile) + xmlreq=xml_attr("create_config", + {'name' => name, 'rcfile' => rcfile}).to_s() + begin + xr=omp_request_xml(xmlreq) + id=xr.elements['create_config_response'].attributes['id'] + return id + rescue + raise OMPResponseError + end + end + + + # OMP - get formats and returns raw rexml object as response + # Added for version 4 + # + # Usage: + # + # rexmlobject=ov.format_get_raw() + # + # + def format_get_raw (p={}) + xmlreq=xml_attr('get_report_formats', p).to_s + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + xr + end + + + # OMP - get report all, returns formats + # added for version 4 + # + # Usage: + # + # pdf_content=ov.format_get_all() + # + def format_get_all () + begin + xr=format_get_raw + list=Array.new + xr.elements.each('//get_report_formats_response/report_format') do |target| + td=Hash.new + td['id']=target.attributes['id'] + td['name']=target.elements['name'].text + td['extension']=target.elements['extension'].text + td['content_type']=target.elements['content_type'].text + td['summary']=target.elements['summary'].text + list.push td + end + list + rescue + raise OMPResponseError + end + end + + + # OMP - get report all, returns formats + # added for version 4 + # + # Usage: + # + # pdf_content=ov.format_get_all() + # + def format_get_by_name (name) + begin + x = format_get_all + x.each { |f| + return f['id'] if f['name'] == name + } + nil + rescue + raise OMPResponseError + end + end + + + # OMP - creates task and returns id of created task + # + # Parameters which usually fit in p hash and i hash: + # p = name,comment,rcfile + # i = config,target,escalator,schedule + # + # Usage: + # + # task_id=ov.task_create_raw() + # + def task_create_raw (p={}, i={}) + xmlreq=xml_mix("create_task", p, "id", i).to_s() + begin + xr=omp_request_xml(xmlreq) + id=xr.elements['create_task_response'].attributes['id'] + return id + rescue + raise OMPResponseError + end + end + + # OMP - creates task and returns id of created task + # + # parameters = name,comment,rcfile,config,target,escalator, + # schedule + # + # Usage: + # + # config_id=o.config_get().index("Full and fast") + # target_id=o.target_create( + # {"name"=>"localtarget", "hosts"=>"127.0.0.1", "comment"=>"t"}) + # task_id=ov.task_create( + # {"name"=>"testlocal","comment"=>"test", "target"=>target_id, + # "config"=>config_id} + # + def task_create (p={}) + specials=Array["config", "target", "escalator", "schedule"] + ids = Hash.new + specials.each do |spec| + if p.has_key?(spec) + ids[spec]=p[spec] + p.delete(spec) + end + end + return task_create_raw(p, ids) + end + + # OMP - deletes task specified by task_id + # + # Usage: + # + # ov.task_delete(task_id) + # + def task_delete (task_id) + xmlreq=xml_attr("delete_task", {"task_id" => task_id}).to_s() + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + # OMP - get task and returns raw rexml object as response + # + # Usage: + # + # rexmlobject=ov.task_get_raw("details"=>"0") + # + def task_get_raw (p={}) + xmlreq=xml_attr("get_tasks", p).to_s() + begin + xr=omp_request_xml(xmlreq) + return xr + rescue + raise OMPResponseError + end + end + + # OMP - get all tasks and returns array with hashes with + # following content: + # id,name,comment,status,progress,first_report,last_report + # + # Usage: + # + # array_of_hashes=ov.task_get_all() + # + def task_get_all (p={}) + xr=task_get_raw(p) + t=Array.new + xr.elements.each('//get_tasks_response/task') do |task| + td=Hash.new + td["id"]=task.attributes["id"] + td["name"]=task.elements["name"].text + td["comment"]=task.elements["comment"].text + td["status"]=task.elements["status"].text + td["progress"]=task.elements["progress"].text + if defined? task.elements["first_report"].elements["report"].attributes["id"] then + td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"] + else + td["firstreport"]=nil + end + if defined? task.elements["last_report"].elements["report"].attributes["id"] then + td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"] + else + td["lastreport"]=nil + end + t.push td + end + return t + end + + # OMP - get task specified by task_id and returns hash with + # following content: + # id,name,comment,status,progress,first_report,last_report + # + # Usage: + # + # hash=ov.task_get_byid(task_id) + # + def task_get_byid (id) + xr=task_get_raw("task_id" => id, "details" => 0) + xr.elements.each('//get_tasks_response/task') do |task| + td=Hash.new + td["id"]=task.attributes["id"] + td["name"]=task.elements["name"].text + td["comment"]=task.elements["comment"].text + td["status"]=task.elements["status"].text + td["progress"]=task.elements["progress"].text + if defined? task.elements["first_report"].elements["report"].attributes["id"] then + td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"] + else + td["firstreport"]=nil + end + if defined? task.elements["last_report"].elements["report"].attributes["id"] then + td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"] + else + td["lastreport"]=nil + end + return (td) + end + end + + # OMP - check if task specified by task_id is finished + # (it checks if task status is "Done" in OMP) + # + # Usage: + # + # if ov.task_finished(task_id) + # puts "Task finished" + # end + # + def task_finished (id) + xr=task_get_raw("task_id" => id, "details" => 0) + xr.elements.each('//get_tasks_response/task') do |task| + if status=task.elements["status"].text == "Done" + return true + else + return false + end + end + end + + # OMP - check progress of task specified by task_id + # (OMP returns -1 if task is finished, not started, etc) + # + # Usage: + # + # print "Progress: " + # puts ov.task_progress(task_id) + # + def task_progress (id) + xr=task_get_raw("task_id" => id, "details" => 0) + xr.elements.each('//get_tasks_response/task') do |task| + return task.elements["progress"].text.to_i() + end + end + + # OMP - starts task specified by task_id + # + # Usage: + # + # ov.task_start(task_id) + # + def task_start (task_id) + xmlreq=xml_attr("start_task", {"task_id" => task_id}).to_s() + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + # OMP - stops task specified by task_id + # + # Usage: + # + # ov.task_stop(task_id) + # + def task_stop (task_id) + xmlreq=xml_attr("stop_task", {"task_id" => task_id}).to_s() + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + # OMP - pauses task specified by task_id + # + # Usage: + # + # ov.task_pause(task_id) + # + def task_pause (task_id) + xmlreq=xml_attr("pause_task", {"task_id" => task_id}).to_s() + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + # OMP - resumes (or starts) task specified by task_id + # + # Usage: + # + # ov.task_resume_or_start(task_id) + # + def task_resume_or_start (task_id) + xmlreq=xml_attr("resume_or_start_task", {"task_id" => task_id}).to_s() + begin + xr=omp_request_xml(xmlreq) + rescue + raise OMPResponseError + end + return xr + end + + end # end of Class end # of Module From ea6791abc9d98ae96f2049796ebcc5291e5d2710 Mon Sep 17 00:00:00 2001 From: lavender Date: Tue, 22 Apr 2014 20:26:13 -0500 Subject: [PATCH 02/10] porting to version omp v. 4 testing reports --- .idea/.rakeTasks | 7 +++ .idea/encodings.xml | 5 ++ .idea/misc.xml | 5 ++ .idea/modules.xml | 9 +++ .idea/openvas-omp-ruby.iml | 100 ++++++++++++++++++++++++++++++++ .idea/scopes/scope_settings.xml | 5 ++ .idea/vcs.xml | 7 +++ Gemfile.lock | 80 +++++++++++++++++++++++++ 8 files changed, 218 insertions(+) create mode 100644 .idea/.rakeTasks create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/openvas-omp-ruby.iml create mode 100644 .idea/scopes/scope_settings.xml create mode 100644 .idea/vcs.xml create mode 100644 Gemfile.lock diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks new file mode 100644 index 0000000..c6865d9 --- /dev/null +++ b/.idea/.rakeTasks @@ -0,0 +1,7 @@ + + diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..e206d70 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5f9fe42 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..af4521e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.idea/openvas-omp-ruby.iml b/.idea/openvas-omp-ruby.iml new file mode 100644 index 0000000..c2cf9e1 --- /dev/null +++ b/.idea/openvas-omp-ruby.iml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..c80f219 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..c49e1bd --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,80 @@ +GEM + remote: http://rubygems.org/ + specs: + activesupport (4.1.0) + i18n (~> 0.6, >= 0.6.9) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.1) + tzinfo (~> 1.1) + addressable (2.3.6) + builder (3.2.2) + descendants_tracker (0.0.4) + thread_safe (~> 0.3, >= 0.3.1) + docile (1.1.3) + faraday (0.9.0) + multipart-post (>= 1.2, < 3) + git (1.2.6) + github_api (0.11.3) + addressable (~> 2.3) + descendants_tracker (~> 0.0.1) + faraday (~> 0.8, < 0.10) + hashie (>= 1.2) + multi_json (>= 1.7.5, < 2.0) + nokogiri (~> 1.6.0) + oauth2 + hashie (2.1.1) + highline (1.6.21) + i18n (0.6.9) + jeweler (2.0.1) + builder + bundler (>= 1.0) + git (>= 1.2.5) + github_api + highline (>= 1.6.15) + nokogiri (>= 1.5.10) + rake + rdoc + json (1.8.1) + jwt (0.1.11) + multi_json (>= 1.5) + mini_portile (0.5.3) + minitest (5.3.3) + multi_json (1.9.2) + multi_xml (0.5.5) + multipart-post (2.0.0) + nokogiri (1.6.1) + mini_portile (~> 0.5.0) + oauth2 (0.9.3) + faraday (>= 0.8, < 0.10) + jwt (~> 0.1.8) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (~> 1.2) + rack (1.5.2) + rake (10.3.1) + rdoc (4.1.1) + json (~> 1.4) + shoulda (3.5.0) + shoulda-context (~> 1.0, >= 1.0.1) + shoulda-matchers (>= 1.4.1, < 3.0) + shoulda-context (1.2.1) + shoulda-matchers (2.6.0) + activesupport (>= 3.0.0) + simplecov (0.8.2) + docile (~> 1.1.0) + multi_json + simplecov-html (~> 0.8.0) + simplecov-html (0.8.0) + thread_safe (0.3.3) + tzinfo (1.1.0) + thread_safe (~> 0.1) + +PLATFORMS + ruby + +DEPENDENCIES + bundler + jeweler + shoulda + simplecov From 03b83cbc57df95b8f1fffd2aafa140448fca2a5b Mon Sep 17 00:00:00 2001 From: lavender Date: Tue, 22 Apr 2014 20:30:19 -0500 Subject: [PATCH 03/10] porting to version omp v. 4 testing reports --- examples/list_stuff.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/list_stuff.rb b/examples/list_stuff.rb index ba27cc4..603770f 100644 --- a/examples/list_stuff.rb +++ b/examples/list_stuff.rb @@ -1,5 +1,7 @@ #!/usr/bin/env ruby +# added by jkl to test access + require_relative "./common" require_relative '../lib/openvas-omp' From 46364f907e572c6620186e4dd5f75b1a8e8d66cb Mon Sep 17 00:00:00 2001 From: lavender Date: Tue, 22 Apr 2014 20:34:31 -0500 Subject: [PATCH 04/10] removing ide files --- .idea/.rakeTasks | 7 --- .idea/encodings.xml | 5 -- .idea/misc.xml | 5 -- .idea/modules.xml | 9 --- .idea/openvas-omp-ruby.iml | 100 -------------------------------- .idea/scopes/scope_settings.xml | 5 -- .idea/vcs.xml | 7 --- 7 files changed, 138 deletions(-) delete mode 100644 .idea/.rakeTasks delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/openvas-omp-ruby.iml delete mode 100644 .idea/scopes/scope_settings.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks deleted file mode 100644 index c6865d9..0000000 --- a/.idea/.rakeTasks +++ /dev/null @@ -1,7 +0,0 @@ - - diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index e206d70..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 5f9fe42..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index af4521e..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.idea/openvas-omp-ruby.iml b/.idea/openvas-omp-ruby.iml deleted file mode 100644 index c2cf9e1..0000000 --- a/.idea/openvas-omp-ruby.iml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b..0000000 --- a/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index c80f219..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - From 38934c3e178444d4b98b573b8d1b782d451677f2 Mon Sep 17 00:00:00 2001 From: lavender Date: Tue, 22 Apr 2014 23:29:48 -0500 Subject: [PATCH 05/10] working on main library....mostly style, but more to ensure I understand. Next is to work on "scan and target" reuse --- examples/basic-scan.rb | 10 +- examples/common.rb | 2 +- examples/list_stuff.rb | 4 +- lib/openvas-omp.rb | 362 ++++++++++++++++++----------------------- 4 files changed, 165 insertions(+), 213 deletions(-) diff --git a/examples/basic-scan.rb b/examples/basic-scan.rb index c680a6b..601f4ad 100755 --- a/examples/basic-scan.rb +++ b/examples/basic-scan.rb @@ -1,17 +1,17 @@ #!/usr/bin/env ruby -require_relative "./common" require_relative '../lib/openvas-omp' +require_relative "./common" -ov = OpenVASOMP::OpenVASOMP.new("user"=>USER,"password"=>PASS,"host"=>URI,"debug"=>0) +ov = OpenVASOMP::OpenVASOMP.new(:user=>USER, :password =>PASS, :host =>HOST, :debug=>0) -config = ov.config_get().index("Full and fast") +config = ov.config_get().key("Full and fast") puts "Config: #{config}" -target = ov.target_create({"name"=>"t", "hosts"=>"127.0.0.1", "comment"=>"t"}) +target = ov.target_create({"name"=>"t2", "hosts"=>"127.0.0.1", "comment"=>"t"}) puts "Target: #{target}" -taskid = ov.task_create({"name"=>"t","comment"=>"t", "target"=>target, "config"=>config}) +taskid = ov.task_create({"name"=>"t2","comment"=>"t", "target"=>target, "config"=>config}) puts "Taskid: #{taskid}" ov.task_start(taskid) diff --git a/examples/common.rb b/examples/common.rb index c730f5b..1a59775 100644 --- a/examples/common.rb +++ b/examples/common.rb @@ -2,4 +2,4 @@ USER = 'tester' PASS = 'tester' -URI = '192.168.101.115' \ No newline at end of file +HOST = '192.168.101.115' \ No newline at end of file diff --git a/examples/list_stuff.rb b/examples/list_stuff.rb index 603770f..98f1fa9 100644 --- a/examples/list_stuff.rb +++ b/examples/list_stuff.rb @@ -2,10 +2,10 @@ # added by jkl to test access -require_relative "./common" require_relative '../lib/openvas-omp' +require_relative "./common" -ov = OpenVASOMP::OpenVASOMP.new("user"=>USER,"password"=>PASS,"host"=>URI,"debug"=>0) +ov = OpenVASOMP::OpenVASOMP.new( :user =>USER, :password =>PASS, :host =>HOST, :debug =>0) puts "Openvas Version #{ov.version_get}" diff --git a/lib/openvas-omp.rb b/lib/openvas-omp.rb index c1cc79c..defab44 100644 --- a/lib/openvas-omp.rb +++ b/lib/openvas-omp.rb @@ -22,7 +22,7 @@ # require 'openvas-omp' # # ov=OpenVASOMP::OpenVASOMP.new("user"=>'openvas',"password"=>'openvas') -# config=ov.config_get().index("Full and fast") +# config=ov.config_get.index("Full and fast") # target=ov.target_create({"name"=>"t", "hosts"=>"127.0.0.1", "comment"=>"t"}) # taskid=ov.task_create({"name"=>"t","comment"=>"t", "target"=>target, "config"=>config}) # ov.task_start(taskid) @@ -70,20 +70,20 @@ def to_s end class OMPResponseError < OMPError - def initialize - self.reason = "Error in OMP request/response" + def initialize reason=nil + self.reason = (reason.nil? ) ? 'Error in OMP request/response' : reason end end class OMPAuthError < OMPError - def initialize - self.reason = "Authentication failed" + def initialize reason=nil + self.reason = (reason.nil? ) ? 'Authentication failed' : reason end end class XMLParsingError < OMPError - def initialize - self.reason = "XML parsing failed" + def initialize reason=nil + self.reason = (reason.nil? ) ? 'XML parsing failed' : reason end end @@ -97,51 +97,31 @@ class OpenVASOMP # # default: host=>'localhost', port=>'9390' # def initialize(p={}) - if p.has_key?("host") - @host=p["host"] - else - @host="localhost" - end - if p.has_key?("port") - @port=p["port"] - else - @port=9390 - end - if p.has_key?("user") - @user=p["user"] - else - @user="openvas" - end - if p.has_key?("password") - @password=p["password"] - else - @password="openvas" - end - if p.has_key?("bufsize") - @bufsize=p["bufsize"] - else - @bufsize=16384 - end - if p.has_key?("debug") - @debug=p["debug"] - else - @debug=0 - end - if @debug>3 - puts "Host: "+@host - puts "Port: "+@port.to_s() - puts "User: "+@user - end - if @debug>99 - puts "Password: "+@password - end + + @host = 'localhost' + @port = 9390 + @user = 'openvas' + @password = 'openvas' + @bufsize = 16384 + @debug = 0 + + @host=p[:host] if p.has_key?(:host) + @port=p[:port] if p.has_key?(:port) + @user=p[:user] if p.has_key?(:user) + @password=p[:password] if p.has_key?(:password) + @bufsize=p[:bufsize] if p.has_key?(:bufsize) + @debug=p[:debug] if p.has_key?(:debug) + + puts "Host: #{@host}\nPort: #{@port}\nUser: #{@user}" if @debug>3 + puts 'Password: '+@password if @debug>99 + @areq='' @read_timeout=3 - if defined? p["noautoconnect"] and not p["noautoconnect"] - connect() - if defined? p["noautologin"] and not p["noautologin"] - login() + if defined? p[:noautoconnect] and not p[:noautoconnect] + connect + if defined? p[:noautologin] and not p[:noautologin] + login end end end @@ -160,11 +140,11 @@ def debug (level) # # Usage: # - # ov.connect() + # ov.connect # def connect @plain_socket=TCPSocket.open(@host, @port) - ssl_context = OpenSSL::SSL::SSLContext.new() + ssl_context = OpenSSL::SSL::SSLContext.new @socket = OpenSSL::SSL::SSLSocket.new(@plain_socket, ssl_context) @socket.sync_close = true @socket.connect @@ -174,30 +154,26 @@ def connect # # Usage: # - # ov.disconnect() + # ov.disconnect # def disconnect - if @socket - @socket.close - end + @socket.close if @socket end # Low level method: Send request and receive response - socket # # Usage: # - # ov.connect(); + # ov.connect; # puts ov.sendrecv("") - # ov.disconnect(); + # ov.disconnect; # def sendrecv (tosend) if not @socket connect end - if @debug>3 then - puts "SENDING: "+tosend - end + puts "SENDING: #{tosend}" if @debug>3 @socket.puts(tosend) @rbuf='' @@ -212,33 +188,29 @@ def sendrecv (tosend) } rescue Timeout::Error size=0 - rescue EOFError - raise OMPResponseError + rescue EOFError => e + raise OMPResponseError e end end while size>=@bufsize response=@rbuf - if @debug>3 then - puts "RECEIVED: "+response - end - return response + puts "RECEIVED: #{response}" if @debug>3 + response end # get OMP version (you don't need to be authenticated) # # Usage: # - # ov.version_get() + # ov.version_get # def version_get - vreq="" + vreq='' resp=sendrecv(vreq) - resp = ""+resp+"" + resp = ''+resp+'' begin docxml = REXML::Document.new(resp) - version='' - version=docxml.root.elements['get_version_response'].elements['version'].text - return version + docxml.root.elements['get_version_response'].elements['version'].text rescue raise XMLParsingError end @@ -249,14 +221,14 @@ def version_get # # Usage: # - # ov.xml_attr() + # ov.xml_attr # def xml_attr(name, opts={}) xml = REXML::Element.new(name) opts.keys.each do |k| xml.attributes[k] = opts[k] end - return xml + xml end # produce multiple XML elements with text specified as hash @@ -264,7 +236,7 @@ def xml_attr(name, opts={}) # # Usage: # - # ov.xml_ele() + # ov.xml_ele # def xml_ele(name, child={}) xml = REXML::Element.new(name) @@ -272,7 +244,7 @@ def xml_ele(name, child={}) xml.add_element(k) xml.elements[k].text = child[k] end - return xml + xml end # produce multiple XML elements with text specified as hash @@ -281,7 +253,7 @@ def xml_ele(name, child={}) # # Usage: # - # ov.xml_mix() + # ov.xml_mix # def xml_mix(name, child, attr, elem) xml = REXML::Element.new(name) @@ -293,7 +265,7 @@ def xml_mix(name, child, attr, elem) xml.add_element(k) xml.elements[k].attributes[attr] = elem[k] end - return xml + xml end # login to OpenVAS server. @@ -302,17 +274,17 @@ def xml_mix(name, child, attr, elem) # # Usage: # - # ov.login() + # ov.login # def login - areq=""+xml_ele("credentials", {"username" => @user, "password" => @password}).to_s()+"" - resp=sendrecv(areq+"") + areq=''+xml_ele("credentials", {'username' => @user, 'password' => @password}).to_s+'' + resp=sendrecv("#{areq}") # wrap it inside tags, so rexml does not complain - resp = ""+resp+"" + resp = "#{resp}" begin docxml = REXML::Document.new(resp) - status=docxml.root.elements['authenticate_response'].attributes['status'].to_i() + status=docxml.root.elements['authenticate_response'].attributes['status'].to_i rescue raise XMLParsingError end @@ -329,16 +301,12 @@ def login # # Usage: # - # if ov.logged_in() then + # if ov.logged_in then # puts "logged in" # end # def logged_in - if @areq == '' - return false - else - return true - end + (@areq == '') ? false : true end # logout from OpenVAS server. @@ -348,11 +316,12 @@ def logged_in # # Usage: # - # ov.logout() + # ov.logout # def logout disconnect @areq = '' + nil end # OMP low level method - Send string request wrapped with @@ -363,8 +332,7 @@ def logout # ov.request_xml("299 raise OMPAuthError end - return docxml.root + docxml.root rescue - raise XMLParsingError + raise XMLParsingError "Request: #{request}\nResponse:\n#{resp}" end end @@ -398,15 +366,13 @@ def omp_request_xml (request) # "hosts"=>"127.0.0.1","comment"=>"yes") # def target_create (p={}) - xmlreq=xml_ele("create_target", p).to_s() + xmlreq=xml_ele('create_target', p).to_s begin - xr=omp_request_xml(xmlreq) - id=xr.elements['create_target_response'].attributes['id'] - rescue + omp_request_xml(xmlreq).elements['create_target_response'].attributes['id'] + rescue raise OMPResponseError end - return id end # OMP - Delete target @@ -416,13 +382,12 @@ def target_create (p={}) # ov.target_delete(target_id) # def target_delete (id) - xmlreq=xml_attr("delete_target", {"target_id" => id}).to_s() + xmlreq=xml_attr('delete_target', {'target_id' => id}).to_s begin - xr=omp_request_xml(xmlreq) + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr end # OMP - Get target for scanning and returns rexml object @@ -431,11 +396,10 @@ def target_delete (id) # rexmlobject = target_get_raw("target_id"=>target_id) # def target_get_raw (p={}) - xmlreq=xml_attr("get_targets", p).to_s() + xmlreq=xml_attr('get_targets', p).to_s begin - xr=omp_request_xml(xmlreq) - return xr + omp_request_xml(xmlreq) rescue raise OMPResponseError end @@ -445,7 +409,7 @@ def target_get_raw (p={}) # with following keys: id,name,comment,hosts,max_hosts,in_use # # Usage: - # array_of_hashes = target_get_all() + # array_of_hashes = target_get_all # def target_get_all (p={}) begin @@ -453,15 +417,15 @@ def target_get_all (p={}) list=Array.new xr.elements.each('//get_targets_response/target') do |target| td=Hash.new - td["id"]=target.attributes["id"] - td["name"]=target.elements["name"].text - td["comment"]=target.elements["comment"].text - td["hosts"]=target.elements["hosts"].text - td["max_hosts"]=target.elements["max_hosts"].text - td["in_use"]=target.elements["in_use"].text + td['id']=target.attributes['id'] + td['name']=target.elements['name'].text + td['comment']=target.elements['comment'].text + td['hosts']=target.elements['hosts'].text + td['max_hosts']=target.elements['max_hosts'].text + td['in_use']=target.elements['in_use'].text list.push td end - return list + list rescue raise OMPResponseError end @@ -469,18 +433,18 @@ def target_get_all (p={}) def target_get_byid (id) begin - xr=target_get_raw("target_id" => id) + xr=target_get_raw('target_id' => id) xr.elements.each('//get_targets_response/target') do |target| td=Hash.new - td["id"]=target.attributes["id"] - td["name"]=target.elements["name"].text - td["comment"]=target.elements["comment"].text - td["hosts"]=target.elements["hosts"].text - td["max_hosts"]=target.elements["max_hosts"].text - td["in_use"]=target.elements["in_use"].text + td['id']=target.attributes['id'] + td['name']=target.elements['name'].text + td['comment']=target.elements['comment'].text + td['hosts']=target.elements['hosts'].text + td['max_hosts']=target.elements['max_hosts'].text + td['in_use']=target.elements['in_use'].text return td end - return list + td # TODO can there be more than one ? rescue raise OMPResponseError end @@ -497,13 +461,12 @@ def target_get_byid (id) # "format"=>"PDF") # def report_get_raw (p={}) - xmlreq=xml_attr("get_reports", p).to_s() + xmlreq=xml_attr("get_reports", p).to_s begin - xr=omp_request_xml(xmlreq) + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr end # OMP - get report by id and format, returns report @@ -539,9 +502,9 @@ def report_get_byid (id, format) # # Usage: # - # pdf_content=ov.report_get_all() + # pdf_content=ov.report_get_all # - def report_get_all () + def report_get_all format_id = format_get_by_name('XML') begin xr=report_get_raw('format_id' => format_id) @@ -572,29 +535,26 @@ def report_get_all () # def result_get_raw (p={}) begin - xmlreq=xml_attr("get_results", p).to_s() - xr=omp_request_xml(xmlreq) + xmlreq=xml_attr('get_results', p).to_s + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr end # OMP - get configs and returns rexml object as response # # Usage: # - # rexmldocument=ov.config_get_raw() + # rexmldocument=ov.config_get_raw # def config_get_raw (p={}) - xmlreq=xml_attr("get_configs", p).to_s() + xmlreq=xml_attr('get_configs', p).to_s begin - xr=omp_request_xml(xmlreq) - return xr + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return false end # OMP - get configs and returns hash as response @@ -602,7 +562,7 @@ def config_get_raw (p={}) # # Usage: # - # array_of_hashes=ov.config_get_all() + # array_of_hashes=ov.config_get_all # def config_get_all (p={}) begin @@ -610,9 +570,9 @@ def config_get_all (p={}) tc=Array.new xr.elements.each('//get_configs_response/config') do |config| c=Hash.new - c["id"]=config.attributes["id"] - c["name"]=config.elements["name"].text - c["comment"]=config.elements["comment"].text + c['id']=config.attributes['id'] + c['name']=config.elements['name'].text + c['comment']=config.elements['comment'].text tc.push c end return tc @@ -627,9 +587,9 @@ def config_get_all (p={}) # # Usage: # - # all_configs_hash=ov.config.get() + # all_configs_hash=ov.config.get # - # config_id=ov.config_get().index("Full and fast") + # config_id=ov.config_get.index("Full and fast") # def config_get (p={}) begin @@ -654,8 +614,8 @@ def config_get (p={}) # new_config_id=config_copy(config_id,"new_name"); # def config_copy (config_id, name) - xmlreq=xml_attr("create_config", - {"copy" => config_id, "name" => name}).to_s() + xmlreq=xml_attr('create_config', + {'copy' => config_id, 'name' => name}).to_s begin xr=omp_request_xml(xmlreq) id=xr.elements['create_config_response'].attributes['id'] @@ -674,15 +634,15 @@ def config_copy (config_id, name) # config_id=config_create("name",rcfile); # def config_create (name, rcfile) - xmlreq=xml_attr("create_config", - {'name' => name, 'rcfile' => rcfile}).to_s() + xmlreq=xml_attr('create_config', + {'name' => name, 'rcfile' => rcfile}).to_s begin xr=omp_request_xml(xmlreq) id=xr.elements['create_config_response'].attributes['id'] - return id rescue raise OMPResponseError end + id end @@ -691,7 +651,7 @@ def config_create (name, rcfile) # # Usage: # - # rexmlobject=ov.format_get_raw() + # rexmlobject=ov.format_get_raw # # def format_get_raw (p={}) @@ -710,9 +670,9 @@ def format_get_raw (p={}) # # Usage: # - # pdf_content=ov.format_get_all() + # pdf_content=ov.format_get_all # - def format_get_all () + def format_get_all begin xr=format_get_raw list=Array.new @@ -737,7 +697,7 @@ def format_get_all () # # Usage: # - # pdf_content=ov.format_get_all() + # pdf_content=ov.format_get_all # def format_get_by_name (name) begin @@ -760,10 +720,10 @@ def format_get_by_name (name) # # Usage: # - # task_id=ov.task_create_raw() + # task_id=ov.task_create_raw # def task_create_raw (p={}, i={}) - xmlreq=xml_mix("create_task", p, "id", i).to_s() + xmlreq=xml_mix('create_task', p, 'id', i).to_s begin xr=omp_request_xml(xmlreq) id=xr.elements['create_task_response'].attributes['id'] @@ -780,7 +740,7 @@ def task_create_raw (p={}, i={}) # # Usage: # - # config_id=o.config_get().index("Full and fast") + # config_id=o.config_get.index("Full and fast") # target_id=o.target_create( # {"name"=>"localtarget", "hosts"=>"127.0.0.1", "comment"=>"t"}) # task_id=ov.task_create( @@ -796,7 +756,7 @@ def task_create (p={}) p.delete(spec) end end - return task_create_raw(p, ids) + task_create_raw(p, ids) end # OMP - deletes task specified by task_id @@ -806,13 +766,12 @@ def task_create (p={}) # ov.task_delete(task_id) # def task_delete (task_id) - xmlreq=xml_attr("delete_task", {"task_id" => task_id}).to_s() + xmlreq=xml_attr("delete_task", {'task_id' => task_id}).to_s begin - xr=omp_request_xml(xmlreq) + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr end # OMP - get task and returns raw rexml object as response @@ -822,10 +781,9 @@ def task_delete (task_id) # rexmlobject=ov.task_get_raw("details"=>"0") # def task_get_raw (p={}) - xmlreq=xml_attr("get_tasks", p).to_s() + xmlreq=xml_attr("get_tasks", p).to_s begin - xr=omp_request_xml(xmlreq) - return xr + omp_request_xml(xmlreq) rescue raise OMPResponseError end @@ -837,31 +795,31 @@ def task_get_raw (p={}) # # Usage: # - # array_of_hashes=ov.task_get_all() + # array_of_hashes=ov.task_get_all # def task_get_all (p={}) xr=task_get_raw(p) t=Array.new xr.elements.each('//get_tasks_response/task') do |task| td=Hash.new - td["id"]=task.attributes["id"] - td["name"]=task.elements["name"].text - td["comment"]=task.elements["comment"].text - td["status"]=task.elements["status"].text - td["progress"]=task.elements["progress"].text - if defined? task.elements["first_report"].elements["report"].attributes["id"] then - td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"] + td['id']=task.attributes['id'] + td['name']=task.elements['name'].text + td['comment']=task.elements['comment'].text + td['status']=task.elements['status'].text + td['progress']=task.elements['progress'].text + if defined? task.elements['first_report'].elements['report'].attributes['id'] then + td['firstreport']=task.elements['first_report'].elements['report'].attributes['id'] else - td["firstreport"]=nil + td['firstreport']=nil end - if defined? task.elements["last_report"].elements["report"].attributes["id"] then - td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"] + if defined? task.elements['last_report'].elements["report"].attributes['id'] then + td['lastreport']=task.elements["last_report"].elements["report"].attributes['id'] else - td["lastreport"]=nil + td['lastreport']=nil end t.push td end - return t + t end # OMP - get task specified by task_id and returns hash with @@ -873,23 +831,25 @@ def task_get_all (p={}) # hash=ov.task_get_byid(task_id) # def task_get_byid (id) - xr=task_get_raw("task_id" => id, "details" => 0) + xr=task_get_raw('task_id' => id, "details" => 0) xr.elements.each('//get_tasks_response/task') do |task| td=Hash.new - td["id"]=task.attributes["id"] - td["name"]=task.elements["name"].text - td["comment"]=task.elements["comment"].text - td["status"]=task.elements["status"].text - td["progress"]=task.elements["progress"].text - if defined? task.elements["first_report"].elements["report"].attributes["id"] then - td["firstreport"]=task.elements["first_report"].elements["report"].attributes["id"] + td['id']=task.attributes['id'] + td['name']=task.elements['name'].text + td['comment']=task.elements['comment'].text + td['status']=task.elements['status'].text + td['progress']=task.elements['progress'].text + + if defined? task.elements['first_report'].elements['report'].attributes['id'] + td['firstreport']=task.elements['first_report'].elements['report'].attributes['id'] else - td["firstreport"]=nil + td['firstreport']=nil end - if defined? task.elements["last_report"].elements["report"].attributes["id"] then - td["lastreport"]=task.elements["last_report"].elements["report"].attributes["id"] + + if defined? task.elements['last_report'].elements["report"].attributes['id'] + td['lastreport']=task.elements['last_report'].elements["report"].attributes['id'] else - td["lastreport"]=nil + td['lastreport']=nil end return (td) end @@ -905,13 +865,9 @@ def task_get_byid (id) # end # def task_finished (id) - xr=task_get_raw("task_id" => id, "details" => 0) + xr=task_get_raw('task_id' => id, "details" => 0) xr.elements.each('//get_tasks_response/task') do |task| - if status=task.elements["status"].text == "Done" - return true - else - return false - end + return (status=task.elements['status'].text == "Done") ? true : false end end @@ -924,9 +880,9 @@ def task_finished (id) # puts ov.task_progress(task_id) # def task_progress (id) - xr=task_get_raw("task_id" => id, "details" => 0) + xr=task_get_raw('task_id' => id, "details" => 0) xr.elements.each('//get_tasks_response/task') do |task| - return task.elements["progress"].text.to_i() + return task.elements["progress"].text.to_i end end @@ -937,14 +893,13 @@ def task_progress (id) # ov.task_start(task_id) # def task_start (task_id) - xmlreq=xml_attr("start_task", {"task_id" => task_id}).to_s() + xmlreq=xml_attr("start_task", {'task_id' => task_id}).to_s begin - xr=omp_request_xml(xmlreq) + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr - end + end # OMP - stops task specified by task_id # @@ -953,13 +908,12 @@ def task_start (task_id) # ov.task_stop(task_id) # def task_stop (task_id) - xmlreq=xml_attr("stop_task", {"task_id" => task_id}).to_s() + xmlreq=xml_attr('stop_task', {'task_id' => task_id}).to_s begin - xr=omp_request_xml(xmlreq) + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr end # OMP - pauses task specified by task_id @@ -969,13 +923,12 @@ def task_stop (task_id) # ov.task_pause(task_id) # def task_pause (task_id) - xmlreq=xml_attr("pause_task", {"task_id" => task_id}).to_s() + xmlreq=xml_attr('pause_task', {'task_id' => task_id}).to_s begin - xr=omp_request_xml(xmlreq) + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr end # OMP - resumes (or starts) task specified by task_id @@ -985,13 +938,12 @@ def task_pause (task_id) # ov.task_resume_or_start(task_id) # def task_resume_or_start (task_id) - xmlreq=xml_attr("resume_or_start_task", {"task_id" => task_id}).to_s() + xmlreq=xml_attr('resume_or_start_task', {'task_id' => task_id}).to_s begin - xr=omp_request_xml(xmlreq) + omp_request_xml(xmlreq) rescue raise OMPResponseError end - return xr end end # end of Class From a5473bc992b0c6c0805060cf645edec374d734b6 Mon Sep 17 00:00:00 2001 From: lavender Date: Tue, 22 Apr 2014 23:48:06 -0500 Subject: [PATCH 06/10] working on main library....mostly style, but more to ensure I understand. Next is to work on "scan and target" reuse --- lib/openvas-omp.rb | 53 ++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/lib/openvas-omp.rb b/lib/openvas-omp.rb index defab44..ae86e3f 100644 --- a/lib/openvas-omp.rb +++ b/lib/openvas-omp.rb @@ -70,20 +70,20 @@ def to_s end class OMPResponseError < OMPError - def initialize reason=nil - self.reason = (reason.nil? ) ? 'Error in OMP request/response' : reason + def initialize(reason=nil) + self.reason = (reason.nil?) ? 'Error in OMP request/response' : reason end end class OMPAuthError < OMPError - def initialize reason=nil - self.reason = (reason.nil? ) ? 'Authentication failed' : reason + def initialize(reason=nil) + self.reason = (reason.nil?) ? 'Authentication failed' : reason end end class XMLParsingError < OMPError - def initialize reason=nil - self.reason = (reason.nil? ) ? 'XML parsing failed' : reason + def initialize(reason=nil) + self.reason = (reason.nil?) ? 'XML parsing failed' : reason end end @@ -169,7 +169,7 @@ def disconnect # ov.disconnect; # def sendrecv (tosend) - if not @socket + unless @socket connect end @@ -277,7 +277,7 @@ def xml_mix(name, child, attr, elem) # ov.login # def login - areq=''+xml_ele("credentials", {'username' => @user, 'password' => @password}).to_s+'' + areq=''+xml_ele('credentials', {'username' => @user, 'password' => @password}).to_s+'' resp=sendrecv("#{areq}") # wrap it inside tags, so rexml does not complain resp = "#{resp}" @@ -343,8 +343,8 @@ def omp_request_raw (request) # rexmlobject = ov.request_xml("" + resp = sendrecv(@areq+request) + resp = "#{resp}" begin docxml = REXML::Document.new(resp) @@ -366,7 +366,7 @@ def omp_request_xml (request) # "hosts"=>"127.0.0.1","comment"=>"yes") # def target_create (p={}) - xmlreq=xml_ele('create_target', p).to_s + xmlreq = xml_ele('create_target', p).to_s begin omp_request_xml(xmlreq).elements['create_target_response'].attributes['id'] @@ -444,7 +444,6 @@ def target_get_byid (id) td['in_use']=target.elements['in_use'].text return td end - td # TODO can there be more than one ? rescue raise OMPResponseError end @@ -579,7 +578,6 @@ def config_get_all (p={}) rescue raise OMPResponseError end - return false end # OMP - get configs and returns hash as response @@ -600,11 +598,10 @@ def config_get (p={}) name=config.elements["name"].text list[id]=name end - return list + list rescue raise OMPResponseError end - return false end # OMP - copy config with new name and returns new id @@ -748,7 +745,7 @@ def task_create_raw (p={}, i={}) # "config"=>config_id} # def task_create (p={}) - specials=Array["config", "target", "escalator", "schedule"] + specials=Array['config', "target", "escalator", "schedule"] ids = Hash.new specials.each do |spec| if p.has_key?(spec) @@ -766,7 +763,7 @@ def task_create (p={}) # ov.task_delete(task_id) # def task_delete (task_id) - xmlreq=xml_attr("delete_task", {'task_id' => task_id}).to_s + xmlreq=xml_attr('delete_task', {'task_id' => task_id}).to_s begin omp_request_xml(xmlreq) rescue @@ -781,7 +778,7 @@ def task_delete (task_id) # rexmlobject=ov.task_get_raw("details"=>"0") # def task_get_raw (p={}) - xmlreq=xml_attr("get_tasks", p).to_s + xmlreq=xml_attr('get_tasks', p).to_s begin omp_request_xml(xmlreq) rescue @@ -807,12 +804,12 @@ def task_get_all (p={}) td['comment']=task.elements['comment'].text td['status']=task.elements['status'].text td['progress']=task.elements['progress'].text - if defined? task.elements['first_report'].elements['report'].attributes['id'] then + if defined? task.elements['first_report'].elements['report'].attributes['id'] td['firstreport']=task.elements['first_report'].elements['report'].attributes['id'] else td['firstreport']=nil end - if defined? task.elements['last_report'].elements["report"].attributes['id'] then + if defined? task.elements['last_report'].elements["report"].attributes['id'] td['lastreport']=task.elements["last_report"].elements["report"].attributes['id'] else td['lastreport']=nil @@ -831,7 +828,7 @@ def task_get_all (p={}) # hash=ov.task_get_byid(task_id) # def task_get_byid (id) - xr=task_get_raw('task_id' => id, "details" => 0) + xr=task_get_raw('task_id' => id, 'details' => 0) xr.elements.each('//get_tasks_response/task') do |task| td=Hash.new td['id']=task.attributes['id'] @@ -846,8 +843,8 @@ def task_get_byid (id) td['firstreport']=nil end - if defined? task.elements['last_report'].elements["report"].attributes['id'] - td['lastreport']=task.elements['last_report'].elements["report"].attributes['id'] + if defined? task.elements['last_report'].elements['report'].attributes['id'] + td['lastreport']=task.elements['last_report'].elements['report'].attributes['id'] else td['lastreport']=nil end @@ -865,9 +862,9 @@ def task_get_byid (id) # end # def task_finished (id) - xr=task_get_raw('task_id' => id, "details" => 0) + xr=task_get_raw('task_id' => id, 'details' => 0) xr.elements.each('//get_tasks_response/task') do |task| - return (status=task.elements['status'].text == "Done") ? true : false + return (task.elements['status'].text == 'Done') ? true : false end end @@ -880,9 +877,9 @@ def task_finished (id) # puts ov.task_progress(task_id) # def task_progress (id) - xr=task_get_raw('task_id' => id, "details" => 0) + xr=task_get_raw('task_id' => id, 'details' => 0) xr.elements.each('//get_tasks_response/task') do |task| - return task.elements["progress"].text.to_i + return task.elements['progress'].text.to_i end end @@ -893,7 +890,7 @@ def task_progress (id) # ov.task_start(task_id) # def task_start (task_id) - xmlreq=xml_attr("start_task", {'task_id' => task_id}).to_s + xmlreq=xml_attr('start_task', {'task_id' => task_id}).to_s begin omp_request_xml(xmlreq) rescue From 993a7d4849948134263f8cf3a43fd8c6234446e1 Mon Sep 17 00:00:00 2001 From: lavender Date: Wed, 23 Apr 2014 09:15:10 -0500 Subject: [PATCH 07/10] small cleanup the class is a bit "bulky". It mixes lower level communications with interpretation of the data. Clever. --- lib/openvas-omp.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/openvas-omp.rb b/lib/openvas-omp.rb index ae86e3f..795c478 100644 --- a/lib/openvas-omp.rb +++ b/lib/openvas-omp.rb @@ -56,7 +56,7 @@ module OpenVASOMP - class OMPError < :: RuntimeError + class OMPError < ::RuntimeError attr_accessor :req, :reason def initialize(req, reason = '') @@ -143,10 +143,13 @@ def debug (level) # ov.connect # def connect - @plain_socket=TCPSocket.open(@host, @port) + plain_socket=TCPSocket.open(@host, @port) ssl_context = OpenSSL::SSL::SSLContext.new - @socket = OpenSSL::SSL::SSLSocket.new(@plain_socket, ssl_context) - @socket.sync_close = true + @socket = OpenSSL::SSL::SSLSocket.new(plain_socket, ssl_context) + + # TODO what did this do ??? + #@socket.sync_close = true + @socket.connect end From 358947565d9da5f5cab0cf6917c658a506a28df8 Mon Sep 17 00:00:00 2001 From: Markus Grobelin Date: Mon, 13 Jul 2015 09:46:38 +0200 Subject: [PATCH 08/10] added .gemspec --- .gemspec | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gemspec diff --git a/.gemspec b/.gemspec new file mode 100644 index 0000000..8a29564 --- /dev/null +++ b/.gemspec @@ -0,0 +1,3 @@ +git 'https://github.com/mgrobelin/openvas-omp-ruby.git' do + gem 'openvas-omp' +end From 33dc53fe7f5381ba04b420543c38e6786769c241 Mon Sep 17 00:00:00 2001 From: Markus Grobelin Date: Mon, 13 Jul 2015 09:57:38 +0200 Subject: [PATCH 09/10] new try --- .gemspec | 3 --- openvas-omp.gemspec | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) delete mode 100644 .gemspec create mode 100644 openvas-omp.gemspec diff --git a/.gemspec b/.gemspec deleted file mode 100644 index 8a29564..0000000 --- a/.gemspec +++ /dev/null @@ -1,3 +0,0 @@ -git 'https://github.com/mgrobelin/openvas-omp-ruby.git' do - gem 'openvas-omp' -end diff --git a/openvas-omp.gemspec b/openvas-omp.gemspec new file mode 100644 index 0000000..e2dcbdf --- /dev/null +++ b/openvas-omp.gemspec @@ -0,0 +1,15 @@ +Gem::Specification.new do |s| + s.name = 'openvas-omp-ruby' + s.license = 'MIT' + s.version = '0.0.5' + s.platform = Gem::Platform::RUBY + s.authors = ["Vlatko Kosturjak", "jackdfw"] + s.summary = "OpenVAS manager communication library" + s.description = "This library is used for communication with OpenVAS manager over OMP You can start, stop, pause and resume scan. Watch progress and status of scan, download report, etc." + + s.files = `git ls-files lib`.split("\n") + ['Gemfile','Rakefile','README.md', 'MIT-LICENSE'] + s.test_files = `git ls-files test`.split("\n") + s.require_paths = ['lib'] + + s.required_ruby_version = '>= 1.9.2' +end From 7f646bca89c1675c5c8187b5ce8de056a83b9695 Mon Sep 17 00:00:00 2001 From: Markus Grobelin Date: Mon, 13 Jul 2015 10:10:24 +0200 Subject: [PATCH 10/10] fixed gemspec file --- openvas-omp.gemspec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openvas-omp.gemspec b/openvas-omp.gemspec index e2dcbdf..6d58bab 100644 --- a/openvas-omp.gemspec +++ b/openvas-omp.gemspec @@ -1,13 +1,18 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path('../lib', __FILE__) + Gem::Specification.new do |s| - s.name = 'openvas-omp-ruby' + s.name = 'openvas-omp' s.license = 'MIT' s.version = '0.0.5' s.platform = Gem::Platform::RUBY s.authors = ["Vlatko Kosturjak", "jackdfw"] + s.email = 'me@example.com' + s.homepage = 'https://github.com/kost/openvas-omp-ruby' s.summary = "OpenVAS manager communication library" s.description = "This library is used for communication with OpenVAS manager over OMP You can start, stop, pause and resume scan. Watch progress and status of scan, download report, etc." - s.files = `git ls-files lib`.split("\n") + ['Gemfile','Rakefile','README.md', 'MIT-LICENSE'] + s.files = `git ls-files lib`.split("\n") + ['Gemfile','Rakefile','README.rdoc', 'LICENSE.txt'] s.test_files = `git ls-files test`.split("\n") s.require_paths = ['lib']