CRUX is a minimalistic GNU/Linux environment, but you still need software to do your job, right? I am all for minimising the software footprint on any machine I manage. It’s better for performance and security, not to mention there simply being less to keep track of.
One piece of software I rely on is GNU Emacs. No, it’s not as minimalistic as vim, out of the box, but I believe in using the right tool for the job. I use Orgmode, mu4e, Emacs diary and other tools to manage my day. Emacs brings it all together nicely, and I’m ok with using both text editors.
However, scaffolding that is provided with any standard Linux distro, when you install emacs, is not present in CRUX. This is an unstructured journey of my attempts to get it working, and the purpose of this post is really for my record, in case I want to create an Emacs package for CRUX that automates (to a degree) the process below.
Install Emacs!
- Download latest Emacs tar from gnu.org
- (optionally, but recommended) download GNU Mailutils
- First install p11-kit, gnutls (
# prt-get depinst p11-kit gnutls) ./configure; make; make install;(mailutils)./configure; make; make install;(emacs)
And then… to support mu4e…
- Download mu (
$ git clone https://github.com/djcb/mu.git) - Install Xapian, GMIME and GLib (
prt-get install glib gmime3 xapian-core) ./configure… Oh. No w3m, which I use from time to time. Let’s get that.
w3m
Go to Sourceforge:
- https://sourceforge.ne./configuret/projects/w3m/
- Download latest, uncompress, cd into dir
./configureOh. No gc library.
Ok, search for that:
$ prt-get search gc
boehm-gc
gcab
gcc
…- A-ha! boehm-gc is what we need. Install it!
# prt-get install boehm-gc
Done! Back to building w3m:
./configuremake… Oh boy, that just doesn’t work with modern gcc. Errors everywhere.- Remove
(require 'w3m-search)from Emacs’ init.el. Perhaps I can live without w3m..? /sniff
Running Emacs
Emacs runs! mu4e doesn’t! error in process sentinel: mu server process ended with exit code 1
Bah! The Xapian mail database was not copied across from old drive.
cp -aurv /mnt/olddrive/home/.cache/mu ~/.cache/
Yay! mu4e runs! Drat! mbsync doesn’t!
$ prt-get search mbsync;
No matching packages found
What about the “new” name for mbsync, “isync”?
$ prt-get search isync
isync
Hurrah! Let’s install it!
# prt-get install isync
…
Still doesn’t work. Of course .. credential handling. Thinking…
Do I need askpass..? I can’t quite recall… Let’s check it out.
$ prt-get search askpass
No matching packages found
For some reason ssh-askpass has been omitted from the Xorg base install. I’ll come back to this…
Password & encryption handling
I also need GNU pass. This is a great tool for storing passwords in a safe, clean, hierarchical and Unix-like manner. To support pass, a few dependencies must be met, so:
# prt-get install xclip tree qrencode
Then:
git clone https://git.zx2c4.com/password-storecd password-store- (as root)
make install
Sidenote! It turns out that password-store is actually provided in a standard CRUX repo. So, in time, I’ll remove this and just install the standard package.
After all of this, I still had a fundamental problem: gpg --list-keys did not list my keys, and instead showed a single key under the heading [keyboxd]
I found, from RTFM here, the following:
common.conf
This is an optional configuration file read by gpg on startup. It may contain options pertaining to all components of GnuPG. Its current main use is for the “use-keyboxd” option. If the default home directory ~/.gnupg does not exist, GnuPG creates this directory and a common.conf file with “use-keyboxd”.
I checked my ~/.gnupg directory and, sure enough, there was common.conf with that one entry in it. Checking my old drive’s .gnupg directory showed that this did not exist, which is why I didn’t have this problem previously. I simply moved that file aside (renaming it to common.conf.bak) and hey, presto! No more weirdness around key listings. (The reason for it being there on the new drive, by the way, was that I’d probably invoked gpg before copying my old config over, so the default config with that was installed for me. As a convenience, obviously!)
Circling back
To use that horrible business buzzword, I need to come back to GNUPG and/or a smartcard daemon. The issue is that while my main GPG key is stored on disk, my sub-keys for encryption/decryption, signing and authorisation are stored on a Yubikey. In order to unlock my GPG-encrypted password, stored using pass, I need my Yubikey plugged in and available to GPG.
However, what I thought was askpass was actually pinentry. It’s all coming back to me now! Luckily for me, pinentry is provided by the CRUX team, so it’s a simple
# prt-get install pinentry
to get that installed.
One more thing…
There’s always one more thing. My laptop doesn’t seem to recognise that my Yubikey is inserted in a USB port. Ooh. What next?
Well, my guess is that the pinentry program doesn’t have access to the USB device. Time to explore those udev rules, to see if it can be given permission.
However, before I do that, let’s see if a little test proves my theory. The pinentry prompt appears with:
Please insert the card with serial number:
7 654 321
A quick look at dmesg shows me that the card is picking up device node usb 1-4.2.2:
[ 2843.676542] usb 1-4.2.2: new full-speed USB device number 8 using xhci_hcd [ 2843.761542] usb 1-4.2.2: New USB device found, idVendor=1050, idProduct=0407, bcdDevice= 4.33 [ 2843.761546] usb 1-4.2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 2843.761547] usb 1-4.2.2: Product: Yubikey 4 OTP+U2F+CCID
Maybe, if I just give that device permission for my user to read, it might work..?
As it was the last device plugged in, and looks like it’s registering as a, HID device, I suspect it’s /dev/hidraw4
The timestamp on /dev/hidraw4 also roughly corresponds to when I plugged it in to the machine (a theory I can easily test if this doesn’t work), so I’m ok with testing this out.
# setfacl -m u:myID:r
And… drumroll, it didn’t work!
I can see now that getting udev to do this makes total sense. Besides, I don’t actually think it’s the HID device I want to address, specifically, because an HID device is a “human interface device”, which really only corresponds to the touch-sensitive button on the key.
Anyway, that aside, there’s helpful documentation on adding two (1, 2) udev rules for yubikeys. Nevertheless, even after issuing:
# udevadm control --reload
… no change occurred in terms of USB device access.
Now two more things
When running
$ gpg --card-status --debug-all
it becomes clear that the blocker is not having a smartcard daemon running – or, at least – one that isn’t accessible to gpg.
gpg: DBG: chan_3 -> SCD GETINFO version gpg: DBG: chan_3 <- D 2.5.14 gpg: DBG: chan_3 <- OK gpg: DBG: chan_3 -> SCD SERIALNO gpg: DBG: chan_3 <- ERR 100663614 Service is not running <SCD> gpg: selecting card failed: Service is not running gpg: OpenPGP card not available: Service is not running
It so happens that pcscd is actually running on the machine and, usefully, it spits out its contempt straight into the syslog:
Dec 3 16:01:16 x1 pcscd: ../pcsc-lite-2.4.0/src/auth.c:166:IsClientAuthorized() Process 11443 (user: 1000) is NOT authorized for action: access_pcsc Dec 3 16:01:16 x1 pcscd: ../pcsc-lite-2.4.0/src/winscard_svc.c:357:ContextThread() Rejected unauthorized PC/SC client
This tells us something useful, which is that GPG is trying to access a smartcard daemon service and is being rejected. So we can probably discount gpg being “guilty” of some kind of misconfiguration.
The question then, is how does a user become “authorised for action: access_pcsc”?
Well, it turns out, you don’t necessarily need to. To start with, I had no such problem when running gpg --card-status as root, which led me initially to a permission-related issue. However, on reflection, it seemed more liekly to me that as there was no smartcard daemon running, it was likely that this needed to be addressed first. It also aligned with the error message GPG was issuing.
Using pcscd
pcscd is a trim, yet fully functional smartcard daemon that is compatible with all sorts of cards and readers. Its documentation steers you towards /usr/lib/pcsc/drivers as a location to find the driver for your smartcard of choice. Except, on CRUX, this directory doesn’t exist. Does this matter? It seems not.
The more important thing, to GPG, is that it is able to interface to a smartcard daemon that’s running – and, more specifically, one running as root.
So, those lines from GPG?
gpg: selecting card failed: Service is not running gpg: OpenPGP card not available: Service is not running
It’s wise not to overthink this. If GPG is looking for a smartcard service (daemon) and one does not exist, it will complain! So, as pcscd in CRUX didn’t come with a service file, I decided to create one using another as a template. My criteria was simple: find the file with the simplest implementation – which you can judge based on the number of lines in the service definition:
$ wc -l /etc/rc.d/* 26 alsa 36 crond 43 dbus 36 dhcpcd 39 gitd 35 inetd 24 lo 48 net 33 nfs 25 nfsclient 36 nfsdcld 38 nfsserver 54 nftables 36 rpc.idmapd 36 rpc.mountd 35 rpc.nfsd 37 rpc.statd 38 rpcbind 36 rsyncd 50 sshd 36 sysklogd 28 wlan 39 wpa_supplicant 23 xdm 890 total
xdm looked like a good candidate, so I copied the file and created a file called pcscd, with the following contents:
#!/bin/sh # # /etc/rc.d/pcscd: start/stop pcscd # case $1 in start) /usr/sbin/pcscd ;; stop) killall -q /usr/sbin/pcscd ;; restart) $0 stop sleep 2 $0 start ;; *) echo "usage: $0 [start|stop|restart]" ;; esac # End of file
The only other requirement is to start this service on boot, which is easily achieved by adding pcscd to the SERVICES line in /etc/rc.conf:
SERVICES=(lo wlan crond dbus alsa pcscd)
I also settled on the following configuration for GPG:
$ cat gpg.conf auto-key-retrieve no-emit-version use-agent $ cat scdaemon.conf pcsc-driver /usr/lib/libpcsclite.so card-timeout 5 #disable-ccid #pcsc-shared
You’ll notice that unlike much advice you’ll read on the web, I didn’t disable ccid. Well, technically I undid my previous disabling of ccid, which didn’t seem to have an adverse effect. I’m of the mind that if the setting doesn’t make any perceptible difference, remove it.
In conclusion
It would be fair to say that I hadn’t expected to spend a whole day on configuring Emacs to work well for me in CRUX. But the effort has been worth it. I now have feature parity with Emacs on Debian 13 – at least for my needs – and I have picked up a lot of useful information along the way. Plus, I have the advantage of my system remaining lean and mean.
Whoever the faint-hearted are, this would not be for them. But as most people are up for trying, and modern computing is an almost zero-risk exercise in experimentation, I hope the above helps the odd soul who is looking for a few pointers on their own journey. For me, having Emacs function in the same way as it does on Debian was an essential criterion for adopting CRUX. That done, I’m now thinking this project is a “go”!


Likes