From d8a2d8f447079932fb2ec4e29bc148df8173aed9 Mon Sep 17 00:00:00 2001 From: Stephan Erb Date: Sun, 28 Dec 2008 14:53:20 +0000 Subject: [PATCH] Backport a few XMPPPY upstream changes. * Use namespace instead of attrs={} for addChild * Unplug SASL module on auth failure (we currently disconnect so don't really need it) --- src/adhoc_commands.py | 10 +++------- src/common/commands.py | 3 +-- src/common/pubsub.py | 2 +- src/common/xmpp/auth_nb.py | 26 ++++++++++++++++++-------- src/common/xmpp/client.py | 1 + src/common/xmpp/client_nb.py | 5 ++++- src/common/xmpp/features_nb.py | 2 +- src/common/xmpp/roster_nb.py | 7 +++++-- src/common/xmpp/simplexml.py | 2 ++ 9 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/adhoc_commands.py b/src/adhoc_commands.py index 17b4c6ef4..e0399a746 100644 --- a/src/adhoc_commands.py +++ b/src/adhoc_commands.py @@ -480,11 +480,8 @@ class CommandWindow: assert action in ('execute', 'prev', 'next', 'complete') stanza = xmpp.Iq(typ='set', to=self.jid) - cmdnode = stanza.addChild('command', attrs={ - 'xmlns':xmpp.NS_COMMANDS, - 'node':self.commandnode, - 'action':action - }) + cmdnode = stanza.addChild('command', namespace=xmpp.NS_COMMANDS, attrs={ + 'node':self.commandnode, 'action':action}) if self.sessionid: cmdnode.setAttr('sessionid', self.sessionid) @@ -511,8 +508,7 @@ class CommandWindow: if self.sessionid and self.account.connection: # we already have sessionid, so the service sent at least one reply. stanza = xmpp.Iq(typ='set', to=self.jid) - stanza.addChild('command', attrs={ - 'xmlns':xmpp.NS_COMMANDS, + stanza.addChild('command', namespace=xmpp.NS_COMMANDS, attrs={ 'node':self.commandnode, 'sessionid':self.sessionid, 'action':'cancel' diff --git a/src/common/commands.py b/src/common/commands.py index dec1b4018..71b0300bc 100644 --- a/src/common/commands.py +++ b/src/common/commands.py @@ -50,8 +50,7 @@ class AdHocCommand: assert status in ('executing', 'completed', 'canceled') response = request.buildReply('result') - cmd = response.addChild('command', { - 'xmlns': xmpp.NS_COMMANDS, + cmd = response.addChild('command', namespace=xmpp.NS_COMMANDS, attrs={ 'sessionid': self.sessionid, 'node': self.commandnode, 'status': status}) diff --git a/src/common/pubsub.py b/src/common/pubsub.py index 517d947a8..bc004a511 100644 --- a/src/common/pubsub.py +++ b/src/common/pubsub.py @@ -33,7 +33,7 @@ class ConnectionPubSub: if not self.connection or self.connected < 2: return query = xmpp.Iq('get', to=jid) - pb = query.addChild('pubsub', {'xmlns': xmpp.NS_PUBSUB}) + pb = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB) pb.addChild('subscriptions') id_ = self.connection.send(query) diff --git a/src/common/xmpp/auth_nb.py b/src/common/xmpp/auth_nb.py index e97770f1f..0210a9adb 100644 --- a/src/common/xmpp/auth_nb.py +++ b/src/common/xmpp/auth_nb.py @@ -1,5 +1,5 @@ ## auth_nb.py -## based on auth.py +## based on auth.py, changes backported up to revision 1.41 ## ## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov ## modified by Dimitur Kirov @@ -143,12 +143,18 @@ class SASL(PlugIn): def plugout(self): ''' Remove SASL handlers from owner's dispatcher. Used internally. ''' - self._owner.UnregisterHandler('features', self.FeaturesHandler, - xmlns=NS_STREAMS) - self._owner.UnregisterHandler('challenge', self.SASLHandler, - xmlns=NS_SASL) - self._owner.UnregisterHandler('failure', self.SASLHandler, xmlns=NS_SASL) - self._owner.UnregisterHandler('success', self.SASLHandler, xmlns=NS_SASL) + if 'features' in self._owner.__dict__: + self._owner.UnregisterHandler('features', self.FeaturesHandler, + xmlns=NS_STREAMS) + if 'challenge' in self._owner.__dict__: + self._owner.UnregisterHandler('challenge', self.SASLHandler, + xmlns=NS_SASL) + if 'failure' in self._owner.__dict__: + self._owner.UnregisterHandler('failure', self.SASLHandler, + xmlns=NS_SASL) + if 'success' in self._owner.__dict__: + self._owner.UnregisterHandler('success', self.SASLHandler, + xmlns=NS_SASL) def auth(self): ''' @@ -187,7 +193,11 @@ class SASL(PlugIn): self.MechanismHandler() def MechanismHandler(self): - if 'GSSAPI' in self.mecs and have_kerberos: + if 'ANONYMOUS' in self.mecs and self.username is None: + self.mecs.remove('ANONYMOUS') + node = Node('auth',attrs={'xmlns': NS_SASL, 'mechanism': 'ANONYMOUS'}) + self.mechanism = 'ANONYMOUS' + elif 'GSSAPI' in self.mecs and have_kerberos: self.mecs.remove('GSSAPI') self.gss_vc = kerberos.authGSSClientInit('xmpp@' + \ self._owner.xmpp_hostname)[1] diff --git a/src/common/xmpp/client.py b/src/common/xmpp/client.py index 257a72f90..1ddded895 100644 --- a/src/common/xmpp/client.py +++ b/src/common/xmpp/client.py @@ -44,6 +44,7 @@ class PlugIn: self._owner=owner log.info('Plugging %s __INTO__ %s' % (self, self._owner)) if self.__class__.__name__ in owner.__dict__: + print "already plugged", self.__class__.__name__ log.debug('Plugging ignored: another instance already plugged.') return self._old_owners_methods=[] diff --git a/src/common/xmpp/client_nb.py b/src/common/xmpp/client_nb.py index 746547cf8..bd1b10124 100644 --- a/src/common/xmpp/client_nb.py +++ b/src/common/xmpp/client_nb.py @@ -1,5 +1,6 @@ ## client_nb.py -## based on client.py +## based on client.py, changes backported up to revision 1.60 + ## ## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov ## modified by Dimitur Kirov @@ -461,6 +462,8 @@ class NonBlockingClient: self.onreceive(None) if self.SASL.startsasl == 'failure': # wrong user/pass, stop auth + if 'SASL' in self.__dict__: + self.SASL.PlugOut() self.connected = None self._on_sasl_auth(None) elif self.SASL.startsasl == 'success': diff --git a/src/common/xmpp/features_nb.py b/src/common/xmpp/features_nb.py index 1501fcbf8..427ca9724 100644 --- a/src/common/xmpp/features_nb.py +++ b/src/common/xmpp/features_nb.py @@ -50,7 +50,7 @@ def getRegInfo(disp, host, info={}, sync=True): iq.setTagData(i,info[i]) if sync: disp.SendAndCallForResponse(iq, lambda resp: - _ReceivedRegInfo(disp.Dispatcher,resp, host)) + _ReceivedRegInfo(disp.Dispatcher, resp, host)) else: disp.SendAndCallForResponse(iq, _ReceivedRegInfo, {'agent': host }) diff --git a/src/common/xmpp/roster_nb.py b/src/common/xmpp/roster_nb.py index f1374fef0..68c88a4f3 100644 --- a/src/common/xmpp/roster_nb.py +++ b/src/common/xmpp/roster_nb.py @@ -21,7 +21,7 @@ Simple roster implementation. Can be used though for different tasks like mass-renaming of contacts. ''' -from protocol import JID, Iq, Presence, Node, NS_ROSTER +from protocol import JID, Iq, Presence, Node, NodeProcessed, NS_ROSTER from client import PlugIn import logging @@ -64,7 +64,8 @@ class NonBlockingRoster(PlugIn): jid=item.getAttr('jid') if item.getAttr('subscription')=='remove': if self._data.has_key(jid): del self._data[jid] - return + # Looks like we have a workaround + # raise NodeProcessed # a MUST log.info('Setting roster item %s...' % jid) if not self._data.has_key(jid): self._data[jid]={} self._data[jid]['name']=item.getAttr('name') @@ -75,6 +76,8 @@ class NonBlockingRoster(PlugIn): for group in item.getTags('group'): self._data[jid]['groups'].append(group.getData()) self._data[self._owner.User+'@'+self._owner.Server]={'resources':{},'name':None,'ask':None,'subscription':None,'groups':None,} self.set=1 + # Looks like we have a workaround + # raise NodeProcessed # a MUST. Otherwise you'll get back an def PresenceHandler(self,dis,pres): ''' Presence tracker. Used internally for setting items' resources state in diff --git a/src/common/xmpp/simplexml.py b/src/common/xmpp/simplexml.py index c640cc234..237f1cec2 100644 --- a/src/common/xmpp/simplexml.py +++ b/src/common/xmpp/simplexml.py @@ -145,6 +145,8 @@ class Node(object): def addChild(self, name=None, attrs={}, payload=[], namespace=None, node=None): ''' If "node" argument is provided, adds it as child node. Else creates new node from the other arguments' values and adds it as well.''' + if 'xmlns' in attrs: + raise AttributeError("Use namespace=x instead of attrs={'xmlns':x}") if node: newnode=node node.parent = self