vlaci / openconnect-sso

Wrapper script for OpenConnect supporting Azure AD (SAMLv2) authentication to Cisco SSL-VPNs
GNU General Public License v3.0
301 stars 131 forks source link

azure sso completes, then login fails #57

Open gilrim opened 3 years ago

gilrim commented 3 years ago

I've installed 0.7.3 from aur and are connecting to a ocserv that works fine with the cisco anyconnect client. When connecting I'm successfully authenticated and receives the cookies from the server, but then it crashes... any pointers? See my sanitized logs below:

Using selector: EpollSelector [info     ] Authenticating to VPN endpoint [openconnect_sso.app] address=some.site.tld name= Starting new HTTPS connection (1): some.site.tld:443 https://some.site.tld:443 "GET / HTTP/1.1" 200 880 [debug    ] Auth target url                [openconnect_sso.authenticator] url=https://some.site.tld/ [debug    ] Sending auth init request      [openconnect_sso.authenticator] content=b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<config-auth client="vpn" type="init" aggregate-auth-ve rsion="2">\n  4.7.00136\n  linux-64\n  \n  https://some.site.tld/\n  <capab ilities>\n    single-sign-on-v2\n  \n\n'                                                                                          Starting new HTTPS connection (1): some.site.tld:443 https://some.site.tld:443 "POST / HTTP/1.1" 200 880 [debug    ] Auth init response received    [openconnect_sso.authenticator] content=b'<?xml version="1.0" encoding="UTF-8"?>\n<config-auth client="vpn" type="auth-request" aggregate-aut h-version="2">\n\nsingle-sign-on-v2\n\n\nLogin\nPlease complete the authentication proce ss in the AnyConnect Login window.\n\nhttps://some.site.tld/+CSCOE+/saml/sp/login\nhttps://some.site.tld/+CSCO E+/saml_ac_login.html\nhttps://some.site.tld/+CSCOE+/saml/sp/logout\nhttps://some.site.tld/+CSCOE+/saml_ac_login. html\nacSamlv2Token\nacSamlv2Error\n

