-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathhtml_roles_fetcher.py
136 lines (117 loc) · 4.09 KB
/
html_roles_fetcher.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import logging
import os
from platform import system
import requests
try:
import cookielib
except ImportError:
# python 3
import http.cookiejar as cookielib
_auth_provider = None
_headers = {'Accept-Language': 'en'}
try:
if system() == 'Windows':
from requests_negotiate_sspi import HttpNegotiateAuth
_auth_provider = HttpNegotiateAuth
else:
from requests_kerberos import HTTPKerberosAuth, OPTIONAL
_auth_provider = HTTPKerberosAuth
except ImportError:
pass
# The initial URL that starts the authentication process.
_IDP_ENTRY_URL = 'https://{}/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp={}'
def fetch_html_encoded_roles(
adfs_host,
adfs_cookie_location,
ssl_verification_enabled,
provider_id,
adfs_ca_bundle=None,
username=None,
password=None,
sspi=None,
u2f_trigger_default=None,
):
# Support for Kerberos SSO on Windows via requests_negotiate_sspi
# also requires tricking the server into thinking we're using IEq
# so that it servers up a redirect to the IWA page.
if sspi:
_headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) Gecko/20100101 Firefox/60.0'
# Initiate session handler
session = requests.Session()
# LWPCookieJar has an issue on Windows when cookies have an 'expires' date too far in the future and they are converted from timestamp to datetime.
# MozillaCookieJar works because it does not convert the timestamps.
# Duo uses 253402300799 for its cookies which translates into 9999-12-31T23:59:59Z.
# Windows 64bit maximum date is 3000-12-31T23:59:59Z, and 32bit is 2038-01-18T23:59:59Z.
session.cookies = cookielib.MozillaCookieJar(filename=adfs_cookie_location)
try:
have_creds = (username and password) or (_auth_provider and sspi)
session.cookies.load(ignore_discard=not(have_creds))
except IOError as e:
error_message = getattr(e, 'message', e)
logging.debug(
u'Attempt to load authentication cookies into session failed. '
u'Re-authentication will be performed. '
u'The error: {}'.format(error_message)
)
if _auth_provider and sspi:
domain = None
if username:
if '@' in username: # User principal name (UPN) format
username, domain = username.split('@', 1)
elif '\\' in username: # Down-level logon name format
domain, username = username.split('\\', 1)
if system() == 'Windows':
auth = _auth_provider(username, password, domain)
elif username and domain:
auth = _auth_provider(principal="{}@{}".format(username, domain), mutual_authentication=OPTIONAL)
else:
auth = _auth_provider(mutual_authentication=OPTIONAL)
data = None
else:
auth = None
data={
'UserName': username,
'Password': password,
'AuthMethod': 'FormsAuthentication'
}
if adfs_ca_bundle:
ssl_verification = adfs_ca_bundle
else:
ssl_verification = ssl_verification_enabled
# Opens the initial AD FS URL and follows all of the HTTP302 redirects
authentication_url = _IDP_ENTRY_URL.format(adfs_host, provider_id)
response = session.post(
authentication_url,
verify=ssl_verification,
headers=_headers,
auth=auth,
data=data
)
logging.debug(u'''Request:
* url: {}
* headers: {}
Response:
* status: {}
* headers: {}
* body: {}
'''.format(
authentication_url,
response.request.headers,
response.status_code,
response.headers,
response.text
))
if response.status_code >= 400:
session.cookies.clear()
mask = os.umask(0o177)
try:
session.cookies.save(ignore_discard=True)
finally:
os.umask(mask)
del auth
del data
del username
password = '###################################################'
del password
# Decode the response
return response, session