code cleanup, removed buffered DB2Socket class and replace with receive_buf

This commit is contained in:
patrik 2012-10-25 19:41:53 +00:00
parent 9cab81511c
commit 165a8c0929

View file

@ -60,6 +60,7 @@
local bin = require "bin"
local bit = require "bit"
local match = require "match"
local nmap = require "nmap"
local stdnse = require "stdnse"
local string = require "string"
@ -120,11 +121,12 @@ SecMec =
DRDAPacket = {
new = function(self, drda_array)
local o = {}
setmetatable(o, self)
self.__index = self
o.drda_array = drda_array
o.count = #drda_array
local o = {
drda_array = drda_array,
count = #drda_array
}
setmetatable(o, self)
self.__index = self
return o
end,
@ -161,11 +163,12 @@ DRDAPacket = {
DRDA = {
new = function(self, ddm)
local o = {}
setmetatable(o, self)
self.__index = self
o.Parameters = {}
o.DDM = ddm
local o = {
Parameters = {},
DDM = ddm
}
setmetatable(o, self)
self.__index = self
return o
end,
@ -256,7 +259,7 @@ DRDA = {
local pos = 1
-- first read atleast enough so that we can populate the DDM
status, data = db2socket:recv( DDM_SIZE )
status, data = db2socket:receive_buf( match.numbytes(DDM_SIZE), true )
if ( not(status) ) then
stdnse.print_debug("drda.DRDA.receive: %s", data)
return false, ("Failed to read at least %d bytes from socket"):format(DDM_SIZE)
@ -266,7 +269,7 @@ DRDA = {
ddm:fromString( data )
self:setDDM( ddm )
status, data = db2socket:recv( ddm.Length - 10 )
status, data = db2socket:receive_buf( match.numbytes(ddm.Length - 10), true )
if ( not(status) ) then
return false, ("Failed to read the remaining %d bytes of the DRDA message")
end
@ -292,16 +295,13 @@ DRDAParameter = {
-- @param data string containing the data portion of the DRDA parameter
-- @return o DRDAParameter object
new = function(self, codepoint, data)
local o = {}
setmetatable(o, self)
self.__index = self
o.CodePoint = codepoint
if ( data ) then
o.Data = data
o.Length = #o.Data + 4
else
o.Length = 4
end
local o = {
CodePoint = codepoint,
Data = data,
Length = ( data and #data + 4 or 4 )
}
setmetatable(o, self)
self.__index = self
return o
end,
@ -378,16 +378,13 @@ DDM = {
-- @param corelid
-- @return DDM object
new = function(self, codepoint, format, corelid)
local o = {}
setmetatable(o, self)
self.__index = self
o.CodePoint = codepoint
if ( format ) then
o.Format = format
end
if ( corelid ) then
o.CorelId = corelid
end
local o = {
CodePoint = codepoint,
Format = format,
CorelId = corelid
}
setmetatable(o, self)
self.__index = self
return o
end,
@ -529,8 +526,8 @@ Helper = {
new = function(self)
local o = {}
setmetatable(o, self)
self.__index = self
setmetatable(o, self)
self.__index = self
return o
end,
@ -541,9 +538,8 @@ Helper = {
-- @return Status (true or false).
-- @return Error code (if status is false).
connect = function( self, host, port )
self.db2socket = DB2Socket:new()
self.comm = Comm:new( self.db2socket )
return self.db2socket:connect(host, port)
self.comm = Comm:new( host, port )
return self.comm:connect()
end,
--- Closes an open connection.
@ -551,7 +547,7 @@ Helper = {
-- @return Status (true or false).
-- @return Error code (if status is false).
close = function( self )
self.db2socket:close()
self.comm:close()
end,
--- Returns Server Information (name, platform, version)
@ -676,14 +672,41 @@ Helper = {
-- The communication class
Comm = {
new = function(self, socket)
local o = {}
setmetatable(o, self)
self.__index = self
o.socket = socket
new = function(self, host, port)
local o = {
host = host,
port = port,
socket = nmap.new_socket()
}
setmetatable(o, self)
self.__index = self
return o
end,
connect = function(self)
return self.socket:connect(self.host, self.port)
end,
close = function(self)
return self.socket:close()
end,
recvDRDA = function( self )
local status, err
local drda_tbl = {}
repeat
local drda = DRDA:new()
status, err = drda:receive( self.socket )
if ( not(status) ) then
return false, err
end
table.insert(drda_tbl, drda)
until ( not(drda.DDM:isChained()) )
return true, drda_tbl
end,
--- Sends a packet to the server and receives the response
--
-- @param DRDAPacket
@ -691,14 +714,14 @@ Comm = {
-- @return packet an instance of DRDAPacket
exchDRDAPacket = function( self, packet )
local drda, err
local status, err = self.socket:sendDRDA( packet )
local status, err = self.socket:send( tostring(packet) )
if ( not(status) ) then
stdnse.print_debug("drda.Helper.login: ERROR: DB2Socket error: %s", err )
return false, ("ERROR: DB2Socket error: %s"):format( err )
end
status, drda = self.socket:recvDRDA()
status, drda = self:recvDRDA()
if( not(status) ) then
stdnse.print_debug("drda.Helper.login: ERROR: DB2Socket error: %s", drda )
return false, ("ERROR: DB2Socket error: %s"):format( drda )
@ -710,117 +733,6 @@ Comm = {
}
-- The DB2Socket class
--
-- Allows for reading an exact count of bytes opposed to the nmap socket
-- implementation that does at least count of bytes.
--
-- The DB2Socket makes use of nmaps underlying socket implementation and
-- buffers the bytes exceeding the number asked for. The next call to the
-- <code>recv</code> function will fetch bytes from the buffer and call
-- the <code>recieve_bytes</code> function of the underlying when there
-- are no more buffered bytes.
--
-- The <code>connect</code>, <code>close</code> and <code>send</code>
-- functions are wrappers around the same functions of the nmap socket code.
-- Consult the nsedoc for additional information on these.
DB2Socket = {
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 Host table, hostname, or IP address.
-- @param port Port table or 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 )
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,
--- Sends a single or multiple DRDA's over the socket
--
-- @param drda a single or a table containing multiple DRDA's
-- @return Status (true or false).
-- @return Error code (if status is false).
sendDRDA = function( self, drda )
return self:send(tostring(drda))
end,
--- Reads a single or multiple DRDA's of the socket
--
-- @return status (true or false)
-- @return drda table containing retrieved DRDA's
recvDRDA = function( self )
local status, err
local drda_tbl = {}
repeat
local drda = DRDA:new()
status, err = drda:receive( self )
if ( not(status) ) then
return false, err
end
table.insert(drda_tbl, drda)
until ( not(drda.DDM:isChained()) )
return true, drda_tbl
end,
}
-- EBCDIC/ASCII Conversion tables
a2e_hex = "00010203372D2E2F1605250B0C0D0E0F101112133C3D322618193F271C1D1E1F"
a2e_hex = a2e_hex .. "405A7F7B5B6C507D4D5D5C4E6B604B61F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F"