LMP
LMP

Reputation: 79

using pexpect and openconnect to bring up a vpn connection

I'm trying to create a script that will bring up a vpn connection. I modeled my script from this question and it works fine for my purposes but I find that as soon as I close the script the vpn connection is interrupted. When using the "-b" option I get the following at the end of my child.read():

Established DTLS connection (using GnuTLS). Ciphersuite (DTLS0.9)-(RSA)-(AES-256-CBC)-(SHA1).\r\nSSL operation canceled\r\nUser detached from session (SIGHUP); exiting.\r\n'

Here is my code:

import os, sys, subprocess, time, re, pexpect
import signal

def signal_handler(sig, frame):
        print("sigHUUUUUP")
        sys.exit

child = pexpect.spawn('sudo openconnect -b --script /etc/vpnc/vpnc-script remote.host')

child.expect('.*')
child.sendline('yes')

child.expect('.*')
child.sendline('ipsec')

child.expect('.*')
child.sendline('username')

child.expect('.*')
child.sendline('password')
signal.signal(signal.SIGHUP, signal_handler)
time.sleep(15)

I have a strong preference to remain in python but I'm open to other ways of running openconnect and feeding it the expected passwords. Mainly looking for a way to have the vpn setup without needing to run the script continuously.

I've tried using ignore_sighup=True and that doesn't work.

Upvotes: 0

Views: 1004

Answers (2)

Philip Müller
Philip Müller

Reputation: 141

It's possible to use disown -h

If the -h option is given, the job is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP.

Working result:

import subprocess
import time
import pexpect
import signal

child = None

def connect_to_vpn():
  global child
  # Send the password and tunnel information to the process
  password = "YOUR_PASSWORD"
  tunnel = "YOUR_TUNNEL"
  print("Attempting to connect to vpn!")
  
  try:
    child = pexpect.spawn('bash')
    openconnect_command = 'sudo openconnect --user=YOUR_USERNAME VPN_ADDRESS --background'
    child.sendline(openconnect_command)
    
    # TUNNEL
    child.expect('TUNNEL_PROMPT_STRING', timeout=90) 
    print(child.before.decode())
    child.sendline(tunnel)
    
    # PASSWORD
    child.expect('Password:', timeout=90)
    print(child.before.decode())
    child.sendline(password)
    
    child.expect("Connected as ", timeout=30)  
    print(child.before.decode())
    print("Successfully connected!")
    child.sendline("disown -h")
  except Exception as e:
    if isinstance(e, pexpect.exceptions.EOF):
        print("Caught EOF exception")
    else:
        raise

Upvotes: 0

LMP
LMP

Reputation: 79

I have found a way accomplish what I wanted:

import os, sys, subprocess, time, re, pexpect
import signal

def signal_handler(sig, frame):
        print("sigHUUUUUP")
        sys.exit

child = pexpect.spawn('sudo screen openconnect remote.host')

child.expect('.*')
child.sendline('yes')

child.expect('.*')
child.sendline('ipsec')

child.expect('.*')
child.sendline('username')

child.expect('.*')
child.sendline('password')
child.sendline('\01d')

I added screen to my spawn line and added "child.sendline('\01d')" I hope this isn't the only way to accomplish this.

Upvotes: 1

Related Questions