Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hhhrrrttt222111
GitHub Repository: hhhrrrttt222111/Dorkify
Path: blob/master/venv/Lib/site-packages/urllib3/contrib/ntlmpool.py
811 views
1
"""
2
NTLM authenticating pool, contributed by erikcederstran
3
4
Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
5
"""
6
from __future__ import absolute_import
7
8
from logging import getLogger
9
from ntlm import ntlm
10
11
from .. import HTTPSConnectionPool
12
from ..packages.six.moves.http_client import HTTPSConnection
13
14
15
log = getLogger(__name__)
16
17
18
class NTLMConnectionPool(HTTPSConnectionPool):
19
"""
20
Implements an NTLM authentication version of an urllib3 connection pool
21
"""
22
23
scheme = "https"
24
25
def __init__(self, user, pw, authurl, *args, **kwargs):
26
"""
27
authurl is a random URL on the server that is protected by NTLM.
28
user is the Windows user, probably in the DOMAIN\\username format.
29
pw is the password for the user.
30
"""
31
super(NTLMConnectionPool, self).__init__(*args, **kwargs)
32
self.authurl = authurl
33
self.rawuser = user
34
user_parts = user.split("\\", 1)
35
self.domain = user_parts[0].upper()
36
self.user = user_parts[1]
37
self.pw = pw
38
39
def _new_conn(self):
40
# Performs the NTLM handshake that secures the connection. The socket
41
# must be kept open while requests are performed.
42
self.num_connections += 1
43
log.debug(
44
"Starting NTLM HTTPS connection no. %d: https://%s%s",
45
self.num_connections,
46
self.host,
47
self.authurl,
48
)
49
50
headers = {"Connection": "Keep-Alive"}
51
req_header = "Authorization"
52
resp_header = "www-authenticate"
53
54
conn = HTTPSConnection(host=self.host, port=self.port)
55
56
# Send negotiation message
57
headers[req_header] = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE(
58
self.rawuser
59
)
60
log.debug("Request headers: %s", headers)
61
conn.request("GET", self.authurl, None, headers)
62
res = conn.getresponse()
63
reshdr = dict(res.getheaders())
64
log.debug("Response status: %s %s", res.status, res.reason)
65
log.debug("Response headers: %s", reshdr)
66
log.debug("Response data: %s [...]", res.read(100))
67
68
# Remove the reference to the socket, so that it can not be closed by
69
# the response object (we want to keep the socket open)
70
res.fp = None
71
72
# Server should respond with a challenge message
73
auth_header_values = reshdr[resp_header].split(", ")
74
auth_header_value = None
75
for s in auth_header_values:
76
if s[:5] == "NTLM ":
77
auth_header_value = s[5:]
78
if auth_header_value is None:
79
raise Exception(
80
"Unexpected %s response header: %s" % (resp_header, reshdr[resp_header])
81
)
82
83
# Send authentication message
84
ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(
85
auth_header_value
86
)
87
auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(
88
ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags
89
)
90
headers[req_header] = "NTLM %s" % auth_msg
91
log.debug("Request headers: %s", headers)
92
conn.request("GET", self.authurl, None, headers)
93
res = conn.getresponse()
94
log.debug("Response status: %s %s", res.status, res.reason)
95
log.debug("Response headers: %s", dict(res.getheaders()))
96
log.debug("Response data: %s [...]", res.read()[:100])
97
if res.status != 200:
98
if res.status == 401:
99
raise Exception("Server rejected request: wrong username or password")
100
raise Exception("Wrong server response: %s %s" % (res.status, res.reason))
101
102
res.fp = None
103
log.debug("Connection established")
104
return conn
105
106
def urlopen(
107
self,
108
method,
109
url,
110
body=None,
111
headers=None,
112
retries=3,
113
redirect=True,
114
assert_same_host=True,
115
):
116
if headers is None:
117
headers = {}
118
headers["Connection"] = "Keep-Alive"
119
return super(NTLMConnectionPool, self).urlopen(
120
method, url, body, headers, retries, redirect, assert_same_host
121
)
122
123