Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@bryanstearns
Created March 7, 2009 22:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryanstearns/75475 to your computer and use it in GitHub Desktop.
Save bryanstearns/75475 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
#
# startvpn: Automatically connect to a VPN when associating with a
# wireless network
#
# Once you've successfully set up an OpenVPN connection in NetworkManager,
# configure the settings below, then install this script as
# /etc/NetworkManager/dispatcher.d/02startvpn (it seems to be happiest
# when chowned root:root)
#
#--
# Copyright (c) 2008-2009 Bryan Stearns
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#--
#
# Configuration:
#
# The name of your VPN, as you've set it in Network Manager
VPN_NAME = "HomeVPN"
# Networks where no VPN is needed (eg, home)
PRIVATE_ESSIDS = ["linksys"]
# Automatically accept the Personal Telco Project EULA page
# for networks with these names:
PTP_ESSIDS = ["www.personaltelco.net"]
# (If I encounter other oft-hit pages like this, I'll generalize
# this mechanism...)
# --- that's all ---
import sys, os, re, syslog, dbus, httplib, urllib, urlparse, commands
from dbus.mainloop.glib import DBusGMainLoop
NM_SERVICE="org.freedesktop.NetworkManager"
NM_PATH="/org/freedesktop/NetworkManager"
NM_VPN_SERVICE ="org.freedesktop.NetworkManager.VPNConnections"
NM_VPN_PATH ="/org/freedesktop/NetworkManager/VPNConnections"
pid = os.getpid()
def log(msg):
msg = "%s: %s" % (pid, repr(msg))
print msg
syslog.syslog(syslog.LOG_INFO, msg)
def doit():
if len(sys.argv) == 3:
interface, status = sys.argv[1:3]
else:
log("Usage: /etc/NetworkManager/dispatcher.d/02startvpn <interface> <status>")
sys.exit(0)
if status != "up":
# log("New status for '%s' is '%s'; ignoring" % (interface, status))
sys.exit(0)
iwconfig = commands.getoutput("iwconfig %s" % interface)
essid = re.search(r"""ESSID:"(.*?)" """, iwconfig).group(1)
log("New wireless network association: '%s'" % essid)
if essid in PRIVATE_ESSIDS:
log("Not starting VPN: we're home")
sys.exit(0)
if essid in PTP_ESSIDS:
log("Checking for PTP EULAwall")
filename, headers = urllib.urlretrieve("http://example.com/index.html")
f = open(filename)
data = f.read()
f.close()
# log("Got from GET: '%s'" % data)
if data.find("<TITLE>Example Web Page</TITLE>") != -1:
log("PTP EULAwall already breached")
else:
log("Looking for the PTP EULA form")
action_match = re.search("form .* action=\"http://(.*)/\"", data)
if action_match is None:
log("Hmm, doesn't look like the PTP form")
sys.exit(0)
action = action_match.groups(1)[0]
params = urllib.urlencode({'redirect': 'http://example.com',
'mode_login': 'I Agree'})
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
conn = httplib.HTTPConnection(action)
conn.request("POST", "/", params, headers)
response = conn.getresponse()
data = response.read()
conn.close()
log("Got %s / %s from POST" % (response.status, response.reason))
if response.status not in (200, 302):
log("Giving up")
sys.exit(0)
log("Starting '%s' VPN" % VPN_NAME)
DBusGMainLoop(set_as_default=True)
b = dbus.SystemBus()
nm = b.get_object(NM_SERVICE, NM_VPN_PATH, True)
interface = dbus.Interface(nm, NM_VPN_SERVICE)
result = interface.getVPNConnections()
# log(result)
# log(interface.getVPNConnectionProperties(VPN_NAME))
def ignore_callback(*args): pass
result = interface.activateVPNConnection(VPN_NAME, dbus.Array([], 's'),
reply_handler=ignore_callback, error_handler=ignore_callback)
# log(result)
try:
doit()
except Exception, e:
log("Exception: %s" % e)
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment