Skip to content

Commit 2fe3c19

Browse files
committed
Don't inquire about incomplete security contexts
This commit changes `SecurityContext` to handle a couple of cases where we called `_inquire` when the context was not fully established. A bug in MIT krb5 prevents this from working properly. In the case of `complete`, we simply cache the result of the last `step` call. Fixes #69
1 parent 8bfd908 commit 2fe3c19

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

gssapi/sec_contexts.py

+31-5
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,21 @@ def __init__(self, base=None, token=None,
110110

111111
else:
112112
# we already have a context in progress, just inspect it
113-
if self.locally_initiated:
114-
self.usage = 'initiate'
115-
else:
116-
self.usage = 'accept'
113+
# NB(directxman12): MIT krb5 refuses to inquire about a context
114+
# if it's partially established, so we have to check here
115+
116+
try:
117+
if self.locally_initiated:
118+
self.usage = 'initiate'
119+
else:
120+
self.usage = 'accept'
121+
except excs.MissingContextError:
122+
msg = ("Cannot extract usage from a partially completed "
123+
"context")
124+
raise excs.UnknownUsageError(msg, obj="security context")
125+
126+
# This is to work around an MIT krb5 bug (see the `complete` property)
127+
self._complete = None
117128

118129
# NB(directxman12): DO NOT ADD AN __del__ TO THIS CLASS -- it screws up
119130
# the garbage collector if _last_tb is still defined
@@ -422,8 +433,19 @@ def lifetime(self):
422433
@_utils.check_last_err
423434
def complete(self):
424435
"""Whether negotiation for this context has been completed"""
436+
# NB(directxman12): MIT krb5 has a bug where it refuses to
437+
# inquire about partially completed contexts,
438+
# so we can't just use `self._inquire` generally
425439
if self._started:
426-
return self._inquire(complete=True).complete
440+
if self._complete is None:
441+
try:
442+
res = self._inquire(complete=True).complete
443+
except excs.MissingContextError:
444+
return False
445+
else:
446+
self._complete = res
447+
448+
return self._complete
427449
else:
428450
return False
429451

@@ -491,6 +513,8 @@ def _acceptor_step(self, token):
491513

492514
self.delegated_creds = Credentials(res.delegated_creds)
493515

516+
self._complete = not res.more_steps
517+
494518
return res.token
495519

496520
def _initiator_step(self, token=None):
@@ -501,6 +525,8 @@ def _initiator_step(self, token=None):
501525
self._channel_bindings,
502526
token)
503527

528+
self._complete = not res.more_steps
529+
504530
return res.token
505531

506532
# pickle protocol support

gssapi/tests/test_high_level.py

+13
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,19 @@ def _create_completed_contexts(self):
619619

620620
return (client_ctx, server_ctx)
621621

622+
def test_complete_on_partially_completed(self):
623+
client_ctx = self._create_client_ctx()
624+
client_tok = client_ctx.step()
625+
client_ctx.complete.should_be_false()
626+
627+
server_ctx = gssctx.SecurityContext(creds=self.server_creds)
628+
server_tok = server_ctx.step(client_tok)
629+
630+
client_ctx.step(server_tok)
631+
632+
client_ctx.complete.should_be_true()
633+
server_ctx.complete.should_be_true()
634+
622635
def test_initiate_accept_steps(self):
623636
client_ctx, server_ctx = self._create_completed_contexts()
624637

0 commit comments

Comments
 (0)