2014-09-27

Ubuntu 14 & OpenPGP smartcards: report from the war zone


Using smartcards on Ubuntu 14 is not a plug&play experience these days; not that it has ever been, and given the whimsically small amount of users this is to be expected.


This post/tutorial is split into different sections to ease readability and evidence ALL the different problems you will have to overcome to achieve a working setup.

Goal


The goal is to have a working gpg-agent integration that will provide signing/encryption for all your X11/terminal session applications, and that will act also as an SSH agent (the key feature here is gpg-agent's --enable-ssh-support).

Use-case examples:
  • Thunderbird + Enigmail
  • remote SSH authentication
  • X2Go sessions
  • any other use of gpg you can think of
In order to achieve this, we must be in control of how gpg-agent is started and make sure that no other agent is being started (most notably: gnome-keyring, ssh-agent, other rogue gpg-agent instances, you-name-it keyring).
Enjoy reading & hacking through this :)

1. First steps first: the reader


Let's install the necessary software:

apt-get install pcscd gnupg2

I had some issues at getting the reader recognized and available to my non-root user. I will skip instructions about to configure udev, as it is already described in the Howtos at FSFE and online everywhere; basically you have to produce correct rules for your device, and then a script that will be executed every time your device is plugged in. I suggest Gentoo's well-written udev wiki page as a start.

NOTE: you should change the ids in the udev rules to match those you can see in your dmesg.

When you have successfully configured your device via udev, you will be able to query the smartcard like this:
$ gpg --card-status
Application ID ...: **************
Version ..........: 2.0
Manufacturer .....: ************
Serial number ....: ************
Name of cardholder: [not set]
Language prefs ...: de
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Private DO 1 .....: [not set]
Private DO 2 .....: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]

This looks good! :)

If you have gone this far, congratulations! You're ready to fix the next mess...

You're feeling lucky

Your reader might be CCID-capable but not on the supported/should work lists; if you want to test if it works with pcscd you can manually add the name and ids (same as above step for udev rules) to:

/usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist

This way pcscd will at least attempt to talk to the device; remember to contact pcscd author if it works and you would like to see this device added to those that are officially supported.

2. Broken systems are broken

There are bugs in Ubuntu/Gnome keyring that by default will make the GPG integration broken; derivatives like Mint are also affected.

This issue can be fixed by removing the damn Ubuntu-installed files and burning them with fire disabling GNOME keyring (at least until it's fixed/completed) with:
sudo rm /etc/xdg/autostart/gnome-keyring-gpg.desktop

In XFCE settings, in Session & Autostart the "Start Gnome services at startup" option should be disabled as well.

Disable the other 2 totally rogue gpg-agent and ssh-agent upstart services: 
echo manual | sudo tee /etc/init/gpg-agent.override
echo manual | sudo tee /etc/init/ssh-agent.override

Finally, disable the Xsession.d scripts that would normally auto-start ssh-agent:

sudo rm /etc/X11/Xsession.d/90ssh-agent

Depending on the desktop environment of your choice, there are countless other ways to autostart applications. Read their documentation and Make sure that no keyrings/agents are being automagically started.

XFCE, good boy


As per XFCE4 documentation, disable both gpg-agent and ssh-agent from being auto-started by xfce4-session:

xfconf-query -c xfce4-session -p /startup/gpg-agent/enabled -n -t bool -s false
xfconf-query -c xfce4-session -p /startup/ssh-agent/enabled -n -t bool -s false 


If no ssh-agent (and only 1 gpg-agent) is running at any time when you login to a new X session, then feel free to proceed to next step :)

Useless rant

Enabling autostart applications in any Linux desktop environment and not providing any easy GUI/CLI to change them is equivalent to producing an unmaintainable/unusable pile of hacks, but this is the average Linux desktop experience and we all know it by now :)

For hardcore users

If you are experiencing issues at individuating who is responsible of the startup of some gpg-agent, I suggest this radical approach:

sudo dpkg-divert --divert /usr/bin/gpg-agent.real --rename /usr/bin/gpg-agent

