NetworkManager: Auto-HTTP login to a Wifi network

One of the cafés in my area where I frequently drink / work requires you to pass through an annoying web page forcing you to agree to some terms before allowing you to access the Internet through their Wifi network. It’s free – but they still annoy you with this silly HTTP gateway. This is actually a frequent thing in Israel – most cafés offer free Wifi access, but some will require to to log-in nevertheless.

So today I figured out how to get NetworkManager to automatically work around this HTTP gateway for me whenever I connect to Arcaffe’s Wifi network. Since it’s super cool, and since I bet lots of people are annoyed by these sort of Wifi gateways, here’s how to do it:

Apparently, NetworkManager allows you to create special post-connect or post-disconnect scripts that are executed when a network interface is brought up or down. Here is what I did:

I Created the following script and saved it at /etc/NetworkManager/dispatcher.d/100httpgateway.sh:

#!/bin/sh

IFACE="eth1"

if [ "x$1" = "x$IFACE" ] && [ "$2" = "up" ]; then
    # Figure out the wifi SSID
    SSID=$(/sbin/iwconfig $IFACE  | grep ESSID | cut -d: -f2 | sed 's/^s*"(.*)"s*$/1/')

    case "$SSID" in
        "012-ArCaffe")
           URL='http://captive.012.net.il/user/refresh/home?confirmed=true&submitButton=+OK+&CPURL=http%3A%2F%2Fwww.arcaffe.co.il%2F&t=fsm3j5oe'
           DATA='x=9&y=5&agree=on&username=arcaffe&password=arcaffe012'
           COOKIE='Cookie: JSESSIONID=uc54121j305s; cookies=true'
           REFERER='Referer: http://captive.012.net.il/home?confirmed=true&submitButton=+OK+&CPURL=http%3A%2F%2Fwww.arcaffe.co.il%2F&t=fsm3j5oe'

           curl -d "$DATA" -H "$COOKIE" -H "$REFERER" "$URL" > /tmp/arcaffe.last 2> /tmp/arcaffe.last.err
        ;;
    esac
fi

Don’t forget to make the file executable – I did it by running chmox +x /etc/NetworkManager/dispatcher.d/100httpgateway.sh.

Some things you should note:

  • “012-ArCaffe” is the ESSID of the network I’m logging in to. This of course work for ArCaffe in Israel, but you should change that with your network’s ESSID.
  • Replace the value of IFACE with the name of your wireless interface
  • $1, the first parametter passed by NetworkManager to the script, is the network interface that was just connected or disconnected
  • $2, the second parameter, is “up” or “down” – the status of the interface.
  • The code I have inside the case block is where the magic happens. In this case, I send an HTTP POST with the correct parameters, Cookie and Referer headers and URL. This causes ArCaffe’s gateway to log me in
  • I use curl – but I could have also used wget or any other tool to do the job
  • The -d flag sends the POST data, the -H flags set a header
  • I figured exactly what request to send using LiveHttpHeaders – but you can also use tcpflow or any other packet sniffing or HTTP sniffing tool
  • You can add more options to the ‘case’ statement for more networks that need that sort of treatment. With a little of bash-fu that should be no problem.

That’s it! Man I love Linux today :D