From 657102e938aeb385cd44daf3cc213a40d58c36fa Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 1 Oct 2012 16:27:55 -0700 Subject: [PATCH 1/7] Update legacy auth to be used outside of stream features. Also, add detection of legacy XMPP version. --- sleekxmpp/basexmpp.py | 4 ++++ .../features/feature_mechanisms/mechanisms.py | 2 +- sleekxmpp/plugins/xep_0078/legacyauth.py | 21 ++++++++++++++----- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py index 55250751..a1969e34 100644 --- a/sleekxmpp/basexmpp.py +++ b/sleekxmpp/basexmpp.py @@ -212,6 +212,10 @@ class BaseXMPP(XMLStream): self.stream_version = xml.get('version', '') self.peer_default_lang = xml.get('{%s}lang' % XML_NS, None) + if not self.is_component and not self.stream_version: + log.warning('Legacy XMPP 0.9 protocol detected.') + self.event('legacy_protocol') + def process(self, *args, **kwargs): """Initialize plugins and begin processing the XML stream. diff --git a/sleekxmpp/features/feature_mechanisms/mechanisms.py b/sleekxmpp/features/feature_mechanisms/mechanisms.py index 672f4fa6..b480d5be 100644 --- a/sleekxmpp/features/feature_mechanisms/mechanisms.py +++ b/sleekxmpp/features/feature_mechanisms/mechanisms.py @@ -44,7 +44,7 @@ class FeatureMechanisms(BasePlugin): } def plugin_init(self): - if not self.use_mech and not self.xmpp.boundjid.user: + if not self.use_mech and not self.xmpp.requested_jid.user: self.use_mech = 'ANONYMOUS' if self.sasl_callback is None: diff --git a/sleekxmpp/plugins/xep_0078/legacyauth.py b/sleekxmpp/plugins/xep_0078/legacyauth.py index 5c4045d8..89716e18 100644 --- a/sleekxmpp/plugins/xep_0078/legacyauth.py +++ b/sleekxmpp/plugins/xep_0078/legacyauth.py @@ -44,16 +44,27 @@ class XEP_0078(BasePlugin): restart=False, order=self.order) + self.xmpp.add_event_handler('legacy_protocol', + self._handle_legacy_protocol) + register_stanza_plugin(Iq, stanza.IqAuth) register_stanza_plugin(StreamFeatures, stanza.AuthFeature) def plugin_end(self): + self.xmpp.del_event_handler('legacy_protocol', + self._handle_legacy_protocol) self.xmpp.unregister_feature('auth', self.order) def _handle_auth(self, features): # If we can or have already authenticated with SASL, do nothing. if 'mechanisms' in features['features']: return False + return self.authenticate() + + def _handle_legacy_protocol(self, event): + self.authenticate() + + def authenticate(self): if self.xmpp.authenticated: return False @@ -62,8 +73,8 @@ class XEP_0078(BasePlugin): # Step 1: Request the auth form iq = self.xmpp.Iq() iq['type'] = 'get' - iq['to'] = self.xmpp.boundjid.host - iq['auth']['username'] = self.xmpp.boundjid.user + iq['to'] = self.xmpp.requested_jid.host + iq['auth']['username'] = self.xmpp.requested_jid.user try: resp = iq.send(now=True) @@ -81,11 +92,11 @@ class XEP_0078(BasePlugin): # Step 2: Fill out auth form for either password or digest auth iq = self.xmpp.Iq() iq['type'] = 'set' - iq['auth']['username'] = self.xmpp.boundjid.user + iq['auth']['username'] = self.xmpp.requested_jid.user # A resource is required, so create a random one if necessary - if self.xmpp.boundjid.resource: - iq['auth']['resource'] = self.xmpp.boundjid.resource + if self.xmpp.requested_jid.resource: + iq['auth']['resource'] = self.xmpp.requested_jid.resource else: iq['auth']['resource'] = '%s' % random.random() From cf2c94d974d193b6ba6387a2660c974c9c74f938 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 1 Oct 2012 16:28:31 -0700 Subject: [PATCH 2/7] Add stream_negotiated event. Fires after all stream features have been processed. --- sleekxmpp/clientxmpp.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sleekxmpp/clientxmpp.py b/sleekxmpp/clientxmpp.py index 9aa64256..eb510352 100644 --- a/sleekxmpp/clientxmpp.py +++ b/sleekxmpp/clientxmpp.py @@ -273,6 +273,8 @@ class ClientXMPP(BaseXMPP): # Don't continue if the feature requires # restarting the XML stream. return True + log.debug('Finished processing stream features.') + self.event('stream_negotiated') def _handle_roster(self, iq): """Update the roster after receiving a roster stanza. From 9f6decdbc1dbb791006e590906bd94021b71495f Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 5 Oct 2012 09:49:04 -0700 Subject: [PATCH 3/7] Fix XEP-0078 error handling --- sleekxmpp/plugins/xep_0078/legacyauth.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sleekxmpp/plugins/xep_0078/legacyauth.py b/sleekxmpp/plugins/xep_0078/legacyauth.py index 89716e18..be9fe3c5 100644 --- a/sleekxmpp/plugins/xep_0078/legacyauth.py +++ b/sleekxmpp/plugins/xep_0078/legacyauth.py @@ -78,8 +78,8 @@ class XEP_0078(BasePlugin): try: resp = iq.send(now=True) - except IqError: - log.info("Authentication failed: %s", resp['error']['condition']) + except IqError as err: + log.info("Authentication failed: %s", err.iq['error']['condition']) self.xmpp.event('failed_auth', direct=True) self.xmpp.disconnect() return True @@ -120,12 +120,12 @@ class XEP_0078(BasePlugin): result = iq.send(now=True) except IqError as err: log.info("Authentication failed") - self.xmpp.disconnect() self.xmpp.event("failed_auth", direct=True) + self.xmpp.disconnect() except IqTimeout: log.info("Authentication failed") - self.xmpp.disconnect() self.xmpp.event("failed_auth", direct=True) + self.xmpp.disconnect() self.xmpp.features.add('auth') From 747a6e94e6039c1e349dafc22d1f3cd2baee6d02 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 15 Oct 2012 22:19:47 -0700 Subject: [PATCH 4/7] Auto-subscribe to whitelisted JIDs if auto_subscribe is true --- sleekxmpp/basexmpp.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py index a1969e34..f26c048f 100644 --- a/sleekxmpp/basexmpp.py +++ b/sleekxmpp/basexmpp.py @@ -746,6 +746,8 @@ class BaseXMPP(XMLStream): item = self.roster[pres['to']][pres['from']] if item['whitelisted']: item.authorize() + if roster.auto_subscribe: + item.subscribe() elif roster.auto_authorize: item.authorize() if roster.auto_subscribe: From 829b225053cf828f40e78b54b251a2da3ba3119f Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 15 Oct 2012 22:20:13 -0700 Subject: [PATCH 5/7] Fix vcard-temp stanzas to include organization data. --- sleekxmpp/plugins/xep_0054/stanza.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sleekxmpp/plugins/xep_0054/stanza.py b/sleekxmpp/plugins/xep_0054/stanza.py index 512e1dd8..72da0b51 100644 --- a/sleekxmpp/plugins/xep_0054/stanza.py +++ b/sleekxmpp/plugins/xep_0054/stanza.py @@ -541,6 +541,7 @@ register_stanza_plugin(VCardTemp, Logo, iterable=True) register_stanza_plugin(VCardTemp, Mailer, iterable=True) register_stanza_plugin(VCardTemp, Note, iterable=True) register_stanza_plugin(VCardTemp, Nickname, iterable=True) +register_stanza_plugin(VCardTemp, Org, iterable=True) register_stanza_plugin(VCardTemp, Photo, iterable=True) register_stanza_plugin(VCardTemp, ProdID, iterable=True) register_stanza_plugin(VCardTemp, Rev, iterable=True) From ef48a8c4d9205d82cb7b59e89d2b22feb980749d Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 15 Oct 2012 22:20:38 -0700 Subject: [PATCH 6/7] Simplify xep-0084 avatar metadata publishing. --- sleekxmpp/plugins/xep_0084/avatar.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sleekxmpp/plugins/xep_0084/avatar.py b/sleekxmpp/plugins/xep_0084/avatar.py index 03711871..2454afc7 100644 --- a/sleekxmpp/plugins/xep_0084/avatar.py +++ b/sleekxmpp/plugins/xep_0084/avatar.py @@ -69,6 +69,8 @@ class XEP_0084(BasePlugin): metadata = MetaData() if items is None: items = [] + if not isinstance(items, (list, set)): + items = [items] for info in items: metadata.add_info(info['id'], info['type'], info['bytes'], height=info.get('height', ''), From 4190027a787f878b4ea07ddd24883bb9d1a94d6e Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 15 Oct 2012 22:22:07 -0700 Subject: [PATCH 7/7] Prevent xmlns="" in stream output. This was causing problems for HTML-IM because the HTML is parsed without a namespaced context. While xmlns="" technically can be valid, it's usually wrong, so this will work for now until the HTML-IM parsing is fixed. --- sleekxmpp/xmlstream/tostring.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sleekxmpp/xmlstream/tostring.py b/sleekxmpp/xmlstream/tostring.py index 0b73d8dc..08d7ad02 100644 --- a/sleekxmpp/xmlstream/tostring.py +++ b/sleekxmpp/xmlstream/tostring.py @@ -70,9 +70,10 @@ def tostring(xml=None, xmlns='', stream=None, # Output the tag name and derived namespace of the element. namespace = '' - if top_level and tag_xmlns not in [default_ns, xmlns, stream_ns] \ - or not top_level and tag_xmlns != xmlns: - namespace = ' xmlns="%s"' % tag_xmlns + if tag_xmlns: + if top_level and tag_xmlns not in [default_ns, xmlns, stream_ns] \ + or not top_level and tag_xmlns != xmlns: + namespace = ' xmlns="%s"' % tag_xmlns if stream and tag_xmlns in stream.namespace_map: mapped_namespace = stream.namespace_map[tag_xmlns] if mapped_namespace: