On writing my first snaps, and keeping my passwords secure everywhere

I’ve been writing snaps for a year, more or less. But all the snaps I had written were a one-time thing to reproduce a bug, automate a scenario, or explore a specific code path. A few months ago I decided to write one snap that I would use day-to-day. The application I use the most by far is keepass, so that seemed like a good place to start.

kpcli

With kpcli I access my password database from the command line. It’s just one big perl script, but not as ugly as it sounds :) That was a great first experiment because I haven’t tried perl in a snap before, and it would let me access the passwords from my beagle bone black in a secure and confined way.

Because it is a script, I just need to copy it into the snap. Of course, there’s a plugin for that! snapcraft is a meta-packaging tool to generate snaps. It comes with plugins for many packaging tools, copy being the most simple of them. Run:

  $ sudo apt install snapcraft
  $ snapcraft help copy

The next step is to look at the dependencies. Luckily, they are right there in the README file, in the form of Ubuntu packages. snapcraft calls them stage-packages, and they will be installed into the snap during the build.

Now I have almost all the difficult details to make the snap, and it was surprisingly easy. With this information, I wrote a part (read more about parts):

  kpcli:
    source: https://github.com/alecsammon/kpcli.git
    plugin: copy
    files:
      kpcli.pl: scripts/kpcli.pl
    stage-packages:
      - perl-base
      - libcrypt-rijndael-perl
      - libterm-readkey-perl
      - libsort-naturally-perl
      - libfile-keepass-perl
      - libterm-shellui-perl
      - libterm-readline-gnu-perl
      - libclone-perl

I am just missing a way to tell the command where to find the perl libraries that I am bundling inside the snap. There is work in progress to make it easier to set up environment variables before launching the command; but for my first simple snap, quick and easy will do. I wrote a wrapper script:

  #!/bin/sh

  $SNAP/usr/bin/perl -I $SNAP/usr/share/perl/5.22 -I $SNAP/usr/lib/x86_64-linux-gnu/perl/5.22 -I $SNAP/usr/lib/x86_64-linux-gnu/perl5/5.22 -I $SNAP/usr/share/perl5 $SNAP/scripts/kpcli.pl

and the corresponding part:

  launcher:
    plugin: copy
    files:
      run.sh: scripts/run.sh

Finally, I added details about the name, version, summary and description of the snap, and defined the kpcli app. You can download the source of this snapcraft.yaml, put it in a directory and run snapcraft in there to generate it yourself. Or try mine installing it from the store:

  $ sudo snap install kpcli-elopio
  $ kpcli-elopio.kpcli

KeepassX

Ok, that solves command line access, but I also want some eye-candy, sometimes. KeepassX gives me access to the same passwords database through a GUI. By the time I finished my CLI snap I saw work from kyrofa, sergiusens and dpm to make it easy to snap desktop apps and use them in Ubuntu classic. I also was at a sprint sitting next to attente, who knows everything I didn’t know about the desktop, so it was a great time to enter the world of collaborative snapping.

Let me digress here for a moment to talk about collaboration. snapcraft and snapd are free software, and a lot of their design is based on the idea that the system can be extended and improved through the shared work of many and diverse developers. snapcraft aims to be the universal packaging tool, and plugins are the way we integrate the wild variety of build systems into the lifecycle to generate a snap. KeepassX is more complex than the CLI client, and it uses cmake to generate the executable. Well, guess what? There’s a plugin for that! :) (see the source of the cmake plugin). Also, this application uses the QT5 UI libraries. Just like with the kpcli snap, that means I will require to set up some environment variables and a launcher; but somebody else already did that and we have a way to share and reuse parts. Run:

  $ snapcraft update
  $ snapcraft search qt5
  $ snapcraft define qt5conf

There’s a part for that!! And when this application is running, I would like it to be integrated with unity7, if available. That means I would need a few extra permissions for my isolated app to access the unity7 services and libraries installed in a classic Ubuntu system. I’m a lucky guy because there’s an interface for that!!! (see the source of the unity7 interface) By default, snaps will be fully confined and won’t be able to access anything they don’t provide by themselves. Through interfaces, we allow snaps to get extra permissions to consume services, access devices and directories, and do anything that you could do in a classic unconfined Linux system; but now in a controlled manner with the explicit acknowledgement of the user for sensitive stuff. Run:

  $ snap interfaces

We have plugins, parts and interfaces for the most common cases of the most common apps. But the fun is just starting, and there are lots and lots of apps out there that would benefit from the controlled dependencies, usable security and transactional updates of snaps. We celebrate when we get new people into the team, so if you want to participate and influence the future of this shiny project, we can help you getting started in the playpen.

