summaryrefslogtreecommitdiffstats
path: root/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'main.py')
-rwxr-xr-xmain.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/main.py b/main.py
index 6ec7158d..36617762 100755
--- a/main.py
+++ b/main.py
@@ -31,6 +31,11 @@ else:
31 urllib = imp.new_module('urllib') 31 urllib = imp.new_module('urllib')
32 urllib.request = urllib2 32 urllib.request = urllib2
33 33
34try:
35 import kerberos
36except ImportError:
37 kerberos = None
38
34from trace import SetTrace 39from trace import SetTrace
35from git_command import git, GitCommand 40from git_command import git, GitCommand
36from git_config import init_ssh, close_ssh 41from git_config import init_ssh, close_ssh
@@ -332,6 +337,86 @@ class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
332 self.retried = 0 337 self.retried = 0
333 raise 338 raise
334 339
340class _KerberosAuthHandler(urllib.request.BaseHandler):
341 def __init__(self):
342 self.retried = 0
343 self.context = None
344 self.handler_order = urllib.request.BaseHandler.handler_order - 50
345
346 def http_error_401(self, req, fp, code, msg, headers):
347 host = req.get_host()
348 retry = self.http_error_auth_reqed('www-authenticate', host, req, headers)
349 return retry
350
351 def http_error_auth_reqed(self, auth_header, host, req, headers):
352 try:
353 spn = "HTTP@%s" % host
354 authdata = self._negotiate_get_authdata(auth_header, headers)
355
356 if self.retried > 3:
357 raise urllib.request.HTTPError(req.get_full_url(), 401,
358 "Negotiate auth failed", headers, None)
359 else:
360 self.retried += 1
361
362 neghdr = self._negotiate_get_svctk(spn, authdata)
363 if neghdr is None:
364 return None
365
366 req.add_unredirected_header('Authorization', neghdr)
367 response = self.parent.open(req)
368
369 srvauth = self._negotiate_get_authdata(auth_header, response.info())
370 if self._validate_response(srvauth):
371 return response
372 except kerberos.GSSError:
373 return None
374 except:
375 self.reset_retry_count()
376 raise
377 finally:
378 self._clean_context()
379
380 def reset_retry_count(self):
381 self.retried = 0
382
383 def _negotiate_get_authdata(self, auth_header, headers):
384 authhdr = headers.get(auth_header, None)
385 if authhdr is not None:
386 for mech_tuple in authhdr.split(","):
387 mech, __, authdata = mech_tuple.strip().partition(" ")
388 if mech.lower() == "negotiate":
389 return authdata.strip()
390 return None
391
392 def _negotiate_get_svctk(self, spn, authdata):
393 if authdata is None:
394 return None
395
396 result, self.context = kerberos.authGSSClientInit(spn)
397 if result < kerberos.AUTH_GSS_COMPLETE:
398 return None
399
400 result = kerberos.authGSSClientStep(self.context, authdata)
401 if result < kerberos.AUTH_GSS_CONTINUE:
402 return None
403
404 response = kerberos.authGSSClientResponse(self.context)
405 return "Negotiate %s" % response
406
407 def _validate_response(self, authdata):
408 if authdata is None:
409 return None
410 result = kerberos.authGSSClientStep(self.context, authdata)
411 if result == kerberos.AUTH_GSS_COMPLETE:
412 return True
413 return None
414
415 def _clean_context(self):
416 if self.context is not None:
417 kerberos.authGSSClientClean(self.context)
418 self.context = None
419
335def init_http(): 420def init_http():
336 handlers = [_UserAgentHandler()] 421 handlers = [_UserAgentHandler()]
337 422
@@ -348,6 +433,8 @@ def init_http():
348 pass 433 pass
349 handlers.append(_BasicAuthHandler(mgr)) 434 handlers.append(_BasicAuthHandler(mgr))
350 handlers.append(_DigestAuthHandler(mgr)) 435 handlers.append(_DigestAuthHandler(mgr))
436 if kerberos:
437 handlers.append(_KerberosAuthHandler())
351 438
352 if 'http_proxy' in os.environ: 439 if 'http_proxy' in os.environ:
353 url = os.environ['http_proxy'] 440 url = os.environ['http_proxy']