mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Consolidate some error handling, standardize geoip coordinates, fix output bugs. Fixes #1744
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
local nmap = require "nmap"
|
||||
local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
local coroutine = require "coroutine"
|
||||
|
||||
_ENV = stdnse.module("geoip", stdnse.seeall)
|
||||
|
||||
@@ -72,4 +73,66 @@ get_all_by_gps = function()
|
||||
return t
|
||||
end
|
||||
|
||||
-- Order in which field names will be shown in XML
|
||||
local field_order = {
|
||||
"latitude",
|
||||
"longitude",
|
||||
"city",
|
||||
"region",
|
||||
"country"
|
||||
}
|
||||
|
||||
--- Location object
|
||||
--
|
||||
-- The object supports setting the following fields using functions like
|
||||
-- <code>set_fieldname</code>:
|
||||
-- * latitude
|
||||
-- * longitude
|
||||
-- * city
|
||||
-- * region
|
||||
-- * country
|
||||
--
|
||||
-- The location object is suitable for returning from a script, and will
|
||||
-- produce appropriate string and structured XML output.
|
||||
Location = {
|
||||
new = function(self,o)
|
||||
o = o or {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
-- Ensure fields are put in the XML in proper order
|
||||
__pairs = function(self)
|
||||
local function iterator ()
|
||||
for i, key in ipairs(field_order) do
|
||||
coroutine.yield(key, self[key])
|
||||
end
|
||||
end
|
||||
return coroutine.wrap(iterator)
|
||||
end,
|
||||
|
||||
__tostring = function(self)
|
||||
local out = {
|
||||
("coordinates: %s, %s"):format(self.latitude, self.longitude)
|
||||
}
|
||||
-- if any of these are nil, it doesn't increase #place
|
||||
local place = {self.city}
|
||||
place[#place+1] = self.region
|
||||
place[#place+1] = self.country
|
||||
if #place > 0 then
|
||||
out[#out+1] = ("location: %s"):format(table.concat(place, ", "))
|
||||
end
|
||||
|
||||
return table.concat(out, "\n")
|
||||
end,
|
||||
}
|
||||
|
||||
-- Generate setter functions
|
||||
for _, field in ipairs(field_order) do
|
||||
Location["set_" .. field] = function(self, value)
|
||||
self[field] = value
|
||||
end
|
||||
end
|
||||
|
||||
return _ENV;
|
||||
|
||||
@@ -4,6 +4,7 @@ local ipOps = require "ipOps"
|
||||
local json = require "json"
|
||||
local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
local oops = require "oops"
|
||||
|
||||
description = [[
|
||||
Tries to identify the physical location of an IP address using the
|
||||
@@ -17,9 +18,13 @@ is no limit on lookups using this service.
|
||||
--
|
||||
-- @output
|
||||
-- | ip-geolocation-geoplugin:
|
||||
-- | 74.207.244.221 (scanme.nmap.org)
|
||||
-- | coordinates (lat,lon): 39.4208984375,-74.497703552246
|
||||
-- |_ state: New Jersey, United States
|
||||
-- | coordinates: 39.4208984375, -74.497703552246
|
||||
-- |_location: New Jersey, United States
|
||||
-- @xmloutput
|
||||
-- <elem key="latitude">37.5605</elem>
|
||||
-- <elem key="longitude">-121.9999</elem>
|
||||
-- <elem key="region">California</elem>
|
||||
-- <elem key="country">United States</elem>
|
||||
--
|
||||
-- @see ip-geolocation-ipinfodb.nse
|
||||
-- @see ip-geolocation-map-bing.nse
|
||||
@@ -44,15 +49,18 @@ end
|
||||
-- No limit on requests
|
||||
local geoplugin = function(ip)
|
||||
local response = http.get("www.geoplugin.net", 80, "/json.gp?ip="..ip, {any_af=true})
|
||||
local stat, loc = json.parse(response.body)
|
||||
local stat, loc = oops.raise(
|
||||
"The geoPlugin service has likely blocked you due to excessive usage",
|
||||
json.parse(response.body))
|
||||
if not stat then
|
||||
return false, loc
|
||||
return stat, loc
|
||||
end
|
||||
|
||||
local output = {}
|
||||
table.insert(output, "coordinates (lat,lon): "..loc.geoplugin_latitude..","..loc.geoplugin_longitude)
|
||||
local regionName = (loc.geoplugin_regionName == json.NULL) and "Unknown" or loc.geoplugin_regionName
|
||||
table.insert(output,"state: ".. regionName ..", ".. loc.geoplugin_countryName)
|
||||
local output = geoip.Location:new()
|
||||
output:set_latitude(loc.geoplugin_latitude)
|
||||
output:set_longitude(loc.geoplugin_longitude)
|
||||
output:set_region((loc.geoplugin_regionName == json.NULL) and "Unknown" or loc.geoplugin_regionName)
|
||||
output:set_country(loc.geoplugin_countryName)
|
||||
|
||||
geoip.add(ip, loc.geoplugin_latitude, loc.geoplugin_longitude)
|
||||
|
||||
@@ -60,21 +68,5 @@ local geoplugin = function(ip)
|
||||
end
|
||||
|
||||
action = function(host,port)
|
||||
local output = stdnse.output_table()
|
||||
|
||||
local status, result = geoplugin(host.ip)
|
||||
if not status then
|
||||
if result == "syntax error" then
|
||||
result = "The geoPlugin service has likely blocked you due to excessive usage, but the response received was 'syntax error'."
|
||||
end
|
||||
output.ERROR = result
|
||||
return output, output.ERROR
|
||||
end
|
||||
|
||||
output.name = host.ip
|
||||
if host.targetname then
|
||||
output.name = output.name.." ("..host.targetname..")"
|
||||
end
|
||||
|
||||
return stdnse.format_output(true,output)
|
||||
return oops.output(geoplugin(host.ip))
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@ local geoip = require "geoip"
|
||||
local http = require "http"
|
||||
local ipOps = require "ipOps"
|
||||
local json = require "json"
|
||||
local oops = require "oops"
|
||||
local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
|
||||
@@ -24,9 +25,15 @@ needs to be obtained through free registration for this service:
|
||||
--
|
||||
-- @output
|
||||
-- | ip-geolocation-ipinfodb:
|
||||
-- | 74.207.244.221 (scanme.nmap.org)
|
||||
-- | coordinates (lat,lon): 37.5384,-121.99
|
||||
-- |_ city: FREMONT, CALIFORNIA, UNITED STATES
|
||||
-- | coordinates: 37.5384, -121.99
|
||||
-- |_location: FREMONT, CALIFORNIA, UNITED STATES
|
||||
--
|
||||
-- @xmloutput
|
||||
-- <elem key="latitude">37.5384</elem>
|
||||
-- <elem key="longitude">-121.99</elem>
|
||||
-- <elem key="city">FREMONT</elem>
|
||||
-- <elem key="region">CALIFORNIA</elem>
|
||||
-- <elem key="country">UNITED STATES</elem>
|
||||
--
|
||||
-- @see ip-geolocation-geoplugin.nse
|
||||
-- @see ip-geolocation-map-bing.nse
|
||||
@@ -62,34 +69,28 @@ end
|
||||
local ipinfodb = function(ip)
|
||||
local api_key = stdnse.get_script_args(SCRIPT_NAME..".apikey")
|
||||
local response = http.get("api.ipinfodb.com", 80, "/v3/ip-city/?key="..api_key.."&format=json".."&ip="..ip, {any_af=true})
|
||||
local stat, loc = json.parse(response.body)
|
||||
local stat, loc = oops.raise(
|
||||
"Unable to parse ipinfodb.com response",
|
||||
json.parse(response.body))
|
||||
if not stat then
|
||||
stdnse.debug1("No response, possibly a network problem.")
|
||||
return nil
|
||||
return stat, loc
|
||||
end
|
||||
if loc.statusMessage and loc.statusMessage == "Invalid API key." then
|
||||
stdnse.debug1(loc.statusMessage)
|
||||
return nil
|
||||
return false, oops.err(loc.statusMessage)
|
||||
end
|
||||
|
||||
local output = {}
|
||||
table.insert(output, "coordinates (lat,lon): "..loc.latitude..","..loc.longitude)
|
||||
table.insert(output,"city: ".. loc.cityName..", ".. loc.regionName..", ".. loc.countryName)
|
||||
local output = geoip.Location:new()
|
||||
output:set_latitude(loc.latitude)
|
||||
output:set_longitude(loc.longitude)
|
||||
output:set_city(loc.cityName)
|
||||
output:set_region(loc.regionName)
|
||||
output:set_country(loc.countryName)
|
||||
|
||||
geoip.add(ip, loc.latitude, loc.longitude)
|
||||
|
||||
return output
|
||||
return true, output
|
||||
end
|
||||
|
||||
action = function(host,port)
|
||||
local output = ipinfodb(host.ip)
|
||||
|
||||
if(output and #output~=0) then
|
||||
output.name = host.ip
|
||||
if host.targetname then
|
||||
output.name = output.name.." ("..host.targetname..")"
|
||||
end
|
||||
end
|
||||
|
||||
return stdnse.format_output(true,output)
|
||||
return oops.output(ipinfodb(host.ip))
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local http = require "http"
|
||||
local geoip = require "geoip"
|
||||
local io = require "io"
|
||||
local oops = require "oops"
|
||||
local stdnse = require "stdnse"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
@@ -177,21 +178,14 @@ postrule = function()
|
||||
end
|
||||
|
||||
action = function()
|
||||
local output = stdnse.output_table()
|
||||
|
||||
-- Parse and sanity check the command line arguments.
|
||||
local status, params, options = parse_args()
|
||||
local status, params, options = oops.raise(
|
||||
"Script argument problem",
|
||||
parse_args())
|
||||
if not status then
|
||||
output.ERROR = params
|
||||
return output, output.ERROR
|
||||
return params
|
||||
end
|
||||
|
||||
-- Render the map.
|
||||
local status, msg = render(params, options)
|
||||
if not status then
|
||||
output.ERROR = msg
|
||||
return output, output.ERROR
|
||||
end
|
||||
|
||||
return output, stdnse.format_output(true, msg)
|
||||
return oops.output(render(params, options))
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local http = require "http"
|
||||
local geoip = require "geoip"
|
||||
local io = require "io"
|
||||
local oops = require "oops"
|
||||
local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
local url = require "url"
|
||||
@@ -167,21 +168,14 @@ postrule = function()
|
||||
end
|
||||
|
||||
action = function()
|
||||
local output = stdnse.output_table()
|
||||
|
||||
-- Parse and sanity check the command line arguments.
|
||||
local status, params, options = parse_args()
|
||||
local status, params, options = oops.raise(
|
||||
"Script argument problem",
|
||||
parse_args())
|
||||
if not status then
|
||||
output.ERROR = params
|
||||
return output, output.ERROR
|
||||
return params
|
||||
end
|
||||
|
||||
-- Render the map.
|
||||
local status, msg = render(params, options)
|
||||
if not status then
|
||||
output.ERROR = msg
|
||||
return output, output.ERROR
|
||||
end
|
||||
|
||||
return output, stdnse.format_output(true, msg)
|
||||
return oops.output(render(params, options))
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local geoip = require "geoip"
|
||||
local io = require "io"
|
||||
local oops = require "oops"
|
||||
local stdnse = require "stdnse"
|
||||
local table = require "table"
|
||||
|
||||
@@ -76,21 +77,14 @@ postrule = function()
|
||||
end
|
||||
|
||||
action = function()
|
||||
local output = stdnse.output_table()
|
||||
|
||||
-- Parse and sanity check the command line arguments.
|
||||
local status, path = parse_args()
|
||||
local status, path = oops.raise(
|
||||
"Script argument problem",
|
||||
parse_args())
|
||||
if not status then
|
||||
output.ERROR = path
|
||||
return output, output.ERROR
|
||||
return path
|
||||
end
|
||||
|
||||
-- Render the map.
|
||||
local status, msg = render(path)
|
||||
if not status then
|
||||
output.ERROR = msg
|
||||
return output, output.ERROR
|
||||
end
|
||||
|
||||
return msg
|
||||
return oops.output(render(path))
|
||||
end
|
||||
|
||||
@@ -25,9 +25,15 @@ the commercial ones.
|
||||
--
|
||||
-- @output
|
||||
-- | ip-geolocation-maxmind:
|
||||
-- | 74.207.244.221 (scanme.nmap.org)
|
||||
-- | coordinates (lat,lon): 39.4899,-74.4773
|
||||
-- |_ city: Absecon, Philadelphia, PA, United States
|
||||
-- | coordinates: 39.4899, -74.4773
|
||||
-- |_location: Absecon, Philadelphia, PA, United States
|
||||
--
|
||||
-- @xmloutput
|
||||
-- <elem key="latitude">39.4899</elem>
|
||||
-- <elem key="longitude">-74.4773</elem>
|
||||
-- <elem key="city">Absecon</elem>
|
||||
-- <elem key="region">Philadelphia, PA</elem>
|
||||
-- <elem key="country">United States</elem>
|
||||
--
|
||||
-- @see ip-geolocation-geoplugin.nse
|
||||
-- @see ip-geolocation-ipinfodb.nse
|
||||
@@ -498,8 +504,13 @@ local GeoIP = {
|
||||
local loc = self:record_by_addr(addr)
|
||||
if not loc then return nil end
|
||||
geoip.add(addr, loc.latitude, loc.longitude)
|
||||
setmetatable(loc, record_metatable)
|
||||
return loc
|
||||
local output = geoip.Location:new()
|
||||
output:set_latitude(loc.latitude)
|
||||
output:set_longitude(loc.longitude)
|
||||
output:set_city(loc.city)
|
||||
output:set_region(loc.metro_code)
|
||||
output:set_country(loc.country_name)
|
||||
return output
|
||||
end,
|
||||
|
||||
record_by_addr=function(self,addr)
|
||||
|
||||
Reference in New Issue
Block a user