All posts by John Goerzen

Review of Secure, Privacy-Respecting Email Services

I’ve been hosting my own email for several decades now. Even before I had access to a dedicated Internet link, I had email via dialup UUCP (and, before that, a FidoNet gateway).

But self-hosting email is becoming increasingly difficult. The time required to maintain spam and virus filters, SPF/DKIM settings, etc. just grows. The importance of email also is increasing. Although my own email has been extremely reliable, it is still running on a single server somewhere and therefore I could stand to have a lot of trouble if it went down while I was unable to fix it

Email with Pretty Good Privacy & Security

(Yes, this heading is a pun.)

There’s a lot of important stuff linked to emails. Family photos. Password resets for banks, social media sites, chat sites, photo storage sites, etc. Shopping histories. In a lot of cases, if your email was compromised, it wouldn’t be all that hard to next compromise your bank account, buy stuff with your Amazon account, hijack your Netflix, etc. There are lots of good resources about why privacy matters; here’s one informative video even if you think you have “nothing to hide”.

There is often a tradeoff between security and usability. A very secure system would be airgapped; you’d always compose your messages and use your secret keys on a system that has no Internet access and never will. Such a system would be quite secure, but not particularly usable.

On the other end of the spectrum are services such as Gmail, which not only make your email available to you, but also to all sorts of other systems within the service that aim to learn about your habits so they can sell this information to advertisers.

This post is about the services in the middle – ones that are usable, can be easily used on mobile devices, and yet make a serious and credible effort to provide better security and privacy than the “big services” run by Google, Yahoo, and Microsoft. Some elements of trust are inherent here; for instance, that the description of the technical nuances of the provider’s services are accurate. (Elements of trust are present in any system; whether your firmware, binaries, etc. are trustworthy.) I used the list at Privacy Tools as a guide to what providers to investigate, supplemented by searches and NoMoreGoogle.

It so happens that most of these services integrate PGP in some way. PGP has long been one of the better ways to have secure communication via email, but it is not always easy for beginners to use. These services make it transparent to a certain degree. None of them are as good as a dedicated client on an airgapped machine, but then again, such a setup isn’t very practical for everyday use. These services give you something better — pretty good, even — but of course not perfect. All of these pay at least lip service to Open Source, some of them actually publishing source for some of their components, but none are fully open.

I pay particular attention to how they handle exchanges with people that do not have PGP, as this kind of communication constitutes the vast majority of my email.

A final comment – if what you really need is an easy and secure way to communicate with one or two people, email itself may not be the right option. Consider Signal.

Protonmail

Protonmail is, in many ways, the gold standard of privacy-respecting email. Every email is stored encrypted in a way that even they can’t see, being decrypted on the client side (using a Javascript PGP implementation or other clients). They definitely seem to be pushing the envelope for security and privacy; they keep no IP logs, don’t require any personal information to set up an account, and go into quite a lot of detail about how your keys are protected.

A side effect of this is that you can’t just access your email with any mail reader. Since the decryption is done on the client side, you pretty much have to use a Protonmail client. They provide clients for iOS and Android, the Web interface, and a “bridge” that exposes IMAP and SMTP ports to localhost and lets you connect a traditional mail client to the system. The bridge, in this case, handles the decryption for you. The bridge works really well and supports Windows, Mac, and Linux, though it is closed source. (The source for the Linux bridge has been “coming soon” for awhile now.) Protonmail provides very good support for bringing your own domain, and in my testing this worked flawlessly. It supports Sieve-based filters, which can also act on envelope recipients (yes!) The web interface is sleek, very well done, tightly integrated, and just generally exceptionally easy to use and just works.

Unfortunately, the mobile clients get the job done for only light use. My opinion: they’re bad. Really bad. For instance:

  • There’s no way to change the sort order on a mail folder
  • The Android client has an option to automatically download all message bodies. The iOS client lacks this option, but no matter; it doesn’t work on Android anyhow.
  • They’re almost completely unusable offline. You can compose a brand new message but that’s it.

There are some other drawbacks. For one, they don’t actually encrypt mail metadata, headers, or subject lines (though this is common to all of the solutions here, Protonmail’s marketing glosses over this). They also seem to have a lot of problems with overly-aggressive systems blocking people’s accounts: here’s a report from 2017, and I’ve seen more recent ones from people that had paid, but then had the account disabled. Apparently protonmail is used by scammers a fair bit and this is a side-effect of offering free, highly secure accounts – some of their deactivations have been legitimate. Nevertheless, it makes me nervous, especially given the high number of reports of this on reddit.

Unfortunately, Proton seems more focused on new products than on fixing these issues. They’ve been long-simmering in the community but what they talk about is more about their upcoming new products.

Protonmail’s terms of service include both a disclaimer that it’s as-is and an SLA, as well as an indemnification clause. Update 2019-03-04: Protonmail’s privacy policy states they use Matomo analytics, that they don’t record your login IP address by default (but IP logs might be kept if you enable it or if they suspect spamming, etc), collect mobile app analytics, IP addresses on incoming messages, etc. Data is retained “indefinitely” for active accounts and for 14 days after account deletion for closed accounts.

Support: email ticket only

Pricing: $4/mo if paid annually; includes 5GB storage, 5 aliases, and 1 custom domain

Location: Switzerland

MFA: TOTP only

Plus address extensions: yes

Transparency report: yes

Mailfence

Mailfence is often mentioned in the same sentence as ProtonMail. They also aim to be a privacy-respecting, secure email solution.

While it is quite possible they use something like LUKS to encrypt data at rest (safeguarding it from a stolen hard drive), unlike ProtonMail, Mailfence does have access to the full content of any plaintext messages sent or received by your account. Mailfence integrates PGP into the Web interface, claiming end-to-end encryption with a “zero-knowledge environment” using, of all things, the same openpgpjs library that is maintained by ProtonMail. While ProtonMail offers a detailed description of key management, I haven’t been able to find this with Mailfence – other than that the private key is stored encrypted on their servers and is protected by a separate passphrase from the login. If we assume the private key is decrypted on the client side, then for PGP-protected communications, the level of security is similar to ProtonMail. With Mailfence, decrypting these messages is a separate operation, while with ProtonMail it happens automatically once logged in. (Update 2019-03-01: Mailfence emailed me, pointing to their document on key storage – it is AES-256 encrypted by the client and stored on the server. They also passed along a link describing their PGP keystore. They also said they plan to work on a feature th encrypt plain text messages.)

While technical measures are part of the story, business policies are another, and Mailfence does seem to have some pretty good policies in place.

In experimenting with it, I found that Mailfence’s filters don’t support filtering based on the envelope recipient, which limits the utility of its aliases since BCC and the like won’t filter properly. A workaround might be possible via the IMAP connection filtering based on Received: headers, but that is somewhat ugly.

Mailfence also supports “secure” documents (word processor, spreadsheet, etc), WebDAV file storage, contacts, and calendars. There is no detail on what makes it “secure” – is it just that it uses TLS or is there something more? I note that the online document editor goes to a URL under writer.zoho.com, so this implies some sort of leakage to me and a possible violation of their “no third-party access to your data” claim. (Update 2019-03-01: Mailfence emailed me to point out that, while it’s not disclosed on the page I liked to, it is disclosed on their blog, and that since I evaluated it, they added a popup warning in the application before sending the documents to Zoho.)

Mailfence supports POP, IMAP, SMTP, and — interestingly — Exchange ActiveSync access to their services. I tested ActiveSync on my Android device, and it appeared to work exactly as planned. This gives a lot of client flexibility and very nice options for calendar and contact sync (*DAV is also supported).

Mailfence’s terms of use is fairly reasonable, though it also includes an indemnification clause. It makes no particular uptime promises. Update 2019-03-04: Per their privacy policy, Mailfence logs IP addresses and use Matomo analytics on the website but not within the application. Deleted messages and documents are retained for 45 days. The policy does not specify retention for logs.

Support: email ticket or business-hours phone support for paying customers

Pricing: EUR 2.50/mo paid annually, includes 5GB storage, 10 aliases, and 1 custom domain

Location: Belgium

MFA: TOTP only

Plus address extensions: Yes

Transparency report: Yes

Mailbox.org

Mailbox.org has been in the hosting business for a long time, and also has a privacy emphasis. Their security is conceptually similar to that of Mailfence. They offer two web-based ways of dealing with PGP: OX Guard and Mailvelope. Mailvelope is a browser extension that does all encryption and decryption on the client side, similar to Mailfence and ProtonMail. OX Guard is part of the Open-Xchange package which mailbox.org uses. It stores the encryption keys on the server, protected by a separate key passphrase, but all encryption and decryption is done server-side. Mailbox’s KB articles on this makes it quite clear and spell out the tradeoffs. The basic upshot is that messages you receive in plaintext will still be theoretically visible to the service itself.

Mailbox.org offers another interesting feature: automatic PGP-encryption of any incoming email that isn’t already encrypted. This encrypts everything inbound. If accessed using Mailvelope or some other external client, it provides equivalent security to ProtonMail. (OX Guard is a little different since the decryption happens server-side.)

They also offer you an @secure.mailbox.org email address that will reject any incoming mail that isn’t properly secured by TLS. You can also send from that address, which will fail to send unless the outgoing connection is properly secured as well. This is one of the more interesting approaches to dealing with the non-PGP-using public. Even if you don’t use that, if you compose in their web interface, you get immediate feedback about the TLS that will be used. It’s not end-to-end, but it’s better than nothing. Mailfence and Protonmail both offer an “secure email” that basically emails a link to a recipient, that links back to their server and requires the recipient to enter a password that was presumably exchanged out of band. Mailbox Guard will automatically go this route when you attempt to send email to someone for whom the PGP keys weren’t known, but goes a step further and invites them to reply there or set up their PGP keys.

Mailbox.org runs Open-Xchange, a semi-Open Source web-based office suite. As such, it also offers calendar, contacts, documents, task lists, IMAP/SMTP/POP, ActiveSync, and so forth. Their KB specifically spells out that things like the calendar are not encrypted with PGP. The filtering does the right thing with envelope recipients.

Mailbox.org has an amazingly comprehensive set of options, a massive knowledge base, even a user forum. Some of the settings I found to be interesting, besides the ones already mentioned, include:

  • Spam settings: greylisting on or off, RBL use, executable file attachment blocking, etc.
  • Restoring email from a backup
  • Disposable addresses (automatically deleted after 30 days)
  • A “catch-all” alias, that just counts as one of your regular aliases, and applies to all usernames under a domain not otherwise aliased.

