def ntlmAuth(self, connection, headers): self.logger.debug("Using NTLM authentication") # Use ntlm headers[ "Authorization"] = "Negotiate %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE( self.username, self.type1_flags) connection.request("POST", self.url, headers=headers) response = connection.getresponse() response.read() if response.status != 401: raise HyperVAuthFailed("NTLM negotiation failed") auth_header = response.getheader("WWW-Authenticate", "") if auth_header == "": raise HyperVAuthFailed("NTLM negotiation failed") nego, challenge = auth_header.split(" ") if nego != "Negotiate": print >> sys.stderr, "Wrong header: ", auth_header sys.exit(1) nonce, flags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(challenge) headers[ "Authorization"] = "Negotiate %s" % ntlm.create_NTLM_AUTHENTICATE_MESSAGE( nonce, self.username, self.domainname, self.password, flags) connection.request("POST", self.url, headers=headers) response = connection.getresponse() response.read() if response.status == 200: headers.pop("Authorization") self.logger.debug("NTLM authentication successful") else: raise HyperVAuthFailed("NTLM negotiation failed")
def retry_using_http_NTLM_auth(self, req, auth_header_field, realm, headers): user, pw = self.passwd.find_user_password(realm, req.get_full_url()) if pw is not None: user_parts = user.split('\\', 1) if len(user_parts) == 1: UserName = user_parts[0] DomainName = '' type1_flags = ntlm.NTLM_TYPE1_FLAGS & ~ntlm.NTLM_NegotiateOemDomainSupplied else: DomainName = user_parts[0].upper() UserName = user_parts[1] type1_flags = ntlm.NTLM_TYPE1_FLAGS # ntlm secures a socket, so we must use the same socket for the complete handshake headers = dict(req.headers) headers.update(req.unredirected_hdrs) auth = 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(user, type1_flags) if req.headers.get(self.auth_header, None) == auth: return None headers[self.auth_header] = auth host = req.get_host() if not host: raise urllib.request.URLError('no host given') h = None if req.get_full_url().startswith('https://'): h = http.client.HTTPSConnection(host) # will parse host:port else: h = http.client.HTTPConnection(host) # will parse host:port # we must keep the connection because NTLM authenticates the connection, not single requests headers["Connection"] = "Keep-Alive" headers = dict((name.title(), val) for name, val in list(headers.items())) h.request(req.get_method(), req.get_selector(), req.data, headers) r = h.getresponse() r.begin() r._safe_read(int(r.getheader('content-length'))) try: if r.getheader('set-cookie'): # this is important for some web applications that store authentication-related info in cookies (it took a long time to figure out) headers['Cookie'] = r.getheader('set-cookie') except TypeError: pass r.fp = None # remove the reference to the socket, so that it can not be closed by the response object (we want to keep the socket open) auth_header_value = r.getheader(auth_header_field, None) (ServerChallenge, NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value[5:]) auth = 'NTLM %s' % ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, UserName, DomainName, pw, NegotiateFlags) headers[self.auth_header] = auth headers["Connection"] = "Close" headers = dict((name.title(), val) for name, val in list(headers.items())) try: h.request(req.get_method(), req.get_selector(), req.data, headers) # none of the configured handlers are triggered, for example redirect-responses are not handled! response = h.getresponse() def notimplemented(): raise NotImplementedError response.readline = notimplemented return addinfourl(response, response.msg, req.get_full_url()) except socket.error as err: raise urllib.request.URLError(err) else: return None
def ntlmAuth(self, connection, headers): self.logger.debug("Using NTLM authentication") # Use ntlm headers["Authorization"] = "Negotiate %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.username, self.type1_flags) connection.request("POST", self.url, headers=headers) response = connection.getresponse() response.read() if response.status != 401: raise HyperVAuthFailed("NTLM negotiation failed") auth_header = response.getheader("WWW-Authenticate", "") if auth_header == "": raise HyperVAuthFailed("NTLM negotiation failed") nego, challenge = auth_header.split(" ") if nego != "Negotiate": print >>sys.stderr, "Wrong header: ", auth_header sys.exit(1) nonce, flags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(challenge) headers["Authorization"] = "Negotiate %s" % ntlm.create_NTLM_AUTHENTICATE_MESSAGE(nonce, self.username, self.domainname, self.password, flags) connection.request("POST", self.url, headers=headers) response = connection.getresponse() response.read() if response.status == 200: headers.pop("Authorization") self.logger.debug("NTLM authentication successful") else: raise HyperVAuthFailed("NTLM negotiation failed")
def retry_using_http_NTLM_auth(self, req, auth_header_field, realm, headers): user, pw = self.passwd.find_user_password(realm, req.get_full_url()) if pw is not None: user_parts = user.split('\\', 1) if len(user_parts) == 1: UserName = user_parts[0] DomainName = '' type1_flags = ntlm.NTLM_TYPE1_FLAGS & ~ntlm.NTLM_NegotiateOemDomainSupplied else: DomainName = user_parts[0].upper() UserName = user_parts[1] type1_flags = ntlm.NTLM_TYPE1_FLAGS # ntlm secures a socket, so we must use the same socket for the complete handshake headers = dict(req.headers) headers.update(req.unredirected_hdrs) auth = 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(user, type1_flags) if req.headers.get(self.auth_header, None) == auth: return None headers[self.auth_header] = auth host = req.get_host() if not host: raise urllib2.URLError('no host given') h = None if req.get_full_url().startswith('https://'): h = httplib.HTTPSConnection(host) # will parse host:port else: h = httplib.HTTPConnection(host) # will parse host:port h.set_debuglevel(self._debuglevel) # we must keep the connection because NTLM authenticates the connection, not single requests headers["Connection"] = "Keep-Alive" headers = dict((name.title(), val) for name, val in headers.items()) h.request(req.get_method(), req.get_selector(), req.data, headers) r = h.getresponse() r.begin() r._safe_read(int(r.getheader('content-length'))) if r.getheader('set-cookie'): # this is important for some web applications that store authentication-related info in cookies (it took a long time to figure out) headers['Cookie'] = r.getheader('set-cookie') r.fp = None # remove the reference to the socket, so that it can not be closed by the response object (we want to keep the socket open) auth_header_value = r.getheader(auth_header_field, None) (ServerChallenge, NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value[5:]) auth = 'NTLM %s' % ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, UserName, DomainName, pw, NegotiateFlags) headers[self.auth_header] = auth headers["Connection"] = "Close" headers = dict((name.title(), val) for name, val in headers.items()) try: h.request(req.get_method(), req.get_selector(), req.data, headers) # none of the configured handlers are triggered, for example redirect-responses are not handled! response = h.getresponse() def notimplemented(): raise NotImplementedError response.readline = notimplemented infourl = addinfourl(response, response.msg, req.get_full_url()) infourl.code = response.status infourl.msg = response.reason return infourl except socket.error, err: raise urllib2.URLError(err)
def __call__(self, response): if self.phase == 0: self.phase = 1 return ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.username) else: assert self.phase == 1 self.phase = 2 # ... finished challenge, flags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(response) user_parts = self.username.split("\\", 1) return ntlm.create_NTLM_AUTHENTICATE_MESSAGE(challenge, user_parts[1], user_parts[0], self.password, flags)
def auth_ntlm(username, password, domain): try: import ntlm except ImportError: raise NotAvailable def response(challenge): if challenge.startswith('+ '): challenge = challenge[2:] (ServerChallenge, NegotiateFlags) = \ ntlm.parse_NTLM_CHALLENGE_MESSAGE(challenge) return ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, username, domain, password, NegotiateFlags) init = ntlm.create_NTLM_NEGOTIATE_MESSAGE(username) return init, response
def ntlm_authenticate(smtp, username, password): """Example: >>> import smtplib >>> smtp = smtplib.SMTP("my.smtp.server") >>> smtp.ehlo() >>> ntlm_authenticate(smtp, r"DOMAIN\username", "password") """ code, response = smtp.docmd("AUTH", "NTLM " + asbase64(ntlm.create_NTLM_NEGOTIATE_MESSAGE(username))) if code != 334: raise SMTPException("Server did not respond as expected to NTLM negotiate message") challenge, flags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(decodestring(response)) user_parts = username.split("\\", 1) code, response = smtp.docmd("", asbase64(ntlm.create_NTLM_AUTHENTICATE_MESSAGE(challenge, user_parts[1], user_parts[0], password, flags))) if code != 235: raise SMTPAuthenticationError(code, response)
def ntlm_authenticate(smtp, username, password, domain_name=None): code, response = smtp.docmd( "AUTH", "NTLM " + ntlm.create_NTLM_NEGOTIATE_MESSAGE(username).decode('utf-8')) if code != 334: raise SMTPException( "Server did not respond as exected to NTLM negotiate message") challenge, flags = ntlm.parse_NTLM_CHALLENGE_MESSAGE( response.decode('utf-8')) code, response = smtp.docmd( "", ntlm.create_NTLM_AUTHENTICATE_MESSAGE(challenge, username, domain_name, password, flags).decode('utf-8')) if code != 235: raise SMTPAuthenticationError(code, response)
def retry_using_http_NTLM_auth(self, req, auth_header_field, realm, headers): user, pw = self.passwd.find_user_password(realm, req.get_full_url()) if pw is not None: # ntlm secures a socket, so we must use the same socket for the complete handshake headers = dict(req.headers) headers.update(req.unredirected_hdrs) auth = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE(user) if req.headers.get(self.auth_header, None) == auth: return None headers[self.auth_header] = auth host = req.get_host() if not host: raise urllib2.URLError("no host given") h = None if req.get_full_url().startswith("https://"): h = httplib.HTTPSConnection(host) # will parse host:port else: h = httplib.HTTPConnection(host) # will parse host:port h.set_debuglevel(self._debuglevel) # we must keep the connection because NTLM authenticates the connection, not single requests headers["Connection"] = "Keep-Alive" headers = dict((name.title(), val) for name, val in headers.items()) h.request(req.get_method(), req.get_selector(), req.data, headers) r = h.getresponse() r.begin() r._safe_read(int(r.getheader("content-length"))) if r.getheader("set-cookie"): # this is important for some web applications that store authentication-related info in cookies (it took a long time to figure out) headers["Cookie"] = r.getheader("set-cookie") r.fp = ( None ) # remove the reference to the socket, so that it can not be closed by the response object (we want to keep the socket open) auth_header_value = r.getheader(auth_header_field, None) (ServerChallenge, NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value[5:]) if "\\" in user: user_parts = user.split("\\", 1) DomainName = user_parts[0].upper() UserName = user_parts[1] else: DomainName = "" UserName = user auth = "NTLM %s" % ntlm.create_NTLM_AUTHENTICATE_MESSAGE( ServerChallenge, UserName, DomainName, pw, NegotiateFlags ) headers[self.auth_header] = auth headers["Connection"] = "Close" headers = dict((name.title(), val) for name, val in headers.items()) try: h.request(req.get_method(), req.get_selector(), req.data, headers) # none of the configured handlers are triggered, for example redirect-responses are not handled! response = h.getresponse() def notimplemented(): raise NotImplementedError response.readline = notimplemented infourl = addinfourl(response, response.msg, req.get_full_url()) infourl.code = response.status infourl.msg = response.reason return infourl except socket.error, err: raise urllib2.URLError(err)
def retry_using_http_NTLM_auth(self, req, auth_header_field, realm, headers): user, pw = self.passwd.find_user_password(realm, req.get_full_url()) if pw is not None: # ntlm secures a socket, so we must use the same socket for the complete handshake headers = dict(req.headers) headers.update(req.unredirected_hdrs) # auth = 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(user) # auth = 'NTLM %s' % asbase64(ntlm.create_NTLM_NEGOTIATE_MESSAGE(user, type1_flags)) auth = 'NTLM %s' % asbase64(ntlm.create_NTLM_NEGOTIATE_MESSAGE(user)) if req.headers.get(self.auth_header, None) == auth: return None headers[self.auth_header] = auth host = req.get_host() if not host: raise urllib2.URLError('no host given') h = None if req.get_full_url().startswith('https://'): h = httplib.HTTPSConnection(host) # will parse host:port else: h = httplib.HTTPConnection(host) # will parse host:port h.set_debuglevel(self._debuglevel) # we must keep the connection because NTLM authenticates the connection, not single requests headers["Connection"] = "Keep-Alive" headers = dict((name.title(), val) for name, val in headers.items()) h.request(req.get_method(), req.get_selector(), req.data, headers) r = h.getresponse() r.begin() r._safe_read(int(r.getheader('content-length'))) if r.getheader('set-cookie'): # this is important for some web applications that store authentication-related info in cookies (it took a long time to figure out) headers['Cookie'] = r.getheader('set-cookie') r.fp = None # remove the reference to the socket, so that it can not be closed by the response object (we want to keep the socket open) auth_header_value = r.getheader(auth_header_field, None) # some Exchange servers send two WWW-Authenticate headers, one with the NTLM challenge # and another with the 'Negotiate' keyword - make sure we operate on the right one m = re.match('(NTLM [A-Za-z0-9+\-/=]+)', auth_header_value) if m: auth_header_value, = m.groups() #(ServerChallenge, NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value[5:]) (ServerChallenge, NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE(base64.decodestring(auth_header_value[5:])) user_parts = user.split('\\', 1) if len(user_parts) == 1: UserName = user_parts[0] DomainName = '' else: DomainName = user_parts[0].upper() UserName = user_parts[1] # auth = 'NTLM %s' % ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, UserName, DomainName, pw, NegotiateFlags) auth = 'NTLM %s' % asbase64(ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, UserName, DomainName, pw, NegotiateFlags)) headers[self.auth_header] = auth headers["Connection"] = "Close" headers = dict((name.title(), val) for name, val in headers.items()) try: h.request(req.get_method(), req.get_selector(), req.data, headers) # none of the configured handlers are triggered, for example redirect-responses are not handled! response = h.getresponse() def notimplemented(): raise NotImplementedError response.readline = notimplemented infourl = addinfourl(response, response.msg, req.get_full_url()) infourl.code = response.status infourl.msg = response.reason return infourl except socket.error, err: raise urllib2.URLError(err)