pythonterminalopenconnect

How to feed command inputs run with Popen programmatically in Python?


I created a Python script that performs several REST API calls to fetch a cookie which then used a password for the openconnect application by piping an echo "my cookie value" to the openconnect command. The purpose is to basically connect to a corporate VPN.

It used to work fine, except that now there is another input to be fed, it appears that there are like 2 gateway servers. And one of them needs to be picked manually and passed to the prompt.

I purposefully only put the part of Python performing the call to openconnect below considering that the REST API calls is already working to fetch a cookie which needs to be passed to the openconnect prompt:

# [...] lots of REST API calls to fetch the portal_userauthcookie:
# for the sake of simplicity let's say it has a dummy value
portal_userauthcookie = "blahblah"
print("portal-userauthcookie = \"{}\"".format(portal_userauthcookie))

# Call openconnect with the cookie / password we got above
cmd = "echo \"{}\"".format(portal_userauthcookie)
cmd += " |"
cmd += " openconnect"
cmd += " --protocol=gp"
cmd += " --usergroup portal:portal-userauthcookie"
cmd += " --user={}".format(username)
cmd += " {}".format(vpn_portal_url)

process = subprocess.Popen(cmd, shell=True, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
out, err = process.communicate()

When the script is run:

$ sudo ./bin/python3 ./main.py 
[sudo] password for perret:           
My username: my-username
My password: 
My non-expired smartphone app code: my-code
portal-userauthcookie = "blahblah"
POST another-corporate.url.com&clientVer=4100&clientos=Linux
Connected to [corporate-ip]:443
SSL negotiation with [corporate-url]
Connected to HTTPS on [corporate-url]
SAML login is required via POST to this URL:
<html>
<!-- corporate html -->
</html>

Enter login credentials
portal-userauthcookie: 
POST corporate.url.com
2 gateway servers available:
  gateway1 (blahblah-url-1)
  gateway2 (blahblah-url-2)
Please select GlobalProtect gateway.
GATEWAY: [gateway1|gateway2]:fgets (stdin): Resource temporarily unavailable

How can I feed automatically say gateway1 to the prompt of the popen command?

I tried to add another echo but seems only one can work (the one I am already for passing the cookie that acts as a password).


Solution

  • You can try to use expect tool to automate user input. Just check man expect out. It's a fully-fledged solution to make interactive command-line programs scriptable.

    However, in accordance with the openconnect man page, it's possible to specify the cookie via --cookie option instead of using stdin. Then you can try to keep sending the gateway via stdin.