@@ -26,14 +26,15 @@ def __init__(self, **config):
26
26
raise ValueError ('sasl_kerberos_service_name or sasl_kerberos_name required for GSSAPI sasl configuration' )
27
27
self ._is_done = False
28
28
self ._is_authenticated = False
29
+ self .gssapi_name = None
29
30
if config .get ('sasl_kerberos_name' , None ) is not None :
30
31
self .auth_id = str (config ['sasl_kerberos_name' ])
32
+ if isinstance (config ['sasl_kerberos_name' ], gssapi .Name ):
33
+ self .gssapi_name = config ['sasl_kerberos_name' ]
31
34
else :
32
35
kerberos_domain_name = config .get ('sasl_kerberos_domain_name' , '' ) or config .get ('host' , '' )
33
36
self .auth_id = config ['sasl_kerberos_service_name' ] + '@' + kerberos_domain_name
34
- if isinstance (config .get ('sasl_kerberos_name' , None ), gssapi .Name ):
35
- self .gssapi_name = config ['sasl_kerberos_name' ]
36
- else :
37
+ if self .gssapi_name is None :
37
38
self .gssapi_name = gssapi .Name (self .auth_id , name_type = gssapi .NameType .hostbased_service ).canonicalize (gssapi .MechType .kerberos )
38
39
self ._client_ctx = gssapi .SecurityContext (name = self .gssapi_name , usage = 'initiate' )
39
40
self ._next_token = self ._client_ctx .step (None )
@@ -43,9 +44,8 @@ def auth_bytes(self):
43
44
# so mark is_done after the final auth_bytes are provided
44
45
# in practice we'll still receive a response when using SaslAuthenticate
45
46
# but not when using the prior unframed approach.
46
- if self ._client_ctx . complete :
47
+ if self ._is_authenticated :
47
48
self ._is_done = True
48
- self ._is_authenticated = True
49
49
return self ._next_token or b''
50
50
51
51
def receive (self , auth_bytes ):
@@ -74,6 +74,13 @@ def receive(self, auth_bytes):
74
74
]
75
75
# add authorization identity to the response, and GSS-wrap
76
76
self ._next_token = self ._client_ctx .wrap (b'' .join (message_parts ), False ).message
77
+ # We need to identify the last token in auth_bytes();
78
+ # we can't rely on client_ctx.complete because it becomes True after generating
79
+ # the second-to-last token (after calling .step(auth_bytes) for the final time)
80
+ # We could introduce an additional state variable (i.e., self._final_token),
81
+ # but instead we just set _is_authenticated. Since the plugin interface does
82
+ # not read is_authenticated() until after is_done() is True, this should be fine.
83
+ self ._is_authenticated = True
77
84
78
85
def is_done (self ):
79
86
return self ._is_done
0 commit comments