Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ONVIF Soap Fault: Error 401: HTTP 401 Unauthorized (Fuluva camera) #178

Closed
kjlaw89 opened this issue Dec 17, 2020 · 8 comments
Closed

ONVIF Soap Fault: Error 401: HTTP 401 Unauthorized (Fuluva camera) #178

kjlaw89 opened this issue Dec 17, 2020 · 8 comments

Comments

@kjlaw89
Copy link

kjlaw89 commented Dec 17, 2020

I'm currently having any issue authenticating with an ONVIF camera. The camera in question is a Fuluva A-Series camera (http://fuluva.cn/A-DFQ610-5MP-POE.html). It's not much, but here are the details I'm using when connecting:

Cam {
hostname: '192.168.112.129',
username: 'admin',
password: '123456',
port: 80,
path: '/onvif/device_service',
timeout: 120000,
agent: false,
preserveAddress: true,
events: {} }
Error: ONVIF SOAP Fault: Error 401: HTTP 401 Unauthorized
at /path/node_modules/onvif/lib/utils.js:91:13
at Parser. (/path/node_modules/onvif/node_modules/xml2js/lib/parser.js:304:18)
at emitOne (events.js:96:13)
at Parser.emit (events.js:188:7)
at Object.onclosetag (/path/node_modules/onvif/node_modules/xml2js/lib/parser.js:262:26)
at emit (/path/node_modules/sax/lib/sax.js:639:35)
at emitNode (/path/node_modules/sax/lib/sax.js:644:5)
at closeTag (/path/node_modules/sax/lib/sax.js:903:7)
at Object.write (/path/node_modules/sax/lib/sax.js:1444:13)
at Parser.exports.Parser.Parser.parseString (/path/node_modules/onvif/node_modules/xml2js/lib/parser.js:323:31)

I've verified that ONVIF is enabled for the camera and also made sure the camera's time was correct. We've used this library for connecting to other cameras so I know the code itself is fine.

I also attempted this process with the popular go onvif library and it was able to connect and authenticate (verified by disabling the authenticating and getting back a 401 as a result), so there must be some difference there.

If you need any other details, let me know. I'd be happy to get the results back from the camera if it'd assist, just need to know where to put the appropriate logging.

@agsh
Copy link
Owner

agsh commented Dec 17, 2020

Hello! For now I think that this is an error with http headers that caused unauthorised response, but I can be mistaken. If you can grab the http requests via wireshark form go-onvif and onvif, this will be great to compare, what's the difference.

@kjlaw89
Copy link
Author

kjlaw89 commented Dec 18, 2020

This is a headless Linux setup, so I used tcpdump to get the data. Hopefully it contains what you're looking for:

Go: https://gist.github.com/kjlaw89/02472f85f9e7c2581af9830100f19708
Node: https://gist.github.com/kjlaw89/553d8d3bd3b3b44ac7955b876006ca1f

One thing I noticed is it looks like the Node ONVIF library attempts to request the DateAndTime as part of its initial request, but this camera returns back a 401 Unauthorized for the attempt.

Hopefully this helps! Let me know if you need anything else!

@kjlaw89
Copy link
Author

kjlaw89 commented Dec 22, 2020

Hey @agsh I was just curious if you've had a chance to review. Do you need any more information from me or need to to test any changes?

@agsh
Copy link
Owner

agsh commented Dec 23, 2020

@kjlaw89 Hi! Can you change locally here

body:

these lines:

'<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
'<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">' +
'<GetSystemDateAndTime xmlns="http://www.onvif.org/ver10/device/wsdl"/>' +
'</s:Body>' +
'</s:Envelope>'

to these:

this._envelopeHeader() +
'<GetSystemDateAndTime xmlns="http://www.onvif.org/ver10/device/wsdl"/>' +
this._envelopeFooter()

And test it.
This will add auth headers to getSystemDateAndTime request. It seems strange for me to this cam, because it the ONVIF spec, as I remember this request doesn't need auth at all.

@RogerHardiman
Copy link
Collaborator

I've found quite a lot of cameras that require authentication on getSystemDateAndTime, even though it is not required in the specification. You are supposed to know the far end camera time so that you can adjust the time offset when sending Auth Headers for cameras that have an incorrect clock, (ie not synced to a NTP time source and the camera's clock is wrong). But the industry seems to accept that you must have a camera synced to the right time and you must have authentication on this ONVIF command

@kjlaw89
Copy link
Author

kjlaw89 commented Dec 23, 2020

@agsh That seems to have worked. I'm getting some "Unrecognized configuration" errors with this camera, but that doesn't seem to be stopping it from functioning. I am no longer getting the 401 Unauthorized error though, so that's a plus!

@agsh
Copy link
Owner

agsh commented Dec 25, 2020

@RogerHardiman Thanks for explanation!
@kjlaw89 I've added auth headers into this method in master and v0.6.4

@RogerHardiman
Copy link
Collaborator

RogerHardiman commented Nov 9, 2022

I've just hit the same problem and can tell you what the actual problem was.

This library sends a getSystemDateAndTime command with NO authentication. This is part of the ONVIF spec and needed to get the date/time on Axis cameras where the camera clock is incorrect and 'replay attach protection' is switch on.

If it fails, with an unauthorized command, the library then re-sends it WITH the authentication.

But because of a feature on Axis, we have to try the unauthenticated command first.

The bug was that the library checked if the ASCII string that came back from the camera had the words "sender not authorized". That is what it matched.
But a Hik Camera I have returns "Unathorized"
Another camera returns "The security token could not be authenticated or authorized"
Neither of these math the "sender not authorised" and the library goes and does the wrong thing.

The proper fix is to check the HTTP Status code and see if the camera sends back a 401 Error code and not to match ASCII strings now that I've seen three different sentences.

I've just fixed this properly in my 'roger' branch of the library.

The workaround posted earlier to always send authentication will work with most cameras but will fail with Axis cameras when the camera clock (or the local computer clock) differ by more than 15 seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants