diff --git a/nselib/pop3.lua b/nselib/pop3.lua index 62cf18b3f..ded922644 100644 --- a/nselib/pop3.lua +++ b/nselib/pop3.lua @@ -151,44 +151,49 @@ end -- @return Table containing capabilities or nil on error. -- @return nil or String error message. function capabilities(host, port) - local socket = nmap.new_socket() - local capas = {} - local opts = {timeout=10000, recv_before=true} - local i = 1 - local socket, line, bopt, first_line = comm.tryssl(host, port, "CAPA\r\n" , opts) - if not socket then return nil, "Could Not Connect" end - if not stat(first_line) then return nil, "No Response" end + local socket, line, bopt, first_line = comm.tryssl(host, port, "" , {timeout=10000, recv_before=true}) + if not socket then + return nil, "Could Not Connect" + end + if not stat(first_line) then + return nil, "No Response" + end - if string.find(first_line, "<[%p%w]+>") then capas.APOP = true end + local capas = {} + if string.find(first_line, "<[%p%w]+>") then + capas.APOP = {} + end - local lines = stdnse.strsplit("\r\n",line) - local line = lines[1] - - if not stat(line) then - capas.capa = false - else - while line do - if line ~= "." then - local capability = string.sub(line, string.find(line, "[%w-]+")) - line = string.sub(line, #capability + 1) - capas[capability] = true - local args = {} - local w - for w in string.gmatch(line, "[%w-]+") do - table.insert(args, w) - end - if #args == 1 then capas[capability] = args[1] - else if #args > 1 then capas[capability] = args - end end - else - break - end - line = lines[i] - i = i + 1 - end + local status = socket:send("CAPA\r\n") + if( not(status) ) then + return nil, "Failed to send" + end + + status, line = socket:receive_buf("%.", false) + if( not(status) ) then + return nil, "Failed to receive" end socket:close() + + local lines = stdnse.strsplit("\r\n",line) + if not stat(table.remove(lines,1)) then + capas.capa = false + return capas + end + + for _, line in ipairs(lines) do + if ( line and #line>0 ) then + local capability = line:sub(line:find("[%w-]+")) + line = line:sub(#capability + 2) + if ( line ~= "" ) then + capas[capability] = stdnse.strsplit(" ", line) + else + capas[capability] = {} + end + end + end + return capas end diff --git a/scripts/pop3-capabilities.nse b/scripts/pop3-capabilities.nse index f2bf97066..ed9ad516e 100644 --- a/scripts/pop3-capabilities.nse +++ b/scripts/pop3-capabilities.nse @@ -27,29 +27,22 @@ categories = {"default","discovery","safe"} portrule = shortport.port_or_service({110,995},{"pop3","pop3s"}) action = function(host, port) - local capa, err = pop3.capabilities(host, port) - if type(capa) == "table" then - -- Convert the capabilities table into an array of strings. - local capstrings = {} - local cap, args - for cap, args in pairs(capa) do - local capstr = cap - if type(args) == "string" then capstr = capstr .. "(" .. args .. ")" end - if type(args) == "table" then - local arg - capstr = capstr .. "(" - for i, arg in ipairs(args) do - capstr = capstr .. arg .. " " - end - capstr = string.sub(capstr, 1, #capstr - 1) .. ")" + local capa, err = pop3.capabilities(host, port) + if type(capa) == "table" then + -- Convert the capabilities table into an array of strings. + local capstrings = {} + for cap, args in pairs(capa) do + if ( #args > 0 ) then + table.insert(capstrings, ("%s(%s)"):format(cap, stdnse.strjoin(" ", args))) + else + table.insert(capstrings, cap) + end + end + return stdnse.strjoin(" ", capstrings) + elseif type(err) == "string" then + stdnse.print_debug(1, "%s: '%s' for %s", SCRIPT_NAME, err, host.ip) + return + else + return "server doesn't support CAPA" end - table.insert(capstrings, capstr) - end - return stdnse.strjoin(" ", capstrings) - elseif type(err) == "string" then - stdnse.print_debug(1, "%s: '%s' for %s", SCRIPT_NAME, err, host.ip) - return - else - return "server doesn't support CAPA" - end end