Index: nmap.standalone.lua
===================================================================
--- nmap.standalone.lua (revision 0)
+++ nmap.standalone.lua (working copy)
@@ -0,0 +1,733 @@
+---
+-- Fake nmap module. Designed for running stuff stand-alone
+-- within a separate Lua environment. All nmap related stuff
+-- has been either removed or replaced with Pure Lua-based equivs.
+--
+-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
+
+require 'base'
+local print = print
+local clock = os.clock
+
+module 'nmap'
+
+registry = {}
+registry.args = {}
+
+--- Returns the debugging level as a non-negative integer.
+--
+-- The debugging level can be set with the -d
option.
+-- @return The debugging level.
+-- @usage if nmap.debugging() > 0 then ... end
+function debugging() return 9 end
+
+--- Determines whether Nmap was compiled with SSL support.
+--
+-- This can be used to avoid sending SSL probes when SSL is not available.
+-- @return True if Nmap was compiled with SSL support, false otherwise.
+function have_ssl() return true end
+
+--- Returns the verbosity level as a non-negative integer.
+--
+-- The verbosity level can be set with the -v
option. When
+-- a script is given by name with the --script
option, as
+-- opposed to being selected by default or by category, its verbosity
+-- level is automatically increased by one.
+-- @return The verbosity level.
+-- @usage if nmap.verbosity() > 0 then ... end
+function verbosity() return 9 end
+
+--- Returns whether a script should be able to perform privileged operations
+--
+-- @return True if Nmap is running privileged, false otherwise.
+function is_privileged() return true end
+
+--- Resolves the specified host name using the optional address family and
+-- returns a table containing all of the matching addresses.
+--
+-- If no address family is given, resolve() will return all addresses for the
+-- name.
+--
+-- @param host Host name to resolve
+-- @param family Address family string (such as "inet") to specify the type
+-- of addresses returned
+-- @see address_family
+-- @return Status (true or false)
+-- @return Table containing addresses resolved from the host name if status
+-- is true, or an error string if status is false
+-- @usage local status, t = nmap.resolve("www.kame.net", nmap.address_family())
+function resolve(host, family) print "ERROR: Unimplemented!" end
+
+--- Returns the address family Nmap is using.
+--
+-- For example, if Nmap is run with the -6 option, then "inet6" is returned.
+--
+-- @return The address family as a string ("inet" or "inet6")
+-- @usage local family = nmap.address_family()
+function address_family() return 'inet' end
+
+--- Searches for the specified file and returns a string containing its path if
+-- it is found and readable (to the process).
+--
+-- If the file is not found, not readable, or is a directory, nil
+-- is returned.
+-- @usage
+-- nmap.fetchfile("nmap-rpc") --> "/usr/local/share/nmap/nmap-rpc"
+-- @param filename Filename to search for.
+-- @return String representing the full path to the file or nil
.
+function fetchfile(filename) print "ERROR: Unimplemented!" end
+
+--- Returns the timing level as a non-negative integer.
+--
+-- Possible return values vary from 0
to 5
,
+-- corresponding to the six built-in Nmap timing templates. The timing level
+-- can be set with the -T
option.
+-- @return The timing level.
+function timing_level() return 4 end
+
+--- Gets a port table for a port on a given host.
+--
+-- This function takes a host table and a port table and returns a port table
+-- for the queried port. The port table returned is similar in structure to the
+-- ones passed to the hostrule
, portrule
, and
+-- action
functions. If the given port was not scanned the function
+-- returns nil
.
+--
+-- You can of course reuse the host and port tables passed to a script's rule
+-- function. The purpose of this call is to be able to match scripts against
+-- more than one open port. For example if the target host has an open port 22
+-- and a running identd server, then you can write a script which will only fire
+-- if both ports are open and there is an identification server on port 113.
+-- While it is possible to specify IP addresses different to the currently
+-- scanned target, the result will only be correct if the target is in the
+-- currently scanned group of hosts.
+-- @param host Host table, containing an ip
field.
+-- @param port Port table, containing number
and
+-- protocol
fields.
+-- @return A new port table holding the status and information for the port, or nil
.
+-- @usage p = nmap.get_port_state({ip="127.0.0.1"}, {number="80", protocol="tcp"})
+function get_port_state(host, port) print "ERROR: Unimplemented!" end
+
+--- Iterates over port tables matching protocol and state for a given host
+--
+-- This function takes a host table, previous port table, port protocol and
+-- port state to return matching port tables on a host.
+--
+-- The first time you call this function, pass nil
for the port
+-- parameter to get the first matching port table. From then on, pass the
+-- previous port table returned by this function to the port parameter for the
+-- next matching port table.
+--
+-- @param host Host table, containing an ip
field
+-- @param port Port table, containing a number
field; or nil
+-- for first port
+-- @param proto Port protocol, such as "tcp"
+-- @param state Port state, such as "open"
+-- @return Next port table for host, or nil
when exhausted
+-- @usage port = nmap.get_ports(host, port, "tcp", "open")
+function get_ports(host, port, proto, state) print "ERROR: Unimplemented!" end
+
+--- Sets the state of a port on a given host.
+--
+-- Using this function, the final port state, reflected in Nmap's results, can
+-- be changed for a target. This is useful when Nmap detects a port as
+-- open|filtered
, but the script successfully connects to that
+-- port. In this case, the script can set the port state to open
.
+-- This function doesn't change the original port table passed a script's
+-- action function.
+-- @param host Host table, containing an ip
field.
+-- @param port Port table, containing number
and
+-- protocol
fields.
+-- @param state Port state, like "open"
or "closed"
.
+function set_port_state(host, port, state) end
+
+--- Sets version information on a port.
+--
+-- NSE scripts are sometimes able to determine the service name and application
+-- version listening on a port. A whole script category (version
)
+-- was designed for this purpose. This function is used to record version
+-- information when it is discovered.
+--
+-- The host and port arguments to this function should either be the tables
+-- passed to the action method or they should have the same structure. The port
+-- argument specifies the port to operate on through its number
+-- and protocol
fields. and also contains the new version
+-- information to set. The version detection fields this function looks at are
+-- name
, product
, version
,
+-- extrainfo
, hostname
, ostype
,
+-- devicetype
, and service_tunnel
. All these keys are
+-- optional.
+--
+-- The probestate
argument describes the state in which the script
+-- completed. It is a string, one of: "hardmatched"
,
+-- "softmatched"
, "nomatch"
,
+-- "tcpwrapped"
, or "incomplete"
.
+-- "hardmatched"
is almost always used (and is the default),
+-- as it signifies a
+-- successful match. The other possible states are generally only used for
+-- standard version detection rather than the NSE enhancement.
+-- @param host Host table, containing an ip
field.
+-- @param port Port table, containing number
and
+-- protocol
fields, as well as any additional version information
+-- fields.
+-- @param probestate The state of the probe: "hardmatched"
,
+-- "softmatched"
, "nomatch"
,
+-- "tcpwrapped"
, or "incomplete"
.
+function set_port_version(host, port, probestate) end
+
+--- Returns the current date and time in seconds.
+-- @return The number of seconds since the epoch (on most systems this is
+-- 01/01/1970) as a floating point value.
+-- @usage local now = nmap.clock()
+clock = clock
+
+--- Returns the current date and time in milliseconds.
+-- @return The number of milliseconds since the epoch (on most systems this is
+-- 01/01/1970).
+-- @usage local now = nmap.clock_ms()
+function clock_ms() return clock() * 1000 end
+
+--- Gets the link-level hardware type of an interface.
+--
+-- This function takes a dnet-style interface name and returns a string
+-- representing the hardware type of the interface. Possible return values are
+-- "ethernet"
, "loopback"
, "p2p"
, or
+-- nil
if none of the other types apply.
+-- @param interface_name The name of the interface.
+-- @return "ethernet"
, "loopback"
,
+-- "p2p"
, or nil
.
+-- @usage iface_type = nmap.get_interface_link("eth0")
+function get_interface_link(interface_name) return "ethernet" end
+
+--- Create a mutex on an object.
+--
+-- This function returns another function that works as a mutex on the object
+-- passed. This object can be any Lua data type except nil
,
+-- Booleans, and Numbers. The Mutex (the returned function) allows you to lock,
+-- try to lock, and release the mutex. The Mutex function takes only one
+-- argument, which must be one of
+-- * "lock"
: makes a blocking lock on the mutex. If the mutex is busy then the thread will yield and wait. The function returns with the mutex locked.
+-- * "trylock"
: makes a non-blocking lock on the mutex. If the mutex is busy then it immediately returns a false value. Otherwise, the mutex locks the mutex and returns true.
+-- * "done"
: releases the mutex and allows another thread to lock it. If the thread does not have a lock on the mutex, an error will be raised.
+-- * "running"
: returns the thread locked on the mutex or nil
if no thread is locked. This should only be used for debugging as it interferes with finished threads from being collected.
+--
+-- NSE maintains a weak reference to the Mutex function so other calls to
+-- nmap.mutex with the same object will return the same function (Mutex);
+-- however, if you discard your reference to the Mutex then it may be collected
+-- and subsequent calls to nmap.mutex with the object will return a different
+-- Mutex!
+-- @param object Object to create a mutex for.
+-- @return Mutex function which takes one of the following arguments:
+-- "lock"
, "trylock"
, "done"
, or
+-- "running"
.
+-- @usage
+-- id = "My Script's Unique ID"
+--
+-- local mutex = nmap.mutex(id)
+-- function action(host, port)
+-- mutex "lock"
+-- -- do stuff
+-- mutex "done"
+-- return script_output
+-- end
+function mutex(object) print "ERROR: Unimplemented!" end
+
+--- Create a condition variable for an object.
+--
+-- This function returns a function that works as a Condition Variable for the
+-- given object parameter. The object can be any Lua data type except
+-- nil
, Booleans, and Numbers. The Condition Variable (returned
+-- function) allows you wait, signal, and broadcast on the condition variable.
+-- The Condition Variable function takes only one argument, which must be one of
+-- * "wait"
: Wait on the condition variable until another thread wakes us.
+-- * "signal"
: Wake up a single thread from the waiting set of threads for this condition variable.
+-- * "broadcast"
: Wake up all threads in the waiting set of threads for this condition variable.
+--
+-- NSE maintains a weak reference to the Condition Variable so other calls to
+-- nmap.condvar with the same object will return the same function (Condition
+-- Variable); however, if you discard your reference to the Condition
+-- Variable then it may be collected; and, subsequent calls to nmap.condvar with
+-- the object will return a different Condition Variable function!
+--
+-- In NSE, Condition Variables are typically used to coordinate with threads
+-- created using the stdnse.new_thread facility. The worker threads must
+-- wait until work is available that the master thread (the actual running
+-- script) will provide. Once work is created, the master thread will awaken
+-- one or more workers so that the work can be done.
+--
+-- It is important to check the predicate (the test to see if your worker
+-- thread should "wait" or not) BEFORE and AFTER the call to wait. You are
+-- not guaranteed spurious wakeups will not occur (that is, there is no
+-- guarantee your thread will not be awakened when no thread called
+-- "signal"
or "broadcast"
on the condition variable).
+-- One important check for your worker threads, before and after waiting,
+-- should be to check that the master script thread is still alive.
+-- (To check that the master script thread is alive, obtain the "base" thread
+-- using stdnse.base and use coroutine.status). You do not want your worker
+-- threads to continue when the script has ended for reasons unknown to your
+-- worker thread. You are guaranteed that all threads waiting on a
+-- condition variable will be awakened if any thread that has accessed
+-- the condition variable via nmap.condvar
ends for any
+-- reason. This is essential to prevent deadlock with threads
+-- waiting for another thread to awaken
+-- them that has ended unexpectedly.
+-- @see stdnse.new_thread
+-- @see stdnse.base
+-- @param object Object to create a condition variable for.
+-- @return ConditionVariable Condition variable function.
+-- @usage
+-- local myobject = {}
+-- local cv = nmap.condvar(myobject)
+-- cv "wait" -- waits until another thread calls cv "signal"
+function condvar(object) print "ERROR: Unimplemented!" end
+
+--- Creates a new exception handler.
+--
+-- This function returns an exception handler function. The exception handler is
+-- meant to be wrapped around other function calls that may raise an exception.
+-- A function raises an exception by making its first return value false and its
+-- second return value a message describing the error. When an exception occurs,
+-- the exception handler optionally calls a user-provided cleanup function, then
+-- terminates the script. When an exception does not occur (the wrapped
+-- function's first return value is true), the exception handler strips off the
+-- first return value and returns the rest.
+--
+-- The optional cleanup function is passed as the sole argument to
+-- new_try
. It can be used to release sockets or other resources
+-- before the script terminates.
+--
+-- A function that may raise an exception must follow the return protocol
+-- understood by this function: on an exception its return values are
+-- false
or nil
followed by an error message; on
+-- success its return values are any true value followed by any other results.
+-- @param handler User cleanup function (optional).
+-- @usage
+-- local result, socket, try, catch
+--
+-- result = ""
+-- socket = nmap.new_socket()
+-- catch = function()
+-- socket:close()
+-- end
+-- try = nmap.new_try(catch)
+-- try(socket:connect(host, port))
+-- result = try(socket:receive_lines(1))
+-- try(socket:send(result))
+function new_try(handler) print "ERROR: Unimplemented!" end
+
+--- Returns a new NSE socket object.
+--
+-- To allow for efficient and parallelizable network I/O, NSE provides an
+-- interface to Nsock, the Nmap socket library. The smart callback mechanism
+-- Nsock uses is fully transparent to NSE scripts. The main benefit of NSE's
+-- sockets is that they never block on I/O operations, allowing many scripts to
+-- be run in parallel. The I/O parallelism is fully transparent to authors of
+-- NSE scripts. In NSE you can either program as if you were using a single
+-- non-blocking socket or you can program as if your connection is blocking.
+-- Seemingly blocking I/O calls still return once a specified timeout has been
+-- exceeded.
+--
+-- NSE sockets are the recommended way to do network I/O. They support
+-- connect
-style sending and receiving over TCP and UDP (and SSL),
+-- as well as raw socket receiving.
+-- @param protocol a protocol string (optional, defaults to "tcp"
).
+-- @param af an address family string (optional, defaults to "inet"
).
+-- @return A new NSE socket.
+-- @see pcap_open
+-- @usage local socket = nmap.new_socket()
+function new_socket(protocol, af) print "ERROR: Unimplemented!" end
+
+--- Sets the local address of a socket.
+--
+-- This socket method sets the local address and port of a socket. It must be
+-- called before connect
. The address set by bind
+-- overrides Nmap's source address and port set by the -S
and
+-- -g
options.
+-- @param addr Address string or nil
(optional).
+-- @param port Port number or nil
(optional).
+-- @return Status (true or false).
+-- @return Error string (if status is false).
+-- @usage
+-- try = nmap.new_try()
+-- try(socket:bind(nil, 53))
+-- try(socket:bind("1.2.3.4"))
+-- try(socket:bind("2001:db8::1"))
+-- try(socket:bind("1.2.3.4", 53))
+function bind(addr, port) print "ERROR: Unimplemented!" end
+
+--- Establishes a connection.
+--
+-- This method puts a socket in a state ready for communication. It takes as
+-- arguments a host descriptor (a host table, IP address, or hostname), a port
+-- descriptor (a port table or number), and optionally a protocol. If given, the
+-- protocol must be one of "tcp"
, "udp"
or
+-- "ssl"
. The default value for the protocol is
+-- port.protocol
if port
is a port table, otherwise
+-- "tcp"
.
+--
+-- If host
is a host table, it must contain at least one of the
+-- keys addr
or targetname
. If targetname
+-- is given, it is used to request the correct certificate in SSL connections.
+-- Passing a string instead of a host table acts like host.addr
and
+-- host.targetname
were set to the same value. If port
+-- is a table, it must contain the number
key.
+--
+-- On success the function returns a true value. On failure it returns a false
+-- value (false
or nil
) and an error string. Those
+-- strings are taken from the gai_strerror
C function. They are
+-- (with the error code in parentheses):
+-- * "Address family for hostname not supported"
(EAI_ADDRFAMILY
)
+-- * "Temporary failure in name resolution"
(EAI_AGAIN
)
+-- * "Bad value for ai_flags"
(EAI_BADFLAGS
)
+-- * "Non-recoverable failure in name resolution"
(EAI_FAIL
)
+-- * "ai_family not supported"
(EAI_FAMILY
)
+-- * "Memory allocation failure"
(EAI_MEMORY
)
+-- * "No address associated with hostname"
(EAI_NODATA
)
+-- * "Name or service not known"
(EAI_NONAME
)
+-- * "Servname not supported for ai_socktype"
(EAI_SERVICE
)
+-- * "ai_socktype not supported"
(EAI_SOCKTYPE
)
+-- * "System error"
(EAI_SYSTEM
)
+-- In addition to these standard system error messages there are two
+-- NSE-specific errors:
+-- * "Sorry, you don't have OpenSSL"
: The protocol is "ssl"
but Nmap was compiled without OpenSSL support.
+-- * "invalid connection method"
: The second parameter is not one of "tcp"
, "udp"
, and "ssl"
.
+-- @param host Host table, hostname or IP address.
+-- @param port Port table or number.
+-- @param protocol "tcp"
, "udp"
, or
+-- "ssl"
(default "tcp"
, or whatever was set in
+-- new_socket
).
+-- @return Status (true or false).
+-- @return Error code (if status is false).
+-- @see new_socket
+-- @usage
+-- local status, err = socket:connect(host, port)
+-- if not status then
+-- return string.format("Can't connect: %s", err)
+-- end
+function connect(host, port, protocol) print "ERROR: Unimplemented!" end
+
+--- Reconnect the open (connected) socket with SSL.
+--
+-- It is sometimes desirable to request SSL over an established connection.
+-- The internal buffers for the socket are cleared when the reconnection is
+-- made. Any received data that has not yet been read through a call to receive
+-- is lost.
+-- @usage
+-- local status, err = socket:reconnect_ssl()
+-- if not status then
+-- return string.format("Can't reconnect with ssl: %s", err)
+-- end
+function reconnect_ssl() print "ERROR: Unimplemented!" end
+
+--- Sends data on an open socket.
+--
+-- This socket method sends the data contained in the data string through an
+-- open connection. On success the function returns a true value. If the send
+-- operation fails, the function returns a false value (false
or
+-- nil
) along with an error string. The error strings are
+-- * "Trying to send through a closed socket"
: There was no call to socket:connect
before the send operation.
+-- * "TIMEOUT"
: The operation took longer than the specified timeout for the socket.
+-- * "ERROR"
: An error occurred inside the underlying Nsock library.
+-- * "CANCELLED"
: The operation was cancelled.
+-- * "KILL"
: For example the script scan is aborted due to a faulty script.
+-- * "EOF"
: An EOF was read (probably will not occur for a send operation).
+-- @param data The data to send.
+-- @return Status (true or false).
+-- @return Error code (if status is false).
+-- @see new_socket
+-- @usage local status, err = socket:send(data)
+function send(data) print "ERROR: Unimplemented!" end
+
+--- Sends data on an unconnected socket to a given destination.
+--
+-- Sockets that have not been connected do not have an implicit
+-- destination address, so the send
function doesn't work. Instead
+-- the destination must be given with each send using this function. The
+-- protocol and address family of the socket must have been set in
+-- new_socket
. On
+-- success the function returns a true value. If the send operation fails, the
+-- function returns a false value (false
or nil
) along
+-- with an error string. The error strings are
+-- * "Trying to send through a closed socket"
: There was no call to socket:connect
before the send operation.
+-- * "TIMEOUT"
: The operation took longer than the specified timeout for the socket.
+-- * "ERROR"
: An error occurred inside the underlying Nsock library.
+-- * "CANCELLED"
: The operation was cancelled.
+-- * "KILL"
: For example the script scan is aborted due to a faulty script.
+-- * "EOF"
: An EOF was read (probably will not occur for a send operation).
+-- @param host The hostname or IP address to send to.
+-- @param port The port number to send to.
+-- @param data The data to send.
+-- @return Status (true or false).
+-- @return Error code (if status is false).
+-- @usage local status, err = socket:send(data)
+function sendto(host, port, data) print "ERROR: Unimplemented!" end
+
+--- Receives data from an open socket.
+--
+-- The receive method does a non-blocking receive operation on an open socket.
+-- On success the function returns true along with the received data. On
+-- failure the function returns a false value (false
or
+-- nil
) along with an error string. A failure occurs for example if
+-- receive
is called on a closed socket. The receive call returns
+-- to the NSE script all the data currently stored in the receive buffer of the
+-- socket. Error conditions are the same as for send
.
+-- @return Status (true or false).
+-- @return Data (if status is true) or error string (if status is false).
+-- @see new_socket
+-- @usage local status, data = socket:receive()
+function receive() print "ERROR: Unimplemented!" end
+
+--- Receives lines from an open connection.
+--
+-- Tries to receive at least n
lines from an open connection. A
+-- line is a string delimited with \n
characters. If no data was
+-- was received before the operation times out a "TIMEOUT"
error
+-- occurs. If even one character was received then it is returned with success.
+-- On the other hand, if more than n
lines were received, all are
+-- returned, not just n
. Use stdnse.make_buffer
to
+-- guarantee only one line is returned per call.
+--
+-- The return values and error codes are the same as for send
.
+-- @param n Minimum number of lines to read.
+-- @return Status (true or false).
+-- @return Data (if status is true) or error string (if status is false).
+-- @see new_socket
+-- @usage local status, lines = socket:receive_lines(1)
+function receive_lines(n) print "ERROR: Unimplemented!" end
+
+--- Receives bytes from an open connection.
+--
+-- Tries to receive at least n
bytes from an open connection. Like
+-- in receive_lines
, n
is the minimum amount of
+-- characters we would like to receive. If more arrive, we get all of them. If
+-- even one is received then it is returned. If no characters arrive before the
+-- operation times out, a "TIMEOUT"
error occurs.
+--
+-- The return values and error codes are the same as for send
.
+-- @param n Minimum number of bytes to read.
+-- @return Status (true or false).
+-- @return Data (if status is true) or error string (if status is false).
+-- @see new_socket
+-- @usage local status, bytes = socket:receive_bytes(1)
+function receive_bytes(n) print "ERROR: Unimplemented!" end
+
+--- Reads from a socket using a buffer and an arbitrary delimiter.
+--
+-- This method reads data from the network until it encounters the given
+-- delimiter string (or matches the function passed in). This function
+-- continues to read from the network until the delimiter is found or the
+-- function times out. If data is read beyond the delimiter, that data is
+-- saved in a buffer for the next call to receive_buf
.
+--
+-- The first argument may be either a pattern or a function. If a pattern, that
+-- pattern is used to separate the data. If a function, it must take exactly
+-- one parameter (the buffer) and its return values must be in the same format
+-- as those of string.find
(offsets to the start and the end of
+-- the delimiter inside the buffer, or nil
if the delimiter is not
+-- found). The nselib match.lua
module provides functions for
+-- matching against regular expressions or byte counts. These functions are
+-- suitable as arguments to receive_buf
.
+--
+-- The second argument to receive_buf
is a Boolean value
+-- controlling whether the delimiting string is returned along with the
+-- received data (true) or discarded (false).
+--
+-- On success the function returns true along with the received data. On failure
+-- the function returns false
or nil
along with an
+-- receive error string. This function may also throw errors for incorrect usage.
+-- @param delimiter A Lua pattern or a function with return values like those of
+-- string.find
.
+-- @param keeppattern Whether to return the delimiter string with any returned
+-- data.
+-- @return Status (true or false).
+-- @return Data (if status is true) or error string (if status is false).
+-- @see new_socket
+-- @usage local status, line = socket:receive_buf("\r?\n", false)
+function receive_buf(delimiter, keeppattern) print "ERROR: Unimplemented!" end
+
+--- Closes an open connection.
+--
+-- On success the function returns true. If the close fails, the function
+-- returns false
or nil
and an error string. Currently
+-- the only error message is "Trying to close a closed socket"
,
+-- which is issued if the socket has already been closed.
+--
+-- Sockets are subject to garbage collection. Should you forget to close a
+-- socket, it will get closed before it gets deleted (on the next occasion Lua's
+-- garbage collector is run). However since garbage collection cycles are
+-- difficult to predict, it is considered good practice to close opened sockets.
+-- @return Status (true or false).
+-- @return Error code (if status is false).
+-- @see new_socket
+-- @usage socket:close()
+function close() end
+
+--- Gets information about a socket.
+--
+-- This function returns information about a socket object. It returns five
+-- values. If an error occurred, the first value is false
or
+-- nil
and the second value is an error string. Otherwise the first
+-- value is true and the remaining 4 values describe both endpoints of the TCP
+-- connection. If you put the call inside an exception handler created by
+-- new_try
the status value is consumed. The call can be used for
+-- example if you want to query an authentication server.
+-- @return Status (true or false).
+-- @return Local IP address (if status is true) or error string (if status is
+-- false).
+-- @return Local port number (if status is true).
+-- @return Remote IP address (if status is true).
+-- @return Remote port number (if status is true).
+-- @see new_socket
+-- @usage local status, lhost, lport, rhost, rport = socket:get_info()
+function get_info() print "ERROR: Unimplemented!" end
+
+--- Sets a timeout for socket input and output operations.
+--
+-- After this time, given in milliseconds, socket operations will time out and
+-- return. The default value is 30,000 (30 seconds). The lowest allowed value is
+-- 10 ms, since this is the granularity of NSE network I/O.
+-- @param t Timeout in milliseconds.
+-- @see new_socket
+-- @usage socket:set_timeout(10000)
+function set_timeout(t) end
+
+--- Opens a socket for raw packet capture.
+--
+-- @param device The dnet-style interface name of the device you want to capture
+-- from.
+-- @param snaplen The length of each packet you want to capture (similar to the
+-- -s
option to tcpdump)
+-- @param promisc Boolean value for whether the interface should activate
+-- promiscuous mode.
+-- @param bpf A string describing a Berkeley Packet Filter expression (like
+-- those provided to tcpdump).
+-- @see new_socket, pcap_receive
+-- @usage
+-- local socket = nmap.new_socket()
+-- socket:pcap_open("eth0", 64, false, "tcp")
+function pcap_open(device, snaplen, promisc, bpf) print "ERROR: Unimplemented!" end
+
+--- Receives a captured packet.
+--
+-- If an error or timeout occurs, the function returns false and an error
+-- message. Otherwise, the function returns true followed by the packet length,
+-- layer two header, layer three header and packet capture time.
+-- @return Status (true or false).
+-- @return The length of the captured packet (this may be smaller than the
+-- actual packet length since packets are truncated when the
+-- libpcap snaplen parameter is smaller than the total packet length).
+-- @return Data from the second OSI layer (e.g. ethernet headers).
+-- @return Data from the third OSI layer (e.g. IPv4 headers).
+-- @return Packet capture time, as floating point seconds since the epoch
+-- @see pcap_open
+-- @usage status, plen, l2_data, l3_data, time = socket:pcap_receive()
+function pcap_receive() print "ERROR: Unimplemented!" end
+
+--- Closes a pcap device.
+-- @see close, pcap_close
+-- @usage socket:pcap_close()
+function pcap_close() print "ERROR: Unimplemented!" end
+
+---
+-- Retrieves the SSL certificate of the peer. The returned value can be accessed
+-- like a table and has the following members:
+--
+--
+-- subject = { commonName = "...", countryName = "...",
+-- { "2", "5", "4", "15" } = "...", ... },
+-- issuer = { commonName = "...", ... },
+-- pubkey = { type = "rsa", bits = 1024 },
+-- validity = { notBefore = { year = 2020, month = 5, day = 5,
+-- hour = 0, min = 0, sec = 0 },
+-- notAfter = { year = 2021, month = 5, day = 5,
+-- hour = 0, min = 0, sec = 0 } },
+-- pem = "-----BEGIN CERTIFICATE-----\nMIIFxzCCBK+gAwIBAgIQX02QuADDB7CVj..."
+--
+--
+-- It also has the following member functions:
+--
+-- * digest(algorithm)
returns the digest of the certificate using the given digest algorithm, which is any of the strings returned by openssl.supported_digests
, typicaly something like "md5"
or "sha1"
.
+--
+-- The "subject"
and "issuer"
fields hold each
+-- distinguished name. Fields with an unknown OID are represented as an array
+-- whose elements are the numeric components of the OID, encoded as strings.
+--
+-- The "validity"
table has the members "notBefore"
+-- and "notAfter"
. Each of these is a table as returned by
+-- os.date("!*t")
if the date in the certificate could be parsed,
+-- except that they lack the "wday"
and "yday"
+-- members. If the date could not be parsed, the value will be a string
+-- containing the raw byte values of the field. If absent, the value will be
+-- nil
.
+--
+-- The "pem"
field contains a PEM-encoded string of the entire
+-- contents of the certificate.
+-- @return A table as described above.
+-- @usage
+-- local s = nmap.new_socket()
+-- local status, error = s:connect(host, port, "ssl")
+-- if status then
+-- local cert = s:get_ssl_certificate()
+-- local digest = cert:digest("md5")
+-- end
+function get_ssl_certificate() print "ERROR: Unimplemented!" end
+
+--- Creates a new dnet object, used to send raw packets.
+-- @usage local dnet = nmap.new_dnet()
+function new_dnet() print "ERROR: Unimplemented!" end
+
+--- Opens an ethernet interface for raw packet sending.
+--
+-- An error ("device is not valid ethernet interface"
) is thrown
+-- in case the provided argument is not valid.
+-- @param interface_name The dnet-style name of the interface to open.
+-- @see new_dnet
+-- @usage dnet:ethernet_open("eth0")
+function ethernet_open(interface_name) print "ERROR: Unimplemented!" end
+
+--- Sends a raw ethernet frame.
+--
+-- The dnet object must be associated with a previously opened interface. The
+-- packet must include the IP and ethernet headers. If there was no previous
+-- valid call to ethernet_open
an error is thrown
+-- ("dnet is not valid opened ethernet interface"
).
+-- @param packet An ethernet frame to send.
+-- @see new_dnet
+-- @usage dnet:ethernet_send(packet)
+function ethernet_send(packet) print "ERROR: Unimplemented!" end
+
+--- Closes an ethernet interface.
+--
+-- An error ("device is not valid ethernet interface"
) is thrown
+-- in case the provided argument is not valid.
+-- @see new_dnet, ethernet_open
+-- @usage dnet:ethernet_close()
+function ethernet_close() end
+
+--- Opens a socket for raw IPv4 packet sending.
+-- @see new_dnet
+-- @usage dnet:ip_open()
+function ip_open() print "ERROR: Unimplemented!" end
+
+--- Sends a raw IPv4 packet.
+--
+-- The dnet object must be associated with a previously opened socket. The
+-- packet must begin with an IP header. If there was no previous valid call
+-- to ip_open
an error is thrown.
+-- @param packet An IP packet to send.
+-- @see new_dnet
+-- @usage dnet:ip_send(packet)
+function ip_send(packet) print "ERROR: Unimplemented!" end
+
+--- Closes a raw IPv4 socket.
+-- @see new_dnet, ip_open
+-- @usage dnet:ip_close()
+function ip_close() print "ERROR: Unimplemented!" end
+
+--- Writes to a log file.
+--
+-- Writes string
to file
("stdout" or "stderr").
+-- Use stdnse.print_debug to print debug information based on the
+-- debugging level.
+-- @see stdnse.print_debug
+function log_write(file, string) print(string) end
Index: stdnse.lua
===================================================================
--- stdnse.lua (revision 29646)
+++ stdnse.lua (working copy)
@@ -55,9 +55,9 @@
_ENV.sleep = nmap.socket.sleep;
---
--- Prints a formatted debug message if the current debugging level is greater
+-- Prints a formatted debug message if the current verbosity level is greater
-- than or equal to a given level.
---
+--
-- This is a convenience wrapper around
-- nmap.log_write
. The first optional numeric
-- argument, level
, is used as the debugging level necessary
@@ -75,30 +75,8 @@
end
end
----
--- Prints a formatted verbosity message if the current verbosity level is greater
--- than or equal to a given level.
---
--- This is a convenience wrapper around
--- nmap.log_write
. The first optional numeric
--- argument, level
, is used as the verbosity level necessary
--- to print the message (it defaults to 1 if omitted). All remaining arguments
--- are processed with Lua's string.format
function.
--- @param level Optional verbosity level.
--- @param fmt Format string.
--- @param ... Arguments to format.
-print_verbose = function(level, fmt, ...)
- local l, d = tonumber(level), nmap.verbosity();
- if l and l <= d then
- nmap.log_write("stdout", format(fmt, ...));
- elseif not l and 1 <= d then
- nmap.log_write("stdout", format(level, fmt, ...));
- end
-end
-
-
--- Join a list of strings with a separator string.
---
+--
-- This is Lua's table.concat
function with the parameters
-- swapped for coherence.
-- @usage
@@ -109,7 +87,7 @@
-- @return Concatenated string.
function strjoin(delimiter, list)
assert(type(delimiter) == "string" or type(delimiter) == nil, "delimiter is of the wrong type! (did you get the parameters backward?)")
-
+
return concat(list, delimiter);
end
@@ -164,7 +142,7 @@
--- Return a wrapper closure around a socket that buffers socket reads into
-- chunks separated by a pattern.
---
+--
-- This function operates on a socket attempting to read data. It separates the
-- data by sep
and, for each invocation, returns a piece of the
-- separated data. Typically this is used to iterate over the lines of data
@@ -271,7 +249,7 @@
-- @param s String or number to be encoded.
-- @param options Table specifiying formatting options.
-- @return String in hexadecimal format.
-function tohex( s, options )
+function tohex( s, options )
options = options or EMPTY
local separator = options.separator
local hex
@@ -453,7 +431,7 @@
return nmap.clock() * 1000000
end
----Get the indentation symbols at a given level.
+---Get the indentation symbols at a given level.
local function format_get_indent(indent, at_end)
local str = ""
local had_continue = false
@@ -505,9 +483,9 @@
-- Used to put 'ERROR: ' in front of all lines on error messages
local prefix = ""
-- Initialize the output string to blank (or, if we're at the top, add a newline)
- local output = {}
+ local output = ""
if(not(indent)) then
- insert(output, '\n')
+ output = '\n'
end
if(not(status)) then
@@ -527,18 +505,12 @@
if(data['name']) then
if(data['warning'] and nmap.debugging() > 0) then
- insert(output, format("%s%s%s (WARNING: %s)\n",
- format_get_indent(indent), prefix,
- data['name'], data['warning']))
+ output = output .. format("%s%s%s (WARNING: %s)\n", format_get_indent(indent), prefix, data['name'], data['warning'])
else
- insert(output, format("%s%s%s\n",
- format_get_indent(indent), prefix,
- data['name']))
+ output = output .. format("%s%s%s\n", format_get_indent(indent), prefix, data['name'])
end
elseif(data['warning'] and nmap.debugging() > 0) then
- insert(output, format("%s%s(WARNING: %s)\n",
- format_get_indent(indent), prefix,
- data['warning']))
+ output = output .. format("%s%s(WARNING: %s)\n", format_get_indent(indent), prefix, data['warning'])
end
for i, value in ipairs(data) do
@@ -555,46 +527,44 @@
insert(new_indent, true)
end
- insert(output, format_output_sub(status, value, new_indent))
-
+ output = output .. format_output_sub(status, value, new_indent)
+
elseif(type(value) == 'string') then
local lines = splitlines(value)
for j, line in ipairs(lines) do
- insert(output, format("%s %s%s\n",
- format_get_indent(indent, i == #data and j == #lines),
- prefix, line))
+ output = output .. format_get_indent(indent, i == #data and j == #lines) .. " " .. prefix .. line .. "\n"
end
end
end
- return concat(output)
+ return output
end
----Takes a table of output on the commandline and formats it for display to the
--- user. This is basically done by converting an array of nested tables into a
--- string. In addition to numbered array elements, each table can have a 'name'
--- and a 'warning' value. The 'name' will be displayed above the table, and
+---Takes a table of output on the commandline and formats it for display to the
+-- user. This is basically done by converting an array of nested tables into a
+-- string. In addition to numbered array elements, each table can have a 'name'
+-- and a 'warning' value. The 'name' will be displayed above the table, and
-- 'warning' will be displayed, with a 'WARNING' tag, if and only if debugging
--- is enabled.
---
+-- is enabled.
+--
-- Here's an example of a table:
--
-- local domains = {}
-- domains['name'] = "DOMAINS"
-- table.insert(domains, 'Domain 1')
-- table.insert(domains, 'Domain 2')
---
+--
-- local names = {}
-- names['name'] = "NAMES"
-- names['warning'] = "Not all names could be determined!"
-- table.insert(names, "Name 1")
---
+--
-- local response = {}
-- table.insert(response, "Apple pie")
-- table.insert(response, domains)
-- table.insert(response, names)
---
+--
-- return stdnse.format_output(true, response)
--
--
@@ -610,13 +580,13 @@
-- |_ Name 1
--
--
---@param status A boolean value dictating whether or not the script succeeded.
+--@param status A boolean value dictating whether or not the script succeeded.
-- If status is false, and debugging is enabled, 'ERROR' is prepended
--- to every line. If status is false and debugging is disabled, no output
--- occurs.
---@param data The table of output.
+-- to every line. If status is false and ebugging is disabled, no output
+-- occurs.
+--@param data The table of output.
--@param indent Used for indentation on recursive calls; should generally be set to
--- nil when callling from a script.
+-- nil when callling from a script.
-- @return nil
, if data
is empty, otherwise a
-- multiline string.
function format_output(status, data, indent)
@@ -644,16 +614,7 @@
local function arg_value(argname)
if nmap.registry.args[argname] then
return nmap.registry.args[argname]
- else
- -- if scriptname.arg is not there, check "arg"
- local argument_frags = strsplit("%.", argname)
- if #argument_frags > 0 then
- if nmap.registry.args[argument_frags[2]] then
- return nmap.registry.args[argument_frags[2]]
- end
- end
end
-
for _, v in ipairs(nmap.registry.args) do
if v == argname then
return 1
@@ -686,7 +647,7 @@
function get_script_args (...)
local args = {}
- for i, set in ipairs({...}) do
+ for i, set in ipairs({...}) do
if type(set) == "string" then
set = {set}
end
@@ -702,10 +663,10 @@
return unpack(args, 1, select("#", ...))
end
----Get the best possible hostname for the given host. This can be the target as given on
--- the commandline, the reverse dns name, or simply the ip address.
---@param host The host table (or a string that'll simply be returned).
---@return The best possible hostname, as a string.
+---Get the best possible hostname for the given host. This can be the target as given on
+-- the commandline, the reverse dns name, or simply the ip address.
+--@param host The host table (or a string that'll simply be returned).
+--@return The best possible hostname, as a string.
function get_hostname(host)
if type(host) == "table" then
return host.targetname or ( host.name ~= '' and host.name ) or host.ip
@@ -715,7 +676,7 @@
end
---Retrieve an item from the registry, checking if each sub-key exists. If any key doesn't
--- exist, return nil.
+-- exist, return nil.
function registry_get(subkeys)
local registry = nmap.registry
local i = 1
@@ -733,7 +694,7 @@
return registry
end
---Check if the given element exists in the registry. If 'key' is nil, it isn't checked.
+--Check if the given element exists in the registry. If 'key' is nil, it isn't checked.
function registry_exists(subkeys, key, value)
local subkey = registry_get(subkeys)
@@ -750,12 +711,12 @@
return false
end
----Add an item to an array in the registry, creating all sub-keys if necessary.
+---Add an item to an array in the registry, creating all sub-keys if necessary.
-- For example, calling:
-- registry_add_array({'192.168.1.100', 'www', '80', 'pages'}, 'index.html')
-- Will create nmap.registry['192.168.1.100'] as a table, if necessary, then add a table
-- under the 'www' key, and so on. 'pages', finally, is treated as an array and the value
--- given is added to the end.
+-- given is added to the end.
function registry_add_array(subkeys, value, allow_duplicates)
local registry = nmap.registry
local i = 1
@@ -785,8 +746,8 @@
end
---Similar to registry_add_array
, except instead of adding a value to the
--- end of an array, it adds a key:value pair to the table.
-function registry_add_table(subkeys, key, value, allow_duplicates)
+-- end of an array, it adds a key:value pair to the table.
+function registry_add_table(subkeys, key, value)
local registry = nmap.registry
local i = 1