PageRenderTime 64ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/nselib/http.lua

https://gitlab.com/g10h4ck/nmap-gsoc2015
Lua | 2886 lines | 2566 code | 58 blank | 262 comment | 97 complexity | 470a24c1ec40b61a76841dcb544e9963 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, Apache-2.0, LGPL-2.0, LGPL-2.1, MIT

Large files files are truncated, but you can click here to view the full file

  1. ---Implements the HTTP client protocol in a standard form that Nmap scripts can
  2. -- take advantage of.
  3. --
  4. -- Because HTTP has so many uses, there are a number of interfaces to this library.
  5. -- The most obvious and common ones are simply <code>get</code>, <code>post</code>,
  6. -- and <code>head</code>; or, if more control is required, <code>generic_request</code>
  7. -- can be used. These functions do what one would expect. The <code>get_url</code>
  8. -- helper function can be used to parse and retrieve a full URL.
  9. --
  10. -- HTTPS support is transparent. The library uses <code>comm.tryssl</code> to
  11. -- determine whether SSL is required for a request.
  12. --
  13. -- These functions return a table of values, including:
  14. -- * <code>status-line</code> - A string representing the status, such as "HTTP/1.1 200 OK". In case of an error, a description will be provided in this line.
  15. -- * <code>status</code>: The HTTP status value; for example, "200". If an error occurs during a request, then this value is going to be nil.
  16. -- * <code>header</code> - An associative array representing the header. Keys are all lowercase, and standard headers, such as 'date', 'content-length', etc. will typically be present.
  17. -- * <code>rawheader</code> - A numbered array of the headers, exactly as the server sent them. While header['content-type'] might be 'text/html', rawheader[3] might be 'Content-type: text/html'.
  18. -- * <code>cookies</code> - A numbered array of the cookies the server sent. Each cookie is a table with the following keys: <code>name</code>, <code>value</code>, <code>path</code>, <code>domain</code>, and <code>expires</code>.
  19. -- * <code>body</code> - The full body, as returned by the server.
  20. --
  21. -- If a script is planning on making a lot of requests, the pipelining functions can
  22. -- be helpful. <code>pipeline_add</code> queues requests in a table, and
  23. -- <code>pipeline</code> performs the requests, returning the results as an array,
  24. -- with the responses in the same order as the queries were added. As a simple example:
  25. --<code>
  26. -- -- Start by defining the 'all' variable as nil
  27. -- local all = nil
  28. --
  29. -- -- Add two 'GET' requests and one 'HEAD' to the queue. These requests are not performed
  30. -- -- yet. The second parameter represents the 'options' table, which we don't need.
  31. -- all = http.pipeline_add('/book', nil, all)
  32. -- all = http.pipeline_add('/test', nil, all)
  33. -- all = http.pipeline_add('/monkeys', nil, all, 'HEAD')
  34. --
  35. -- -- Perform all three requests as parallel as Nmap is able to
  36. -- local results = http.pipeline('nmap.org', 80, all)
  37. --</code>
  38. --
  39. -- At this point, <code>results</code> is an array with three elements. Each element
  40. -- is a table containing the HTTP result, as discussed above.
  41. --
  42. -- One more interface provided by the HTTP library helps scripts determine whether or not
  43. -- a page exists. The <code>identify_404</code> function will try several URLs on the
  44. -- server to determine what the server's 404 pages look like. It will attempt to identify
  45. -- customized 404 pages that may not return the actual status code 404. If successful,
  46. -- the function <code>page_exists</code> can then be used to determine whether or not
  47. -- a page existed.
  48. --
  49. -- Some other miscellaneous functions that can come in handy are <code>response_contains</code>,
  50. -- <code>can_use_head</code>, and <code>save_path</code>. See the appropriate documentation
  51. -- for them.
  52. --
  53. -- The response to each function is typically a table with the following keys:
  54. -- * <code>status-line</code>: The HTTP status line; for example, "HTTP/1.1 200 OK" (note: this is followed by a newline). In case of an error, a description will be provided in this line.
  55. -- * <code>status</code>: The HTTP status value; for example, "200". If an error occurs during a request, then this value is going to be nil.
  56. -- * <code>header</code>: A table of header values, where the keys are lowercase and the values are exactly what the server sent
  57. -- * <code>rawheader</code>: A list of header values as "name: value" strings, in the exact format and order that the server sent them
  58. -- * <code>cookies</code>: A list of cookies that the server is sending. Each cookie is a table containing the keys <code>name</code>, <code>value</code>, and <code>path</code>. This table can be sent to the server in subsequent responses in the <code>options</code> table to any function (see below).
  59. -- * <code>body</code>: The body of the response
  60. -- * <code>location</code>: a list of the locations of redirects that were followed.
  61. --
  62. -- Many of the functions optionally allow an 'options' table. This table can alter the HTTP headers
  63. -- or other values like the timeout. The following are valid values in 'options' (note: not all
  64. -- options will necessarily affect every function):
  65. -- * <code>timeout</code>: A timeout used for socket operations.
  66. -- * <code>header</code>: A table containing additional headers to be used for the request. For example, <code>options['header']['Content-Type'] = 'text/xml'</code>
  67. -- * <code>content</code>: The content of the message (content-length will be added -- set header['Content-Length'] to override). This can be either a string, which will be directly added as the body of the message, or a table, which will have each key=value pair added (like a normal POST request).
  68. -- * <code>cookies</code>: A list of cookies as either a string, which will be directly sent, or a table. If it's a table, the following fields are recognized: <code>name</code>, <code>value</code>, <code>path</code>, <code>expires</code>. Only <code>name</code> and <code>value</code> fields are required.
  69. -- * <code>auth</code>: A table containing the keys <code>username</code> and <code>password</code>, which will be used for HTTP Basic authentication.
  70. -- If a server requires HTTP Digest authentication, then there must also be a key <code>digest</code>, with value <code>true</code>.
  71. -- If a server requires NTLM authentication, then there must also be a key <code>ntlm</code>, with value <code>true</code>.
  72. -- * <code>bypass_cache</code>: Do not perform a lookup in the local HTTP cache.
  73. -- * <code>no_cache</code>: Do not save the result of this request to the local HTTP cache.
  74. -- * <code>no_cache_body</code>: Do not save the body of the response to the local HTTP cache.
  75. -- * <code>redirect_ok</code>: Closure that overrides the default redirect_ok used to validate whether to follow HTTP redirects or not. False, if no HTTP redirects should be followed. Alternatively, a number may be passed to change the number of redirects to follow.
  76. -- The following example shows how to write a custom closure that follows 5 consecutive redirects, without the safety checks in the default redirect_ok:
  77. -- <code>
  78. -- redirect_ok = function(host,port)
  79. -- local c = 5
  80. -- return function(url)
  81. -- if ( c==0 ) then return false end
  82. -- c = c - 1
  83. -- return true
  84. -- end
  85. -- end
  86. -- </code>
  87. --
  88. -- @args http.max-cache-size The maximum memory size (in bytes) of the cache.
  89. --
  90. -- @args http.useragent The value of the User-Agent header field sent with
  91. -- requests. By default it is
  92. -- <code>"Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"</code>.
  93. -- A value of the empty string disables sending the User-Agent header field.
  94. --
  95. -- @args http.pipeline If set, it represents the number of HTTP requests that'll be
  96. -- sent on one connection. This can be set low to make debugging easier, or it
  97. -- can be set high to test how a server reacts (its chosen max is ignored).
  98. -- @args http.max-pipeline If set, it represents the number of outstanding HTTP requests
  99. -- that should be pipelined. Defaults to <code>http.pipeline</code> (if set), or to what
  100. -- <code>getPipelineMax</code> function returns.
  101. --
  102. -- TODO
  103. -- Implement cache system for http pipelines
  104. --
  105. local base64 = require "base64"
  106. local bin = require "bin"
  107. local bit = require "bit"
  108. local comm = require "comm"
  109. local coroutine = require "coroutine"
  110. local nmap = require "nmap"
  111. local os = require "os"
  112. local sasl = require "sasl"
  113. local stdnse = require "stdnse"
  114. local string = require "string"
  115. local table = require "table"
  116. local url = require "url"
  117. local smbauth = require "smbauth"
  118. local unicode = require "unicode"
  119. _ENV = stdnse.module("http", stdnse.seeall)
  120. ---Use ssl if we have it
  121. local have_ssl, openssl = pcall(require,'openssl')
  122. USER_AGENT = stdnse.get_script_args('http.useragent') or "Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
  123. local MAX_REDIRECT_COUNT = 5
  124. -- Recursively copy a table.
  125. -- Only recurs when a value is a table, other values are copied by assignment.
  126. local function tcopy (t)
  127. local tc = {};
  128. for k,v in pairs(t) do
  129. if type(v) == "table" then
  130. tc[k] = tcopy(v);
  131. else
  132. tc[k] = v;
  133. end
  134. end
  135. return tc;
  136. end
  137. --- Recursively copy into a table any elements from another table whose key it
  138. -- doesn't have.
  139. local function table_augment(to, from)
  140. for k, v in pairs(from) do
  141. if type( to[k] ) == 'table' then
  142. table_augment(to[k], from[k])
  143. else
  144. to[k] = from[k]
  145. end
  146. end
  147. end
  148. --- Get a value suitable for the Host header field.
  149. -- See RFC 2616 sections 14.23 and 5.2.
  150. local function get_host_field(host, port)
  151. return stdnse.get_hostname(host)
  152. end
  153. -- Skip *( SP | HT ) starting at offset. See RFC 2616, section 2.2.
  154. -- @return the first index following the spaces.
  155. -- @return the spaces skipped over.
  156. local function skip_space(s, offset)
  157. local _, i, space = s:find("^([ \t]*)", offset)
  158. return i + 1, space
  159. end
  160. -- Get a token starting at offset. See RFC 2616, section 2.2.
  161. -- @return the first index following the token, or nil if no token was found.
  162. -- @return the token.
  163. local function get_token(s, offset)
  164. -- All characters except CTL and separators.
  165. local _, i, token = s:find("^([^()<>@,;:\\\"/%[%]?={} \0\001-\031\127]+)", offset)
  166. if i then
  167. return i + 1, token
  168. else
  169. return nil
  170. end
  171. end
  172. -- Get a quoted-string starting at offset. See RFC 2616, section 2.2. crlf is
  173. -- used as the definition for CRLF in the case of LWS within the string.
  174. -- @return the first index following the quoted-string, or nil if no
  175. -- quoted-string was found.
  176. -- @return the contents of the quoted-string, without quotes or backslash
  177. -- escapes.
  178. local function get_quoted_string(s, offset, crlf)
  179. local result = {}
  180. local i = offset
  181. assert(s:sub(i, i) == "\"")
  182. i = i + 1
  183. while i <= s:len() do
  184. local c = s:sub(i, i)
  185. if c == "\"" then
  186. -- Found the closing quote, done.
  187. return i + 1, table.concat(result)
  188. elseif c == "\\" then
  189. -- This is a quoted-pair ("\" CHAR).
  190. i = i + 1
  191. c = s:sub(i, i)
  192. if c == "" then
  193. -- No character following.
  194. error(string.format("\\ escape at end of input while parsing quoted-string."))
  195. end
  196. -- Only CHAR may follow a backslash.
  197. if c:byte(1) > 127 then
  198. error(string.format("Unexpected character with value > 127 (0x%02X) in quoted-string.", c:byte(1)))
  199. end
  200. else
  201. -- This is qdtext, which is TEXT except for '"'.
  202. -- TEXT is "any OCTET except CTLs, but including LWS," however "a CRLF is
  203. -- allowed in the definition of TEXT only as part of a header field
  204. -- continuation." So there are really two definitions of quoted-string,
  205. -- depending on whether it's in a header field or not. This function does
  206. -- not allow CRLF.
  207. c = s:sub(i, i)
  208. if c ~= "\t" and c:match("^[\0\001-\031\127]$") then
  209. error(string.format("Unexpected control character in quoted-string: 0x%02X.", c:byte(1)))
  210. end
  211. end
  212. result[#result + 1] = c
  213. i = i + 1
  214. end
  215. return nil
  216. end
  217. -- Get a ( token | quoted-string ) starting at offset.
  218. -- @return the first index following the token or quoted-string, or nil if
  219. -- nothing was found.
  220. -- @return the token or quoted-string.
  221. local function get_token_or_quoted_string(s, offset, crlf)
  222. if s:sub(offset, offset) == "\"" then
  223. return get_quoted_string(s, offset)
  224. else
  225. return get_token(s, offset)
  226. end
  227. end
  228. -- Returns the index just past the end of LWS.
  229. local function skip_lws(s, pos)
  230. local _, e
  231. while true do
  232. while string.match(s, "^[ \t]", pos) do
  233. pos = pos + 1
  234. end
  235. _, e = string.find(s, "^\r?\n[ \t]", pos)
  236. if not e then
  237. return pos
  238. end
  239. pos = e + 1
  240. end
  241. end
  242. ---Validate an 'options' table, which is passed to a number of the HTTP functions. It is
  243. -- often difficult to track down a mistake in the options table, and requires fiddling
  244. -- with the http.lua source, but this should make that a lot easier.
  245. local function validate_options(options)
  246. local bad = false
  247. if(options == nil) then
  248. return true
  249. end
  250. for key, value in pairs(options) do
  251. if(key == 'timeout') then
  252. if(type(tonumber(value)) ~= 'number') then
  253. stdnse.debug1('http: options.timeout contains a non-numeric value')
  254. bad = true
  255. end
  256. elseif(key == 'header') then
  257. if(type(value) ~= 'table') then
  258. stdnse.debug1("http: options.header should be a table")
  259. bad = true
  260. end
  261. elseif(key == 'content') then
  262. if(type(value) ~= 'string' and type(value) ~= 'table') then
  263. stdnse.debug1("http: options.content should be a string or a table")
  264. bad = true
  265. end
  266. elseif(key == 'cookies') then
  267. if(type(value) == 'table') then
  268. for _, cookie in ipairs(value) do
  269. for cookie_key, cookie_value in pairs(cookie) do
  270. if(cookie_key == 'name') then
  271. if(type(cookie_value) ~= 'string') then
  272. stdnse.debug1("http: options.cookies[i].name should be a string")
  273. bad = true
  274. end
  275. elseif(cookie_key == 'value') then
  276. if(type(cookie_value) ~= 'string') then
  277. stdnse.debug1("http: options.cookies[i].value should be a string")
  278. bad = true
  279. end
  280. elseif(cookie_key == 'path') then
  281. if(type(cookie_value) ~= 'string') then
  282. stdnse.debug1("http: options.cookies[i].path should be a string")
  283. bad = true
  284. end
  285. elseif(cookie_key == 'expires') then
  286. if(type(cookie_value) ~= 'string') then
  287. stdnse.debug1("http: options.cookies[i].expires should be a string")
  288. bad = true
  289. end
  290. else
  291. stdnse.debug1("http: Unknown field in cookie table: %s", cookie_key)
  292. bad = true
  293. end
  294. end
  295. end
  296. elseif(type(value) ~= 'string') then
  297. stdnse.debug1("http: options.cookies should be a table or a string")
  298. bad = true
  299. end
  300. elseif(key == 'auth') then
  301. if(type(value) == 'table') then
  302. if(value['username'] == nil or value['password'] == nil) then
  303. stdnse.debug1("http: options.auth should contain both a 'username' and a 'password' key")
  304. bad = true
  305. end
  306. else
  307. stdnse.debug1("http: options.auth should be a table")
  308. bad = true
  309. end
  310. elseif (key == 'digestauth') then
  311. if(type(value) == 'table') then
  312. local req_keys = {"username","realm","nonce","digest-uri","response"}
  313. for _,k in ipairs(req_keys) do
  314. if not value[k] then
  315. stdnse.debug1("http: options.digestauth missing key: %s",k)
  316. bad = true
  317. break
  318. end
  319. end
  320. else
  321. bad = true
  322. stdnse.debug1("http: options.digestauth should be a table")
  323. end
  324. elseif (key == 'ntlmauth') then
  325. stdnse.debug1("Proceeding with ntlm message")
  326. elseif(key == 'bypass_cache' or key == 'no_cache' or key == 'no_cache_body') then
  327. if(type(value) ~= 'boolean') then
  328. stdnse.debug1("http: options.bypass_cache, options.no_cache, and options.no_cache_body must be boolean values")
  329. bad = true
  330. end
  331. elseif(key == 'redirect_ok') then
  332. if(type(value)~= 'function' and type(value)~='boolean' and type(value) ~= 'number') then
  333. stdnse.debug1("http: options.redirect_ok must be a function or boolean or number")
  334. bad = true
  335. end
  336. else
  337. stdnse.debug1("http: Unknown key in the options table: %s", key)
  338. end
  339. end
  340. return not(bad)
  341. end
  342. -- The following recv functions, and the function <code>next_response</code>
  343. -- follow a common pattern. They each take a <code>partial</code> argument
  344. -- whose value is data that has been read from the socket but not yet used in
  345. -- parsing, and they return as their second return value a new value for
  346. -- <code>partial</code>. The idea is that, for example, in reading from the
  347. -- socket to get the Status-Line, you will probably read too much and read part
  348. -- of the header. That part (the "partial") has to be retained when you go to
  349. -- parse the header. The common use pattern is this:
  350. -- <code>
  351. -- local partial
  352. -- status_line, partial = recv_line(socket, partial)
  353. -- ...
  354. -- header, partial = recv_header(socket, partial)
  355. -- ...
  356. -- </code>
  357. -- On error, the functions return <code>nil</code> and the second return value
  358. -- is an error message.
  359. -- Receive a single line (up to <code>\n</code>).
  360. local function recv_line(s, partial)
  361. local _, e
  362. local status, data
  363. local pos
  364. partial = partial or ""
  365. pos = 1
  366. while true do
  367. _, e = string.find(partial, "\n", pos, true)
  368. if e then
  369. break
  370. end
  371. status, data = s:receive()
  372. if not status then
  373. return status, data
  374. end
  375. pos = #partial
  376. partial = partial .. data
  377. end
  378. return string.sub(partial, 1, e), string.sub(partial, e + 1)
  379. end
  380. local function line_is_empty(line)
  381. return line == "\r\n" or line == "\n"
  382. end
  383. -- Receive up to and including the first blank line, but return everything up
  384. -- to and not including the final blank line.
  385. local function recv_header(s, partial)
  386. local lines = {}
  387. partial = partial or ""
  388. while true do
  389. local line
  390. line, partial = recv_line(s, partial)
  391. if not line then
  392. return line, partial
  393. end
  394. if line_is_empty(line) then
  395. break
  396. end
  397. lines[#lines + 1] = line
  398. end
  399. return table.concat(lines), partial
  400. end
  401. -- Receive until the connection is closed.
  402. local function recv_all(s, partial)
  403. local parts
  404. partial = partial or ""
  405. parts = {partial}
  406. while true do
  407. local status, part = s:receive()
  408. if not status then
  409. break
  410. else
  411. parts[#parts + 1] = part
  412. end
  413. end
  414. return table.concat(parts), ""
  415. end
  416. -- Receive exactly <code>length</code> bytes. Returns <code>nil</code> if that
  417. -- many aren't available.
  418. local function recv_length(s, length, partial)
  419. local parts, last
  420. partial = partial or ""
  421. parts = {}
  422. last = partial
  423. length = length - #last
  424. while length > 0 do
  425. local status
  426. parts[#parts + 1] = last
  427. status, last = s:receive()
  428. if not status then
  429. return nil
  430. end
  431. length = length - #last
  432. end
  433. -- At this point length is 0 or negative, and indicates the degree to which
  434. -- the last read "overshot" the desired length.
  435. if length == 0 then
  436. return table.concat(parts) .. last, ""
  437. else
  438. return table.concat(parts) .. string.sub(last, 1, length - 1), string.sub(last, length)
  439. end
  440. end
  441. -- Receive until the end of a chunked message body, and return the dechunked
  442. -- body.
  443. local function recv_chunked(s, partial)
  444. local chunks, chunk
  445. local chunk_size
  446. local pos
  447. chunks = {}
  448. repeat
  449. local line, hex, _, i
  450. line, partial = recv_line(s, partial)
  451. if not line then
  452. return nil, partial
  453. end
  454. pos = 1
  455. pos = skip_space(line, pos)
  456. -- Get the chunk-size.
  457. _, i, hex = string.find(line, "^([%x]+)", pos)
  458. if not i then
  459. return nil, string.format("Chunked encoding didn't find hex; got %q.", string.sub(line, pos, pos + 10))
  460. end
  461. pos = i + 1
  462. chunk_size = tonumber(hex, 16)
  463. if not chunk_size or chunk_size < 0 then
  464. return nil, string.format("Chunk size %s is not a positive integer.", hex)
  465. end
  466. -- Ignore chunk-extensions that may follow here.
  467. -- RFC 2616, section 2.1 ("Implied *LWS") seems to allow *LWS between the
  468. -- parts of a chunk-extension, but that is ambiguous. Consider this case:
  469. -- "1234;a\r\n =1\r\n...". It could be an extension with a chunk-ext-name
  470. -- of "a" (and no value), and a chunk-data beginning with " =", or it could
  471. -- be a chunk-ext-name of "a" with a value of "1", and a chunk-data
  472. -- starting with "...". We don't allow *LWS here, only ( SP | HT ), so the
  473. -- first interpretation will prevail.
  474. chunk, partial = recv_length(s, chunk_size, partial)
  475. if not chunk then
  476. return nil, partial
  477. end
  478. chunks[#chunks + 1] = chunk
  479. line, partial = recv_line(s, partial)
  480. if not line then
  481. -- this warning message was initially an error but was adapted
  482. -- to support broken servers, such as the Citrix XML Service
  483. stdnse.debug2("Didn't find CRLF after chunk-data.")
  484. elseif not string.match(line, "^\r?\n") then
  485. return nil, string.format("Didn't find CRLF after chunk-data; got %q.", line)
  486. end
  487. until chunk_size == 0
  488. return table.concat(chunks), partial
  489. end
  490. -- Receive a message body, assuming that the header has already been read by
  491. -- <code>recv_header</code>. The handling is sensitive to the request method
  492. -- and the status code of the response.
  493. local function recv_body(s, response, method, partial)
  494. local connection_close, connection_keepalive
  495. local version_major, version_minor
  496. local transfer_encoding
  497. local content_length
  498. local err
  499. partial = partial or ""
  500. -- First check for Connection: close and Connection: keep-alive. This is
  501. -- necessary to handle some servers that don't follow the protocol.
  502. connection_close = false
  503. connection_keepalive = false
  504. if response.header.connection then
  505. local offset, token
  506. offset = 0
  507. while true do
  508. offset, token = get_token(response.header.connection, offset + 1)
  509. if not offset then
  510. break
  511. end
  512. if string.lower(token) == "close" then
  513. connection_close = true
  514. elseif string.lower(token) == "keep-alive" then
  515. connection_keepalive = true
  516. end
  517. end
  518. end
  519. -- The HTTP version may also affect our decisions.
  520. version_major, version_minor = string.match(response["status-line"], "^HTTP/(%d+)%.(%d+)")
  521. -- See RFC 2616, section 4.4 "Message Length".
  522. -- 1. Any response message which "MUST NOT" include a message-body (such as
  523. -- the 1xx, 204, and 304 responses and any response to a HEAD request) is
  524. -- always terminated by the first empty line after the header fields...
  525. --
  526. -- Despite the above, some servers return a body with response to a HEAD
  527. -- request. So if an HTTP/1.0 server returns a response without Connection:
  528. -- keep-alive, or any server returns a response with Connection: close, read
  529. -- whatever's left on the socket (should be zero bytes).
  530. if string.upper(method) == "HEAD"
  531. or (response.status >= 100 and response.status <= 199)
  532. or response.status == 204 or response.status == 304 then
  533. if connection_close or (version_major == "1" and version_minor == "0" and not connection_keepalive) then
  534. return recv_all(s, partial)
  535. else
  536. return "", partial
  537. end
  538. end
  539. -- 2. If a Transfer-Encoding header field (section 14.41) is present and has
  540. -- any value other than "identity", then the transfer-length is defined by
  541. -- use of the "chunked" transfer-coding (section 3.6), unless the message
  542. -- is terminated by closing the connection.
  543. if response.header["transfer-encoding"]
  544. and response.header["transfer-encoding"] ~= "identity" then
  545. return recv_chunked(s, partial)
  546. end
  547. -- The Citrix XML Service sends a wrong "Transfer-Coding" instead of
  548. -- "Transfer-Encoding".
  549. if response.header["transfer-coding"]
  550. and response.header["transfer-coding"] ~= "identity" then
  551. return recv_chunked(s, partial)
  552. end
  553. -- 3. If a Content-Length header field (section 14.13) is present, its decimal
  554. -- value in OCTETs represents both the entity-length and the
  555. -- transfer-length. The Content-Length header field MUST NOT be sent if
  556. -- these two lengths are different (i.e., if a Transfer-Encoding header
  557. -- field is present). If a message is received with both a
  558. -- Transfer-Encoding header field and a Content-Length header field, the
  559. -- latter MUST be ignored.
  560. if response.header["content-length"] and not response.header["transfer-encoding"] then
  561. content_length = tonumber(response.header["content-length"])
  562. if not content_length then
  563. return nil, string.format("Content-Length %q is non-numeric", response.header["content-length"])
  564. end
  565. return recv_length(s, content_length, partial)
  566. end
  567. -- 4. If the message uses the media type "multipart/byteranges", and the
  568. -- transfer-length is not otherwise specified, then this self-delimiting
  569. -- media type defines the transfer-length. [sic]
  570. -- Case 4 is unhandled.
  571. -- 5. By the server closing the connection.
  572. return recv_all(s, partial)
  573. end
  574. -- Sets response["status-line"] and response.status.
  575. local function parse_status_line(status_line, response)
  576. local version, status, reason_phrase
  577. response["status-line"] = status_line
  578. version, status, reason_phrase = string.match(status_line,
  579. "^HTTP/(%d%.%d) *(%d+) *(.*)\r?\n$")
  580. if not version then
  581. return nil, string.format("Error parsing status-line %q.", status_line)
  582. end
  583. -- We don't have a use for the version; ignore it.
  584. response.status = tonumber(status)
  585. if not response.status then
  586. return nil, string.format("Status code is not numeric: %s", status)
  587. end
  588. return true
  589. end
  590. -- Sets response.header and response.rawheader.
  591. local function parse_header(header, response)
  592. local pos
  593. local name, words
  594. local s, e
  595. response.header = {}
  596. response.rawheader = stdnse.strsplit("\r?\n", header)
  597. pos = 1
  598. while pos <= #header do
  599. -- Get the field name.
  600. e, name = get_token(header, pos)
  601. if not name or e > #header or string.sub(header, e, e) ~= ":" then
  602. return nil, string.format("Can't get header field name at %q", string.sub(header, pos, pos + 30))
  603. end
  604. pos = e + 1
  605. -- Skip initial space.
  606. pos = skip_lws(header, pos)
  607. -- Get non-space words separated by LWS, then join them with a single space.
  608. words = {}
  609. while pos <= #header and not string.match(header, "^\r?\n", pos) do
  610. s = pos
  611. while not string.match(header, "^[ \t]", pos) and
  612. not string.match(header, "^\r?\n", pos) do
  613. pos = pos + 1
  614. end
  615. words[#words + 1] = string.sub(header, s, pos - 1)
  616. pos = skip_lws(header, pos)
  617. end
  618. -- Set it in our table.
  619. name = string.lower(name)
  620. if response.header[name] then
  621. response.header[name] = response.header[name] .. ", " .. table.concat(words, " ")
  622. else
  623. response.header[name] = table.concat(words, " ")
  624. end
  625. -- Next field, or end of string. (If not it's an error.)
  626. s, e = string.find(header, "^\r?\n", pos)
  627. if not e then
  628. return nil, string.format("Header field named %q didn't end with CRLF", name)
  629. end
  630. pos = e + 1
  631. end
  632. return true
  633. end
  634. -- Parse the contents of a Set-Cookie header field. The result is an array
  635. -- containing tables of the form
  636. --
  637. -- { name = "NAME", value = "VALUE", Comment = "...", Domain = "...", ... }
  638. --
  639. -- Every key except "name" and "value" is optional.
  640. --
  641. -- This function attempts to support the cookie syntax defined in RFC 2109
  642. -- along with the backwards-compatibility suggestions from its section 10,
  643. -- "HISTORICAL". Values need not be quoted, but if they start with a quote they
  644. -- will be interpreted as a quoted string.
  645. local function parse_set_cookie(s)
  646. local cookies
  647. local name, value
  648. local _, pos
  649. cookies = {}
  650. pos = 1
  651. while true do
  652. local cookie = {}
  653. -- Get the NAME=VALUE part.
  654. pos = skip_space(s, pos)
  655. pos, cookie.name = get_token(s, pos)
  656. if not cookie.name then
  657. return nil, "Can't get cookie name."
  658. end
  659. pos = skip_space(s, pos)
  660. if pos > #s or string.sub(s, pos, pos) ~= "=" then
  661. return nil, string.format("Expected '=' after cookie name \"%s\".", cookie.name)
  662. end
  663. pos = pos + 1
  664. pos = skip_space(s, pos)
  665. if string.sub(s, pos, pos) == "\"" then
  666. pos, cookie.value = get_quoted_string(s, pos)
  667. else
  668. _, pos, cookie.value = string.find(s, "([^;]*)[ \t]*", pos)
  669. pos = pos + 1
  670. end
  671. if not cookie.value then
  672. return nil, string.format("Can't get value of cookie named \"%s\".", cookie.name)
  673. end
  674. pos = skip_space(s, pos)
  675. -- Loop over the attributes.
  676. while pos <= #s and string.sub(s, pos, pos) == ";" do
  677. pos = pos + 1
  678. pos = skip_space(s, pos)
  679. pos, name = get_token(s, pos)
  680. if not name then
  681. return nil, string.format("Can't get attribute name of cookie \"%s\".", cookie.name)
  682. end
  683. pos = skip_space(s, pos)
  684. if pos <= #s and string.sub(s, pos, pos) == "=" then
  685. pos = pos + 1
  686. pos = skip_space(s, pos)
  687. if string.sub(s, pos, pos) == "\"" then
  688. pos, value = get_quoted_string(s, pos)
  689. else
  690. -- account for the possibility of the expires attribute being empty or improperly formatted
  691. local last_pos = pos
  692. if string.lower(name) == "expires" then
  693. -- For version 0 cookies we must allow one comma for "expires".
  694. _, pos, value = string.find(s, "([^,]*,[^;,]*)[ \t]*", pos)
  695. else
  696. _, pos, value = string.find(s, "([^;,]*)[ \t]*", pos)
  697. end
  698. -- account for the possibility of the expires attribute being empty or improperly formatted
  699. if ( not(pos) ) then
  700. _, pos, value = s:find("([^;]*)", last_pos)
  701. end
  702. pos = pos + 1
  703. end
  704. if not value then
  705. return nil, string.format("Can't get value of cookie attribute \"%s\".", name)
  706. end
  707. else
  708. value = true
  709. end
  710. cookie[name:lower()] = value
  711. pos = skip_space(s, pos)
  712. end
  713. cookies[#cookies + 1] = cookie
  714. if pos > #s then
  715. break
  716. end
  717. if string.sub(s, pos, pos) ~= "," then
  718. return nil, string.format("Syntax error after cookie named \"%s\".", cookie.name)
  719. end
  720. pos = pos + 1
  721. pos = skip_space(s, pos)
  722. end
  723. return cookies
  724. end
  725. -- Read one response from the socket <code>s</code> and return it after
  726. -- parsing.
  727. local function next_response(s, method, partial)
  728. local response
  729. local status_line, header, body
  730. local status, err
  731. partial = partial or ""
  732. response = {
  733. status=nil,
  734. ["status-line"]=nil,
  735. header={},
  736. rawheader={},
  737. body=""
  738. }
  739. status_line, partial = recv_line(s, partial)
  740. if not status_line then
  741. return nil, partial
  742. end
  743. status, err = parse_status_line(status_line, response)
  744. if not status then
  745. return nil, err
  746. end
  747. header, partial = recv_header(s, partial)
  748. if not header then
  749. return nil, partial
  750. end
  751. status, err = parse_header(header, response)
  752. if not status then
  753. return nil, err
  754. end
  755. body, partial = recv_body(s, response, method, partial)
  756. if not body then
  757. return nil, partial
  758. end
  759. response.body = body
  760. -- We have the Status-Line, header, and body; now do any postprocessing.
  761. response.cookies = {}
  762. if response.header["set-cookie"] then
  763. response.cookies, err = parse_set_cookie(response.header["set-cookie"])
  764. if not response.cookies then
  765. -- Ignore a cookie parsing error.
  766. response.cookies = {}
  767. end
  768. end
  769. return response, partial
  770. end
  771. --- Tries to extract the max number of requests that should be made on
  772. -- a keep-alive connection based on "Keep-Alive: timeout=xx,max=yy" response
  773. -- header.
  774. --
  775. -- If the value is not available, an arbitrary value is used. If the connection
  776. -- is not explicitly closed by the server, this same value is attempted.
  777. --
  778. -- @param response The http response - Might be a table or a raw response
  779. -- @return The max number of requests on a keep-alive connection
  780. local function getPipelineMax(response)
  781. -- Allow users to override this with a script-arg
  782. local pipeline = stdnse.get_script_args({'http.pipeline', 'pipeline'})
  783. if(pipeline) then
  784. return tonumber(pipeline)
  785. end
  786. if response then
  787. if response.header and response.header.connection ~= "close" then
  788. if response.header["keep-alive"] then
  789. local max = string.match( response.header["keep-alive"], "max=(%d*)")
  790. if(max == nil) then
  791. return 40
  792. end
  793. return tonumber(max)
  794. else
  795. return 40
  796. end
  797. end
  798. end
  799. return 1
  800. end
  801. --- Builds a string to be added to the request mod_options table
  802. --
  803. -- @param cookies A cookie jar just like the table returned parse_set_cookie.
  804. -- @param path If the argument exists, only cookies with this path are included to the request
  805. -- @return A string to be added to the mod_options table
  806. local function buildCookies(cookies, path)
  807. local cookie = ""
  808. if type(cookies) == 'string' then return cookies end
  809. for _, ck in ipairs(cookies or {}) do
  810. local ckpath = ck["path"]
  811. if not path or not ckpath
  812. or ckpath == path
  813. or ckpath:sub(-1) == "/" and ckpath == path:sub(1, ckpath:len())
  814. or ckpath .. "/" == path:sub(1, ckpath:len()+1)
  815. then
  816. cookie = cookie .. ck["name"] .. "=" .. ck["value"] .. "; "
  817. end
  818. end
  819. return cookie:gsub("; $","")
  820. end
  821. -- HTTP cache.
  822. -- Cache of GET and HEAD requests. Uses <"host:port:path", record>.
  823. -- record is in the format:
  824. -- result: The result from http.get or http.head
  825. -- last_used: The time the record was last accessed or made.
  826. -- get: Was the result received from a request to get or recently wiped?
  827. -- size: The size of the record, equal to #record.result.body.
  828. local cache = {size = 0};
  829. local function check_size (cache)
  830. local max_size = tonumber(stdnse.get_script_args({'http.max-cache-size', 'http-max-cache-size'}) or 1e6);
  831. local size = cache.size;
  832. if size > max_size then
  833. stdnse.debug1(
  834. "Current http cache size (%d bytes) exceeds max size of %d",
  835. size, max_size);
  836. table.sort(cache, function(r1, r2)
  837. return (r1.last_used or 0) < (r2.last_used or 0);
  838. end);
  839. for i, record in ipairs(cache) do
  840. if size <= max_size then break end
  841. local result = record.result;
  842. if type(result.body) == "string" then
  843. size = size - record.size;
  844. record.size, record.get, result.body = 0, false, "";
  845. end
  846. end
  847. cache.size = size;
  848. end
  849. stdnse.debug2("Final http cache size (%d bytes) of max size of %d",
  850. size, max_size);
  851. return size;
  852. end
  853. -- Unique value to signal value is being retrieved.
  854. -- Also holds <mutex, thread> pairs, working thread is value
  855. local WORKING = setmetatable({}, {__mode = "v"});
  856. local function lookup_cache (method, host, port, path, options)
  857. if(not(validate_options(options))) then
  858. return nil
  859. end
  860. options = options or {};
  861. local bypass_cache = options.bypass_cache; -- do not lookup
  862. local no_cache = options.no_cache; -- do not save result
  863. local no_cache_body = options.no_cache_body; -- do not save body
  864. if type(port) == "table" then port = port.number end
  865. local key = stdnse.get_hostname(host)..":"..port..":"..path;
  866. local mutex = nmap.mutex(tostring(lookup_cache)..key);
  867. local state = {
  868. mutex = mutex,
  869. key = key,
  870. method = method,
  871. bypass_cache = bypass_cache,
  872. no_cache = no_cache,
  873. no_cache_body = no_cache_body,
  874. };
  875. while true do
  876. mutex "lock";
  877. local record = cache[key];
  878. if bypass_cache or record == nil or method ~= record.method then
  879. WORKING[mutex] = coroutine.running();
  880. cache[key], state.old_record = WORKING, record;
  881. return nil, state;
  882. elseif record == WORKING then
  883. local working = WORKING[mutex];
  884. if working == nil or coroutine.status(working) == "dead" then
  885. -- thread died before insert_cache could be called
  886. cache[key] = nil; -- reset
  887. end
  888. mutex "done";
  889. else
  890. mutex "done";
  891. record.last_used = os.time();
  892. return tcopy(record.result), state;
  893. end
  894. end
  895. end
  896. local function response_is_cacheable(response)
  897. -- if response.status is nil, then an error must have occurred during the request
  898. -- and we probably don't want to cache the response
  899. if not response.status then
  900. return false
  901. end
  902. -- 206 Partial Content. RFC 2616, 1.34: "...a cache that does not support the
  903. -- Range and Content-Range headers MUST NOT cache 206 (Partial Content)
  904. -- responses."
  905. if response.status == 206 then
  906. return false
  907. end
  908. -- RFC 2616, 13.4. "A response received with any [status code other than 200,
  909. -- 203, 206, 300, 301 or 410] (e.g. status codes 302 and 307) MUST NOT be
  910. -- returned in a reply to a subsequent request unless there are cache-control
  911. -- directives or another header(s) that explicitly allow it."
  912. -- We violate the standard here and allow these other codes to be cached,
  913. -- with the exceptions listed below.
  914. -- 401 Unauthorized. Caching this would prevent us from retrieving it later
  915. -- with the correct credentials.
  916. if response.status == 401 then
  917. return false
  918. end
  919. return true
  920. end
  921. local function insert_cache (state, response)
  922. local key = assert(state.key);
  923. local mutex = assert(state.mutex);
  924. if response == nil or state.no_cache or not response_is_cacheable(response) then
  925. cache[key] = state.old_record;
  926. else
  927. local record = {
  928. result = tcopy(response),
  929. last_used = os.time(),
  930. method = state.method,
  931. size = type(response.body) == "string" and #response.body or 0,
  932. };
  933. response = record.result; -- only modify copy
  934. cache[key], cache[#cache+1] = record, record;
  935. if state.no_cache_body then
  936. response.body = "";
  937. end
  938. if type(response.body) == "string" then
  939. cache.size = cache.size + #response.body;
  940. check_size(cache);
  941. end
  942. end
  943. mutex "done";
  944. end
  945. -- Return true if the given method requires a body in the request. In case no
  946. -- body was supplied we must send "Content-Length: 0".
  947. local function request_method_needs_content_length(method)
  948. return method == "POST"
  949. end
  950. -- For each of the following request functions, <code>host</code> may either be
  951. -- a string or a table, and <code>port</code> may either be a number or a
  952. -- table.
  953. --
  954. -- The format of the return value is a table with the following structure:
  955. -- {status = 200, status-line = "HTTP/1.1 200 OK", header = {}, rawheader = {}, body ="<html>...</html>"}
  956. -- The header table has an entry for each received header with the header name
  957. -- being the key. The table also has an entry named "status" which contains the
  958. -- http status code of the request.
  959. -- In case of an error, the status is nil and status-line describes the problem.
  960. local function http_error(status_line)
  961. return {
  962. status = nil,
  963. ["status-line"] = status_line,
  964. header = {},
  965. rawheader = {},
  966. body = nil,
  967. }
  968. end
  969. --- Build an HTTP request from parameters and return it as a string.
  970. --
  971. -- @param host The host this request is intended for.
  972. -- @param port The port this request is intended for.
  973. -- @param method The method to use.
  974. -- @param path The path for the request.
  975. -- @param options A table of options, which may include the keys:
  976. -- * <code>header</code>: A table containing additional headers to be used for the request.
  977. -- * <code>content</code>: The content of the message (content-length will be added -- set header['Content-Length'] to override)
  978. -- * <code>cookies</code>: A table of cookies in the form returned by <code>parse_set_cookie</code>.
  979. -- * <code>auth</code>: A table containing the keys <code>username</code> and <code>password</code>.
  980. -- @return A request string.
  981. -- @see generic_request
  982. local function build_request(host, port, method, path, options)
  983. if(not(validate_options(options))) then
  984. return nil
  985. end
  986. options = options or {}
  987. -- Private copy of the options table, used to add default header fields.
  988. local mod_options = {
  989. header = {
  990. Connection = "close",
  991. Host = get_host_field(host, port),
  992. ["User-Agent"] = USER_AGENT
  993. }
  994. }
  995. if options.cookies then
  996. local cookies = buildCookies(options.cookies, path)
  997. if #cookies > 0 then
  998. mod_options.header["Cookie"] = cookies
  999. end
  1000. end
  1001. if options.auth and not (options.auth.digest or options.auth.ntlm) then
  1002. local username = options.auth.username
  1003. local password = options.auth.password
  1004. local credentials = "Basic " .. base64.enc(username .. ":" .. password)
  1005. mod_options.header["Authorization"] = credentials
  1006. end
  1007. if options.digestauth then
  1008. local order = {"username", "realm", "nonce", "digest-uri", "algorithm", "response", "qop", "nc", "cnonce"}
  1009. local no_quote = {algorithm=true, qop=true, nc=true}
  1010. local creds = {}
  1011. for _,k in ipairs(order) do
  1012. local v = options.digestauth[k]
  1013. if v then
  1014. if no_quote[k] then
  1015. table.insert(creds, ("%s=%s"):format(k,v))
  1016. else
  1017. if k == "digest-uri" then
  1018. table.insert(creds, ('%s="%s"'):format("uri",v))
  1019. else
  1020. table.insert(creds, ('%s="%s"'):format(k,v))
  1021. end
  1022. end
  1023. end
  1024. end
  1025. local credentials = "Digest "..table.concat(creds, ", ")
  1026. mod_options.header["Authorization"] = credentials
  1027. end
  1028. if options.ntlmauth then
  1029. mod_options.header["Authorization"] = "NTLM " .. base64.enc(options.ntlmauth)
  1030. end
  1031. local body
  1032. -- Build a form submission from a table, like "k1=v1&k2=v2".
  1033. if type(options.content) == "table" then
  1034. local parts = {}
  1035. local k, v
  1036. for k, v in pairs(options.content) do
  1037. parts[#parts + 1] = url.escape(k) .. "=" .. url.escape(v)
  1038. end
  1039. body = table.concat(parts, "&")
  1040. mod_options.header["Content-Type"] = "application/x-www-form-urlencoded"
  1041. elseif options.content then
  1042. body = options.content
  1043. elseif request_method_needs_content_length(method) then
  1044. body = ""
  1045. end
  1046. if body then
  1047. mod_options.header["Content-Length"] = #body
  1048. end
  1049. -- Add any other header fields into the local copy.
  1050. table_augment(mod_options, options)
  1051. -- We concat this string manually to allow null bytes in requests
  1052. local request_line = method.." "..path.." HTTP/1.1"
  1053. local header = {}
  1054. for name, value in pairs(mod_options.header) do
  1055. -- we concat this string manually to allow null bytes in requests
  1056. header[#header + 1] = name..": "..value
  1057. end
  1058. return request_line .. "\r\n" .. stdnse.strjoin("\r\n", header) .. "\r\n\r\n" .. (body or "")
  1059. end
  1060. --- Send a string to a host and port and return the HTTP result. This function
  1061. -- is like <code>generic_request</code>, to be used when you have a ready-made
  1062. -- request, not a collection of request parameters.
  1063. --
  1064. -- @param host The host to connect to.
  1065. -- @param port The port to connect to.
  1066. -- @param options A table of other parameters. It may have any of these fields:
  1067. -- * <code>timeout</code>: A timeout used for socket operations.
  1068. -- * <code>header</code>: A table containing additional headers to be used for the request.
  1069. -- * <code>content</code>: The content of the message (content-length will be added -- set header['Content-Length'] to override)
  1070. -- * <code>cookies</code>: A table of cookies in the form returned by <code>parse_set_cookie</code>.
  1071. -- * <code>auth</code>: A table containing the keys <code>username</code> and <code>password</code>.
  1072. -- @return A response table, see module documentation for description.
  1073. -- @see generic_request
  1074. local function request(host, port, data, options)
  1075. if(not(validate_options(options))) then
  1076. return http_error("Options failed to validate.")
  1077. end
  1078. local method
  1079. local header
  1080. local response
  1081. options = options or {}
  1082. if type(port) == 'table' then
  1083. if port.protocol and port.protocol ~= 'tcp' then
  1084. stdnse.debug1("http.request() supports the TCP protocol only, your request to %s cannot be completed.", host)
  1085. return http_error("Unsupported protocol.")
  1086. end
  1087. end
  1088. method = string.match(data, "^(%S+)")
  1089. local socket, partial, opts = comm.tryssl(host, port, data, { timeout = options.timeout })
  1090. if not socket then
  1091. return http_error("Error creating socket.")
  1092. end
  1093. repeat
  1094. response, partial = next_response(socket, method, partial)
  1095. if not response then
  1096. return http_error("There was an error in next_response function.")
  1097. end
  1098. -- See RFC 2616, sections 8.2.3 and 10.1.1, for the 100 Continue status.
  1099. -- Sometimes a server will tell us to "go ahead" with a POST body before
  1100. -- sending the real response. If we got one of those, skip over it.
  1101. until not (response.status >= 100 and response.status <= 199)
  1102. socket:close()
  1103. -- if SSL was used to retrieve the URL mark this in the response
  1104. response.ssl = ( opts == 'ssl' )
  1105. return response
  1106. end
  1107. ---Do a single request with a given method. The response is returned as the standard
  1108. -- response table (see the module documentation).
  1109. --
  1110. -- The <code>get</code>, <code>head</code>, and <code>post</code> functions are simple
  1111. -- wrappers around <code>generic_request</code>.
  1112. --
  1113. -- Any 1XX (informational) responses are discarded.
  1114. --
  1115. -- @param host The host to connect to.
  1116. -- @param port The port to connect to.
  1117. -- @param method The method to use; for example, 'GET', 'HEAD', etc.
  1118. -- @param path The path to retrieve.
  1119. -- @param options [optional] A table that lets the caller control socket timeouts, HTTP headers, and other parameters. For full documentation, see the module documentation (above).
  1120. -- @return A response table, see module documentation for description.
  1121. -- @see request
  1122. function generic_request(host, port, method, path, options)
  1123. if(not(validate_options(options))) then
  1124. return http_error("Options failed to validate.")
  1125. end
  1126. local digest_auth = options and options.auth and options.auth.digest
  1127. local ntlm_auth = options and options.auth and options.auth.ntlm
  1128. if (digest_auth or ntlm_auth) and not have_ssl then
  1129. stdnse.debug1("http: digest and ntlm auth require openssl.")
  1130. end
  1131. if digest_auth and have_ssl then
  1132. -- If we want to do digest authentication, we have to make an initial
  1133. -- request to get realm, nonce and other fields.
  1134. local options_with_auth_removed = tcopy(options)
  1135. options_with_auth_removed["auth"] = nil
  1136. local r = generic_request(host, port, method, path, options_with_auth_removed)
  1137. local h = r.header['www-authenticate']
  1138. if not r.status or (h and not string.find(h:lower(), "digest.-realm")) then
  1139. stdnse.debug1("http: the target doesn't support digest auth or there was an error during request.")
  1140. return http_error("The target doesn't support digest auth or there was an error during request.")
  1141. end
  1142. -- Compute the response hash
  1143. local dmd5 = sasl.DigestMD5:new(h, options.auth.username, options.auth.password, method, path)
  1144. local _, digest_table = dmd5:calcDigest()
  1145. options.digestauth = digest_table
  1146. end
  1147. if ntlm_auth and have_ssl then
  1148. local custom_options = tcopy(options) -- to be sent with the type 1 request
  1149. custom_options["auth"] = nil -- removing the auth options
  1150. -- let's check if the target supports ntlm with a simple get request.
  1151. -- Setting a timeout here other than nil messes up the authentication if this is the first device sending
  1152. -- a request to the server. Don't know why.
  1153. custom_options.timeout = nil
  1154. local response = generic_request(host, port, method, path, custom_options)
  1155. local authentication_header = response.header['www-authenticate']
  1156. -- get back the timeout option.
  1157. custom_options.timeout = options.timeout
  1158. custom_options.header = options.header or {}
  1159. custom_options.header["Connection"] = "Keep-Alive" -- Keep-Alive headers are needed for authentication.
  1160. if (not authentication_header) or (not response.status) or (not string.find(authentication_header:lower(), "ntlm")) then
  1161. stdnse.debug1("http: the target doesn't support NTLM or there was an error during request.")
  1162. return http_error("The target doesn't support NTLM or there was an error during request.")
  1163. end
  1164. -- ntlm works with three messages. we send a request, it sends
  1165. -- a challenge, we respond to the challenge.
  1166. local hostname = options.auth.hostname or "localhost" -- the hostname to be sent
  1167. local workstation_name = options.auth.workstation_name or "NMAP" -- the workstation name to be sent
  1168. local username = options.auth.username -- the username as specified
  1169. local auth_blob = "NTLMSSP\x00" .. -- NTLM signature
  1170. "\x01\x00\x00\x00" .. -- NTLM Type 1 message
  1171. bin.pack("<I", 0xa208b207) .. -- flags 56, 128, Version, Extended Security, Always Sign, Workstation supplied, Domain Supplied, NTLM Key, OEM, Unicode
  1172. bin.pack("<SSISSI",#workstation_name, #workstation_name, 40 + #hostname, #hostname, #hostname, 40) .. -- Supplied Domain and Workstation
  1173. bin.pack("CC<S", -- OS version info
  1174. 5, 1, 2600) .. -- 5.1.2600
  1175. "\x00\x00\x00\x0f" .. -- OS version info end (static 0x0000000f)
  1176. hostname.. -- HOST NAME
  1177. workstation_name --WORKSTATION name
  1178. custom_options.ntlmauth = auth_blob
  1179. -- check if the protocol is tcp
  1180. if type(port) == 'table' then
  1181. if port.protocol and port.protocol ~= 'tcp' then
  1182. stdnse.debug1("NTLM authentication supports the TCP protocol only, your request to %s cannot be completed.", host)
  1183. return http_error("Unsupported protocol.")
  1184. end
  1185. end
  1186. -- tryssl uses ssl if needed. sends the type 1 message.
  1187. local socket, partial, opts = comm.tryssl(host, port, build_request(host, port, method, path, custom_options), { timeout = options.timeout })
  1188. if not socket then
  1189. return http_error("Could not create socket to send type 1 message.")
  1190. end
  1191. repeat
  1192. response, partial = next_response(socket, method, partial)
  1193. if not response then
  1194. return http_error("There was error in receivin…

Large files files are truncated, but you can click here to view the full file