It's left to the reader as an exercise to create a gpg-agent script that will save the output of pstree somewhere, so that you can figure out what's going on :)

Remember to revert your change or use the correct binary name later on if you have applied this diversion.

3. Session mayhem


Modern login managers will ignore your ~.Xsession/~.xsession file; instructions here cover only LightDM/XFCE4, but suffice it to say that being able to start your X sessions via an .xsession file is enough to complete this integration setup.

Create /usr/share/xsessions/xsession.desktop:

[Desktop Entry]
Name=Xsession
Exec=/etc/X11/Xsession


Make it the default session in LightDM via /etc/lightdm/lightdm.conf:

[SeatDefaults]
user-session=Xsession

Create your ~/.xsession:


exec ck-launch-session dbus-launch --exit-with-session startxfce4

Restart lightdm (or the whole system, since not all processes will terminate with your session) and check that everything works as expected. If you cannot mount external devices, make sure you have policykit-desktop-privileges installed (go look here for another delicious bug about this).

Once you made yourself comfortable and everything is working as expected, we're ready to add the final chef touch to our setup.

4. Please wrap it


We are going to make sure that gpg-agent is a STARTUP prefix for our beloved X session, so that gpg-agent will correctly setup a bunch of other environment variables.

For reference, this is their list:
  • GPG_AGENT_INFO=/home/neagix/.gnupg/S.gpg-agent:17244:1
  • SSH_AUTH_SOCK=/home/neagix/.gnupg/S.gpg-agent.ssh
  • SSH_AGENT_PID=17244

Open your ~/.gnupg/gpg.conf and make sure that you have:

enable-ssh-support
use-standard-socket

At this point, reboot (or restart lightdm) and check that your setup worked by typing in any terminal emulator:

set | grep 'GPG\|SSH'

If you don't see the expected 3 environment variables, either you did something wrong or the distro gods have changed something (yes, this post will eventually become old as this mess is cleaned up & fixed upstream).

You can test that the correct gpg-agent is running by inspecting the command line:
xargs -0 < /proc/$(pgrep gpg-agent)/cmdline
Remember that options are read by default from ~/.gnupg/gpg-agent.conf.

And finally, enjoy your correctly-working gpg smartcard setup!

37 hours is the estimated amount of time that an average Ubuntu user would need to correctly complete this setup from scratch, nonetheless with the help of search engines. Hope this walk-through was of some help :)

Update 24 January 2015: gnupg2 package is in extra, not main. Thus one cannot expect it to be perfectly working.

2014-09-06

Linux Mint 17: install troubles

I have been reading a lot about Linux Mint in recent weeks, and today I decided to install it, in particular the Cinnamon variant.

Installation fireworks


LM = Linux Mint, got it!

I downloaded the ISO and dd'umped it into an USB stick; once booted this Live Linux Mint, you can click on the Install icon on desktop to start the famous Ubiquity installation wizard (of Ubuntu fame).


This wizard comes with the strong and weak spots of the Ubuntu one, except that it does not offer an option to download most recent packages directly (maybe for better stability).

First issue: you cannot install on devices under /dev/mapper, thus you cannot directly use anything like LUKS.

Second issue: it does not allow to select "no bootloader" (I want to customize my existing GRUB and not install a new one); if you try to trick the installer by selecting the USB stick used for the Live distro, then it will fail writing there and ask you if you prefer to continue without bootloader. Bingo you say? No, it will crash afterwards (or after installation is complete).
So I had to apply this patch to correctly continue installation (NOTE: this is a problem common to Ubuntu 14.04 and Linux Mint 17).

Afterwards installation proceeds smoothly and then finally the wizard says it completed and asks if you want to continue testing or reboot. Choosing to continue testing inevitably leads to a short hourglass waiting time and then the announcement that the installation wizard crashed (as happened before with the GRUB problem), thus I advise to not click anything and leave the dialog there; once completed using the Live distro, then press the restart button.

Boot attempt 1

So, right after installation I added a stanza to my already-existing GRUB to boot Linux Mint, and here the first problem comes:

