diff --git a/CHANGELOG b/CHANGELOG index c7ff9f050..0f698ab17 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] The nmap.connect function can now accept host and port tables + (like those provided to the action function) in place of a string + and a number. The motivation behind this is to easily support Server + Name Indication for SSL sockets by reading host.targetname. [David + Fifield] + o [NSE] Added wdb-version, which discovers information from a VxWorks debug service that is often left open. [Daniel Miller] diff --git a/nse_nsock.cc b/nse_nsock.cc index aeed77648..7c569128a 100644 --- a/nse_nsock.cc +++ b/nse_nsock.cc @@ -654,9 +654,54 @@ static int l_nsock_connect(lua_State * L) static const char * const op[] = {"tcp", "udp", "ssl", NULL}; l_nsock_udata *udata = (l_nsock_udata *) luaL_checkudata(L, 1, "nsock"); - const char *addr = luaL_checkstring(L, 2); - unsigned short port = (unsigned short) luaL_checkint(L, 3); - int what = luaL_checkoption(L, 4, "tcp", op); + const char *addr, *targetname; + unsigned short port; + int what; + + addr = NULL; + targetname = NULL; + + /* host argument. */ + if (lua_istable(L, 2)) { + const char *ip; + + ip = NULL; + targetname = NULL; + + lua_getfield(L, 2, "ip"); + ip = lua_tostring(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 2, "targetname"); + targetname = lua_tostring(L, -1); + lua_pop(L, 1); + + if (ip != NULL) + addr = ip; + else if (targetname != NULL) + addr = targetname; + else + luaL_error(L, "host table does not have a 'ip' or 'targetname' field"); + } else { + addr = luaL_checkstring(L, 2); + targetname = addr; + } + + /* port argument. */ + if (lua_istable(L, 3)) { + lua_getfield(L, 3, "number"); + if (lua_isnil(L, -1)) + luaL_error(L, "port table does not have a 'number' field"); + else if (!lua_isnumber(L, -1)) + luaL_error(L, "port.number is not numeric"); + port = lua_tointeger(L, -1); + lua_pop(L, 1); + } else { + port = (unsigned short) luaL_checkint(L, 3); + } + + /* proto argument. */ + what = luaL_checkoption(L, 4, "tcp", op); const char *error; struct addrinfo *dest; @@ -698,6 +743,10 @@ static int l_nsock_connect(lua_State * L) o.SourceSockAddr(&ss, &sslen); nsi_set_localaddr(udata->nsiod, &ss, sslen); } + if (targetname != NULL) { + if (nsi_set_hostname(udata->nsiod, targetname) == -1) + fatal("nsi_set_hostname(\"%s\" failed in %s()", targetname, __func__); + } if (o.ipoptionslen) nsi_set_ipoptions(udata->nsiod, o.ipoptions, o.ipoptionslen); diff --git a/nselib/nmap.luadoc b/nselib/nmap.luadoc index 108b3f583..0cd94c01a 100644 --- a/nselib/nmap.luadoc +++ b/nselib/nmap.luadoc @@ -327,10 +327,18 @@ function bind(addr, port) --- Establishes a connection. -- -- This method puts a socket in a state ready for communication. It takes as --- arguments a host descriptor (either an IP address or a hostname), a port --- number and optionally a protocol. The protocol must be one of --- "tcp", "udp" or "ssl"; it is --- "tcp" if not specified. +-- 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"; +-- "tcp" is the default. +-- +-- 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 @@ -351,8 +359,8 @@ function bind(addr, port) -- 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 hostid Hostname or IP address. --- @param port Port number. +-- @param host Host table, hostname or IP address. +-- @param port Port table or number. -- @param protocol "tcp", "udp", or -- "ssl" (default "tcp"). -- @return Status (true or false). @@ -363,7 +371,7 @@ function bind(addr, port) -- if not status then -- return string.format("Can't connect: %s", err) -- end -function connect(hostid, port, protocol) +function connect(host, port, protocol) --- Reconnect the open (connected) socket with SSL. --