New open source project on work time – git-history-data

Announcing a little open source project that I have built at work and been allowed to publish Freely.

git-history-data analyses a Git source code repository and dumps out data in a form that is easy to analyse.

I wrote an article demonstrating how to use it to find out some interesting information about the codebase of Git itself and got it published on IBM DeveloperWorks Open: Learning about the Git codebase using git-history-data.

Java HTTPS to a server with a self-signed certificate

Nothing is easy in Java, and nothing is more disproportionately non-easy than downloading something. If you add SSL to the equation, it becomes unfeasible for any human to navigate the twisted passages of the Java API, so here is a tiny fragment of map I have pieced together using the Internets.

Updated to link to my article about how to create a self-signed cert and trust store file.

If you have a server that you want to download something from, and you need to use SSL (i.e. your URL starts with “https://”), and it has a self-signed certificate, you will need to get hold of a “trust store” file (a .pkcs12 or .jks file) that tells Java it can trust your server. If you need to set this up yourself, try my article how to create a self-signed cert and trust store file.

Note that this will only work if the self-signed certificate has the correct Subject Alternative Name (the hostname of the server) embedded in it. The article linked above tells you how to achieve this.

Assuming you have somehow magicked up a trust store file (let’s call it trust.pkcs12), and you know the password for it (let’s assume it’s 000000, as we set up in the linked article), we can continue.

Let’s write a little program Get.java that fetches a URL and tells us whether we got an error with the SSL connection:

import java.net.URL;
public class Get
{
   public static void main( String[] args ) throws Exception
   {
       try
       {
           new URL( args[0] ).openConnection().getInputStream();
           System.out.println( "Succeeded." );
       }
       catch( javax.net.ssl.SSLHandshakeException e )
       {
           System.out.println( "SSL exception." );
       }
   }
}

Compile this with:

javac Get.java

And run it with:

$ java Get https://google.com
Succeeded.

This should succeed, because Java knows it can trust the benevolent Google deity, as we all do.

Now try it against your server with a self-signed (or otherwise untrusted) certificate and you should see an error:

$ java Get https://selfsigned.example.com
SSL exception.

And now for the answer you were waiting for. You don’t need to use keytool. Repeat: you don’t need to use keytool. To run Java telling it to trust your server, just do this:

$ java \
    -Djavax.net.ssl.trustStore=/path/to/trust.pkcs12 \
    -Djavax.net.ssl.trustStorePassword=000000 \
    Get https://selfsigned.example.com
Succeeded.

That’s it.

If it doesn’t work, try:

$ java \
    -Djavax.net.debug=SSL,trustmanager \
    -Djavax.net.ssl.trustStore=/path/to/trust.pkcs12 \
    -Djavax.net.ssl.trustStorePassword=000000 \
    Get https://selfsigned.example.com

and you should see some debugging output that may help.

Another useful debugging command is:

openssl s_client -showcerts -connect selfsigned.example.com

Hope it helps.

Vim as editor for Claws Mail

I got sick of not having Vim as my text editor for emails in Claws Mail but GVim makes my eyes bleed so I wanted proper Vim-in-a-terminal as my editor, which was not particularly straightforward.

The proper incantation was to make a script in my PATH called terminal-vim like this:

#!/bin/bash

mate-terminal --disable-factory -x vim -f "$@"

(gnome-terminal should work similarly if you’re in GNOME.)

and to set it as my external editor in Claws Mail by going to Configuration, Preferences, External Programs, and setting Text Editor to terminal-vim '%s'.

Then under Writing in Preferences, I ticked the box “Automatically launch the external editor” and all is well.

Avoiding postfix error “status=deferred (unable to look up host”

My emails wouldn’t send when I was working from home, giving me this message in /var/log/mail.log:

Nov 11 12:38:16 machinename postfix/smtp[20672]: CF5D6D41CE2: to=, relay=none, delay=14416, delays=14416/0.01/0.07/0, dsn=4.3.5, status=deferred (Host or domain name not found. Name service error for name=relay.example.com type=AAAA: Host not found)

It turned out I was telling postfix not to use DNS to resolve the domain name of my mail relay server. There were several postfix config options I needed to remove to make this work:

# Make sure all of these are commented out or removed!
#default_transport = smtp
#relay_transport = smtp
#inet_protocols = ipv4
#smtp_host_lookup = native

The default values for these options are fine, but the ones shown above stop it working, so remove them or comment out with a # at the beginning of the line.

More at Postfix configuration parameters.