Nmap Development mailing list archives

Re: [NSE] NSE HTTP library


From: Sven Klemm <sven () c3d2 de>
Date: Fri, 18 Jan 2008 20:51:46 +0100

Sven Klemm wrote:

But I've run into problem that let's nmap segfault reproducible.
Somehow that's related to my http library at least it does not occur
without the library. I am also getting cannot resume dead coroutine
errors. But currently I have no idea what causes these. Maybe someone
can help me here.

Ah I found the bug. I forgot to declare the socket variable as local.
Now everything works fine. I've attached the fixed version.

Cheers,
Sven

-- 
Sven Klemm
http://cthulhu.c3d2.de/~sven/

-- See nmaps COPYING for licence
module(...,package.seeall)

require 'stdnse'
require 'url'

--
-- http.get( host, port, path )
-- http.request( host, port, request )
-- http.get_url( url )
--
-- host may either be a string or table
-- port may either be a number or a table
--
-- the format of the return value is a table with the following structure:
-- {status = 200, header = {}, body ="<html>...</html>"}
-- the header table has an entry for each received header with the header name being the key
-- thee table also has an entry named "status" which contains the http status code of the request
-- in case of an error status is nil


-- fetch relative URL with get request
get = function( host, port, path )
  local hostname = host
  if type(host) == 'table' then
    hostname = ( host.name ~= '' and host.name ) or host.ip
  end

  local data
  data = "GET "..path.." HTTP/1.1\r\n"
  data = data .. "Host: "..hostname.."\r\n"
  data = data .. "User-Agent: Nmap NSE\r\n"
  data = data .. "Connection: close\r\n\r\n"

  return request( host, port, data )
end

-- URL with get request
get_url = function( u )
  local parsed = url.parse( u )
  local port = {}

  port.service = parsed.scheme
  port.number = parsed.port

  if not port.number then
    if parsed.scheme == 'https' then
      port.number = 443
    else
      port.number = 80
    end
  end

  local path = parsed.path or "/"
  if parsed.query then
    path = path .. "?" .. parsed.query
  end

  return get( parsed.host, port, path )
end

-- send http request and return the result as table
-- host may be a table or the hostname
-- port may be a table or the portnumber
request = function( host, port, data )

  if type(host) == 'table' then
    host = ( host.name ~= '' and host.name ) or host.ip
  end

  local protocol = 'tcp'
  if type(port) == 'table' then
    if nmap.have_ssl() and ( port.service == 'https' or ( port.version and port.version.service_tunnel == 'ssl' ) ) then
      protocol = 'ssl'
    end
    port = port.number
  end

  local socket = nmap.new_socket()
  socket:connect( host, port, protocol )
  socket:send( data )

  local buffer = stdnse.make_buffer( socket, "\r?\n" )

  local status, line, result, _
  local header, body = {}, {}
  -- header loop
  while true do
    status, line = buffer()
    if (not status or line == "") then break end
    table.insert(header,line)
  end

  result = {status=nil,header={},body=""}

  -- build nicer table for header
  for key, value in pairs( header ) do
    if key == 1 then
      local code
      _, _, code = string.find( value, "HTTP/%d\.%d (%d+)")
      result.status = tonumber(code)
    else
      _, _, key, value = string.find( value, "(.+): (.*)" )
      if key and value then
        value = value:gsub( '[\r\n]+', '' )
        if result.header[key] then
          result.header[key] = result.header[key] .. ',' .. value
        else
          result.header[key] = value
        end
      end
    end
  end

  -- body loop
  while true do
    status, line = buffer()
    if (not status) then break end
    table.insert(body,line)
  end

  socket:close()
  result.body = table.concat( body )

  return result

end

Attachment: signature.asc
Description: OpenPGP digital signature


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org

Current thread: