Configuring Android K-9 Mail from the command line

I hate having to re-enter my email settings in a new or reinstalled device. Secure passwords are particularly painful to transcribe via a phone keyboard, but it's not just the basic settings. It's also those extras like signature, disabling notifications and folders that buy you if they're not right. I've set it all up dozens of times before and will no doubt do it many more.

On my laptop and desktop I have a permanent, version controlled copy of my email settings that I can apply automatically. Surely you could do the same on Android/Replicant? I couldn't find any useful information about people doing this with configuration management tools like Puppet, Salt, Ansible or anything else so here's my first attempt:

#!/usr/bin/env bash

set -x

# Set the K-9 incoming and outgoing account details via ADB and SQLite3.
#
# Does not yet *create* the accounts, so you still need to click through the
# accounts wizard and enter dummy information.#
#
# K-9 account settings live in an SQLite3 database and have a unique identifier
# for each account. Records in the database look like:
#
# primkey                                           | value
# ba46a4cf-bde0-4d5d-aa6d-9da12a8367df.transportUri | xxx
#
# The transportUri and storeUri represent the server settings and are base64
# encoded, presumably to obfuscate the password.

PREFERENCES_DATABASE='/data/data/com.fsck.k9/databases/preferences_storage'
ACCOUNT_UUID_PERSONAL='ba46a4cf-bde0-4d5d-aa6d-9da12a8367df'
ACCOUNT_UUID_WORK='83a40e3e-a4ef-4351-a9f2-cd2fb8510654'

# These weird looking URLs came directly from the database (base64 decoded), eg.
# sqlite3 preferences_storage "select * from preferences_storage"
PERSONAL_STOREURI='imap+ssl+://PLAIN:ben%2540stumbles.id.au:password1@imap.fastmail.com:993/1%7C'
PERSONAL_TRANSPORTURI='smtp+ssl+://ben%2540stumbles.id.au:password1:PLAIN@smtp.fastmail.com:465'
WORK_STOREURI='imap+ssl+://PLAIN:ben%2540sturm.com.au:password2@imap.fastmail.com:993/1%7C'
WORK_TRANSPORTURI='smtp+ssl+://ben%2540sturm.com.au:password2:PLAIN@smtp.fastmail.com:465'
WORK_SIGNATURE=$(<~/dotfiles/.signature)

read -r -d '' QUERY <<EOF
    UPDATE preferences_storage SET VALUE = 'Ben Sturmfels' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.name.0';
    UPDATE preferences_storage SET VALUE = 'Personal' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.description';
    UPDATE preferences_storage SET VALUE = '$(echo -n $PERSONAL_STOREURI | base64)' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.storeUri';
    UPDATE preferences_storage SET VALUE = '$(echo -n $PERSONAL_TRANSPORTURI | base64)' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.transportUri';
    UPDATE preferences_storage SET VALUE = 'false' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.notifyNewMail';
    UPDATE preferences_storage SET VALUE = '' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.signature.0';
    UPDATE preferences_storage SET VALUE = 'Archive' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.sentFolderName';
    UPDATE preferences_storage SET VALUE = 'Junk Mail' WHERE primkey = '${ACCOUNT_UUID_PERSONAL}.spamFolderName';


    UPDATE preferences_storage SET VALUE = 'Ben Sturmfels' WHERE primkey = '${ACCOUNT_UUID_WORK}.name.0';
    UPDATE preferences_storage SET VALUE = 'Work' WHERE primkey = '${ACCOUNT_UUID_WORK}.description';
    UPDATE preferences_storage SET VALUE = '$(echo -n $WORK_STOREURI | base64)' WHERE primkey = '${ACCOUNT_UUID_WORK}.storeUri';
    UPDATE preferences_storage SET VALUE = '$(echo -n $WORK_TRANSPORTURI | base64)' WHERE primkey = '${ACCOUNT_UUID_WORK}.transportUri';
    UPDATE preferences_storage SET VALUE = 'false' WHERE primkey = '${ACCOUNT_UUID_WORK}.notifyNewMail';
    UPDATE preferences_storage SET VALUE = '--
${WORK_SIGNATURE}' WHERE primkey = '${ACCOUNT_UUID_WORK}.signature.0';
    UPDATE preferences_storage SET VALUE = 'Archive' WHERE primkey = '${ACCOUNT_UUID_WORK}.sentFolderName';
EOF

# As my config grew, ADB started telling me "error: service name too long", so I
# had to write the configuration to a shell script, transfer it to the phone and
# run it.
TEMPFILE=$(tempfile)
echo "sqlite3 $PREFERENCES_DATABASE \"$QUERY\"" > $TEMPFILE
adb push $TEMPFILE /data/local/tmp
adb shell sh /data/local/tmp/$(basename ${TEMPFILE})

The idea is that you'd plug in your Android/Replicant phone by USB with ADB debugging enabled and run the above shell script. I gather that you need to kill K-9 mail for the settings to take effect (long hold on primary button and close K-9).

Alright, now I'll freely admit that this took quite a bit more time than it would of to just complete the K-9 settings wizard, but it's the principle that counts! The great thing about Free Software is that I can have confidence that I'll be using K-9 for many years to come, so this investment of time is worthwhile.

I haven't tried creating accounts from scratch. It could be just generating a UUID identifier and setting [UUID].accountNumber to say 2 for a third account. Or there might be some place you need to register the UUID. That's work for another day.

blogroll

social

Powered by Pelican and Python. Theme by Smashing Magazine.