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

Add support for portal-userauthcookie authentication #98

Closed

Conversation

arthepsy
Copy link

@arthepsy arthepsy commented Apr 9, 2018

This patch adds new authentication mechanism (via portal-userauthcookie). This is required for different types of third-party integrations. I have tested this with OKTA (okta.com) integration. Was able to successfully use GlobalProtect VPN on FreeBSD and MacOS X, even with 2FA.

Basically, there is a "authentication dance" with Global Protect and OKTA, which results in portal-userauthcookie, which is used instead of password, i.e., password is sent empty. Therefore, I use my python script to do the dance and just pass the portal-userauthcookie to openconnect and everything is working fine.

Simplified, "authentication dance" flow with OKTA is like this:

  1. send request to GP's /global-protect/prelogin.esp; retrieve saml-auth-method and saml-request
  2. send request to OKTA URL (retrieved in previous step's saml-request); retrieve "redirect url" in response
  3. authenticate with OKTA's /api/v1/authn (and if necessary then also with additional 2FA in following request) and retrieve sessionToken
  4. send request to OKTA's /login/sessionCookieRedirect, providing "redirect url" and sessionToken; retrieve saml-username and prelogin-cookie
  5. send request to GP's /global-protect/getconfig.esp with saml-username and prelogin-cookie; retrieve portal-userauthcookie
  6. use portal-userauthcookie with openconnect

You can see the specific details of "authentication dance" by looking at python script in:
https://github.com/arthepsy/pan-globalprotect-okta

@dlenski
Copy link
Owner

dlenski commented Apr 9, 2018

Basically, there is a "authentication dance" with Global Protect and OKTA, which results in portal-userauthcookie, which is used instead of password, i.e., password is sent empty. Therefore, I use my python script to do the dance and just pass the portal-userauthcookie to openconnect and everything is working fine.

You can see the specific details of "authentication dance" by looking at python script in:
https://github.com/arthepsy/pan-globalprotect-okta

Big 👍 👍 for prototyping it in Python, excellent.

This is very closely related to #97, which also wants to submit the prelogin-cookie in following a SAML auth flow.

  1. send request to GP's /global-protect/getconfig.esp with saml-username and prelogin-cookie; retrieve portal-userauthcookie

Few questions on this…

  1. Does the username have to go in saml-username, or does putting it in the "regular" user field have an equivalent effect?
  2. Does the request have to be submitted to /global-protect/getconfig.esp, or can equivalently be submitted to /ssl-vpn/login.esp on the gateway, rather than the portal?

Overall, I very much like your approach, but I'm wondering if there is a way to converge on a single script that will work for both this use case, as well as that of #97, and ideally as many other SAML-with-redirection use cases as well.

@arthepsy
Copy link
Author

  1. no, it's regular user, as it's in the code, i.e., saml-username is taken as value for user field. in my case, it adds domain prefix, e.g., my username changes from "myname" to "mydomain\myname".
  2. yes, request have to be submitted to /global-protect/getconfig.esp, because 1) you can only use prelogin-cookie once (second request will fail) and 2) submitting prelogin-cookie to /ssl-vpn/login.esp just gives 3-line javascript response (three empty fields), which current code doesn't understand and isn't usable.

Regarding script, what kind of use-cases did You think? I can adjust the script or help with a rewrite if that's what You would wish. Anyhow, it's a different task (can be worked on without this pull request), right? Therefore, would You mind merging these particular changes regarding portal-userauthcookie?

@dlenski
Copy link
Owner

dlenski commented Apr 12, 2018

Regarding script, what kind of use-cases did You think? I can adjust the script or help with a rewrite if that's what You would wish. Anyhow, it's a different task (can be worked on without this pull request), right? Therefore, would You mind merging these particular changes regarding portal-userauthcookie?

I'm glad this is working for you, but the difficulty is that your changes add an additional command-line option which alters the authentication flow… and this won't be accessible from any GUI front-ends.

Therefore these changes won't be accepted upstream in this form. I'm trying to figure out how to make a more general-purpose mechanism to alter the field used for the password/cookie, which will work with existing UIs.

dlenski added a commit that referenced this pull request Apr 12, 2018
This change allows the user to specify an alternative-secret field for the
login form submission, instead of 'passwd'.

The alternative field is specified by appending :FIELDNAME to the URL path:

	https://vpn.bigcorp.com/gateway:prelogin-cookie       (for #97)
	https://vpn.bigcorp.com/portal:portal-userauthcookie  (for #98)
@dlenski
Copy link
Owner

dlenski commented Apr 12, 2018

@arthepsy and @cizra, please check out and test the fun_with_cookies branch.

This is a general-purpose solution which allows you to specify an "alternative secret field name" instead of the default passwd. I hope it will allow us to handle all of these alternate authentication entry-points, which require the submission of a special cookie rather than the user's password.

@arthepsy: For your use case, you would connect with:

$ ./script_that_obtains_the_portal_userauthcookie |
> openconnect --passwd-on-stdin --protocol=gp -u USERNAME \
>     https://vpn.bigcorp.com/portal:portal-userauthcookie

@cizra: For your use case, you would connect with:

$ ./script_that_obtains_the_SAML_gateway_prelogin_cookie |
> openconnect --passwd-on-stdin --protocol=gp -u USERNAME \
>    https://vpn.bigcorp.com/gateway:prelogin-cookie

