Handle SASLCancelled and SASLError exceptions.

This commit is contained in:
Lance Stout 2012-01-21 00:19:08 -08:00
parent baad907422
commit bb0a5186d6

View file

@ -9,6 +9,7 @@
import logging import logging
from sleekxmpp.thirdparty import suelta from sleekxmpp.thirdparty import suelta
from sleekxmpp.thirdparty.suelta.exceptions import SASLCancelled, SASLError
from sleekxmpp.stanza import StreamFeatures from sleekxmpp.stanza import StreamFeatures
from sleekxmpp.xmlstream import RestartStream, register_stanza_plugin from sleekxmpp.xmlstream import RestartStream, register_stanza_plugin
@ -71,6 +72,7 @@ class feature_mechanisms(base_plugin):
self.xmpp.register_stanza(stanza.Auth) self.xmpp.register_stanza(stanza.Auth)
self.xmpp.register_stanza(stanza.Challenge) self.xmpp.register_stanza(stanza.Challenge)
self.xmpp.register_stanza(stanza.Response) self.xmpp.register_stanza(stanza.Response)
self.xmpp.register_stanza(stanza.Abort)
self.xmpp.register_handler( self.xmpp.register_handler(
Callback('SASL Success', Callback('SASL Success',
@ -112,11 +114,18 @@ class feature_mechanisms(base_plugin):
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() try:
resp.send(now=True) resp['value'] = self.mech.process()
except SASLCancelled:
self.attempted_mechs.add(self.mech.name)
self._send_auth()
except SASLError:
self.attempted_mechs.add(self.mech.name)
self._send_auth()
else:
resp.send(now=True)
else: else:
log.error("No appropriate login method.") log.error("No appropriate login method.")
self.xmpp.event("no_auth", direct=True) self.xmpp.event("no_auth", direct=True)
@ -126,17 +135,25 @@ class feature_mechanisms(base_plugin):
def _handle_challenge(self, stanza): def _handle_challenge(self, stanza):
"""SASL challenge received. Process and send response.""" """SASL challenge received. Process and send response."""
resp = self.stanza.Response(self.xmpp) resp = self.stanza.Response(self.xmpp)
resp['value'] = self.mech.process(stanza['value']) try:
resp.send(now=True) resp['value'] = self.mech.process(stanza['value'])
except SASLCancelled:
self.stanza.Abort(self.xmpp).send()
except SASLError:
self.stanza.Abort(self.xmpp).send()
else:
resp.send(now=True)
def _handle_success(self, stanza): def _handle_success(self, stanza):
"""SASL authentication succeeded. Restart the stream.""" """SASL authentication succeeded. Restart the stream."""
self.attempted_mechs = set()
self.xmpp.authenticated = True self.xmpp.authenticated = True
self.xmpp.features.add('mechanisms') self.xmpp.features.add('mechanisms')
raise RestartStream() raise RestartStream()
def _handle_fail(self, stanza): def _handle_fail(self, stanza):
"""SASL authentication failed. Disconnect and shutdown.""" """SASL authentication failed. Disconnect and shutdown."""
self.attempted_mechs.add(self.mech.name)
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._send_auth() self._send_auth()