diff options
Diffstat (limited to 'sleekxmpp')
-rw-r--r-- | sleekxmpp/clientxmpp.py | 4 | ||||
-rw-r--r-- | sleekxmpp/features/feature_starttls/starttls.py | 6 | ||||
-rw-r--r-- | sleekxmpp/plugins/xep_0045.py | 14 | ||||
-rw-r--r-- | sleekxmpp/plugins/xep_0280/carbons.py | 9 | ||||
-rw-r--r-- | sleekxmpp/plugins/xep_0280/stanza.py | 22 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/stanzabase.py | 8 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/xmlstream.py | 105 |
7 files changed, 80 insertions, 88 deletions
diff --git a/sleekxmpp/clientxmpp.py b/sleekxmpp/clientxmpp.py index eb510352..ec64664c 100644 --- a/sleekxmpp/clientxmpp.py +++ b/sleekxmpp/clientxmpp.py @@ -95,7 +95,7 @@ class ClientXMPP(BaseXMPP): self.bound = False self.bindfail = False - self.add_event_handler('connected', self._handle_connected) + self.add_event_handler('connected', self._reset_connection_state) self.add_event_handler('session_bind', self._handle_session_bind) self.register_stanza(StreamFeatures) @@ -253,7 +253,7 @@ class ClientXMPP(BaseXMPP): self._handle_roster(response) return response - def _handle_connected(self, event=None): + def _reset_connection_state(self, event=None): #TODO: Use stream state here self.authenticated = False self.sessionstarted = False diff --git a/sleekxmpp/features/feature_starttls/starttls.py b/sleekxmpp/features/feature_starttls/starttls.py index 212b9da5..eb5eee1d 100644 --- a/sleekxmpp/features/feature_starttls/starttls.py +++ b/sleekxmpp/features/feature_starttls/starttls.py @@ -54,13 +54,9 @@ class FeatureSTARTTLS(BasePlugin): return False elif not self.xmpp.use_tls: return False - elif self.xmpp.ssl_support: + else: self.xmpp.send(features['starttls'], now=True) return True - else: - log.warning("The module tlslite is required to log in" + \ - " to some servers, and has not been found.") - return False def _handle_starttls_proceed(self, proceed): """Restart the XML stream when TLS is accepted.""" diff --git a/sleekxmpp/plugins/xep_0045.py b/sleekxmpp/plugins/xep_0045.py index 45f2915f..cba07702 100644 --- a/sleekxmpp/plugins/xep_0045.py +++ b/sleekxmpp/plugins/xep_0045.py @@ -245,11 +245,11 @@ class XEP_0045(BasePlugin): stanza = self.xmpp.makePresence(pto="%s/%s" % (room, nick), pstatus=pstatus, pshow=pshow, pfrom=pfrom) x = ET.Element('{http://jabber.org/protocol/muc}x') if password: - passelement = ET.Element('password') + passelement = ET.Element('{http://jabber.org/protocol/muc}password') passelement.text = password x.append(passelement) if maxhistory: - history = ET.Element('history') + history = ET.Element('{http://jabber.org/protocol/muc}history') if maxhistory == "0": history.attrib['maxchars'] = maxhistory else: @@ -271,10 +271,10 @@ class XEP_0045(BasePlugin): iq['from'] = ifrom iq['to'] = room query = ET.Element('{http://jabber.org/protocol/muc#owner}query') - destroy = ET.Element('destroy') + destroy = ET.Element('{http://jabber.org/protocol/muc#owner}destroy') if altroom: destroy.attrib['jid'] = altroom - xreason = ET.Element('reason') + xreason = ET.Element('{http://jabber.org/protocol/muc#owner}reason') xreason.text = reason destroy.append(xreason) query.append(destroy) @@ -294,9 +294,9 @@ class XEP_0045(BasePlugin): raise TypeError query = ET.Element('{http://jabber.org/protocol/muc#admin}query') if nick is not None: - item = ET.Element('item', {'affiliation':affiliation, 'nick':nick}) + item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {'affiliation':affiliation, 'nick':nick}) else: - item = ET.Element('item', {'affiliation':affiliation, 'jid':jid}) + item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {'affiliation':affiliation, 'jid':jid}) query.append(item) iq = self.xmpp.makeIqSet(query) iq['to'] = room @@ -317,7 +317,7 @@ class XEP_0045(BasePlugin): x = ET.Element('{http://jabber.org/protocol/muc#user}x') invite = ET.Element('{http://jabber.org/protocol/muc#user}invite', {'to': jid}) if reason: - rxml = ET.Element('reason') + rxml = ET.Element('{http://jabber.org/protocol/muc#user}reason') rxml.text = reason invite.append(rxml) x.append(invite) diff --git a/sleekxmpp/plugins/xep_0280/carbons.py b/sleekxmpp/plugins/xep_0280/carbons.py index fe2cdbb2..482d046a 100644 --- a/sleekxmpp/plugins/xep_0280/carbons.py +++ b/sleekxmpp/plugins/xep_0280/carbons.py @@ -47,13 +47,18 @@ class XEP_0280(BasePlugin): register_stanza_plugin(Iq, stanza.CarbonEnable) register_stanza_plugin(Iq, stanza.CarbonDisable) + register_stanza_plugin(stanza.ReceivedCarbon, + self.xmpp['xep_0297'].stanza.Forwarded) + register_stanza_plugin(stanza.SentCarbon, + self.xmpp['xep_0297'].stanza.Forwarded) + def plugin_end(self): self.xmpp.remove_handler('Carbon Received') self.xmpp.remove_handler('Carbon Sent') - self.xmpp.plugin['xep_0030'].del_feature(feature='urn:xmpp:carbons:1') + self.xmpp.plugin['xep_0030'].del_feature(feature='urn:xmpp:carbons:2') def session_bind(self, jid): - self.xmpp.plugin['xep_0030'].add_feature('urn:xmpp:carbons:1') + self.xmpp.plugin['xep_0030'].add_feature('urn:xmpp:carbons:2') def _handle_carbon_received(self, msg): self.xmpp.event('carbon_received', msg) diff --git a/sleekxmpp/plugins/xep_0280/stanza.py b/sleekxmpp/plugins/xep_0280/stanza.py index 94b37823..2f3aad86 100644 --- a/sleekxmpp/plugins/xep_0280/stanza.py +++ b/sleekxmpp/plugins/xep_0280/stanza.py @@ -11,54 +11,54 @@ from sleekxmpp.xmlstream import ElementBase class ReceivedCarbon(ElementBase): name = 'received' - namespace = 'urn:xmpp:carbons:1' + namespace = 'urn:xmpp:carbons:2' plugin_attrib = 'carbon_received' interfaces = set(['carbon_received']) is_extension = True def get_carbon_received(self): - return self.parent()['forwarded']['stanza'] + return self['forwarded']['stanza'] def del_carbon_received(self): - del self.parent()['forwarded']['stanza'] + del self['forwarded']['stanza'] def set_carbon_received(self, stanza): - self.parent()['forwarded']['stanza'] = stanza + self['forwarded']['stanza'] = stanza class SentCarbon(ElementBase): name = 'sent' - namespace = 'urn:xmpp:carbons:1' + namespace = 'urn:xmpp:carbons:2' plugin_attrib = 'carbon_sent' interfaces = set(['carbon_sent']) is_extension = True def get_carbon_sent(self): - return self.parent()['forwarded']['stanza'] + return self['forwarded']['stanza'] def del_carbon_sent(self): - del self.parent()['forwarded']['stanza'] + del self['forwarded']['stanza'] def set_carbon_sent(self, stanza): - self.parent()['forwarded']['stanza'] = stanza + self['forwarded']['stanza'] = stanza class PrivateCarbon(ElementBase): name = 'private' - namespace = 'urn:xmpp:carbons:1' + namespace = 'urn:xmpp:carbons:2' plugin_attrib = 'carbon_private' interfaces = set() class CarbonEnable(ElementBase): name = 'enable' - namespace = 'urn:xmpp:carbons:1' + namespace = 'urn:xmpp:carbons:2' plugin_attrib = 'carbon_enable' interfaces = set() class CarbonDisable(ElementBase): name = 'disable' - namespace = 'urn:xmpp:carbons:1' + namespace = 'urn:xmpp:carbons:2' plugin_attrib = 'carbon_disable' interfaces = set() diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index 4f58953b..08ce702a 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -662,7 +662,7 @@ class ElementBase(object): full_attrib = attrib attrib_lang = ('%s|' % attrib).split('|') attrib = attrib_lang[0] - lang = attrib_lang[1] or '' + lang = attrib_lang[1] or None kwargs = {} if lang and attrib in self.lang_interfaces: @@ -738,7 +738,7 @@ class ElementBase(object): full_attrib = attrib attrib_lang = ('%s|' % attrib).split('|') attrib = attrib_lang[0] - lang = attrib_lang[1] or '' + lang = attrib_lang[1] or None kwargs = {} if lang and attrib in self.lang_interfaces: @@ -824,7 +824,7 @@ class ElementBase(object): full_attrib = attrib attrib_lang = ('%s|' % attrib).split('|') attrib = attrib_lang[0] - lang = attrib_lang[1] or '' + lang = attrib_lang[1] or None kwargs = {} if lang and attrib in self.lang_interfaces: @@ -862,7 +862,7 @@ class ElementBase(object): del plugin[full_attrib] del self.plugins[(attrib, None)] else: - del self.plugins[(attrib, lang)] + del self.plugins[(attrib, plugin['lang'])] self.loaded_plugins.remove(attrib) try: self.xml.remove(plugin.xml) diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index dff32461..bea6e88f 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -58,9 +58,6 @@ WAIT_TIMEOUT = 0.1 #: a GIL increasing this value can provide better performance. HANDLER_THREADS = 1 -#: Flag indicating if the SSL library is available for use. -SSL_SUPPORT = True - #: The time in seconds to delay between attempts to resend data #: after an SSL error. SSL_RETRY_DELAY = 0.5 @@ -117,9 +114,6 @@ class XMLStream(object): """ def __init__(self, socket=None, host='', port=0): - #: Flag indicating if the SSL library is available for use. - self.ssl_support = SSL_SUPPORT - #: Most XMPP servers support TLSv1, but OpenFire in particular #: does not work well with it. For OpenFire, set #: :attr:`ssl_version` to use ``SSLv23``:: @@ -335,7 +329,7 @@ class XMLStream(object): #: ``_xmpp-client._tcp`` service. self.dns_service = None - self.add_event_handler('connected', self._handle_connected) + self.add_event_handler('connected', self._session_timeout_check) self.add_event_handler('disconnected', self._remove_schedules) self.add_event_handler('session_start', self._start_keepalive) self.add_event_handler('session_start', self._cert_expiration) @@ -506,7 +500,7 @@ class XMLStream(object): self.reconnect_delay = delay return False - if self.use_ssl and self.ssl_support: + if self.use_ssl: log.debug("Socket Wrapped for SSL") if self.ca_certs is None: cert_policy = ssl.CERT_NONE @@ -535,7 +529,7 @@ class XMLStream(object): log.debug("Connecting to %s:%s", domain, self.address[1]) self.socket.connect(self.address) - if self.use_ssl and self.ssl_support: + if self.use_ssl: try: self.socket.do_handshake() except (Socket.error, ssl.SSLError): @@ -630,7 +624,7 @@ class XMLStream(object): serr.errno, serr.strerror) return False - def _handle_connected(self, event=None): + def _session_timeout_check(self, event=None): """ Add check to ensure that a session is established within a reasonable amount of time. @@ -823,58 +817,55 @@ class XMLStream(object): If the handshake is successful, the XML stream will need to be restarted. """ - if self.ssl_support: - log.info("Negotiating TLS") - log.info("Using SSL version: %s", str(self.ssl_version)) - if self.ca_certs is None: - cert_policy = ssl.CERT_NONE - else: - cert_policy = ssl.CERT_REQUIRED - - ssl_socket = ssl.wrap_socket(self.socket, - certfile=self.certfile, - keyfile=self.keyfile, - ssl_version=self.ssl_version, - do_handshake_on_connect=False, - ca_certs=self.ca_certs, - cert_reqs=cert_policy) + log.info("Negotiating TLS") + log.info("Using SSL version: %s", str(self.ssl_version)) + if self.ca_certs is None: + cert_policy = ssl.CERT_NONE + else: + cert_policy = ssl.CERT_REQUIRED + + ssl_socket = ssl.wrap_socket(self.socket, + certfile=self.certfile, + keyfile=self.keyfile, + ssl_version=self.ssl_version, + do_handshake_on_connect=False, + ca_certs=self.ca_certs, + cert_reqs=cert_policy) + + if hasattr(self.socket, 'socket'): + # We are using a testing socket, so preserve the top + # layer of wrapping. + self.socket.socket = ssl_socket + else: + self.socket = ssl_socket - if hasattr(self.socket, 'socket'): - # We are using a testing socket, so preserve the top - # layer of wrapping. - self.socket.socket = ssl_socket + try: + self.socket.do_handshake() + except (Socket.error, ssl.SSLError): + log.error('CERT: Invalid certificate trust chain.') + if not self.event_handled('ssl_invalid_chain'): + self.disconnect(self.auto_reconnect, send_close=False) else: - self.socket = ssl_socket - - try: - self.socket.do_handshake() - except (Socket.error, ssl.SSLError): - log.error('CERT: Invalid certificate trust chain.') - if not self.event_handled('ssl_invalid_chain'): - self.disconnect(self.auto_reconnect, send_close=False) - else: - self.event('ssl_invalid_chain', direct=True) - return False + self._der_cert = self.socket.getpeercert(binary_form=True) + self.event('ssl_invalid_chain', direct=True) + return False - self._der_cert = self.socket.getpeercert(binary_form=True) - pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert) - log.debug('CERT: %s', pem_cert) - self.event('ssl_cert', pem_cert, direct=True) + self._der_cert = self.socket.getpeercert(binary_form=True) + pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert) + log.debug('CERT: %s', pem_cert) + self.event('ssl_cert', pem_cert, direct=True) - try: - cert.verify(self._expected_server_name, self._der_cert) - except cert.CertificateError as err: - if not self.event_handled('ssl_invalid_cert'): - log.error(err.message) - self.disconnect(self.auto_reconnect, send_close=False) - else: - self.event('ssl_invalid_cert', pem_cert, direct=True) + try: + cert.verify(self._expected_server_name, self._der_cert) + except cert.CertificateError as err: + if not self.event_handled('ssl_invalid_cert'): + log.error(err.message) + self.disconnect(self.auto_reconnect, send_close=False) + else: + self.event('ssl_invalid_cert', pem_cert, direct=True) - self.set_socket(self.socket) - return True - else: - log.warning("Tried to enable TLS, but ssl module not found.") - return False + self.set_socket(self.socket) + return True def _cert_expiration(self, event): """Schedule an event for when the TLS certificate expires.""" |