2

I am trying to connect to CISCO Anyconnect VPN via python function. I have seen the ways given here: Connect CISCO Anyconnect VPN via bash

But first I have a couple of problems, the first one being new to Python and second being reluctant to use any/very-few third-party modules/libraries other than https://github.com/cernekee/stoken.

Here, stoken gives me the RSA SecureID token for authentication when I run:

$ stoken tokencode

My password consists of a 4-digits pin say, WXYZ which is concatenated with the RSA token for the passcode input.

I came up with the following one-liner bash command to connect which works so far from my OSX:

'(echo "user.name";echo "WXYZ$(stoken tokencode)"; echo y )> vps.ad ; /opt/cisco/anyconnect/bin/vpn -s connect "vpn.domain" < vps.ad'

Now, in my python script, I tried using both os and subprocess modules to do the same but failed spectacularly.

I have several VPN domains and two different pins(like, WXYZ) which I am trying to put together to replicate the above bash command. The function now looks like this:

def __auth_cisco_vpn__(username, pin, domain):
try:
    token = str(os.popen('stoken tokencode', 'r'))

    pre_prcs = '(echo "' + username + '";echo "' + pin + '$(stoken tokencode)"; ' + 'echo y )> vps.ad ; /opt/cisco/anyconnect/bin/vpn -s connect "' + domain + '" < vps.ad'

    subprocess.Popen(pre_prcs, shell=True, executable="/bin/bash", stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE).communicate()
    return True

except KeyboardInterrupt:
    return False

I managed to get the following error when I try to get the token separately as below:

pre_prcs = '(echo "'+username+'";echo "'+pin+'$'+token+'"; ' + 'echo y )> vps.ad ; /opt/cisco/anyconnect/bin/vpn -s connect "'+domain+'" < vps.ad'

subprocess.Popen(pre_prcs, shell=True, executable="/bin/bash", stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

TypeError: cannot concatenate 'str' and 'file' objects

What should I do? Many thanks in advance.

Community
  • 1
  • 1
katiepy
  • 95
  • 1
  • 1
  • 6
  • I suspect it will be easier to modify [openconnect](http://www.infradead.org/openconnect/) to suit your needs. It can connect to Cisco AnyConnect but is open-source. – ephemient Mar 09 '17 at 22:17

1 Answers1

4

After a little tweaking, I found out the problem and come up with the following solution. Notice the error with the quotations in # Assign cmd section below:

import subprocess

def __auth_cisco_vpn__(username, pin, domain):

    # Grab Token
    proc = subprocess.Popen(['stoken', 'tokencode'],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    store = list(proc.stdout)
    token = store[0].strip()

    # Assign cmd
    credentials = "printf '" + username + "\\n" + pin + token + "\\ny'"
    vpn_cmd = "/opt/cisco/anyconnect/bin/vpn -s connect '" + domain + "'"
    cmd = credentials + " | " + vpn_cmd

    # Command Execution
    print("Executing Command: \n" + cmd)
    subprocess.Popen(cmd,
                     shell=True,
                     executable="/bin/bash",
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE).communicate()

__auth_cisco_vpn__('user.name', 'WXYZ', 'domain')
Nuno André
  • 4,739
  • 1
  • 33
  • 46
katiepy
  • 95
  • 1
  • 1
  • 6