I know Protonmail has frequent third-party security audits; I haven’t seen any mention of this on the mailbox.org site. However, it looks probable that less of their code was written in house, and it may have been audited without a mention.

Overall, I’ve been pretty impressed with them. They give details on EVERYTHING. It’s the geeky sort of comprehensive, professional solution I’d like. I wish it would have full end-to-end transparent encryption like ProtonMail, but honestly what they’re doing is more practical and useful to a lot of folks.

Mailbox has a reasonable T&C (though it does include an indemnity clause as many others do) and a thorough data protection and privacy policy. Some providers don’t log IP addresses at all; mailbox.org does, but destroys them after 4 days. (Update 2019-03-04: Discovered that all of the providers reviewed may do this at times; updated the other reviews and removed incorrect text; mailbox.org’s is actually one of the better policies) mailbox.org goes into a lot more detail than others, and also explicitly supports things such as Tor for greater anonymity.

Support: email ticket (phone for business-level customers)

Pricing: EUR 1/mo for 2GB storage and 3 aliases; EUR 2.50/mo for 5GB storage and 25 aliases. Expansions possible (for instance, 25GB storage costs a total of EUR 3.50/mo)

Location: Germany

MFA: Yubikey, OATH, TOTP, HOTP, MOTP (web interface only)

Plus address extensions: Yes

Transparency Report: Yes

Startmail

Startmail is a service from the people behind the privacy-respecting search engine Startpage. There is not a lot of information about the technical implementation of Startmail, with the exception of a technical white paper from 2016. It is unclear if this white paper remains accurate, but this review will assume it is. There are also some articles in the knowledge base.

I was unable to fully review Startmail, because the free trial is quite limited (doesn’t even support IMAP) and anything past that level requires an up-front payment of $60. While I paid a few dollars for a month’s real account elsewhere, this was rather too much for a few paragraphs’ review.

However, from the trial, it appears to have a feature set roughly akin to Mailfence. Its mail filters are actually more limited, and it’s mail only: no documents, calendars, etc.

Startmail a somewhat unique setup, in which a person’s mail, PGP keys, etc. are stored in a “vault” which turns out to be a LUKS-encrypted volume. This vault is opened when a person logs in and closed when they log out, and controlled by a derivative of their password. On the one hand, this provides an even stronger level of security than Protonmail (since headers are also encrypted). On the other hand, when the vault is “open” – when one must presume it is quite frequently for an account being polled by IMAP – it is no better than anything else.

They explicitly state that they have not had a third-party audit.

Support: ticket only

Pricing: $60/yr ($5/mo), must be paid as an entire year up-front

Location: Netherlands

MFA: TOTP only

Plus address extensions: unknown

Transparency report: no

Not Reviewed

Some other frequently-used providers I didn’t review carefully:

  • posteo.de: encrypts your mail using a dovecot extension that decrypts it using a derivation of your password when you connect. Something better than nothing but less than Protonmail. Didn’t evaluate because it didn’t support my own domain.
  • Tutanota: Seems to have a security posture similar to ProtonMail, but has no IMAP support at all. If I can’t use emacs to read my mail, I’m not going to bother.

Conclusions

The level of security represented by Protonmail was quite appealing to me. I wish that the service itself was more usable. It looks like an excellent special-needs service, but just isn’t quite there yet as a main mail account for people that have a lot of mail.

I am likely to pursue mailbox.org some more, as although it isn’t as strong as Protonmail when it comes to privacy, it is still pretty good and is amazing on usability and flexibility.

A Final Word on Trust

Trust is a big part of everything going on here. For instance, if you use ProtonMail, where does trust come into play? Well, you trust that they aren’t serving you malicious JavaScript that captures your password and sends it to them out of band. You trust that your browser provides a secure environment for JavaScript and doesn’t have leakage. Or if you use mailbox.org, you trust that the server is providing a secure environment and that when you supply your password for the PGP key, it’s used only for that. ProtonMail will tell you how great it is to have this code client-side. Startmail will tell you how bad Javascript in a browser is for doing things related to security. Both make good, valid points.

To be absolutely sure, it is not possible or practical for any person to verify every component in their stack on every use. Different approaches have different trust models. The very best is still standalone applications.

The providers reviewed here raise the average level of privacy and security on the Internet, and do it by making it easier for the average user. That alone is a good thing and worthy of support. None of them can solve every problem, but all of them are a step up from the standard, which is almost no security at all.

Beauty Breaks Through

IMG_8795_v1

Two years ago, I was in the middle of the forest in rural southern Indiana. It was a time of hope – of defeating racism, sexism, xenophobia. Hope for affordable health care, for peace, for care for the young and the old. Then I woke up, in that beautiful place, to the news that Donald Trump would be president. Trump. President.

A few days later, I wrote Morning In The Skies, which included, in part:

Not long after the election, I got in a plane, pushed in the throttle, and started the takeoff roll down a runway in the midst of an Indiana forest. The skies were the best kind of clear blue, and pretty soon I lifted off and could see for miles. Off in the distance, I could see the last cottony remnants of the morning’s fog, lying still in the valleys, surrounding the little farms and houses as if to give them a loving hug. Wow.

