Do the "another_dance" at the desired gateway to obtain a cookie that is valid there

This commit is contained in:
Tino Lange
2019-06-13 17:17:58 +02:00
parent d6a3863774
commit ceeaebba6d
+40 -33
View File
@@ -230,15 +230,20 @@ def send_req(conf, s, name, url, data, **kwargs):
return r.headers, parse_rjson(r) return r.headers, parse_rjson(r)
return r.headers, r.text return r.headers, r.text
def paloalto_prelogin(conf, s, gateway=None):
def paloalto_prelogin(conf, s, again=False): verify = None
log('prelogin request [vpn_url]') if gateway:
if again: # 2nd round: use gateway
url = '{0}/ssl-vpn/prelogin.esp'.format(conf.get('vpn_url')) log('prelogin request [gateway]')
url = 'https://{0}/ssl-vpn/prelogin.esp'.format(gateway)
verify = conf.get('vpn_url_cert')
else: else:
# 1st round: use portal
log('prelogin request [vpn_url]')
url = '{0}/global-protect/prelogin.esp'.format(conf.get('vpn_url')) url = '{0}/global-protect/prelogin.esp'.format(conf.get('vpn_url'))
h, c = send_req(conf, s, 'prelogin', url, {}, get=True, if conf.get('openconnect_certs') and os.path.getsize(conf.get('openconnect_certs').name) > 0:
verify=conf.get('vpn_url_cert')) verify = conf.get('openconnect_certs').name
h, c = send_req(conf, s, 'prelogin', url, {}, get=True, verify=verify)
x = parse_xml(c) x = parse_xml(c)
saml_req = x.find('.//saml-request') saml_req = x.find('.//saml-request')
if saml_req is None: if saml_req is None:
@@ -472,7 +477,7 @@ def paloalto_getconfig(conf, s, saml_username, prelogin_cookie):
portal_userauthcookie = xtmp.text portal_userauthcookie = xtmp.text
if len(portal_userauthcookie) == 0: if len(portal_userauthcookie) == 0:
err('empty portal_userauthcookie') err('empty portal_userauthcookie')
gateway = x.find('.//gateways//entry').get('name') gateway = x.find('.//gateways//entry').get('name') # FIXME: this just grabs the very first, probably not what you want
for entry in x.find('.//root-ca'): for entry in x.find('.//root-ca'):
cert = entry.find('.//cert').text cert = entry.find('.//cert').text
conf['openconnect_certs'].write(to_b(cert)) conf['openconnect_certs'].write(to_b(cert))
@@ -480,29 +485,27 @@ def paloalto_getconfig(conf, s, saml_username, prelogin_cookie):
return portal_userauthcookie, gateway return portal_userauthcookie, gateway
# Combined first half of okta_saml with second half of okta_redirect # Combined first half of okta_saml with second half of okta_redirect
def okta_saml_2(conf, s, saml_xml): def okta_saml_2(conf, s, gateway, saml_xml):
log('okta saml request') log('okta saml request (2) [okta_url]')
url, data = parse_form(saml_xml) url, data = parse_form(saml_xml)
r = s.post(url, data=data) h, c = send_req(conf, s, 'okta saml request (2)', url, data,
if r.status_code != 200: expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
err('redirect request failed. {0}'.format(reprr(r))) xhtml = parse_html(c)
dbg(conf.get('debug'), 'redirect.response', r.status_code, r.text)
xhtml = parse_html(r.text)
url, data = parse_form(xhtml) url, data = parse_form(xhtml)
log('okta redirect form request')
r = s.post(url, data=data) log('okta redirect form request (2) [gateway]')
if r.status_code != 200: verify = None
err('redirect form request failed. {0}'.format(reprr(r))) if conf.get('openconnect_certs') and os.path.getsize(conf.get('openconnect_certs').name) > 0:
dbg(conf.get('debug'), 'form.response', r.status_code, r.text) verify = conf.get('openconnect_certs').name
saml_username = r.headers.get('saml-username', '').strip() h, c = send_req(conf, s, 'okta redirect form (2)', url, data,
if len(saml_username) == 0 and not again: expected_url='https://{0}'.format(gateway), verify=verify)
saml_username = h.get('saml-username', '').strip()
if len(saml_username) == 0:
err('saml-username empty') err('saml-username empty')
#saml_auth_status = r.headers.get('saml-auth-status', '').strip() prelogin_cookie = h.get('prelogin-cookie', '').strip()
#saml_slo = r.headers.get('saml-slo', '').strip()
prelogin_cookie = r.headers.get('prelogin-cookie', '').strip()
if len(prelogin_cookie) == 0: if len(prelogin_cookie) == 0:
err('prelogin-cookie empty') err('prelogin-cookie empty')
return saml_username, prelogin_cookie return saml_username, prelogin_cookie
def main(): def main():
@@ -524,14 +527,16 @@ def main():
log('sessionToken: {0}'.format(token)) log('sessionToken: {0}'.format(token))
saml_username, prelogin_cookie = okta_redirect(conf, s, token, redirect_url) saml_username, prelogin_cookie = okta_redirect(conf, s, token, redirect_url)
userauthcookie, gateway = paloalto_getconfig(conf, s, saml_username, prelogin_cookie) userauthcookie, gateway = paloalto_getconfig(conf, s, saml_username, prelogin_cookie)
gateway = conf.get('gateway', gateway).strip()
log('portal-userauthcookie: {0}'.format(userauthcookie)) log('portal-userauthcookie: {0}'.format(userauthcookie))
log('gateway: {0}'.format(gateway)) log('gateway: {0}'.format(gateway))
log('saml-username: {0}'.format(saml_username))
# Another dance? # We're done with the portal now. Another dance with the gateway now?
if conf.get('another_dance', '').lower() in ['1', 'true']: if conf.get('another_dance', '').lower() in ['1', 'true']:
saml_xml = paloalto_prelogin(conf, s, again=True) saml_xml = paloalto_prelogin(conf, s, gateway)
saml_username, prelogin_cookie = okta_saml_2(conf, s, saml_xml) saml_username, prelogin_cookie = okta_saml_2(conf, s, gateway, saml_xml)
log('saml-username: {0}'.format(saml_username)) log('saml-username: {0}'.format(saml_username))
log('prelogin-cookie: {0}'.format(prelogin_cookie)) log('prelogin-cookie: {0}'.format(prelogin_cookie))
@@ -544,6 +549,7 @@ def main():
cookie = userauthcookie cookie = userauthcookie
username = saml_username username = saml_username
cmd = conf.get('openconnect_cmd', 'openconnect') cmd = conf.get('openconnect_cmd', 'openconnect')
cmd += ' --protocol=gp -u \'{0}\'' cmd += ' --protocol=gp -u \'{0}\''
cmd += ' --usergroup {1}' cmd += ' --usergroup {1}'
@@ -552,15 +558,16 @@ def main():
if conf.get('openconnect_certs') and os.path.getsize(conf.get('openconnect_certs').name) > 0: if conf.get('openconnect_certs') and os.path.getsize(conf.get('openconnect_certs').name) > 0:
cmd += ' --cafile=\'{0}\''.format(conf.get('openconnect_certs').name) cmd += ' --cafile=\'{0}\''.format(conf.get('openconnect_certs').name)
cmd += ' --passwd-on-stdin ' + conf.get('openconnect_args', '') + ' \'{2}\'' cmd += ' --passwd-on-stdin ' + conf.get('openconnect_args', '') + ' \'{2}\''
cmd = cmd.format(username, cookie_type, conf.get('vpn_url')) cmd = cmd.format(username, cookie_type,
gw = conf.get('gateway', gateway).strip() 'https://{0}'.format(gateway) if conf.get('another_dance', '').lower() in ['1', 'true'] else conf.get('vpn_url'))
bugs = '' bugs = ''
if conf.get('bug.nl', '').lower() in ['1', 'true']: if conf.get('bug.nl', '').lower() in ['1', 'true']:
bugs += '\\n' bugs += '\\n'
if conf.get('bug.username', '').lower() in ['1', 'true']: if conf.get('bug.username', '').lower() in ['1', 'true']:
bugs += '{0}\\n'.format(username.replace('\\', '\\\\')) bugs += '{0}\\n'.format(username.replace('\\', '\\\\'))
if len(gw) > 0: if len(gateway) > 0:
pcmd = 'printf \'' + bugs + '{0}\\n{1}\''.format(cookie, gw) pcmd = 'printf \'' + bugs + '{0}\\n{1}\''.format(cookie, gateway)
else: else:
pcmd = 'printf \'' + bugs + '{0}\''.format(cookie) pcmd = 'printf \'' + bugs + '{0}\''.format(cookie)
print() print()