Automating Let’s Encrypt Wildcard Certificates with the Namecheap API

I’m a big fan of Let’s Encrypt but when I recently found out about TLS Certificate Transparency Logs and how easy they made searching for otherwise unpublished subdomains, I decided that it might be a good idea to look into using wildcard TLS certificates.

A minor complication was that to validate a wildcard certificate Let’s Encrypt needs to create a TXT DNS record for your domain with a validation code. This is known as the DNS-01 challenge. I happen to use Namecheap as the registrar for most of my domains and luckily there is a Python library to access their API and automatically create this DNS record.

I’ve written a quick Python script which works as a manual authentication hook for Let’s Encrypt’s certbot and helps to automate the process of issuing / renewing a certificate using the DNS-01 challenge.

Usage:

  1. Obtain API credentials for Namecheap as detailed here
  2. Download the script and edit to add the API credentials to the appropriate variables
    N.B. Bad Things could happen if these credentials become public, please take appropriate precautions to keep them secure.
  3. To issue / renew a wildcard certificate for your domain run certbot something like this:
    sudo certbot certonly \
    --non-interactive \
    --manual \
    --manual-public-ip-logging-ok \
    -d <*.domain> \
    --email <email@address> \
    --manual-auth-hook <path/to/the/script>

Pairing a bluetooth Intsun/Terios T3 gamepad on Linux

These instructions are mostly for my later convenience but if you have an Intsun or Terios T3 bluetooth gamepad that you want to pair with Linux via the command line they might help you out.

