Auto login to open Wifi

If you go to many places with open wireless access you might find it annoying that every time you have to open the browser to accept the same rules and conditions from that provider before you can have real internet access. It is even worse if you have tabs left open from your last session and they all now point to the same wifi login page!

However, if you are using Linux and you have NetworkManager set as the default network management tool then I have a solution for you, NetworkManager will run the scripts inside the folder “dispatcher.d” whenever the connection status changed for any of the network cards on the machine. Under Fedora the folder is located in “/etc/NetworkManager/dispatcher.d/” and I will assume other Linux distributions will be similar if not the same.

So all you have to do is create a script in that folder that will run whenever the wireless connection is up and the network name (SSID) matches the location that have the open wifi, then the script should automate the process of clicking on the accept button or whatever it takes to get internet access.

I have already made such a script that will allow me to login to Panera Bread and Baltimore County Public Library, but it can be expanded easily to include other locations. The first part of the script should be placed under the “dispatcher.d” folder and should be accessible by “root” only (This is a security feature, since NetworkManager will execute all scripts in that folder as root and anyone with access to these files can change their content to do other stuff that might harm your system, so make sure to set the permission to root only). That script will parse the iwconfig output to find the name of the wifi and call the script that matches the name if any.

Here is my main script (07-autologin_openwifi)

#!/bin/bash
#------------------------------
# By Fahad Alduraibi
# Last update: June 12, 2012
# Version: 1.1
#------------------------------

export LC_ALL=C
LogFile="/var/log/07-WIFI_ACCESS.log"

# The parameters that get passed to the script are:
# $1 = The interface name ( eth0, wlan0 ...etc)
# $2 = Interface status ( "up" or "down" )

# Check if wireless status is up
# I have two wifi cards in my laptop, named "wlan0 and wlan1"
# so I use regular expression "wlan[01]" to match both of them.
if [[ "$1" =~ wlan[01] && $2 == "up" ]]; then

# Get the network name from "iwconfig" or (can also locate the network based on IP or MAC address if needed)
ESSID=$(/sbin/iwconfig $1 | grep ESSID | cut -d'"' -f2)

# Record the date and time for debugging purposes only
echo "[`date`] ESSID=($ESSID)" >> $LogFile

# If the wireless name matches then run its python script
if [[ "$ESSID" == "BCPL-PUBLIC-WIFI" ]]; then
/usr/bin/python /myscripts/baltimore-county_library_wifi.py 1>> $LogFile 2>&1
elif [[ "$ESSID" == "PANERA" ]]; then
/usr/bin/python /myscripts/panera.py 1>> $LogFile 2>&1
elif [[ "$ESSID" == "Nordstrom_Wi-Fi" ]]; then
/usr/bin/python /myscripts/nordstrom.py 1>> $LogFile 2>&1
#elif .... (you can add more open wifi here)

fi
fi

#if [[ "$1" =~ wlan[01] && $2 == "down" ]]; then
##If you want to do somehting when the network is down
#fi

As you can see that the above script will call another python script when a name matches which are located in another folder (change it to whatever suits you and don’t forget to set the root only permissions)
And here is the script for “baltimore-county_library_wifi.py

#------------------------------
# By Fahad Alduraibi
# Last update: June 12, 2012
# Version: 1.0
#------------------------------
import httplib
conn = httplib.HTTPConnection("1.1.1.1")
conn.request("GET", "/fs/customwebauth/login.html?switch_url=http://1.1.1.1/login.html&wlan=BCPL-PUBLIC-WIFI")
r1 = conn.getresponse()
print r1.status, r1.reason
output1 = r1.read()

headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
params = "buttonClicked=4&err_flag=0&err_msg=&info_flag=0&info_msg=&redirect_url=&username=guest&password=guest"
conn.request("POST", "/login.html", params, headers)
r2 = conn.getresponse()
print r2.status, r2.reason
output2 = r2.read()

conn.close()

In this script I used the “httplib” python library which is kind of a low level library since you have to setup all HTTP stuff manually also if one of the URL or its parameters changed in the future the script will not work and will need to be updated.
However, in the second script “panera.py” I use the “mechanize” library which act as a web browser and takes care of the low level HTTP details (mechanize might not be among the standard library and you might have to install it)
panera.py

#------------------------------
# By Fahad Alduraibi
# Last update: June 12, 2012
# Version: 1.1
#------------------------------
import mechanize
import sys

br = mechanize.Browser()
br.set_handle_equiv(True)
#br.set_handle_gzip(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0')]