\n\n
\n'                                                                                                                          [info     ] Response received              [openconnect_sso.authenticator] id=main message=Please complete the authentication process in the AnyConnect Login window. title=Login [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [info     ] Browser started                [webengine] startup_info=StartupInfo(url='https://some.site.tld/+CSCOE+/saml/sp/login', credentials=None) [info     ] Loading page                   [webengine] url=https://some.site.tld/+CSCOE+/saml/sp/login Icon theme "Sardi" not found. Icon theme "gnome" not found. Icon theme "elementary" not found. Icon theme "gnome" not found. Icon theme "gnome" not found. [debug    ] Cookie set                     [webengine] name=ESTSAUTHPERSISTENT [debug    ] Cookie set                     [webengine] name=brcap [debug    ] Cookie set                     [webengine] name=ch [debug    ] Cookie set                     [webengine] name=wlidperf [debug    ] Cookie set                     [webengine] name=buid [debug    ] Cookie set                     [webengine] name=clrc [debug    ] Cookie set                     [webengine] name=fpc [debug    ] Cookie set                     [webengine] name=webvpncontext [debug    ] Cookie set                     [webengine] name=webvpncontext [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='ESTSAUTHPERSISTENT', value='**')                                                                                                           [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='brcap', value='0') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='ch', value='*') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='wlidperf', value='FR=L&ST=****') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='buid', value='**')                                                                                                                                                                                 [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='clrc', value='{***}') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='fpc', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpncontext', value='=') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpncontext', value='=') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Cookie set                     [webengine] name=webvpncontext [debug    ] Cookie set                     [webengine] name=acsamlcap [debug    ] Cookie set                     [webengine] name=tg [debug    ] Cookie set                     [webengine] name=acSamlv2Error [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpncontext', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='acsamlcap', value='v2') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='tg', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='acSamlv2Error', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Cookie set                     [webengine] name=ESTSAUTHPERSISTENT [debug    ] Cookie set                     [webengine] name=ESTSAUTH [debug    ] Cookie set                     [webengine] name=ESTSAUTHLIGHT [debug    ] Cookie set                     [webengine] name=ch [debug    ] Cookie set                     [webengine] name=ESTSSC [debug    ] Cookie set                     [webengine] name=buid [debug    ] Cookie set                     [webengine] name=SignInStateCookie [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='ESTSAUTHPERSISTENT', value='')                                                                                                          [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Cookie set                     [webengine] name=fpc [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='ESTSAUTH', value='')                                                                             [debug    ] Cookie set                     [webengine] name=esctx [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Cookie set                     [webengine] name=x-ms-gateway-slice [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='ESTSAUTHLIGHT', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Cookie set                     [webengine] name=stsservicecookie [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='ch', value='n2CLc-425JLbpRoSWg1Recn4ml-W3zwv51UZUcu1d9k') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='ESTSSC', value='00') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='buid', value='')                                                                                                                                                                                 [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='SignInStateCookie', value='')                                                                                         [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='fpc', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='esctx', value='')                                              [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='x-ms-gateway-slice', value='estsfd') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='stsservicecookie', value='estsfd') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Cookie set                     [webengine] name=webvpncontext [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpncontext', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Cookie set                     [webengine] name=webvpncontext [debug    ] Page loaded                    [webengine] url=https://some.site.tld/+CSCOE+/saml/sp/acs [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpncontext', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=Url(url='https://some.site.tld/+CSCOE+/saml/sp/acs') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Browser loaded page            [openconnect_sso.saml_authenticator] url=https://some.site.tld/+CSCOE+/saml/sp/acs [debug    ] Cookie set                     [webengine] name=webvpncontext [debug    ] Cookie set                     [webengine] name=acSamlv2Token [debug    ] Cookie set                     [webengine] name=webvpn [debug    ] Cookie set                     [webengine] name=webvpnc [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpncontext', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='acSamlv2Token', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpn', value='') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=SetCookie(name='webvpnc', value='bu:/&p:t&iu:1/&sh:&lu:/+CS COT+/translation-table?textdomain%3DAnyConnect%26type%3Dmanifest&fu:profiles%2F/config/profile.xml&fh:')                                          [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Page loaded                    [webengine] url=https://some.site.tld/+CSCOE+/saml_ac_login.html [debug    ] Message received from browser  [openconnect_sso.browser.browser] message=Url(url='https://some.site.tld/+CSCOE+/saml_ac_login.html') [debug    ] Waiting for message from browser process [openconnect_sso.browser.browser]   [debug    ] Browser loaded page            [openconnect_sso.saml_authenticator] url=https://some.site.tld/+CSCOE+/saml_ac_login.html [info     ] Terminate requested.           [webengine]   [info     ] Exiting browser                [webengine]   [info     ] Browser exited                 [openconnect_sso.browser.browser]   [debug    ] Sending auth finish request    [openconnect_sso.authenticator] content=b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<config-auth client="vpn" type="auth-reply" aggregate-a uth-version="2">\n  4.7.00136\n  linux-64\n  \n  \n  \n    single-sign -on-v2\n  \n  \n    \n  \n\n'                                        https://some.site.tld:443 "POST / HTTP/1.1" 200 454 [debug    ] Auth finish response received  [openconnect_sso.authenticator] content=b'<?xml version="1.0" encoding="UTF-8"?>\n\n0.1(1)\n\nSSL VPN Service\n<file type="profile" service-t ype="user">/profiles//config/profile.xml\n'        Traceback (most recent call last):  File "/usr/bin/openconnect-sso", line 33, in    sys.exit(load_entry_point('openconnect-sso==0.7.3', 'console_scripts', 'openconnect-sso')())  File "/usr/lib/python3.9/site-packages/openconnect_sso/cli.py", line 169, in main    return app.run(args)  File "/usr/lib/python3.9/site-packages/openconnect_sso/app.py", line 34, in run    auth_response, selected_profile = asyncio.get_event_loop().run_until_complete(  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete    return future.result()  File "/usr/lib/python3.9/site-packages/openconnect_sso/app.py", line 139, in _run    auth_response = await authenticate_to(  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 44, in authenticate    response = self._complete_authentication(auth_request_response, sso_token)  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 81, in _complete_authentication    return parse_response(response)  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 142, in parse_response    return parse_auth_complete_response(xml)  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 187, in parse_auth_complete_response    auth_message=xml.auth.message,  File "src/lxml/objectify.pyx", line 231, in lxml.objectify.ObjectifiedElement.getattr  File "src/lxml/objectify.pyx", line 450, in lxml.objectify._lookupChildOrRaise AttributeError: no such child: message

vlaci commented 3 years ago

Could you try changing the following line: https://github.com/vlaci/openconnect-sso/blob/54da0073732cc1cb445360c3d6f0c915ae223ec8/openconnect_sso/authenticator.py#L187 to look like

auth_message=xml.auth.get("message"),

and see if the connection succeeds that way.

gilrim commented 3 years ago

This change made a change to the output, but it still doesn't connect:

