c.im is one of the many independent Mastodon servers you can use to participate in the fediverse.
C.IM is a general, mainly English-speaking Mastodon instance.

Server stats:

2.8K
active users

#swad

6 posts4 participants0 posts today

I need some advise: Is there a good portable and free (really free, not GPL!) #implementation of #bcrypt in #C around?

There's #OpenBSD source I could use, but integrating that would probably be quite a hassle...

Background: I want to start creating a second credential checker for #swad using files. And it probably makes sense to support a sane subset of #Apache's #htpasswd format here. Looking at the docs:
httpd.apache.org/docs/current/
... the "sane subset" seems to be just bcrypt. *MAYBE* also this apache-specific flavor of "iterated" MD5, although that sounds a bit fishy ...

httpd.apache.orgPassword Formats - Apache HTTP Server Version 2.4

I finally eliminated the need for a dedicated #thread controlling the pam helper #process in #swad. 🥳

The building block that was still missing from #poser was a way to await some async I/O task performed on the main thread from a worker thread. So I added a class to allow exactly that. The naive implementation just signals the main thread to carry out the requested task and then waits on a #semaphore for completion, which of course blocks the worker thread.

Turns out we can actually do better, reaching similar functionality like e.g. #async / #await in C#: Release the worker thread to do other jobs while waiting. The key to this is user context switching support like offered by #POSIX-1.2001 #getcontext and friends. Unfortunately it was deprecated in POSIX-1.2008 without an obvious replacement (the docs basically say "use threads", which doesn't work for my scenario), but still lots of systems provide it, e.g. #FreeBSD, #NetBSD, #Linux (with #glibc) ...

The posercore lib now offers both implementations, prefering to use user context switching if available. It comes at a price: Every thread job now needs its private stack space (I allocated 64kiB there for now), and of course the switching takes some time as well, but that's very likely better than leaving a task idle waiting. And there's a restriction, resuming must still happen on the same thread that called the "await", so if this thread is currently busy, we have to wait a little bit longer. I still think it's a very nice solution. 😎

In any case, the code for the PAM credential checker module looks much cleaner now (the await "magic" happens on line 174):
github.com/Zirias/swad/blob/57

On a #coding mission to improve my #poser lib 😎.

In the current implementation of #swad, I don't really like that I need an extra thread, just to control a child #process. A first piece to add to poser is generic "child process support", which I'm testing right now. I realized I could reuse my #Connection class, which was built for #sockets, but works just as well with #pipes 🙃

TODO now is mostly testing. See screenshots for some mimimal testing code and its output ... would you like this kind of interface? 🤔

Continued thread

Nice, #threadpool overhaul done. Removed two locks (#mutex) and two condition variables, replaced by a single lock and a single #semaphore. 😎 Simplifies the overall structure a lot, and it's probably safe to assume slightly better performance in contended situations as well. And so far, #valgrind's helgrind tool doesn't find anything to complain about. 🙃

Looking at the screenshot, I should probably make #swad default to *two* threads per CPU and expose the setting in the configuration file. When some thread jobs are expected to block, having more threads than CPUs is probably better.

github.com/Zirias/poser/commit

Still working on #swad, and currently very busy with improving quality, most of the actual work done inside my #poser library.

After finally supporting #kqueue and #epoll, I now integrated #xxhash to completely replace my previous stupid and naive hashing. I also added a more involved #dictionary class as an alternative to the already existing #hashtable. While the hashtable's size must be pre-configured and collissions are only ever resolved by storing linked lists, the new dictionary dynamically nests multiple hashtables (using different bits of a single hash value). I hope to achieve acceptable scaling while maintaining also acceptable memory overhead that way ...

#swad already uses both container classes as appropriate.

Next I'll probably revisit poser's #threadpool. I think I could replace #pthread condition variables by "simple" #semaphores, which should also reduce overhead ...

github.com/Zirias/swad

Simple Web Authentication Daemon. Contribute to Zirias/swad development by creating an account on GitHub.
GitHubGitHub - Zirias/swad: Simple Web Authentication DaemonSimple Web Authentication Daemon. Contribute to Zirias/swad development by creating an account on GitHub.

First change since #swad 0.2 will actually be a (huge?) improvement to my #poser lib. So far, it was hardwired to use the good old #POSIX #select call. This is perfectly fine for handling around up to 100 (or at least less than 1000, YMMV) clients.

Some #select implementations offer defining the upper limit for checked file descriptors. Added support for that.

POSIX also specifies #poll, which has very similar #scalability issues, but slightly different. Added support for this as well.

And then, I went on to add support for the #Linux-specific #epoll and #BSD-specific #kqueue (#FreeBSD, #NetBSD, #OpenBSD, ...) which are both designed to *solve* any scalability issues 🥳

A little thing that slightly annoyed me about kqueue was that there's no support for temporarily changing the signal mask, so I had to do the silly dance shown in the screenshot. OTOH, it offers changing event filters and getting events in a single call, which I might try to even further optimize ... 😎

Continued thread

As my initial use case for #swad was to stop #AI #bots clogging my DSL upstream, and the #FreeBSD / #poudriere build logs they were downloading in gigabytes aren't secret at all (to the contrary, it can sometimes be helpful to share them when hunting down build issues in the community) I wonder whether I should add a module somewhat similar to #anubis[1] for "guest logins"? 🤔 Might be a lot of work though...

