mirror of
https://github.com/os-mnemo/pan-globalprotect-okta
synced 2026-07-31 15:54:36 +02:00
Implement double authn login (via stateToken) needed for some corporate VPN setups.
The first authn call only returns the `sessionToken`, with the redirect later one gets the `stateToken` and afterwards need to do the authn call again for full authentication (and mfa).
This commit is contained in:
+14
-1
@@ -153,6 +153,14 @@ def mfa_priority(conf, ftype, fprovider):
|
|||||||
priority += (512 - line_nr)
|
priority += (512 - line_nr)
|
||||||
return priority
|
return priority
|
||||||
|
|
||||||
|
def get_state_token(conf, c, current_url = None):
|
||||||
|
rx_state_token = re.search(r'var\s*stateToken\s*=\s*\'([^\']+)\'', c)
|
||||||
|
if not rx_state_token:
|
||||||
|
dbg(conf.get('debug'), 'not found', 'stateToken')
|
||||||
|
return None
|
||||||
|
state_token = to_b(rx_state_token.group(1)).decode('unicode_escape').strip()
|
||||||
|
return state_token
|
||||||
|
|
||||||
def get_redirect_url(conf, c, current_url = None):
|
def get_redirect_url(conf, c, current_url = None):
|
||||||
rx_base_url = re.search(r'var\s*baseUrl\s*=\s*\'([^\']+)\'', c)
|
rx_base_url = re.search(r'var\s*baseUrl\s*=\s*\'([^\']+)\'', c)
|
||||||
rx_from_uri = re.search(r'var\s*fromUri\s*=\s*\'([^\']+)\'', c)
|
rx_from_uri = re.search(r'var\s*fromUri\s*=\s*\'([^\']+)\'', c)
|
||||||
@@ -222,7 +230,7 @@ def okta_saml(conf, s, saml_xml):
|
|||||||
err('did not find redirect url')
|
err('did not find redirect url')
|
||||||
return redirect_url
|
return redirect_url
|
||||||
|
|
||||||
def okta_auth(conf, s):
|
def okta_auth(conf, s, stateToken = None):
|
||||||
log('okta auth request')
|
log('okta auth request')
|
||||||
url = '{0}/api/v1/authn'.format(conf.get('okta_url'))
|
url = '{0}/api/v1/authn'.format(conf.get('okta_url'))
|
||||||
data = {
|
data = {
|
||||||
@@ -232,6 +240,8 @@ def okta_auth(conf, s):
|
|||||||
'warnBeforePasswordExpired':True,
|
'warnBeforePasswordExpired':True,
|
||||||
'multiOptionalFactorEnroll':True
|
'multiOptionalFactorEnroll':True
|
||||||
}
|
}
|
||||||
|
} if stateToken is None else {
|
||||||
|
'stateToken': stateToken
|
||||||
}
|
}
|
||||||
h, j = send_req(conf, s, 'auth', url, data, json=True)
|
h, j = send_req(conf, s, 'auth', url, data, json=True)
|
||||||
|
|
||||||
@@ -370,12 +380,15 @@ def okta_redirect(conf, s, session_token, redirect_url):
|
|||||||
url = '{0}/login/sessionCookieRedirect'.format(conf.get('okta_url'))
|
url = '{0}/login/sessionCookieRedirect'.format(conf.get('okta_url'))
|
||||||
log('okta redirect request')
|
log('okta redirect request')
|
||||||
h, c = send_req(conf, s, 'redirect', url, data)
|
h, c = send_req(conf, s, 'redirect', url, data)
|
||||||
|
state_token = get_state_token(conf, c, url)
|
||||||
redirect_url = get_redirect_url(conf, c, url)
|
redirect_url = get_redirect_url(conf, c, url)
|
||||||
if redirect_url:
|
if redirect_url:
|
||||||
form_url, form_data = None, {}
|
form_url, form_data = None, {}
|
||||||
else:
|
else:
|
||||||
xhtml = parse_html(c)
|
xhtml = parse_html(c)
|
||||||
form_url, form_data = parse_form(xhtml, url)
|
form_url, form_data = parse_form(xhtml, url)
|
||||||
|
if state_token is not None:
|
||||||
|
okta_auth(conf, s, state_token)
|
||||||
elif form_url:
|
elif form_url:
|
||||||
log('okta redirect form request')
|
log('okta redirect form request')
|
||||||
h, c = send_req(conf, s, 'redirect form', form_url, form_data)
|
h, c = send_req(conf, s, 'redirect form', form_url, form_data)
|
||||||
|
|||||||
Reference in New Issue
Block a user