[debug    ] Auth finish response received  [openconnect_sso.authenticator] content=b'<?xml version="1.0" encoding="UTF-8"?>\n<config-auth client="vpn" type="complete">\n<version who="sg">0.1(1)</version>\n<auth id="success">\n<title>SSL VPN Service</title></auth>\n<config client="vpn" type="private"><vpn-profile-manifest><vpn rev="1.0"><file type="profile" service-type="user"><uri>/profiles//config/profile.xml</uri><hash type="sha1">919A911F43566682DB27559388BB836CC8203DAF</hash></file></vpn></vpn-profile-manifest>\n</config></config-auth>'
Traceback (most recent call last):
  File "/usr/bin/openconnect-sso", line 33, in <module>
    sys.exit(load_entry_point('openconnect-sso==0.7.3', 'console_scripts', 'openconnect-sso')())
  File "/usr/lib/python3.9/site-packages/openconnect_sso/cli.py", line 169, in main
    return app.run(args)
  File "/usr/lib/python3.9/site-packages/openconnect_sso/app.py", line 34, in run
    auth_response, selected_profile = asyncio.get_event_loop().run_until_complete(
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/usr/lib/python3.9/site-packages/openconnect_sso/app.py", line 139, in _run
    auth_response = await authenticate_to(
  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 44, in authenticate
    response = self._complete_authentication(auth_request_response, sso_token)
  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 81, in _complete_authentication
    return parse_response(response)
  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 142, in parse_response
    return parse_auth_complete_response(xml)
  File "/usr/lib/python3.9/site-packages/openconnect_sso/authenticator.py", line 188, in parse_auth_complete_response
    session_token=xml["session-token"],
  File "src/lxml/objectify.pyx", line 289, in lxml.objectify.ObjectifiedElement.__getitem__
  File "src/lxml/objectify.pyx", line 450, in lxml.objectify._lookupChildOrRaise
AttributeError: no such child: session-token
vlaci commented 3 years ago

Hm, the response structure is different then the one I am familiar with. My VPN responds with the structure like this:

<?xml version="1.0" encoding="UTF-8"?>
<config-auth client="vpn" type="complete" aggregate-auth-version="2">
<session-id>11111111</session-id>
<session-token>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</session-token>
<auth id="success">
<message id="0" param1="" param2=""></message>
</auth>
<!-- [...] -->
</config-auth>

The session-token is a long alphanumerical string which is used to authenticate the actual VPN connection. Do you see something in the response that could contain that value?

gilrim commented 3 years ago

This is the closest I get from the debug messages. The server is running ocserv, should that matter?

[debug ] Sending auth finish request [openconnect_sso.authenticator] content=b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<config-auth client="vpn" type="auth-reply" aggregate-auth-version="2">\n <version who="vpn">4.7.00136</version>\n <device-id>linux-64</device-id>\n <session-token/>\n <session-id/>\n <opaque is-for="sg">\n <auth-method>single-sign-on-v2</auth-method>\n </opaque>\n <auth>\n <sso-token>xxXXxxXxxXxxXxXXXxXxXXxxxxxxxXxXxXxXXXxXXXX=</sso-token>\n </auth>\n</config-auth>\n' https://some.host.tld:443 "POST / HTTP/1.1" 200 454 [debug ] Auth finish response received [openconnect_sso.authenticator] content=b'<?xml version="1.0" encoding="UTF-8"?>\n<config-auth client="vpn" type="complete">\n<version who="sg">0.1(1)</version>\n<auth id="success">\n<title>SSL VPN Service</title></auth>\n<config client="vpn" type="private"><vpn-profile-manifest><vpn rev="1.0"><file type="profile" service-type="user"><uri>/profiles//config/profile.xml</uri><hash type="sha1">XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</hash></file></vpn></vpn-profile-manifest>\n</config></config-auth>'

vlaci commented 3 years ago

I see you have an sso-token element in the xml. You could try adjusting this line: https://github.com/vlaci/openconnect-sso/blob/54da0073732cc1cb445360c3d6f0c915ae223ec8/openconnect_sso/authenticator.py#L188

session_token=xml["sso-token"],

If this would work, I'll update the code to handle this case.

gilrim commented 3 years ago

strangely, that results in python claiming not having seen that child node: image

vlaci commented 3 years ago

Ohm, I have misread the logs: The sso-token was the one we have posted to the VPN endpoint, not the response to that.

My next idea is that you need to specify the tunnel-group for the connection. In my case the VPN server uses a default one but it may not be for you. I think about what could be done there.

CJKay commented 3 years ago

@vlaci I am seeing the same issue, and I can see from the debug output that I do require a different tunnel group, so I suspect you are correct.