[1] github.com/TecharoHQ/anubis

Weighs the soul of incoming HTTP requests using proof-of-work to stop AI crawlers - TecharoHQ/anubis
GitHubGitHub - TecharoHQ/anubis: Weighs the soul of incoming HTTP requests using proof-of-work to stop AI crawlersWeighs the soul of incoming HTTP requests using proof-of-work to stop AI crawlers - TecharoHQ/anubis

Just released: #swad v0.2

SWAD is the "Simple Web Authentication Daemon", meant to add #cookie #authentication with a simple #login form and configurable credential checker modules to a reverse #proxy supporting to delegate authentication to a backend service, like e.g. #nginx' "auth_request". It's a very small piece of software written in pure #C with as little external dependencies as possible. It requires some #POSIX (or "almost POSIX", like #Linux, #FreeBSD, ...) environment, OpenSSL (or LibreSSL) for TLS and zlib for response compression.

Currently, the only credential checker module available offers #PAM authentication, more modules will come in later releases.

swad 0.2 brings a few bugfixes and improvements, especially helping with security by rate-limiting the creation of new sessions as well as failed login attempts. Read details and grab it here:

github.com/Zirias/swad/release

New features:

Configurable rate-limits for new session creation
Configurable rate-limits for failed login attempts (per session, realm
and user name)
Configurable types of proxy headers (X-Forward...
GitHubRelease swad 0.2 · Zirias/swadNew features: Configurable rate-limits for new session creation Configurable rate-limits for failed login attempts (per session, realm and user name) Configurable types of proxy headers (X-Forward...

I would claim that I'm *very* experienced with #programming in #C. But still, C gets annoyingly weird when it comes to #pointers *to* #arrays.

Does the following code look sober to you? 🤔 (My compiler doesn't complain)

Especially interested in the highlighted line, but also the block above trying to expand the array ...

Context: I started work on a generic/configurable rate-limiter to add to #swad.

I would claim that I'm *very* experienced with #programming in #C. But still, C get's annoyingly weird when it comes to #pointers *to* #arrays.

Does the following code look sober to you? 🤔 (My compiler doesn't complain)

Especially interested in the highlighted line, but also the block above trying to expand the array ...

Context: I started work on a generic/configurable rate-limiter to add to #swad.

Earlier today, I added a "ProxyList" component to #swad to get a list of proxies and, ideally, the "real" remote address for requests. It supports the custom (de-facto standard) X-Forwarded-For #header as well as the #Forwarded header specified in #RFC7239.

Well, I just learned I'll have to revisit this implementation with these horrible issues with the standardized(!) flavor in mind:

adam-p.ca/blog/2022/03/forward

adam-p.caForwarded Header Sabotage | adam-p

Released: #swad v0.1 🥳

Looking for a simple way to add #authentication to your #nginx reverse proxy? Then swad *could* be for you!

swad is the "Simple Web Authentication Daemon", written in pure #C (+ #POSIX) with almost no external dependencies. #TLS support requires #OpenSSL (or #LibreSSL). It's designed to work with nginx' "auth_request" module and offers authentication using a #cookie and a login form.

Well, this is a first release and you can tell by the version number it isn't "complete" yet. Most notably, only one single credentials checker is implemented: #PAM. But as pam already allows pretty flexible configuration, I already consider this pretty useful 🙈

If you want to know more, read here:
github.com/Zirias/swad

Simple Web Authentication Daemon. Contribute to Zirias/swad development by creating an account on GitHub.
GitHubGitHub - Zirias/swad: Simple Web Authentication DaemonSimple Web Authentication Daemon. Contribute to Zirias/swad development by creating an account on GitHub.
Replied in thread

DId lots of smaller improvements to #swad ... but first, I had to hunt down a crash 🤯. Finally found it was caused by my #poser lib (to be fixed later): A connection there can resolve the hostname of a remote end and does so in a thread job to avoid blocking. If the connection dies meanwhile, the job is canceled. Seems my canceling mechanism relying on a signal to the thread is, well, not reliable (the signal can arrive delayed). Ok, for now just disabled name resolution to sidestep that.

Now, integration with #nginx is much better. I intrdoduced (optional) custom headers to transport the authentication realm and the redirect URI, plus state management in the session, so these can be passed to the "auth" endpoint. This requires to make sure nginx always passes the session #cookie, Unfortunately, I still need a "hacky" redirect configuration for login in nginx. If auth_request could just pass the response body, this would be unnecessary .... 🙄

The nginx configuration shows #swad running on "files" and another nginx running on "wwwint" serving #poudriere output there. This nginx instance helpfully adds cache hints, which I have to override, so a redirect works as expected when for example the swad session times out.

Replied in thread

First "production test" successful 💪 ... after band-aid "deployment" (IOW, scp binaries to the prod jail).

#swad integrates with #nginx exactly as I planned it. And #PAM authentication using a child process running as root also just works (while the main process dropped privileges). 🥳

So, I guess I can say goodbye to #AI #bots hammering my poor DSL connection just to download poudriere build logs.

Still a lot to do for #swad: Make it nicer. So many ideas. Best start would probably be to implement more credentials checking modules besides PAM.