themactep / thingino-firmware

Open-source firmware for Ingenic SoC IP cameras
https://thingino.com
MIT License
121 stars 38 forks source link

Authentication for snapshot with an onvif client #128

Closed roleoroleo closed 3 weeks ago

roleoroleo commented 1 month ago

When authentication is enabled in onvif.conf, the onvif client tries to use the same user:password when it calls the snapshot. But the snapshot is a http call and it's handled outside the onvif logic. The user configured for onvif comes from /etc/prudynt.cfg (default thingino). If it's not a security issue the same user should be added to /etc/httpd.conf to authorize the snapshot: /cgi-bin/image.cgi:thingino:thingino

themactep commented 1 month ago

tracking password changes in configs is pain. what if we create a system user onvif and use the system authenticatation for that, like we do with root? so that would be

/cgi-bin/image.cgi:onvif:*
roleoroleo commented 1 month ago

Yes, could be the best solution. I will add system auth to onvif_simple_server.

--- EDIT ---

No... onvif_simple_server uses digest authentication and I need the password in clear text to generate the digest. I can't use passwd/shadow.

roleoroleo commented 1 month ago

What do you think about this procedure:

Maybe you can add username/password editing in the webui.

If you like this procedure I can create a new pr.

check_pwd.sh:

#!/bin/sh

USER=$1
NEW_PWD=$2
OLD_PWD_SALT=$(awk -v userpat="$USER" -F[:$] '$1 == userpat {print $4}' /etc/shadow)
OLD_PWD_HASH=$(awk -v userpat="$USER" -F[:$] '$1 == userpat {print $5}' /etc/shadow)
NEW_PWD_LINE=$(mkpasswd -m sha512 -S $OLD_PWD_SALT $NEW_PWD)
NEW_PWD_SALT=$(echo $NEW_PWD_LINE | awk -F[:$] '{print $3}')
NEW_PWD_HASH=$(echo $NEW_PWD_LINE | awk -F[:$] '{print $4}')
if [ "$OLD_PWD_HASH" != "$NEW_PWD_HASH" ]; then
        echo "Updating password for onvif user"
        echo $USER:$NEW_PWD | chpasswd -c sha512
fi
themactep commented 1 month ago

I have added thingino:thingino for now, as per your initial request. Working on the web ui and backend to handle changes from web ui.

themactep commented 1 month ago

I have added web ui for onvif credentials (b1c87916722a55807f437608088a6300edf7202f). It saves plain text creds in /etc/webui/onvif.conf and creates/updates a corresponding user (onvif) for system authentication.

roleoroleo commented 1 month ago

So, when I change user and password in the webui, they are stored in /etc/webui.onvif.conf And a the user is created/updated in passwd/shadow Tested, it works!

I think two details are missing:

themactep commented 1 month ago

i just realized that httpd does not provide multichoice authentication for access to a resource, it stacks up security instead. now when i open the page for osd fonts control it demands a second password, lol. i think i will have to add an alternative script exclusively for onvif access.

themactep commented 1 month ago

@roleoroleo do we need authentication on /onvif/ handled by onvif-simple-server if we can just leave it to httpd?

roleoroleo commented 1 month ago

Unfortunately basic authentication is not compliant with onvif specification:

https://www.onvif.org/specs/core/ONVIF-Core-Specification.pdf

Does busybox support digest?

roleoroleo commented 1 month ago

Another way is to use a different http daemon but we should change the port. Or a reverse proxy...

roleoroleo commented 1 month ago

i just realized that httpd does not provide multichoice authentication for access to a resource, it stacks up security instead. now when i open the page for osd fonts control it demands a second password, lol. i think i will have to add an alternative script exclusively for onvif access.

Could you eplain me better this problem? I'm trying to obtain the same behavior but it works with my cam.

themactep commented 1 month ago

we have just changed the the web a little. switched to a new generation of the streamer, changed webui preview to websockets, replaced image generating backend cgi script with a C cli tool. and we moved web from /cgi-bin/ to /x/ for brevity. so now, when major changes are completed we can straighten the onvif access out.

the problem is in my head, lol. need to wrap it around the architecture.

we have rtsp streams which require login and password. these credentials are defined in /etc/prudynt.cfg.

we have onvif endpoints which require login and password, too. these credentials are set in /etc/onvif.conf.

we have httpd which is dumb and can only do basic auth, and it protects access to webui with a different set of login/password set at a system level (/etc/passwd).

onvif returns rtsp urls which should have credentials to be viewed and these credentials can differ from those to access the onvif itself. it also needs a preview url which is in webui namepace and portected with the system credentials.

now we need to figure out how to make it all play together not biting one another.

roleoroleo commented 1 month ago

Is it possible to share credentials between rtsp daemon and onvif? The user sets only one login and both daemons use it. If this setup is possible, I think we can adjust httpd.conf to handle different users for different paths as you wrote here https://github.com/themactep/thingino-firmware/issues/128#issuecomment-2241770725

EDIT

I pulled the last version and tried again. S96onvif gets username and password from /etc/prudynt.cfg and it's ok: if I call the rtsp stream from an onvif client it works. Just a few details are missing to make snapshot working:

The last two steps are a problem if you want to allow the user to change the password.

themactep commented 1 month ago

I found this document and it highlights that onvif media configuration and rtsp stream should be protected with the same credentials. That at least removes the neccesity to take care of two sets of credentials. Now we just need to decide where to store the password so that it is secure but yet accessible for onvif operations.

Storing it in prudynt config seems easy but it also makes onvif dependant on the streamer. What if we use an alternative streamer with a different config format? @gtxaspec has plans for Raptor, an alternative modular media platform. But we can go with prudynt.cfg as a temporary measure until we figure out a better way.

I will make changes tonight and adjust webui to deal with prudynt config and update system user at the same time.

roleoroleo commented 1 month ago

iirc the snapshot should also be protected with the same credentials. I can test your changes if you want.

themactep commented 4 weeks ago

In todays changes:

default non-root system user is thingino with password thingino, same as in prudynt.cfg.

web ui changes password in both prudynt.cfg and for the system user.

/image.jpg proxied to /onvif/image.cgi which is under thingino user with password from the system.

See if it needs any further changes.

roleoroleo commented 4 weeks ago

I think it's ok.

If I change the password from the webui both /etc/shadow and /etc/prudynt.cfg are updated. onvif and snapshot work properly after changing the password, rtsp requires a daemon restart. Maybe a warning message in the web page "Please restart the cam after this change" or something else...

Thank you for your support.