One last detail about collaboration is the relation with upstreams and distribution maintainers. Snapping free software projects is a pleasure because the source is available for us to inspect and decide on the best strategy to build the snap. Then we spread the apps to more people, we get more feedback and in many cases we end up sending patches to improve the upstream project. And I already mentioned the use of Ubuntu packages during the build of the snaps. With this we bootstrap from the awesome work that the Debian and Ubuntu communities are doing, and we’ll keep benefitting from both sides as we need debs to build some snaps, and the two play nicely together.

Aaaand back on track, because with all the work shared by the community this KeepassX snap is almost done by itself, but not quite.

I start by creating a new snapcraft.yaml file an defining the snap details:

  name: keepassx-elopio
  version: "2.0.2"
  summary: KeePassX is a cross platform password safe
  description: |
    KeePassX is an application for people with extremly high demands on secure
    personal data management. It has a light interface, is cross platform and
    published under the terms of the GNU General Public License.

Next, the app:

  apps:
    keepassx:
      command: qt5-launch keepassx
      plugs: [unity7, opengl]

Take a look at that qt5-launch, which is provided from the shared qt part that I will reference in a few lines. keepassx is a binary that lives inside the snap, and that we will compile using a snapcraft plugin. Also look at those plugs. That’s how we tell the system that a snap wants to consume an interface slot of the same name.

Followed by the parts:

  parts:
    keepassx:
      source: https://github.com/keepassx/keepassx.git
      source-tag: 2.0.2
      plugin: cmake
      build-packages:
        - g++
        - qtbase5-dev
        - libqt4-dev
        - libqt5x11extras5-dev
        - qttools5-dev
        - qttools5-dev-tools
        - libgcrypt20-dev
        - zlib1g-dev
      stage-packages:
        - libgtk2.0-0
        - libqt5gui5
        - unity-gtk2-module
        - appmenu-qt5
        - dconf-gsettings-backend
      after: [qt5conf]

Note the new build-packages section. Those packages will not end up in the snap, they are only used during the compilation so they will be installed in the host where you are running snapcraft. I already discussed about the stage-packages, nothing new to see there. Now the after keyword is where a lot of the collaboration magic happens. It means that my keepassx part depends on the qt5conf part. But I don’t define the qt5conf part in my yaml file, so snapcraft will bring it from the pool of shared parts (see the source of the qt5conf part). I love this because I didn’t have to write any of the qt complications, and when a qt expert makes a change to improve it, I just need to run snapcraft again and my snap will be better with no effort. This is where the qt5-launch I used in the apps section comes from.

I finish my yaml adding a last part:

  ...
  parts:
    keepassx:
      ...
    glibcompiledassets:
      plugin: copy
      files:
        gschemas.compiled: usr/share/glib-2.0/schemas/gschemas.compiled
        giomodule.cache: usr/lib/x86_64-linux-gnu/gio/modules/giomodule.cache

This is required to save the KeepassX settings. It’s currently not a nice way to include the compiled files in the snap, and we are discussing about how to improve it, so I won’t dig too much here. It shows how simple yet flexible snaps are: you can put anything into the snap, it doesn’t matter how you got it. But it also shows that we have things to improve, so let me insist on my invitation for you to join our project. If there’s something you hate, this is the right time to change it. If there’s something you like, there’s always room to improve it. We have cookies.

Punto final, café con tamal. Give it a try:

  $ sudo snap install keepassx-elopio
  $ keepassx-elopio.keepassx

image

Convert cbr files to pdf

Here’s a quick tip. Generally when some of my good internet pirate friends share with me a comic book,1 it comes in the cbr format. There is no application for my Ubuntu phone to read these files (yet), but there are some good pdf readers. All I have to do is convert the files with some handy terminal commands.

A cbr file is just a group of image files compressed in the rar format. So, let’s uncompress the files in a temporary directory:

  dir=$(mktemp -d)
  cd $dir
  unrar x /path/to/file.cbr

And then let’s convert them to pdf:

  convert * /path/to/file.pdf

Open the pdf to check it is OK:

  evince /path/to/file.pdf

And delete the temporary directory:

  cd ..
  rm -rf $dir

Transfer to the phone, and enjoy.

Sharing the Wi-Fi connection through Ethernet

