#swad's new #pow (proof of work) credential checker is working! It does almost exactly the same as #anubis, with two little differences:
* the nonce string is calculated from a number by some custom base64-like encoding, which is a little bit more work than what anubis does.
* still it's only a fraction of the #javascript code because it skips e.g. all the "progress reporting" (don't really see the point here, it's probabilistic anyways, so just show a spinner) and similar things.
What's exactly the same is spreading the work across one worker per core, and the goal to find a nonce that makes the challenge sha256-hash to something with n (default: 5) leading zeros.
Before crafting a new release of #swad, I'll think about ways how to customize the login form template (so you can e.g. just add a button for "login as guest", or tell the user what to enter for that).
BTW, the binary size is currently around 175 kiB
Some progress, I can successfully "hijack" #swad's login handler to display a special hidden form with (currently dummy) javascript attached plus a random challenge. Also, verify a nonce (passed as a password) whether when appended to the challenge hashes to a #sha256 hash with "x" leading zero nibbles.
So, now I "just" have to write some #javascript to make this fly ...
There's a lot that could still be improved in #swad, but I don't get that "proof of work" idea out of my mind, so I started a branch to work on it:
https://github.com/Zirias/swad/pull/1
I really think it makes sense when you want some publicly known "guest login" which is still protected against #bots. Not sure yet whether this will succeed, we will see!
It certainly won't be as "fancy" as #anubis, but do the same thing functionally: Require the client to find a #nonce that, combined with a server-provided #challenge, hashes to something with 'n' leading zeros using #sha256. In contrast to anubis, swad won't have to proxy everything (but rely on nginx' auth_request), and no challenge will be issued when the user logs in with credentials some *other* credentials checker accepts.
Just released: #swad v0.4
swad is the "Simple Web Authentication Daemon", offering a minimal #http server to do #cookie authentication with some #login form, intended for usage behind a reverse #proxy, designed with #nginx' "auth_request" in mind. It's written in pure #C with minimal dependencies (just OpenSSL/LibreSSL for TLS support and libpam for PAM support).
This release was a quick one, but a new credentials checker module deserves a new release. Now we have "exec" to delegate checking credentials to some external tool.
Read more in the full release notes, grab the .tar.xz and build/install it :
https://github.com/Zirias/swad/releases/tag/v0.4
I have to say the "#workflows" offered by #github used for #CI builds are *very* useful.
After discovering some mishandling of build options in #swad, I decided to use their "matrix strategy" for testing some combinations of options automatically, and sure enough, this failed:
https://github.com/Zirias/swad/commit/b8cfb9c6db69d9593f39fc1503a388a4002471a3
Fixed in the next commit
@stefano @hllizi Not "just" Javascript, it also requires specific "modern" APIs, namely Worker[1] and SubtleCrypto[2]. Only full-blown graphical Browsers are likely to ever implement these.
But OTOH, I see few alternatives to keep the bots out without making the content fully private. I mean, you say "breaking basic web access", sure, but that's exactly what these bots use .
I still have that crazy idea in mind that I could kind of "steal" this proof-of-work idea for my #swad tool, but there it would be combined with username/password login, so you could decide whether you just log in OR you hit a button to have your browser do some stupid hashing work ... but really not sure whether I'll tackle that.
--
[1] https://developer.mozilla.org/en-US/docs/Web/API/Worker
[2] https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
And documented.
I guess I should test a while before releasing this with #swad 0.4
https://github.com/Zirias/swad/commit/70607960709ae17833cf31192c702f4017d89b44
And here's the "real world" usage
So now I can give ppl a #login for #swad with a monthly changing password to access my #poudriere logs. Hopefully still keeps the #bot hordes out.
I figured #swad's password file management tool (swadpw) should really *ensure* that when reading a password from the #terminal, prompts are printed to exactly that terminal.
Well, I already check whether standard input *is* a terminal. In that case, I assume it *should* be writable. It certainly *is* writable on #FreeBSD and #Linux. But I can't find any guarantee looking at #POSIX specs .
Ok, so I wrote a weirdo function to provide fallbacks. Is this taking it too far? And how would I ever test these fallbacks?
Here's a script I wrote to test the *next* #credentials checker module for #swad: "exec"
Oh boy, I discovered two quite problematic bugs after releasing #swad 0.3:
* The #PAM checker could cause swad to deadlock under unlikely, but possible circumstances: Creating another PAM checker instance when the PAM helper process already died (or couldn't be started at all)
* The file checker had a bug of the stupid kind, it failed to authenticate users that *don't* have a "real name" set in the password file because it didn't correctly strip the newline following the hash in this case.
Fixed them both now!
I think I'll do something you normally should never do: Re-roll the existing #release. It's IMHO kind of acceptable because this is still an incomplete 0.x version AND there are (as far as I know) no packagers yet.
Just released: #swad v0.3!
https://github.com/Zirias/swad/releases/tag/v0.3
swad is the "Simple Web Authentication Daemon", your tiny, efficient and (almost) dependency-free solution to add #cookie + login #form #authentication to whatever your #reverse #proxy offers. It's written in pure #C, portable across #POSIX platforms. It's designed with #nginx' 'auth_request' in mind, example configurations are included.
This release brings a file-based credential checker in addition to the already existing one using #PAM. Also lots of improvements, see details in the release notes.
I finally added complete build instructions to the README.md:
https://github.com/Zirias/swad
And there's more documentation available: manpages as well as a fully commented example configuration file.
Of course, this new credentials checker in #swad needs a #tool to edit these #password files, that's currently work in progress.
I just implemented the class for reading a password, pretty simple thing from a pipe, but an "interesting" job from a #terminal. Turns out doing that portably, reliably and secure needs quite some code.
There's #getpass, but that's deprecated for good reasons (global state and not perfectly clear how it deals with #signals that could interrupt the input). And there's the sane replacement #readpassphrase in *some* systems (e.g. #FreeBSD), but that's not portable.
So, plain old #tcsetattr it is, with some signal handling on top:
https://github.com/Zirias/swad/commit/447f48096fc275a5bae113393ffe9a3cbc66cc95
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:
https://httpd.apache.org/docs/current/misc/password_encryptions.html
... the "sane subset" seems to be just bcrypt. *MAYBE* also this apache-specific flavor of "iterated" MD5, although that sounds a bit fishy ...
Next #swad improvement: Make sure to #wipe #passwords from RAM directly after used. That's more of a #security precaution, because there *should* be no way how an attacker can access a running process' memory, but you never know which bugs surface .
Unexpectedly, that posed #portability issues. #C11 has #memset_s ... a pretty weird function, but suitable for wiping. It's there on #FreeBSD and on #OpenBSD. Not on #NetBSD though. But NetBSD offers the much saner #C23 function #memset_explicit. Looking at #Linux, there's neither. But there is the (non-standard!) #explicit_bzero .. and with glibc, it requires _DEFAULT_SOURCE to be defined as soon as you compile with a C standard version given to the compiler. This function exists on some other systems as well, but there's confusion whether it should be declared in string.h or strings.h.
Here's the full set of compile-tests I'm now doing, only to find the best way to really erase memory:
https://github.com/Zirias/swad/blob/master/src/bin/swad/swad.mk#L6
And if none of these functions is found, swad uses the "hacky" way that most likely works as well: Access the normal memset function via a volatile pointer.
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):
https://github.com/Zirias/swad/blob/57eefe93cdad0df55ebede4bd877d22e7be1a7f8/src/bin/swad/cred/pamchecker.c