description = [[
Retrieves information from the remote iSCSI target.
]]

---
-- @output
-- PORT     STATE SERVICE
-- 3260/tcp open  iscsi
-- | iscsi-info: 
-- |   iqn.2006-01.com.openfiler:tsn.c8c08cad469d
-- |     Target address: 192.168.56.5:3260,1
-- |     Authentication: NOT required
-- |   iqn.2006-01.com.openfiler:tsn.6aea7e052952
-- |     Target address: 192.168.56.5:3260,1
-- |_    Authentication: required
-- 

-- Version 0.1
-- Created 2010/11/18 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>

author = "Patrik Karlsson"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery"}

require("shortport")
require("bit")
require("iscsi")

portrule = shortport.portnumber(3260, "tcp", {"open", "open|filtered"})

-- Attempts to determine whether authentication is required or not
--
-- @return status true on success false on failure
-- @return result true if auth is required false if not
--         err string containing error message
local function requiresAuth( host, port, target )
	local helper = iscsi.Helper:new( host, port )
	local errors = iscsi.Packet.LoginResponse.Errors
	
	local status, err = helper:connect()
	if ( not(status) ) then return false, "Failed to connect" end

	local response
	status, response = helper:login( target )
	if ( not(status) ) then return false, "Failed to login" end

	if ( status and response:getErrorCode() == errors.SUCCESS) then
		status = helper:logout()
		if ( not(status) ) then return false, "Failed to logout" end
	end
	
	status = helper:close()

	return true, ( response:getErrorCode() == errors.AUTH_FAILED )
end

action = function( host, port )

	local helper = iscsi.Helper:new( host, port )
	
	local status = helper:connect()
	if ( not(status) ) then
		stdnse.print_debug("%s: failed to connect to server", SCRIPT_NAME )
		return
	end

	local targets
	status, targets = helper:discoverTargets()
	if ( not(status) ) then
		stdnse.print_debug("%s: failed to discover targets", SCRIPT_NAME )
		return
	end
	
	local result = {}
	for _, target in ipairs( targets ) do
		local result_part = { name = target.name }
		table.insert(result_part, ("Target address: %s"):format( target.addr ))
		local status, authreq = requiresAuth( host, port, target.name )
		if ( status and authreq ) then
			table.insert(result_part, "Authentication: required")
		elseif( status ) then
			table.insert(result_part, "Authentication: NOT required")
		end
		table.insert(result, result_part )
	end

	status = helper:logout()
	status = helper:close()
	
	return stdnse.format_output( true, result )
end