My apartment was clearly not designed for the Internet of Things. I have a weird set up to connect all my devices: there’s ADSL, Ethernet, Wi-Fi, powerline networking, 4G from a free promotion until I download 3GB and then 3G for the rest of the month... It’s crazy, and getting crazier as I have to test more and more devices for snappy. When I was about to throw a cable from the kitchen to the office I found about sharing the network (thanks Luis!). Now let me repeat a slightly modified version of part of Luis’ answer to show how I share my wireless connection through an ethernet cable with my test board.

  1. Open the network indicator.

  2. Click Edit Connections....

    image

  3. On the Network Connections dialog, click the Add button.

    image

  4. On the Choose a Connection Type dialog, select Ethernet.

    image

  5. On the Editing dialog, enter a name for the connection.

  6. Go to the IPv4 Settings tab.

  7. Select the Method Shared to other computers.

    image

  8. Click the Save button.

What’s left is to connect an Ethernet cable from your laptop to the board, give power to the board and wait for it to finish booting.

To get the IP of the board you can run the arp command (Thanks to Alex for the tip). It will show you the addresses of the neighbour machines. The one of your board will be like 10.42.0.?. Now you can ssh into the board using the default credentials (username ubuntu, password ubuntu) or the ones you configured.

image

This also proved to be useful during our first snappy maker night, when we had to connect many boards to play with the system.

Pro tip: If you are having problems connecting through ssh, you can connect through the serial console to check for errors.

Connecting to Snappy through the serial console

I’m working on Snappy Ubuntu with a BeagleBone Black Rev C and a Raspberry Pi 2. You can connect to the boards through the serial console to watch for errors during the boot process and to control the system. After my first burned cable I decided to write down the instructions to connect the cables to reduce the likelihood of my boards catching fire.

First, of course, you should flash the SD card with snappy. Then, get one of these FTDI cables that convert USB to serial. As this cable has the plugs separated, it will work for both boads. The black wire is ground (GND), the white wire is receive into the USB port, the green wire is transmit out of the USB port and the red wire is 5V power.

BeagleBone Black

The BeagleBone Black Rev C has 6 pins. There’s a white dot next to the first pin. Connect the black GND wire to the first pin, the green wire to the fourth pin and the white wire to the fifth pin. On the BeagleBone NEVER connect the red power wire.

image

image

Raspberry Pi

The Raspberry Pi 2 Model B has 40 pins. Here you can find a nice pinout drawing with the numbers and functions of the pins.

Connect the black GND wire to the sixth pin, the white wire to the eight pin and the green wire to the tenth pin. You can optionally power the Raspberry connecting the red wire to the second pin, but if you do this DO NOT connect the USB power connector as you can’t have both power sources.

image

image

Serial console

Install screen:

  sudo apt-get install screen

Plug the other end of the cable to an USB port of your computer and figure out the name of the tty device:

  ls /dev/ttyUSB*

And start the screen session on the serial terminal, replacing the /dev/ttyUSB? with the number of your device.

  sudo screen {/dev/ttyUSB?} 115200

Finally, insert the SD card and plug in the power source of the board. You will see the boot messages on your terminal and in the end you will be presented with the login prompt. The default user is ubuntu and the default password is ubuntu too.

image

Snappy has an SSH server preinstalled, so once you booted successfully you can login through SSH, which will give you a better experience. You can use the serial console to query the IP address of the board:

  ip addr show

And from a different terminal, replacing ip with the board IP address:

  ssh ubuntu@{ip}

Now you are ready to start playing with snappy on the board. Don’t miss the tour.

To exit the serial console, press CTRL+a and then k.

More information about the cables and the serial console

Awful Shape, what art thou?

JUPITER
[...]
Awful Shape, what art thou? Speak!

DEMOGORGON
Eternity – demand no direr name.
Descend, and follow me down the abyss;
I am thy child, as thou wert Saturn’s child,
Mightier than thee; and we must dwell together
Hencefoth in darkness. –Lift thy lightnings not.
The tyranny of Heaven none may retain,
Or reassume, or hold succeeding thee...
Yet if thou wilt–as ’tis the destiny
Of trodden worms to writhe til they are dead–
Put forth thy might.

on Prometheus Unbound, Act III, Scene I

There is no God

I was an infant when my mother went
To see an atheist burned. She took me there:
The dark-robed priests were met around the pile;
The multitude was gazing silently;
And as the culprit passed with dauntless mien,
Tempered disdain in his unaltering eye,
Mixed with a quiet smile, shone calmly forth:
The thirsty fire crept round his manly limbs;
His resolute eyes were scorched to blindness, soon;
His death-pang rent my heart! the insensate mob
Uttered a cry of triumph, and I wept.
“Weep not, child!” cried my mother, “for that man
Has said, ’There is no God.’”

on Queen Mab, Canto VII