Sometimes the flight is bumpy. Sometimes the weather doesn’t cooperate, and it doesn’t happen at all. Sometimes you can fly across four large states and it feels as smooth as glass the whole way.

Whatever happens, at the end of the day, the magic flying carpet machine gets locked up again. We go home, rest our heads on our soft pillows, and if we so choose, remember the beauty we experienced that day.

Really, this post is not about being a pilot. This post is a reminder to pay attention to all that is beautiful in this world. It surrounds us; the smell of pine trees in the forest, the delight in the faces of children, the gentle breeze in our hair, the kind word from a stranger, the very sunrise.

I hope that more of us will pay attention to the moments of clear skies and wind at our back. Even at those moments when we pull the hangar door shut.

For two years, I have often reflected on the bittersweet memories of that trip to Indiana. But for some reason, I hadn’t shared that photo until today. That beautiful valley-hugging fog is what you see above.

These last two years have been — well, full. Full of hate, even of death in the wake of several racist murders. But that’s not all. These years have also been full of an awakening, a swelling of people that care. People that care enough to do something. All across the country, people have risen up to send the message: “Trumpism is not American.” My own family did something we never had before: joined a protest, against families being separated. I and many others knocked on doors and made phone calls for the first time. Millions of Americans care and are doing something. We have seen the true colors of what the GOP has become, and it’s ugly, but people care. What’s more, we’ve won the first battle. Here in what the media often calls “deep-red Kansas”, we will have a Democratic governor. Racism and vote suppression has been sent packing, here in Kansas.

We have a powerful reminder that part of what makes this world beautiful is its people. People that go knock on doors in the cold. People that drive people to voting places. People that care about health care for others, about food for others, about education, intact families, refugees, and the earth itself. People that know the fight has just begun and are going to be there fighting for what is right and just for years to come. People that make the world beautiful.

The Python Unicode Mess

Unicode has solved a lot of problems. Anyone that remembers the mess of ISO-8859-* vs. CP437 (and of course it’s even worse for non-Western languages) can attest to that. And of course, these days they’re doing the useful work of…. codifying emojis.

Emojis aside, things aren’t all so easy. Today’s cause of pain: Python 3. So much pain.

Python decided to fully integrate Unicode into the language. Nice idea, right?

But here come the problems. And they are numerous.

gpodder, for instance, frequently exits with tracebacks due to Python errors converting podcast titles with smartquotes into ASCII. Then you have the case where the pexpect docs say to use logfile = sys.stdout to show the interaction with the virtual terminal. Only that causes an error these days.

But processing of filenames takes the cake. I was recently dealing with data from 20 years ago, before UTF-8 was a filename standard. These filenames are still valid on Unix. tar unpacks them, and they work fine. But you start getting encoding errors from Python trying to do things like store filenames in strings. For a Python program to properly support all valid Unix filenames, it must use “bytes” instead of strings, which has all sorts of annoying implications. What’s the chances that all Python programs do this correctly? Yeah. Not high, I bet.

I recently was processing data generated by mtree, which uses octal escapes for special characters in filenames. I thought this should be easy in Python, eh?

That second link had a mention of an undocumented function, codecs.escape_decode, which does it right. I finally had to do this:

    if line.startswith(b'#'):
        continue
    fields = line.split()
    filename = codecs.escape_decode(fields[0])[0]
    filetype = getfield(b"type", fields[1:])
    if filetype == b"file":

And, whatever you do, don’t accidentally write if filetype == "file" — that will silently always evaluate to False, because "file" tests different than b"file". Not that I, uhm, wrote that and didn’t notice it at first…

So if you want to actually handle Unix filenames properly in Python, you:

  • Must have a processing path that fully avoids Python strings.
  • Must use sys.{stdin,stdout}.buffer instead of just sys.stdin/stdout
  • Must supply filenames as bytes to various functions. See PEP 0471 for this comment: “Like the other functions in the os module, scandir() accepts either a bytes or str object for the path parameter, and returns the DirEntry.name and DirEntry.path attributes with the same type as path. However, it is strongly recommended to use the str type, as this ensures cross-platform support for Unicode filenames. (On Windows, bytes filenames have been deprecated since Python 3.3).” So if you want to be cross-platform, it’s even worse, because you can’t use str on Unix nor bytes on Windows.

Update: Would you like to receive filenames on the command line? I’ll hand you this fine mess. And the environment? it’s not even clear.

Making a difference

Every day, ask yourself this question: What one thing can I do today that will make this democracy stronger and honor and support its institutions? It doesn’t have to be a big thing. And it probably won’t shake the Earth. The aggregation of them will shake the Earth.

– Benjamin Wittes

I have written some over the past year or two about the dangers facing the country. I have become increasingly alarmed about the state of it. And that Benjamin Wittes quote, along with the terrible tragedy, spurred me to action. Among other things, I did two things I never have done before:

I registered to protest on June 30.

I volunteered to do phone banking with SwingLeft.

And I changed my voter registration from independent to Republican.

No, I have not gone insane. The reason for the latter is that here in Kansas, the Democrats rarely field candidates for most offices. The real action happens in the Republican primary. So if I can vote in that primary, I can have a voice in keeping the crazy out of office. It’s not much, but it’s something.

