This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Get Snapshot from Hikvision Camera
#3
(13.03.2023, 12:51)admin Wrote: Are you sure that this uses Basic auth but not digest?

I´ll try it with digest first. I wroute in the post "Email with attachement" but you tell me to try with basic auth. But this post is very old and I create a new more specific.

Trying with digest auth this is the result:

Code:
* arg: 1
  * string: <!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error</p>
</body>
</html>
<!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error</p>
</body>
</html>

* arg: 2
  * number: 401
* arg: 3
  * table:
   ["server"]
    * string: webserver
   ["content-type"]
    * string: text/html
   ["connection"]
    * string: close
   ["date"]
    * string: Mon, 13 Mar 2023 10:37:01 GMT
   ["x-frame-options"]
    * string: SAMEORIGIN
   ["www-authenticate"]
    * string: Digest qop="auth", realm="IP Camera(F0849)", nonce="5a6d566c5a475a6d59324d365a474534596a67794d6d493d", stale="FALSE"
   ["content-length"]
    * string: 178

And the code is:

Code:
local url = 'http://user:Pass@'..IP..'/ISAPI/Streaming/channels/101/picture'


function SnapshotCamaraIP (url)
 
  --Meter url de la camara http://admin:pass@"IP"/snapshot.jpeg
  local skthttp = require('socket.http')
  local skturl = require('socket.url')
  local ltn12 = require('ltn12')
  local md5sum = require('encdec').md5

  local hash = function(...)
    return md5sum(table.concat({...}, ':'))
    end

  local parse_header = function(header)
    local result = {}
    for key, value in (header .. ','):gmatch('(%w+)=(.-),') do
      if value:sub(1, 1) == '"' then -- strip quotes
        result[ key:lower() ] = value:sub(2, -2)
      else
        result[ key:lower() ] = value
      end
    end

    return result
   
        end

    local make_digest_header = function(headers)
      local digest = {}
      for _, header in ipairs(headers) do
        if not header.unquote then
          header[ 2 ] = '"' .. header[ 2 ] .. '"'
        end

        digest[ #digest + 1 ] = header[ 1 ] .. '=' .. header[ 2 ]
      end
      return 'Digest ' .. table.concat(digest, ', ')
    end

local _request = function(req)
  if not req.url then
    return nil, 'missing url'
  end

  local url = skturl.parse(req.url)
  local user, password = url.user, url.password
    --log(user,password)
  if not user or not password then
    return nil, 'missing credentials in url'
  end

  url.user, url.password, url.authority, url.userinfo = nil, nil, nil, nil
  req.url = skturl.build(url)
  local source
  if req.source then
    local chunks = {}
    local capture = function(chunk)
      if chunk then
        chunks[ #chunks + 1 ] = chunk
      end
      return chunk
    end
    local chunk_id = 0
    source = function()
      chunk_id = chunk_id + 1
      return chunks[ chunk_id ]
    end
    req.source = ltn12.source.chain(req.source, capture)
  end
  local body, code, hdrs = skthttp.request(req)
  --log(body, code, hdrs)
  if code == 401 and hdrs['www-authenticate'] then
    local ht = parse_header(hdrs['www-authenticate'])
    log(ht)
    if not ht.realm or not ht.nonce then
      log("REALM")
      return nil, 'missing realm/nonce from response'
    end
    if ht.qop ~= 'auth' then
      log("QOP")
      return nil, 'unsupported qop ' .. tostring(ht.qop)
    end
    if ht.algorithm and ht.algorithm:lower() ~= 'md5' then
      log("MD5")
      return nil, 'unsupported algo ' .. tostring(ht.algorithm)
    end
    local nc = '00000001'
    local cnonce = string.format('%08x', os.time())
    local uri = skturl.build({ path = url.path, query = url.query })
    local method = req.method or 'GET'
    local response = hash(
      hash(user, ht.realm, password),
      ht.nonce,
      nc,
      cnonce,
      'auth',
      hash(method, uri)
    )
    req.headers = req.headers or {}
    local auth = {
      { 'username', user },
      { 'realm', ht.realm },
      { 'nonce', ht.nonce },
      { 'uri', uri },
      { 'cnonce', cnonce },
      { 'nc', nc, unquote = true },
      { 'qop', 'auth' },
      { 'algorithm', 'MD5' },
      { 'response', response },
    }
    if ht.opaque then
      table.insert(auth, { 'opaque', ht.opaque })
    end
    req.headers.authorization = make_digest_header(auth)
    if not req.headers.cookie and hdrs['set-cookie'] then
      -- not really correct but enough for httpbin
      local cookie = (hdrs['set-cookie'] .. ';'):match('(.-=.-)[;,]')
      if cookie then
        req.headers.cookie = '$Version: 0; ' .. cookie .. ';'
      end
    end
    if req.source then
      req.source = source
    end
    body, code, hdrs = skthttp.request(req)
  end

  return body, code, hdrs
end

local request = function(url)
  local t = type(url)
  if t == 'table' then
    return _request(table.clone(url))
  elseif t == 'string' then
    local req = {}
    local _, code, headers = _request({ url = url, sink = ltn12.sink.table(req) })
    return table.concat(req), code, headers
  end
end
 
  image, err, hdrs = request(url)
  log(image, err, hdrs)
  return image,err

end

Thanks
Reply


Messages In This Thread
RE: Get Snapshot from Hikvision Camera - by DGrandes - 14.03.2023, 07:57

Forum Jump: