Elektrine lite

← Feed

@ska@social.treehouse.systems

2026-09-29 00:54 UTC

@daztucker@infosec.exchange @darrenmoffat@mastodon.social @JdeBP@tty0.social @damienmiller@hachyderm.io Thank you a lot for the explanation! If you're around, and can (at your own pace, bless asynchronous media such as fedi) answer a few more questions, this might really help me, and I hope us, going forward. Here's the context: I want to learn about the details of PAM usage and encountered problems and what clients wish they had instead. No project I know that uses PAM is entirely happy with it (for good reasons), and I may soon have an opening to do something radical: design and write a complete replacement. And so, I want to be sure of exactly where and how PAM fails, in order to make something better, in the sense of: it can do everything PAM does, it provides better security, it doesn't require clients to bend themselves into a pretzel to do things correctly, and the API is friendly enough so that clients are willing to use it. I am aware of the address space issue. Some time ago I wrote a PAM implementation that aimed to protect against that: https://skarnet.org/software/pamela/ but of course it's not usable as a drop-in replacement since so many PAM modules and applications want to use the fact that modules are loaded in the same address space to share global data, such as environment variables. Bleh. I initially thought that the reluctance of a lot of projects to use PAM conversations was simply due to pam_conv being cumbersome to use, but you also gave another explanation: PAM conversations are synchronous, so they're not usable in a project organized around an async event loop. This is a useful insight for me: in order to work, a PAM replacement must provide a way to have asynchronous conversations. Thank you for that. The API I have in mind looks roughly like: (it won't be a pam_ prefix but bear with me) pam_start() to start a session. It spawns a helper process, for address space isolation. The helper process loads the modules, rewritten not to share global data with the application (basically the whole module system gets rewritten, probably using executables instead of shared objects)Various primitives that don't block, don't make networking calls, don't require any callback to the application: these can be synchronous.Asynchronous primitives, let's say pam_send(), that send something to the helper but return instantly, they're usable in an async loop.You get a file descriptor with pam_fd() and add it to your select/poll fd list.When the fd is readable, you call pam_update(). That invisibly advances conversations, making callbacks that you have registered, etc. Depending on the return code from pam_update(), you may have gotten a result, which you then check in previously set up data structures, and decide what to do from there.For simple cases where you don't need async stuff, there's a fully synchronous layer that encapsulates all the fd/poll/update thing.pam_end() cleans up everything, the helper dies and is silently reaped, etc.The only code sharing address space with your application is the lightweight client-side that basically just serializes data and sends it to the helper process, and back. For those who like that, it can even be statically linked: no dlopen() there or anything of the kind. The goal is for the library to be used naturally by clients without needing threads or whatever isolation headaches PAM clients are using. It is a programming pattern that I use regularly, I have the necessary library infrastructure for it, I like it and it does everything I need; however, a PAM replacement would not be for me, it would be for other people. So I have the following questions: If you were an application needing to use a PAM-equivalent stuff to authenticate users and whatnot, would you use such an API? Would it be user-friendly enough that you decide you can work with it? would it integrate well enough with your workflow that it's natural, and if not, what pattern would you prefer?Assuming all the backends (previously known as PAM modules) are rewritten to take advantage of improved conversations rather than sharing global data: is this powerful enough? Would a PAM replacement built along these lines be able to do, over time, everything that PAM currently does - or at least, everything that you, as a client of PAM in OpenSSH, require from it? Or is there a system that I have missed and that absolutely needs to be addressed? I will stop here for now, thanks for reading all this already 😅 And if the project happens, it won't be before the summer of next year at the very least, so, absolutely no rush - but I am interested in your insights. And this is of course also valid for other PAM users out there, if this thread reaches them.

Replies (1)

  • @JdeBP@tty0.social 2026-09-29 09:19

    @ska@social.treehouse.systems The important thing to grasp is that to sophisticated users of PAM, it is a modal dialogue box created at PAM's behest, running its own message loop. Whereas the API that they need is #PAM requesting creation of a modeless dialogue box (it supplying all of the message and response structures), and PAM providing a function to call when that dialogue box is dismissed (for it to read out the response structures and Do Stuff). This has been addressed long since in the GUI world. #OpenPAM

    Open ##5015276