A simple UI for ‘vpnc’

I’ve been using the Nortel branch of vpnc for a while with great success, but it’s a command-line tool, and a drag to use now that Ubuntu 9.04 is so swish.

So here’s a 30-minute Python/Tkinter UI hack which wraps the vpnc and vpnc-disconnect tools.

Notes:

  1. you’ll need to edit the CONNECT and DISCONNECT command paths at the top of the file
  2. this assumes that you, like me, use a private PIN and a SecurID password
  3. it also assumes that your /etc/vpnc/default.conf file is configured with everything except your password
  4. it’s probably best run with gksudo
  5. I’m no Python guru, so don’t take this code as being ‘best practice’ ;-)
#!/usr/bin/env python
# (c) 2009 m@tthew.org
# http://insignificant.org/2009/05/20/a-simple-ui-for-vpnc/
 
# Feel free to use and abuse this code, but please remember:
# - it comes with no warranty
# - if you make enhancements, please share them with me :)
 
from Tkinter import *
import threading
import subprocess
 
# Edit these paths!
CONNECT="/path/to/vpnc"
DISCONNECT="/path/to/vpnc-disconnect"
 
STATE_DISCONNECTED=0;
STATE_CONNECTED=1;
STATE_DISCONNECTING=2;
 
class ConnectThread(threading.Thread):
 def __init__(self, app):
 threading.Thread.__init__(self)
 self.app=app
 
 def run(self):
 app.setState(STATE_CONNECTED)
 proc = subprocess.Popen([CONNECT, "--no-detach"], stdin=subprocess.PIPE)
 proc.communicate(app.entryPIN.get() + app.entryPassword.get());
 proc.wait()
 app.setState(STATE_DISCONNECTED)
 app.entryPassword.delete(0, END)
 app.entryPassword.focus_set()
 
class DisconnectThread(threading.Thread):
 def __init__(self, app):
 threading.Thread.__init__(self)
 self.app=app
 
 def run(self):
 app.setState(STATE_DISCONNECTING)
 subprocess.call([DISCONNECT])
 
class VPNCApplication(Frame):
 def setState(self, state):
 self.state = state
 
 self.btnConnect['state']=NORMAL if self.state==STATE_DISCONNECTED else DISABLED
 self.btnDisconnect['state']=NORMAL if self.state==STATE_CONNECTED else DISABLED
 self.entryPIN['state']=NORMAL if self.state==STATE_DISCONNECTED else DISABLED
 self.entryPassword['state']=NORMAL if self.state==STATE_DISCONNECTED else DISABLED
 
 def connect(self):
 ConnectThread(self).start()
 
 def disconnect(self):
 DisconnectThread(self).start()
 
 def createWidgets(self):
 self.lblPIN = Label(self, text="PIN: ")
 self.lblPassword = Label(self, text="Password: ")
 self.entryPIN = Entry(self, show="*", width="4")
 self.entryPassword = Entry(self, width="6")
 self.btnConnect = Button(self,text="Connect",command=self.connect)
 self.btnDisconnect = Button(self,text="Disconnect",command=self.disconnect)
 
 self.lblPIN.grid(row=0, column=0, sticky=W)
 self.lblPassword.grid(row=1, column=0, sticky=W)
 self.entryPIN.grid(row=0, column=1, sticky=W)
 self.entryPassword.grid(row=1, column=1, sticky=W)
 self.btnConnect.grid(row=2, column=0)
 self.btnDisconnect.grid(row=2, column=1)
 
 self.setState(STATE_DISCONNECTED)
 self.entryPIN.focus_set()
 
 def __init__(self, master=None):
 Frame.__init__(self, master)
 master.title("VPNC")
 self.pack()
 self.createWidgets()
 
root = Tk()
app = VPNCApplication(master=root)
app.mainloop()
root.destroy

Tags: , ,
Filed under tech : Comments (0) : May 20th, 2009

Leave a Reply