mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 12:41:29 +00:00
Replace "buffered socket" classes with socket.receive_buf()
The match library has a helpful function for doing exactly this, with less copy-and-pasted code: http://nmap.org/nsedoc/lib/match.html#numbytes
This commit is contained in:
@@ -13,8 +13,6 @@
|
|||||||
-- o AMQP
|
-- o AMQP
|
||||||
-- - This class contains the core functions needed to communicate with AMQP
|
-- - This class contains the core functions needed to communicate with AMQP
|
||||||
--
|
--
|
||||||
-- o AMQPSocket
|
|
||||||
-- - This is a copy of the VNCSocket class.
|
|
||||||
|
|
||||||
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
|
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
|
||||||
-- @author "Sebastian Dragomir <velorien@gmail.com>"
|
-- @author "Sebastian Dragomir <velorien@gmail.com>"
|
||||||
@@ -24,6 +22,7 @@
|
|||||||
-- Created 05/04/2011 - v0.1 - created by Sebastian Dragomir <velorien@gmail.com>
|
-- Created 05/04/2011 - v0.1 - created by Sebastian Dragomir <velorien@gmail.com>
|
||||||
|
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
|
local match = require "match"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
@@ -52,7 +51,7 @@ AMQP = {
|
|||||||
self.__index = self
|
self.__index = self
|
||||||
o.host = host
|
o.host = host
|
||||||
o.port = port
|
o.port = port
|
||||||
o.amqpsocket = AMQPSocket:new()
|
o.amqpsocket = nmap.new_socket()
|
||||||
o.cli_version = self.client_version_strings[nmap.registry.args['amqp.version']] or self.client_version_strings["0-9-1"]
|
o.cli_version = self.client_version_strings[nmap.registry.args['amqp.version']] or self.client_version_strings["0-9-1"]
|
||||||
o.protover = nil
|
o.protover = nil
|
||||||
o.server_version = nil
|
o.server_version = nil
|
||||||
@@ -88,27 +87,27 @@ AMQP = {
|
|||||||
while read < tsize do
|
while read < tsize do
|
||||||
local key, value
|
local key, value
|
||||||
|
|
||||||
status, tmp = self.amqpsocket:recv( 1 )
|
status, tmp = self.amqpsocket:receive_buf(match.numbytes(1), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading key length", nil
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading key length", nil
|
||||||
end
|
end
|
||||||
read = read + 1
|
read = read + 1
|
||||||
|
|
||||||
tmp = select( 2, bin.unpack("C", tmp) )
|
tmp = select( 2, bin.unpack("C", tmp) )
|
||||||
status, key = self.amqpsocket:recv( tmp )
|
status, key = self.amqpsocket:receive_buf(match.numbytes(tmp), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading key", nil
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading key", nil
|
||||||
end
|
end
|
||||||
read = read + tmp
|
read = read + tmp
|
||||||
|
|
||||||
status, tmp = self.amqpsocket:recv( 1 )
|
status, tmp = self.amqpsocket:receive_buf(match.numbytes(1), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value type for " .. key, nil
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value type for " .. key, nil
|
||||||
end
|
end
|
||||||
read = read + 1
|
read = read + 1
|
||||||
|
|
||||||
if ( tmp == 'F' ) then -- table type
|
if ( tmp == 'F' ) then -- table type
|
||||||
status, tmp = self.amqpsocket:recv( 4 )
|
status, tmp = self.amqpsocket:receive_buf(match.numbytes(4), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading table size", nil
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading table size", nil
|
||||||
end
|
end
|
||||||
@@ -152,14 +151,14 @@ AMQP = {
|
|||||||
-- @return number of bytes read after decoding this value
|
-- @return number of bytes read after decoding this value
|
||||||
decodeString = function(self, key, read)
|
decodeString = function(self, key, read)
|
||||||
local value, status, tmp
|
local value, status, tmp
|
||||||
status, tmp = self.amqpsocket:recv( 4 )
|
status, tmp = self.amqpsocket:receive_buf(match.numbytes(4), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value size for " .. key, nil, 0
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value size for " .. key, nil, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
read = read + 4
|
read = read + 4
|
||||||
tmp = select( 2, bin.unpack(">I", tmp) )
|
tmp = select( 2, bin.unpack(">I", tmp) )
|
||||||
status, value = self.amqpsocket:recv( tmp )
|
status, value = self.amqpsocket:receive_buf(match.numbytes(tmp), true)
|
||||||
|
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value for " .. key, nil, 0
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value for " .. key, nil, 0
|
||||||
@@ -179,7 +178,7 @@ AMQP = {
|
|||||||
-- @return number of bytes read after decoding this value
|
-- @return number of bytes read after decoding this value
|
||||||
decodeBoolean = function(self, key, read)
|
decodeBoolean = function(self, key, read)
|
||||||
local status, value
|
local status, value
|
||||||
status, value = self.amqpsocket:recv( 1 )
|
status, value = self.amqpsocket:receive_buf(match.numbytes(1), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value for " .. key, nil, 0
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading value for " .. key, nil, 0
|
||||||
end
|
end
|
||||||
@@ -204,7 +203,7 @@ AMQP = {
|
|||||||
return false, "ERROR: AMQP:handshake failed while sending client version"
|
return false, "ERROR: AMQP:handshake failed while sending client version"
|
||||||
end
|
end
|
||||||
|
|
||||||
status, tmp = self.amqpsocket:recv( 11 )
|
status, tmp = self.amqpsocket:receive_buf(match.numbytes(11), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading frame header"
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading frame header"
|
||||||
end
|
end
|
||||||
@@ -261,7 +260,7 @@ AMQP = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- parse protocol version
|
-- parse protocol version
|
||||||
status, tmp = self.amqpsocket:recv( 2 )
|
status, tmp = self.amqpsocket:receive_buf(match.num_bytes(2), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading version"
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading version"
|
||||||
end
|
end
|
||||||
@@ -273,7 +272,7 @@ AMQP = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- parse server properties
|
-- parse server properties
|
||||||
status, tmp = self.amqpsocket:recv( 4 )
|
status, tmp = self.amqpsocket:receive_buf(match.numbytes(4), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading server properties size"
|
return status, "ERROR: AMQP:handshake connection closed unexpectedly while reading server properties size"
|
||||||
end
|
end
|
||||||
@@ -332,72 +331,4 @@ AMQP = {
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
AMQPSocket =
|
|
||||||
{
|
|
||||||
retries = 3,
|
|
||||||
|
|
||||||
new = function(self)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Establishes a connection.
|
|
||||||
--
|
|
||||||
-- @param hostid Hostname or IP address.
|
|
||||||
-- @param port Port number.
|
|
||||||
-- @param protocol <code>"tcp"</code>, <code>"udp"</code>, or
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
connect = function( self, hostid, port, protocol )
|
|
||||||
return self.Socket:connect( hostid, port, protocol )
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
self.Buffer = nil
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
return _ENV;
|
return _ENV;
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
-- o Addr - The server address packet
|
-- o Addr - The server address packet
|
||||||
-- o Inv - The server inventory packet
|
-- o Inv - The server inventory packet
|
||||||
--
|
--
|
||||||
-- * BCSocket - A buffering socket class
|
|
||||||
--
|
|
||||||
-- * Helper - The primary interface to scripts
|
-- * Helper - The primary interface to scripts
|
||||||
--
|
--
|
||||||
--@author Patrik Karlsson <patrik@cqure.net>
|
--@author Patrik Karlsson <patrik@cqure.net>
|
||||||
@@ -34,6 +32,7 @@
|
|||||||
|
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
local ipOps = require "ipOps"
|
local ipOps = require "ipOps"
|
||||||
|
local match = require "match"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
local os = require "os"
|
local os = require "os"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
@@ -371,13 +370,13 @@ Response = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
-- Receives the packet and decodes it
|
-- Receives the packet and decodes it
|
||||||
-- @param socket BCSocket instance
|
-- @param socket socket connected to the server
|
||||||
-- @param version number containing the server version
|
-- @param version number containing the server version
|
||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return response instance of response packet if status is true
|
-- @return response instance of response packet if status is true
|
||||||
-- err string containing the error message if status is false
|
-- err string containing the error message if status is false
|
||||||
recvPacket = function(socket, version)
|
recvPacket = function(socket, version)
|
||||||
local status, header = socket:recv(24)
|
local status, header = socket:receive_buf(match.numbytes(24), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return false, "Failed to read the packet header"
|
return false, "Failed to read the packet header"
|
||||||
end
|
end
|
||||||
@@ -387,7 +386,7 @@ Response = {
|
|||||||
|
|
||||||
-- the verack has no payload
|
-- the verack has no payload
|
||||||
if ( 0 ~= len ) then
|
if ( 0 ~= len ) then
|
||||||
status, data = socket:recv(len)
|
status, data = socket:receive_buf(match.numbytes(len), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return false, "Failed to read the packet header"
|
return false, "Failed to read the packet header"
|
||||||
end
|
end
|
||||||
@@ -442,82 +441,6 @@ Util = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- A buffered socket implementation
|
|
||||||
BCSocket =
|
|
||||||
{
|
|
||||||
retries = 3,
|
|
||||||
|
|
||||||
-- Creates a new BCSocket instance
|
|
||||||
-- @param host table as received by the action method
|
|
||||||
-- @param port table as received by the action method
|
|
||||||
-- @param options table containing additional options
|
|
||||||
-- <code>timeout</code> - the socket timeout in ms
|
|
||||||
-- @return instance of BCSocket
|
|
||||||
new = function(self, host, port, options)
|
|
||||||
local o = {
|
|
||||||
host = host,
|
|
||||||
port = port,
|
|
||||||
timeout = "table" == type(options) and options.timeout or 10000
|
|
||||||
}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Establishes a connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
connect = function( self )
|
|
||||||
self.Socket:set_timeout( self.timeout )
|
|
||||||
return self.Socket:connect( self.host, self.port )
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) or #data < count - #self.Buffer ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- The Helper class used as a primary interface to scripts
|
-- The Helper class used as a primary interface to scripts
|
||||||
Helper = {
|
Helper = {
|
||||||
|
|
||||||
@@ -531,7 +454,7 @@ Helper = {
|
|||||||
local o = {
|
local o = {
|
||||||
host = host,
|
host = host,
|
||||||
port = port,
|
port = port,
|
||||||
options = options
|
options = options or {}
|
||||||
}
|
}
|
||||||
setmetatable(o, self)
|
setmetatable(o, self)
|
||||||
self.__index = self
|
self.__index = self
|
||||||
@@ -542,13 +465,14 @@ Helper = {
|
|||||||
-- @return status true on success false on failure
|
-- @return status true on success false on failure
|
||||||
-- @return err string containing the error message in case status is false
|
-- @return err string containing the error message in case status is false
|
||||||
connect = function(self)
|
connect = function(self)
|
||||||
self.socket = BCSocket:new(self.host, self.port, self.options)
|
self.socket = nmap.new_socket()
|
||||||
local status, err = self.socket:connect()
|
self.socket:set_timeout(self.options.timeout or 10000)
|
||||||
|
local status, err = self.socket:connect(self.host, self.port)
|
||||||
|
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return false, err
|
return false, err
|
||||||
end
|
end
|
||||||
status, self.lhost, self.lport = self.socket.Socket:get_info()
|
status, self.lhost, self.lport = self.socket:get_info()
|
||||||
return status, (status and nil or self.lhost)
|
return status, (status and nil or self.lhost)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|||||||
@@ -18,15 +18,11 @@
|
|||||||
--
|
--
|
||||||
-- o Comm
|
-- o Comm
|
||||||
-- - Implements a number of functions to handle communication over the
|
-- - Implements a number of functions to handle communication over the
|
||||||
-- the Socket class.
|
-- the socket.
|
||||||
--
|
--
|
||||||
-- o Helper
|
-- o Helper
|
||||||
-- - A helper class that provides easy access to the rest of the library
|
-- - A helper class that provides easy access to the rest of the library
|
||||||
--
|
--
|
||||||
-- o Socket
|
|
||||||
-- - This is a copy of the DB2Socket class which provides fundamental
|
|
||||||
-- buffering
|
|
||||||
--
|
|
||||||
--
|
--
|
||||||
-- Example
|
-- Example
|
||||||
-- -------
|
-- -------
|
||||||
@@ -58,6 +54,7 @@
|
|||||||
--
|
--
|
||||||
|
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
|
local match = require "match"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
@@ -129,7 +126,7 @@ Packet.GIOP = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return err containing the error message if status is false
|
-- @return err containing the error message if status is false
|
||||||
recv = function( self, socket )
|
recv = function( self, socket )
|
||||||
local status, data = socket:recv( 12 )
|
local status, data = socket:receive_buf(match.numbytes(12), true)
|
||||||
local pos
|
local pos
|
||||||
|
|
||||||
if ( not(status) ) then return false, "Failed to read Packet.GIOP" end
|
if ( not(status) ) then return false, "Failed to read Packet.GIOP" end
|
||||||
@@ -139,7 +136,7 @@ Packet.GIOP = {
|
|||||||
|
|
||||||
pos, self.size = bin.unpack( ( self.byte_order == 0 and ">" or "<") .. "I", data, pos )
|
pos, self.size = bin.unpack( ( self.byte_order == 0 and ">" or "<") .. "I", data, pos )
|
||||||
|
|
||||||
status, data = socket:recv( self.size )
|
status, data = socket:receive_buf(match.numbytes(self.size), true)
|
||||||
if ( not(status) ) then return false, "Failed to read Packet.GIOP" end
|
if ( not(status) ) then return false, "Failed to read Packet.GIOP" end
|
||||||
|
|
||||||
self.data = data
|
self.data = data
|
||||||
@@ -420,80 +417,6 @@ Packet.GIOP.list =
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- A socket implementation that provides fundamental buffering and allows for
|
|
||||||
-- reading of an exact number of bytes, instead of atleast ...
|
|
||||||
Socket =
|
|
||||||
{
|
|
||||||
new = function(self, socket)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = socket or nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
getSrcIp = function( self )
|
|
||||||
local status, lhost, _, _, _ = self.Socket:get_info()
|
|
||||||
if (not(status)) then return false, "Error failed to get socket information" end
|
|
||||||
return true, lhost
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Establishes a connection.
|
|
||||||
--
|
|
||||||
-- @param hostid Hostname or IP address.
|
|
||||||
-- @param port Port number.
|
|
||||||
-- @param protocol <code>"tcp"</code>, <code>"udp"</code>, or
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
connect = function( self, hostid, port, protocol )
|
|
||||||
local status = self.Socket:set_timeout(10000)
|
|
||||||
return self.Socket:connect( hostid, port, protocol )
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) or #data < count - #self.Buffer ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Static class containing various message decoders
|
-- Static class containing various message decoders
|
||||||
MessageDecoder = {
|
MessageDecoder = {
|
||||||
|
|
||||||
@@ -624,7 +547,7 @@ Helper = {
|
|||||||
self.__index = self
|
self.__index = self
|
||||||
o.host = host
|
o.host = host
|
||||||
o.port = port
|
o.port = port
|
||||||
o.socket = Socket:new()
|
o.socket = nmap.new_socket()
|
||||||
return o
|
return o
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -674,14 +597,15 @@ Helper = {
|
|||||||
-- @return true on success, false on failure
|
-- @return true on success, false on failure
|
||||||
-- @return err containing error message when status is false
|
-- @return err containing error message when status is false
|
||||||
Connect = function( self )
|
Connect = function( self )
|
||||||
|
self.socket:set_timeout(10000)
|
||||||
local status, data = self.socket:connect( self.host.ip, self.port.number, "tcp" )
|
local status, data = self.socket:connect( self.host.ip, self.port.number, "tcp" )
|
||||||
if( not(status) ) then return status, data end
|
if( not(status) ) then return status, data end
|
||||||
self.comm = Comm:new( self.socket )
|
self.comm = Comm:new( self.socket )
|
||||||
|
|
||||||
status, self.lhost = self.socket:getSrcIp()
|
status, self.lhost = self.socket:get_info()
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
self.socket:close()
|
self.socket:close()
|
||||||
return false, self.lhost
|
return false, "Error failed to get socket information"
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -23,15 +23,11 @@
|
|||||||
--
|
--
|
||||||
-- o Comm
|
-- o Comm
|
||||||
-- - Implements a number of functions to handle communication over the
|
-- - Implements a number of functions to handle communication over the
|
||||||
-- the Socket class.
|
-- the socket.
|
||||||
--
|
--
|
||||||
-- o Helper
|
-- o Helper
|
||||||
-- - A helper class that provides easy access to the rest of the library
|
-- - A helper class that provides easy access to the rest of the library
|
||||||
--
|
--
|
||||||
-- o Socket
|
|
||||||
-- - This is a copy of the DB2Socket class which provides fundamental
|
|
||||||
-- buffering
|
|
||||||
--
|
|
||||||
-- In addition the library contains the following tables with decoder functions
|
-- In addition the library contains the following tables with decoder functions
|
||||||
--
|
--
|
||||||
-- o MetaDataDecoders
|
-- o MetaDataDecoders
|
||||||
@@ -77,6 +73,7 @@
|
|||||||
|
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
|
local match = require "match"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local table = require "table"
|
local table = require "table"
|
||||||
_ENV = stdnse.module("informix", stdnse.seeall)
|
_ENV = stdnse.module("informix", stdnse.seeall)
|
||||||
@@ -132,76 +129,6 @@ Constants =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
-- A socket implementation that provides fundamental buffering and allows for
|
|
||||||
-- reading of an exact number of bytes, instead of atleast ...
|
|
||||||
Socket =
|
|
||||||
{
|
|
||||||
new = function(self, socket)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = socket or nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
|
|
||||||
--- Establishes a connection.
|
|
||||||
--
|
|
||||||
-- @param hostid Hostname or IP address.
|
|
||||||
-- @param port Port number.
|
|
||||||
-- @param protocol <code>"tcp"</code>, <code>"udp"</code>, or
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
connect = function( self, hostid, port, protocol )
|
|
||||||
-- Some Informix server seem to take a LOT of time to respond?!
|
|
||||||
local status = self.Socket:set_timeout(20000)
|
|
||||||
return self.Socket:connect( hostid, port, protocol )
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) or #data < count - #self.Buffer ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- The ColMetaData class
|
-- The ColMetaData class
|
||||||
ColMetaData = {
|
ColMetaData = {
|
||||||
|
|
||||||
@@ -387,7 +314,7 @@ MessageDecoders = {
|
|||||||
-- @return errmsg, Informix error message or decoding error message if
|
-- @return errmsg, Informix error message or decoding error message if
|
||||||
-- status is false
|
-- status is false
|
||||||
[Constants.Message.SQ_ERR] = function( socket )
|
[Constants.Message.SQ_ERR] = function( socket )
|
||||||
local status, data = socket:recv(8)
|
local status, data = socket:receive_buf(match.numbytes(8), true)
|
||||||
local _, svcerr, oserr, errmsg, str, len, pos
|
local _, svcerr, oserr, errmsg, str, len, pos
|
||||||
|
|
||||||
if( not(status) ) then return false, "Failed to decode error response" end
|
if( not(status) ) then return false, "Failed to decode error response" end
|
||||||
@@ -395,12 +322,12 @@ MessageDecoders = {
|
|||||||
pos, svcerr, oserr, _, len = bin.unpack(">ssss", data )
|
pos, svcerr, oserr, _, len = bin.unpack(">ssss", data )
|
||||||
|
|
||||||
if( len and len > 0 ) then
|
if( len and len > 0 ) then
|
||||||
status, data = socket:recv(len)
|
status, data = socket:receive_buf(match.numbytes(len), true)
|
||||||
if( not(status) ) then return false, "Failed to decode error response" end
|
if( not(status) ) then return false, "Failed to decode error response" end
|
||||||
_, str = bin.unpack("A" .. len, data)
|
_, str = bin.unpack("A" .. len, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
|
|
||||||
errmsg = Constants.ErrorMsg[svcerr]
|
errmsg = Constants.ErrorMsg[svcerr]
|
||||||
if ( errmsg and str ) then
|
if ( errmsg and str ) then
|
||||||
@@ -418,12 +345,12 @@ MessageDecoders = {
|
|||||||
local status, data
|
local status, data
|
||||||
local len, _
|
local len, _
|
||||||
|
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_PROTOCOLS response" end
|
if( not(status) ) then return false, "Failed to decode SQ_PROTOCOLS response" end
|
||||||
_, len = bin.unpack(">S", data )
|
_, len = bin.unpack(">S", data )
|
||||||
|
|
||||||
-- read the remaining data
|
-- read the remaining data
|
||||||
return socket:recv(len + 2)
|
return socket:receive_buf(match.numbytes(len + 2), true)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- Decodes the SQ_EOT message
|
--- Decodes the SQ_EOT message
|
||||||
@@ -439,7 +366,7 @@ MessageDecoders = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return err error message if status is false
|
-- @return err error message if status is false
|
||||||
[Constants.Message.SQ_DONE] = function( socket )
|
[Constants.Message.SQ_DONE] = function( socket )
|
||||||
local status, data = socket:recv(2)
|
local status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
local _, len, tmp
|
local _, len, tmp
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_DONE response" end
|
if( not(status) ) then return false, "Failed to decode SQ_DONE response" end
|
||||||
_, len = bin.unpack(">S", data )
|
_, len = bin.unpack(">S", data )
|
||||||
@@ -447,9 +374,9 @@ MessageDecoders = {
|
|||||||
-- For some *@#! reason the SQ_DONE packet sometimes contains an
|
-- For some *@#! reason the SQ_DONE packet sometimes contains an
|
||||||
-- length exeeding the length of the packet by one. Attempt to
|
-- length exeeding the length of the packet by one. Attempt to
|
||||||
-- detect this and fix.
|
-- detect this and fix.
|
||||||
status, data = socket:recv( len )
|
status, data = socket:receive_buf(match.numbytes(len), true)
|
||||||
_, tmp = bin.unpack(">S", data, len - 2)
|
_, tmp = bin.unpack(">S", data, len - 2)
|
||||||
return socket:recv( (tmp == 0) and 3 or 4 )
|
return socket:receive_buf(match.numbytes((tmp == 0) and 3 or 4), true)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- Decodes the metadata for a result set
|
--- Decodes the metadata for a result set
|
||||||
@@ -458,7 +385,7 @@ MessageDecoders = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return column_meta table containing the metadata
|
-- @return column_meta table containing the metadata
|
||||||
[Constants.Message.SQ_DESCRIBE] = function( socket )
|
[Constants.Message.SQ_DESCRIBE] = function( socket )
|
||||||
local status, data = socket:recv(14)
|
local status, data = socket:receive_buf(match.numbytes(14), true)
|
||||||
local pos, cols, col_type, col_name, col_len, col_md, stmt_id
|
local pos, cols, col_type, col_name, col_len, col_md, stmt_id
|
||||||
local coldesc_len, x
|
local coldesc_len, x
|
||||||
local column_meta = {}
|
local column_meta = {}
|
||||||
@@ -470,33 +397,33 @@ MessageDecoders = {
|
|||||||
if ( cols <= 0 ) then
|
if ( cols <= 0 ) then
|
||||||
-- We can end up here if we executed a CREATE, UPDATE OR INSERT statement
|
-- We can end up here if we executed a CREATE, UPDATE OR INSERT statement
|
||||||
local tmp
|
local tmp
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
||||||
|
|
||||||
pos, tmp = bin.unpack(">S", data)
|
pos, tmp = bin.unpack(">S", data)
|
||||||
|
|
||||||
-- This was the result of a CREATE or UPDATE statement
|
-- This was the result of a CREATE or UPDATE statement
|
||||||
if ( tmp == 0x0f ) then
|
if ( tmp == 0x0f ) then
|
||||||
status, data = socket:recv(26)
|
status, data = socket:receive_buf(match.numbytes(26), true)
|
||||||
-- This was the result of a INSERT statement
|
-- This was the result of a INSERT statement
|
||||||
elseif( tmp == 0x5e ) then
|
elseif( tmp == 0x5e ) then
|
||||||
status, data = socket:recv(46)
|
status, data = socket:receive_buf(match.numbytes(46), true)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
status, data = socket:recv(6)
|
status, data = socket:receive_buf(match.numbytes(6), true)
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
||||||
|
|
||||||
for i=1, cols do
|
for i=1, cols do
|
||||||
|
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
||||||
pos, col_type = bin.unpack("C", data, 2)
|
pos, col_type = bin.unpack("C", data, 2)
|
||||||
|
|
||||||
if ( MetaDataDecoders[col_type] ) then
|
if ( MetaDataDecoders[col_type] ) then
|
||||||
|
|
||||||
status, data = socket:recv(20)
|
status, data = socket:receive_buf(match.numbytes(20), true)
|
||||||
if( not(status) ) then
|
if( not(status) ) then
|
||||||
return false, "Failed to read column meta data"
|
return false, "Failed to read column meta data"
|
||||||
end
|
end
|
||||||
@@ -510,7 +437,7 @@ MessageDecoders = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
if ( i<cols ) then
|
if ( i<cols ) then
|
||||||
status, data = socket:recv(6)
|
status, data = socket:receive_buf(match.numbytes(6), true)
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -518,7 +445,7 @@ MessageDecoders = {
|
|||||||
table.insert( column_meta, col_md )
|
table.insert( column_meta, col_md )
|
||||||
end
|
end
|
||||||
|
|
||||||
status, data = socket:recv( ( coldesc_len % 2 ) == 0 and coldesc_len or coldesc_len + 1 )
|
status, data = socket:receive_buf(match.numbytes(( coldesc_len % 2 ) == 0 and coldesc_len or coldesc_len + 1), true)
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
||||||
pos = 1
|
pos = 1
|
||||||
|
|
||||||
@@ -528,14 +455,14 @@ MessageDecoders = {
|
|||||||
column_meta[i]:setName( col_name )
|
column_meta[i]:setName( col_name )
|
||||||
end
|
end
|
||||||
|
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
if( not(status) ) then return false, "Failed to decode SQ_DESCRIBE response" end
|
||||||
|
|
||||||
pos, data = bin.unpack(">S", data)
|
pos, data = bin.unpack(">S", data)
|
||||||
if( data == Constants.Message.SQ_DONE ) then
|
if( data == Constants.Message.SQ_DONE ) then
|
||||||
status, data = socket:recv(26)
|
status, data = socket:receive_buf(match.numbytes(26), true)
|
||||||
else
|
else
|
||||||
status, data = socket:recv(10)
|
status, data = socket:receive_buf(match.numbytes(10), true)
|
||||||
end
|
end
|
||||||
return true, { metadata = column_meta, stmt_id = stmt_id }
|
return true, { metadata = column_meta, stmt_id = stmt_id }
|
||||||
end,
|
end,
|
||||||
@@ -561,11 +488,11 @@ MessageDecoders = {
|
|||||||
while (true) do
|
while (true) do
|
||||||
local pos = 1
|
local pos = 1
|
||||||
|
|
||||||
status, data = socket:recv(6)
|
status, data = socket:receive_buf(match.numbytes(6), true)
|
||||||
if( not(status) ) then return false, "Failed to read column data" end
|
if( not(status) ) then return false, "Failed to read column data" end
|
||||||
|
|
||||||
local _, total_len = bin.unpack(">I", data, 3)
|
local _, total_len = bin.unpack(">I", data, 3)
|
||||||
status, data = socket:recv( ( total_len % 2 == 0 ) and total_len or total_len + 1)
|
status, data = socket:receive_buf(match.numbytes(( total_len % 2 == 0 ) and total_len or total_len + 1), true)
|
||||||
if( not(status) ) then return false, "Failed to read column data" end
|
if( not(status) ) then return false, "Failed to read column data" end
|
||||||
|
|
||||||
row = {}
|
row = {}
|
||||||
@@ -581,7 +508,7 @@ MessageDecoders = {
|
|||||||
table.insert( row, val )
|
table.insert( row, val )
|
||||||
end
|
end
|
||||||
|
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
|
|
||||||
local _, flags = bin.unpack(">S", data)
|
local _, flags = bin.unpack(">S", data)
|
||||||
|
|
||||||
@@ -598,7 +525,7 @@ MessageDecoders = {
|
|||||||
local status, tmp = socket:send( tostring(Packet.SQ_ID:new( info.id, nil, "continue" ) ) )
|
local status, tmp = socket:send( tostring(Packet.SQ_ID:new( info.id, nil, "continue" ) ) )
|
||||||
local pkt_type
|
local pkt_type
|
||||||
|
|
||||||
status, tmp = socket:recv( 2 )
|
status, tmp = socket:receive_buf(match.numbytes(2), true)
|
||||||
pos, pkt_type = bin.unpack(">S", tmp)
|
pos, pkt_type = bin.unpack(">S", tmp)
|
||||||
|
|
||||||
return MessageDecoders[pkt_type]( socket, info )
|
return MessageDecoders[pkt_type]( socket, info )
|
||||||
@@ -607,12 +534,12 @@ MessageDecoders = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- read the remaining data
|
-- read the remaining data
|
||||||
status, data = socket:recv( 26 )
|
status, data = socket:receive_buf(match.numbytes(26), true)
|
||||||
if( not(status) ) then return false, "Failed to read column data" end
|
if( not(status) ) then return false, "Failed to read column data" end
|
||||||
|
|
||||||
-- signal finnish reading
|
-- signal finnish reading
|
||||||
status, data = socket:send( tostring(Packet.SQ_ID:new( info.id, nil, "end" ) ) )
|
status, data = socket:send( tostring(Packet.SQ_ID:new( info.id, nil, "end" ) ) )
|
||||||
status, data = socket:recv( 2 )
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
|
|
||||||
return true, info
|
return true, info
|
||||||
|
|
||||||
@@ -629,32 +556,32 @@ MessageDecoders = {
|
|||||||
local databases = {}
|
local databases = {}
|
||||||
|
|
||||||
while( true ) do
|
while( true ) do
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
if ( not(status) ) then return false, "Failed to parse SQ_DBLIST response" end
|
if ( not(status) ) then return false, "Failed to parse SQ_DBLIST response" end
|
||||||
|
|
||||||
pos, len = bin.unpack(">S", data)
|
pos, len = bin.unpack(">S", data)
|
||||||
if ( 0 == len ) then break end
|
if ( 0 == len ) then break end
|
||||||
|
|
||||||
status, data = socket:recv(len)
|
status, data = socket:receive_buf(match.numbytes(len), true)
|
||||||
if ( not(status) ) then return false, "Failed to parse SQ_DBLIST response" end
|
if ( not(status) ) then return false, "Failed to parse SQ_DBLIST response" end
|
||||||
|
|
||||||
pos, db = bin.unpack("A" .. len, data )
|
pos, db = bin.unpack("A" .. len, data )
|
||||||
table.insert( databases, db )
|
table.insert( databases, db )
|
||||||
|
|
||||||
if ( len %2 == 1 ) then
|
if ( len %2 == 1 ) then
|
||||||
socket:recv(1)
|
socket:receive_buf(match.numbytes(1), true)
|
||||||
if ( not(status) ) then return false, "Failed to parse SQ_DBLIST response" end
|
if ( not(status) ) then return false, "Failed to parse SQ_DBLIST response" end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- read SQ_EOT
|
-- read SQ_EOT
|
||||||
status, data = socket:recv(2)
|
status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
|
|
||||||
return true, databases
|
return true, databases
|
||||||
end,
|
end,
|
||||||
|
|
||||||
[Constants.Message.SQ_EXIT] = function( socket )
|
[Constants.Message.SQ_EXIT] = function( socket )
|
||||||
local status, data = socket:recv(2)
|
local status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
if ( not(status) ) then return false, "Failed to parse SQ_EXIT response" end
|
if ( not(status) ) then return false, "Failed to parse SQ_EXIT response" end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@@ -1084,12 +1011,12 @@ Packet.Connect = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return err msg if status is false
|
-- @return err msg if status is false
|
||||||
readResponse = function( self, socket )
|
readResponse = function( self, socket )
|
||||||
local status, data = socket:recv( 2 )
|
local status, data = socket:receive_buf(match.numbytes(2), true)
|
||||||
local len, pos, tmp
|
local len, pos, tmp
|
||||||
|
|
||||||
if ( not(status) ) then return false, data end
|
if ( not(status) ) then return false, data end
|
||||||
pos, len = bin.unpack(">S", data)
|
pos, len = bin.unpack(">S", data)
|
||||||
status, data = socket:recv( len - 2 )
|
status, data = socket:receive_buf(match.numbytes(len - 2), true)
|
||||||
if ( not(status) ) then return false, data end
|
if ( not(status) ) then return false, data end
|
||||||
|
|
||||||
pos = 13
|
pos = 13
|
||||||
@@ -1218,7 +1145,7 @@ Comm =
|
|||||||
local status, data = self.socket:send( tostring(packet) )
|
local status, data = self.socket:send( tostring(packet) )
|
||||||
if ( not(status) ) then return false, data end
|
if ( not(status) ) then return false, data end
|
||||||
|
|
||||||
status, data = self.socket:recv( 2 )
|
status, data = self.socket:receive_buf(match.numbytes(2), true)
|
||||||
_, typ = bin.unpack(">S", data)
|
_, typ = bin.unpack(">S", data)
|
||||||
|
|
||||||
if ( MessageDecoders[typ] ) then
|
if ( MessageDecoders[typ] ) then
|
||||||
@@ -1249,7 +1176,7 @@ Helper = {
|
|||||||
self.__index = self
|
self.__index = self
|
||||||
o.host = host
|
o.host = host
|
||||||
o.port = port
|
o.port = port
|
||||||
o.socket = Socket:new()
|
o.socket = nmap.new_socket()
|
||||||
o.instance = instance or "nmap_probe"
|
o.instance = instance or "nmap_probe"
|
||||||
return o
|
return o
|
||||||
end,
|
end,
|
||||||
@@ -1262,6 +1189,8 @@ Helper = {
|
|||||||
local status, data
|
local status, data
|
||||||
local conn, packet
|
local conn, packet
|
||||||
|
|
||||||
|
-- Some Informix server seem to take a LOT of time to respond?!
|
||||||
|
self.socket:set_timeout(20000)
|
||||||
status, data = self.socket:connect( self.host.ip, self.port.number, "tcp" )
|
status, data = self.socket:connect( self.host.ip, self.port.number, "tcp" )
|
||||||
|
|
||||||
if( not(status) ) then
|
if( not(status) ) then
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
-- * <code>Comm</code>
|
-- * <code>Comm</code>
|
||||||
-- ** A class used to send and receive packet between the library and server
|
-- ** A class used to send and receive packet between the library and server
|
||||||
-- ** The class handles some of the packet "counting" and value updating
|
-- ** The class handles some of the packet "counting" and value updating
|
||||||
-- * <code>Socket</code>
|
|
||||||
-- ** A buffered socket class that allows reading of exakt number of bytes
|
|
||||||
-- * <code>KVP</code>
|
-- * <code>KVP</code>
|
||||||
-- ** A key/value pair class that holds key value pairs
|
-- ** A key/value pair class that holds key value pairs
|
||||||
-- * <code>Helper</code>
|
-- * <code>Helper</code>
|
||||||
@@ -39,6 +37,7 @@
|
|||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
local bit = require "bit"
|
local bit = require "bit"
|
||||||
local ipOps = require "ipOps"
|
local ipOps = require "ipOps"
|
||||||
|
local match = require "match"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local openssl = stdnse.silent_require "openssl"
|
local openssl = stdnse.silent_require "openssl"
|
||||||
@@ -202,7 +201,7 @@ Packet = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return resp instance of LoginResponse
|
-- @return resp instance of LoginResponse
|
||||||
fromSocket = function( s )
|
fromSocket = function( s )
|
||||||
local status, header = s:recv(48)
|
local status, header = s:receive_buf(match.numbytes(48), true)
|
||||||
|
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return false, "Failed to read header from socket"
|
return false, "Failed to read header from socket"
|
||||||
@@ -218,7 +217,7 @@ Packet = {
|
|||||||
local pad = ( 4 - ( resp.data_seg_len % 4 ) )
|
local pad = ( 4 - ( resp.data_seg_len % 4 ) )
|
||||||
pad = ( pad == 4 ) and 0 or pad
|
pad = ( pad == 4 ) and 0 or pad
|
||||||
|
|
||||||
local status, data = s:recv( resp.data_seg_len + pad )
|
local status, data = s:receive_buf(match.numbytes(resp.data_seg_len + pad), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return false, "Failed to read data from socket"
|
return false, "Failed to read data from socket"
|
||||||
end
|
end
|
||||||
@@ -308,7 +307,7 @@ Packet = {
|
|||||||
local textdata = ""
|
local textdata = ""
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
local status, header = s:recv(48)
|
local status, header = s:receive_buf(match.numbytes(48), true)
|
||||||
local pos, _, flags, _, _, len = bin.unpack(">CCCCI", header)
|
local pos, _, flags, _, _, len = bin.unpack(">CCCCI", header)
|
||||||
local cont = ( bit.band(flags, 0x40) == 0x40 )
|
local cont = ( bit.band(flags, 0x40) == 0x40 )
|
||||||
|
|
||||||
@@ -316,7 +315,7 @@ Packet = {
|
|||||||
resp.data_seg_len = bit.band(len, 0x00ffffff)
|
resp.data_seg_len = bit.band(len, 0x00ffffff)
|
||||||
|
|
||||||
local data
|
local data
|
||||||
status, data = s:recv( resp.data_seg_len )
|
status, data = s:receive_buf(match.numbytes(resp.data_seg_len), true)
|
||||||
|
|
||||||
textdata = textdata .. data
|
textdata = textdata .. data
|
||||||
|
|
||||||
@@ -415,7 +414,7 @@ Packet = {
|
|||||||
-- err string containing error message
|
-- err string containing error message
|
||||||
fromSocket = function( s )
|
fromSocket = function( s )
|
||||||
local resp = Packet.LogoutResponse:new()
|
local resp = Packet.LogoutResponse:new()
|
||||||
local status, header = s:recv(48)
|
local status, header = s:receive_buf(match.numbytes(48), true)
|
||||||
if ( not(status) ) then return status, header end
|
if ( not(status) ) then return status, header end
|
||||||
return true, resp
|
return true, resp
|
||||||
end
|
end
|
||||||
@@ -469,78 +468,6 @@ Comm = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--- A buffered socket implementation
|
|
||||||
Socket =
|
|
||||||
{
|
|
||||||
|
|
||||||
--- Creates a new instance of Socket
|
|
||||||
--
|
|
||||||
-- @return instance of Socket
|
|
||||||
new = function(self)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
|
|
||||||
--- Establishes a connection.
|
|
||||||
--
|
|
||||||
-- @param hostid Hostname or IP address.
|
|
||||||
-- @param port Port number.
|
|
||||||
-- @param protocol <code>"tcp"</code>, <code>"udp"</code>, or
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
connect = function( self, hostid, port, protocol )
|
|
||||||
self.Socket:set_timeout(10000)
|
|
||||||
return self.Socket:connect( hostid, port, protocol )
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) or #data < count - #self.Buffer ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Key/Value pairs class
|
--- Key/Value pairs class
|
||||||
KVP = {
|
KVP = {
|
||||||
|
|
||||||
@@ -623,7 +550,7 @@ Helper = {
|
|||||||
setmetatable(o, self)
|
setmetatable(o, self)
|
||||||
self.__index = self
|
self.__index = self
|
||||||
o.host, o.port = host, port
|
o.host, o.port = host, port
|
||||||
o.socket = Socket:new()
|
o.socket = nmap.new_socket()
|
||||||
return o
|
return o
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -632,6 +559,7 @@ Helper = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return err string containing error message is status is false
|
-- @return err string containing error message is status is false
|
||||||
connect = function( self )
|
connect = function( self )
|
||||||
|
self.socket:set_timeout(10000)
|
||||||
local status, err = self.socket:connect(self.host, self.port, "tcp")
|
local status, err = self.socket:connect(self.host, self.port, "tcp")
|
||||||
if ( not(status) ) then return false, err end
|
if ( not(status) ) then return false, err end
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
-- - Contains the "native" NCP functions sending the actual request to the
|
-- - Contains the "native" NCP functions sending the actual request to the
|
||||||
-- server.
|
-- server.
|
||||||
--
|
--
|
||||||
-- * Socket
|
|
||||||
-- - A buffered socket implementation
|
|
||||||
--
|
|
||||||
-- * Helper
|
-- * Helper
|
||||||
-- - The prefered script interface to the library containing functions
|
-- - The prefered script interface to the library containing functions
|
||||||
-- that wrap functions from the NCP class using more descriptive names
|
-- that wrap functions from the NCP class using more descriptive names
|
||||||
@@ -56,6 +53,7 @@
|
|||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
local bit = require "bit"
|
local bit = require "bit"
|
||||||
local ipOps = require "ipOps"
|
local ipOps = require "ipOps"
|
||||||
|
local match = require "match"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
@@ -622,7 +620,7 @@ Response = {
|
|||||||
-- @param socket socket connected to server and ready to receive data
|
-- @param socket socket connected to server and ready to receive data
|
||||||
-- @return Response containing a new Response instance
|
-- @return Response containing a new Response instance
|
||||||
fromSocket = function(socket)
|
fromSocket = function(socket)
|
||||||
local status, header = socket:recv(16)
|
local status, header = socket:receive_buf(match.numbytes(16), true)
|
||||||
if ( not(status) ) then return false, "Failed to receive data" end
|
if ( not(status) ) then return false, "Failed to receive data" end
|
||||||
|
|
||||||
local pos, sig, len = bin.unpack(">II", header)
|
local pos, sig, len = bin.unpack(">II", header)
|
||||||
@@ -631,7 +629,7 @@ Response = {
|
|||||||
local data
|
local data
|
||||||
|
|
||||||
if ( 0 < len - 16 ) then
|
if ( 0 < len - 16 ) then
|
||||||
status, data = socket:recv(len - 16)
|
status, data = socket:receive_buf(match.numbytes(len - 16), true)
|
||||||
if ( not(status) ) then return false, "Failed to receive data" end
|
if ( not(status) ) then return false, "Failed to receive data" end
|
||||||
end
|
end
|
||||||
return true, Response:new(header, data)
|
return true, Response:new(header, data)
|
||||||
@@ -977,7 +975,8 @@ Helper = {
|
|||||||
--- Connect the socket and creates a NCP connection
|
--- Connect the socket and creates a NCP connection
|
||||||
-- @return true on success false on failure
|
-- @return true on success false on failure
|
||||||
connect = function(self)
|
connect = function(self)
|
||||||
self.socket = Socket:new()
|
self.socket = nmap.new_socket()
|
||||||
|
self.socket:set_timeout(5000)
|
||||||
local status, err = self.socket:connect(self.host, self.port)
|
local status, err = self.socket:connect(self.host, self.port)
|
||||||
if ( not(status) ) then return status, err end
|
if ( not(status) ) then return status, err end
|
||||||
|
|
||||||
@@ -1077,76 +1076,6 @@ Helper = {
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket =
|
|
||||||
{
|
|
||||||
new = function(self)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sets the socket timeout (@see nmap.set_timeout)
|
|
||||||
-- @param tm number containing the socket timeout in ms
|
|
||||||
set_timeout = function(self, tm) self.Socket:set_timeout(tm) end,
|
|
||||||
|
|
||||||
--- Establishes a connection.
|
|
||||||
--
|
|
||||||
-- @param hostid Hostname or IP address.
|
|
||||||
-- @param port Port number.
|
|
||||||
-- @param protocol <code>"tcp"</code>, <code>"udp"</code>, or
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
connect = function( self, hostid, port, protocol )
|
|
||||||
self.Socket:set_timeout(5000)
|
|
||||||
return self.Socket:connect( hostid, port, protocol )
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) or #data < count - #self.Buffer ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
--- "static" Utility class containing mostly conversion functions
|
--- "static" Utility class containing mostly conversion functions
|
||||||
Util =
|
Util =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,11 +16,6 @@
|
|||||||
-- o Helper
|
-- o Helper
|
||||||
-- - A helper class that provides easy access to the rest of the library
|
-- - A helper class that provides easy access to the rest of the library
|
||||||
--
|
--
|
||||||
-- o DominoSocket
|
|
||||||
-- - This is a copy of the DB2Socket class which provides fundamental
|
|
||||||
-- buffering
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- Example
|
-- Example
|
||||||
-- -------
|
-- -------
|
||||||
-- The following sample code illustrates how scripts can use the Helper class
|
-- The following sample code illustrates how scripts can use the Helper class
|
||||||
@@ -44,6 +39,7 @@
|
|||||||
|
|
||||||
|
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
|
local match = require "match"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
_ENV = stdnse.module("nrpc", stdnse.seeall)
|
_ENV = stdnse.module("nrpc", stdnse.seeall)
|
||||||
@@ -63,16 +59,16 @@ DominoPacket = {
|
|||||||
return o
|
return o
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- Reads a packet from the DominoSocket
|
--- Reads a packet from the socket
|
||||||
--
|
--
|
||||||
-- @param domsock DominoSocket connected to the server
|
-- @param domsock socket connected to the server
|
||||||
-- @return Status (true or false).
|
-- @return Status (true or false).
|
||||||
-- @return Error code (if status is false).
|
-- @return Error code (if status is false).
|
||||||
read = function( self, domsock )
|
read = function( self, domsock )
|
||||||
local status, data = domsock:recv(2)
|
local status, data = domsock:receive_buf(match.numbytes(2), true)
|
||||||
local pos, len = bin.unpack( "<S", data )
|
local pos, len = bin.unpack( "<S", data )
|
||||||
|
|
||||||
return domsock:recv( len )
|
return domsock:receive_buf(match.numbytes(len), true)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--- converts the packet to a string
|
--- converts the packet to a string
|
||||||
@@ -82,73 +78,6 @@ DominoPacket = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DominoSocket =
|
|
||||||
{
|
|
||||||
|
|
||||||
new = function(self)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Establishes a connection.
|
|
||||||
--
|
|
||||||
-- @param hostid Hostname or IP address.
|
|
||||||
-- @param port Port number.
|
|
||||||
-- @param protocol <code>"tcp"</code>, <code>"udp"</code>, or
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
connect = function( self, hostid, port, protocol )
|
|
||||||
self.Socket:set_timeout(5000)
|
|
||||||
return self.Socket:connect( hostid, port, protocol )
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) or #data < count - #self.Buffer ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
--- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper = {
|
Helper = {
|
||||||
|
|
||||||
--- Creates a new Helper instance
|
--- Creates a new Helper instance
|
||||||
@@ -161,7 +90,7 @@ Helper = {
|
|||||||
self.__index = self
|
self.__index = self
|
||||||
o.host = host
|
o.host = host
|
||||||
o.port = port
|
o.port = port
|
||||||
o.domsock = DominoSocket:new()
|
o.domsock = nmap.new_socket()
|
||||||
return o
|
return o
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -170,6 +99,7 @@ Helper = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return err error message if status is false
|
-- @return err error message if status is false
|
||||||
connect = function( self )
|
connect = function( self )
|
||||||
|
self.domsock:set_timeout(5000)
|
||||||
if( not( self.domsock:connect( self.host.ip, self.port.number, "tcp" ) ) ) then
|
if( not( self.domsock:connect( self.host.ip, self.port.number, "tcp" ) ) ) then
|
||||||
return false, ("ERROR: Failed to connect to Domino server %s:%d\n"):format(self.host, self.port)
|
return false, ("ERROR: Failed to connect to Domino server %s:%d\n"):format(self.host, self.port)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
--
|
--
|
||||||
|
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
|
local match = require "match"
|
||||||
local nmap = require "nmap"
|
local nmap = require "nmap"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
@@ -164,82 +165,6 @@ Response = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- A buffered socket implementation
|
|
||||||
Socket =
|
|
||||||
{
|
|
||||||
retries = 3,
|
|
||||||
|
|
||||||
-- Creates a new socket instance
|
|
||||||
-- @param host table containing the host table
|
|
||||||
-- @param port table containing the port table
|
|
||||||
-- @param options table containing options, currenlty supports:
|
|
||||||
-- <code>timeout</code> - socket timeout in ms
|
|
||||||
-- @return o new instance of Socket
|
|
||||||
new = function(self, host, port, options)
|
|
||||||
local o = {
|
|
||||||
host = host,
|
|
||||||
port = port,
|
|
||||||
options = options or {}
|
|
||||||
}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.Socket = nmap.new_socket()
|
|
||||||
o.Buffer = nil
|
|
||||||
return o
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- Connects the socket to the server
|
|
||||||
-- @return status true on success false on failure
|
|
||||||
-- @return err string containing error message on failure
|
|
||||||
connect = function( self )
|
|
||||||
self.Socket:set_timeout(self.options.timeout or 10000)
|
|
||||||
return self.Socket:connect( self.host, self.port )
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- Closes an open connection.
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
close = function( self )
|
|
||||||
return self.Socket:close()
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- Opposed to the <code>socket:receive_bytes</code> function, that returns
|
|
||||||
-- at least x bytes, this function returns the amount of bytes requested.
|
|
||||||
--
|
|
||||||
-- @param count of bytes to read
|
|
||||||
-- @return true on success, false on failure
|
|
||||||
-- @return data containing bytes read from the socket
|
|
||||||
-- err containing error message if status is false
|
|
||||||
recv = function( self, count )
|
|
||||||
local status, data
|
|
||||||
|
|
||||||
self.Buffer = self.Buffer or ""
|
|
||||||
|
|
||||||
if ( #self.Buffer < count ) then
|
|
||||||
status, data = self.Socket:receive_bytes( count - #self.Buffer )
|
|
||||||
if ( not(status) or #data < count - #self.Buffer ) then
|
|
||||||
return false, data
|
|
||||||
end
|
|
||||||
self.Buffer = self.Buffer .. data
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.Buffer:sub( 1, count )
|
|
||||||
self.Buffer = self.Buffer:sub( count + 1)
|
|
||||||
|
|
||||||
return true, data
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- Sends data over the socket
|
|
||||||
--
|
|
||||||
-- @return Status (true or false).
|
|
||||||
-- @return Error code (if status is false).
|
|
||||||
send = function( self, data )
|
|
||||||
return self.Socket:send( data )
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-- The main script interface
|
-- The main script interface
|
||||||
Helper = {
|
Helper = {
|
||||||
|
|
||||||
@@ -250,6 +175,7 @@ Helper = {
|
|||||||
-- <code>timeout</code> - socket timeout in ms
|
-- <code>timeout</code> - socket timeout in ms
|
||||||
-- @return o instance of Helper
|
-- @return o instance of Helper
|
||||||
new = function(self, host, port, options)
|
new = function(self, host, port, options)
|
||||||
|
options = options or {}
|
||||||
local o = { host = host, port = port, options = options }
|
local o = { host = host, port = port, options = options }
|
||||||
setmetatable(o, self)
|
setmetatable(o, self)
|
||||||
self.__index = self
|
self.__index = self
|
||||||
@@ -273,8 +199,9 @@ Helper = {
|
|||||||
-- @return status true on success, false on failure
|
-- @return status true on success, false on failure
|
||||||
-- @return response table containing the respons or err string on failure
|
-- @return response table containing the respons or err string on failure
|
||||||
connect = function(self, auth_method)
|
connect = function(self, auth_method)
|
||||||
self.socket = Socket:new(self.host, self.port, self.options)
|
self.socket = nmap.new_socket()
|
||||||
local status, err = self.socket:connect()
|
self.socket:set_timeout(self.options.timeout or 10000)
|
||||||
|
local status, err = self.socket:connect(self.host, self.port)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
return status, err
|
return status, err
|
||||||
end
|
end
|
||||||
@@ -286,7 +213,7 @@ Helper = {
|
|||||||
return false, "Failed to send connection request to server"
|
return false, "Failed to send connection request to server"
|
||||||
end
|
end
|
||||||
|
|
||||||
local status, data = self.socket:recv(2)
|
local status, data = self.socket:receive_buf(match.numbytes(2), true)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
self.socket:close()
|
self.socket:close()
|
||||||
return false, "Failed to receive connection response from server"
|
return false, "Failed to receive connection response from server"
|
||||||
@@ -332,7 +259,7 @@ Helper = {
|
|||||||
end
|
end
|
||||||
|
|
||||||
if ( 2 == self.auth_method ) then
|
if ( 2 == self.auth_method ) then
|
||||||
local status, data = self.socket:recv(2)
|
local status, data = self.socket:receive_buf(match.numbytes(2), true)
|
||||||
local auth = Response.Authenticate:new(data)
|
local auth = Response.Authenticate:new(data)
|
||||||
|
|
||||||
if ( not(auth) ) then
|
if ( not(auth) ) then
|
||||||
|
|||||||
Reference in New Issue
Block a user