1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-23 22:59:20 +00:00

STARTTLS support for LDAP

This commit is contained in:
claudiu
2014-06-20 10:11:38 +00:00
parent f5e438b966
commit 2772733958

View File

@@ -10,12 +10,16 @@
--
-- * FTP
-- * IMAP
-- * LDAP
-- * POP3
-- * SMTP
-- * XMPP
--
-- @author "Patrik Karlsson <patrik@cqure.net>"
local asn1 = require "asn1"
local bin = require "bin"
local ldap = require "ldap"
local nmap = require "nmap"
local stdnse = require "stdnse"
local string = require "string"
@@ -24,7 +28,7 @@ _ENV = stdnse.module("sslcert", stdnse.seeall)
StartTLS = {
-- TODO: Implement STARTTLS for LDAP, NNTP
-- TODO: Implement STARTTLS for NNTP
ftp_prepare_tls_without_reconnect = function(host, port)
local s = nmap.new_socket()
@@ -145,6 +149,85 @@ StartTLS = {
return false, "Failed to connect to IMAP server"
end,
ldap_prepare_tls_without_reconnect = function(host, port)
local s = nmap.new_socket()
-- Attempt to negotiate TLS over LDAP for services that support it
-- Works for LDAP (389)
-- Open a standard TCP socket
local status, error = s:connect(host, port, "tcp")
if not status then
return false, "Failed to connect to LDAP server"
end
-- Create an ExtendedRequest and specify the OID for the
-- Start TTLS operation (see http://www.ietf.org/rfc/rfc2830.txt)
local ExtendedRequest = 23
local ExtendedResponse = 24
local oid, ldapRequest, ldapRequestId
oid = ldap.encode("1.3.6.1.4.1.1466.20037")
ldapRequest = ldap.encodeLDAPOp(ExtendedRequest, true, oid)
ldapRequestId = ldap.encode(1)
-- Send the STARTTLS request
local encoder = asn1.ASN1Encoder:new()
local data = encoder:encodeSeq(ldapRequestId .. ldapRequest)
status = s:send(data)
if not status then
return false, "STARTTLS failed"
end
-- Decode the response
local response
status, response = s:receive()
if not status then
return false, "STARTTLS failed"
end
local decoder = asn1.ASN1Decoder:new()
local len, pos, messageId, ldapOp, tmp = ""
pos, len = decoder.decodeLength(response, 2)
pos, messageId = ldap.decode(response, pos)
pos, tmp = bin.unpack("C", response, pos)
ldapOp = asn1.intToBER(tmp)
if ldapOp.number ~= ExtendedResponse then
stdnse.print_debug(1, string.format(
"STARTTLS failed (got wrong op number: %d)", ldapOp.number))
return false, "STARTTLS failed"
end
local resultCode
pos, len = decoder.decodeLength(response, pos)
pos, resultCode = ldap.decode(response, pos)
if resultCode ~= 0 then
stdnse.print_debug(1, string.format(
"STARTTLS failed (LDAP error code is: %d)", resultCode))
return false, "STARTTLS failed"
end
-- Should have a solid TLS over LDAP session now...
return true,s
end,
ldap_prepare_tls = function(host, port)
local err
local status, s = StartTLS.ldap_prepare_tls_without_reconnect(host, port)
if status then
status,err = s:reconnect_ssl()
if not status then
stdnse.print_debug(
1,"Could not establish SSL session after STARTTLS command.")
s:close()
return false, "Failed to connect to LDAP server"
else
return true,s
end
end
return false, "Failed to connect to LDAP server"
end,
pop3_prepare_tls_without_reconnect = function(host, port)
local s = nmap.new_socket()
-- Attempt to negotiate TLS over POP3 for services that support it
@@ -345,6 +428,8 @@ local SPECIALIZED_PREPARE_TLS = {
[21] = StartTLS.ftp_prepare_tls,
imap = StartTLS.imap_prepare_tls,
[143] = StartTLS.imap_prepare_tls,
[ldap] = StartTLS.ldap_prepare_tls,
[389] = StartTLS.ldap_prepare_tls,
pop3 = StartTLS.pop3_prepare_tls,
[110] = StartTLS.pop3_prepare_tls,
smtp = StartTLS.smtp_prepare_tls,
@@ -360,6 +445,8 @@ local SPECIALIZED_PREPARE_TLS_WITHOUT_RECONNECT = {
[21] = StartTLS.ftp_prepare_tls_without_reconnect,
imap = StartTLS.imap_prepare_tls_without_reconnect,
[143] = StartTLS.imap_prepare_tls_without_reconnect,
ldap = StartTLS.ldap_prepare_tls_without_reconnect,
[389] = StartTLS.ldap_prepare_tls_without_reconnect,
pop3 = StartTLS.pop3_prepare_tls_without_reconnect,
[110] = StartTLS.pop3_prepare_tls_without_reconnect,
smtp = StartTLS.smtp_prepare_tls_without_reconnect,