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

Source Code for Module logilab.common.urllib2ext

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