Allow attempting multiple SASL mechs during a single stream.

Instead of disconnecting when the first chosen mech fails, we will
try all of them once.
This commit is contained in:
Lance Stout 2012-01-20 02:01:08 -08:00
parent 71ea430c62
commit 3a22d798f8

View file

@ -61,6 +61,9 @@ class feature_mechanisms(base_plugin):
tls_active=tls_active, tls_active=tls_active,
mech=self.use_mech) mech=self.use_mech)
self.mech_list = set()
self.attempted_mechs = set()
register_stanza_plugin(StreamFeatures, stanza.Mechanisms) register_stanza_plugin(StreamFeatures, stanza.Mechanisms)
self.xmpp.register_stanza(stanza.Success) self.xmpp.register_stanza(stanza.Success)
@ -73,14 +76,12 @@ class feature_mechanisms(base_plugin):
Callback('SASL Success', Callback('SASL Success',
MatchXPath(stanza.Success.tag_name()), MatchXPath(stanza.Success.tag_name()),
self._handle_success, self._handle_success,
instream=True, instream=True))
once=True))
self.xmpp.register_handler( self.xmpp.register_handler(
Callback('SASL Failure', Callback('SASL Failure',
MatchXPath(stanza.Failure.tag_name()), MatchXPath(stanza.Failure.tag_name()),
self._handle_fail, self._handle_fail,
instream=True, instream=True))
once=True))
self.xmpp.register_handler( self.xmpp.register_handler(
Callback('SASL Challenge', Callback('SASL Challenge',
MatchXPath(stanza.Challenge.tag_name()), MatchXPath(stanza.Challenge.tag_name()),
@ -103,10 +104,15 @@ class feature_mechanisms(base_plugin):
# server has incorrectly offered it again. # server has incorrectly offered it again.
return False return False
mech_list = features['mechanisms'] self.mech_list = set(features['mechanisms'])
return self._send_auth()
def _send_auth(self):
mech_list = self.mech_list - self.attempted_mechs
self.mech = self.sasl.choose_mechanism(mech_list) self.mech = self.sasl.choose_mechanism(mech_list)
if self.mech is not None: if self.mech is not None:
self.attempted_mechs.add(self.mech.name)
resp = stanza.Auth(self.xmpp) resp = stanza.Auth(self.xmpp)
resp['mechanism'] = self.mech.name resp['mechanism'] = self.mech.name
resp['value'] = self.mech.process() resp['value'] = self.mech.process()
@ -133,5 +139,5 @@ class feature_mechanisms(base_plugin):
"""SASL authentication failed. Disconnect and shutdown.""" """SASL authentication failed. Disconnect and shutdown."""
log.info("Authentication failed: %s", stanza['condition']) log.info("Authentication failed: %s", stanza['condition'])
self.xmpp.event("failed_auth", stanza, direct=True) self.xmpp.event("failed_auth", stanza, direct=True)
self.xmpp.disconnect() self._send_auth()
return True return True