Mercurial Contribution Charts

One of the things I’d really like to see is Bitbucket to have Github style contribution graphs and after waiting a while to see if that feature request #4307 was ever going to get a green light I decided to see how hard it would be to build it myself.

Yes I am sure there are 100 people who have already done this… but I didn’t find any that I particularly liked, I wanted the distraction this weekend and it was surprisingly easy to do.

After building a simple hg log parser in python I was to convert the data to json and wrap it with highcharts to produce a couple of really nice looking interactive contribution graphs.



You can grab the code and take a look yourself: mercurial-charts bitbucket

If you want to contribute, have some ideas or feedback hit me up on Google+

Enabling SSL and Best Practice Ciphers

Get a free SSL certificate from StartSSL which is surprisingly easy, even if their website is a little awkward to navigate.

After creating a private key, obtaining the certificate and intermediate certificate ( you can setup your apache/nginx server.

Use the modern compatibility ciphers listed on the Mozilla wiki and the sections for both apache and nginx for details on how to configure your individual server or use their handy online tool ssl config generator

Tip for nginx you will want to create a chained certificate, and use that your ssl_certificate file.

$ cat yourdomain.crt intermediate.pem > yourdomain.crt.chained

Tip for apache enable ssl and headers modules

$ sudo a2enmod ssl headers

Tip for wordpress to force administration pages to use SSL add near the top of the wp-config.php

define('FORCE_SSL_ADMIN', true);

Now you can visit my site via

Sendmail Masquerade Using Generic Map

Changes to configure sendmail to masquerade from address allowing me to replace local system email address user@server.localhost.localdomain with another email address like or

Create the following files:

FEATURE(genericstable, hash /etc/mail/generics)dnl

Run the following commands:

$ makemap hash /etc/mail/generics < /etc/mail/generics
$ m4 /etc/mail/ > /etc/mail/
$ /etc/init.d/sendmail restart

Test using the following command:

echo "Checking if masquerade worked" | mailx -s "Masquerade Email Test"

Disclaimer: I would not rely on this information in a production environment.

HMAC SHA1 – Java, Python and PHP

Generating a consistent HMAC SHA1 across multiple languages and mirror the java byte array (byte[]) mechanism.

Java Code

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Signer {
    public static void main(String[] args) throws Exception {
        String key = "0f2100e34b54d50fd0138f300d3497579dae5279";
        String data = "secret-message";
        byte[] decodedKey = Hex.decodeHex(key.toCharArray());
        SecretKeySpec keySpec = new SecretKeySpec(decodedKey, "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        byte[] dataBytes = data.getBytes("UTF-8");
        byte[] signatureBytes = mac.doFinal(dataBytes);
        String signature = new String(Base64.encodeBase64(signatureBytes), "UTF-8");
        System.out.println("key = " + key);
        System.out.println("data = " + data);
        System.out.println("signature = " + signature);

PHP Equivalent

  $key = "0f2100e34b54d50fd0138f300d3497579dae5279";
  $data = "secret-message";
  $decodedKey = pack("H*", $key);
  $hmac = hash_hmac("sha1", $data, $decodedKey, TRUE);
  $signature = base64_encode($hmac);
  echo "key = $key\n";
  echo "data = $data\n";
  echo "signature = $signature";

Python Equivalent

import hmac
import hashlib
key = "0f2100e34b54d50fd0138f300d3497579dae5279"
data = "secret-message"
decodedKey = key.decode("hex")
hmac =, data.encode('UTF-8'), hashlib.sha1)
signature = hmac.digest().encode('base64')
print "key =", key
print "data =", data
print "signature =", signature

Expected Output

key = 0f2100e34b54d50fd0138f300d3497579dae5279
data = secret-message
signature = MhzlxM4a2htRhimCU/fXNBDBWaU=

Heartbleed nginx check

Few quick commands to check nginx has been patched succesfully for heartbleed.

# check nginx compile config
$ /opt/nginx/sbin/nginx -V
nginx version: nginx/1.4.0
built by gcc 4.7.2 (Debian 4.7.2-5) 
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx --with-http_ssl_module --with-pcre=/opt/nginx/pcre-8.32 --with-zlib=/opt/nginx/zlib-1.2.8

# check which ssl library
$ ldd /opt/nginx/sbin/nginx | grep ssl => /usr/lib/x86_64-linux-gnu/ (0x00007f489cd5a000)

$ strings /usr/lib/x86_64-linux-gnu/ | grep "^OpenSSL "
OpenSSL 1.0.1e 11 Feb 2013

# check full ssl version (including when it was built)
$ openssl version -a
OpenSSL 1.0.1e 11 Feb 2013
built on: Tue Apr  8 08:49:19 UTC 2014
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx) 
OPENSSLDIR: "/usr/lib/ssl"

# check changelog for note regarding CVE-2014-0160 patch
$ aptitude changelog openssl
openssl (1.0.1e-2+deb7u5) wheezy-security; urgency=high

  * Non-maintainer upload by the Security Team.
  * Add CVE-2014-0160.patch patch.
    CVE-2014-0160: Fix TLS/DTLS hearbeat information disclosure.
    A missing bounds check in the handling of the TLS heartbeat extension
    can be used to reveal up to 64k of memory to a connected client or

Download script

Just a little script to download files from my remote server and if need be unrar the files.


function init() {
  # create required directories
  [ ! -d "$LOCAL" ] && mkdir $LOCAL && echo "created $LOCAL"
  [ ! -d "$UNRAR" ] && mkdir $UNRAR && echo "created $UNRAR"

function download() {
  # append wildcard to input
  [ -n "$INPUT" ] && INPUT="${INPUT}*" && echo "Downloading $INPUT"
  [ -z "$INPUT" ] && INPUT="*" && echo "Downloading all files"
  # rsync files from remote server to local folder
  rsync -a --quiet --compress --log-file="$LOG" $REMOTE/$INPUT $LOCAL/ >> $LOG 2>&1 &

function unrar() {
  echo "Extracting *.rar files to $UNRAR"
  # unrar convert filenames to lower case, exclude paths and do not overwrite
  find $LOCAL -name "*.rar" -exec unrar x -cl -ep -o- {} $UNRAR \; >> $LOG 2>&1 &

case "$1" in
    echo "Usage: $0 {download|unrar|both}"

Tethering to Android Phone for Internet via Bluetooth

As mentioned earlier until I purchase a usb dongle I am running without a network. Just for kicks though I decided to setup tethering via bluetooth with my android phone. Which allows me to update packages etc without having to plug the raspberry pi into a network point.

Bluetooth Pairing

To make it a little easier I paired to raspberry pi from my phone.

# to check the raspberry pi bluetooth name
$ sudo hciconfig hci0 name

# to set the bluetooth name
$ sudo hciconfig hci0 name raspberrypi

# make the raspberry pi discoverable
$ sudo hciconfig hci0 piscan

# setup agent to listen for pairing request
$ sudo bluetooth-agent 12345
# from my phone I connected to raspberrpi-0 and confirmed code was displayed
Confirmation request of 7654321 fir device /org/bluez/1936/hci0/dev_0E_C9_35_42_E6_E9

# turn of discoverable
$ sudo hciconfig hci0 noscan

# check connected devices
# list currently connected bluetooth devices
$ sudo bluez-test-device list
BC:B0:0B:47:57:A8 matt’s keyboard
FA:C7:48:46:47:33 Logitech Bluetooth Mouse M555b
0E:C9:35:42:E6:E9 Galaxy Nexus

Setup Tethering

To tether to android phone for internet we need a little more configuration

# package required for 'pand' command
$ sudo apt-get install bluez-compat

# connect to phone and sets up network interface
$ sudo pand --connect 0E:C9:35:42:E6:E9 -n

# show networks
$ ifconfig
bnep0     Link encap:Ethernet  HWaddr 00:4d:9c:2a:47:94  
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:12 (12.0 B)  TX bytes:60 (60.0 B)

# set dhclient to use bnep0 
$ sudo dhclient bnep0

# test internet connectivity
$ ping
PING ( 56(84) bytes of data.
64 bytes from ( icmp_req=1 ttl=52 time=26.3 ms
64 bytes from ( icmp_req=2 ttl=52 time=26.6 ms

Turning off tethering

To turn of tethering and unconfigure the PAN network

# release bnep0 dhclient
$ sudo dhclient -r bnep0

# disconnect pan
$sudo pand -K

Create an alias to make this tethering easy peasy

As I’ll probably turn tethering on and off lots of times I put all this into an alias

$ vi ~/.bash_aliases
alias leash='sudo pand --connect 0E:C9:35:42:E6:E9 -n && sudo dhclient bnep0'
alias unleash='sudo dhclient -r bnep0 && sudo pand -K'

After reloading bash I can simply type the following to tether or untether

$ leash
$ unleash

If you haven’t already got it installed you should also put Power Toggles on your phone so you can quickly turn wifi / bluetooth tethering on and off.

USB Bluetooth dongle and keyboard

As I am running my raspberry pi without a network (until I can grab a usb wifi dongle) I’m using a spare usb bluetooth dongle and bluetooth keyboard I had lying around.

Bluetooth Installation

$ sudo apt-get install bluez python-gobject

# check bluetooth dongle it recognised
$ hcitool dev
	hci0	7B:13:75:FD:11:EB

# scan for discoverable devices
$ hcitool scan
Scanning ...
	BC:B0:0B:47:57:A8	matt’s keyboard
	FA:C7:48:46:47:33	Logitech Bluetooth Mouse M555b

# pair with keyboard
$ sudo bluez-simple-agent hci0 BC:B0:0B:47:57:A8
RequestPinCode (/org/bluez/3465/hci0/dev_BC_B0_0B_47_57_A8)
Enter PIN Code: 12345
# type pin + enter on keyboard
New device (/org/bluez/3465/hci0/dev_BC_B0_0B_47_57_A8)

# pair with mouse
$ sudo bluez-simple-agent hci0 FA:C7:48:46:47:33
RequestPinCode (/org/bluez/2015/hci0/dev_FA_C7_48_46_47_33)
Enter PIN Code: 0000
New device (/org/bluez/2015/hci0/dev_FA_C7_48_46_47_33)

# add devices to trusted list and connect
$ sudo bluez-test-device trusted BC:B0:0B:47:57:A8 yes
$ sudo bluez-test-device trusted FA:C7:48:46:47:33 yes
$ sudo bluez-test-input connect BC:B0:0B:47:57:A8 yes
$ sudo bluez-test-input connect FA:C7:48:46:47:33 yes

# reboot and test if keyboard connects
$ sudo shutdown -r now

# list currently connected bluetooth devices
$ sudo bluez-test-device list
BC:B0:0B:47:57:A8 matt’s keyboard
FA:C7:48:46:47:33 Logitech Bluetooth Mouse M555b

As I’m using an apple wireless keyboard I needed to jump into raspi-config and reconfigure my keyboard settings

$ sudo raspi-config
# 3 - Internationalisation Options
# I3 - Change Keyboard Layout (wait a little for it to load)
# set keyboard to Apple Aluminium Keyboard (ANSI) and default options for rest of prompts

Raspbian Install

Load Raspbian Image onto SD Card

Installation was done using OSX terminal and a 16 GB SD Card (class 10).

  • Download latest Raspbian
  • Insert SD Card and open terminal
$ df -h
Filesystem      Size   Used  Avail Capacity  iused    ifree %iused  Mounted on
/dev/disk2s1    15Gi  2.1Mi   15Gi     1%        0        0  100%   /Volumes/UNTITLED

$ diskutil unmount /dev/disk2s1
$ unzip

$ sudo dd if=2013-09-25-wheezy-raspbian.img of=/dev/rdisk2 bs=1m
# note: dd does not output anything until it finishes just be patient
2825+0 records in
2825+0 records out
2962227200 bytes transferred in 295.230490 secs (10033609 bytes/sec)

$ diskutil eject /dev/disk2s1

Thats it stick the sd card into the raspberry pi and turn it on.

For those who are curious:

Why am I using /dev/rdisk2 and not /dev/disk2? rdisk is a raw path, which is faster.

I tested it to see how much faster (it wasn’t worth the wait):
5 minutes using /dev/rdisk2 vs 25 minutes using /dev/disk2

Initial Config

Now that we have the raspberry pi booted up time to ssh in and configure a few basic things.

$ ssh pi@

# set your local time.
$ sudo dpkg-reconfigure tzdata

# update package list and upgrade to latest
$ sudo apt-get update && sudo apt-get upgrade

# configure raspberry
$ sudo raspi-config
# expand filesystem to fill sd card
# change the default password (raspberry) to something else

# reboot
$ sudo shutdown -r now && exit