These instructions assume you have a bluetooth dongle that is recognised by your kernel. I’ve had success with this one. These steps worked for me on Ubuntu 16.04 LTS.

  1. Install the following packages:
    $ sudo apt-get install bluez joystick
  2. Put the gamepad in bluetooth pairing mode by holding down the X and Home buttons simultaneously. The LED ring around the home button should now start blinking rapidly.
  3. Start the interactive command-line interface to the bluetooth stack bluetoothctl
    $ sudo bluetoothctl
    [NEW] Controller XX:XX:XX:XX:XX:XX live-0 [default]

    For readability I’ll put the typed commands in blue from here on.
  4. Next power on your bluetooth interface and make it discoverable (maybe not strictly necessary):
    [bluetooth]# power on
    Changing power on succeeded
    [bluetooth]# discoverable on
    Changing discoverable on succeeded
    [CHG] Controller XX:XX:XX:XX:XX:XX Discoverable: yes
  5. Register as the default agent:
    [bluetooth]# agent on
    Agent registered
    [bluetooth]# default-agent
    Default agent request successful
  6. Start scanning to look for discoverable devices:
    [bluetooth]# scan on
    Discovery started
    [CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
  7. After a few seconds the devices command should list your gamepad:
    [bluetooth]# devices
    [NEW] Device YY:YY:YY:YY:YY:YY Bluetooth Gamepad
  8. It seems that PIN-less pairing requires that the device be trusted first:
    [bluetooth]# trust YY:YY:YY:YY:YY:YY
    [CHG] Device YY:YY:YY:YY:YY:YY Trusted: yes
    Changing YY:YY:YY:YY:YY:YY trust succeeded
  9. Try to pair with the gamepad:
    [bluetooth]# pair YY:YY:YY:YY:YY:YY
    Attempting to pair with YY:YY:YY:YY:YY:YY
    [CHG] Device YY:YY:YY:YY:YY:YY Connected: yes
    [CHG] Device YY:YY:YY:YY:YY:YY Modalias: usb:v1949p0402d011B
    [CHG] Device YY:YY:YY:YY:YY:YY UUIDs: 00001124-0000-1000-8000-00805f9b34fb
    [CHG] Device YY:YY:YY:YY:YY:YY UUIDs: 00001200-0000-1000-8000-00805f9b34fb
    [CHG] Device YY:YY:YY:YY:YY:YY Paired: yes
    Pairing successful
  10. Connect to the gamepad:
    [bluetooth]# connect YY:YY:YY:YY:YY:YY
    Attempting to connect to YY:YY:YY:YY:YY:YY
  11. Quit bluetoolctl:
    [bluetooth]# quit
    Agent unregistered
    [DEL] Controller XX:XX:XX:XX:XX:XX live-0 [default]

All being well the gamepad LEDs will now stop flashing and a single one will be illuminated.

You can test the gamepad using the jstest command:
jstest /dev/input/js0
(your device name may vary)

Virgin Media WiFi Android app on a rooted device

Virgin Media have a handy Android app which lets Virgin Media subscribers connect to their Virgin Media WiFi service. However they have, in their infinite wisdom, decided that they will not support running this app on rooted Android devices – which is entirely their prerogative.

As a longtime fan of rooted Android (I currently run LineageOS 14.1 on my HTC 10) I was disappointed by Virgin’s decision but decided to treat it as a learning opportunity. So, purely for academic / research purposes, is it possible to modify the Android APK such that it will run on a rooted handset? Yes, yes it is and it’s quite easy if you know what you’re doing.

Here’s how I went about my proof-of-concept:

  1. Install the Virgin Media WiFi app on your phone from the Play Store.
  2. Use ADB to pull the APK file from your device. For me this worked like this:
    adb pull /data/app/com.virginmedia.simplewifi-1
    pull: building file list...
    pull: /data/app/com.virginmedia.simplewifi-1/lib/arm64/libdevicescape-jni.so -> ./lib/arm64/libdevicescape-jni.so
    pull: /data/app/com.virginmedia.simplewifi-1/base.apk -> ./base.apk
    
  3. Use the fantastic apktool to decompile the base.apk:
    apktool d base.apk
    I: Using Apktool 2.2.2 on base.apk
    I: Loading resource table...
    I: Decoding AndroidManifest.xml with resources...
    I: Loading resource table from file: /home/simon/.local/share/apktool/framework/1.apk
    I: Regular manifest package...
    I: Decoding file-resources...
    I: Decoding values */* XMLs...
    I: Baksmaling classes.dex...
    I: Copying assets and libs...
    I: Copying unknown files...
    I: Copying original files...
  4. Now let’s start looking for the text in the toast notification it pops up to tell you it’s not going to run on a rooted device:
    grep -R "rooted" *
    res/values/public.xml:    <public type="string" name="alert_rooted_device" id="0x7f0800d1" />
    res/values/strings.xml:    <string name="alert_rooted_device">For security reasons you are not able to run this app on a rooted device</string>

    I’d take a reasonable guess that “alert_rooted_device” is the one we’re after. Let’s see if that id “0x7f0800d1” is referenced anywhere in the decompiled code:

    grep -Ri "7f0800d1" *
    res/values/public.xml:    <public type="string" name="alert_rooted_device" id="0x7f0800d1" />
    smali/com/studios/ocasta/prototype/vmwfsclient/ui/activities/StartActivity.smali:    const v0, 0x7f0800d1

    Aha! It looks like StartActivity.smali might be worth a closer look.

  5. So let’s take a look at the decompiled StartActivity.smali:
    StartActivity.smali
    Seems like it’s invoking com/studios/ocasta/prototype/vmwfsclient/g/i;->a() (line 283), putting the result into v0 (line 285) and then jumping to :cond_0 if v0 is equal to 0 (line 287). If v0 isn’t zero then it raises a Toast notification with the id of the “alert_rooted_device” string (0x7f0800d) (lines 289-297) and calls the “finish()” method (line 299).
    I think it’s a reasonable guess that lines 283-299 are responsible to detecting whether the device is rooted, displaying a toast notification to that effect and exiting.
    So what, if we were so inclined, could we do about it?
  6. Looks likely that if the device isn’t rooted then line 287:
    if-eqz v0, :cond_0

    will skip over the toast + exit stuff. So what if line 287 read simply:

    goto :cond_0

    instead? Skipping over the toast and exit regardless of the result of the method invoked at line 283.
    Let’s give it a go!

  7. Make whatever modifications you decide to and use apktool to rebuild the apk
    apktool b base -o com.virginmedia.simplewifi-rooted.apk
    I: Using Apktool 2.2.2
    I: Checking whether sources has changed...
    I: Smaling smali folder into classes.dex...
    I: Checking whether resources has changed...
    I: Building apk file...
    I: Copying unknown files/dir...

    This should produce an apk which you’ll need to zipalign and sign before you try installing it on a rooted Android device for educational purposes only.

So what did we learn here?

  1. It is often trivial to work around root detection on Android apps.
  2. The root detection in this case isn’t even necessary since the app will set-up WiFi auto sign-on for you, so you could:
    Remove root (temporary)
    Install the app & set-up auto sign-on
    Reinstate root and just don’t launch the app
A USB cable lies unplugged next to a laptop

Virtually unplug USB devices under Linux

My laptop has a built-in webcam which I don’t normally want enabled. The immediately obvious solution to this would be to blacklist the usb webcam kernel module (uvcvideo). However, I sometimes want to plug in an external USB webcam and use that. So how do you unplug/disable a built-in USB device under Linux?

After a bit of poking about it turns out to be possible to do via sysfs, but it’s a bit fiddly. So I wrote a script that I can run from rc.local to disable (or enable) a device with a specific vendor and product id.

Example usage:

$ lsusb
[...]
Bus 003 Device 005: ID 04ca:7034 Lite-On Technology Corp. 
[...]
usbEnableDisable.sh 04ca 7034 disable

Reject DOS line-endings at Git pre-commit

All *nix devs seethe with rage when DOS line-endings (CRLF) end up in your beautiful source code, right? If you use Git for your version control you’re in luck, use this local pre-commit hook to kick those CRLFs to the kerb before they can even make it into your local commit.

Install by copying the pre-commit file to the .git/hooks directory of your checkout. Ask your Windows using colleagues nicely to do the same.

I quit Facebook for a month, you’ll never guess what happened next …

One day in January 2016 I checked my Facebook “news” feed to discover that it contained no actual news from any of my friends. There were no status updates, no news or pictures of friends and their lives. What it was crammed full of was shares, likes and re-posts (usually clickbait or viral marketing stuff) none of which I cared about. I decided I’d had enough, I would go on a one month Facebook detox.

I posted a status telling everyone that I was going to leave Facebook for a bit, uninstalled the app from my phone and deactivated my account on the site. I went Facebook “cold turkey” for a month and here’s what happened. Continue reading

Fixing Telegram’s notification icon in Mate

I like Telegram a lot for cross platform instant messaging. It’s basically a WhatsApp clone but superior (for my purposes) because it has native (Windows, Mac & Linux) clients as well as mobile apps.

A while back I noticed that a Telegram update had caused the notification/indicator icon to go missing on my Ubuntu MATE desktop:

Telegram notification icon missing

Telegram notification icon missing

I eventually tracked the problem down to an environment variable: XDG_CURRENT_DESKTOP which Telegram uses to determine which desktop environment you’re running. In Mate it’s set to “MATE”, setting it to “GNOME” (which is what MATE actually is) works around the problem and the icon comes back:

Telegram notification icon present

Telegram notification icon present

I now use the following script to launch Telegram when I logon:
#!/bin/bash
export XDG_CURRENT_DESKTOP=GNOME
${HOME}/bin/telegram/Telegram "$@"