diff options
Diffstat (limited to 'main.py')
-rwxr-xr-x | main.py | 87 |
1 files changed, 87 insertions, 0 deletions
@@ -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 | ||
34 | try: | ||
35 | import kerberos | ||
36 | except ImportError: | ||
37 | kerberos = None | ||
38 | |||
34 | from trace import SetTrace | 39 | from trace import SetTrace |
35 | from git_command import git, GitCommand | 40 | from git_command import git, GitCommand |
36 | from git_config import init_ssh, close_ssh | 41 | from 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 | ||
340 | class _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 | |||
335 | def init_http(): | 420 | def 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'] |