Skip to content

Commit

Permalink
Don't inquire about incomplete security contexts
Browse files Browse the repository at this point in the history
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
  • Loading branch information
DirectXMan12 committed Jun 5, 2015
1 parent 8bfd908 commit 2fe3c19
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
36 changes: 31 additions & 5 deletions gssapi/sec_contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,21 @@ def __init__(self, base=None, token=None,

else:
# we already have a context in progress, just inspect it
if self.locally_initiated:
self.usage = 'initiate'
else:
self.usage = 'accept'
# NB(directxman12): MIT krb5 refuses to inquire about a context
# if it's partially established, so we have to check here

try:
if self.locally_initiated:
self.usage = 'initiate'
else:
self.usage = 'accept'
except excs.MissingContextError:
msg = ("Cannot extract usage from a partially completed "
"context")
raise excs.UnknownUsageError(msg, obj="security context")

# This is to work around an MIT krb5 bug (see the `complete` property)
self._complete = None

# NB(directxman12): DO NOT ADD AN __del__ TO THIS CLASS -- it screws up
# the garbage collector if _last_tb is still defined
Expand Down Expand Up @@ -422,8 +433,19 @@ def lifetime(self):
@_utils.check_last_err
def complete(self):
"""Whether negotiation for this context has been completed"""
# NB(directxman12): MIT krb5 has a bug where it refuses to
# inquire about partially completed contexts,
# so we can't just use `self._inquire` generally
if self._started:
return self._inquire(complete=True).complete
if self._complete is None:
try:
res = self._inquire(complete=True).complete
except excs.MissingContextError:
return False
else:
self._complete = res

return self._complete
else:
return False

Expand Down Expand Up @@ -491,6 +513,8 @@ def _acceptor_step(self, token):

self.delegated_creds = Credentials(res.delegated_creds)

self._complete = not res.more_steps

return res.token

def _initiator_step(self, token=None):
Expand All @@ -501,6 +525,8 @@ def _initiator_step(self, token=None):
self._channel_bindings,
token)

self._complete = not res.more_steps

return res.token

# pickle protocol support
Expand Down
13 changes: 13 additions & 0 deletions gssapi/tests/test_high_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ def _create_completed_contexts(self):

return (client_ctx, server_ctx)

def test_complete_on_partially_completed(self):
client_ctx = self._create_client_ctx()
client_tok = client_ctx.step()
client_ctx.complete.should_be_false()

server_ctx = gssctx.SecurityContext(creds=self.server_creds)
server_tok = server_ctx.step(client_tok)

client_ctx.step(server_tok)

client_ctx.complete.should_be_true()
server_ctx.complete.should_be_true()

def test_initiate_accept_steps(self):
client_ctx, server_ctx = self._create_completed_contexts()

Expand Down

0 comments on commit 2fe3c19

Please sign in to comment.