Tuesday, October 7, 2008

Automated Login on Time-based Public Wireless Access Point

Public wireless access point sometimes employ a time-based logout-login/connect-disconnect cycles to "attract" users into their paid service counterpart in which the time-based logout-login/connect-disconnect cycles removed. Of course that kind of connect-disconnect cycles are annoying. However, with a little bit of bash script. The login-logout chores can be automated. I'll present an example script. You will need a machine that runs *nix and has curl installed. Mind you that in this scheme, it is assumed that the access-point recognize your WLAN card based on it's MAC address. The MAC address will be used as your user name used for login purposes. This is it.


#!/bin/bash
#
# Script to login and renew connection to FreeHotspot@somewhere
#
# Note: This script connects the INTERFACE to the access point and
# renew the connection automatically.
# Press CTRL+C to stop the script
#

INTERFACE=wlan2
ESSID="FreeHotSpot@somewhere"
SESSION_LENGTH=20m
WLAN_KEY=off
LOGOUT_URL="http://192.168.10.254/logout"
LOGIN_URL="http://192.168.10.254/login?username=T-00%3AAA%3CCC%3FFF%3EEE"

if [ $UID -ne 0 ]; then
echo "This script needs root privilege to run!"
exit 1;
fi

while [ 1 ];
do
# It seems that killing dhcpcd is the most reliable way to do now.
# Otherwise reconnecting is always problematic.
# Just removing dhcpcd PID file is not enough.
#
echo "Killing dhcpcd.."
killall dhcpcd
rm -vf /etc/dhcpc/dhcpcd-${INTERFACE}.pid

echo "Bringing the interface down.."
ifconfig ${INTERFACE} down

echo "Configuring ${INTERFACE}.."
iwconfig ${INTERFACE} essid ${ESSID}
iwconfig ${INTERFACE} key ${WLAN_KEY}

echo "Bringing the interface up.."
ifconfig ${INTERFACE} up

echo "Activating dhcpcd on ${INTERFACE}.."
dhcpcd ${INTERFACE}

if [ -e /etc/dhcpc/dhcpcd-${INTERFACE}.pid ]; then
#
# Always logout first to ensure that there is no "stall"
# session which will reject your subsequent DNS requests
#
echo "IP address obtained. Logging out with curl.."
curl ${LOGOUT_URL} > /dev/null
echo "Logging in with curl.."
curl ${LOGIN_URL} > /dev/null
sleep ${SESSION_LENGTH};
else
echo "Unable to obtain dhcp address. Please run the script again. Exiting.. "
exit 1
fi
done


The script above must be executed by someone with root privilege. The script above also assumes that to logout from the current session, you have to visit some special URL. The LOGOUT_URL variable contains this URL. You have to modify it to suit your need. You can obtain this URL from your browser by examining the HTML code of the page that shows the logout button. This page usually displayed right after you do a "manual" login in your browser, for example when you are using Firefox or Opera to login and use the access point to connect to the net. Moreover, the script also assumes that you have to visit some special URL to login into a new session. The LOGIN_URL variable contains this URL. You have to modify it to suit your need as well. The IP address in the LOGIN_URL and LOGOUT_URL seems to be owned by the access point. I'm not really sure about it, but in most cases it is. One thing that I want to note that you have to modify the SESSION_LENGTH to suit the logout interval to suit the public access point that you use. Its value must be less than the session expiration time in the public access point that you use. For example, if the session expires in 30 minutes in your particular public access point, then use 29m (or less) as the value of the SESSION_LENGTH variable. Note that 29m corresponds to 29 minutes, because this value is passed to the sleep bash built-in function.

There you have it, automated login script for "smooth" surfing on public access point. As a bonus, let's see how to do automated download as well. In this case, we assume that the download process will resume after some interval. Nonetheless the script is not bug free. You have to stop it downloading things when you think it's finished because it will keep trying downloading even if the download already completed. To stop the script, simply press CTRL+C. Here it is:


#!/bin/bash

# get the file
#
#

INTERVAL=15m
SRC="http://download.mystuff.com/source_code.zip"
DEST="source_code.zip"

# Install a trap (interrupt handler) to handle Ctrl+C
trap 'killall wget; exit 0' 2

while [ 1 ]; do
# run wget in the background
(wget -c ${SRC} -O ${DEST} &> /dev/null) &

# wait for few minutes
sleep ${INTERVAL}

# restart the download
# this is a rather brute force approach to stop current download
# TODO: fix it!

killall wget

done

exit 0


Remember to stop the script by using CTRL+C. It's advised to run wget and then terminate wget previous to running this script in order to know the size of the file that you are going to download. With that information you will know when you should stop the script.

That's it for the moment. Ciao