Today we witnessed, hopefully, the first victory in our battle against the abusive practices happening to children at the southern border. Donald Trump caved, and in so doing, implicitly admitted the lies he and his administration have been telling about the situation. This only happened because enough people thought like Wittes: “I am small, but I can do SOMETHING.” When I called the three Washington offices of my senators and representatives — far-right Republicans all — it was apparent that I was by no means the first to give them an earful about this, and that they were changing their tone because of what they heard. Mind you, they hadn’t taken any ACTION yet, but the calls mattered. The reporting mattered. The attention mattered.

I am going to keep doing what little bit I can. I hope everyone else will too. Let us shake the Earth.

Memories, Father’s Day, and an 89-year-old plane

“Oh! I have slipped the surly bonds of Earth
And danced the skies on laughter-silvered wings;
Sunward I’ve climbed, and joined the tumbling mirth
of sun-split clouds, — and done a hundred things”

– John Gillespie Magee, Jr.

I clicked on the radio transmitter in my plane.

O’Neill Traffic, Bonanza xx departing to the south. And Trimotor, thanks for flight . We really enjoyed it.

And we had. Off to my left, a 1929 Ford Trimotor airliner was heading off into the distance, looking as if it were just hanging in the air, glinting in the morning sun, 1000 feet above the ground. Earlier that morning, my boys and I had been passengers in that very plane. But now we had taken off right after them, as they were taking another load of passengers up for a flight and we were flying back home. To my right was my 8-year-old, and my 11-year-old was in back, both watching out the windows. The radio clicked on, and the three of us heard the other pilot’s response:

Oh thank you. We’re glad you came!

A few seconds later, they were gone out of sight.

The experience of flying in an 89-year-old airliner is quite something. As with the time we rode on the Durango & Silverton railroad, it felt like stepping back into a time machine — into the early heyday of aviation.

Jacob and Oliver had been excited about this day a long time. We had tried to get a ride when it was on tour in Oklahoma, much closer, but one of them got sick on the drive that day and it didn’t work out. So Saturday morning, we took the 1.5-hour-flight up to northern Nebraska. We’d heard they’d have a pancake breakfast fundraiser, and the boys were even more excited. They asked to set the alarm early, so we’d have no risk of missing out on airport pancakes.

Jacob took this photo of the sunrise at the airport while I was doing my preflight checks:

IMG_1574

Here’s one of the beautiful views we got as we flew north to meet the Trimotor.

IMG_20180616_070810_v1

It was quite something to share a ramp with that historic machine. Here’s a photo of our plane not far from the Trimotor.

IMG_20180616_082051

After we got there, we checked in for the flight, had a great pancake and sausage breakfast, and then into the Trimotor. The engines fired up with a most satisfying low rumble, and soon we were aloft — cruising along at 1000 feet, in that (by modern standards) noisy, slow, and beautiful machine. We explored the Nebraska countryside from the air before returning 20 minutes later. I asked the boys what they thought.

“AWESOME!” was the reply. And I agreed.

IMG_20180616_090828

Jacob and Oliver have long enjoyed pretending to be flight attendants when we fly somewhere. They want me to make airline-sounding announcements, so I’ll say something like, “This is your captain speaking. In a few moments, we’ll begin our descent into O’Neill. Flight attendants, prepare the cabin for arrival.” Then Jacob will say, “Please return your tray tables that you don’t have to their full upright and locked position, make sure your seat belt is tightly fastened, and your luggage is stowed. This is your last chance to visit the lavatory that we don’t have. We’ll be on the ground shortly.”

Awhile back, I loaded up some zip-lock bags with peanuts and found some particularly small bottles of pop. Since then, it’s become tradition on our longer flights for them to hand out bags of peanuts and small quantities of pop as we cruise along — “just like the airlines.” A little while back, I finally put a small fridge in the hangar so they get to choose a cold beverage right before we leave. (We don’t typically have such things around, so it’s a special treat.)

Last week, as I was thinking about Father’s Day, I told them how I remembered visiting my dad at work, and how he’d let me get a bottle of Squirt from the pop machine there (now somewhat rare). So when we were at the airport on Saturday, it brought me a smile to hear, “DAD! This pop machine has Squirt! Can we get a can? It’s only 75 cents!” “Sure – after our Trimotor flight.” “Great! Oh, thank you dad!”

I realized then I was passing a small but special memory on to another generation. I’ve written before of my childhood memories of my dad, and wondering what my children will remember of me. Martha isn’t old enough yet to remember her cackles of delight as we play peek-a-boo or the books we read at bedtime. Maybe Jacob and Oliver will remember our flights, or playing with mud, or researching dusty maps in a library, playing with radios, or any of the other things we do. Maybe all three of them will remember the cans of Squirt I’m about to stock that hangar fridge with.

But if they remember that I love them and enjoy doing things with them, they will have remembered the most important thing. And that is another special thing I got from my parents, and can pass on to another generation.

Syncing with a memory: a unique use of tar –listed-incremental

I have a Nextcloud instance that various things automatically upload photos to. These automatic folders sync to a directory on my desktop. I wanted to pull things out of that directory without deleting them, and only once. (My wife might move them out of the directory on her computer, and I might arrange them into targets on my end.)

In other words, I wanted to copy a file from a source to a destination, but remember what had been copied before so it only ever copies once.