Kernel panic in native_smp_send_reschedule (???)
I dare anybody to tell what this kernel panic is about. After a few attempts, I figured out that the root= kernel command line parameter was wrong, but one would expect a radically different message in such case (not a kernel panic in native_smp_send_reschedule).

Boot attempt 2

After having fixed this trivial problem, Linux Mint seems to boot...except that it doesn't.

The boot process gets stuck and I figured out thanks to this forum thread that it's because of some invalid fake start-stop-daemon and fake initctl.

This was a good time to meter the quality of the community, testing, bug tracking/fixing of the FOSS project, so I went to check the bug tracker:
https://bugs.launchpad.net/linuxmint/+bug/1096570

The forum thread is dated Fri Nov 23, 2012 4:27 pm and the bug 2013-01-06. And today it's 6 September 2014.

Perhaps a regression and previous versions of Linux Mint worked perfectly?
Nonetheless this situation sucks.

Band-aid & first healthy boot

Ubiquity already mounts the new system in /target, so I proceeded to mount there the usual proc, sys and dev, then chroot in it to reinstall dpkg and upstart:
apt-get install --reinstall dpkg upstart

At this point I was able to successfully boot Linux Mint 17; a tad slower than I expected, thus I am going to remove some undesired packages. This will probably be hijacked by the many dependencies into Ubuntu or Mint meta packages...I am surrendering to this logic these days, and will try to remove what is sensibly slowing down the startup without sacrificing too much of these hyper-dependent packages.

Undesired extensions

I noticed also that the branding is a bit too much aggressive, perhaps a reaction to the fact the distro itself is a re-branding of Ubuntu?
Thus as advised in this post I advise to add this line (before exit 0) in your /etc/rc.local, so that at every boot the eventually reinstalled firefox crapxtension will be removed:
rm -rf /usr/lib/firefox/extensions/mint-search-enhancer@linuxmint.com/
I hope to not find other mind-boggling "features" like these, but so far so good: interface seems pretty sleek.

Update: Found something else you might want to remove:
aptitude remove mint-search-addon mintbackup mintnanny mintstick mintupload mintwifi
From package description of mint-search-addon:
Enhances the results given by Google
Yeah, sure, enhancements.

No pingbacks/comments

Looks like the official blog is not eager for community feedback & comments on their blog, as all posts are labelled with this:

Meh! Ok, so this will be a monologue :(

Credits

I know packing a distro and fixing bugs takes a lot of time and efforts, so the due closing credits line:
Thanks to the Linux Mint and Ubuntu folks for this distro!

2014-05-10

Let's run (chrooted) Debian Wheezy on LG Optimus Prime 4X HD (P880)

I have been struggling quite a bit to find a lightweight ROM for my phone, but now that I have finally settled down I believe it's time to start playing for real with this smartphone.

This is one of the official pictures provided by vendor, probably photoshopped. Gotta love those glares! Imagine this: you are going to pay extra $$$ to have good photos made for your nice shiny new product, and then you photoshop them to add glare. Wonderful times we live in :)

My experiment will be to have a running Debian Wheezy 7 inside my Android, and I will use this article as basis; I had some issues with those instructions, thus I created this updated post. I know there is the nice Lil'Debi out there, but that would spoil most of the fun :)

In order to build this Debian I am giving up a 4GB external microSD card that is plugged in my phone already, so first thing unmount it by going to Settings -> Storage:


Make a backup before continuing because we are going to completely replace its content.