Please test these and let me know if they work for you. (Of course, you can enter the cookie values manually rather than via script, as needed.)

This solution is general-purpose enough that it should work with any other cookie-based login possibilities and allow integration into all the OpenConnect GUIs.

dlenski added a commit that referenced this pull request Apr 12, 2018
This change allows the user to specify an alternative-secret field for the
login form submission, instead of 'passwd'.

The alternative field is specified by appending :FIELDNAME to the URL path:

	https://vpn.bigcorp.com/gateway:prelogin-cookie       (for #97)
	https://vpn.bigcorp.com/portal:portal-userauthcookie  (for #98)
dlenski added a commit that referenced this pull request Apr 12, 2018
This change allows the user to specify an alternative-secret field for the
login form submission, instead of 'passwd'.

The alternative field is specified by appending :FIELDNAME to the URL path:

	https://vpn.bigcorp.com/gateway:prelogin-cookie       (for #97)
	https://vpn.bigcorp.com/portal:portal-userauthcookie  (for #98)
dlenski added a commit that referenced this pull request Apr 13, 2018
This change allows the user to specify an alternative-secret field for the
login form submission, instead of 'passwd'.

The alternative field is specified by appending :FIELDNAME to the URL path:

	https://vpn.bigcorp.com/gateway:prelogin-cookie       (for #97)
	https://vpn.bigcorp.com/portal:portal-userauthcookie  (for #98)
@cizra
Copy link

cizra commented Apr 24, 2018

$ LD_LIBRARY_PATH=`pwd`/out/lib out/sbin/openconnect --passwd-on-stdin --protocol=gp -u [email protected] https://bigcorp.com/gateway:prelogin-cookie
copy-pasted in the prelogin cookie
Please enter your username and password
POST https://bigcorp.com/ssl-vpn/login.esp
Connected to 1.2.3.4
SSL negotiation with bigcorp.com
Connected to HTTPS on bigcorp.com
Ignoring unknown HTTP response line '                                           script-src 'self' 'unsafe-inline';'
Ignoring unknown HTTP response line '                                           style-src 'self' 'unsafe-inline';'
GlobalProtect login returned authentication-source=(empty_authprofile)
munmap_chunk(): invalid pointer
Aborted (core dumped)
$ LD_LIBRARY_PATH=`pwd`/out/lib out/sbin/openconnect --version
OpenConnect version v7.08-280-g1b38c425
Using GnuTLS. Features present: TPM, PKCS#11, RSA software token, HOTP software token, TOTP software token, Yubikey OATH, System keys, DTLS, ESP
Supported protocols: anyconnect (default), nc, gp
$ git rev-parse HEAD
1b38c425ee3d0101d5c8e3f5edf5cff7258a14b2
gdb:
Program received signal SIGABRT, Aborted.
0x00007ffff4cb5efb in raise () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff4cb5efb in raise () from /usr/lib/libc.so.6
#1  0x00007ffff4cb72c1 in abort () from /usr/lib/libc.so.6
#2  0x00007ffff4cf89d7 in __libc_message () from /usr/lib/libc.so.6
#3  0x00007ffff4cfefda in malloc_printerr () from /usr/lib/libc.so.6
#4  0x00007ffff4cff53c in munmap_chunk () from /usr/lib/libc.so.6
#5  0x00007ffff7ba3391 in free_opt (opt=0x555555793fa0) at auth-common.c:114
#6  0x00007ffff7ba33e8 in free_auth_form (form=0x555555793640) at auth-common.c:125
#7  0x00007ffff7bbe80f in gpst_login (vpninfo=0x555555791fa0, portal=<optimized out>, pw_or_cookie_field=0x555555774188 "prelogin-cookie") at auth-globalprotect.c:376
#8  0x0000555555558b00 in main (argc=6, argv=0x7fffffffe228) at main.c:1538

@dlenski
Copy link
Owner

dlenski commented Apr 26, 2018

Sorry @cizra

The correct patch was de0feaa, then I second-guessed it and screwed it up in 1b38c42… now I've undone it and added back a comment in 7a6d32c.

I double-checked with valgrind and it should work now.

@dlenski
Copy link
Owner

dlenski commented Apr 30, 2018

@cizra, any updates on if this is working for you? Insofar as I'm able to test it with a fake "server simulator", it works fine and doesn't mishandle memory allocation.

@cizra
Copy link

cizra commented May 9, 2018

Yep, works fine. Sorry for the looooong delay.

@dlenski dlenski closed this May 10, 2018
dlenski added a commit that referenced this pull request May 10, 2018
@arthepsy
Copy link
Author

arthepsy commented Aug 20, 2018

Finally, got to try it out and it doesn't work for me, i.e., it doesn't read from stdin. Tried with echo, printf, additional newline, - no changes. Always get this error:

Please enter your username and password
portal-userauthcookie: 
fgets (stdin): Inappropriate ioctl for device

If I prepend a newline (printf "\ncookie" | openconnect ...), it gets further. That leads me to believe it reads something before the cookie. Any clues?

@dlenski
Copy link
Owner

dlenski commented Aug 20, 2018

That leads me to believe it reads something before the cookie. Any clues?

Hmm… does it read something before the cookie, if you run interactively?

Other than asking you to confirm the server certificate if it's no automatically verified, and asking for input of the username (if you don't specify with -u), there shouldn't be any input prior to the password field.

Repository owner locked and limited conversation to collaborators Oct 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants