Index: nse_nsock.cc
===================================================================
--- nse_nsock.cc (revision 15706)
+++ nse_nsock.cc (working copy)
@@ -530,8 +530,8 @@
static int l_nsock_connect(lua_State * L)
{
- enum type {TCP, UDP, SSL};
- static const char * const op[] = {"tcp", "udp", "ssl", NULL};
+ enum type {TCP, UDP, SSL, RESSL};
+ static const char * const op[] = {"tcp", "udp", "ssl", "ressl", NULL};
l_nsock_udata *udata = (l_nsock_udata *) luaL_checkudata(L, 1, "nsock");
const char *addr = luaL_checkstring(L, 2);
@@ -596,6 +596,10 @@
udata->timeout, &udata->yield, dest->ai_addr, dest->ai_addrlen,
IPPROTO_TCP, port, udata->ssl_session);
break;
+ case RESSL:
+ nsock_reconnect_ssl(nsp, udata->nsiod, l_nsock_connect_handler,
+ udata->timeout, &udata->yield, udata->ssl_session);
+ break;
}
freeaddrinfo(dest);
Index: scripts/ssl-cert.nse
===================================================================
--- scripts/ssl-cert.nse (revision 15706)
+++ scripts/ssl-cert.nse (working copy)
@@ -1,168 +1,220 @@
-description = [[
-Retrieves a server's SSL certificate. The amount of information printed
-about the certificate depends on the verbosity level. With no extra
-verbosity, the script prints the validity period and the commonName,
-organizationName, stateOrProvinceName, and countryName of the subject.
-
-
-443/tcp open https
-| ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
-/stateOrProvinceName=California/countryName=US
-| Not valid before: 2009-05-28 00:00:00
-|_ Not valid after: 2010-05-01 23:59:59
-
-
-With -v it adds the issuer name and fingerprints.
-
-
-443/tcp open https
-| ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
-/stateOrProvinceName=California/countryName=US
-| Issuer: commonName=VeriSign Class 3 Extended Validation SSL CA\
-/organizationName=VeriSign, Inc./countryName=US
-| Not valid before: 2009-05-28 00:00:00
-| Not valid after: 2010-05-01 23:59:59
-| MD5: c5b8 7ddd ccc7 537f 8861 b476 078d e8fd
-|_ SHA-1: dc5a cb8b 9eb9 b5de 7117 c536 8c15 0e75 ba88 702e
-
-
-With -vv it adds the PEM-encoded contents of the entire
-certificate.
-
-
-443/tcp open https
-| ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
-/stateOrProvinceName=California/countryName=US/serialNumber=3014267\
-/1.3.6.1.4.1.311.60.2.1.3=US/streetAddress=2211 N 1st St\
-/1.3.6.1.4.1.311.60.2.1.2=Delaware/postalCode=95131-2021\
-/localityName=San Jose/organizationalUnitName=Information Systems\
-/2.5.4.15=V1.0, Clause 5.(b)
-| Issuer: commonName=VeriSign Class 3 Extended Validation SSL CA\
-/organizationName=VeriSign, Inc./countryName=US\
-/organizationalUnitName=Terms of use at https://www.verisign.com/rpa (c)06
-| Not valid before: 2009-05-28 00:00:00
-| Not valid after: 2010-05-01 23:59:59
-| MD5: c5b8 7ddd ccc7 537f 8861 b476 078d e8fd
-| SHA-1: dc5a cb8b 9eb9 b5de 7117 c536 8c15 0e75 ba88 702e
-| -----BEGIN CERTIFICATE-----
-| MIIFxzCCBK+gAwIBAgIQX02QuADDB7CVjZdooVge+zANBgkqhkiG9w0BAQUFADCB
-...
-
-]]
-
----
--- @output
--- 443/tcp open https
--- | ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
--- /stateOrProvinceName=California/countryName=US
--- | Not valid before: 2009-05-28 00:00:00
--- |_ Not valid after: 2010-05-01 23:59:59
-
-author = "David Fifield "
-
-license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
-
-categories = { "safe", "discovery" }
-
-require("nmap")
-require("nsedebug")
-require("stdnse")
-
-local stringify_name
-local date_to_string
-local table_find
-
-local LIKELY_SSL_PORTS = { 443, 465, 989, 990, 992, 993, 994, 995, 587, 8443 }
-
-portrule = function(host, port)
- return port.version.service_tunnel == "ssl"
- or table_find(LIKELY_SSL_PORTS, port.number)
-end
-
-action = function(host, port)
- local s = nmap.new_socket()
- local status, error = s:connect(host.ip, port.number, "ssl")
- if not status then
- if nmap.verbosity() > 0 then
- return error
- else
- return nil
- end
- end
- local cert = s:get_ssl_certificate()
- s:close()
-
- local lines = {}
- lines[#lines + 1] = "Subject: " .. stringify_name(cert.subject)
-
- if nmap.verbosity() > 0 then
- lines[#lines + 1] = "Issuer: " .. stringify_name(cert.issuer)
- end
-
- lines[#lines + 1] = "Not valid before: " ..
- date_to_string(cert.validity.notBefore)
- lines[#lines + 1] = "Not valid after: " ..
- date_to_string(cert.validity.notAfter)
-
- lines[#lines + 1] = "MD5: " .. stdnse.tohex(cert:digest("md5"), { separator = " ", group = 4 })
- lines[#lines + 1] = "SHA-1: " .. stdnse.tohex(cert:digest("sha1"), { separator = " ", group = 4 })
-
- if nmap.verbosity() > 1 then
- lines[#lines + 1] = cert.pem
- end
-
- return stdnse.strjoin("\n", lines)
-end
-
--- Find the index of a value in an array.
-function table_find(t, value)
- local i, v
- for i, v in ipairs(t) do
- if v == value then
- return i
- end
- end
- return nil
-end
-
--- These are the subject/issuer name fields that will be shown, in this order,
--- without a high verbosity.
-local NON_VERBOSE_FIELDS = { "commonName", "organizationName",
- "stateOrProvinceName", "countryName" }
-
-function stringify_name(name)
- local fields = {}
- local _, k, v
- if not name then
- return nil
- end
- for _, k in ipairs(NON_VERBOSE_FIELDS) do
- v = name[k]
- if v then
- fields[#fields + 1] = string.format("%s=%s", k, v)
- end
- end
- if nmap.verbosity() > 1 then
- for k, v in pairs(name) do
- -- Don't include a field twice.
- if not table_find(NON_VERBOSE_FIELDS, k) then
- if type(k) == "table" then
- k = stdnse.strjoin(".", k)
- end
- fields[#fields + 1] = string.format("%s=%s", k, v)
- end
- end
- end
- return stdnse.strjoin("/", fields)
-end
-
-function date_to_string(date)
- if not date then
- return "MISSING"
- end
- if type(date) == "string" then
- return string.format("Can't parse; string is \"%s\"", date)
- else
- return os.date("%Y-%m-%d %H:%M:%S", os.time(date))
- end
-end
+description = [[
+Retrieves a server's SSL certificate. The amount of information printed
+about the certificate depends on the verbosity level. With no extra
+verbosity, the script prints the validity period and the commonName,
+organizationName, stateOrProvinceName, and countryName of the subject.
+
+
+443/tcp open https
+| ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
+/stateOrProvinceName=California/countryName=US
+| Not valid before: 2009-05-28 00:00:00
+|_ Not valid after: 2010-05-01 23:59:59
+
+
+With -v it adds the issuer name and fingerprints.
+
+
+443/tcp open https
+| ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
+/stateOrProvinceName=California/countryName=US
+| Issuer: commonName=VeriSign Class 3 Extended Validation SSL CA\
+/organizationName=VeriSign, Inc./countryName=US
+| Not valid before: 2009-05-28 00:00:00
+| Not valid after: 2010-05-01 23:59:59
+| MD5: c5b8 7ddd ccc7 537f 8861 b476 078d e8fd
+|_ SHA-1: dc5a cb8b 9eb9 b5de 7117 c536 8c15 0e75 ba88 702e
+
+
+With -vv it adds the PEM-encoded contents of the entire
+certificate.
+
+
+443/tcp open https
+| ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
+/stateOrProvinceName=California/countryName=US/serialNumber=3014267\
+/1.3.6.1.4.1.311.60.2.1.3=US/streetAddress=2211 N 1st St\
+/1.3.6.1.4.1.311.60.2.1.2=Delaware/postalCode=95131-2021\
+/localityName=San Jose/organizationalUnitName=Information Systems\
+/2.5.4.15=V1.0, Clause 5.(b)
+| Issuer: commonName=VeriSign Class 3 Extended Validation SSL CA\
+/organizationName=VeriSign, Inc./countryName=US\
+/organizationalUnitName=Terms of use at https://www.verisign.com/rpa (c)06
+| Not valid before: 2009-05-28 00:00:00
+| Not valid after: 2010-05-01 23:59:59
+| MD5: c5b8 7ddd ccc7 537f 8861 b476 078d e8fd
+| SHA-1: dc5a cb8b 9eb9 b5de 7117 c536 8c15 0e75 ba88 702e
+| -----BEGIN CERTIFICATE-----
+| MIIFxzCCBK+gAwIBAgIQX02QuADDB7CVjZdooVge+zANBgkqhkiG9w0BAQUFADCB
+...
+
+]]
+
+---
+-- @output
+-- 443/tcp open https
+-- | ssl-cert: Subject: commonName=www.paypal.com/organizationName=PayPal, Inc.\
+-- /stateOrProvinceName=California/countryName=US
+-- | Not valid before: 2009-05-28 00:00:00
+-- |_ Not valid after: 2010-05-01 23:59:59
+
+author = "David Fifield "
+
+license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
+
+categories = { "safe", "discovery" }
+
+require("nmap")
+require("nsedebug")
+require("stdnse")
+
+local stringify_name
+local date_to_string
+local table_find
+
+local LIKELY_SSL_PORTS = { 443, 465, 989, 990, 992, 993, 994, 995, 587, 8443 }
+
+portrule = function(host, port)
+ return port.version.service_tunnel == "ssl"
+ or table_find(LIKELY_SSL_PORTS, port.number)
+end
+
+action = function(host, port)
+ local s = nmap.new_socket()
+ local status, error = s:connect(host.ip, port.number, "ssl")
+
+ if not status then
+ status, error = s:connect(host.ip, port.number, "tcp") -- SSL negotiation failed, let try for SMTP + TLS
+
+ if not status then
+ if nmap.verbosity() > 0 then
+ return error
+ else
+ return nil
+ end
+ else
+
+ local i = 0
+ repeat
+ status, resultEHLO = s:receive_lines(1)
+ i = i + 1
+ until string.match(resultEHLO, "^220") or i == 5
+
+ local query = "EHLO example.org\r\n"
+ status = s:send(query)
+ status, resultEHLO = s:receive_lines(1)
+
+ if not (string.match(resultEHLO, "^250")) then
+ stdnse.print_debug("1","%s",resultEHLO)
+ stdnse.print_debug("1","EHLO with errors or timeout. Enable --script-trace to see what is happening.")
+ return error
+ end
+
+ resultEHLO = ""
+
+ local query = "STARTTLS\r\n"
+ status = s:send(query)
+ status, resultEHLO = s:receive_lines(1)
+
+ if not (string.match(resultEHLO, "^220")) then
+ stdnse.print_debug("1","%s",resultEHLO)
+ stdnse.print_debug("1","STARTTLS failed or unavailable. Enable --script-trace to see what is happening.")
+ resultEHLO = ""
+
+ if nmap.verbosity() > 0 then
+ return error
+ else
+ return nil
+ end
+ s:close()
+ end
+
+ status, error = s:connect(host.ip, port.number, "ressl")
+ if not status then
+ if nmap.verbosity() > 0 then
+ return error
+ else
+ return nil
+ end
+ end
+
+
+ end
+ end
+ local cert = s:get_ssl_certificate()
+ s:close()
+
+ local lines = {}
+ lines[#lines + 1] = "Subject: " .. stringify_name(cert.subject)
+
+ if nmap.verbosity() > 0 then
+ lines[#lines + 1] = "Issuer: " .. stringify_name(cert.issuer)
+ end
+
+ lines[#lines + 1] = "Not valid before: " ..
+ date_to_string(cert.validity.notBefore)
+ lines[#lines + 1] = "Not valid after: " ..
+ date_to_string(cert.validity.notAfter)
+
+ lines[#lines + 1] = "MD5: " .. stdnse.tohex(cert:digest("md5"), { separator = " ", group = 4 })
+ lines[#lines + 1] = "SHA-1: " .. stdnse.tohex(cert:digest("sha1"), { separator = " ", group = 4 })
+
+ if nmap.verbosity() > 1 then
+ lines[#lines + 1] = cert.pem
+ end
+
+ return stdnse.strjoin("\n", lines)
+end
+
+-- Find the index of a value in an array.
+function table_find(t, value)
+ local i, v
+ for i, v in ipairs(t) do
+ if v == value then
+ return i
+ end
+ end
+ return nil
+end
+
+-- These are the subject/issuer name fields that will be shown, in this order,
+-- without a high verbosity.
+local NON_VERBOSE_FIELDS = { "commonName", "organizationName",
+ "stateOrProvinceName", "countryName" }
+
+function stringify_name(name)
+ local fields = {}
+ local _, k, v
+ if not name then
+ return nil
+ end
+ for _, k in ipairs(NON_VERBOSE_FIELDS) do
+ v = name[k]
+ if v then
+ fields[#fields + 1] = string.format("%s=%s", k, v)
+ end
+ end
+ if nmap.verbosity() > 1 then
+ for k, v in pairs(name) do
+ -- Don't include a field twice.
+ if not table_find(NON_VERBOSE_FIELDS, k) then
+ if type(k) == "table" then
+ k = stdnse.strjoin(".", k)
+ end
+ fields[#fields + 1] = string.format("%s=%s", k, v)
+ end
+ end
+ end
+ return stdnse.strjoin("/", fields)
+end
+
+function date_to_string(date)
+ if not date then
+ return "MISSING"
+ end
+ if type(date) == "string" then
+ return string.format("Can't parse; string is \"%s\"", date)
+ else
+ return os.date("%Y-%m-%d %H:%M:%S", os.time(date))
+ end
+end