So, let's recap the needed ingredients:
- a rooted Android phone, I am using LG Optimus Prime 4x HD
- an external microSD card, minimum 2GB
- debootstrap command on your Linux system (it's available almost everywhere)
- adb & your phone's USB configured to receive adb commands

Ready to go!
Let's build a tarball of the base Debian system for our target architecture. I have added my scripts (from this gist) to ease setup, but I advise you go through each of them at least for learning purposes.

debootstrap --arch armel --foreign wheezy wheezy http://http.debian.net/debian/
cd wheezy
wget https://gist.github.com/neagix/bbfed4f91f8821bed7e7/download -O gist.tgz
tar xf gist.tgz
mv gist*/* root/
rm -r gist.tgz gist*
chmod +x root/*.sh
sudo tar cf ../debian-wheezy-armel.tgz .
cd ..

At this point upload the archive to your P880 and let's start hacking our way through Android.
We will individuate our external SD by excluding the internal block device marked for boot. This is a hack, so always double-check results before wiping out the block device.

sudo adb push debian-wheezy-armel.tgz /data/local/
sudo adb shell
su
cd /dev/block/vold/
for D in `ls`; do fdisk -l $D | grep ^`echo $D | awk '{ print substr($1, 1, 3) }'`; done | grep '*' | awk '{ print substr($1, 1, length($1)-2) }' > /data/local/boot-device.txt
clear && echo -e "**********************\nThe individuated device of your external SD is: $PWD/`ls | grep -v $(</data/local/boot-device.txt )`\nPlease double check with output of fdisk -l before proceeding!!!\n**********************\n" && rm /data/local/boot-device.txt

(commands in blue are run in the adb shell, available also as gist here)
Example output you will see:
**********************
The individuated device of your external SD is: /dev/block/vold/179:49
Please double check with output of fdisk -l before proceeding!!!
**********************
Remember to double-check for correctness with fdisk, then take note of the individuated device. On my P880 it is:
/dev/block/vold/179:49
Now we will format the external SD, use the default mountpoint /storage/sdcard1 and extract the Debian base system on the external SD. The mount command will allow mounting the SD with dev and exec permissions, which are necessary for our Debian chroot to work.

NOTE: do not copy/paste these commands but run them one by one, so that you can take action in case of errors.

On the adb shell (replace device in bold with what you got from above, and remember to escape the ':'):

mkfs.ext2 -L AndyWheezy /dev/block/vold/179\:XXX
mount -o rw,noatime,nodiratime,user_xattr,acl,barrier=0,data=ordered,noauto_da_alloc -t ext4 /dev/block/vold/179\:XXX /storage/sdcard1/
cd /storage/sdcard1

mkdir rootfs && cd rootfs && tar xf /data/local/debian-wheezy-armel.tgz

Once this operation is complete successfully, you are half-way :) Feel free to remove the archive with:
rm /data/local/debian-wheezy-armel.tgz

Now let's enter the chroot environment with:
busybox chroot /storage/sdcard1/rootfs /bin/bash

Thanks to the correct permissions on our external SD, you now have the wonderful and powerful bash prompt available at your fingers' range.
I have no name!@localhost:/#
In our new chroot, run these commands (these are safer to copy/paste):
export PATH=/usr/bin:/usr/sbin:/bin:$PATH
export TERM=linux
export HOME=/root
export USER=root
mkdir /dev/pts
mount -t devpts devpts /dev/pts
mount -t proc proc /proc
mount -t sysfs sysfs /sys
/debootstrap/debootstrap --second-stage 

The last one will complete the debootstrap process, and will take some time (about 10 minutes for me).

Once it's complete you are basically done with the preparation of the Debian chroot :)

Now let's put the mount/umount scripts outside the chroot, so that you can easily call them in an Android shell:

mkdir /data/local/debian
mv /storage/sdcard1/rootfs/root/*.sh /data/local/debian/

From now on you can mount/umount your Debian chroot by calling one of these:

/data/local/debian/mount.sh # OR
/data/local/debian/umount.sh

Tips:
- set hostname in chroot: hostname AndyWheezy && hostname > /etc/hostname
- set APT sources in /etc/apt/sources.list (in chroot: mv /root/sources.list /etc/apt/)
- install an SSH server
- set your root password or better use certificates for remote login
- automate chroot setup/teardown with some scripts and use gscript to start them, for example: su -c '/data/local/debian/run.sh /storage/sdcard1 /etc/init.d/ssh start'


Here you see Debian Wheezy on all its glory, running from within a P880 Android device


Enjoy experimenting!