This is a PAM module in Swift that builds using Nix to get dependencies. For inexplicable reasons, it does not use Nix as a build system, which might have made this a little less painful. I also wonder if this is less painful on e.g. Debian.
To build, use nix-shell -E 'with import <nixpkgs> {}; mkShell.override {stdenv = swift.stdenv;} {buildInputs = [swift swiftPackages.Foundation];}'
to get a working Swift dev shell (see NixOS/nixpkgs#242779) and then run make
.
To use it, add session required /path/to/libpam_swift.so
to /etc/pam.d/sshd
or something it includes. (Again, on NixOS, there is probably a more pleasant way to do this, but I copied the file that /etc/pam.d/sshd
points to and replaced the symlink with my updated file. Don't worry, I'm doing this on a live CD in a VM.)
You should see something like:
pokio:~ geofft$ ssh [email protected]
([email protected]) Password:
Hello from Swift!
Last login: Wed Oct 9 00:37:13 2024
[nixos@nixos:~]$
For reasons probably related to the above nixpkgs issue, I needed to explicitly add the location of libdispatch to the rpath, and then also explicitly link libdispatch (which is an indirect dependency of libswift_Concurrency, so neither the PAM module's DT_RPATH nor DT_RUNPATH will get used when locating it). The rpath issue is probably relatively Nix-specific, but I'm not actually sure why Concurrency is getting linked at all when I'm not using it, and that seems mildly concerning for a loadable module, so maybe we should solve that first.
This uses @_cdecl
, which is discussed in detail in https://forums.swift.org/t/best-way-to-call-a-swift-function-from-c/9829 . If anyone really wants to start writing Linux userspace libraries in Swift, a proposal for stabilizing @_cdecl
would be the first step.