rsync doesn’t quite do this. But it turns out that tar’s listed-incremental feature can do exactly that. Ordinarily, it would delete files that were deleted on the source. But if we make the tar file with the incremental option, but extract it without, it doesn’t try to delete anything at extract time.

Here’s my synconce script:

#!/bin/bash

set -e

if [ -z "$3" ]; then
    echo "Syntax: $0 snapshotfile sourcedir destdir"
    exit 5
fi

SNAPFILE="$(realpath "$1")"
SRCDIR="$2"
DESTDIR="$(realpath "$3")"

cd "$SRCDIR"
if [ -e "$SNAPFILE" ]; then
    cp "$SNAPFILE" "${SNAPFILE}.new"
fi
tar "--listed-incremental=${SNAPFILE}.new" -cpf - . | \
    tar -xf - -C "$DESTDIR"
mv "${SNAPFILE}.new" "${SNAPFILE}"

Just have the snapshotfile be outside both the sourcedir and destdir and you’re good to go!

Running Digikam inside Docker

After my recent complaint about AppImage, I thought I’d describe how I solved my problem. I needed a small patch to Digikam, which was already in Debian’s 5.9.0 package, and the thought of rebuilding the AppImage was… unpleasant.

I thought – why not just run it inside Buster in Docker? There are various sources on the Internet for X11 apps in Docker. It took a little twiddling to make it work, but I did.

My Dockerfile was pretty simple:

FROM debian:buster
MAINTAINER John Goerzen 

RUN apt-get update && \
    apt-get -yu dist-upgrade && \
    apt-get --install-recommends -y install firefox-esr digikam digikam-doc \
         ffmpegthumbs imagemagick minidlna hugin enblend enfuse minidlna pulseaudio \
         strace xterm less breeze && \
    apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN adduser --disabled-password --uid 1000 --gecos "John Goerzen" jgoerzen && \
    rm -r /home/jgoerzen/.[a-z]*
RUN rm /etc/machine-id
CMD /usr/bin/docker

RUN mkdir -p /nfs/personalmedia /run/user/1000 && chown -R jgoerzen:jgoerzen /nfs /run/user/1000

I basically create the container and my account in it.

Then this script starts up Digikam:

#!/bin/bash

set -e

# This will be unnecessary with docker 18.04 theoretically....  --privileged see
# https://stackoverflow.com/questions/48995826/which-capabilities-are-needed-for-statx-to-stop-giving-eperm
# and https://bugs.launchpad.net/ubuntu/+source/docker.io/+bug/1755250

docker run -ti \
       -v /tmp/.X11-unix:/tmp/.X11-unix -v "/run/user/1000/pulse:/run/user/1000/pulse" -v /etc/machine-id:/etc/machine-id \
       -v /etc/localtime:/etc/localtime \
       -v /dev/shm:/dev/shm -v /var/lib/dbus:/var/lib/dbus -v /var/run/dbus:/var/run/dbus -v /run/user/1000/bus:/run/user/1000/bus  \
       -v "$HOME:$HOME" -v "/nfs/personalmedia/Pictures:/nfs/personalmedia/Pictures" \
     -e DISPLAY="$DISPLAY" \
     -e XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
     -e DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" \
     -e LANG="$LANG" \
     --user "$USER" \
     --hostname=digikam \
     --name=digikam \
     --privileged \
     --rm \
     jgoerzen/digikam "$@"  /usr/bin/digikam

The goal here was not total security isolation; if it had been, then all the dbus mounting and $HOME mounting was a poor idea. But as an alternative to AppImage — well, it worked perfectly. I could even get security updates if I wanted.

Please stop making the library situation worse with attempts to fix it

I recently had a simple-sounding desire. I would like to run the latest stable version of Digikam. My desktop, however, runs Debian stable, which has 5.3.0, not 5.9.0.

This is not such a simple proposition.


$ ldd /usr/bin/digikam | wc -l
396

And many of those were required at versions that weren’t in stable.

I had long thought that AppImage was a rather bad idea, but I decided to give it a shot. I realized it was worse than I had thought.

The problems with AppImage

About a year ago, I wrote about the problems Docker security. I go into much more detail there, but the summary for AppImage is quite similar. How can I trust all the components in the (for instance) Digikam AppImage image are being kept secure? Are they using the latest libssl and libpng, to avoid security issues? How will I get notified of a security update? (There seems to be no mechanism for this right now.) An AppImage user that wants to be secure has to manually answer every one of those questions for every application. Ugh.

Nevertheless, the call of better facial detection beckoned, and I downloaded the Digikam AppImage and gave it a whirl. The darn thing actually fired up. But when it would play videos, there was no sound. Hmmmm.

I found errors like this:

Cannot access file ././/share/alsa/alsa.conf

Nasty. I spent quite some time trying to make ALSA work, before a bunch of experimentation showed that if I ran alsoft-conf on the host, and selected only the PulseAudio backend, then it would work. I reported this bug to Digikam.

Then I thought it was working — until I tried to upload some photos. It turns out that SSL support in Qt in the AppImage was broken, since it was trying to dlopen an incompatible version of libssl or libcrypto on the host. More details are in the bug I reported about this also.

These are just two examples. In the rather extensive Googling I did about these problems, I came across issue after issue people had with running Digikam in an AppImage. These issues are not limited to the ALSA and SSL issues I describe here. And they are not occurring due to some lack of skill on the part of Digikam developers.

