Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PulseSecure support with SAML and 2FA #11

Open
bene2342 opened this issue Feb 26, 2020 · 8 comments
Open

PulseSecure support with SAML and 2FA #11

bene2342 opened this issue Feb 26, 2020 · 8 comments
Labels
enhancement New feature or request

Comments

@bene2342
Copy link

bene2342 commented Feb 26, 2020

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.

[info     ] Authenticating to VPN endpoint [openconnect_sso.app] address=sslvpn.example.net name=UNNAMED
Traceback (most recent call last):
  File "/home/bene/.local/bin/openconnect-sso", line 8, in <module>
    sys.exit(main())
  File "/home/bene/.local/pipx/venvs/openconnect-sso/lib/python3.7/site-packages/openconnect_sso/cli.py", line 150, in main
    return app.run(args)
  File "/home/bene/.local/pipx/venvs/openconnect-sso/lib/python3.7/site-packages/openconnect_sso/app.py", line 28, in run
    return asyncio.get_event_loop().run_until_complete(_run(args))
  File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "/home/bene/.local/pipx/venvs/openconnect-sso/lib/python3.7/site-packages/openconnect_sso/app.py", line 98, in _run
    auth_response = await authenticate_to(selected_profile, credentials, display_mode)
  File "/home/bene/.local/pipx/venvs/openconnect-sso/lib/python3.7/site-packages/openconnect_sso/authenticator.py", line 21, in authenticate
    response = self._start_authentication()
  File "/home/bene/.local/pipx/venvs/openconnect-sso/lib/python3.7/site-packages/openconnect_sso/authenticator.py", line 65, in _start_authentication
    return parse_response(response)
  File "/home/bene/.local/pipx/venvs/openconnect-sso/lib/python3.7/site-packages/openconnect_sso/authenticator.py", line 133, in parse_response
    xml = objectify.fromstring(resp.content)
  File "src/lxml/objectify.pyx", line 1808, in lxml.objectify.fromstring
  File "src/lxml/etree.pyx", line 3235, in lxml.etree.fromstring
  File "src/lxml/parser.pxi", line 1876, in lxml.etree._parseMemoryDocument
  File "src/lxml/parser.pxi", line 1764, in lxml.etree._parseDoc
  File "src/lxml/parser.pxi", line 1127, in lxml.etree._BaseParser._parseDoc
  File "src/lxml/parser.pxi", line 601, in lxml.etree._ParserContext._handleParseResultDoc
  File "src/lxml/parser.pxi", line 711, in lxml.etree._handleParseResult
  File "src/lxml/parser.pxi", line 640, in lxml.etree._raiseParseError
  File "<string>", line 1256
lxml.etree.XMLSyntaxError: Opening and ending tag mismatch: meta line 7 and head, line 1256, column 10```

@vlaci
Copy link
Owner

vlaci commented Feb 27, 2020

Please run openconnect-sso with -l debug argument and paste the contents of log line starting with [debug ] Auth init response received

@bene2342
Copy link
Author

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.

@vlaci
Copy link
Owner

vlaci commented Feb 29, 2020

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>

@bene2342
Copy link
Author

bene2342 commented Mar 2, 2020

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.

@vlaci
Copy link
Owner

vlaci commented Mar 2, 2020

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.

@bene2342
Copy link
Author

bene2342 commented Mar 4, 2020

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.

@vlaci vlaci added the enhancement New feature or request label Oct 25, 2020
@eoprede
Copy link

eoprede commented Sep 22, 2021

@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])

@azrdev
Copy link

azrdev commented Nov 23, 2023

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants