#!/usr/bin/env python
"""
Connect to a Cisco VPN under Linux, without requiring user interaction.  

I wrote this script because I was tired of having to restart the driver and
enter my password every time I wanted to connect to the VPN.  Eventually this
should become a GUI application with a Connect and a Disconnect button.

You need to create a configuration file in ~/.cisco_params, with the following
contents::

    group_name = 'mycompany'
    group_passwd = 'company_password'
    user_name = 'myuser'
    user_passwd = 'user_password'

Note: in case you didn't get it, this defeats the entire purpose of using a
password, trading off security for convenience.  If you don't know what this
entails, don't use this script.
"""

import os, pexpect
from os.path import *

config_fn = join(os.environ['HOME'], '.cisco_params')


def read_config():
    "Read in the username and password from the configuration file."
    execfile(config_fn, globals())
    for name in 'group_name', 'group_passwd', 'user_name', 'user_passwd':
        assert name in globals()


def connect(log):
    """Establish the connection, entirely automatically, without user
    intervention."""

    log('Restarting service') # This is sometimes required
    c = pexpect.spawn('/etc/init.d/vpnclient restart')
    c.expect('.*Starting Cisco VPN Client')
    c.expect(pexpect.EOF)
    c.close()

    log('Logging in')
    c = pexpect.spawn('/usr/bin/vpnclient connect "%s"' % group_name)
    log('(group passwd)')
    c.expect('Enter a group password:')
    c.sendline(group_passwd)
    log('(user)')
    c.expect('Username.*:')
    c.sendline(user_name)
    log('(passwd)')
    c.expect('Password.*:')
    c.sendline(user_passwd)
    #log('(accepting aggreement; please be patient...)')
    # c.expect('Do you wish to continue')
    # c.sendline('y')
    c.expect('Your VPN connection is secure.')
    return c

def disconnect(c, log):
    """Close the connection and make really sure that the VPN connection is
    terminated."""

    log('Closing down connection.')
    c = pexpect.spawn('/usr/bin/vpnclient disconnect')
    c.expect(pexpect.EOF)
    c = pexpect.spawn('/etc/init.d/vpnclient stop')
    c.expect(pexpect.EOF)
    log('Done (disconnected).')


def main_console():
    "Main program when run as a console utility."

    def log(x):
        print x
        
    c = connect(log)
    log('\n\n   CONNECTED! Interrupt this to disable the VPN.\n\n')
    try:
        c.expect(pexpect.EOF, timeout=None)
    except KeyboardInterrupt:
        c.close()
    disconnect(c, log)

def main_gui():
    "Main program when run with a GUI."

    ## FIXME: running as sudo, I cannot access the display...
##     import sys, os
##     import re, string
##     from PyQt4 import Qt
## 
##     a = Qt.QApplication(sys.argv[0:1])
##     font = Qt.QFont( "Helvetica", 32, Qt.QFont.Bold );
##     a.setFont(font);
##     
##     class BigButton(Qt.QPushButton):
##         def __init__(self, name, cmd, parent):
##             Qt.QPushButton.__init__(self, name, parent)
##             self.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding,
##                                               Qt.QSizePolicy.Expanding))
## 
##             self.name = name
##             self.cmd = cmd
##     
##             self.connect(self, Qt.SIGNAL("clicked()"), self.click)
## 
##         def click(self):
##             print 'do something'
## 
##     parent = Qt.QWidget()
##     layout = Qt.QVBoxLayout(parent)
##     for i in commands:
##         (name, cmd) = i
##         print name
##         button = BigButton(name, cmd, parent)
##         layout.addWidget(button)
## 
##     ##a.setMainWidget(parent)
##     parent.show()
##     
##     # allow the app to be interrupted once we enter the event loop
##     import signal; signal.signal(signal.SIGINT, signal.SIG_DFL)
## 
##     a.exec_()


if __name__ == '__main__':
    read_config()
    main_console()


