Open bene2342 opened 4 years ago
Please run openconnect-sso with -l debug
argument and paste the contents of log line starting with [debug ] Auth init response received
Thanks for your reply, I can paste at least the beginning as starts with [debug ] Auth init response received [openconnect_sso.authenticator] content=b'\n<!DOCTYPE html>\n<html
and then there are ~75k characters of html code, not sure if that's really helping but if so let me know and I'll paste the entire output.
Are you sure you are connecting on an AnyConnect compatible endpoint? Does anyconnect work on that endpoint?
The reason I ask this is that openconnect-sso (and openconnect in anyconnect compatibility mode too) expects that the endpoint it connects to serves an XML like this:
<?xml version="1.0" encoding="UTF-8"?>
<config-auth client="vpn" type="auth-request" aggregate-auth-version="2">
<opaque is-for="sg">
<tunnel-group>Q-Employee</tunnel-group>
<auth-method>single-sign-on-v2</auth-method>
<group-alias>Employee (Global)</group-alias>
<config-hash>1567100134259</config-hash>
</opaque>
<auth id="main">
<title>Login</title>
<message>Please complete the authentication process in the AnyConnect Login window.</message>
<banner></banner>
<sso-v2-login>...</sso-v2-login>
<sso-v2-login-final>...</sso-v2-login-final>
<sso-v2-logout>...</sso-v2-logout>
<sso-v2-logout-final>...</sso-v2-logout-final>
<sso-v2-token-cookie-name>acSamlv2Token</sso-v2-token-cookie-name>
<sso-v2-error-cookie-name>acSamlv2Error</sso-v2-error-cookie-name>
<form>
<input type="sso" name="sso-token"></input>
...
</select>
</form>
</auth>
</config-auth>
I'm trying to connect to a PulseSecure PSA5000 which is working fine as long as it's not using SAML. If the login is username/password + 2FA, everything works as expected. For openconnect I'm adding the paramenter --juniper.
Unfortunately openconnect-sso
is only compatible with the protocol Cisco's AnyConnect is using.
It seems to me that unlike AnyConnect, Pulse is starting with the web for authentication. I have found that we'd need to parse the DSID
cookie https://github.com/russdill/juniper-vpn-py/blob/master/juniper-vpn.py#L258. openconnect-sso
also would need to be able to execute the host checker code, according to juniper-vpn-py
.
thanks for looking into that. I had a look at the repo you mentioned and also gave it a try, same behavior. I guess the main problem here is that the Pusle is using GSuite SAML and wants to open a browser window to get the needed credentials. At least that's what the Pulse Linux client is doing, problem with that is, it's using libwebkit-1.0.0 which is kinda old.
@bene2342 @vlaci It has been a while since you have asked your question, but this page was one of the top ones that came up during my search, so I figured I may as well share my findings here. Pulse Secure does rely on user going through web pages to authenticate and receive authentication cookie (named DSID) and it will be nearly impossible to automate the process of logging in all the possible SAML providers, as you will be effectively screen scraping for specific fields and any interface change can break your code. However it is extremely easy to just fire up the web browser, let the user log in manually, then extract the cookie and fire up openconnect with that cookie authentication. Here's the barebones version of what I am talking about, written in python and using selenium to open up a browser for user to interact with. It should work with any SAML provider out there:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import subprocess
host = "your.vpn.com" #could be "your.vpn.com/saml" if you have different authentication endpoints
user = "username"
# declare webdriver to control browser. You can use different browser if you prefer
driver = webdriver.Chrome("./chromedriver")
# Configure wait, 60 seconds should be more than enough to enter all the credentials
wait = WebDriverWait(driver, 60)
# open up the VPN web page
driver.get("https://"+host)
# Keep checking for cookie to appear in the web browser (after user is done with authentication process)
dsid = wait.until(lambda driver: driver.get_cookie("DSID"))
# We don't need browser once we got cookie
driver.quit()
# Run a shell command to start openconnect
subprocess.run(["openconnect", "-C", dsid["value"], "--protocol=pulse", "-u", user, host])
Here's the barebones version of what I am talking about, written in python and using selenium to open up a browser for user to interact with.
Keep in mind that this will be complicated if a host checker is in use (at least our company pulse server requires the host checker before authentication on the website)
I tried connecting to a Pulse Secure appliance which is configured with GSuite and 2FA, unfortunately it was not working. It would be great if that could be added. Some output I able to share.