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
Leave a Reply

avatar
1 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
bradshawFahad Alduraibibradshaw lupton Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest
Notify of
bradshaw lupton
Guest
bradshaw lupton

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)