Rather, they’re occurring because AppImage packaging for a complex package like this is hard. It’s hard because it’s based on a fiction — the fiction that it’s possible to make an AppImage container for a complex desktop application act exactly the same, when the host environment is not exactly the same. Does the host run PulseAudio or ALSA? Where are its libraries stored? How do you talk to dbus?

And it’s not for lack of trying. The scripts to build the Digikam appimage support runs to over 1000 lines of code in the AppImage directory, plus another 1300 lines of code (at least) in CMake files that handle much of the work, and another 3000 lines or so of patches to 3rd-party packages. That’s over 5000 lines of code! By contrast, the Debian packaging for the same version of Digikam, including Debian patches but excluding the changelog and copyright files, amounts to 517 lines. Of course, it is reusing OS packages for the dependencies that were already built, but this amounts to a lot simpler build.

Frankly I don’t believe that AppImage really lives up to its hype. Requiring reinventing a build system and making some dangerous concessions on security for something that doesn’t really work in the end — not good in my book.

The library problem

But of course, AppImage exists for a reason. That reason is that it’s a real pain to deal with so many levels of dependencies in software. Even if we were to compile from source like the old days, and even if it was even compatible with the versions of the dependencies in my OS, that’s still a lot of work. And if I have to build dependencies from source, then I’ve given up automated updates that way too.

There’s a lot of good that ELF has brought us, but I can’t help but think that it wasn’t really designed for a world in which a program links 396 libraries (plus dlopens a few more). Further, this world isn’t the corporate Unix world of the 80s; Open Source developers aren’t big on maintaining backwards compatibility (heck, both the KDE and Qt libraries under digikam have both been entirely rewritten in incompatible ways more than once!) The farther you get from libc, the less people seem to care about backwards compatibility. And really, who can blame volunteers? You want to work on new stuff, not supporting binaries from 5 years ago, right?

I don’t really know what the solution is here. Build-from-source approaches like FreeBSD and Gentoo have plenty of drawbacks too. Is there some grand solution I’m missing? Some effort to improve this situation without throwing out all the security benefits that individually-packaged libraries give us in distros like Debian?

Emacs #5: Documents and Presentations with org-mode

The Emacs series

This is fifth in a series on Emacs and org-mode.

This blog post was generated from an org-mode source and is available as: a blog page, slides (PDF format), and a PDF document.

1 About org-mode exporting

1.1 Background

org-mode isn't just an agenda-making program. It can also export to lots of formats: LaTeX, PDF, Beamer, iCalendar (agendas), HTML, Markdown, ODT, plain text, man pages, and more complicated formats such as a set of web pages.

This isn't just some afterthought either; it's a core part of the system and integrates very well.

One file can be source code, automatically-generated output, task list, documentation, and presentation, all at once.

Some use org-mode as their preferred markup format, even for things like LaTeX documents. The org-mode manual has an extensive section on exporting.

1.2 Getting started

From any org-mode document, just hit C-c C-e. From there will come up a menu, letting you choose various export formats and options. These are generally single-key options so it's easy to set and execute. For instance, to export a document to a PDF, use C-c C-e l p or for HTML export, C-c C-e h h.

There are lots of settings available for all of these export options; see the manual. It is, in fact, quite possible to use LaTeX-format equations in both LaTeX and HTML modes, to insert arbitrary preambles and settings for different modes, etc.

1.3 Add-on packages

ELPA containts many addition exporters for org-mode as well. Check there for details.

2 Beamer slides with org-mode

2.1 About Beamer

Beamer is a LaTeX environment for making presentations. Its features include:

  • Automated generating of structural elements in the presentation (see, for example, the Marburg theme). This provides a visual reference for the audience of where they are in the presentation.
  • Strong help for structuring the presentation
  • Themes
  • Full LaTeX available

2.2 Benefits of Beamer in org-mode

org-mode has a lot of benefits for working with Beamer. Among them:

  • org-mode's very easy and strong support for visualizing and changing the structure makes it very quick to reorganize your material.
  • Combined with org-babel, live source code (with syntax highlighting) and results can be embedded.
  • The syntax is often easier to work with.

I have completely replaced my usage of LibreOffice/Powerpoint/GoogleDocs with org-mode and beamer. It is, in fact, rather frustrating when I have to use one of those tools, as they are nowhere near as strong as org-mode for visualizing a presentation structure.

2.3 Headline Levels

org-mode's Beamer export will convert sections of your document (defined by headings) into slides. The question, of course, is: which sections? This is governed by the H export setting (org-export-headline-levels).

There are many ways to go, which suit people. I like to have my presentation like this:

#+OPTIONS: H:2
#+BEAMER_HEADER: \AtBeginSection{\frame{\sectionpage}}

This gives a standalone section slide for each major topic, to highlight major transitions, and then takes the level 2 (two asterisks) headings to set the slide. Many Beamer themes expect a third level of indirection, so you would set H:3 for them.

2.4 Themes and settings

You can configure many Beamer and LaTeX settings in your document by inserting lines at the top of your org file. This document, for instance, defines:

#+TITLE:  Documents and presentations with org-mode
#+AUTHOR: John Goerzen
#+BEAMER_HEADER: \institute{The Changelog}
#+PROPERTY: comments yes
#+PROPERTY: header-args :exports both :eval never-export
#+OPTIONS: H:2
#+BEAMER_THEME: CambridgeUS
#+BEAMER_COLOR_THEME: default

