Cleanup to support v1.2 as well as 1.1

This commit is contained in:
HD Moore 2012-07-08 01:53:32 -05:00
parent 4199b67879
commit 75430a0b7e
1 changed files with 69 additions and 18 deletions

View File

@ -144,6 +144,7 @@ class APIRequest
begin
prepare_http_client
@raw_response = @http.post(@uri.path, @req, @headers)
@raw_response_data = @raw_response.body
@res = parse_xml(@raw_response_data)
@ -155,19 +156,32 @@ class APIRequest
@sid = attributes['session-id']
if(attributes['success'] and attributes['success'].to_i == 1)
@success = true
else
@success = true
if(attributes['success'] and attributes['success'].to_i == 0)
@success = false
@res.elements.each('//Failure/Exception') do |s|
s.elements.each('message') do |m|
@error = m.text
end
s.elements.each('stacktrace') do |m|
@trace = m.text
end
end
# Look for a stack trace
@res.elements.each('//Failure/Exception') do |s|
# 1.1 returns lower case elements
s.elements.each('message') do |m|
@error = m.text
end
s.elements.each('stacktrace') do |m|
@trace = m.text
end
# 1.2 returns capitalized elements
s.elements.each('Message') do |m|
@error = m.text
end
s.elements.each('Stacktrace') do |m|
@trace = m.text
end
end
# This is a hack to handle corner cases where a heavily loaded Nexpose instance
# drops our HTTP connection before processing. We try 5 times to establish a
# connection in these situations. The actual exception occurs in the Ruby
@ -194,9 +208,7 @@ class APIRequest
@error = "Nexpose has not been properly licensed"
end
if ! (@success or @error)
@error = "Nexpose service returned an unrecognized response: #{@raw_response_data.inspect}"
end
@success = false if @error
@sid
end
@ -234,6 +246,17 @@ module NexposeAPI
xml
end
def make_xml_plain(name, opts={}, data='')
xml = REXML::Element.new(name)
opts.keys.each do |k|
xml.attributes[k] = "#{opts[k]}"
end
xml.text = data
xml
end
def scan_stop(param)
r = execute(make_xml('ScanStopRequest', { 'scan-id' => param }))
r.success
@ -342,6 +365,28 @@ module NexposeAPI
r.success
end
def vuln_exception_create(vuln_id, reason, scope, comment='', attrs={})
attrs = attrs.merge({ 'vuln-id' => vuln_id, 'reason' => reason, 'scope' => scope })
req = make_xml('VulnerabilityExceptionCreateRequest', attrs)
com = make_xml_plain('comment', {}, comment.to_s)
req << com
r = execute(req, '1.2')
end
def vuln_exception_approve(exception_id, comment='', attrs={})
attrs = attrs.merge({ 'exception-id' => exception_id })
req = make_xml('VulnerabilityExceptionApproveRequest', attrs)
com = make_xml_plain('comment', {}, comment.to_s)
req << com
r = execute(req, '1.2')
end
def vuln_exception_update_expiration(exception_id, expiration_date, attrs={})
attrs = attrs.merge({ 'exception-id' => exception_id, 'expiration-date' => expiration_date })
req = make_xml('VulnerabilityExceptionUpdateExpirationDateRequest', attrs)
r = execute(req, '1.2')
end
def asset_group_delete(connection, id, debug = false)
r = execute(make_xml('AssetGroupDeleteRequest', { 'group-id' => param }))
r.success
@ -349,10 +394,10 @@ module NexposeAPI
def asset_group_create(name, description, devices)
req = make_xml('AssetGroupSaveRequest')
req_ag = make_xml('AssetGroup', { 'id' => "-1", 'name' => name, 'description' => description })
req_devices = make_xml('Devices')
req_ag = make_xml_plain('AssetGroup', { 'id' => "-1", 'name' => name, 'description' => description })
req_devices = make_xml_plain('Devices')
devices.each do |did|
req_devices << make_xml('device', { 'id' => did })
req_devices << make_xml_plain('device', { 'id' => did })
end
req_ag << req_devices
req << req_ag
@ -639,6 +684,7 @@ class Connection
@session_id = nil
@error = false
@url = "https://#{@host}:#{@port}/api/1.1/xml"
@url_base = "https://#{@host}:#{@port}/api/"
end
# Establish a new connection and Session ID
@ -650,10 +696,15 @@ class Connection
@session_id = r.sid
return true
end
false
end
# Logout of the current connection
def logout
# Bypass logout unless we have an actual session ID
return true unless @session_id
r = execute(make_xml('LogoutRequest', {'sync-id' => 0}))
if(r.success)
return true
@ -662,8 +713,8 @@ class Connection
end
# Execute an API request
def execute(xml)
APIRequest.execute(url,xml.to_s)
def execute(xml, version='1.1')
APIRequest.execute("#{@url_base}#{version}/xml", xml.to_s)
end
# Download a specific URL