Skip to content

Commit c43c77e

Browse files
dpkp88manpreet
authored andcommitted
Always wait for completion during SASL/GSSAPI authentication (dpkp#1248)
1 parent d3479bd commit c43c77e

File tree

1 file changed

+15
-26
lines changed

1 file changed

+15
-26
lines changed

kafka/conn.py

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
import logging
77
from random import shuffle, uniform
88
import socket
9-
import time
9+
import struct
1010
import sys
11+
import time
1112

1213
from kafka.vendor import six
1314

@@ -516,52 +517,40 @@ def _try_authenticate_gssapi(self, future):
516517
ctx_CanonName = ctx_Name.canonicalize(gssapi.MechType.kerberos)
517518
log.debug('%s: canonical Servicename: %s', self, ctx_CanonName)
518519
ctx_Context = gssapi.SecurityContext(name=ctx_CanonName, usage='initiate')
519-
# Exchange tokens until authentication either succeeds or fails:
520+
log.debug("%s: initiator name: %s", self, ctx_Context.initiator_name)
521+
522+
# Exchange tokens until authentication either succeeds or fails
520523
received_token = None
521524
try:
522525
while not ctx_Context.complete:
523-
# calculate the output token
524-
try:
525-
output_token = ctx_Context.step(received_token)
526-
except GSSError as e:
527-
log.exception("%s: Error invalid token received from server", self)
528-
error = Errors.ConnectionError("%s: %s" % (self, e))
526+
# calculate an output token from kafka token (or None if first iteration)
527+
output_token = ctx_Context.step(received_token)
529528

530-
if not output_token:
531-
if ctx_Context.complete:
532-
log.debug("%s: Security Context complete ", self)
533-
log.debug("%s: Successful GSSAPI handshake for %s", self, ctx_Context.initiator_name)
534-
break
529+
# pass output token to kafka
535530
try:
536531
self._sock.setblocking(True)
537-
# Send output token
538532
msg = output_token
539533
size = Int32.encode(len(msg))
540534
self._sock.sendall(size + msg)
541-
542535
# The server will send a token back. Processing of this token either
543536
# establishes a security context, or it needs further token exchange.
544537
# The gssapi will be able to identify the needed next step.
545538
# The connection is closed on failure.
546-
response = self._sock.recv(2000)
539+
header = self._sock.recv(4)
540+
token_size = struct.unpack('>i', header)
541+
received_token = self._sock.recv(token_size)
547542
self._sock.setblocking(False)
548543

549-
except (AssertionError, ConnectionError) as e:
544+
except ConnectionError as e:
550545
log.exception("%s: Error receiving reply from server", self)
551546
error = Errors.ConnectionError("%s: %s" % (self, e))
552-
future.failure(error)
553547
self.close(error=error)
554-
555-
# pass the received token back to gssapi, strip the first 4 bytes
556-
received_token = response[4:]
548+
return future.failure(error)
557549

558550
except Exception as e:
559-
log.exception("%s: GSSAPI handshake error", self)
560-
error = Errors.ConnectionError("%s: %s" % (self, e))
561-
future.failure(error)
562-
self.close(error=error)
551+
return future.failure(e)
563552

564-
log.info('%s: Authenticated as %s', self, gssname)
553+
log.info('%s: Authenticated as %s via GSSAPI', self, gssname)
565554
return future.success(True)
566555

567556
def blacked_out(self):

0 commit comments

Comments
 (0)