OpenPrinting / ipp-usb

ipp-usb -- HTTP reverse proxy, backed by IPP-over-USB connection to device
BSD 2-Clause "Simplified" License
141 stars 15 forks source link

Authentication support? #61

Closed zdohnal closed 11 months ago

zdohnal commented 1 year ago

Hi Alex,

I've sent the proposal to fedora-devel list and some questions were raised. Here is the thread . I've filed the issue for public visibility.

Robert Marcano asked there about authentication features of ipp-usb, whether there are any and if not, whether it will be possible to implement authentication. His concern is about the daemon being exposed on localhost, which enables bypassing CUPS by applications and losing CUPS features for such print jobs.

Thank you in advance!

alexpevzner commented 1 year ago

Hi @zdohnal,

it's not quite clear for me, how clients of ipp-usb will obtain authentication credentials. If cups can take it from its configuration, sane-airscan runs in context of arbitrary process, and its own configuration is system-global.

robmv commented 1 year ago

@alexpevzner

The idea of using authentication is to avoid users bypassing CUPS to print directly on the printer application like ipp-usb, skipping features CUPS provides like accounting and authentication.

If ipp-usb could be protected with at least basic authentication. CUPS could be setup with fixed queues like ipp://user:password@localhost:60000/..... In order to only allow CUPS to talk directly to the printers. It is just an idea, because the other option of firewall rules are more complicated for the average sysadmin, and more prone to errors.

Update: and firewall rules will not help when you only need to protect a single USB printer. Firewall rules will be for all printers provided by ipp-usb or none.

alexpevzner commented 1 year ago

Yes, I understood the idea. It is not quite clear how it will work with scanning. CUPS is a system process, while scanning requests come from user processes (via the sane-airscan or sane-escl plugins). If user has ipp-usb credentials, effectively it will have full access to the ipp-usb

robmv commented 1 year ago

Nearly all scanning on Linux is done via SANE. As you know, it is an in process library, it loads drivers in the calling process. I may say that SANE needs its own CUPS, that in some way it does, there is a SANE server that can share scanners over the network.

Previously I have used that server even for local scanning because some closed source SANE drivers was randomly crashing the calling application, at least with the SANE server the crash was external to the applications and it could be automatically restarted.

IMHO the SANE in process library should be switched to not load drivers directly ever, but to use a system supplied SANE server, with all the move to containerized applications (like flatkpaks), I am surprised It hasn't happened before.

Note: Windows scanning moved a long time ago to an out of process model, only the old TWAIN remains being a DLL to be loaded inside the applications, and all the drivers too.

robmv commented 1 year ago

There is even a request to add a portal for scanning from flatpaks https://github.com/flatpak/xdg-desktop-portal/issues/218

alexpevzner commented 1 year ago

There are 3 clients of the ipp-usb:

  1. CUPS
  2. SANE that runs in-process
  3. web browser, used to access printer web console

Adding HTTP-level authentication easily integrates only with CUPS. So this idea, to isolate ipp-usb from access by arbitrary applications, sounds, in general, as very reasonable, but requires more architectural effort.

alexpevzner commented 1 year ago

One thing that I'd consider to think about is if there is any reasonable way to obtain UID/EUID of the client process assuming connection goes via localhost address, the ipp-usb may check that UID belongs to some particular group.

It will allow to control access at the per-user basics.

However, all applications of the allowed user will be able to access the ipp-usb

zdohnal commented 1 year ago

@alexpevzner that sounds great! We can use some new group like ippusb, together with root and wheel and provide a basic authentication/authorization via usernames/groups.

debiantriage commented 1 year ago

I could possibly be misunderstanding the issue but, here goes...

The user here wants to disallow direct access to the printer and, for example, enforce printing accounting with CUPS in all circumstances. Avoiding CUPS is already possible by sending a file directly to /dev/lpX or with netcat to port 9100 over the network.

Perhaps it should be kept in mind that a Printer Application does not require CUPS to be on the system.

robmv commented 1 year ago

/dev/* devices can be locked down with for example udev rules. The netcat case is what we want to be able to block direct access, but there is no 9100 raw port on ipp-usb, it is an HTTP server.

All this could be avoided if CUPS and ipp-usb implemented IPP over Unix sockets, instead of only over TCP. On the original mailing list post there was a mentio that there was some possibility of having it on CUPS later.

robmv commented 1 year ago

One thing that I'd consider to think about is if there is any reasonable way to obtain UID/EUID of the client process assuming connection goes via localhost address, the ipp-usb may check that UID belongs to some particular group.

Not secure enough, some people say that reading /proc to get the source port connection, but that isn't something I would do. On the other hand Unix sockets on Linux can retrieve the UID from the client, but at the time CUPS and ipp-usb adds support Unix sockets, HTTP authentication will not make much sense because file systems permissions on the socket would be able to limit access to the CUPS system user.

The HTTP authentication is for me a workaround if Unix sockets is never supported.

alexpevzner commented 1 year ago

Hi @zdohnal, @robmv,

having some time to invest into the ipp-usb, I've finally implemented UID-based authentication for local connections.

See explanation under the [auth uid] section in the ipp-usb.conf

Please, review and test. Looking for your feedback.

alexpevzner commented 1 year ago

Ping?

robmv commented 1 year ago

Ping?

Thanks for the ping, I will try to make a little time in the following days to test it. I checked the implementation only and looks cool that there is a way to identify the client uid from a local network connection, I was under the idea that it was only possible for unix sockets.

This would be nice to have on my experimental (not released yet) cups-pdf replacement printer server (There are too many legacy applications that don't show modern printer dialogs with a save to PDF option), maybe I will use the same API to propose it to the PAPPL library.

zdohnal commented 1 year ago

@alexpevzner I'm sorry, Alex, and thank you for your work! The change looks good to me, I was just thinking about whether we could set common CUPS groups as default for printing functionality - @sys @root @wheel @printadmin - wdyt?

alexpevzner commented 1 year ago

I checked the implementation only and looks cool that there is a way to identify the client uid from a local network connection, I was under the idea that it was only possible for unix sockets.

Definitely, if netstat was able to do it for decades, I also can :-)

The only problem with this approach, FreeBSD (which recently also can run ipp-usb) will need to use some different, system-specific API for this purpose. And somebody needs to implemet a port...

alexpevzner commented 1 year ago

CUPS groups as default for printing functionality - @sys @root @wheel @printadmin - wdyt?

Under which user/group currently CUPS runs? Is it distro-specific?

alexpevzner commented 1 year ago

BTW, if somebody knows which paths does libusb use under the /sys/... hierarchy to access USB devices, I can also add check for access rights for tese devices, for the connection client UID - it will allow to provide ipp-usb access, based on udev rules for USB devices.

zdohnal commented 1 year ago

CUPS groups as default for printing functionality - @sys @root @wheel @printadmin - wdyt?

Under which user/group currently CUPS runs? Is it distro-specific?

I would say it is solution specific - packaged cupsd runs under root:root, containerized (SNAP, podman containers) under specific user:user.

alexpevzner commented 11 months ago

The proposed solution was included into recently released 0.9.24

zdohnal commented 11 months ago

Thank you! :)