mirror of
https://github.com/os-mnemo/pan-globalprotect-okta
synced 2026-07-31 15:54:36 +02:00
Use gateway as choice in openconnect and gateway_url as direct authentication URL.
Rename `--show-list-of-gateways` to `--list-gateways` and fix it (sometimes gateways can be listed only after authentication). Reorder configuration file to be more sane.
This commit is contained in:
+4
-2
@@ -6,6 +6,10 @@ vpn_url = https://vpn.example.com
|
|||||||
okta_url = https://example.okta.com
|
okta_url = https://example.okta.com
|
||||||
#okta_url_cert = okta_url.cert
|
#okta_url_cert = okta_url.cert
|
||||||
|
|
||||||
|
#gateway = NEWYORK1-GW # optional gateway name to choose
|
||||||
|
#gateway_url = https://ny1-gw.my.lan # optional gateway url to authenticate
|
||||||
|
another_dance = 0 # second round of authentication
|
||||||
|
|
||||||
username = myuser
|
username = myuser
|
||||||
password = mypass
|
password = mypass
|
||||||
#client_cert = path-to-myusers-client-cert-as-unencrypted-pem-file.pem
|
#client_cert = path-to-myusers-client-cert-as-unencrypted-pem-file.pem
|
||||||
@@ -16,12 +20,10 @@ sms.okta = 0
|
|||||||
#totp.google = ABCDEFGHIJKLMNOP
|
#totp.google = ABCDEFGHIJKLMNOP
|
||||||
#totp.symantec = ABCDEFGHIJKLMNOP
|
#totp.symantec = ABCDEFGHIJKLMNOP
|
||||||
|
|
||||||
gateway = Manual ny1-gw.example.com # optional hardcoded gateway
|
|
||||||
|
|
||||||
#openconnect_cmd = sudo openconnect
|
#openconnect_cmd = sudo openconnect
|
||||||
#openconnect_certs = path-to-a-writeable-filename-in-which-the-script-will-collect-all-involved-server-certs-if-not-set-a-temp-file-is-used-instead
|
#openconnect_certs = path-to-a-writeable-filename-in-which-the-script-will-collect-all-involved-server-certs-if-not-set-a-temp-file-is-used-instead
|
||||||
openconnect_args = # optional arguments to openconnect
|
openconnect_args = # optional arguments to openconnect
|
||||||
execute = 0 # execute openconnect command
|
execute = 0 # execute openconnect command
|
||||||
another_dance = 0 # second round of authentication required
|
|
||||||
bug.nl = 0 # newline work-around for openconnect
|
bug.nl = 0 # newline work-around for openconnect
|
||||||
bug.username = 0 # username work-around for openconnect
|
bug.username = 0 # username work-around for openconnect
|
||||||
|
|||||||
+94
-59
@@ -3,7 +3,7 @@
|
|||||||
"""
|
"""
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2018 Andris Raugulis (moo@arthepsy.eu)
|
Copyright (C) 2018-2020 Andris Raugulis (moo@arthepsy.eu)
|
||||||
Copyright (C) 2018 Nick Lanham (nick@afternight.org)
|
Copyright (C) 2018 Nick Lanham (nick@afternight.org)
|
||||||
Copyright (C) 2019 Aaron Lindsay (aclindsa@gmail.com)
|
Copyright (C) 2019 Aaron Lindsay (aclindsa@gmail.com)
|
||||||
Copyright (C) 2019 Taylor Dean (taylor@makeshift.dev)
|
Copyright (C) 2019 Taylor Dean (taylor@makeshift.dev)
|
||||||
@@ -256,19 +256,20 @@ def send_req(conf, s, name, url, data, **kwargs):
|
|||||||
verify=kwargs.get('verify', True))
|
verify=kwargs.get('verify', True))
|
||||||
hdump = '\n'.join([k + ': ' + v for k, v in sorted(r.headers.items())])
|
hdump = '\n'.join([k + ': ' + v for k, v in sorted(r.headers.items())])
|
||||||
rr = 'status: {0}\n\n{1}\n\n{2}'.format(r.status_code, hdump, r.text)
|
rr = 'status: {0}\n\n{1}\n\n{2}'.format(r.status_code, hdump, r.text)
|
||||||
if r.status_code != 200:
|
can_fail = True if kwargs.get('can_fail', False) else False
|
||||||
|
if not can_fail and r.status_code != 200:
|
||||||
err('{0}.request failed.\n{1}'.format(name, rr))
|
err('{0}.request failed.\n{1}'.format(name, rr))
|
||||||
dbg(conf.get('debug'), '{0}.response'.format(name), rr)
|
dbg(conf.get('debug'), '{0}.response'.format(name), rr)
|
||||||
if do_json:
|
if do_json:
|
||||||
return r.headers, parse_rjson(r)
|
return r.status_code, r.headers, parse_rjson(r)
|
||||||
return r.headers, r.text
|
return r.status_code, r.headers, r.text
|
||||||
|
|
||||||
def paloalto_prelogin(conf, s, gateway=None):
|
def paloalto_prelogin(conf, s, gateway_url=None):
|
||||||
verify = None
|
verify = None
|
||||||
if gateway:
|
if gateway_url:
|
||||||
# 2nd round: use gateway
|
# 2nd round or direct gateway: use gateway
|
||||||
log('prelogin request [gateway]')
|
log('prelogin request [gateway_url]')
|
||||||
url = 'https://{0}/ssl-vpn/prelogin.esp'.format(gateway)
|
url = '{0}/ssl-vpn/prelogin.esp'.format(gateway_url)
|
||||||
verify = conf.get('vpn_url_cert')
|
verify = conf.get('vpn_url_cert')
|
||||||
else:
|
else:
|
||||||
# 1st round: use portal
|
# 1st round: use portal
|
||||||
@@ -276,7 +277,7 @@ def paloalto_prelogin(conf, s, gateway=None):
|
|||||||
url = '{0}/global-protect/prelogin.esp'.format(conf.get('vpn_url'))
|
url = '{0}/global-protect/prelogin.esp'.format(conf.get('vpn_url'))
|
||||||
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:
|
||||||
verify = conf.get('openconnect_certs').name
|
verify = conf.get('openconnect_certs').name
|
||||||
_h, c = send_req(conf, s, 'prelogin', url, {}, get=True, verify=verify)
|
_, _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:
|
||||||
@@ -287,7 +288,7 @@ def paloalto_prelogin(conf, s, gateway=None):
|
|||||||
msg = msg.strip()
|
msg = msg.strip()
|
||||||
else:
|
else:
|
||||||
msg = 'Probably SAML is disabled at the portal? Or you need a certificate? Try another_dance=0 with some concrete gateway instead.'
|
msg = 'Probably SAML is disabled at the portal? Or you need a certificate? Try another_dance=0 with some concrete gateway instead.'
|
||||||
err('did not find saml request. {0}'.format(msg))
|
err('did not find saml request.\n{0}'.format(msg))
|
||||||
if len(saml_req.text.strip()) == 0:
|
if len(saml_req.text.strip()) == 0:
|
||||||
err('empty saml request')
|
err('empty saml request')
|
||||||
try:
|
try:
|
||||||
@@ -301,7 +302,7 @@ def paloalto_prelogin(conf, s, gateway=None):
|
|||||||
def okta_saml(conf, s, saml_xml):
|
def okta_saml(conf, s, saml_xml):
|
||||||
log('okta saml request [okta_url]')
|
log('okta saml request [okta_url]')
|
||||||
url, data = parse_form(saml_xml)
|
url, data = parse_form(saml_xml)
|
||||||
_h, c = send_req(conf, s, 'saml', url, data,
|
_, _h, c = send_req(conf, s, 'saml', url, data,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
redirect_url = get_redirect_url(conf, c, url)
|
redirect_url = get_redirect_url(conf, c, url)
|
||||||
if redirect_url is None:
|
if redirect_url is None:
|
||||||
@@ -321,7 +322,7 @@ def okta_auth(conf, s, stateToken = None):
|
|||||||
} if stateToken is None else {
|
} if stateToken is None else {
|
||||||
'stateToken': stateToken
|
'stateToken': stateToken
|
||||||
}
|
}
|
||||||
_h, j = send_req(conf, s, 'auth', url, data, json=True,
|
_, _h, j = send_req(conf, s, 'auth', url, data, json=True,
|
||||||
verify=conf.get('okta_url_cert'))
|
verify=conf.get('okta_url_cert'))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@@ -345,7 +346,7 @@ def okta_transaction_state(conf, s, j):
|
|||||||
if len(state_token) == 0:
|
if len(state_token) == 0:
|
||||||
err('empty state token')
|
err('empty state token')
|
||||||
data = {'stateToken': state_token}
|
data = {'stateToken': state_token}
|
||||||
_h, j = send_req(conf, s, 'skip', url, data, json=True,
|
_, _h, j = send_req(conf, s, 'skip', url, data, json=True,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
return False, j
|
return False, j
|
||||||
# status: password_expired
|
# status: password_expired
|
||||||
@@ -431,7 +432,7 @@ def okta_mfa_totp(conf, s, factor, state_token):
|
|||||||
'passCode': code
|
'passCode': code
|
||||||
}
|
}
|
||||||
log('mfa {0} totp request: {1} [okta_url]'.format(provider, code))
|
log('mfa {0} totp request: {1} [okta_url]'.format(provider, code))
|
||||||
_h, j = send_req(conf, s, 'totp mfa', factor.get('url'), data, json=True,
|
_, _h, j = send_req(conf, s, 'totp mfa', factor.get('url'), data, json=True,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
return j
|
return j
|
||||||
|
|
||||||
@@ -442,14 +443,14 @@ def okta_mfa_sms(conf, s, factor, state_token):
|
|||||||
'stateToken': state_token
|
'stateToken': state_token
|
||||||
}
|
}
|
||||||
log('mfa {0} sms request [okta_url]'.format(provider))
|
log('mfa {0} sms request [okta_url]'.format(provider))
|
||||||
_h, j = send_req(conf, s, 'sms mfa (1)', factor.get('url'), data, json=True,
|
_, _h, j = send_req(conf, s, 'sms mfa (1)', factor.get('url'), data, json=True,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
code = input('{0} SMS verification code: '.format(provider)).strip()
|
code = input('{0} SMS verification code: '.format(provider)).strip()
|
||||||
if len(code) == 0:
|
if len(code) == 0:
|
||||||
return None
|
return None
|
||||||
data['passCode'] = code
|
data['passCode'] = code
|
||||||
log('mfa {0} sms request [okta_url]'.format(provider))
|
log('mfa {0} sms request [okta_url]'.format(provider))
|
||||||
_h, j = send_req(conf, s, 'sms mfa (2)', factor.get('url'), data, json=True,
|
_, _h, j = send_req(conf, s, 'sms mfa (2)', factor.get('url'), data, json=True,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
return j
|
return j
|
||||||
|
|
||||||
@@ -463,7 +464,7 @@ def okta_mfa_push(conf, s, factor, state_token):
|
|||||||
status = 'MFA_CHALLENGE'
|
status = 'MFA_CHALLENGE'
|
||||||
counter = 0
|
counter = 0
|
||||||
while status == 'MFA_CHALLENGE':
|
while status == 'MFA_CHALLENGE':
|
||||||
_h, j = send_req(conf, s, 'push mfa ({0})'.format(counter),
|
_, _h, j = send_req(conf, s, 'push mfa ({0})'.format(counter),
|
||||||
factor.get('url'), data, json=True,
|
factor.get('url'), data, json=True,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
status = j.get('status', '').strip()
|
status = j.get('status', '').strip()
|
||||||
@@ -485,7 +486,7 @@ def okta_mfa_webauthn(conf, s, factor, state_token):
|
|||||||
data = {
|
data = {
|
||||||
'stateToken': state_token
|
'stateToken': state_token
|
||||||
}
|
}
|
||||||
_h, j = send_req(conf, s, 'webauthn mfa challenge', factor.get('url'), data, json=True,
|
_, _h, j = send_req(conf, s, 'webauthn mfa challenge', factor.get('url'), data, json=True,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
factor = j['_embedded']['factor']
|
factor = j['_embedded']['factor']
|
||||||
profile = factor['profile']
|
profile = factor['profile']
|
||||||
@@ -515,7 +516,7 @@ def okta_mfa_webauthn(conf, s, factor, state_token):
|
|||||||
'authenticatorData': to_u(base64.b64encode(assertion.auth_data))
|
'authenticatorData': to_u(base64.b64encode(assertion.auth_data))
|
||||||
}
|
}
|
||||||
log('mfa {0} signature request [okta_url]'.format(provider))
|
log('mfa {0} signature request [okta_url]'.format(provider))
|
||||||
_h, j = send_req(conf, s, 'uf2 mfa signature', j['_links']['next']['href'], data, json=True,
|
_, _h, j = send_req(conf, s, 'uf2 mfa signature', j['_links']['next']['href'], data, json=True,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
return j
|
return j
|
||||||
|
|
||||||
@@ -535,7 +536,7 @@ 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 {0} [okta_url]'.format(rc))
|
log('okta redirect request {0} [okta_url]'.format(rc))
|
||||||
h, c = send_req(conf, s, 'redirect', url, data,
|
_, h, c = send_req(conf, s, 'redirect', url, data,
|
||||||
verify=conf.get('okta_url_cert'))
|
verify=conf.get('okta_url_cert'))
|
||||||
state_token = get_state_token(conf, c, url)
|
state_token = get_state_token(conf, c, url)
|
||||||
redirect_url = get_redirect_url(conf, c, url)
|
redirect_url = get_redirect_url(conf, c, url)
|
||||||
@@ -549,7 +550,7 @@ def okta_redirect(conf, s, session_token, redirect_url):
|
|||||||
okta_auth(conf, s, state_token)
|
okta_auth(conf, s, state_token)
|
||||||
elif form_url:
|
elif form_url:
|
||||||
log('okta redirect form request [vpn_url]')
|
log('okta redirect form request [vpn_url]')
|
||||||
h, c = send_req(conf, s, 'redirect form', form_url, form_data,
|
_, h, c = send_req(conf, s, 'redirect form', form_url, form_data,
|
||||||
expected_url=conf.get('vpn_url'), verify=conf.get('vpn_url_cert'))
|
expected_url=conf.get('vpn_url'), verify=conf.get('vpn_url_cert'))
|
||||||
saml_username = h.get('saml-username', '').strip()
|
saml_username = h.get('saml-username', '').strip()
|
||||||
prelogin_cookie = h.get('prelogin-cookie', '').strip()
|
prelogin_cookie = h.get('prelogin-cookie', '').strip()
|
||||||
@@ -559,7 +560,7 @@ def okta_redirect(conf, s, session_token, redirect_url):
|
|||||||
dbg(conf.get('debug'), 'saml prop', [saml_auth_status, saml_slo])
|
dbg(conf.get('debug'), 'saml prop', [saml_auth_status, saml_slo])
|
||||||
return saml_username, prelogin_cookie
|
return saml_username, prelogin_cookie
|
||||||
|
|
||||||
def paloalto_getconfig(conf, s, username = None, prelogin_cookie = None):
|
def paloalto_getconfig(conf, s, username = None, prelogin_cookie = None, can_fail = False):
|
||||||
log('getconfig request [vpn_url]')
|
log('getconfig request [vpn_url]')
|
||||||
url = '{0}/global-protect/getconfig.esp'.format(conf.get('vpn_url'))
|
url = '{0}/global-protect/getconfig.esp'.format(conf.get('vpn_url'))
|
||||||
data = {
|
data = {
|
||||||
@@ -581,8 +582,10 @@ def paloalto_getconfig(conf, s, username = None, prelogin_cookie = None):
|
|||||||
'prelogin-cookie': prelogin_cookie or '',
|
'prelogin-cookie': prelogin_cookie or '',
|
||||||
'ipv6-support': 'yes'
|
'ipv6-support': 'yes'
|
||||||
}
|
}
|
||||||
_h, c = send_req(conf, s, 'getconfig', url, data,
|
sc, _h, c = send_req(conf, s, 'getconfig', url, data,
|
||||||
verify=conf.get('vpn_url_cert'))
|
verify=conf.get('vpn_url_cert'), can_fail=can_fail)
|
||||||
|
if sc != 200:
|
||||||
|
return sc, '', ''
|
||||||
x = parse_xml(c)
|
x = parse_xml(c)
|
||||||
xtmp = x.find('.//portal-userauthcookie')
|
xtmp = x.find('.//portal-userauthcookie')
|
||||||
if xtmp is None:
|
if xtmp is None:
|
||||||
@@ -590,24 +593,26 @@ def paloalto_getconfig(conf, s, username = None, prelogin_cookie = None):
|
|||||||
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')
|
||||||
gateways = set()
|
gateways = {}
|
||||||
xtmp = x.find('.//gateways//external//list')
|
xtmp = x.find('.//gateways//external//list')
|
||||||
if xtmp is not None:
|
if xtmp is not None:
|
||||||
for entry in xtmp:
|
for entry in xtmp:
|
||||||
gateways.add(entry.get('name'))
|
gw_name = entry.get('name')
|
||||||
|
gw_desc = (entry.xpath('./description/text()') or [''])[0]
|
||||||
|
gateways[gw_name] = gw_desc
|
||||||
xtmp = x.find('.//root-ca')
|
xtmp = x.find('.//root-ca')
|
||||||
if xtmp is not None:
|
if xtmp is not None:
|
||||||
for entry in xtmp:
|
for entry in xtmp:
|
||||||
cert = entry.find('.//cert').text
|
cert = entry.find('.//cert').text
|
||||||
conf['openconnect_certs'].write(to_b(cert))
|
conf['openconnect_certs'].write(to_b(cert))
|
||||||
conf['openconnect_certs'].flush()
|
conf['openconnect_certs'].flush()
|
||||||
return portal_userauthcookie, gateways
|
return 200, portal_userauthcookie, gateways
|
||||||
|
|
||||||
# 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, gateway, saml_xml):
|
def okta_saml_2(conf, s, gateway_url, saml_xml):
|
||||||
log('okta saml request (2) [okta_url]')
|
log('okta saml request (2) [okta_url]')
|
||||||
url, data = parse_form(saml_xml)
|
url, data = parse_form(saml_xml)
|
||||||
h, c = send_req(conf, s, 'okta saml request (2)', url, data,
|
_, h, c = send_req(conf, s, 'okta saml request (2)', url, data,
|
||||||
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
expected_url=conf.get('okta_url'), verify=conf.get('okta_url_cert'))
|
||||||
xhtml = parse_html(c)
|
xhtml = parse_html(c)
|
||||||
url, data = parse_form(xhtml)
|
url, data = parse_form(xhtml)
|
||||||
@@ -616,8 +621,8 @@ def okta_saml_2(conf, s, gateway, saml_xml):
|
|||||||
verify = None
|
verify = None
|
||||||
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:
|
||||||
verify = conf.get('openconnect_certs').name
|
verify = conf.get('openconnect_certs').name
|
||||||
h, c = send_req(conf, s, 'okta redirect form (2)', url, data,
|
_, h, c = send_req(conf, s, 'okta redirect form (2)', url, data,
|
||||||
expected_url='https://{0}'.format(gateway), verify=verify)
|
expected_url=gateway_url, verify=verify)
|
||||||
saml_username = h.get('saml-username', '').strip()
|
saml_username = h.get('saml-username', '').strip()
|
||||||
if len(saml_username) == 0:
|
if len(saml_username) == 0:
|
||||||
err('saml-username empty')
|
err('saml-username empty')
|
||||||
@@ -627,6 +632,28 @@ def okta_saml_2(conf, s, gateway, saml_xml):
|
|||||||
|
|
||||||
return saml_username, prelogin_cookie
|
return saml_username, prelogin_cookie
|
||||||
|
|
||||||
|
def output_gateways(gateways):
|
||||||
|
print("Gateways:")
|
||||||
|
for k in sorted(gateways.keys()):
|
||||||
|
print("\t{0} {1}".format(k, gateways[k]))
|
||||||
|
|
||||||
|
def choose_gateway_url(conf, gateways):
|
||||||
|
gateway_url = conf.get('gateway_url', '').strip()
|
||||||
|
if gateway_url:
|
||||||
|
return gateway_url
|
||||||
|
if len(gateways) == 0:
|
||||||
|
err('no available gateways')
|
||||||
|
gateway_name = conf.get('gateway', '').strip()
|
||||||
|
gateway_host = None
|
||||||
|
for k in gateways.keys():
|
||||||
|
if gateways[k] == gateway_name:
|
||||||
|
gateway_host = k
|
||||||
|
break
|
||||||
|
if not gateway_host:
|
||||||
|
# this just grabs an arbitrary gateway
|
||||||
|
gateway_host = gateways.keys().pop()
|
||||||
|
return 'https://{0}'.format(gateway_host)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="""
|
parser = argparse.ArgumentParser(description="""
|
||||||
@@ -638,7 +665,7 @@ def main():
|
|||||||
parser.add_argument('--gpg-decrypt', action='store_true',
|
parser.add_argument('--gpg-decrypt', action='store_true',
|
||||||
help='use gpg and settings from gpg-home to decrypt gpg encrypted conf_file')
|
help='use gpg and settings from gpg-home to decrypt gpg encrypted conf_file')
|
||||||
parser.add_argument('--gpg-home', default=os.path.expanduser('~/.gnupg'))
|
parser.add_argument('--gpg-home', default=os.path.expanduser('~/.gnupg'))
|
||||||
parser.add_argument('--show-list-of-gateways', default=False, action='store_true',
|
parser.add_argument('--list-gateways', default=False, action='store_true',
|
||||||
help='get list of gateways from portal')
|
help='get list of gateways from portal')
|
||||||
parser.add_argument('--quiet', default=False, action='store_true',
|
parser.add_argument('--quiet', default=False, action='store_true',
|
||||||
help='disable verbose logging')
|
help='disable verbose logging')
|
||||||
@@ -679,50 +706,58 @@ def main():
|
|||||||
if conf.get('client_cert'):
|
if conf.get('client_cert'):
|
||||||
s.cert = conf.get('client_cert')
|
s.cert = conf.get('client_cert')
|
||||||
|
|
||||||
if args.show_list_of_gateways:
|
if args.list_gateways:
|
||||||
userauthcookie, gateways = paloalto_getconfig(conf, s)
|
log('listing gateways')
|
||||||
print("Gateways:")
|
sc, _, gateways = paloalto_getconfig(conf, s, can_fail=True)
|
||||||
for gateway in sorted(gateways):
|
if sc == 200:
|
||||||
print(" ", gateway)
|
output_gateways(gateways)
|
||||||
sys.exit(0)
|
return 0
|
||||||
|
else:
|
||||||
|
log('gateway list requires authentication')
|
||||||
|
|
||||||
another_dance = conf.get('another_dance', '').lower() in ['1', 'true']
|
another_dance = conf.get('another_dance', '').lower() in ['1', 'true']
|
||||||
|
gateway_url = conf.get('gateway_url', '').strip()
|
||||||
|
gateway_name = conf.get('gateway', '').strip()
|
||||||
|
|
||||||
if conf.get('gateway'):
|
if gateway_url and not another_dance:
|
||||||
gateway = conf.get('gateway').strip()
|
vpn_url = gateway_url
|
||||||
else:
|
|
||||||
gateway = None
|
|
||||||
|
|
||||||
if gateway and not another_dance:
|
|
||||||
vpn_url = 'https://{0}'.format(gateway)
|
|
||||||
if vpn_url != conf.get('vpn_url'):
|
if vpn_url != conf.get('vpn_url'):
|
||||||
log('Discarding \'vpn_url\', as concrete gateway is given and another_dance = 0')
|
log('Discarding \'vpn_url\', as concrete \'gateway_url\' is given and another_dance = 0')
|
||||||
conf['vpn_url'] = vpn_url
|
conf['vpn_url'] = vpn_url
|
||||||
|
|
||||||
userauthcookie = None
|
userauthcookie = None
|
||||||
|
|
||||||
if another_dance or not gateway:
|
if another_dance or not gateway_url:
|
||||||
saml_xml = paloalto_prelogin(conf, s)
|
saml_xml = paloalto_prelogin(conf, s)
|
||||||
else:
|
else:
|
||||||
saml_xml = paloalto_prelogin(conf, s, gateway)
|
saml_xml = paloalto_prelogin(conf, s, gateway_url)
|
||||||
|
|
||||||
redirect_url = okta_saml(conf, s, saml_xml)
|
redirect_url = okta_saml(conf, s, saml_xml)
|
||||||
token = okta_auth(conf, s)
|
token = okta_auth(conf, s)
|
||||||
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)
|
||||||
if another_dance or not gateway:
|
if args.list_gateways:
|
||||||
userauthcookie, gateways = paloalto_getconfig(conf, s, saml_username, prelogin_cookie)
|
log('listing gateways')
|
||||||
if not gateway and len(gateways):
|
sc, _, gateways = paloalto_getconfig(conf, s, saml_username, prelogin_cookie)
|
||||||
gateway = gateways.pop() # this just grabs an arbitrary gateway
|
if sc == 200:
|
||||||
|
output_gateways(gateways)
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
err('could not list gateways')
|
||||||
|
|
||||||
|
if another_dance or not gateway_url:
|
||||||
|
_, userauthcookie, gateways = paloalto_getconfig(conf, s, saml_username, prelogin_cookie)
|
||||||
|
gateway_url = choose_gateway_url(conf, gateways)
|
||||||
|
|
||||||
log('portal-userauthcookie: {0}'.format(userauthcookie))
|
log('portal-userauthcookie: {0}'.format(userauthcookie))
|
||||||
log('gateway: {0}'.format(gateway))
|
log('gateway: {0}'.format(gateway_url))
|
||||||
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))
|
||||||
|
|
||||||
if another_dance:
|
if another_dance:
|
||||||
# 1st step: dance with the portal, 2nd step: dance with the gateway
|
# 1st step: dance with the portal, 2nd step: dance with the gateway
|
||||||
saml_xml = paloalto_prelogin(conf, s, gateway)
|
saml_xml = paloalto_prelogin(conf, s, gateway_url)
|
||||||
saml_username, prelogin_cookie = okta_saml_2(conf, s, gateway, saml_xml)
|
saml_username, prelogin_cookie = okta_saml_2(conf, s, gateway_url, saml_xml)
|
||||||
log('saml-username (2): {0}'.format(saml_username))
|
log('saml-username (2): {0}'.format(saml_username))
|
||||||
log('prelogin-cookie (2): {0}'.format(prelogin_cookie))
|
log('prelogin-cookie (2): {0}'.format(prelogin_cookie))
|
||||||
|
|
||||||
@@ -744,15 +779,15 @@ def main():
|
|||||||
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,
|
cmd = cmd.format(username, cookie_type,
|
||||||
'https://{0}'.format(gateway) if conf.get('another_dance', '').lower() in ['1', 'true'] else conf.get('vpn_url'))
|
gateway_url 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(gateway) > 0:
|
if len(gateway_name) > 0:
|
||||||
pcmd = 'printf \'' + bugs + '{0}\\n{1}\''.format(cookie, gateway)
|
pcmd = 'printf \'' + bugs + '{0}\\n{1}\''.format(cookie, gateway_name)
|
||||||
else:
|
else:
|
||||||
pcmd = 'printf \'' + bugs + '{0}\''.format(cookie)
|
pcmd = 'printf \'' + bugs + '{0}\''.format(cookie)
|
||||||
print()
|
print()
|
||||||
|
|||||||
Reference in New Issue
Block a user