2.5 Advanced settings

I like to change some colors, bullet formatting, and the like. I round out my document with:

# We can't just +BEAMER_INNER_THEME: default because that picks the theme default.
# Override per https://tex.stackexchange.com/questions/11168/change-bullet-style-formatting-in-beamer
#+BEAMER_INNER_THEME: default
#+LaTeX_CLASS_OPTIONS: [aspectratio=169]
#+BEAMER_HEADER: \definecolor{links}{HTML}{0000A0}
#+BEAMER_HEADER: \hypersetup{colorlinks=,linkcolor=,urlcolor=links}
#+BEAMER_HEADER: \setbeamertemplate{itemize items}[default]
#+BEAMER_HEADER: \setbeamertemplate{enumerate items}[default]
#+BEAMER_HEADER: \setbeamertemplate{items}[default]
#+BEAMER_HEADER: \setbeamercolor*{local structure}{fg=darkred}
#+BEAMER_HEADER: \setbeamercolor{section in toc}{fg=darkred}
#+BEAMER_HEADER: \setlength{\parskip}{\smallskipamount}

Here, aspectratio=169 sets a 16:9 aspect ratio, and the remaining are standard LaTeX/Beamer configuration bits.

2.6 Shrink (to fit)

Sometimes you've got some really large code examples and you might prefer to just shrink the slide to fit.

Just type C-c C-x p, set the BEAMER_opt property to shrink=15.

(Or a larger value of shrink). The previous slide uses this here.

2.7 Result

Here's the end result:

screenshot1

3 Interactive Slides

3.1 Interactive Emacs Slideshows

With the org-tree-slide package, you can display your slideshow from right within Emacs. Just run M-x org-tree-slide-mode. Then, use C-> and C-< to move between slides.

You might find C-c C-x C-v (which is org-toggle-inline-images) helpful to cause the system to display embedded images.

3.2 HTML Slideshows

There are a lot of ways to export org-mode presentations to HTML, with various levels of JavaScript integration. See the non-beamer presentations section of the org-mode wiki for details.

4 Miscellaneous

4.1 Additional resources to accompany this post

4.2 Up next in my Emacs series…

mu4e for email!

Emacs #4: Automated emails to org-mode and org-mode syncing

This is fourth in a series on Emacs and org-mode.

Hopefully by now you’ve started to see how powerful and useful org-mode is. If you’re like me, you’re thinking:

“I’d really like to have this in sync across all my devices.”

and, perhaps:

“Can I forward emails into org-mode?”

This being Emacs, the answers, of course, are “Yes.”

Syncing

Since org-mode just uses text files, syncing is pretty easily accomplished using any number of tools. I use git with git-remote-gcrypt. Due to some limitations of git-remote-gcrypt, each machine tends to push to its own branch, and to master on command. Each machine merges from all the other branches and pushes the result to master after a merge. A cron job causes pushes to the machine’s branch to happen, and a bit of elisp coordinates it all — making sure to save buffers before a sync, refresh them from disk after, etc.

The code for this post is somewhat more extended, so I will be linking to it on github rather than posting inline.

I have a directory $HOME/org where all my org-stuff lives. In ~/org lives a Makefile that handles the syncing. It defines these targets:

  • push: adds, commits, and pushes to a branch named after the machine’s hostname
  • fetch: does a simple git fetch
  • sync: adds, commits, pulls remote changes, merges, and (assuming the merge was successful) pushes to the branch named after the machine’s hostname plus master

Now, in my user’s crontab, I have this:

*/15   *   *  *   *      make -C $HOME/org push fetch 2>&1 | logger --tag 'orgsync'

The accompanying elisp code defines a shortcut (C-c s) to cause a sync to occur. Thanks to the cronjob, as long as files were saved — even if I didn’t explicitly sync on the other boxen — they’ll be pulled in.

I have found this setup to work really well.

Emailing to org-mode

Before going down this path, one should ask the question: do you really need it? I use org-mode with mu4e, and the integration is excellent; any org task can link to an email by message-id, and this is ideal — it lets a person do things like make a reminder to reply to a message in a week.

However, org is not just about reminders. It’s also a knowledge base, authoring system, etc. And, not all of my mail clients use mu4e. (Note: things like MobileOrg exist for mobile devices). I don’t actually use this as much as I thought I would, but it has its uses and I thought I’d document it here too.

Now I didn’t want to just be able to accept plain text email. I wanted to be able to handle attachments, HTML mail, etc. This quickly starts to sound problematic — but with tools like ripmime and pandoc, it’s not too bad.

The first step is to set up some way to get mail into a specific folder. A plus-extension, special user, whatever. I then use a fetchmail configuration to pull it down and run my insorgmail script.

This script is where all the interesting bits happen. It starts with ripmime to process the message. HTML bits are converted from HTML to org format using pandoc. an org hierarchy is made to represent the structure of the email as best as possible. emails can get pretty complicated, with HTML and the rest, but I have found this does an acceptable job with my use cases.

Up next…

My last post on org-mode will talk about using it to write documents and prepare slides — a use for which I found myself surprisingly pleased with it, but which needed a bit of tweaking.