testURL = 'http://www.fadvisor.net/blog/'
response = br.open(testURL)

if response.geturl() == testURL:
print "FAD: You are already logged in to Panera."
sys.exit()

try:
forms = mechanize.ParseResponse(response, backwards_compat=False)
except:
print "FAD: Error in parsing forms, Am I already logged in to Panera?"
sys.exit()

response.close

form = forms[0]
#print form
#print "----------------------------------- Login"
request = form.click()
response = mechanize.urlopen(request)
forms = mechanize.ParseResponse(response, backwards_compat=False)
response.close()

form = forms[0]
#print form
#print "----------------------------------- Validate"
#print
request = form.click()
response = mechanize.urlopen(request)
forms = mechanize.ParseResponse(response, backwards_compat=False)
response.close()

form = forms[0]
#print form
#print "----------------------------------- ConfirmLogin New"
#print
request = form.click()
response = mechanize.urlopen(request)
forms = mechanize.ParseResponse(response, backwards_compat=False)
response.close()

form = forms[0]
#print form
#print "----------------------------------- ConfirmLogin Validate"
#print
request = form.click()
response = mechanize.urlopen(request)
forms = mechanize.ParseResponse(response, backwards_compat=False)
response.close()

form = forms[0]
#print form
#print "----------------------------------- CompleteLogin New"
#print

request = form.click()
response = mechanize.urlopen(request)
forms = mechanize.ParseResponse(response, backwards_compat=False)
response.close()

form = forms[0]
#print form
#print "----------------------------------- HttpLoginRequest"
#print

request = form.click()
response = br.open(request)
#print response.read()

response.close()
print "--- Panera Done ---"

Panera uses a more complicated process, but mechanize made it much easier to develop the script, and I didn’t hardcode any link or parameters which means the script will work even if they change the URLs, but will still fail if they change the login process.

nordstrom.py

#------------------------------
# By Fahad Alduraibi
# Last update: June 12, 2012
# Version: 1.0
#------------------------------

import mechanize
import sys

br = mechanize.Browser()
br.set_handle_equiv(True)
#br.set_handle_gzip(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0')]

testURL = 'http://www.fadvisor.net/blog/'
response = br.open(testURL)

if response.geturl() == testURL:
print "FAD: You are already logged in to Nordstrom."
sys.exit()

try:
forms = mechanize.ParseResponse(response, backwards_compat=False)
except:
print "FAD: Error in parsing forms, Am I already logged in?"
sys.exit()

response.close

form = forms[0]
#print form
#print "----------------------------------- Login"
request = form.click()
response = mechanize.urlopen(request)
forms = mechanize.ParseResponse(response, backwards_compat=False)
response.close()
print "--- Nordstrom Done ---"

You can add other providers as well like starbucks and many other coffee shops, all you need is some network capturing tool like tcpdump or wireshark and some scripting skills.
A similar thing can be done under Microsoft Windows Vista and above, since you can create a task under “Task Scheduler” that will trigger based on network event.

Disclaimer: you still have to read and agree to the terms and conditions before you start using such script, and you will be responsible for not complying with them.

3 thoughts on “Auto login to open Wifi”

  1. Fahad, this is wonderful, thank you! Do you have newer scripts? I will start working from here. Dunkin Donuts and Home Depot are in my sights for drive by very low bandwidth internet email updates. Actually, on the drive to Boston, I am next to an MBTA train with wifi, and a Peter Pan bus, with wifi. A no hands connection (free) would be unbelievable! Thanks, Bradshaw at Buzzards Bay (MA, on the cape cod canal)

    1. Hi Bradshaw, I created these scripts when I was using these places a lot to study and haven’t touched them since. I know Panera script doesn’t work since I tried it few days ago and noticed they have changed few things. The biggest problem is not having a standard for such systems, and almost every place have a different implementation, even the ones that uses the same technology do have very similar steps but usually not exact, so they will need a tailor script still. If you plan to make your own scripts I would suggest using mechanize library to handle http connections, since it takes care of following up with the same session and cookies while going between pages, the same way I am doing in the Panera and Nordstrom scripts, while with the Baltimore library i was doing every thing manually since I haven’t discovered mechanize yet.

      1. Let me try a few scripts for the local area and share them. I am coming up to speed on android. It got a lot easier when I put the android phone under a book and stopped looking at it. I respond to the smart phone much better via black screens and x windows. Looking at it messes me up.

        I am also working at the linux, hardware and device driver level, and not down a billion layers, trusting everyone between me and the radio waves. Solar and or wind power is coming! Need to control the grid! thanks again.

Comments are closed.