Package common :: Module urllib2ext
[frames] | no frames]

Source Code for Module common.urllib2ext

 1  import logging 
 2  import urllib.request, urllib.error, urllib.parse 
 3   
 4  import kerberos as krb 
 5   
6 -class GssapiAuthError(Exception):
7 """raised on error during authentication process"""
8 9 import re 10 RGX = re.compile('(?:.*,)*\s*Negotiate\s*([^,]*),?', re.I) 11
12 -def get_negociate_value(headers):
13 for authreq in headers.getheaders('www-authenticate'): 14 match = RGX.search(authreq) 15 if match: 16 return match.group(1)
17
18 -class HTTPGssapiAuthHandler(urllib.request.BaseHandler):
19 """Negotiate HTTP authentication using context from GSSAPI""" 20 21 handler_order = 400 # before Digest Auth 22
23 - def __init__(self):
24 self._reset()
25
26 - def _reset(self):
27 self._retried = 0 28 self._context = None
29
30 - def clean_context(self):
31 if self._context is not None: 32 krb.authGSSClientClean(self._context)
33
34 - def http_error_401(self, req, fp, code, msg, headers):
35 try: 36 if self._retried > 5: 37 raise urllib.error.HTTPError(req.get_full_url(), 401, 38 "negotiate auth failed", headers, None) 39 self._retried += 1 40 logging.debug('gssapi handler, try %s' % self._retried) 41 negotiate = get_negociate_value(headers) 42 if negotiate is None: 43 logging.debug('no negociate found in a www-authenticate header') 44 return None 45 logging.debug('HTTPGssapiAuthHandler: negotiate 1 is %r' % negotiate) 46 result, self._context = krb.authGSSClientInit("HTTP@%s" % req.get_host()) 47 if result < 1: 48 raise GssapiAuthError("HTTPGssapiAuthHandler: init failed with %d" % result) 49 result = krb.authGSSClientStep(self._context, negotiate) 50 if result < 0: 51 raise GssapiAuthError("HTTPGssapiAuthHandler: step 1 failed with %d" % result) 52 client_response = krb.authGSSClientResponse(self._context) 53 logging.debug('HTTPGssapiAuthHandler: client response is %s...' % client_response[:10]) 54 req.add_unredirected_header('Authorization', "Negotiate %s" % client_response) 55 server_response = self.parent.open(req) 56 negotiate = get_negociate_value(server_response.info()) 57 if negotiate is None: 58 logging.warning('HTTPGssapiAuthHandler: failed to authenticate server') 59 else: 60 logging.debug('HTTPGssapiAuthHandler negotiate 2: %s' % negotiate) 61 result = krb.authGSSClientStep(self._context, negotiate) 62 if result < 1: 63 raise GssapiAuthError("HTTPGssapiAuthHandler: step 2 failed with %d" % result) 64 return server_response 65 except GssapiAuthError as exc: 66 logging.error(repr(exc)) 67 finally: 68 self.clean_context() 69 self._reset()
70 71 if __name__ == '__main__': 72 import sys 73 # debug 74 import http.client 75 http.client.HTTPConnection.debuglevel = 1 76 http.client.HTTPSConnection.debuglevel = 1 77 # debug 78 import logging 79 logging.basicConfig(level=logging.DEBUG) 80 # handle cookies 81 import http.cookiejar 82 cj = http.cookiejar.CookieJar() 83 ch = urllib.request.HTTPCookieProcessor(cj) 84 # test with url sys.argv[1] 85 h = HTTPGssapiAuthHandler() 86 response = urllib.request.build_opener(h, ch).open(sys.argv[1]) 87 print('\nresponse: %s\n--------------\n' % response.code, response.info()) 88