Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.html1
-rw-r--r--src/adhoc_commands.py32
-rw-r--r--src/chat_control.py9
-rw-r--r--src/common/atom.py14
-rw-r--r--src/common/caps_cache.py10
-rw-r--r--src/common/commands.py24
-rw-r--r--src/common/connection.py316
-rw-r--r--src/common/connection_handlers.py227
-rw-r--r--src/common/connection_handlers_events.py130
-rw-r--r--src/common/dataforms.py26
-rw-r--r--src/common/gajim.py21
-rw-r--r--src/common/ged.py2
-rw-r--r--src/common/helpers.py57
-rw-r--r--src/common/jingle.py22
-rw-r--r--src/common/jingle_content.py28
-rw-r--r--src/common/jingle_ft.py24
-rw-r--r--src/common/jingle_ftstates.py10
-rw-r--r--src/common/jingle_rtp.py16
-rw-r--r--src/common/jingle_session.py79
-rw-r--r--src/common/jingle_transport.py36
-rw-r--r--src/common/jingle_xtls.py11
-rw-r--r--src/common/message_archiving.py44
-rw-r--r--src/common/pep.py43
-rw-r--r--src/common/protocol/bytestream.py159
-rw-r--r--src/common/proxy65_manager.py14
-rw-r--r--src/common/pubsub.py46
-rw-r--r--src/common/resolver.py4
-rw-r--r--src/common/socks5.py2
-rw-r--r--src/common/stanza_session.py265
-rw-r--r--src/common/xmpp/__init__.py18
-rw-r--r--src/common/xmpp/auth_nb.py724
-rw-r--r--src/common/xmpp/bosh.py581
-rw-r--r--src/common/xmpp/c14n.py59
-rw-r--r--src/common/xmpp/client_nb.py629
-rw-r--r--src/common/xmpp/dispatcher_nb.py639
-rw-r--r--src/common/xmpp/features_nb.py218
-rw-r--r--src/common/xmpp/idlequeue.py550
-rw-r--r--src/common/xmpp/plugin.py96
-rw-r--r--src/common/xmpp/protocol.py1489
-rw-r--r--src/common/xmpp/proxy_connectors.py238
-rw-r--r--src/common/xmpp/roster_nb.py368
-rw-r--r--src/common/xmpp/simplexml.py692
-rw-r--r--src/common/xmpp/smacks.py132
-rw-r--r--src/common/xmpp/stringprepare.py238
-rw-r--r--src/common/xmpp/tls_nb.py461
-rw-r--r--src/common/xmpp/transports_nb.py786
-rw-r--r--src/common/zeroconf/client_zeroconf.py31
-rw-r--r--src/common/zeroconf/connection_handlers_zeroconf.py10
-rw-r--r--src/common/zeroconf/connection_zeroconf.py6
-rw-r--r--src/dataforms_widget.py2
-rw-r--r--src/disco.py20
-rw-r--r--src/filetransfers_window.py6
-rw-r--r--src/gajim.py6
-rw-r--r--src/groups.py5
-rw-r--r--src/gui_interface.py4
-rw-r--r--src/gui_menu_builder.py3
-rw-r--r--src/negotiation.py16
-rw-r--r--src/roster_window.py2
-rw-r--r--src/session.py2
59 files changed, 898 insertions, 8805 deletions
diff --git a/README.html b/README.html
index 7cb2f7aea..38861e74b 100644
--- a/README.html
+++ b/README.html
@@ -16,6 +16,7 @@
<ul>
<li>python2.5 or higher</li>
<li>pygtk2.22 or higher</li>
+<li>python-nbxmpp</li>
</ul>
<h2>Optional Runtime Requirements</h2>
diff --git a/src/adhoc_commands.py b/src/adhoc_commands.py
index bc947d49d..8e0859512 100644
--- a/src/adhoc_commands.py
+++ b/src/adhoc_commands.py
@@ -28,7 +28,9 @@
import gobject
import gtk
-from common import xmpp, gajim, dataforms
+import nbxmpp
+from common import gajim
+from common import dataforms
import gtkgui_helpers
import dialogs
@@ -386,7 +388,7 @@ class CommandWindow:
self.send_command(action)
def stage3_next_form(self, command):
- if not isinstance(command, xmpp.Node):
+ if not isinstance(command, nbxmpp.Node):
self.stage5(error=_('Service sent malformed data'), senderror=True)
return
@@ -506,8 +508,8 @@ class CommandWindow:
if errorid:
# we've got error code, display appropriate message
try:
- errorname = xmpp.NS_STANZAS + ' ' + str(errorid)
- errordesc = xmpp.ERRORS[errorname][2]
+ errorname = nbxmpp.NS_STANZAS + ' ' + str(errorid)
+ errordesc = nbxmpp.ERRORS[errorname][2]
error = errordesc.decode('utf-8')
del errorname, errordesc
except KeyError: # when stanza doesn't have error description
@@ -570,9 +572,9 @@ class CommandWindow:
"""
Request the command list. Change stage on delivery
"""
- query = xmpp.Iq(typ='get', to=xmpp.JID(self.jid),
- queryNS=xmpp.NS_DISCO_ITEMS)
- query.setQuerynode(xmpp.NS_COMMANDS)
+ query = nbxmpp.Iq(typ='get', to=xmpp.JID(self.jid),
+ queryNS=nbxmpp.NS_DISCO_ITEMS)
+ query.setQuerynode(nbxmpp.NS_COMMANDS)
def callback(response):
'''Called on response to query.'''
@@ -580,14 +582,14 @@ class CommandWindow:
# is error => error stage
error = response.getError()
if error:
- # extracting error description from xmpp/protocol.py
- self.stage5(errorid = error)
+ # extracting error description
+ self.stage5(errorid=error)
return
# no commands => no commands stage
# commands => command selection stage
query = response.getTag('query')
- if query and query.getAttr('node') == xmpp.NS_COMMANDS:
+ if query and query.getAttr('node') == nbxmpp.NS_COMMANDS:
items = query.getTags('item')
else:
items = []
@@ -609,9 +611,9 @@ class CommandWindow:
assert isinstance(self.commandnode, unicode)
assert action in ('execute', 'prev', 'next', 'complete')
- stanza = xmpp.Iq(typ='set', to=self.jid)
- cmdnode = stanza.addChild('command', namespace=xmpp.NS_COMMANDS, attrs={
- 'node':self.commandnode, 'action':action})
+ stanza = nbxmpp.Iq(typ='set', to=self.jid)
+ cmdnode = stanza.addChild('command', namespace=nbxmpp.NS_COMMANDS,
+ attrs={'node':self.commandnode, 'action':action})
if self.sessionid:
cmdnode.setAttr('sessionid', self.sessionid)
@@ -636,8 +638,8 @@ class CommandWindow:
assert self.commandnode
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', namespace=xmpp.NS_COMMANDS, attrs={
+ stanza = nbxmpp.Iq(typ='set', to=self.jid)
+ stanza.addChild('command', namespace=nbxmpp.NS_COMMANDS, attrs={
'node':self.commandnode,
'sessionid':self.sessionid,
'action':'cancel'
diff --git a/src/chat_control.py b/src/chat_control.py
index 76a4ef8fb..466ce7ba0 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -51,10 +51,11 @@ from common.stanza_session import EncryptedStanzaSession, ArchivingStanzaSession
from common.contacts import GC_Contact
from common.logger import constants
from common.pep import MOODS, ACTIVITIES
-from common.xmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
-from common.xmpp.protocol import NS_RECEIPTS, NS_ESESSION
-from common.xmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_JINGLE_ICE_UDP, NS_JINGLE_FILE_TRANSFER
-from common.xmpp.protocol import NS_CHATSTATES
+from nbxmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
+from nbxmpp.protocol import NS_RECEIPTS, NS_ESESSION
+from nbxmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO
+from nbxmpp.protocol import NS_JINGLE_ICE_UDP, NS_JINGLE_FILE_TRANSFER
+from nbxmpp.protocol import NS_CHATSTATES
from common.connection_handlers_events import MessageOutgoingEvent
from common.exceptions import GajimGeneralException
diff --git a/src/common/atom.py b/src/common/atom.py
index b642f8b52..baa3b02d7 100644
--- a/src/common/atom.py
+++ b/src/common/atom.py
@@ -29,10 +29,10 @@ if you need
# suggestion: rewrite functions that return dates to return standard python time tuples,
# exteneded to contain timezone
-import xmpp
+import nbxmpp
import time
-class PersonConstruct(xmpp.Node, object):
+class PersonConstruct(nb.Node, object):
"""
Not used for now, as we don't need authors/contributors in pubsub.com feeds.
They rarely exist there
@@ -40,7 +40,7 @@ class PersonConstruct(xmpp.Node, object):
def __init__(self, node):
''' Create person construct from node. '''
- xmpp.Node.__init__(self, node=node)
+ nbxmpp.Node.__init__(self, node=node)
def get_name(self):
return self.getTagData('name')
@@ -63,14 +63,14 @@ class PersonConstruct(xmpp.Node, object):
'''Conveys an e-mail address associated with the person. Might be None when
not set.''')
-class Entry(xmpp.Node, object):
+class Entry(nbxmpp.Node, object):
def __init__(self, node=None):
- xmpp.Node.__init__(self, 'entry', node=node)
+ nbxmpp.Node.__init__(self, 'entry', node=node)
def __repr__(self):
return '<Atom:Entry object of id="%r">' % self.getAttr('id')
-class OldEntry(xmpp.Node, object):
+class OldEntry(nbxmpp.Node, object):
"""
Parser for feeds from pubsub.com. They use old Atom 0.3 format with their
extensions
@@ -78,7 +78,7 @@ class OldEntry(xmpp.Node, object):
def __init__(self, node=None):
''' Create new Atom 0.3 entry object. '''
- xmpp.Node.__init__(self, 'entry', node=node)
+ nbxmpp.Node.__init__(self, 'entry', node=node)
def __repr__(self):
return '<Atom0.3:Entry object of id="%r">' % self.getAttr('id')
diff --git a/src/common/caps_cache.py b/src/common/caps_cache.py
index 33bdb6afd..6c8286188 100644
--- a/src/common/caps_cache.py
+++ b/src/common/caps_cache.py
@@ -37,11 +37,13 @@ import hashlib
import logging
log = logging.getLogger('gajim.c.caps_cache')
-from common.xmpp import (NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION, NS_CHATSTATES,
- NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_CAPS, NS_JINGLE_FILE_TRANSFER)
+from nbxmpp import (NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION, NS_CHATSTATES,
+ NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_CAPS,
+ NS_JINGLE_FILE_TRANSFER)
# Features where we cannot safely assume that the other side supports them
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION,
- NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_JINGLE_FILE_TRANSFER]
+ NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO,
+ NS_JINGLE_FILE_TRANSFER]
# Query entry status codes
NEW = 0
@@ -96,7 +98,7 @@ def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'):
"""
Compute caps hash according to XEP-0115, V1.5
- dataforms are xmpp.DataForms objects as common.dataforms don't allow several
+ dataforms are nbxmpp.DataForms objects as common.dataforms don't allow several
values without a field type list-multi
"""
def sort_identities_func(i1, i2):
diff --git a/src/common/commands.py b/src/common/commands.py
index 969d0e81a..4c2c90ad5 100644
--- a/src/common/commands.py
+++ b/src/common/commands.py
@@ -22,7 +22,7 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
-import xmpp
+import nbxmpp
import helpers
import dataforms
import gajim
@@ -33,7 +33,7 @@ log = logging.getLogger('gajim.c.commands')
class AdHocCommand:
commandnode = 'command'
commandname = 'The Command'
- commandfeatures = (xmpp.NS_DATA,)
+ commandfeatures = (nbxmpp.NS_DATA,)
@staticmethod
def isVisibleFor(samejid):
@@ -56,7 +56,7 @@ class AdHocCommand:
assert status in ('executing', 'completed', 'canceled')
response = request.buildReply('result')
- cmd = response.getTag('command', namespace=xmpp.NS_COMMANDS)
+ cmd = response.getTag('command', namespace=nbxmpp.NS_COMMANDS)
cmd.setAttr('sessionid', self.sessionid)
cmd.setAttr('node', self.commandnode)
cmd.setAttr('status', status)
@@ -72,8 +72,8 @@ class AdHocCommand:
return response, cmd
def badRequest(self, stanza):
- self.connection.connection.send(xmpp.Error(stanza, xmpp.NS_STANZAS + \
- ' bad-request'))
+ self.connection.connection.send(nbxmpp.Error(stanza,
+ nbxmpp.NS_STANZAS + ' bad-request'))
def cancel(self, request):
response = self.buildResponse(request, status = 'canceled')[0]
@@ -354,14 +354,14 @@ class ConnectionCommands:
"""
Test if the bare jid given is the same as our bare jid
"""
- return xmpp.JID(jid).getStripped() == self.getOurBareJID()
+ return nbxmpp.JID(jid).getStripped() == self.getOurBareJID()
def commandListQuery(self, con, iq_obj):
iq = iq_obj.buildReply('result')
jid = helpers.get_full_jid_from_iq(iq_obj)
q = iq.getTag('query')
# buildReply don't copy the node attribute. Re-add it
- q.setAttr('node', xmpp.NS_COMMANDS)
+ q.setAttr('node', nbxmpp.NS_COMMANDS)
for node, cmd in self.__commands.iteritems():
if cmd.isVisibleFor(self.isSameJID(jid)):
@@ -394,7 +394,7 @@ class ConnectionCommands:
q.addChild('identity', attrs = {'type': 'command-node',
'category': 'automation',
'name': cmd.commandname})
- q.addChild('feature', attrs = {'var': xmpp.NS_COMMANDS})
+ q.addChild('feature', attrs = {'var': nbxmpp.NS_COMMANDS})
for feature in cmd.commandfeatures:
q.addChild('feature', attrs = {'var': feature})
@@ -436,8 +436,8 @@ class ConnectionCommands:
# and command exist
if node not in self.__commands.keys():
self.connection.send(
- xmpp.Error(iq_obj, xmpp.NS_STANZAS + ' item-not-found'))
- raise xmpp.NodeProcessed
+ nbxmpp.Error(iq_obj, nbxmpp.NS_STANZAS + ' item-not-found'))
+ raise nbxmpp.NodeProcessed
newcmd = self.__commands[node]
if not newcmd.isVisibleFor(self.isSameJID(jid)):
@@ -451,7 +451,7 @@ class ConnectionCommands:
rc = obj.execute(iq_obj)
if rc:
self.__sessions[(jid, sessionid, node)] = obj
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
# the command is already running, check for it
magictuple = (jid, sessionid, node)
@@ -486,4 +486,4 @@ class ConnectionCommands:
if not rc:
del self.__sessions[magictuple]
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
diff --git a/src/common/connection.py b/src/common/connection.py
index 871ec3cc5..25208946a 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -52,7 +52,7 @@ import signal
if os.name != 'nt':
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
-import common.xmpp
+import nbxmpp
from common import helpers
from common import gajim
from common import gpg
@@ -61,7 +61,7 @@ from common import exceptions
from common import check_X509
from connection_handlers import *
-from xmpp import Smacks
+from nbxmpp import Smacks
from string import Template
import logging
log = logging.getLogger('gajim.c.connection')
@@ -357,21 +357,21 @@ class CommonConnection:
label, forward_from, delayed, session, form_node, user_nick, attention,
callback):
if type_ == 'chat':
- msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ=type_,
+ msg_iq = nbxmpp.Message(to=fjid, body=msgtxt, typ=type_,
xhtml=xhtml)
else:
if subject:
- msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
+ msg_iq = nbxmpp.Message(to=fjid, body=msgtxt, typ='normal',
subject=subject, xhtml=xhtml)
else:
- msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ='normal',
+ msg_iq = nbxmpp.Message(to=fjid, body=msgtxt, typ='normal',
xhtml=xhtml)
if msg_id:
msg_iq.setID(msg_id)
if msgenc:
- msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc)
+ msg_iq.setTag(nbxmpp.NS_ENCRYPTED + ' x').setData(msgenc)
if form_node:
msg_iq.addChild(node=form_node)
@@ -380,7 +380,7 @@ class CommonConnection:
# XEP-0172: user_nickname
if user_nick:
- msg_iq.setTag('nick', namespace = common.xmpp.NS_NICK).setData(
+ msg_iq.setTag('nick', namespace = nbxmpp.NS_NICK).setData(
user_nick)
# TODO: We might want to write a function so we don't need to
@@ -399,7 +399,7 @@ class CommonConnection:
if forward_from:
addresses = msg_iq.addChild('addresses',
- namespace=common.xmpp.NS_ADDRESS)
+ namespace=nbxmpp.NS_ADDRESS)
addresses.addChild('address', attrs = {'type': 'ofrom',
'jid': forward_from})
@@ -408,14 +408,14 @@ class CommonConnection:
our_jid = gajim.get_jid_from_account(self.name) + '/' + \
self.server_resource
timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(delayed))
- msg_iq.addChild('delay', namespace=common.xmpp.NS_DELAY2,
+ msg_iq.addChild('delay', namespace=nbxmpp.NS_DELAY2,
attrs={'from': our_jid, 'stamp': timestamp})
# XEP-0184
if msgtxt and gajim.config.get_per('accounts', self.name,
'request_receipt') and contact and contact.supports(
- common.xmpp.NS_RECEIPTS):
- msg_iq.setTag('request', namespace=common.xmpp.NS_RECEIPTS)
+ nbxmpp.NS_RECEIPTS):
+ msg_iq.setTag('request', namespace=nbxmpp.NS_RECEIPTS)
if session:
# XEP-0201
@@ -428,7 +428,7 @@ class CommonConnection:
# XEP-0224
if attention:
- msg_iq.setTag('attention', namespace=common.xmpp.NS_ATTENTION)
+ msg_iq.setTag('attention', namespace=nbxmpp.NS_ATTENTION)
if callback:
callback(jid, msg, keyID, forward_from, session, original_message,
@@ -453,7 +453,7 @@ class CommonConnection:
try:
if xhtml and gajim.config.get('log_xhtml_messages'):
log_msg = '<body xmlns="%s">%s</body>' % (
- common.xmpp.NS_XHTML, xhtml)
+ nbxmpp.NS_XHTML, xhtml)
gajim.logger.write(kind, jid, log_msg)
except exceptions.PysqliteOperationalError, e:
self.dispatch('DB_ERROR', (_('Disk Write Error'),
@@ -546,8 +546,7 @@ class CommonConnection:
to_whom_jid = jid
if resource:
to_whom_jid += '/' + resource
- iq = common.xmpp.Iq(to=to_whom_jid, typ='get', queryNS=\
- common.xmpp.NS_LAST)
+ iq = nbxmpp.Iq(to=to_whom_jid, typ='get', queryNS=nbxmpp.NS_LAST)
id_ = self.connection.getAnID()
iq.setID(id_)
if groupchat_jid:
@@ -615,10 +614,10 @@ class CommonConnection:
def _event_dispatcher(self, realm, event, data):
if realm == '':
- if event == common.xmpp.transports_nb.DATA_RECEIVED:
+ if event == nbxmpp.transports_nb.DATA_RECEIVED:
gajim.nec.push_incoming_event(StanzaReceivedEvent(None,
conn=self, stanza_str=unicode(data, errors='ignore')))
- elif event == common.xmpp.transports_nb.DATA_SENT:
+ elif event == nbxmpp.transports_nb.DATA_SENT:
gajim.nec.push_incoming_event(StanzaSentEvent(None, conn=self,
stanza_str=unicode(data)))
@@ -646,7 +645,7 @@ class CommonConnection:
if show == 'offline':
self.connected = 0
if self.connection:
- p = common.xmpp.Presence(typ = 'unavailable')
+ p = nbxmpp.Presence(typ = 'unavailable')
p = self.add_sha(p, False)
if msg:
p.setStatus(msg)
@@ -868,8 +867,8 @@ class Connection(CommonConnection, ConnectionHandlers):
def _event_dispatcher(self, realm, event, data):
CommonConnection._event_dispatcher(self, realm, event, data)
- if realm == common.xmpp.NS_REGISTER:
- if event == common.xmpp.features_nb.REGISTER_DATA_RECEIVED:
+ if realm == nbxmpp.NS_REGISTER:
+ if event == nbxmpp.features_nb.REGISTER_DATA_RECEIVED:
# data is (agent, DataFrom, is_form, error_msg)
if self.new_account_info and \
self.new_account_info['hostname'] == data[0]:
@@ -887,7 +886,7 @@ class Connection(CommonConnection, ConnectionHandlers):
helpers.replace_dataform_media(conf, data[4])
if self.new_account_form:
def _on_register_result(result):
- if not common.xmpp.isResultNode(result):
+ if not nbxmpp.isResultNode(result):
gajim.nec.push_incoming_event(AccountNotCreatedEvent(
None, conn=self, reason=result.getError()))
return
@@ -908,7 +907,7 @@ class Connection(CommonConnection, ConnectionHandlers):
# typed, so send them
if is_form:
#TODO: Check if form has changed
- iq = common.xmpp.Iq('set', common.xmpp.NS_REGISTER,
+ iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER,
to=self._hostname)
iq.setTag('query').addChild(node=self.new_account_form)
self.connection.SendAndCallForResponse(iq,
@@ -922,7 +921,7 @@ class Connection(CommonConnection, ConnectionHandlers):
gajim.nec.push_incoming_event(AccountNotCreatedEvent(
None, conn=self, reason=reason))
return
- common.xmpp.features_nb.register(self.connection,
+ nbxmpp.features_nb.register(self.connection,
self._hostname, self.new_account_form,
_on_register_result)
return
@@ -944,12 +943,12 @@ class Connection(CommonConnection, ConnectionHandlers):
gajim.nec.push_incoming_event(RegisterAgentInfoReceivedEvent(
None, conn=self, agent=data[0], config=conf,
is_form=is_form))
- elif realm == common.xmpp.NS_PRIVACY:
- if event == common.xmpp.features_nb.PRIVACY_LISTS_RECEIVED:
+ elif realm == nbxmpp.NS_PRIVACY:
+ if event == nbxmpp.features_nb.PRIVACY_LISTS_RECEIVED:
# data is (list)
gajim.nec.push_incoming_event(PrivacyListsReceivedEvent(None,
conn=self, lists_list=data))
- elif event == common.xmpp.features_nb.PRIVACY_LIST_RECEIVED:
+ elif event == nbxmpp.features_nb.PRIVACY_LIST_RECEIVED:
# data is (resp)
if not data:
return
@@ -971,7 +970,7 @@ class Connection(CommonConnection, ConnectionHandlers):
'order':dict_item['order'], 'child':childs})
gajim.nec.push_incoming_event(PrivacyListReceivedEvent(None,
conn=self, list_name=name, rules=rules))
- elif event == common.xmpp.features_nb.PRIVACY_LISTS_ACTIVE_DEFAULT:
+ elif event == nbxmpp.features_nb.PRIVACY_LISTS_ACTIVE_DEFAULT:
# data is (dict)
gajim.nec.push_incoming_event(PrivacyListActiveDefaultEvent(
None, conn=self, active_list=data['active'],
@@ -1116,7 +1115,7 @@ class Connection(CommonConnection, ConnectionHandlers):
if self._proxy and self._proxy['type']=='bosh':
# with BOSH, we can't do TLS negotiation with <starttls>, we do only "plain"
# connection and TLS with handshake right after TCP connecting ("ssl")
- scheme = common.xmpp.transports_nb.urisplit(self._proxy['bosh_uri'])[0]
+ scheme = nbxmpp.transports_nb.urisplit(self._proxy['bosh_uri'])[0]
if scheme=='https':
self._connection_types = ['ssl']
else:
@@ -1172,14 +1171,14 @@ class Connection(CommonConnection, ConnectionHandlers):
mycerts = common.gajim.MY_CACERTS
secure_tuple = (self._current_type, cacerts, mycerts)
- con = common.xmpp.NonBlockingClient(
+ con = nbxmpp.NonBlockingClient(
domain=self._hostname,
caller=self,
idlequeue=gajim.idlequeue)
self.last_connection = con
# increase default timeout for server responses
- common.xmpp.dispatcher_nb.DEFAULT_TIMEOUT_SECONDS = \
+ nbxmpp.dispatcher_nb.DEFAULT_TIMEOUT_SECONDS = \
self.try_connecting_for_foo_secs
# FIXME: this is a hack; need a better way
if self.on_connect_success == self._on_new_account:
@@ -1231,9 +1230,9 @@ class Connection(CommonConnection, ConnectionHandlers):
sectxt = _('Check your connection or try again later.')
if self.streamError:
# show error dialog
- key = common.xmpp.NS_XMPP_STREAMS + ' ' + self.streamError
- if key in common.xmpp.ERRORS:
- sectxt2 = _('Server replied: %s') % common.xmpp.ERRORS[key][2]
+ key = nbxmpp.NS_XMPP_STREAMS + ' ' + self.streamError
+ if key in nbxmpp.ERRORS:
+ sectxt2 = _('Server replied: %s') % nbxmpp.ERRORS[key][2]
gajim.nec.push_incoming_event(InformationEvent(None,
conn=self, level='error', pri_txt=pritxt,
sec_txt='%s\n%s' % (sectxt2, sectxt)))
@@ -1433,7 +1432,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def get_privacy_lists(self):
if not gajim.account_is_connected(self.name):
return
- common.xmpp.features_nb.getPrivacyLists(self.connection)
+ nbxmpp.features_nb.getPrivacyLists(self.connection)
def send_keepalive(self):
# nothing received for the last foo seconds
@@ -1460,12 +1459,12 @@ class Connection(CommonConnection, ConnectionHandlers):
else:
to = gajim.config.get_per('accounts', self.name, 'hostname')
self.awaiting_xmpp_ping_id = id_
- iq = common.xmpp.Iq('get', to=to)
- iq.addChild(name = 'ping', namespace = common.xmpp.NS_PING)
+ iq = nbxmpp.Iq('get', to=to)
+ iq.addChild(name='ping', namespace=nbxmpp.NS_PING)
iq.setID(id_)
def _on_response(resp):
timePong = time_time()
- if not common.xmpp.isResultNode(resp):
+ if not nbxmpp.isResultNode(resp):
gajim.nec.push_incoming_event(PingErrorEvent(None, conn=self,
contact=pingTo))
return
@@ -1478,12 +1477,12 @@ class Connection(CommonConnection, ConnectionHandlers):
else:
self.connection.SendAndCallForResponse(iq, self._on_xmpp_ping_answer)
gajim.idlequeue.set_alarm(self.check_pingalive, gajim.config.get_per(
- 'accounts', self.name, 'time_for_ping_alive_answer'))
+ 'accounts', self.name, 'time_for_ping_alive_answer'))
def get_active_default_lists(self):
if not gajim.account_is_connected(self.name):
return
- common.xmpp.features_nb.getActiveAndDefaultPrivacyLists(self.connection)
+ nbxmpp.features_nb.getActiveAndDefaultPrivacyLists(self.connection)
def del_privacy_list(self, privacy_list):
if not gajim.account_is_connected(self.name):
@@ -1498,41 +1497,42 @@ class Connection(CommonConnection, ConnectionHandlers):
'list'), sec_txt=_('Privacy list %s has not been removed. '
'It is maybe active in one of your connected resources. '
'Deactivate it and try again.') % privacy_list))
- common.xmpp.features_nb.delPrivacyList(self.connection, privacy_list,
- _on_del_privacy_list_result)
+ nbxmpp.features_nb.delPrivacyList(self.connection, privacy_list,
+ _on_del_privacy_list_result)
def get_privacy_list(self, title):
if not gajim.account_is_connected(self.name):
return
- common.xmpp.features_nb.getPrivacyList(self.connection, title)
+ nbxmpp.features_nb.getPrivacyList(self.connection, title)
def set_privacy_list(self, listname, tags):
if not gajim.account_is_connected(self.name):
return
- common.xmpp.features_nb.setPrivacyList(self.connection, listname, tags)
+ nbxmpp.features_nb.setPrivacyList(self.connection, listname, tags)
def set_active_list(self, listname):
if not gajim.account_is_connected(self.name):
return
- common.xmpp.features_nb.setActivePrivacyList(self.connection, listname, 'active')
+ nbxmpp.features_nb.setActivePrivacyList(self.connection, listname,
+ 'active')
def set_default_list(self, listname):
if not gajim.account_is_connected(self.name):
return
- common.xmpp.features_nb.setDefaultPrivacyList(self.connection, listname)
+ nbxmpp.features_nb.setDefaultPrivacyList(self.connection, listname)
def build_privacy_rule(self, name, action, order=1):
"""
Build a Privacy rule stanza for invisibility
"""
- iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
+ iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, xmlns='')
l = iq.setQuery().setTag('list', {'name': name})
i = l.setTag('item', {'action': action, 'order': str(order)})
i.setTag('presence-out')
return iq
def build_invisible_rule(self):
- iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
+ iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, xmlns='')
l = iq.setQuery().setTag('list', {'name': 'invisible'})
if self.name in gajim.interface.status_sent_to_groups and \
len(gajim.interface.status_sent_to_groups[self.name]) > 0:
@@ -1562,7 +1562,7 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
+ iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, xmlns='')
iq.setQuery().setTag('active', {'name': name})
self.connection.send(iq)
@@ -1581,7 +1581,7 @@ class Connection(CommonConnection, ConnectionHandlers):
# offline presence first as it's required by XEP-0126
if self.connected > 1 and self.privacy_rules_supported:
self.on_purpose = True
- p = common.xmpp.Presence(typ = 'unavailable')
+ p = nbxmpp.Presence(typ='unavailable')
p = self.add_sha(p, False)
if msg:
p.setStatus(msg)
@@ -1602,12 +1602,12 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connected = gajim.SHOW_LIST.index('invisible')
self.status = msg
priority = unicode(gajim.get_priority(self.name, 'invisible'))
- p = common.xmpp.Presence(priority = priority)
+ p = nbxmpp.Presence(priority=priority)
p = self.add_sha(p, True)
if msg:
p.setStatus(msg)
if signed:
- p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
+ p.setTag(nbxmpp.NS_SIGNED + ' x').setData(signed)
self.connection.send(p)
self.priority = priority
gajim.nec.push_incoming_event(OurShowEvent(None, conn=self,
@@ -1669,7 +1669,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def _request_privacy(self):
if not gajim.account_is_connected(self.name) or not self.connection:
return
- iq = common.xmpp.Iq('get', common.xmpp.NS_PRIVACY, xmlns = '')
+ iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY, xmlns='')
id_ = self.connection.getAnID()
iq.setID(id_)
self.awaiting_answers[id_] = (PRIVACY_ARRIVED, )
@@ -1704,44 +1704,43 @@ class Connection(CommonConnection, ConnectionHandlers):
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
our_jid = gajim.get_jid_from_account(self.name)
if obj.fjid == hostname:
- if common.xmpp.NS_GMAILNOTIFY in obj.features:
+ if nbxmpp.NS_GMAILNOTIFY in obj.features:
gajim.gmail_domains.append(obj.fjid)
self.request_gmail_notifications()
- if common.xmpp.NS_SECLABEL in obj.features:
+ if nbxmpp.NS_SECLABEL in obj.features:
self.seclabel_supported = True
for identity in obj.identities:
if identity['category'] == 'pubsub' and identity.get(
'type') == 'pep':
self.pep_supported = True
break
- if common.xmpp.NS_VCARD in obj.features:
+ if nbxmpp.NS_VCARD in obj.features:
self.vcard_supported = True
- if common.xmpp.NS_PUBSUB in obj.features:
+ if nbxmpp.NS_PUBSUB in obj.features:
self.pubsub_supported = True
- if common.xmpp.NS_PUBSUB_PUBLISH_OPTIONS in obj.features:
+ if nbxmpp.NS_PUBSUB_PUBLISH_OPTIONS in obj.features:
self.pubsub_publish_options_supported = True
else:
# Remove stored bookmarks accessible to everyone.
self.send_pb_purge(our_jid, 'storage:bookmarks')
self.send_pb_delete(our_jid, 'storage:bookmarks')
- if common.xmpp.NS_ARCHIVE in obj.features:
+ if nbxmpp.NS_ARCHIVE in obj.features:
self.archiving_supported = True
- if common.xmpp.NS_ARCHIVE_AUTO in obj.features:
+ if nbxmpp.NS_ARCHIVE_AUTO in obj.features:
self.archive_auto_supported = True
- if common.xmpp.NS_ARCHIVE_MANAGE in obj.features:
+ if nbxmpp.NS_ARCHIVE_MANAGE in obj.features:
self.archive_manage_supported = True
- if common.xmpp.NS_ARCHIVE_MANUAL in obj.features:
+ if nbxmpp.NS_ARCHIVE_MANUAL in obj.features:
self.archive_manual_supported = True
- if common.xmpp.NS_ARCHIVE_PREF in obj.features:
+ if nbxmpp.NS_ARCHIVE_PREF in obj.features:
self.archive_pref_supported = True
- if common.xmpp.NS_CARBONS in obj.features and \
- gajim.config.get_per('accounts', self.name,
- 'enable_message_carbons'):
+ if nbxmpp.NS_CARBONS in obj.features and gajim.config.get_per(
+ 'accounts', self.name, 'enable_message_carbons'):
# Server supports carbons, activate it
- iq = common.xmpp.Iq('set')
- iq.setTag('enable', namespace=common.xmpp.NS_CARBONS)
+ iq = nbxmpp.Iq('set')
+ iq.setTag('enable', namespace=nbxmpp.NS_CARBONS)
self.connection.send(iq)
- if common.xmpp.NS_BYTESTREAM in obj.features and \
+ if nbxmpp.NS_BYTESTREAM in obj.features and \
gajim.config.get_per('accounts', self.name, 'use_ft_proxies'):
our_fjid = helpers.parse_jid(our_jid + '/' + \
self.server_resource)
@@ -1749,7 +1748,7 @@ class Connection(CommonConnection, ConnectionHandlers):
'test_ft_proxies_on_startup')
gajim.proxy65_manager.resolve(obj.fjid, self.connection,
our_fjid, default=self.name, testit=testit)
- if common.xmpp.NS_MUC in obj.features and is_muc:
+ if nbxmpp.NS_MUC in obj.features and is_muc:
type_ = transport_type or 'jabber'
self.muc_jid[type_] = obj.fjid
if transport_type:
@@ -1770,20 +1769,19 @@ class Connection(CommonConnection, ConnectionHandlers):
if not msg:
msg = ''
if show == 'offline':
- p = common.xmpp.Presence(typ = 'unavailable', to = jid)
+ p = nbxmpp.Presence(typ='unavailable', to=jid)
p = self.add_sha(p, False)
if msg:
p.setStatus(msg)
else:
signed = self.get_signed_presence(msg)
priority = unicode(gajim.get_priority(self.name, sshow))
- p = common.xmpp.Presence(typ = None, priority = priority, show = sshow,
- to = jid)
+ p = nbxmpp.Presence(typ=None, priority=priority, show=sshow, to=jid)
p = self.add_sha(p)
if msg:
p.setStatus(msg)
if signed:
- p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
+ p.setTag(nbxmpp.NS_SIGNED + ' x').setData(signed)
self.connection.send(p)
def _change_to_invisible(self, msg):
@@ -1802,24 +1800,24 @@ class Connection(CommonConnection, ConnectionHandlers):
def _update_status(self, show, msg):
xmpp_show = helpers.get_xmpp_show(show)
priority = unicode(gajim.get_priority(self.name, xmpp_show))
- p = common.xmpp.Presence(typ=None, priority=priority, show=xmpp_show)
+ p = nbxmpp.Presence(typ=None, priority=priority, show=xmpp_show)
p = self.add_sha(p)
if msg:
p.setStatus(msg)
signed = self.get_signed_presence(msg)
if signed:
- p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
+ p.setTag(nbxmpp.NS_SIGNED + ' x').setData(signed)
if self.connection:
self.connection.send(p)
self.priority = priority
gajim.nec.push_incoming_event(OurShowEvent(None, conn=self,
show=show))
- def send_motd(self, jid, subject = '', msg = '', xhtml = None):
+ def send_motd(self, jid, subject='', msg='', xhtml=None):
if not gajim.account_is_connected(self.name):
return
- msg_iq = common.xmpp.Message(to = jid, body = msg, subject = subject,
- xhtml = xhtml)
+ msg_iq = nbxmpp.Message(to=jid, body=msg, subject=subject,
+ xhtml=xhtml)
self.connection.send(msg_iq)
@@ -1887,8 +1885,8 @@ class Connection(CommonConnection, ConnectionHandlers):
for contact in contacts:
msg += '\n "%s" (%s)' % (contact.get_full_jid(),
contact.get_shown_name())
- msg_iq = common.xmpp.Message(to=jid, body=msg)
- x = msg_iq.addChild(name='x', namespace=common.xmpp.NS_ROSTERX)
+ msg_iq = nbxmpp.Message(to=jid, body=msg)
+ x = msg_iq.addChild(name='x', namespace=nbxmpp.NS_ROSTERX)
for contact in contacts:
x.addChild(name='item', attrs={'action': 'add', 'jid': contact.jid,
'name': contact.get_shown_name()})
@@ -1906,14 +1904,14 @@ class Connection(CommonConnection, ConnectionHandlers):
if not gajim.account_is_connected(self.name):
return
log.debug('ack\'ing subscription complete for %s' % jid)
- p = common.xmpp.Presence(jid, 'subscribe')
+ p = nbxmpp.Presence(jid, 'subscribe')
self.connection.send(p)
def ack_unsubscribed(self, jid):
if not gajim.account_is_connected(self.name):
return
log.debug('ack\'ing unsubscription complete for %s' % jid)
- p = common.xmpp.Presence(jid, 'unsubscribe')
+ p = nbxmpp.Presence(jid, 'unsubscribe')
self.connection.send(p)
def request_subscription(self, jid, msg='', name='', groups=[],
@@ -1927,16 +1925,16 @@ class Connection(CommonConnection, ConnectionHandlers):
infos = {'jid': jid}
if name:
infos['name'] = name
- iq = common.xmpp.Iq('set', common.xmpp.NS_ROSTER)
+ iq = nbxmpp.Iq('set', nbxmpp.NS_ROSTER)
q = iq.setQuery()
item = q.addChild('item', attrs=infos)
for g in groups:
item.addChild('group').setData(g)
self.connection.send(iq)
- p = common.xmpp.Presence(jid, 'subscribe')
+ p = nbxmpp.Presence(jid, 'subscribe')
if user_nick:
- p.setTag('nick', namespace = common.xmpp.NS_NICK).setData(user_nick)
+ p.setTag('nick', namespace = nbxmpp.NS_NICK).setData(user_nick)
p = self.add_sha(p)
if msg:
p.setStatus(msg)
@@ -1945,14 +1943,14 @@ class Connection(CommonConnection, ConnectionHandlers):
def send_authorization(self, jid):
if not gajim.account_is_connected(self.name):
return
- p = common.xmpp.Presence(jid, 'subscribed')
+ p = nbxmpp.Presence(jid, 'subscribed')
p = self.add_sha(p)
self.connection.send(p)
def refuse_authorization(self, jid):
if not gajim.account_is_connected(self.name):
return
- p = common.xmpp.Presence(jid, 'unsubscribed')
+ p = nbxmpp.Presence(jid, 'unsubscribed')
p = self.add_sha(p)
self.connection.send(p)
@@ -1972,7 +1970,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def unsubscribe_agent(self, agent):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq('set', common.xmpp.NS_REGISTER, to = agent)
+ iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
iq.setQuery().setTag('remove')
id_ = self.connection.getAnID()
iq.setID(id_)
@@ -2019,7 +2017,7 @@ class Connection(CommonConnection, ConnectionHandlers):
return
self.on_connect_failure = None
self.connection = con
- common.xmpp.features_nb.getRegInfo(con, self._hostname)
+ nbxmpp.features_nb.getRegInfo(con, self._hostname)
def request_os_info(self, jid, resource, groupchat_jid=None):
"""
@@ -2035,8 +2033,7 @@ class Connection(CommonConnection, ConnectionHandlers):
to_whom_jid = jid
if resource:
to_whom_jid += '/' + resource
- iq = common.xmpp.Iq(to=to_whom_jid, typ='get', queryNS=\
- common.xmpp.NS_VERSION)
+ iq = nbxmpp.Iq(to=to_whom_jid, typ='get', queryNS=nbxmpp.NS_VERSION)
id_ = self.connection.getAnID()
iq.setID(id_)
if groupchat_jid:
@@ -2058,8 +2055,8 @@ class Connection(CommonConnection, ConnectionHandlers):
to_whom_jid = jid
if resource:
to_whom_jid += '/' + resource
- iq = common.xmpp.Iq(to=to_whom_jid, typ='get')
- iq.addChild('time', namespace=common.xmpp.NS_TIME_REVISED)
+ iq = nbxmpp.Iq(to=to_whom_jid, typ='get')
+ iq.addChild('time', namespace=nbxmpp.NS_TIME_REVISED)
id_ = self.connection.getAnID()
iq.setID(id_)
if groupchat_jid:
@@ -2075,8 +2072,8 @@ class Connection(CommonConnection, ConnectionHandlers):
typ_ = 'set'
else:
typ_ = 'get'
- iq = common.xmpp.Iq(typ=typ_, to=jid)
- query = iq.addChild(name='query', namespace=common.xmpp.NS_GATEWAY)
+ iq = nbxmpp.Iq(typ=typ_, to=jid)
+ query = iq.addChild(name='query', namespace=nbxmpp.NS_GATEWAY)
if prompt:
query.setTagData('prompt', prompt)
self.connection.SendAndCallForResponse(iq, _on_prompt_result)
@@ -2087,8 +2084,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='get')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='get')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq2.addChild(name='gajim', namespace='gajim:prefs')
self.connection.send(iq)
@@ -2097,8 +2094,8 @@ class Connection(CommonConnection, ConnectionHandlers):
return
self.seclabel_catalogue_request(to, callback)
server = gajim.get_jid_from_account(self.name).split("@")[1] # Really, no better way?
- iq = common.xmpp.Iq(typ='get', to=server)
- iq2 = iq.addChild(name='catalog', namespace=common.xmpp.NS_SECLABEL_CATALOG)
+ iq = nbxmpp.Iq(typ='get', to=server)
+ iq2 = iq.addChild(name='catalog', namespace=nbxmpp.NS_SECLABEL_CATALOG)
iq2.setAttr('to', to)
self.connection.send(iq)
@@ -2135,8 +2132,8 @@ class Connection(CommonConnection, ConnectionHandlers):
def _request_bookmarks_xml(self):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='get')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='get')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq2.addChild(name='storage', namespace='storage:bookmarks')
self.connection.send(iq)
@@ -2170,7 +2167,7 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Node(tag='storage', attrs={'xmlns': 'storage:bookmarks'})
+ iq = nbxmpp.Node(tag='storage', attrs={'xmlns': 'storage:bookmarks'})
for bm in self.bookmarks:
iq2 = iq.addChild(name = "conference")
iq2.setAttr('jid', bm['jid'])
@@ -2189,11 +2186,11 @@ class Connection(CommonConnection, ConnectionHandlers):
if self.pubsub_supported and self.pubsub_publish_options_supported and \
storage_type != 'xml':
- options = common.xmpp.Node(common.xmpp.NS_DATA + ' x',
+ options = nbxmpp.Node(nbxmpp.NS_DATA + ' x',
attrs={'type': 'submit'})
f = options.addChild('field', attrs={'var': 'FORM_TYPE',
'type': 'hidden'})
- f.setTagData('value', common.xmpp.NS_PUBSUB_PUBLISH_OPTIONS)
+ f.setTagData('value', nbxmpp.NS_PUBSUB_PUBLISH_OPTIONS)
f = options.addChild('field', attrs={'var': 'pubsub#persist_items'})
f.setTagData('value', 'true')
f = options.addChild('field', attrs={'var': 'pubsub#access_model'})
@@ -2201,8 +2198,8 @@ class Connection(CommonConnection, ConnectionHandlers):
self.send_pb_publish('', 'storage:bookmarks', iq, 'current',
options=options)
if storage_type != 'pubsub':
- iqA = common.xmpp.Iq(typ='set')
- iqB = iqA.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iqA = nbxmpp.Iq(typ='set')
+ iqB = iqA.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iqB.addChild(node=iq)
self.connection.send(iqA)
@@ -2213,8 +2210,8 @@ class Connection(CommonConnection, ConnectionHandlers):
self.annotations = {}
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='get')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='get')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq2.addChild(name='storage', namespace='storage:rosternotes')
self.connection.send(iq)
@@ -2224,8 +2221,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='set')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='set')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq3 = iq2.addChild(name='storage', namespace='storage:rosternotes')
for jid in self.annotations.keys():
if self.annotations[jid]:
@@ -2240,8 +2237,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='get')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='get')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq2.addChild(name='roster', namespace='roster:delimiter')
id_ = self.connection.getAnID()
iq.setID(id_)
@@ -2254,8 +2251,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='set')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='set')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq3 = iq2.addChild(name='roster', namespace='roster:delimiter')
iq3.setData(delimiter)
@@ -2267,8 +2264,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='get')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='get')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq2.addChild(name='storage', namespace='storage:metacontacts')
id_ = self.connection.getAnID()
iq.setID(id_)
@@ -2281,8 +2278,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='set')
- iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE)
+ iq = nbxmpp.Iq(typ='set')
+ iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq3 = iq2.addChild(name='storage', namespace='storage:metacontacts')
for tag in tags_list:
for data in tags_list[tag]:
@@ -2290,14 +2287,14 @@ class Connection(CommonConnection, ConnectionHandlers):
dict_ = {'jid': jid, 'tag': tag}
if 'order' in data:
dict_['order'] = data['order']
- iq3.addChild(name = 'meta', attrs = dict_)
+ iq3.addChild(name='meta', attrs=dict_)
self.connection.send(iq)
def request_roster(self):
version = None
features = self.connection.Dispatcher.Stream.features
if features and features.getTag('ver',
- namespace=common.xmpp.NS_ROSTER_VER):
+ namespace=nbxmpp.NS_ROSTER_VER):
version = gajim.config.get_per('accounts', self.name,
'roster_version')
if version and not gajim.contacts.get_contacts_jid_list(
@@ -2313,26 +2310,26 @@ class Connection(CommonConnection, ConnectionHandlers):
if not gajim.account_is_connected(self.name):
return
show = helpers.get_xmpp_show(gajim.SHOW_LIST[self.connected])
- p = common.xmpp.Presence(to = agent, typ = ptype, show = show)
+ p = nbxmpp.Presence(to=agent, typ=ptype, show=show)
p = self.add_sha(p, ptype != 'unavailable')
self.connection.send(p)
def send_captcha(self, jid, form_node):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ='set', to=jid)
- captcha = iq.addChild(name='captcha', namespace=common.xmpp.NS_CAPTCHA)
+ iq = nbxmpp.Iq(typ='set', to=jid)
+ captcha = iq.addChild(name='captcha', namespace=nbxmpp.NS_CAPTCHA)
captcha.addChild(node=form_node)
self.connection.send(iq)
def check_unique_room_id_support(self, server, instance):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'get', to = server)
+ iq = nbxmpp.Iq(typ='get', to=server)
iq.setAttr('id', 'unique1')
- iq.addChild('unique', namespace=common.xmpp.NS_MUC_UNIQUE)
+ iq.addChild('unique', namespace=nbxmpp.NS_MUC_UNIQUE)
def _on_response(resp):
- if not common.xmpp.isResultNode(resp):
+ if not nbxmpp.isResultNode(resp):
gajim.nec.push_incoming_event(UniqueRoomIdNotSupportedEvent(
None, conn=self, instance=instance, server=server))
return
@@ -2369,7 +2366,7 @@ class Connection(CommonConnection, ConnectionHandlers):
last_log = 0
self.last_history_time[room_jid] = last_log
- p = common.xmpp.Presence(to='%s/%s' % (room_jid, nick),
+ p = nbxmpp.Presence(to='%s/%s' % (room_jid, nick),
show=show, status=self.status)
h = hmac.new(self.secret_hmac, room_jid).hexdigest()[:6]
id_ = self.connection.getAnID()
@@ -2379,7 +2376,7 @@ class Connection(CommonConnection, ConnectionHandlers):
p = self.add_sha(p)
self.add_lang(p)
if not change_nick:
- t = p.setTag(common.xmpp.NS_MUC + ' x')
+ t = p.setTag(nbxmpp.NS_MUC + ' x')
tags = {}
timeout = gajim.config.get_per('room', room_jid,
'muc_restore_timeout')
@@ -2407,13 +2404,13 @@ class Connection(CommonConnection, ConnectionHandlers):
t.setTagData('password', password)
self.connection.send(p)
- def send_gc_message(self, jid, msg, xhtml = None, label = None):
+ def send_gc_message(self, jid, msg, xhtml=None, label=None):
if not gajim.account_is_connected(self.name):
return
if not xhtml and gajim.config.get('rst_formatting_outgoing_messages'):
from common.rst_xhtml_generator import create_xhtml
xhtml = create_xhtml(msg)
- msg_iq = common.xmpp.Message(jid, msg, typ = 'groupchat', xhtml = xhtml)
+ msg_iq = nbxmpp.Message(jid, msg, typ='groupchat', xhtml=xhtml)
if label is not None:
msg_iq.addChild(node = label)
self.connection.send(msg_iq)
@@ -2423,22 +2420,22 @@ class Connection(CommonConnection, ConnectionHandlers):
def send_gc_subject(self, jid, subject):
if not gajim.account_is_connected(self.name):
return
- msg_iq = common.xmpp.Message(jid, typ = 'groupchat', subject = subject)
+ msg_iq = nbxmpp.Message(jid, typ='groupchat', subject=subject)
self.connection.send(msg_iq)
def request_gc_config(self, room_jid):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'get', queryNS = common.xmpp.NS_MUC_OWNER,
- to = room_jid)
+ iq = nbxmpp.Iq(typ='get', queryNS=nbxmpp.NS_MUC_OWNER,
+ to=room_jid)
self.add_lang(iq)
self.connection.send(iq)
def destroy_gc_room(self, room_jid, reason = '', jid = ''):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'set', queryNS = common.xmpp.NS_MUC_OWNER,
- to = room_jid)
+ iq = nbxmpp.Iq(typ='set', queryNS=nbxmpp.NS_MUC_OWNER,
+ to=room_jid)
destroy = iq.setQuery().setTag('destroy')
if reason:
destroy.setTagData('reason', reason)
@@ -2455,8 +2452,8 @@ class Connection(CommonConnection, ConnectionHandlers):
if show == 'offline':
ptype = 'unavailable'
xmpp_show = helpers.get_xmpp_show(show)
- p = common.xmpp.Presence(to = '%s/%s' % (jid, nick), typ = ptype,
- show = xmpp_show, status = status)
+ p = nbxmpp.Presence(to='%s/%s' % (jid, nick), typ=ptype,
+ show=xmpp_show, status=status)
h = hmac.new(self.secret_hmac, jid).hexdigest()[:6]
id_ = self.connection.getAnID()
id_ = 'gajim_muc_' + id_ + '_' + h
@@ -2478,19 +2475,18 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
gajim.logger.set_room_last_message_time(room_jid, self.last_history_time[room_jid])
- def gc_set_role(self, room_jid, nick, role, reason = ''):
+ def gc_set_role(self, room_jid, nick, role, reason=''):
"""
Role is for all the life of the room so it's based on nick
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
- common.xmpp.NS_MUC_ADMIN)
+ iq = nbxmpp.Iq(typ='set', to=room_jid, queryNS=nbxmpp.NS_MUC_ADMIN)
item = iq.setQuery().setTag('item')
item.setAttr('nick', nick)
item.setAttr('role', role)
if reason:
- item.addChild(name = 'reason', payload = reason)
+ item.addChild(name='reason', payload=reason)
self.connection.send(iq)
def gc_set_affiliation(self, room_jid, jid, affiliation, reason = ''):
@@ -2499,8 +2495,7 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
- common.xmpp.NS_MUC_ADMIN)
+ iq = nbxmpp.Iq(typ='set', to=room_jid, queryNS=nbxmpp.NS_MUC_ADMIN)
item = iq.setQuery().setTag('item')
item.setAttr('jid', jid)
item.setAttr('affiliation', affiliation)
@@ -2511,8 +2506,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def send_gc_affiliation_list(self, room_jid, users_dict):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS = \
- common.xmpp.NS_MUC_ADMIN)
+ iq = nbxmpp.Iq(typ='set', to=room_jid, queryNS=nbxmpp.NS_MUC_ADMIN)
item = iq.setQuery()
for jid in users_dict:
item_tag = item.addChild('item', {'jid': jid,
@@ -2524,8 +2518,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def get_affiliation_list(self, room_jid, affiliation):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'get', to = room_jid, queryNS = \
- common.xmpp.NS_MUC_ADMIN)
+ iq = nbxmpp.Iq(typ='get', to=room_jid, queryNS=nbxmpp.NS_MUC_ADMIN)
item = iq.setQuery().setTag('item')
item.setAttr('affiliation', affiliation)
self.connection.send(iq)
@@ -2533,8 +2526,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def send_gc_config(self, room_jid, form):
if not gajim.account_is_connected(self.name):
return
- iq = common.xmpp.Iq(typ = 'set', to = room_jid, queryNS =\
- common.xmpp.NS_MUC_OWNER)
+ iq = nbxmpp.Iq(typ='set', to=room_jid, queryNS=nbxmpp.NS_MUC_OWNER)
query = iq.setQuery()
form.setAttr('type', 'submit')
query.addChild(node = form)
@@ -2545,8 +2537,8 @@ class Connection(CommonConnection, ConnectionHandlers):
return
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
username = gajim.config.get_per('accounts', self.name, 'name')
- iq = common.xmpp.Iq(typ = 'set', to = hostname)
- q = iq.setTag(common.xmpp.NS_REGISTER + ' query')
+ iq = nbxmpp.Iq(typ='set', to=hostname)
+ q = iq.setTag(nbxmpp.NS_REGISTER + ' query')
q.setTagData('username', username)
q.setTagData('password', password)
self.connection.send(iq)
@@ -2610,10 +2602,10 @@ class Connection(CommonConnection, ConnectionHandlers):
self.on_connect_auth = None
if gajim.account_is_connected(self.name):
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
- iq = common.xmpp.Iq(typ = 'set', to = hostname)
+ iq = nbxmpp.Iq(typ='set', to=hostname)
id_ = self.connection.getAnID()
iq.setID(id_)
- iq.setTag(common.xmpp.NS_REGISTER + ' query').setTag('remove')
+ iq.setTag(nbxmpp.NS_REGISTER + ' query').setTag('remove')
def _on_answer(con, result):
if result.getID() == id_:
on_remove_success(True)
@@ -2639,8 +2631,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
Send invitation
"""
- message=common.xmpp.Message(to=room)
- c = message.addChild(name='x', namespace=common.xmpp.NS_MUC_USER)
+ message=nbxmpp.Message(to=room)
+ c = message.addChild(name='x', namespace=nbxmpp.NS_MUC_USER)
c = c.addChild(name='invite', attrs={'to': to})
if continue_tag:
c.addChild(name='continue')
@@ -2652,8 +2644,8 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
decline a groupchat invitation
"""
- message=common.xmpp.Message(to=room)
- c = message.addChild(name='x', namespace=common.xmpp.NS_MUC_USER)
+ message=nbxmpp.Message(to=room)
+ c = message.addChild(name='x', namespace=nbxmpp.NS_MUC_USER)
c = c.addChild(name='decline', attrs={'to': to})
if reason != '':
c.setTagData('reason', reason)
@@ -2663,11 +2655,11 @@ class Connection(CommonConnection, ConnectionHandlers):
"""
Request voice in a moderated room
"""
- message = common.xmpp.Message(to=room)
+ message = nbxmpp.Message(to=room)
x = xmpp.DataForm(typ='submit')
x.addChild(node=xmpp.DataField(name='FORM_TYPE',
- value=common.xmpp.NS_MUC + '#request'))
+ value=nbxmpp.NS_MUC + '#request'))
x.addChild(node=xmpp.DataField(name='muc#role', value='participant',
typ='text-single'))
@@ -2692,13 +2684,11 @@ class Connection(CommonConnection, ConnectionHandlers):
self.time_to_reconnect = None
def request_search_fields(self, jid):
- iq = common.xmpp.Iq(typ = 'get', to = jid, queryNS = \
- common.xmpp.NS_SEARCH)
+ iq = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_SEARCH)
self.connection.send(iq)
def send_search_form(self, jid, form, is_form):
- iq = common.xmpp.Iq(typ = 'set', to = jid, queryNS = \
- common.xmpp.NS_SEARCH)
+ iq = nbxmpp.Iq(typ='set', to=jid, queryNS=nbxmpp.NS_SEARCH)
item = iq.setQuery()
if is_form:
item.addChild(node=form)
diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py
index fc9006ba2..c5b6b7311 100644
--- a/src/common/connection_handlers.py
+++ b/src/common/connection_handlers.py
@@ -38,7 +38,7 @@ from time import (altzone, daylight, gmtime, localtime, mktime, strftime,
time as time_time, timezone, tzname)
from calendar import timegm
-import common.xmpp
+import nbxmpp
import common.caps_cache as capscache
from common import helpers
@@ -101,7 +101,7 @@ class ConnectionDisco:
jid is mandatory;
name, node, action is optional.
"""
- self._discover(common.xmpp.NS_DISCO_ITEMS, jid, node, id_prefix)
+ self._discover(nbxmpp.NS_DISCO_ITEMS, jid, node, id_prefix)
def discoverInfo(self, jid, node=None, id_prefix=None):
"""
@@ -109,12 +109,12 @@ class ConnectionDisco:
For identity: category, type is mandatory, name is optional.
For feature: var is mandatory.
"""
- self._discover(common.xmpp.NS_DISCO_INFO, jid, node, id_prefix)
+ self._discover(nbxmpp.NS_DISCO_INFO, jid, node, id_prefix)
def request_register_agent_info(self, agent):
if not self.connection or self.connected < 2:
return None
- iq = common.xmpp.Iq('get', common.xmpp.NS_REGISTER, to=agent)
+ iq = nbxmpp.Iq('get', nbxmpp.NS_REGISTER, to=agent)
id_ = self.connection.getAnID()
iq.setID(id_)
# Wait the answer during 30 secondes
@@ -132,7 +132,7 @@ class ConnectionDisco:
self.request_subscription(agent, auto_auth=True)
self.agent_registrations[agent]['roster_push'] = True
if self.agent_registrations[agent]['sub_received']:
- p = common.xmpp.Presence(agent, 'subscribed')
+ p = nbxmpp.Presence(agent, 'subscribed')
p = self.add_sha(p)
self.connection.send(p)
if resp.getType() == 'error':
@@ -146,7 +146,7 @@ class ConnectionDisco:
if not self.connection or self.connected < 2:
return
if is_form:
- iq = common.xmpp.Iq('set', common.xmpp.NS_REGISTER, to=agent)
+ iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
query = iq.setQuery()
info.setAttr('type', 'submit')
query.addChild(node=info)
@@ -154,7 +154,7 @@ class ConnectionDisco:
self._agent_registered_cb, {'agent': agent})
else:
# fixed: blocking
- common.xmpp.features_nb.register(self.connection, agent, info,
+ nbxmpp.features_nb.register(self.connection, agent, info,
self._agent_registered_cb, {'agent': agent})
self.agent_registrations[agent] = {'roster_push': False,
'sub_received': False}
@@ -162,7 +162,7 @@ class ConnectionDisco:
def _discover(self, ns, jid, node=None, id_prefix=None):
if not self.connection or self.connected < 2:
return
- iq = common.xmpp.Iq(typ='get', to=jid, queryNS=ns)
+ iq = nbxmpp.Iq(typ='get', to=jid, queryNS=ns)
if id_prefix:
id_ = self.connection.getAnID()
iq.setID('%s%s' % (id_prefix, id_))
@@ -171,7 +171,7 @@ class ConnectionDisco:
self.connection.send(iq)
def _ReceivedRegInfo(self, con, resp, agent):
- common.xmpp.features_nb._ReceivedRegInfo(con, resp, agent)
+ nbxmpp.features_nb._ReceivedRegInfo(con, resp, agent)
self._IqCB(con, resp)
def _discoGetCB(self, con, iq_obj):
@@ -183,23 +183,21 @@ class ConnectionDisco:
frm = helpers.get_full_jid_from_iq(iq_obj)
to = unicode(iq_obj.getAttr('to'))
id_ = unicode(iq_obj.getAttr('id'))
- iq = common.xmpp.Iq(to=frm, typ='result', queryNS=common.xmpp.NS_DISCO,
- frm=to)
+ iq = nbxmpp.Iq(to=frm, typ='result', queryNS=nbxmpp.NS_DISCO, frm=to)
iq.setAttr('id', id_)
query = iq.setTag('query')
query.setAttr('node', 'http://gajim.org#' + gajim.version.split('-', 1)[
0])
- for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI,
- common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS,
- common.xmpp.NS_JINGLE_FILE_TRANSFER, common.xmpp.NS_JINGLE_XTLS,
- common.xmpp.NS_PUBKEY_PUBKEY, common.xmpp.NS_PUBKEY_REVOKE,
- common.xmpp.NS_PUBKEY_ATTEST):
- feature = common.xmpp.Node('feature')
+ for f in (nbxmpp.NS_BYTESTREAM, nbxmpp.NS_SI, nbxmpp.NS_FILE,
+ nbxmpp.NS_COMMANDS, nbxmpp.NS_JINGLE_FILE_TRANSFER,
+ nbxmpp.NS_JINGLE_XTLS, nbxmpp.NS_PUBKEY_PUBKEY, nbxmpp.NS_PUBKEY_REVOKE,
+ nbxmpp.NS_PUBKEY_ATTEST):
+ feature = nbxmpp.Node('feature')
feature.setAttr('var', f)
query.addChild(node=feature)
self.connection.send(iq)
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _DiscoverItemsErrorCB(self, con, iq_obj):
log.debug('DiscoverItemsErrorCB')
@@ -218,15 +216,15 @@ class ConnectionDisco:
return
if self.commandItemsQuery(con, iq_obj):
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
node = iq_obj.getTagAttr('query', 'node')
if node is None:
result = iq_obj.buildReply('result')
self.connection.send(result)
- raise common.xmpp.NodeProcessed
- if node == common.xmpp.NS_COMMANDS:
+ raise nbxmpp.NodeProcessed
+ if node == nbxmpp.NS_COMMANDS:
self.commandListQuery(con, iq_obj)
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _DiscoverInfoGetCB(self, con, iq_obj):
log.debug('DiscoverInfoGetCB')
@@ -235,12 +233,12 @@ class ConnectionDisco:
node = iq_obj.getQuerynode()
if self.commandInfoQuery(con, iq_obj):
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
id_ = unicode(iq_obj.getAttr('id'))
if id_[:6] == 'Gajim_':
# We get this request from echo.server
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
iq = iq_obj.buildReply('result')
q = iq.setQuery()
@@ -257,7 +255,7 @@ class ConnectionDisco:
if q.getChildren():
self.connection.send(iq)
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _DiscoverInfoErrorCB(self, con, iq_obj):
log.debug('DiscoverInfoErrorCB')
@@ -279,7 +277,7 @@ class ConnectionVcard:
self.room_jids = []
def add_sha(self, p, send_caps=True):
- c = p.setTag('x', namespace=common.xmpp.NS_VCARD_UPDATE)
+ c = p.setTag('x', namespace=nbxmpp.NS_VCARD_UPDATE)
if self.vcard_sha is not None:
c.setTagData('photo', self.vcard_sha)
if send_caps:
@@ -288,7 +286,7 @@ class ConnectionVcard:
def _add_caps(self, p):
''' advertise our capabilities in presence stanza (xep-0115)'''
- c = p.setTag('c', namespace=common.xmpp.NS_CAPS)
+ c = p.setTag('c', namespace=nbxmpp.NS_CAPS)
c.setAttr('hash', 'sha-1')
c.setAttr('node', 'http://gajim.org')
c.setAttr('ver', gajim.caps_hash[self.name])
@@ -357,7 +355,7 @@ class ConnectionVcard:
c = f.read()
f.close()
try:
- card = common.xmpp.Node(node=c)
+ card = nbxmpp.Node(node=c)
except Exception:
# We are unable to parse it. Remove it
os.remove(path_to_file)
@@ -386,10 +384,10 @@ class ConnectionVcard:
"""
if not self.connection or self.connected < 2:
return
- iq = common.xmpp.Iq(typ='get')
+ iq = nbxmpp.Iq(typ='get')
if jid:
iq.setTo(jid)
- iq.setQuery('vCard').setNamespace(common.xmpp.NS_VCARD)
+ iq.setQuery('vCard').setNamespace(nbxmpp.NS_VCARD)
id_ = self.connection.getAnID()
iq.setID(id_)
@@ -407,8 +405,8 @@ class ConnectionVcard:
def send_vcard(self, vcard):
if not self.connection or self.connected < 2:
return
- iq = common.xmpp.Iq(typ='set')
- iq2 = iq.setTag(common.xmpp.NS_VCARD + ' vCard')
+ iq = nbxmpp.Iq(typ='set')
+ iq2 = iq.setTag(nbxmpp.NS_VCARD + ' vCard')
for i in vcard:
if i == 'jid':
continue
@@ -481,7 +479,7 @@ class ConnectionVcard:
self.vcard_sha = new_sha
sshow = helpers.get_xmpp_show(gajim.SHOW_LIST[
self.connected])
- p = common.xmpp.Presence(typ=None, priority=self.priority,
+ p = nbxmpp.Presence(typ=None, priority=self.priority,
show=sshow, status=self.status)
p = self.add_sha(p)
self.connection.send(p)
@@ -587,7 +585,7 @@ class ConnectionVcard:
if not conf:
return
node = conf.getAttr('node')
- form_tag = conf.getTag('x', namespace=common.xmpp.NS_DATA)
+ form_tag = conf.getTag('x', namespace=nbxmpp.NS_DATA)
if form_tag:
form = common.dataforms.ExtendForm(node=form_tag)
gajim.nec.push_incoming_event(PEPConfigReceivedEvent(None,
@@ -664,7 +662,7 @@ class ConnectionVcard:
"""
if not vc.getTag('vCard'):
return
- if not vc.getTag('vCard').getNamespace() == common.xmpp.NS_VCARD:
+ if not vc.getTag('vCard').getNamespace() == nbxmpp.NS_VCARD:
return
id_ = vc.getID()
frm_iq = vc.getFrom()
@@ -745,7 +743,7 @@ class ConnectionVcard:
if not self.connection:
return
sshow = helpers.get_xmpp_show(gajim.SHOW_LIST[self.connected])
- p = common.xmpp.Presence(typ=None, priority=self.priority,
+ p = nbxmpp.Presence(typ=None, priority=self.priority,
show=sshow, status=self.status)
p = self.add_sha(p)
self.connection.send(p)
@@ -1020,7 +1018,7 @@ class ConnectionHandlersBase:
if obj.receipt_request_tag and gajim.config.get_per('accounts',
self.name, 'answer_receipts') and ((contact and contact.sub \
not in (u'to', u'none')) or gc_contact) and obj.mtype != 'error':
- receipt = common.xmpp.Message(to=obj.fjid, typ='chat')
+ receipt = nbxmpp.Message(to=obj.fjid, typ='chat')
receipt.setID(obj.id_)
receipt.setTag('received', namespace='urn:xmpp:receipts',
attrs={'id': obj.id_})
@@ -1205,7 +1203,7 @@ class ConnectionHandlersBase:
if not cls:
cls = gajim.default_session_type
- sess = cls(self, common.xmpp.JID(jid), thread_id, type_)
+ sess = cls(self, nbxmpp.JID(jid), thread_id, type_)
# determine if this session is a pm session
# if not, discard the resource so that all sessions are stored bare
@@ -1370,8 +1368,7 @@ ConnectionJingle, ConnectionIBBytestream):
reply.addChild(node=confirm)
self.connection.send(reply)
elif answer == 'no':
- err = common.xmpp.Error(iq_obj,
- common.xmpp.protocol.ERR_NOT_AUTHORIZED)
+ err = nbxmpp.Error(iq_obj, nbxmpp.protocol.ERR_NOT_AUTHORIZED)
self.connection.send(err)
def _nec_http_auth_received(self, obj):
@@ -1385,7 +1382,7 @@ ConnectionJingle, ConnectionIBBytestream):
log.debug('HttpAuthCB')
gajim.nec.push_incoming_event(HttpAuthReceivedEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _ErrorCB(self, con, iq_obj):
log.debug('ErrorCB')
@@ -1466,7 +1463,7 @@ ConnectionJingle, ConnectionIBBytestream):
log.debug('rosterSetCB')
gajim.nec.push_incoming_event(RosterSetReceivedEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_roster_set_received(self, obj):
if obj.conn.name != self.name:
@@ -1489,7 +1486,7 @@ ConnectionJingle, ConnectionIBBytestream):
return
gajim.nec.push_incoming_event(VersionRequestEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_version_request_received(self, obj):
if obj.conn.name != self.name:
@@ -1503,7 +1500,7 @@ ConnectionJingle, ConnectionIBBytestream):
qp.setTagData('os', helpers.get_os_info())
else:
iq_obj = obj.stanza.buildReply('error')
- err = common.xmpp.ErrorNode(name=common.xmpp.NS_STANZAS + \
+ err = nbxmpp.ErrorNode(name=nbxmpp.NS_STANZAS + \
' service-unavailable')
iq_obj.addChild(node=err)
self.connection.send(iq_obj)
@@ -1514,7 +1511,7 @@ ConnectionJingle, ConnectionIBBytestream):
return
gajim.nec.push_incoming_event(LastRequestEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_last_request_received(self, obj):
global HAS_IDLE
@@ -1527,7 +1524,7 @@ ConnectionJingle, ConnectionIBBytestream):
qp.attrs['seconds'] = int(self.sleeper.getIdleSec())
else:
iq_obj = obj.stanza.buildReply('error')
- err = common.xmpp.ErrorNode(name=common.xmpp.NS_STANZAS + \
+ err = nbxmpp.ErrorNode(name=nbxmpp.NS_STANZAS + \
' service-unavailable')
iq_obj.addChild(node=err)
self.connection.send(iq_obj)
@@ -1543,7 +1540,7 @@ ConnectionJingle, ConnectionIBBytestream):
return
gajim.nec.push_incoming_event(TimeRequestEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_time_request_received(self, obj):
if obj.conn.name != self.name:
@@ -1557,7 +1554,7 @@ ConnectionJingle, ConnectionIBBytestream):
localtime())))
else:
iq_obj = obj.stanza.buildReply('error')
- err = common.xmpp.ErrorNode(name=common.xmpp.NS_STANZAS + \
+ err = nbxmpp.ErrorNode(name=nbxmpp.NS_STANZAS + \
' service-unavailable')
iq_obj.addChild(node=err)
self.connection.send(iq_obj)
@@ -1568,14 +1565,14 @@ ConnectionJingle, ConnectionIBBytestream):
return
gajim.nec.push_incoming_event(TimeRevisedRequestEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_time_revised_request_received(self, obj):
if obj.conn.name != self.name:
return
if gajim.config.get_per('accounts', self.name, 'send_time_info'):
iq_obj = obj.stanza.buildReply('result')
- qp = iq_obj.setTag('time', namespace=common.xmpp.NS_TIME_REVISED)
+ qp = iq_obj.setTag('time', namespace=nbxmpp.NS_TIME_REVISED)
qp.setTagData('utc', strftime('%Y-%m-%dT%H:%M:%SZ', gmtime()))
isdst = localtime().tm_isdst
zone = -(timezone, altzone)[isdst] / 60.0
@@ -1583,7 +1580,7 @@ ConnectionJingle, ConnectionIBBytestream):
qp.setTagData('tzo', '%+03d:%02d' % (tzo))
else:
iq_obj = obj.stanza.buildReply('error')
- err = common.xmpp.ErrorNode(name=common.xmpp.NS_STANZAS + \
+ err = nbxmpp.ErrorNode(name=nbxmpp.NS_STANZAS + \
' service-unavailable')
iq_obj.addChild(node=err)
self.connection.send(iq_obj)
@@ -1600,7 +1597,7 @@ ConnectionJingle, ConnectionIBBytestream):
log.debug('gMailNewMailCB')
gajim.nec.push_incoming_event(GmailNewMailReceivedEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_gmail_new_mail_received(self, obj):
if obj.conn.name != self.name:
@@ -1611,9 +1608,9 @@ ConnectionJingle, ConnectionIBBytestream):
jid = gajim.get_jid_from_account(self.name)
log.debug('Got notification of new gmail e-mail on %s. Asking the '
'server for more info.' % jid)
- iq = common.xmpp.Iq(typ='get')
+ iq = nbxmpp.Iq(typ='get')
query = iq.setTag('query')
- query.setNamespace(common.xmpp.NS_GMAILNOTIFY)
+ query.setNamespace(nbxmpp.NS_GMAILNOTIFY)
# we want only be notified about newer mails
if self.gmail_last_tid:
query.setAttr('newer-than-tid', self.gmail_last_tid)
@@ -1629,7 +1626,7 @@ ConnectionJingle, ConnectionIBBytestream):
log.debug('gMailQueryCB')
gajim.nec.push_incoming_event(GMailQueryReceivedEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _rosterItemExchangeCB(self, con, msg):
"""
@@ -1638,7 +1635,7 @@ ConnectionJingle, ConnectionIBBytestream):
log.debug('rosterItemExchangeCB')
gajim.nec.push_incoming_event(RosterItemExchangeEvent(None, conn=self,
stanza=msg))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _messageCB(self, con, msg):
"""
@@ -1662,7 +1659,7 @@ ConnectionJingle, ConnectionIBBytestream):
return
if result.getType() == 'result':
- data = msg.getTags('data', namespace=common.xmpp.NS_BOB)
+ data = msg.getTags('data', namespace=nbxmpp.NS_BOB)
if data.getAttr('cid') == cid:
for func in self.awaiting_cids[cid]:
cb = func[0]
@@ -1697,9 +1694,9 @@ ConnectionJingle, ConnectionIBBytestream):
self.awaiting_cids[cid].appends((callback, args, position))
else:
self.awaiting_cids[cid] = [(callback, args, position)]
- iq = common.xmpp.Iq(to=to, typ='get')
+ iq = nbxmpp.Iq(to=to, typ='get')
data = iq.addChild(name='data', attrs={'cid': cid},
- namespace=common.xmpp.NS_BOB)
+ namespace=nbxmpp.NS_BOB)
self.connection.SendAndCallForResponse(iq, self._on_bob_received,
{'cid': cid})
@@ -1828,7 +1825,7 @@ ConnectionJingle, ConnectionIBBytestream):
log.debug('IqPingCB')
gajim.nec.push_incoming_event(PingReceivedEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_ping_received(self, obj):
if obj.conn.name != self.name:
@@ -1852,7 +1849,7 @@ ConnectionJingle, ConnectionIBBytestream):
if q:
result.delChild(q)
self.connection.send(result)
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _getRoster(self):
log.debug('getRosterCB')
@@ -1947,12 +1944,12 @@ ConnectionJingle, ConnectionIBBytestream):
vcard = self.get_cached_vcard(our_jid)
if vcard and 'PHOTO' in vcard and 'SHA' in vcard['PHOTO']:
self.vcard_sha = vcard['PHOTO']['SHA']
- p = common.xmpp.Presence(typ=None, priority=priority, show=sshow)
+ p = nbxmpp.Presence(typ=None, priority=priority, show=sshow)
p = self.add_sha(p)
if msg:
p.setStatus(msg)
if signed:
- p.setTag(common.xmpp.NS_SIGNED + ' x').setData(signed)
+ p.setTag(nbxmpp.NS_SIGNED + ' x').setData(signed)
if self.connection:
self.connection.send(p)
@@ -1982,18 +1979,18 @@ ConnectionJingle, ConnectionIBBytestream):
our_jid = helpers.parse_jid(gajim.get_jid_from_account(self.name))
log.debug(('%s is a gmail account. Setting option '
'to get e-mail notifications on the server.') % (our_jid))
- iq = common.xmpp.Iq(typ='set', to=our_jid)
+ iq = nbxmpp.Iq(typ='set', to=our_jid)
iq.setAttr('id', 'MailNotify')
query = iq.setTag('usersetting')
- query.setNamespace(common.xmpp.NS_GTALKSETTING)
+ query.setNamespace(nbxmpp.NS_GTALKSETTING)
query = query.setTag('mailnotifications')
query.setAttr('value', 'true')
self.connection.send(iq)
# Ask how many messages there are now
- iq = common.xmpp.Iq(typ='get')
+ iq = nbxmpp.Iq(typ='get')
iq.setID(self.connection.getAnID())
query = iq.setTag('query')
- query.setNamespace(common.xmpp.NS_GMAILNOTIFY)
+ query.setNamespace(nbxmpp.NS_GMAILNOTIFY)
self.connection.send(iq)
def _SearchCB(self, con, iq_obj):
@@ -2003,11 +2000,11 @@ ConnectionJingle, ConnectionIBBytestream):
def _search_fields_received(self, con, iq_obj):
jid = jid = helpers.get_jid_from_iq(iq_obj)
- tag = iq_obj.getTag('query', namespace = common.xmpp.NS_SEARCH)
+ tag = iq_obj.getTag('query', namespace = nbxmpp.NS_SEARCH)
if not tag:
self.dispatch('SEARCH_FORM', (jid, None, False))
return
- df = tag.getTag('x', namespace = common.xmpp.NS_DATA)
+ df = tag.getTag('x', namespace=nbxmpp.NS_DATA)
if df:
self.dispatch('SEARCH_FORM', (jid, df, True))
return
@@ -2021,7 +2018,7 @@ ConnectionJingle, ConnectionIBBytestream):
jid_from = helpers.get_full_jid_from_iq(iq_obj)
sid = iq_obj.getAttr('id')
jingle_xtls.send_cert(con, jid_from, sid)
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _PubkeyResultCB(self, con, iq_obj):
log.info('PubkeyResultCB')
@@ -2048,76 +2045,68 @@ ConnectionJingle, ConnectionIBBytestream):
# We also don't check for namespace, else it cannot stop _messageCB to
# be called
con.RegisterHandler('message', self._pubsubEventCB, makefirst=True)
- con.RegisterHandler('iq', self._vCardCB, 'result', common.xmpp.NS_VCARD)
- con.RegisterHandler('iq', self._rosterSetCB, 'set',
- common.xmpp.NS_ROSTER)
- con.RegisterHandler('iq', self._siSetCB, 'set', common.xmpp.NS_SI)
+ con.RegisterHandler('iq', self._vCardCB, 'result', nbxmpp.NS_VCARD)
+ con.RegisterHandler('iq', self._rosterSetCB, 'set', nbxmpp.NS_ROSTER)
+ con.RegisterHandler('iq', self._siSetCB, 'set', nbxmpp.NS_SI)
con.RegisterHandler('iq', self._rosterItemExchangeCB, 'set',
- common.xmpp.NS_ROSTERX)
- con.RegisterHandler('iq', self._siErrorCB, 'error', common.xmpp.NS_SI)
- con.RegisterHandler('iq', self._siResultCB, 'result', common.xmpp.NS_SI)
- con.RegisterHandler('iq', self._discoGetCB, 'get', common.xmpp.NS_DISCO)
+ nbxmpp.NS_ROSTERX)
+ con.RegisterHandler('iq', self._siErrorCB, 'error', nbxmpp.NS_SI)
+ con.RegisterHandler('iq', self._siResultCB, 'result', nbxmpp.NS_SI)
+ con.RegisterHandler('iq', self._discoGetCB, 'get', nbxmpp.NS_DISCO)
con.RegisterHandler('iq', self._bytestreamSetCB, 'set',
- common.xmpp.NS_BYTESTREAM)
+ nbxmpp.NS_BYTESTREAM)
con.RegisterHandler('iq', self._bytestreamResultCB, 'result',
- common.xmpp.NS_BYTESTREAM)
+ nbxmpp.NS_BYTESTREAM)
con.RegisterHandler('iq', self._bytestreamErrorCB, 'error',
- common.xmpp.NS_BYTESTREAM)
+ nbxmpp.NS_BYTESTREAM)
con.RegisterHandlerOnce('iq', self.IBBAllIqHandler)
- con.RegisterHandler('iq', self.IBBIqHandler, ns=common.xmpp.NS_IBB)
- con.RegisterHandler('message', self.IBBMessageHandler,
- ns=common.xmpp.NS_IBB)
+ con.RegisterHandler('iq', self.IBBIqHandler, ns=nbxmpp.NS_IBB)
+ con.RegisterHandler('message', self.IBBMessageHandler, ns=nbxmpp.NS_IBB)
con.RegisterHandler('iq', self._DiscoverItemsCB, 'result',
- common.xmpp.NS_DISCO_ITEMS)
+ nbxmpp.NS_DISCO_ITEMS)
con.RegisterHandler('iq', self._DiscoverItemsErrorCB, 'error',
- common.xmpp.NS_DISCO_ITEMS)
+ nbxmpp.NS_DISCO_ITEMS)
con.RegisterHandler('iq', self._DiscoverInfoCB, 'result',
- common.xmpp.NS_DISCO_INFO)
+ nbxmpp.NS_DISCO_INFO)
con.RegisterHandler('iq', self._DiscoverInfoErrorCB, 'error',
- common.xmpp.NS_DISCO_INFO)
- con.RegisterHandler('iq', self._VersionCB, 'get',
- common.xmpp.NS_VERSION)
- con.RegisterHandler('iq', self._TimeCB, 'get', common.xmpp.NS_TIME)
+ nbxmpp.NS_DISCO_INFO)
+ con.RegisterHandler('iq', self._VersionCB, 'get', nbxmpp.NS_VERSION)
+ con.RegisterHandler('iq', self._TimeCB, 'get', nbxmpp.NS_TIME)
con.RegisterHandler('iq', self._TimeRevisedCB, 'get',
- common.xmpp.NS_TIME_REVISED)
- con.RegisterHandler('iq', self._LastCB, 'get', common.xmpp.NS_LAST)
- con.RegisterHandler('iq', self._LastResultCB, 'result',
- common.xmpp.NS_LAST)
+ nbxmpp.NS_TIME_REVISED)
+ con.RegisterHandler('iq', self._LastCB, 'get', nbxmpp.NS_LAST)
+ con.RegisterHandler('iq', self._LastResultCB, 'result', nbxmpp.NS_LAST)
con.RegisterHandler('iq', self._VersionResultCB, 'result',
- common.xmpp.NS_VERSION)
+ nbxmpp.NS_VERSION)
con.RegisterHandler('iq', self._TimeRevisedResultCB, 'result',
- common.xmpp.NS_TIME_REVISED)
+ nbxmpp.NS_TIME_REVISED)
con.RegisterHandler('iq', self._MucOwnerCB, 'result',
- common.xmpp.NS_MUC_OWNER)
+ nbxmpp.NS_MUC_OWNER)
con.RegisterHandler('iq', self._MucAdminCB, 'result',
- common.xmpp.NS_MUC_ADMIN)
- con.RegisterHandler('iq', self._PrivateCB, 'result',
- common.xmpp.NS_PRIVATE)
+ nbxmpp.NS_MUC_ADMIN)
+ con.RegisterHandler('iq', self._PrivateCB, 'result', nbxmpp.NS_PRIVATE)
con.RegisterHandler('iq', self._SecLabelCB, 'result',
- common.xmpp.NS_SECLABEL_CATALOG)
- con.RegisterHandler('iq', self._HttpAuthCB, 'get',
- common.xmpp.NS_HTTP_AUTH)
+ nbxmpp.NS_SECLABEL_CATALOG)
+ con.RegisterHandler('iq', self._HttpAuthCB, 'get', nbxmpp.NS_HTTP_AUTH)
con.RegisterHandler('iq', self._CommandExecuteCB, 'set',
- common.xmpp.NS_COMMANDS)
+ nbxmpp.NS_COMMANDS)
con.RegisterHandler('iq', self._gMailNewMailCB, 'set',
- common.xmpp.NS_GMAILNOTIFY)
+ nbxmpp.NS_GMAILNOTIFY)
con.RegisterHandler('iq', self._gMailQueryCB, 'result',
- common.xmpp.NS_GMAILNOTIFY)
+ nbxmpp.NS_GMAILNOTIFY)
con.RegisterHandler('iq', self._DiscoverInfoGetCB, 'get',
- common.xmpp.NS_DISCO_INFO)
+ nbxmpp.NS_DISCO_INFO)
con.RegisterHandler('iq', self._DiscoverItemsGetCB, 'get',
- common.xmpp.NS_DISCO_ITEMS)
- con.RegisterHandler('iq', self._IqPingCB, 'get', common.xmpp.NS_PING)
- con.RegisterHandler('iq', self._SearchCB, 'result',
- common.xmpp.NS_SEARCH)
- con.RegisterHandler('iq', self._PrivacySetCB, 'set',
- common.xmpp.NS_PRIVACY)
- con.RegisterHandler('iq', self._ArchiveCB, ns=common.xmpp.NS_ARCHIVE)
+ nbxmpp.NS_DISCO_ITEMS)
+ con.RegisterHandler('iq', self._IqPingCB, 'get', nbxmpp.NS_PING)
+ con.RegisterHandler('iq', self._SearchCB, 'result', nbxmpp.NS_SEARCH)
+ con.RegisterHandler('iq', self._PrivacySetCB, 'set', nbxmpp.NS_PRIVACY)
+ con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_ARCHIVE)
con.RegisterHandler('iq', self._PubSubCB, 'result')
con.RegisterHandler('iq', self._PubSubErrorCB, 'error')
con.RegisterHandler('iq', self._JingleCB, 'result')
con.RegisterHandler('iq', self._JingleCB, 'error')
- con.RegisterHandler('iq', self._JingleCB, 'set', common.xmpp.NS_JINGLE)
+ con.RegisterHandler('iq', self._JingleCB, 'set', nbxmpp.NS_JINGLE)
con.RegisterHandler('iq', self._ErrorCB, 'error')
con.RegisterHandler('iq', self._IqCB)
con.RegisterHandler('iq', self._StanzaArrivedCB)
@@ -2125,8 +2114,8 @@ ConnectionJingle, ConnectionIBBytestream):
con.RegisterHandler('presence', self._StanzaArrivedCB)
con.RegisterHandler('message', self._StanzaArrivedCB)
con.RegisterHandler('unknown', self._StreamCB,
- common.xmpp.NS_XMPP_STREAMS, xmlns=common.xmpp.NS_STREAMS)
+ nbxmpp.NS_XMPP_STREAMS, xmlns=nbxmpp.NS_STREAMS)
con.RegisterHandler('iq', self._PubkeyGetCB, 'get',
- common.xmpp.NS_PUBKEY_PUBKEY)
+ nbxmpp.NS_PUBKEY_PUBKEY)
con.RegisterHandler('iq', self._PubkeyResultCB, 'result',
- common.xmpp.NS_PUBKEY_PUBKEY)
+ nbxmpp.NS_PUBKEY_PUBKEY)
diff --git a/src/common/connection_handlers_events.py b/src/common/connection_handlers_events.py
index 0e51eb22c..9bb2e96a4 100644
--- a/src/common/connection_handlers_events.py
+++ b/src/common/connection_handlers_events.py
@@ -29,13 +29,13 @@ from common import atom
from common import nec
from common import helpers
from common import gajim
-from common import xmpp
+import nbxmpp
from common import dataforms
from common import exceptions
from common.zeroconf import zeroconf
from common.logger import LOG_DB_PATH
from common.pep import SUPPORTED_PERSONAL_USER_EVENTS
-from common.xmpp.protocol import NS_CHATSTATES
+from nbxmpp.protocol import NS_CHATSTATES
from common.jingle_transport import JingleTransportSocks5
from common.file_props import FilesProp
@@ -102,7 +102,7 @@ class HelperEvent:
self.chatstate = None
# chatstates - look for chatstate tags in a message if not delayed
- delayed = self.stanza.getTag('x', namespace=xmpp.NS_DELAY) is not None
+ delayed = self.stanza.getTag('x', namespace=nbxmpp.NS_DELAY) is not None
if not delayed:
children = self.stanza.getChildren()
for child in children:
@@ -243,7 +243,7 @@ class GMailQueryReceivedEvent(nec.NetworkIncomingEvent):
if not mb.getAttr('url'):
return
self.conn.gmail_url = mb.getAttr('url')
- if mb.getNamespace() != xmpp.NS_GMAILNOTIFY:
+ if mb.getNamespace() != nbxmpp.NS_GMAILNOTIFY:
return
self.newmsgs = mb.getAttr('total-matched')
if not self.newmsgs:
@@ -303,7 +303,7 @@ class RosterItemExchangeEvent(nec.NetworkIncomingEvent, HelperEvent):
self.action = items_list[0].getAttr('action')
if self.action is None:
self.action = 'add'
- for item in self.stanza.getTag('x', namespace=xmpp.NS_ROSTERX).\
+ for item in self.stanza.getTag('x', namespace=nbxmpp.NS_ROSTERX).\
getChildren():
try:
jid = helpers.parse_jid(item.getAttr('jid'))
@@ -412,7 +412,7 @@ class RosterSetReceivedEvent(nec.NetworkIncomingEvent):
self.items[jid] = {'name': name, 'sub': sub, 'ask': ask,
'groups': groups}
if self.conn.connection and self.conn.connected > 1:
- reply = xmpp.Iq(typ='result', attrs={'id': self.stanza.getID()},
+ reply = nbxmpp.Iq(typ='result', attrs={'id': self.stanza.getID()},
to=self.stanza.getFrom(), frm=self.stanza.getTo(), xmlns=None)
self.conn.connection.send(reply)
return True
@@ -430,7 +430,7 @@ class MucOwnerReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
qp = self.stanza.getQueryPayload()
self.form_node = None
for q in qp:
- if q.getNamespace() == xmpp.NS_DATA:
+ if q.getNamespace() == nbxmpp.NS_DATA:
self.form_node = q
self.dataform = dataforms.ExtendForm(node=self.form_node)
return True
@@ -442,7 +442,7 @@ class MucAdminReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
def generate(self):
self.get_jid_resource()
items = self.stanza.getTag('query',
- namespace=xmpp.NS_MUC_ADMIN).getTags('item')
+ namespace=nbxmpp.NS_MUC_ADMIN).getTags('item')
self.users_dict = {}
for item in items:
if item.has_attr('jid') and item.has_attr('affiliation'):
@@ -514,7 +514,7 @@ BookmarksHelper):
def generate(self):
self.conn = self.base_event.conn
self.storage_node = self.base_event.storage_node
- if self.base_event.namespace != xmpp.NS_BOOKMARKS:
+ if self.base_event.namespace != nbxmpp.NS_BOOKMARKS:
return
self.parse_bookmarks()
return True
@@ -535,7 +535,7 @@ class PrivateStorageRosternotesReceivedEvent(nec.NetworkIncomingEvent):
def generate(self):
self.conn = self.base_event.conn
- if self.base_event.namespace != xmpp.NS_ROSTERNOTES:
+ if self.base_event.namespace != nbxmpp.NS_ROSTERNOTES:
return
notes = self.base_event.storage_node.getTags('note')
self.annotations = {}
@@ -587,7 +587,7 @@ class PubsubBookmarksReceivedEvent(nec.NetworkIncomingEvent, BookmarksHelper):
self.conn = self.base_event.conn
self.storage_node = self.base_event.node
ns = self.storage_node.getNamespace()
- if ns != xmpp.NS_BOOKMARKS:
+ if ns != nbxmpp.NS_BOOKMARKS:
return
self.parse_bookmarks()
return True
@@ -600,10 +600,10 @@ class SearchFormReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
self.get_jid_resource()
self.data = None
self.is_dataform = False
- tag = self.stanza.getTag('query', namespace=xmpp.NS_SEARCH)
+ tag = self.stanza.getTag('query', namespace=nbxmpp.NS_SEARCH)
if not tag:
return True
- self.data = tag.getTag('x', namespace=xmpp.NS_DATA)
+ self.data = tag.getTag('x', namespace=nbxmpp.NS_DATA)
if self.data:
self.is_dataform = True
return True
@@ -621,10 +621,10 @@ class SearchResultReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
self.get_jid_resource()
self.data = None
self.is_dataform = False
- tag = self.stanza.getTag('query', namespace=xmpp.NS_SEARCH)
+ tag = self.stanza.getTag('query', namespace=nbxmpp.NS_SEARCH)
if not tag:
return True
- self.data = tag.getTag('x', namespace=xmpp.NS_DATA)
+ self.data = tag.getTag('x', namespace=nbxmpp.NS_DATA)
if self.data:
self.is_dataform = True
return True
@@ -655,7 +655,8 @@ class GmailNewMailReceivedEvent(nec.NetworkIncomingEvent):
def generate(self):
if not self.stanza.getTag('new-mail'):
return
- if self.stanza.getTag('new-mail').getNamespace() != xmpp.NS_GMAILNOTIFY:
+ if self.stanza.getTag('new-mail').getNamespace() != \
+ nbxmpp.NS_GMAILNOTIFY:
return
return True
@@ -769,20 +770,20 @@ PresenceHelperEvent):
self.contact_nickname = None
self.transport_auto_auth = False
# XEP-0203
- delay_tag = self.stanza.getTag('delay', namespace=xmpp.NS_DELAY2)
+ delay_tag = self.stanza.getTag('delay', namespace=nbxmpp.NS_DELAY2)
if delay_tag:
self._generate_timestamp(self.stanza.getTimestamp2())
xtags = self.stanza.getTags('x')
for x in xtags:
namespace = x.getNamespace()
- if namespace.startswith(xmpp.NS_MUC):
+ if namespace.startswith(nbxmpp.NS_MUC):
self.is_gc = True
- elif namespace == xmpp.NS_SIGNED:
+ elif namespace == nbxmpp.NS_SIGNED:
sig_tag = x
- elif namespace == xmpp.NS_VCARD_UPDATE:
+ elif namespace == nbxmpp.NS_VCARD_UPDATE:
self.avatar_sha = x.getTagData('photo')
self.contact_nickname = x.getTagData('nickname')
- elif namespace == xmpp.NS_DELAY and not self.timestamp:
+ elif namespace == nbxmpp.NS_DELAY and not self.timestamp:
# XEP-0091
self._generate_timestamp(self.stanza.getTimestamp())
elif namespace == 'http://delx.cjb.net/protocol/roster-subsync':
@@ -922,7 +923,7 @@ class GcPresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
# NOTE: if it's a gc presence, don't ask vcard here.
# We may ask it to real jid in gui part.
self.status_code = []
- ns_muc_user_x = self.stanza.getTag('x', namespace=xmpp.NS_MUC_USER)
+ ns_muc_user_x = self.stanza.getTag('x', namespace=nbxmpp.NS_MUC_USER)
if ns_muc_user_x:
destroy = ns_muc_user_x.getTag('destroy')
else:
@@ -1007,13 +1008,13 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
account = self.conn.name
# check if the message is a roster item exchange (XEP-0144)
- if self.stanza.getTag('x', namespace=xmpp.NS_ROSTERX):
+ if self.stanza.getTag('x', namespace=nbxmpp.NS_ROSTERX):
gajim.nec.push_incoming_event(RosterItemExchangeEvent(None,
conn=self.conn, stanza=self.stanza))
return
# check if the message is a XEP-0070 confirmation request
- if self.stanza.getTag('confirm', namespace=xmpp.NS_HTTP_AUTH):
+ if self.stanza.getTag('confirm', namespace=nbxmpp.NS_HTTP_AUTH):
gajim.nec.push_incoming_event(HttpAuthReceivedEvent(None,
conn=self.conn, stanza=self.stanza))
return
@@ -1027,7 +1028,8 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
'ignored.')))
return
- address_tag = self.stanza.getTag('addresses', namespace=xmpp.NS_ADDRESS)
+ address_tag = self.stanza.getTag('addresses',
+ namespace=nbxmpp.NS_ADDRESS)
# Be sure it comes from one of our resource, else ignore address element
if address_tag and self.jid == gajim.get_jid_from_account(account):
address = address_tag.getTag('address', attrs={'type': 'ofrom'})
@@ -1040,15 +1042,17 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
return
self.jid = gajim.get_jid_without_resource(self.fjid)
- carbon_marker = self.stanza.getTag('sent', namespace=xmpp.NS_CARBONS)
+ carbon_marker = self.stanza.getTag('sent', namespace=nbxmpp.NS_CARBONS)
if not carbon_marker:
- carbon_marker = self.stanza.getTag('received', namespace=xmpp.NS_CARBONS)
+ carbon_marker = self.stanza.getTag('received',
+ namespace=nbxmpp.NS_CARBONS)
# Be sure it comes from one of our resource, else ignore forward element
if carbon_marker and self.jid == gajim.get_jid_from_account(account):
- forward_tag = self.stanza.getTag('forwarded', namespace=xmpp.NS_FORWARD)
+ forward_tag = self.stanza.getTag('forwarded',
+ namespace=nbxmpp.NS_FORWARD)
if forward_tag:
msg = forward_tag.getTag('message')
- self.stanza = xmpp.Message(node=msg)
+ self.stanza = nbxmpp.Message(node=msg)
if carbon_marker.getName() == 'sent':
to = self.stanza.getTo()
self.stanza.setTo(self.stanza.getFrom())
@@ -1065,18 +1069,18 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
return
self.forwarded = True
- self.enc_tag = self.stanza.getTag('x', namespace=xmpp.NS_ENCRYPTED)
+ self.enc_tag = self.stanza.getTag('x', namespace=nbxmpp.NS_ENCRYPTED)
self.invite_tag = None
self.decline_tag = None
if not self.enc_tag:
self.invite_tag = self.stanza.getTag('x',
- namespace=xmpp.NS_MUC_USER)
+ namespace=nbxmpp.NS_MUC_USER)
if self.invite_tag and not self.invite_tag.getTag('invite'):
self.invite_tag = None
self.decline_tag = self.stanza.getTag('x',
- namespace=xmpp.NS_MUC_USER)
+ namespace=nbxmpp.NS_MUC_USER)
if self.decline_tag and not self.decline_tag.getTag('decline'):
self.decline_tag = None
@@ -1111,11 +1115,11 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
# check if the message is a XEP-0020 feature negotiation request
if not self.forwarded and self.stanza.getTag('feature',
- namespace=xmpp.NS_FEATURE):
+ namespace=nbxmpp.NS_FEATURE):
if gajim.HAVE_PYCRYPTO:
feature = self.stanza.getTag(name='feature',
- namespace=xmpp.NS_FEATURE)
- form = xmpp.DataForm(node=feature.getTag('x'))
+ namespace=nbxmpp.NS_FEATURE)
+ form = nbxmpp.DataForm(node=feature.getTag('x'))
if form['FORM_TYPE'] == 'urn:xmpp:ssn':
self.session.handle_negotiation(form)
@@ -1123,16 +1127,16 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
reply = self.stanza.buildReply()
reply.setType('error')
reply.addChild(feature)
- err = xmpp.ErrorNode('service-unavailable', typ='cancel')
+ err = nbxmpp.ErrorNode('service-unavailable', typ='cancel')
reply.addChild(node=err)
self.conn.connection.send(reply)
return
if not self.forwarded and self.stanza.getTag('init',
- namespace=xmpp.NS_ESESSION_INIT):
+ namespace=nbxmpp.NS_ESESSION_INIT):
init = self.stanza.getTag(name='init',
- namespace=xmpp.NS_ESESSION_INIT)
- form = xmpp.DataForm(node=init.getTag('x'))
+ namespace=nbxmpp.NS_ESESSION_INIT)
+ form = nbxmpp.DataForm(node=init.getTag('x'))
self.session.handle_negotiation(form)
@@ -1142,7 +1146,7 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
self.encrypted = False
xep_200_encrypted = self.stanza.getTag('c',
- namespace=xmpp.NS_STANZA_CRYPTO)
+ namespace=nbxmpp.NS_STANZA_CRYPTO)
if xep_200_encrypted:
if self.forwarded:
# Ignore E2E forwarded encrypted messages
@@ -1248,22 +1252,22 @@ class DecryptedMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
self.attention = False # XEP-0224
self.receipt_request_tag = self.stanza.getTag('request',
- namespace=xmpp.NS_RECEIPTS)
+ namespace=nbxmpp.NS_RECEIPTS)
self.receipt_received_tag = self.stanza.getTag('received',
- namespace=xmpp.NS_RECEIPTS)
+ namespace=nbxmpp.NS_RECEIPTS)
self.subject = self.stanza.getSubject()
self.displaymarking = None
self.seclabel = self.stanza.getTag('securitylabel',
- namespace=xmpp.NS_SECLABEL)
+ namespace=nbxmpp.NS_SECLABEL)
if self.seclabel:
self.displaymarking = self.seclabel.getTag('displaymarking')
- if self.stanza.getTag('attention', namespace=xmpp.NS_ATTENTION):
+ if self.stanza.getTag('attention', namespace=nbxmpp.NS_ATTENTION):
self.attention = True
- self.form_node = self.stanza.getTag('x', namespace=xmpp.NS_DATA)
+ self.form_node = self.stanza.getTag('x', namespace=nbxmpp.NS_DATA)
if gajim.config.get('ignore_incoming_xhtml'):
self.xhtml = None
@@ -1343,7 +1347,7 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
self.displaymarking = None
seclabel = self.stanza.getTag('securitylabel')
- if seclabel and seclabel.getNamespace() == xmpp.NS_SECLABEL:
+ if seclabel and seclabel.getNamespace() == nbxmpp.NS_SECLABEL:
# Ignore message from room in which we are not
self.displaymarking = seclabel.getTag('displaymarking')
@@ -1351,9 +1355,10 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
return
self.captcha_form = None
- captcha_tag = self.stanza.getTag('captcha', namespace=xmpp.NS_CAPTCHA)
+ captcha_tag = self.stanza.getTag('captcha', namespace=nbxmpp.NS_CAPTCHA)
if captcha_tag:
- self.captcha_form = captcha_tag.getTag('x', namespace=xmpp.NS_DATA)
+ self.captcha_form = captcha_tag.getTag('x',
+ namespace=nbxmpp.NS_DATA)
for field in self.captcha_form.getTags('field'):
for media in field.getTags('media'):
for uri in media.getTags('uri'):
@@ -1362,7 +1367,7 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
uri_data = uri_data[4:]
found = False
for data in self.stanza.getTags('data',
- namespace=xmpp.NS_BOB):
+ namespace=nbxmpp.NS_BOB):
if data.getAttr('cid') == uri_data:
uri.setData(data.getData())
found = True
@@ -1644,7 +1649,7 @@ PresenceHelperEvent):
base_network_events = ['raw-pres-received']
def _extract_caps_from_presence(self):
- caps_tag = self.stanza.getTag('c', namespace=xmpp.NS_CAPS)
+ caps_tag = self.stanza.getTag('c', namespace=nbxmpp.NS_CAPS)
if caps_tag:
self.hash_method = caps_tag['hash']
self.node = caps_tag['node']
@@ -1722,11 +1727,11 @@ class PEPReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
# for each entry in feed (there shouldn't be more than one, but to
# be sure...
for item in items.getTags('item'):
- entry = item.getTag('entry', namespace=xmpp.NS_ATOM)
+ entry = item.getTag('entry', namespace=nbxmpp.NS_ATOM)
if entry:
gajim.nec.push_incoming_event(AtomEntryReceived(None,
conn=self.conn, node=entry))
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
class AtomEntryReceived(nec.NetworkIncomingEvent):
name = 'atom-entry-received'
@@ -1878,7 +1883,7 @@ class AgentItemsReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
qp = []
for i in qp:
# CDATA payload is not processed, only nodes
- if not isinstance(i, xmpp.simplexml.Node):
+ if not isinstance(i, nbxmpp.simplexml.Node):
continue
attr = {}
for key in i.getAttrs():
@@ -1940,8 +1945,8 @@ class AgentInfoReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
var = i.getAttr('var')
if var:
self.features.append(var)
- elif i.getName() == 'x' and i.getNamespace() == xmpp.NS_DATA:
- self.data.append(xmpp.DataForm(node=i))
+ elif i.getName() == 'x' and i.getNamespace() == nbxmpp.NS_DATA:
+ self.data.append(nbxmpp.DataForm(node=i))
if not self.identities:
# ejabberd doesn't send identities when we browse online users
@@ -1992,7 +1997,7 @@ class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
host['initiator'] = self.FT_content.session.initiator
host['target'] = self.FT_content.session.responder
self.file_props.session_type = 'jingle'
- self.file_props.stream_methods = xmpp.NS_BYTESTREAM
+ self.file_props.stream_methods = nbxmpp.NS_BYTESTREAM
desc = self.jingle_content.getTag('description')
if desc.getTag('offer'):
file_tag = desc.getTag('offer').getTag('file')
@@ -2031,14 +2036,14 @@ class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
unicode(si.getAttr('id'))
)
profile = si.getAttr('profile')
- if profile != xmpp.NS_FILE:
+ if profile != nbxmpp.NS_FILE:
self.conn.send_file_rejection(self.file_props, code='400',
typ='profile')
- raise xmpp.NodeProcessed
- feature_tag = si.getTag('feature', namespace=xmpp.NS_FEATURE)
+ raise nbxmpp.NodeProcessed
+ feature_tag = si.getTag('feature', namespace=nbxmpp.NS_FEATURE)
if not feature_tag:
return
- form_tag = feature_tag.getTag('x', namespace=xmpp.NS_DATA)
+ form_tag = feature_tag.getTag('x', namespace=nbxmpp.NS_DATA)
if not form_tag:
return
self.dataform = dataforms.ExtendForm(node=form_tag)
@@ -2046,12 +2051,13 @@ class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
if f.var == 'stream-method' and f.type_ == 'list-single':
values = [o[1] for o in f.options]
self.file_props.stream_methods = ' '.join(values)
- if xmpp.NS_BYTESTREAM in values or xmpp.NS_IBB in values:
+ if nbxmpp.NS_BYTESTREAM in values or \
+ nbxmpp.NS_IBB in values:
break
else:
self.conn.send_file_rejection(self.file_props, code='400',
typ='stream')
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
file_tag = si.getTag('file')
for name, val in file_tag.getAttrs().items():
if val is None:
diff --git a/src/common/dataforms.py b/src/common/dataforms.py
index 184af501b..1129ba2e3 100644
--- a/src/common/dataforms.py
+++ b/src/common/dataforms.py
@@ -26,19 +26,19 @@ This module contains wrappers for different parts of data forms (JEP 0004). For
information how to use them, read documentation
"""
-import xmpp
+import nbxmpp
import helpers
# exceptions used in this module
# base class
class Error(Exception): pass
-# when we get xmpp.Node which we do not understand
+# when we get nbxmpp.Node which we do not understand
class UnknownDataForm(Error): pass
-# when we get xmpp.Node which contains bad fields
+# when we get nbxmpp.Node which contains bad fields
class WrongFieldValue(Error): pass
# helper class to change class of already existing object
-class ExtendedNode(xmpp.Node, object):
+class ExtendedNode(nbxmpp.Node, object):
@classmethod
def __new__(cls, *a, **b):
if 'extend' not in b.keys() or not b['extend']:
@@ -234,7 +234,7 @@ class DataField(ExtendedNode):
Media data
"""
def fget(self):
- media = self.getTag('media', namespace=xmpp.NS_DATA_MEDIA)
+ media = self.getTag('media', namespace=nbxmpp.NS_DATA_MEDIA)
if media:
return Media(media)
@@ -252,9 +252,9 @@ class DataField(ExtendedNode):
def is_valid(self):
return True
-class Uri(xmpp.Node):
+class Uri(nbxmpp.Node):
def __init__(self, uri_tag):
- xmpp.Node.__init__(self, node=uri_tag)
+ nbxmpp.Node.__init__(self, node=uri_tag)
@nested_property
def type_():
@@ -288,9 +288,9 @@ class Uri(xmpp.Node):
return locals()
-class Media(xmpp.Node):
+class Media(nbxmpp.Node):
def __init__(self, media_tag):
- xmpp.Node.__init__(self, node=media_tag)
+ nbxmpp.Node.__init__(self, node=media_tag)
@nested_property
def uris():
@@ -522,12 +522,12 @@ class DataRecord(ExtendedNode):
self.vars = {}
if extend is None:
# we have to build this object from scratch
- xmpp.Node.__init__(self)
+ nbxmpp.Node.__init__(self)
if fields is not None:
self.fields = fields
else:
- # we already have xmpp.Node inside - try to convert all
+ # we already have nbxmpp.Node inside - try to convert all
# fields into DataField objects
if fields is None:
for field in self.iterTags('field'):
@@ -588,7 +588,7 @@ class DataForm(ExtendedNode):
def __init__(self, type_=None, title=None, instructions=None, extend=None):
if extend is None:
# we have to build form from scratch
- xmpp.Node.__init__(self, 'x', attrs={'xmlns': xmpp.NS_DATA})
+ nbxmpp.Node.__init__(self, 'x', attrs={'xmlns': nbxmpp.NS_DATA})
if type_ is not None:
self.type_=type_
@@ -700,7 +700,7 @@ class MultipleDataForm(DataForm):
if items is not None:
self.items = items
else:
- # we already have xmpp.Node inside - try to convert all
+ # we already have nbxmpp.Node inside - try to convert all
# fields into DataField objects
if items is None:
self.items = list(self.iterTags('item'))
diff --git a/src/common/gajim.py b/src/common/gajim.py
index 428b6cae2..27df4e379 100644
--- a/src/common/gajim.py
+++ b/src/common/gajim.py
@@ -32,7 +32,7 @@ import logging
import locale
import config
-import xmpp
+import nbxmpp
import defs
import common.ged
@@ -203,15 +203,16 @@ except ImportError:
gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'}
-gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI, xmpp.NS_FILE,
- xmpp.NS_MUC, xmpp.NS_MUC_USER, xmpp.NS_MUC_ADMIN, xmpp.NS_MUC_OWNER,
- xmpp.NS_MUC_CONFIG, xmpp.NS_COMMANDS, xmpp.NS_DISCO_INFO, 'ipv6',
- 'jabber:iq:gateway', xmpp.NS_LAST, xmpp.NS_PRIVACY, xmpp.NS_PRIVATE,
- xmpp.NS_REGISTER, xmpp.NS_VERSION, xmpp.NS_DATA, xmpp.NS_ENCRYPTED, 'msglog',
- 'sslc2s', 'stringprep', xmpp.NS_PING, xmpp.NS_TIME_REVISED, xmpp.NS_SSN,
- xmpp.NS_MOOD, xmpp.NS_ACTIVITY, xmpp.NS_NICK, xmpp.NS_ROSTERX, xmpp.NS_SECLABEL,
- xmpp.NS_HASHES, xmpp.NS_HASHES_MD5, xmpp.NS_HASHES_SHA1,
- xmpp.NS_HASHES_SHA256, xmpp.NS_HASHES_SHA512]
+gajim_common_features = [nbxmpp.NS_BYTESTREAM, nbxmpp.NS_SI, nbxmpp.NS_FILE,
+ nbxmpp.NS_MUC, nbxmpp.NS_MUC_USER, nbxmpp.NS_MUC_ADMIN, nbxmpp.NS_MUC_OWNER,
+ nbxmpp.NS_MUC_CONFIG, nbxmpp.NS_COMMANDS, nbxmpp.NS_DISCO_INFO, 'ipv6',
+ 'jabber:iq:gateway', nbxmpp.NS_LAST, nbxmpp.NS_PRIVACY, nbxmpp.NS_PRIVATE,
+ nbxmpp.NS_REGISTER, nbxmpp.NS_VERSION, nbxmpp.NS_DATA, nbxmpp.NS_ENCRYPTED,
+ 'msglog', 'sslc2s', 'stringprep', nbxmpp.NS_PING, nbxmpp.NS_TIME_REVISED,
+ nbxmpp.NS_SSN, nbxmpp.NS_MOOD, nbxmpp.NS_ACTIVITY, nbxmpp.NS_NICK,
+ nbxmpp.NS_ROSTERX, nbxmpp.NS_SECLABEL, nbxmpp.NS_HASHES,
+ nbxmpp.NS_HASHES_MD5, nbxmpp.NS_HASHES_SHA1, nbxmpp.NS_HASHES_SHA256,
+ nbxmpp.NS_HASHES_SHA512]
# Optional features gajim supports per account
gajim_optional_features = {}
diff --git a/src/common/ged.py b/src/common/ged.py
index 0d8766c1f..9ac3604a2 100644
--- a/src/common/ged.py
+++ b/src/common/ged.py
@@ -27,7 +27,7 @@ Global Events Dispatcher module.
import traceback
-from common.xmpp import NodeProcessed
+from nbxmpp import NodeProcessed
import logging
log = logging.getLogger('gajim.c.ged')
diff --git a/src/common/helpers.py b/src/common/helpers.py
index 36d4e7373..c83da177a 100644
--- a/src/common/helpers.py
+++ b/src/common/helpers.py
@@ -142,7 +142,7 @@ def parse_resource(resource):
"""
if resource:
try:
- from xmpp.stringprepare import resourceprep
+ from nbxmpp.stringprepare import resourceprep
return resourceprep.prepare(unicode(resource))
except UnicodeError:
raise InvalidFormat, 'Invalid character in resource.'
@@ -157,7 +157,7 @@ def prep(user, server, resource):
if len(user) < 1 or len(user) > 1023:
raise InvalidFormat, _('Username must be between 1 and 1023 chars')
try:
- from xmpp.stringprepare import nodeprep
+ from nbxmpp.stringprepare import nodeprep
user = nodeprep.prepare(unicode(user))
except UnicodeError:
raise InvalidFormat, _('Invalid character in username.')
@@ -168,7 +168,7 @@ def prep(user, server, resource):
if len(server) < 1 or len(server) > 1023:
raise InvalidFormat, _('Server must be between 1 and 1023 chars')
try:
- from xmpp.stringprepare import nameprep
+ from nbxmpp.stringprepare import nameprep
server = nameprep.prepare(unicode(server))
except UnicodeError:
raise InvalidFormat, _('Invalid character in hostname.')
@@ -179,7 +179,7 @@ def prep(user, server, resource):
if len(resource) < 1 or len(resource) > 1023:
raise InvalidFormat, _('Resource must be between 1 and 1023 chars')
try:
- from xmpp.stringprepare import resourceprep
+ from nbxmpp.stringprepare import resourceprep
resource = resourceprep.prepare(unicode(resource))
except UnicodeError:
raise InvalidFormat, _('Invalid character in resource.')
@@ -1300,7 +1300,7 @@ def prepare_and_validate_gpg_keyID(account, jid, keyID):
return keyID
def update_optional_features(account = None):
- import xmpp
+ import nbxmpp
if account:
accounts = [account]
else:
@@ -1308,38 +1308,41 @@ def update_optional_features(account = None):
for a in accounts:
gajim.gajim_optional_features[a] = []
if gajim.config.get_per('accounts', a, 'subscribe_mood'):
- gajim.gajim_optional_features[a].append(xmpp.NS_MOOD + '+notify')
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_MOOD + '+notify')
if gajim.config.get_per('accounts', a, 'subscribe_activity'):
- gajim.gajim_optional_features[a].append(xmpp.NS_ACTIVITY + '+notify')
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_ACTIVITY + \
+ '+notify')
if gajim.config.get_per('accounts', a, 'publish_tune'):
- gajim.gajim_optional_features[a].append(xmpp.NS_TUNE)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_TUNE)
if gajim.config.get_per('accounts', a, 'publish_location'):
- gajim.gajim_optional_features[a].append(xmpp.NS_LOCATION)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_LOCATION)
if gajim.config.get_per('accounts', a, 'subscribe_tune'):
- gajim.gajim_optional_features[a].append(xmpp.NS_TUNE + '+notify')
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_TUNE + '+notify')
if gajim.config.get_per('accounts', a, 'subscribe_nick'):
- gajim.gajim_optional_features[a].append(xmpp.NS_NICK + '+notify')
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_NICK + '+notify')
if gajim.config.get_per('accounts', a, 'subscribe_location'):
- gajim.gajim_optional_features[a].append(xmpp.NS_LOCATION + '+notify')
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_LOCATION + \
+ '+notify')
if gajim.config.get('outgoing_chat_state_notifactions') != 'disabled':
- gajim.gajim_optional_features[a].append(xmpp.NS_CHATSTATES)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_CHATSTATES)
if not gajim.config.get('ignore_incoming_xhtml'):
- gajim.gajim_optional_features[a].append(xmpp.NS_XHTML_IM)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_XHTML_IM)
if gajim.HAVE_PYCRYPTO \
and gajim.config.get_per('accounts', a, 'enable_esessions'):
- gajim.gajim_optional_features[a].append(xmpp.NS_ESESSION)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_ESESSION)
if gajim.config.get_per('accounts', a, 'answer_receipts'):
- gajim.gajim_optional_features[a].append(xmpp.NS_RECEIPTS)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_RECEIPTS)
if gajim.HAVE_FARSTREAM:
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP_AUDIO)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP_VIDEO)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_ICE_UDP)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_FILE_TRANSFER)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_XTLS)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_BYTESTREAM)
- gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_IBB)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE_RTP)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE_RTP_AUDIO)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE_RTP_VIDEO)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE_ICE_UDP)
+ gajim.gajim_optional_features[a].append(
+ nbxmpp.NS_JINGLE_FILE_TRANSFER)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE_XTLS)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE_BYTESTREAM)
+ gajim.gajim_optional_features[a].append(nbxmpp.NS_JINGLE_IBB)
gajim.caps_hash[a] = caps_cache.compute_caps_hash([gajim.gajim_identity],
gajim.gajim_common_features + gajim.gajim_optional_features[a])
# re-send presence with new hash
@@ -1381,7 +1384,7 @@ def get_subscription_request_msg(account=None):
return s
def replace_dataform_media(form, stanza):
- import xmpp
+ import nbxmpp
found = False
for field in form.getTags('field'):
for media in field.getTags('media'):
@@ -1389,7 +1392,7 @@ def replace_dataform_media(form, stanza):
uri_data = uri.getData()
if uri_data.startswith('cid:'):
uri_data = uri_data[4:]
- for data in stanza.getTags('data', namespace=xmpp.NS_BOB):
+ for data in stanza.getTags('data', namespace=nbxmpp.NS_BOB):
if data.getAttr('cid') == uri_data:
uri.setData(data.getData())
found = True
diff --git a/src/common/jingle.py b/src/common/jingle.py
index 9d4e86f54..57e26c3b1 100644
--- a/src/common/jingle.py
+++ b/src/common/jingle.py
@@ -26,7 +26,7 @@ Handles the jingle signalling protocol
# * config:
# - codecs
-import xmpp
+import nbxmpp
import helpers
import gajim
@@ -80,7 +80,7 @@ class ConnectionJingle(object):
if (jid, id_) in self.__iq_responses.keys():
self.__iq_responses[(jid, id_)].on_stanza(stanza)
del self.__iq_responses[(jid, id_)]
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
jingle = stanza.getTag('jingle')
# a jingle element is not necessary in iq-result stanza
# don't check for that
@@ -105,7 +105,7 @@ class ConnectionJingle(object):
if sid in self._sessions and \
self._sessions[sid].state == JingleStates.ended:
self.delete_jingle_session(sid)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def start_audio(self, jid):
if self.get_jingle_session(jid, media='audio'):
@@ -143,15 +143,15 @@ class ConnectionJingle(object):
contact = gajim.contacts.get_gc_contact(self.name, gcc[0], gcc[1])
if contact is None:
return
- use_security = contact.supports(xmpp.NS_JINGLE_XTLS)
+ use_security = contact.supports(nbxmpp.NS_JINGLE_XTLS)
jingle = JingleSession(self, weinitiate=True, jid=jid, werequest=request)
# this is a file transfer
jingle.session_type_FT = True
self._sessions[jingle.sid] = jingle
file_props.sid = jingle.sid
- if contact.supports(xmpp.NS_JINGLE_BYTESTREAM):
+ if contact.supports(nbxmpp.NS_JINGLE_BYTESTREAM):
transport = JingleTransportSocks5()
- elif contact.supports(xmpp.NS_JINGLE_IBB):
+ elif contact.supports(nbxmpp.NS_JINGLE_IBB):
transport = JingleTransportIBB()
c = JingleFileTransfer(jingle, transport=transport,
file_props=file_props, use_security=use_security)
@@ -161,14 +161,14 @@ class ConnectionJingle(object):
return c.transport.sid
def __hash_support(self, contact):
- if contact.supports(xmpp.NS_HASHES):
- if contact.supports(xmpp.NS_HASHES_MD5):
+ if contact.supports(nbxmpp.NS_HASHES):
+ if contact.supports(nbxmpp.NS_HASHES_MD5):
return 'md5'
- elif contact.supports(xmpp.NS_HASHES_SHA1):
+ elif contact.supports(nbxmpp.NS_HASHES_SHA1):
return 'sha-1'
- elif contact.supports(xmpp.NS_HASHES_SHA256):
+ elif contact.supports(nbxmpp.NS_HASHES_SHA256):
return 'sha-256'
- elif contact.supports(xmpp.NS_HASHES_SHA512):
+ elif contact.supports(nbxmpp.NS_HASHES_SHA512):
return 'sha-512'
return None
diff --git a/src/common/jingle_content.py b/src/common/jingle_content.py
index adb32814a..df04d729f 100644
--- a/src/common/jingle_content.py
+++ b/src/common/jingle_content.py
@@ -16,7 +16,7 @@ Handles Jingle contents (XEP 0166)
"""
import gajim
-import xmpp
+import nbxmpp
from jingle_transport import JingleTransportIBB
contents = {}
@@ -127,7 +127,7 @@ class JingleContent(object):
"""
Build a XML content-wrapper for our data
"""
- return xmpp.Node('content',
+ return nbxmpp.Node('content',
attrs={'name': self.name, 'creator': self.creator},
payload=payload)
@@ -164,29 +164,29 @@ class JingleContent(object):
content.addChild(node=self.transport.make_transport())
def _fill_content(self, content):
- description_node = xmpp.simplexml.Node(
- tag=xmpp.NS_JINGLE_FILE_TRANSFER + ' description')
+ description_node = nbxmpp.simplexml.Node(
+ tag=nbxmpp.NS_JINGLE_FILE_TRANSFER + ' description')
if self.session.werequest:
- simode = xmpp.simplexml.Node(tag='request')
+ simode = nbxmpp.simplexml.Node(tag='request')
else:
- simode = xmpp.simplexml.Node(tag='offer')
- file_tag = simode.setTag('file', namespace=xmpp.NS_FILE)
+ simode = nbxmpp.simplexml.Node(tag='offer')
+ file_tag = simode.setTag('file', namespace=nbxmpp.NS_FILE)
if self.file_props.name:
- node = xmpp.simplexml.Node(tag='name')
+ node = nbxmpp.simplexml.Node(tag='name')
node.addData(self.file_props.name)
file_tag.addChild(node=node)
if self.file_props.date:
- node = xmpp.simplexml.Node(tag='date')
+ node = nbxmpp.simplexml.Node(tag='date')
node.addData(self.file_props.date)
file_tag.addChild(node=node)
if self.file_props.size:
- node = xmpp.simplexml.Node(tag='size')
+ node = nbxmpp.simplexml.Node(tag='size')
node.addData(self.file_props.size)
file_tag.addChild(node=node)
if self.file_props.type_ == 'r':
if self.file_props.hash_:
h = file_tag.addChild('hash', attrs={
- 'algo': self.file_props.algo}, namespace=xmpp.NS_HASHES,
+ 'algo': self.file_props.algo}, namespace=nbxmpp.NS_HASHES,
payload=self.file_props.hash_)
else:
# if the file is less than 10 mb, then it is small
@@ -209,11 +209,11 @@ class JingleContent(object):
desc.setData(self.file_props.desc)
description_node.addChild(node=simode)
if self.use_security:
- security = xmpp.simplexml.Node(
- tag=xmpp.NS_JINGLE_XTLS + ' security')
+ security = nbxmpp.simplexml.Node(
+ tag=nbxmpp.NS_JINGLE_XTLS + ' security')
# TODO: add fingerprint element
for m in ('x509', ): # supported authentication methods
- method = xmpp.simplexml.Node(tag='method')
+ method = nbxmpp.simplexml.Node(tag='method')
method.setAttr('name', m)
security.addChild(node=method)
content.addChild(node=security)
diff --git a/src/common/jingle_ft.py b/src/common/jingle_ft.py
index 101e93310..8ac9330c4 100644
--- a/src/common/jingle_ft.py
+++ b/src/common/jingle_ft.py
@@ -21,7 +21,7 @@ Handles Jingle File Transfer (XEP 0234)
import hashlib
import gajim
-import xmpp
+import nbxmpp
from jingle_content import contents, JingleContent
from jingle_transport import *
from common import helpers
@@ -70,7 +70,7 @@ class JingleFileTransfer(JingleContent):
self.use_security = use_security
self.file_props = file_props
self.weinitiate = self.session.weinitiate
- self.werequest = self.session.werequest
+ self.werequest = self.session.werequest
if self.file_props is not None:
if self.session.werequest:
self.file_props.sender = self.session.peerjid
@@ -130,9 +130,9 @@ class JingleFileTransfer(JingleContent):
def __send_hash(self):
# Send hash in a session info
- checksum = xmpp.Node(tag='checksum', payload=[xmpp.Node(tag='file',
+ checksum = nbxmpp.Node(tag='checksum', payload=[nbxmpp.Node(tag='file',
payload=[self._calcHash()])])
- checksum.setNamespace(xmpp.NS_JINGLE_FILE_TRANSFER)
+ checksum.setNamespace(nbxmpp.NS_JINGLE_FILE_TRANSFER)
self.session.__session_info(checksum )
pjid = gajim.get_jid_without_resource(self.session.peerjid)
file_info = {'name' : self.file_props.name,
@@ -153,7 +153,7 @@ class JingleFileTransfer(JingleContent):
except:
# can't open file
return
- h = xmpp.Hashes()
+ h = nbxmpp.Hashes()
hash_ = h.calculateHash(self.file_props.algo, file_)
# DEBUG
#hash_ = '1294809248109223'
@@ -177,10 +177,10 @@ class JingleFileTransfer(JingleContent):
con.connection.send(response)
# If we are requesting we don't have the file
if self.session.werequest:
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
# We send the file
self.__state_changed(STATE_TRANSFERING)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
self.file_props.streamhosts = self.transport.remote_candidates
# Calculate file hash in a new thread
# if we haven't sent the hash already.
@@ -205,7 +205,7 @@ class JingleFileTransfer(JingleContent):
receiving=False)
return
self.__state_changed(STATE_TRANSFERING)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def __on_session_terminate(self, stanza, content, error, action):
log.info("__on_session_terminate")
@@ -228,7 +228,7 @@ class JingleFileTransfer(JingleContent):
candUsed = content.getTag('transport').getTag('candidate-used')
if (candError or candUsed) and \
self.state >= STATE_CAND_SENT_AND_RECEIVED:
- raise xmpp.OutOfOrder
+ raise nbxmpp.OutOfOrder
if candError:
if not gajim.socks5queue.listener.connections:
gajim.socks5queue.listener.disconnect()
@@ -244,7 +244,7 @@ class JingleFileTransfer(JingleContent):
response.delChild(response.getQuery())
self.session.connection.connection.send(response)
self.__state_changed(STATE_TRANSFERING)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
args = {'candError' : True}
self.__state_changed(STATE_CAND_RECEIVED, args)
@@ -273,7 +273,7 @@ class JingleFileTransfer(JingleContent):
response.delChild(response.getQuery())
self.session.connection.connection.send(response)
self.__state_changed(STATE_TRANSFERING)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
self.__state_changed(STATE_CAND_RECEIVED, args)
@@ -376,4 +376,4 @@ class JingleFileTransfer(JingleContent):
def get_content(desc):
return JingleFileTransfer
-contents[xmpp.NS_JINGLE_FILE_TRANSFER] = get_content
+contents[nbxmpp.NS_JINGLE_FILE_TRANSFER] = get_content
diff --git a/src/common/jingle_ftstates.py b/src/common/jingle_ftstates.py
index 80b0d4e71..a83ab9e30 100644
--- a/src/common/jingle_ftstates.py
+++ b/src/common/jingle_ftstates.py
@@ -12,7 +12,7 @@
##
import gajim
-import xmpp
+import nbxmpp
from jingle_transport import *
from common.socks5 import Socks5ReceiverClient, Socks5SenderClient
@@ -65,13 +65,13 @@ class StateCandSent(JingleFileTransferStates):
# Send candidate used
streamhost = args['streamhost']
self.jft.nominated_cand['our-cand'] = streamhost
- content = xmpp.Node('content')
+ content = nbxmpp.Node('content')
content.setAttr('creator', 'initiator')
content.setAttr('name', self.jft.name)
- transport = xmpp.Node('transport')
- transport.setNamespace(xmpp.NS_JINGLE_BYTESTREAM)
+ transport = nbxmpp.Node('transport')
+ transport.setNamespace(nbxmpp.NS_JINGLE_BYTESTREAM)
transport.setAttr('sid', self.jft.transport.sid)
- candidateused = xmpp.Node('candidate-used')
+ candidateused = nbxmpp.Node('candidate-used')
candidateused.setAttr('cid', streamhost['cid'])
transport.addChild(node=candidateused)
content.addChild(node=transport)
diff --git a/src/common/jingle_rtp.py b/src/common/jingle_rtp.py
index 4e552dbb1..8717c2105 100644
--- a/src/common/jingle_rtp.py
+++ b/src/common/jingle_rtp.py
@@ -20,7 +20,7 @@ from collections import deque
import gobject
import socket
-import xmpp
+import nbxmpp
import farstream, gst
from glib import GError
@@ -151,7 +151,7 @@ class JingleRTPContent(JingleContent):
self.p2psession.stop_telephony_event()
def _fill_content(self, content):
- content.addChild(xmpp.NS_JINGLE_RTP + ' description',
+ content.addChild(nbxmpp.NS_JINGLE_RTP + ' description',
attrs={'media': self.media}, payload=self.iter_codecs())
def _setup_funnel(self):
@@ -190,7 +190,7 @@ class JingleRTPContent(JingleContent):
elif name == 'farstream-component-state-changed':
state = message.structure['state']
if state == farstream.STREAM_STATE_FAILED:
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
reason.setTag('failed-transport')
self.session.remove_content(self.creator, self.name, reason)
elif name == 'farstream-error':
@@ -222,7 +222,7 @@ class JingleRTPContent(JingleContent):
self.src_bin.get_pad('src').link(sink_pad)
self.stream_failed_once = True
else:
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
reason.setTag('failed-application')
self.session.remove_content(self.creator, self.name, reason)
@@ -276,11 +276,11 @@ class JingleRTPContent(JingleContent):
if codec.clock_rate:
attrs['clockrate'] = codec.clock_rate
if codec.optional_params:
- payload = (xmpp.Node('parameter', {'name': name, 'value': value})
- for name, value in codec.optional_params)
+ payload = (nbxmpp.Node('parameter', {'name': name,
+ 'value': value}) for name, value in codec.optional_params)
else:
payload = ()
- yield xmpp.Node('payload-type', attrs, payload)
+ yield nbxmpp.Node('payload-type', attrs, payload)
def __stop(self, *things):
self.pipeline.set_state(gst.STATE_NULL)
@@ -408,4 +408,4 @@ def get_content(desc):
elif desc['media'] == 'video':
return JingleVideo
-contents[xmpp.NS_JINGLE_RTP] = get_content
+contents[nbxmpp.NS_JINGLE_RTP] = get_content
diff --git a/src/common/jingle_session.py b/src/common/jingle_session.py
index c5356b76e..a19056f9b 100644
--- a/src/common/jingle_session.py
+++ b/src/common/jingle_session.py
@@ -27,7 +27,7 @@ Handles Jingle sessions (XEP 0166)
# * timeout
import gajim #Get rid of that?
-import xmpp
+import nbxmpp
from jingle_transport import get_jingle_transport, JingleTransportIBB
from jingle_content import get_jingle_content, JingleContentSetupException
from jingle_content import JingleContent
@@ -105,9 +105,9 @@ class JingleSession(object):
# use .prepend() to add new callbacks, especially when you're going
# to send error instead of ack
self.callbacks = {
- 'content-accept': [self.__ack, self.__on_content_accept,
+ 'content-accept': [self.__ack, self.__on_content_accept,
self.__broadcast],
- 'content-add': [self.__ack,
+ 'content-add': [self.__ack,
self.__on_content_add, self.__broadcast
], #TODO
'content-modify': [self.__ack], #TODO
@@ -118,14 +118,14 @@ class JingleSession(object):
'session-accept': [self.__ack, self.__on_session_accept,
self.__on_content_accept,
self.__broadcast],
- 'session-info': [self.__ack, self.__broadcast,
+ 'session-info': [self.__ack, self.__broadcast,
self.__on_session_info ],
- 'session-initiate': [self.__ack, self.__on_session_initiate,
+ 'session-initiate': [self.__ack, self.__on_session_initiate,
self.__broadcast],
- 'session-terminate': [self.__ack,self.__on_session_terminate,
+ 'session-terminate': [self.__ack,self.__on_session_terminate,
self.__broadcast_all],
'transport-info': [self.__ack, self.__broadcast],
- 'transport-replace': [self.__ack, self.__broadcast,
+ 'transport-replace': [self.__ack, self.__broadcast,
self.__on_transport_replace], #TODO
'transport-accept': [self.__ack], #TODO
'transport-reject': [self.__ack], #TODO
@@ -147,15 +147,15 @@ class JingleSession(object):
"""
Called when user declines session in UI (when we aren't the initiator)
"""
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
reason.addChild('decline')
self._session_terminate(reason)
-
+
def cancel_session(self):
"""
Called when user declines session in UI (when we aren't the initiator)
"""
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
reason.addChild('cancel')
self._session_terminate(reason)
@@ -177,7 +177,7 @@ class JingleSession(object):
"""
Called when user stops or cancel session in UI
"""
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
if self.state == JingleStates.active:
reason.addChild('success')
else:
@@ -227,7 +227,7 @@ class JingleSession(object):
self.end_session()
def modify_content(self, creator, name, transport = None):
- '''
+ '''
Currently used for transport replacement
'''
content = self.contents[(creator,name)]
@@ -314,7 +314,7 @@ class JingleSession(object):
"""
A callback for ConnectionJingle. It gets stanza, then tries to send it to
all internally registered callbacks. First one to raise
- xmpp.NodeProcessed breaks function
+ nbxmpp.NodeProcessed breaks function
"""
jingle = stanza.getTag('jingle')
error = stanza.getTag('error')
@@ -339,7 +339,7 @@ class JingleSession(object):
try:
for call in callables:
call(stanza=stanza, jingle=jingle, error=error, action=action)
- except xmpp.NodeProcessed:
+ except nbxmpp.NodeProcessed:
pass
except TieBreak:
self.__send_error(stanza, 'conflict', 'tiebreak')
@@ -360,10 +360,10 @@ class JingleSession(object):
text = error.getTagData('text')
error_name = None
for child in error.getChildren():
- if child.getNamespace() == xmpp.NS_JINGLE_ERRORS:
+ if child.getNamespace() == nbxmpp.NS_JINGLE_ERRORS:
error_name = child.getName()
break
- elif child.getNamespace() == xmpp.NS_STANZAS:
+ elif child.getNamespace() == nbxmpp.NS_STANZAS:
error_name = child.getName()
self.__dispatch_error(error_name, text, error.getAttr('type'))
@@ -387,12 +387,12 @@ class JingleSession(object):
name = content['name']
if (creator, name) in self.contents:
transport_ns = content.getTag('transport').getNamespace()
- if transport_ns == xmpp.NS_JINGLE_ICE_UDP:
+ if transport_ns == nbxmpp.NS_JINGLE_ICE_UDP:
# FIXME: We don't manage anything else than ICE-UDP now...
# What was the previous transport?!?
# Anyway, content's transport is not modifiable yet
pass
- elif transport_ns == xmpp.NS_JINGLE_IBB:
+ elif transport_ns == nbxmpp.NS_JINGLE_IBB:
transport = JingleTransportIBB()
self.modify_content(creator, name, transport)
self.state = JingleStates.pending
@@ -406,7 +406,7 @@ class JingleSession(object):
'name': name})
content.setTag('transport', namespace=transport_ns)
self.connection.connection.send(stanza)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
# FIXME: This ressource is unknown to us, what should we do?
# For now, reject the transport
@@ -415,7 +415,7 @@ class JingleSession(object):
'name': name})
c.setTag('transport', namespace=transport_ns)
self.connection.connection.send(stanza)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def __on_session_info(self, stanza, jingle, error, action):
# TODO: ringing, active, (un)hold, (un)mute
@@ -424,18 +424,18 @@ class JingleSession(object):
payload = jingle.getPayload()
for p in payload:
if p.getName() == 'checksum':
- hash_ = p.getTag('file').getTag(name='hash',
- namespace=xmpp.NS_HASHES)
+ hash_ = p.getTag('file').getTag(name='hash',
+ namespace=nbxmpp.NS_HASHES)
algo = hash_.getAttr('algo')
- if algo in xmpp.Hashes.supported:
+ if algo in nbxmpp.Hashes.supported:
file_props = FilesProp.getFileProp(self.connection.name,
self.sid)
file_props.algo = algo
file_props.hash_ = hash_.getData()
- raise xmpp.NodeProcessed
- self.__send_error(stanza, 'feature-not-implemented', 'unsupported-info',
+ raise nbxmpp.NodeProcessed
+ self.__send_error(stanza, 'feature-not-implemented', 'unsupported-info',
type_='modify')
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def __on_content_remove(self, stanza, jingle, error, action):
for content in jingle.iterTags('content'):
@@ -449,7 +449,7 @@ class JingleSession(object):
media=content.media, reason='removed'))
content.destroy()
if not self.contents:
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
reason.setTag('success')
self._session_terminate(reason)
@@ -507,12 +507,12 @@ class JingleSession(object):
if contents[0][0] != 'file':
for session in self.connection.iter_jingle_sessions(self.peerjid):
if not session is self:
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
alternative_session = reason.setTag('alternative-session')
alternative_session.setTagData('sid', session.sid)
self.__ack(stanza, jingle, error, action)
self._session_terminate(reason)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
# Stop if we don't have the requested file or the peer is not
# allowed to request the file
@@ -533,15 +533,15 @@ class JingleSession(object):
'file that we dont have or ' + \
'it is not allowed to request')
self.decline_session()
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
# If there's no content we understand...
if not contents:
# TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate
- reason = xmpp.Node('reason')
+ reason = nbxmpp.Node('reason')
reason.setTag(reason_txt)
self.__ack(stanza, jingle, error, action)
self._session_terminate(reason)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
self.state = JingleStates.pending
# Send event about starting a session
gajim.nec.push_incoming_event(JingleRequestReceivedEvent(None,
@@ -566,7 +566,7 @@ class JingleSession(object):
if (creator, name) not in self.contents:
text = 'Content %s (created by %s) does not exist' % (name, creator)
self.__send_error(stanza, 'bad-request', text=text, type_='_modify')
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
cn = self.contents[(creator, name)]
cn.on_stanza(stanza, content, error, action)
@@ -654,23 +654,24 @@ class JingleSession(object):
return (reason, text)
def __make_jingle(self, action, reason=None):
- stanza = xmpp.Iq(typ='set', to=xmpp.JID(self.peerjid),
- frm=self.ourjid)
+ stanza = nbxmpp.Iq(typ='set', to=nbxmpp.JID(self.peerjid),
+ frm=self.ourjid)
attrs = {'action': action,
'sid': self.sid,
'initiator' : self.initiator}
- jingle = stanza.addChild('jingle', attrs=attrs, namespace=xmpp.NS_JINGLE)
+ jingle = stanza.addChild('jingle', attrs=attrs,
+ namespace=nbxmpp.NS_JINGLE)
if reason is not None:
jingle.addChild(node=reason)
return stanza, jingle
def __send_error(self, stanza, error, jingle_error=None, text=None, type_=None):
- err_stanza = xmpp.Error(stanza, '%s %s' % (xmpp.NS_STANZAS, error))
+ err_stanza = nbxmpp.Error(stanza, '%s %s' % (nbxmpp.NS_STANZAS, error))
err = err_stanza.getTag('error')
if type_:
err.setAttr('type', type_)
if jingle_error:
- err.setTag(jingle_error, namespace=xmpp.NS_JINGLE_ERRORS)
+ err.setTag(jingle_error, namespace=nbxmpp.NS_JINGLE_ERRORS)
if text:
err.setTagData('text', text)
self.connection.connection.send(err_stanza)
@@ -718,7 +719,7 @@ class JingleSession(object):
if payload:
jingle.addChild(node=payload)
self.connection.connection.send(stanza)
-
+
def _JingleFileTransfer__session_info(self, p):
# For some strange reason when I call
# self.session.__session_info(h) from the jingleFileTransfer object
diff --git a/src/common/jingle_transport.py b/src/common/jingle_transport.py
index dabd8ce0b..b812fe471 100644
--- a/src/common/jingle_transport.py
+++ b/src/common/jingle_transport.py
@@ -15,7 +15,7 @@
Handles Jingle Transports (currently only ICE-UDP)
"""
-import xmpp
+import nbxmpp
import socket
from common import gajim
from common.protocol.bytestream import ConnectionSocks5Bytestream
@@ -70,7 +70,7 @@ class JingleTransport(object):
candidates = self._iter_candidates()
else:
candidates = (self.make_candidate(candidate) for candidate in candidates)
- transport = xmpp.Node('transport', payload=candidates)
+ transport = nbxmpp.Node('transport', payload=candidates)
return transport
def parse_transport_stanza(self, transport):
@@ -120,7 +120,7 @@ class JingleTransportSocks5(JingleTransport):
'type': candidate['type']
}
- return xmpp.Node('candidate', attrs=attrs)
+ return nbxmpp.Node('candidate', attrs=attrs)
def make_transport(self, candidates=None, add_candidates = True):
if add_candidates:
@@ -129,8 +129,8 @@ class JingleTransportSocks5(JingleTransport):
self._add_proxy_candidates()
transport = JingleTransport.make_transport(self, candidates)
else:
- transport = xmpp.Node('transport')
- transport.setNamespace(xmpp.NS_JINGLE_BYTESTREAM)
+ transport = nbxmpp.Node('transport')
+ transport.setNamespace(nbxmpp.NS_JINGLE_BYTESTREAM)
transport.setAttr('sid', self.sid)
if self.file_props.dstaddr:
transport.setAttr('dstaddr', self.file_props.dstaddr)
@@ -266,10 +266,10 @@ class JingleTransportSocks5(JingleTransport):
if sesn is None:
return
- iq = xmpp.Iq(to=proxy['jid'], frm=self.ourjid, typ='set')
+ iq = nbxmpp.Iq(to=proxy['jid'], frm=self.ourjid, typ='set')
auth_id = "au_" + proxy['sid']
iq.setID(auth_id)
- query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
+ query = iq.setTag('query', namespace=nbxmpp.NS_BYTESTREAM)
query.setAttr('sid', proxy['sid'])
activate = query.setTag('activate')
activate.setData(sesn.peerjid)
@@ -277,14 +277,14 @@ class JingleTransportSocks5(JingleTransport):
self.connection.connection.send(iq)
- content = xmpp.Node('content')
+ content = nbxmpp.Node('content')
content.setAttr('creator', 'initiator')
c = self.get_content()
content.setAttr('name', c.name)
- transport = xmpp.Node('transport')
- transport.setNamespace(xmpp.NS_JINGLE_BYTESTREAM)
+ transport = nbxmpp.Node('transport')
+ transport.setNamespace(nbxmpp.NS_JINGLE_BYTESTREAM)
transport.setAttr('sid', proxy['sid'])
- activated = xmpp.Node('activated')
+ activated = nbxmpp.Node('activated')
cid = None
if 'cid' in proxy:
@@ -322,8 +322,8 @@ class JingleTransportIBB(JingleTransport):
def make_transport(self):
- transport = xmpp.Node('transport')
- transport.setNamespace(xmpp.NS_JINGLE_IBB)
+ transport = nbxmpp.Node('transport')
+ transport.setNamespace(nbxmpp.NS_JINGLE_IBB)
transport.setAttr('block-size', self.block_sz)
transport.setAttr('sid', self.sid)
return transport
@@ -360,11 +360,11 @@ class JingleTransportICEUDP(JingleTransport):
else:
# we actually don't handle properly different tcp options in jingle
attrs['protocol'] = 'tcp'
- return xmpp.Node('candidate', attrs=attrs)
+ return nbxmpp.Node('candidate', attrs=attrs)
def make_transport(self, candidates=None):
transport = JingleTransport.make_transport(self, candidates)
- transport.setNamespace(xmpp.NS_JINGLE_ICE_UDP)
+ transport.setNamespace(nbxmpp.NS_JINGLE_ICE_UDP)
if self.candidates and self.candidates[0].username and \
self.candidates[0].password:
transport.setAttr('ufrag', self.candidates[0].username)
@@ -405,6 +405,6 @@ class JingleTransportICEUDP(JingleTransport):
self.remote_candidates.extend(candidates)
return candidates
-transports[xmpp.NS_JINGLE_ICE_UDP] = JingleTransportICEUDP
-transports[xmpp.NS_JINGLE_BYTESTREAM] = JingleTransportSocks5
-transports[xmpp.NS_JINGLE_IBB] = JingleTransportIBB
+transports[nbxmpp.NS_JINGLE_ICE_UDP] = JingleTransportICEUDP
+transports[nbxmpp.NS_JINGLE_BYTESTREAM] = JingleTransportSocks5
+transports[nbxmpp.NS_JINGLE_IBB] = JingleTransportIBB
diff --git a/src/common/jingle_xtls.py b/src/common/jingle_xtls.py
index 5e3c6ecf1..39d62bca6 100644
--- a/src/common/jingle_xtls.py
+++ b/src/common/jingle_xtls.py
@@ -17,6 +17,7 @@
##
import os
+import nbxmpp
import logging
import common
@@ -56,7 +57,7 @@ def default_callback(connection, certificate, error_num, depth, return_code):
def load_cert_file(cert_path, cert_store):
"""
- This is almost identical to the one in common.xmpp.tls_nb
+ This is almost identical to the one in nbxmpp.tls_nb
"""
if not os.path.isfile(cert_path):
return
@@ -118,11 +119,11 @@ def send_cert(con, jid_from, sid):
for line in certfile.readlines():
if not line.startswith('-'):
certificate += line
- iq = common.xmpp.Iq('result', to=jid_from);
+ iq = nbxmpp.Iq('result', to=jid_from);
iq.setAttr('id', sid)
pubkey = iq.setTag('pubkeys')
- pubkey.setNamespace(common.xmpp.NS_PUBKEY_PUBKEY)
+ pubkey.setNamespace(nbxmpp.NS_PUBKEY_PUBKEY)
keyinfo = pubkey.setTag('keyinfo')
name = keyinfo.setTag('name')
@@ -151,11 +152,11 @@ def handle_new_cert(con, obj, jid_from):
approve_pending_content(id_)
def send_cert_request(con, to_jid):
- iq = common.xmpp.Iq('get', to=to_jid)
+ iq = nbxmpp.Iq('get', to=to_jid)
id_ = con.connection.getAnID()
iq.setAttr('id', id_)
pubkey = iq.setTag('pubkeys')
- pubkey.setNamespace(common.xmpp.NS_PUBKEY_PUBKEY)
+ pubkey.setNamespace(nbxmpp.NS_PUBKEY_PUBKEY)
con.connection.send(iq)
return unicode(id_)
diff --git a/src/common/message_archiving.py b/src/common/message_archiving.py
index 32936462b..5a5388f63 100644
--- a/src/common/message_archiving.py
+++ b/src/common/message_archiving.py
@@ -18,7 +18,7 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
-import common.xmpp
+import nbxmpp
from common import gajim
from common import ged
from common.connection_handlers_events import ArchivingReceivedEvent
@@ -52,16 +52,16 @@ class ConnectionArchive:
self._nec_archiving_changed_received)
def request_message_archiving_preferences(self):
- iq_ = common.xmpp.Iq('get')
- iq_.setTag('pref', namespace=common.xmpp.NS_ARCHIVE)
+ iq_ = nbxmpp.Iq('get')
+ iq_.setTag('pref', namespace=nbxmpp.NS_ARCHIVE)
self.connection.send(iq_)
def set_pref(self, name, **data):
'''
data contains names and values of pref name attributes.
'''
- iq_ = common.xmpp.Iq('set')
- pref = iq_.setTag('pref', namespace=common.xmpp.NS_ARCHIVE)
+ iq_ = nbxmpp.Iq('set')
+ pref = iq_.setTag('pref', namespace=nbxmpp.NS_ARCHIVE)
tag = pref.setTag(name)
for key, value in data.items():
if value is not None:
@@ -81,21 +81,21 @@ class ConnectionArchive:
self.set_pref('item', jid=jid, otr=otr, save=save)
def remove_item(self, jid):
- iq_ = common.xmpp.Iq('set')
- itemremove = iq_.setTag('itemremove', namespace=common.xmpp.NS_ARCHIVE)
+ iq_ = nbxmpp.Iq('set')
+ itemremove = iq_.setTag('itemremove', namespace=nbxmpp.NS_ARCHIVE)
item = itemremove.setTag('item')
item.setAttr('jid', jid)
self.connection.send(iq_)
def stop_archiving_session(self, thread_id):
- iq_ = common.xmpp.Iq('set')
- pref = iq_.setTag('pref', namespace=common.xmpp.NS_ARCHIVE)
+ iq_ = nbxmpp.Iq('set')
+ pref = iq_.setTag('pref', namespace=nbxmpp.NS_ARCHIVE)
session = pref.setTag('session', attrs={'thread': thread_id,
'save': 'false', 'otr': 'concede'})
self.connection.send(iq_)
def get_item_pref(self, jid):
- jid = common.xmpp.JID(jid)
+ jid = nbxmpp.JID(jid)
if unicode(jid) in self.items:
return self.items[jid]
@@ -142,7 +142,7 @@ class ConnectionArchive:
log.debug('_ArchiveCB %s' % iq_obj.getType())
gajim.nec.push_incoming_event(ArchivingReceivedEvent(None, conn=self,
stanza=iq_obj))
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_archiving_changed_received(self, obj):
if obj.conn.name != self.name:
@@ -160,8 +160,8 @@ class ConnectionArchive:
def request_collections_list_page(self, with_='', start=None, end=None,
after=None, max=30, exact_match=False):
- iq_ = common.xmpp.Iq('get')
- list_ = iq_.setTag('list', namespace=common.xmpp.NS_ARCHIVE)
+ iq_ = nbxmpp.Iq('get')
+ list_ = iq_.setTag('list', namespace=nbxmpp.NS_ARCHIVE)
if with_:
list_.setAttr('with', with_)
if exact_match:
@@ -170,7 +170,7 @@ class ConnectionArchive:
list_.setAttr('start', start)
if end:
list_.setAttr('end', end)
- set_ = list_.setTag('set', namespace=common.xmpp.NS_RSM)
+ set_ = list_.setTag('set', namespace=nbxmpp.NS_RSM)
set_.setTagData('max', max)
if after:
set_.setTagData('after', after)
@@ -181,12 +181,12 @@ class ConnectionArchive:
def request_collection_page(self, with_, start, end=None, after=None,
max=30, exact_match=False):
- iq_ = common.xmpp.Iq('get')
- retrieve = iq_.setTag('retrieve', namespace=common.xmpp.NS_ARCHIVE,
+ iq_ = nbxmpp.Iq('get')
+ retrieve = iq_.setTag('retrieve', namespace=nbxmpp.NS_ARCHIVE,
attrs={'with': with_, 'start': start})
if exact_match:
retrieve.setAttr('exactmatch', 'true')
- set_ = retrieve.setTag('set', namespace=common.xmpp.NS_RSM)
+ set_ = retrieve.setTag('set', namespace=nbxmpp.NS_RSM)
set_.setTagData('max', max)
if after:
set_.setTagData('after', after)
@@ -197,8 +197,8 @@ class ConnectionArchive:
def remove_collection(self, with_='', start=None, end=None,
exact_match=False, open=False):
- iq_ = common.xmpp.Iq('set')
- remove = iq_.setTag('remove', namespace=common.xmpp.NS_ARCHIVE)
+ iq_ = nbxmpp.Iq('set')
+ remove = iq_.setTag('remove', namespace=nbxmpp.NS_ARCHIVE)
if with_:
remove.setAttr('with', with_)
if exact_match:
@@ -212,10 +212,10 @@ class ConnectionArchive:
self.connection.send(iq_)
def request_modifications_page(self, start, max=30):
- iq_ = common.xmpp.Iq('get')
- moified = iq_.setTag('modified', namespace=common.xmpp.NS_ARCHIVE,
+ iq_ = nbxmpp.Iq('get')
+ moified = iq_.setTag('modified', namespace=nbxmpp.NS_ARCHIVE,
attrs={'start': start})
- set_ = moified.setTag('set', namespace=common.xmpp.NS_RSM)
+ set_ = moified.setTag('set', namespace=nbxmpp.NS_RSM)
set_.setTagData('max', max)
id_ = self.connection.getAnID()
iq_.setID(id_)
diff --git a/src/common/pep.py b/src/common/pep.py
index 1afc12f85..ab14c2212 100644
--- a/src/common/pep.py
+++ b/src/common/pep.py
@@ -221,7 +221,7 @@ import logging
log = logging.getLogger('gajim.c.pep')
from common import helpers
-from common import xmpp
+import nbxmpp
from common import gajim
import gtkgui_helpers
@@ -281,7 +281,7 @@ class UserMoodPEP(AbstractPEP):
'''XEP-0107: User Mood'''
type_ = 'mood'
- namespace = xmpp.NS_MOOD
+ namespace = nbxmpp.NS_MOOD
def _extract_info(self, items):
mood_dict = {}
@@ -327,7 +327,7 @@ class UserTunePEP(AbstractPEP):
'''XEP-0118: User Tune'''
type_ = 'tune'
- namespace = xmpp.NS_TUNE
+ namespace = nbxmpp.NS_TUNE
def _extract_info(self, items):
tune_dict = {}
@@ -373,7 +373,7 @@ class UserActivityPEP(AbstractPEP):
'''XEP-0108: User Activity'''
type_ = 'activity'
- namespace = xmpp.NS_ACTIVITY
+ namespace = nbxmpp.NS_ACTIVITY
def _extract_info(self, items):
activity_dict = {}
@@ -439,7 +439,7 @@ class UserNicknamePEP(AbstractPEP):
'''XEP-0172: User Nickname'''
type_ = 'nickname'
- namespace = xmpp.NS_NICK
+ namespace = nbxmpp.NS_NICK
def _extract_info(self, items):
nick = ''
@@ -468,7 +468,7 @@ class UserLocationPEP(AbstractPEP):
'''XEP-0080: User Location'''
type_ = 'location'
- namespace = xmpp.NS_LOCATION
+ namespace = nbxmpp.NS_LOCATION
def _extract_info(self, items):
location_dict = {}
@@ -562,7 +562,7 @@ class ConnectionPEP(object):
return
if not self.pep_supported:
return
- item = xmpp.Node('activity', {'xmlns': xmpp.NS_ACTIVITY})
+ item = nbxmpp.Node('activity', {'xmlns': nbxmpp.NS_ACTIVITY})
if activity:
i = item.addChild(activity)
if subactivity:
@@ -570,14 +570,15 @@ class ConnectionPEP(object):
if message:
i = item.addChild('text')
i.addData(message)
- self._pubsub_connection.send_pb_publish('', xmpp.NS_ACTIVITY, item, '0')
+ self._pubsub_connection.send_pb_publish('', nbxmpp.NS_ACTIVITY, item,
+ '0')
def retract_activity(self):
if not self.pep_supported:
return
self.send_activity(None)
# not all client support new XEP, so we still retract
- self._pubsub_connection.send_pb_retract('', xmpp.NS_ACTIVITY, '0')
+ self._pubsub_connection.send_pb_retract('', nbxmpp.NS_ACTIVITY, '0')
def send_mood(self, mood, message=None):
if self.connected == 1:
@@ -587,20 +588,20 @@ class ConnectionPEP(object):
return
if not self.pep_supported:
return
- item = xmpp.Node('mood', {'xmlns': xmpp.NS_MOOD})
+ item = nbxmpp.Node('mood', {'xmlns': nbxmpp.NS_MOOD})
if mood:
item.addChild(mood)
if message:
i = item.addChild('text')
i.addData(message)
- self._pubsub_connection.send_pb_publish('', xmpp.NS_MOOD, item, '0')
+ self._pubsub_connection.send_pb_publish('', nbxmpp.NS_MOOD, item, '0')
def retract_mood(self):
if not self.pep_supported:
return
self.send_mood(None)
# not all client support new XEP, so we still retract
- self._pubsub_connection.send_pb_retract('', xmpp.NS_MOOD, '0')
+ self._pubsub_connection.send_pb_retract('', nbxmpp.NS_MOOD, '0')
def send_tune(self, artist='', title='', source='', track=0, length=0,
items=None):
@@ -611,7 +612,7 @@ class ConnectionPEP(object):
return
if not self.pep_supported:
return
- item = xmpp.Node('tune', {'xmlns': xmpp.NS_TUNE})
+ item = nbxmpp.Node('tune', {'xmlns': nbxmpp.NS_TUNE})
if artist:
i = item.addChild('artist')
i.addData(artist)
@@ -629,14 +630,14 @@ class ConnectionPEP(object):
i.addData(length)
if items:
item.addChild(payload=items)
- self._pubsub_connection.send_pb_publish('', xmpp.NS_TUNE, item, '0')
+ self._pubsub_connection.send_pb_publish('', nbxmpp.NS_TUNE, item, '0')
def retract_tune(self):
if not self.pep_supported:
return
self.send_tune(None)
# not all client support new XEP, so we still retract
- self._pubsub_connection.send_pb_retract('', xmpp.NS_TUNE, '0')
+ self._pubsub_connection.send_pb_retract('', nbxmpp.NS_TUNE, '0')
def send_nickname(self, nick):
if self.connected == 1:
@@ -646,16 +647,16 @@ class ConnectionPEP(object):
return
if not self.pep_supported:
return
- item = xmpp.Node('nick', {'xmlns': xmpp.NS_NICK})
+ item = nbxmpp.Node('nick', {'xmlns': nbxmpp.NS_NICK})
item.addData(nick)
- self._pubsub_connection.send_pb_publish('', xmpp.NS_NICK, item, '0')
+ self._pubsub_connection.send_pb_publish('', nbxmpp.NS_NICK, item, '0')
def retract_nickname(self):
if not self.pep_supported:
return
self.send_nickname(None)
# not all client support new XEP, so we still retract
- self._pubsub_connection.send_pb_retract('', xmpp.NS_NICK, '0')
+ self._pubsub_connection.send_pb_retract('', nbxmpp.NS_NICK, '0')
def send_location(self, info):
if self.connected == 1:
@@ -665,16 +666,16 @@ class ConnectionPEP(object):
return
if not self.pep_supported:
return
- item = xmpp.Node('geoloc', {'xmlns': xmpp.NS_LOCATION})
+ item = nbxmpp.Node('geoloc', {'xmlns': nbxmpp.NS_LOCATION})
for field in LOCATION_DATA:
if info.get(field, None):
i = item.addChild(field)
i.addData(info[field])
- self._pubsub_connection.send_pb_publish('', xmpp.NS_LOCATION, item, '0')
+ self._pubsub_connection.send_pb_publish('', nbxmpp.NS_LOCATION, item, '0')
def retract_location(self):
if not self.pep_supported:
return
self.send_location({})
# not all client support new XEP, so we still retract
- self._pubsub_connection.send_pb_retract('', xmpp.NS_LOCATION, '0')
+ self._pubsub_connection.send_pb_retract('', nbxmpp.NS_LOCATION, '0')
diff --git a/src/common/protocol/bytestream.py b/src/common/protocol/bytestream.py
index c87e210ea..4f6df6f8a 100644
--- a/src/common/protocol/bytestream.py
+++ b/src/common/protocol/bytestream.py
@@ -33,7 +33,7 @@ import base64
import gobject
import time
-from common import xmpp
+import nbxmpp
from common import gajim
from common import helpers
from common import dataforms
@@ -109,25 +109,25 @@ class ConnectionBytestream:
return
file_props.sender = self._ft_get_our_jid()
fjid = self._ft_get_receiver_jid(file_props)
- iq = xmpp.Iq(to=fjid, typ='set')
+ iq = nbxmpp.Iq(to=fjid, typ='set')
iq.setID(file_props.sid)
- si = iq.setTag('si', namespace=xmpp.NS_SI)
- si.setAttr('profile', xmpp.NS_FILE)
+ si = iq.setTag('si', namespace=nbxmpp.NS_SI)
+ si.setAttr('profile', nbxmpp.NS_FILE)
si.setAttr('id', file_props.sid)
- file_tag = si.setTag('file', namespace=xmpp.NS_FILE)
+ file_tag = si.setTag('file', namespace=nbxmpp.NS_FILE)
file_tag.setAttr('name', file_props.name)
file_tag.setAttr('size', file_props.size)
desc = file_tag.setTag('desc')
if file_props.desc:
desc.setData(file_props.desc)
file_tag.setTag('range')
- feature = si.setTag('feature', namespace=xmpp.NS_FEATURE)
- _feature = xmpp.DataForm(typ='form')
+ feature = si.setTag('feature', namespace=nbxmpp.NS_FEATURE)
+ _feature = nbxmpp.DataForm(typ='form')
feature.addChild(node=_feature)
field = _feature.setField('stream-method')
field.setAttr('type', 'list-single')
- field.addOption(xmpp.NS_BYTESTREAM)
- field.addOption(xmpp.NS_IBB)
+ field.addOption(nbxmpp.NS_BYTESTREAM)
+ field.addOption(nbxmpp.NS_IBB)
self.connection.send(iq)
def send_file_approval(self, file_props):
@@ -163,22 +163,22 @@ class ConnectionBytestream:
session.approve_content('file', content.name)
return
- iq = xmpp.Iq(to=unicode(file_props.sender), typ='result')
+ iq = nbxmpp.Iq(to=unicode(file_props.sender), typ='result')
iq.setAttr('id', file_props.request_id)
- si = iq.setTag('si', namespace=xmpp.NS_SI)
+ si = iq.setTag('si', namespace=nbxmpp.NS_SI)
if file_props.offset:
- file_tag = si.setTag('file', namespace=xmpp.NS_FILE)
+ file_tag = si.setTag('file', namespace=nbxmpp.NS_FILE)
range_tag = file_tag.setTag('range')
range_tag.setAttr('offset', file_props.offset)
- feature = si.setTag('feature', namespace=xmpp.NS_FEATURE)
- _feature = xmpp.DataForm(typ='submit')
+ feature = si.setTag('feature', namespace=nbxmpp.NS_FEATURE)
+ _feature = nbxmpp.DataForm(typ='submit')
feature.addChild(node=_feature)
field = _feature.setField('stream-method')
field.delAttr('type')
- if xmpp.NS_BYTESTREAM in file_props.stream_methods:
- field.setValue(xmpp.NS_BYTESTREAM)
+ if nbxmpp.NS_BYTESTREAM in file_props.stream_methods:
+ field.setValue(nbxmpp.NS_BYTESTREAM)
else:
- field.setValue(xmpp.NS_IBB)
+ field.setValue(nbxmpp.NS_IBB)
self.connection.send(iq)
def send_file_rejection(self, file_props, code='403', typ=None):
@@ -195,7 +195,7 @@ class ConnectionBytestream:
jingle = self._sessions[file_props.sid]
jingle.cancel_session()
return
- iq = xmpp.Iq(to=unicode(file_props.sender), typ='error')
+ iq = nbxmpp.Iq(to=unicode(file_props.sender), typ='error')
iq.setAttr('id', file_props.request_id)
if code == '400' and typ in ('stream', 'profile'):
name = 'bad-request'
@@ -203,12 +203,12 @@ class ConnectionBytestream:
else:
name = 'forbidden'
text = 'Offer Declined'
- err = xmpp.ErrorNode(code=code, typ='cancel', name=name, text=text)
+ err = nbxmpp.ErrorNode(code=code, typ='cancel', name=name, text=text)
if code == '400' and typ in ('stream', 'profile'):
if typ == 'stream':
- err.setTag('no-valid-streams', namespace=xmpp.NS_SI)
+ err.setTag('no-valid-streams', namespace=nbxmpp.NS_SI)
else:
- err.setTag('bad-profile', namespace=xmpp.NS_SI)
+ err.setTag('bad-profile', namespace=nbxmpp.NS_SI)
iq.addChild(node=err)
self.connection.send(iq)
@@ -233,25 +233,25 @@ class ConnectionBytestream:
if length:
file_props.length = int(length)
feature = si.setTag('feature')
- if feature.getNamespace() != xmpp.NS_FEATURE:
+ if feature.getNamespace() != nbxmpp.NS_FEATURE:
return
form_tag = feature.getTag('x')
- form = xmpp.DataForm(node=form_tag)
+ form = nbxmpp.DataForm(node=form_tag)
field = form.getField('stream-method')
- if field.getValue() == xmpp.NS_BYTESTREAM:
+ if field.getValue() == nbxmpp.NS_BYTESTREAM:
self._send_socks5_info(file_props)
- raise xmpp.NodeProcessed
- if field.getValue() == xmpp.NS_IBB:
+ raise nbxmpp.NodeProcessed
+ if field.getValue() == nbxmpp.NS_IBB:
sid = file_props.sid
fp = open(file_props.file_name, 'r')
self.OpenStream(sid, file_props.receiver, fp)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _siSetCB(self, con, iq_obj):
from common.connection_handlers_events import FileRequestReceivedEvent
gajim.nec.push_incoming_event(FileRequestReceivedEvent(None, conn=self,
stanza=iq_obj))
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _nec_file_request_received(self, obj):
pass
@@ -259,7 +259,7 @@ class ConnectionBytestream:
def _siErrorCB(self, con, iq_obj):
si = iq_obj.getTag('si')
profile = si.getAttr('profile')
- if profile != xmpp.NS_FILE:
+ if profile != nbxmpp.NS_FILE:
return
file_props = FilesProp.getFileProp(con.name, iq_obj.getAttr('id'))
if not file_props:
@@ -269,7 +269,7 @@ class ConnectionBytestream:
from common.connection_handlers_events import FileRequestErrorEvent
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
jid=jid, file_props=file_props, error_msg=''))
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
class ConnectionSocks5Bytestream(ConnectionBytestream):
@@ -281,10 +281,10 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
return
if streamhost is None:
return None
- iq = xmpp.Iq(to=streamhost['initiator'], typ='result',
+ iq = nbxmpp.Iq(to=streamhost['initiator'], typ='result',
frm=streamhost['target'])
iq.setAttr('id', streamhost['id'])
- query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
+ query = iq.setTag('query', namespace=nbxmpp.NS_BYTESTREAM)
stream_tag = query.setTag('streamhost-used')
stream_tag.setAttr('jid', streamhost['jid'])
self.connection.send(iq)
@@ -358,10 +358,10 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
self._connect_error(unicode(receiver), file_props.sid,
file_props.sid, code=406)
else:
- iq = xmpp.Iq(to=unicode(receiver), typ='set')
+ iq = nbxmpp.Iq(to=unicode(receiver), typ='set')
file_props.request_id = 'id_' + file_props.sid
iq.setID(file_props.request_id)
- query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
+ query = iq.setTag('query', namespace=nbxmpp.NS_BYTESTREAM)
query.setAttr('sid', file_props.sid)
self._add_addiditional_streamhosts_to_query(query, file_props)
@@ -372,7 +372,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
def _add_streamhosts_to_query(self, query, sender, port, hosts):
for host in hosts:
- streamhost = xmpp.Node(tag='streamhost')
+ streamhost = nbxmpp.Node(tag='streamhost')
query.addChild(node=streamhost)
streamhost.setAttr('port', unicode(port))
streamhost.setAttr('host', host)
@@ -560,7 +560,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
to = file_props.receiver
else:
to = file_props.sender
- iq = xmpp.Iq(to=to, typ='error')
+ iq = nbxmpp.Iq(to=to, typ='error')
iq.setAttr('id', file_props.sid)
err = iq.setTag('error')
err.setAttr('code', unicode(code))
@@ -581,10 +581,10 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
if not self.connection or self.connected < 2:
return
file_props = FilesProp.getFileProp(self.name, proxy['sid'])
- iq = xmpp.Iq(to=proxy['initiator'], typ='set')
+ iq = nbxmpp.Iq(to=proxy['initiator'], typ='set')
auth_id = "au_" + proxy['sid']
iq.setID(auth_id)
- query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
+ query = iq.setTag('query', namespace=nbxmpp.NS_BYTESTREAM)
query.setAttr('sid', proxy['sid'])
activate = query.setTag('activate')
activate.setData(file_props.proxy_receiver)
@@ -606,7 +606,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
from common.connection_handlers_events import FileRequestErrorEvent
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
jid=jid, file_props=file_props, error_msg=''))
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _bytestreamSetCB(self, con, iq_obj):
target = unicode(iq_obj.getAttr('to'))
@@ -643,16 +643,16 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
file_props.streamhosts = streamhosts
gajim.socks5queue.connect_to_hosts(self.name, sid,
self.send_success_connect_reply, None)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
log.warn('Gajim got streamhosts for unknown transfer. Ignoring it.')
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
file_props.streamhosts = streamhosts
if file_props.type_ == 'r':
gajim.socks5queue.connect_to_hosts(self.name, sid,
self.send_success_connect_reply, self._connect_error)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _ResultCB(self, con, iq_obj):
# if we want to respect xep-0065 we have to check for proxy
@@ -667,7 +667,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
for host in file_props.proxyhosts:
if host['initiator'] == frm and 'idx' in host:
gajim.socks5queue.activate_proxy(host['idx'])
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _bytestreamResultCB(self, con, iq_obj):
frm = self._ft_get_from(iq_obj)
@@ -682,30 +682,30 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
id_ = real_id[3:]
file_props = FilesProp.getFileProp(self.name, id_)
if file_props is None:
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
if streamhost is None:
# proxy approves the activate query
if real_id.startswith('au_'):
if file_props.streamhost_used is False:
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
if not file_props.proxyhosts:
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
for host in file_props.proxyhosts:
if host['initiator'] == frm and \
unicode(query.getAttr('sid')) == file_props.sid:
gajim.socks5queue.activate_proxy(host['idx'])
break
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
jid = self._ft_get_streamhost_jid_attr(streamhost)
if file_props.streamhost_used is True:
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
if real_id.startswith('au_'):
if file_props.stopped:
self.remove_transfer(file_props)
else:
gajim.socks5queue.send_file(file_props, self.name)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
proxy = None
if file_props.proxyhosts:
@@ -715,7 +715,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
if file_props.stopped:
self.remove_transfer(file_props)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
if proxy is not None:
file_props.streamhost_used = True
file_props.streamhosts.append(proxy)
@@ -729,7 +729,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
gajim.socks5queue.add_sockobj(self.name, sender, 'sender')
proxy['idx'] = sender.queue_idx
gajim.socks5queue.on_success[file_props.sid] = self._proxy_auth_ok
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
else:
if file_props.stopped:
@@ -737,7 +737,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
else:
gajim.socks5queue.send_file(file_props, self.name, 'server')
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
class ConnectionIBBytestream(ConnectionBytestream):
@@ -753,17 +753,17 @@ class ConnectionIBBytestream(ConnectionBytestream):
"""
typ = stanza.getType()
log.debug('IBBIqHandler called typ->%s' % typ)
- if typ == 'set' and stanza.getTag('open', namespace=xmpp.NS_IBB):
+ if typ == 'set' and stanza.getTag('open', namespace=nbxmpp.NS_IBB):
self.StreamOpenHandler(conn, stanza)
- elif typ == 'set' and stanza.getTag('close', namespace=xmpp.NS_IBB):
+ elif typ == 'set' and stanza.getTag('close', namespace=nbxmpp.NS_IBB):
self.StreamCloseHandler(conn, stanza)
elif typ == 'result':
self.SendHandler()
elif typ == 'error':
gajim.socks5queue.error_cb()
else:
- conn.send(xmpp.Error(stanza, xmpp.ERR_BAD_REQUEST))
- raise xmpp.NodeProcessed
+ conn.send(nbxmpp.Error(stanza, nbxmpp.ERR_BAD_REQUEST))
+ raise nbxmpp.NodeProcessed
def StreamOpenHandler(self, conn, stanza):
"""
@@ -778,16 +778,16 @@ class ConnectionIBBytestream(ConnectionBytestream):
try:
blocksize = int(blocksize)
except:
- err = xmpp.ERR_BAD_REQUEST
+ err = nbxmpp.ERR_BAD_REQUEST
if not sid or not blocksize:
- err = xmpp.ERR_BAD_REQUEST
+ err = nbxmpp.ERR_BAD_REQUEST
elif not file_props:
- err = xmpp.ERR_UNEXPECTED_REQUEST
+ err = nbxmpp.ERR_UNEXPECTED_REQUEST
if err:
- rep = xmpp.Error(stanza, err)
+ rep = nbxmpp.Error(stanza, err)
else:
log.debug("Opening stream: id %s, block-size %s" % (sid, blocksize))
- rep = xmpp.Protocol('iq', stanza.getFrom(), 'result',
+ rep = nbxmpp.Protocol('iq', stanza.getFrom(), 'result',
stanza.getTo(), {'id': stanza.getID()})
file_props.block_size = blocksize
file_props.seq = 0
@@ -811,7 +811,7 @@ class ConnectionIBBytestream(ConnectionBytestream):
Take into account that recommended stanza size is 4k and IBB uses
base64 encoding that increases size of data by 1/3.
"""
- if not xmpp.JID(to).getResource():
+ if not nbxmpp.JID(to).getResource():
return
file_props = FilesProp.getFilePropBySid(sid)
file_props.direction = '|>' + to
@@ -826,8 +826,9 @@ class ConnectionIBBytestream(ConnectionBytestream):
file_props.completed = False
file_props.disconnect_cb = None
file_props.continue_cb = None
- syn = xmpp.Protocol('iq', to, 'set', payload=[xmpp.Node(xmpp.NS_IBB + \
- ' open', {'sid': sid, 'block-size': blocksize, 'stanza': 'iq'})])
+ syn = nbxmpp.Protocol('iq', to, 'set', payload=[nbxmpp.Node(
+ nbxmpp.NS_IBB + ' open', {'sid': sid, 'block-size': blocksize,
+ 'stanza': 'iq'})])
self.connection.send(syn)
file_props.syn_id = syn.getID()
return file_props
@@ -850,15 +851,15 @@ class ConnectionIBBytestream(ConnectionBytestream):
continue
chunk = file_props.fp.read(file_props.block_size)
if chunk:
- datanode = xmpp.Node(xmpp.NS_IBB + ' data', {'sid': sid,
+ datanode = nbxmpp.Node(nbxmpp.NS_IBB + ' data', {'sid': sid,
'seq': file_props.seq}, base64.encodestring(chunk))
file_props.seq += 1
file_props.started = True
if file_props.seq == 65536:
file_props.seq = 0
- self.last_sent_ibb_id = self.connection.send(xmpp.Protocol(
- name='iq', to=file_props.direction[1:], typ='set',
- payload=[datanode]))
+ self.last_sent_ibb_id = self.connection.send(
+ nbxmpp.Protocol(name='iq', to=file_props.direction[1:],
+ typ='set', payload=[datanode]))
current_time = time.time()
file_props.elapsed_time += current_time - file_props.last_time
file_props.last_time = current_time
@@ -869,9 +870,9 @@ class ConnectionIBBytestream(ConnectionBytestream):
# notify the other side about stream closing
# notify the local user about sucessfull send
# delete the local stream
- self.connection.send(xmpp.Protocol('iq',
+ self.connection.send(nbxmpp.Protocol('iq',
file_props.direction[1:], 'set',
- payload=[xmpp.Node(xmpp.NS_IBB + ' close',
+ payload=[nbxmpp.Node(nbxmpp.NS_IBB + ' close',
{'sid':sid})]))
file_props.completed = True
@@ -893,12 +894,12 @@ class ConnectionIBBytestream(ConnectionBytestream):
err = None
file_props = FilesProp.getFileProp(self.name, sid)
if file_props is None:
- err = xmpp.ERR_ITEM_NOT_FOUND
+ err = nbxmpp.ERR_ITEM_NOT_FOUND
else:
if not data:
- err = xmpp.ERR_BAD_REQUEST
+ err = nbxmpp.ERR_BAD_REQUEST
elif seq <> file_props.seq:
- err = xmpp.ERR_UNEXPECTED_REQUEST
+ err = nbxmpp.ERR_UNEXPECTED_REQUEST
else:
log.debug('Successfull receive sid->%s %s+%s bytes' % (sid,
file_props.fp.tell(), len(data)))
@@ -914,9 +915,9 @@ class ConnectionIBBytestream(ConnectionBytestream):
file_props.completed = True
if err:
log.debug('Error on receive: %s' % err)
- conn.send(xmpp.Error(xmpp.Iq(to=stanza.getFrom(),
+ conn.send(nbxmpp.Error(nbxmpp.Iq(to=stanza.getFrom(),
frm=stanza.getTo(),
- payload=[xmpp.Node(xmpp.NS_IBB + ' close')]), err, reply=0))
+ payload=[nbxmpp.Node(nbxmpp.NS_IBB + ' close')]), err, reply=0))
else:
return True
@@ -940,7 +941,7 @@ class ConnectionIBBytestream(ConnectionBytestream):
file_props.fp.close()
gajim.socks5queue.complete_transfer_cb(self.name, file_props)
else:
- conn.send(xmpp.Error(stanza, xmpp.ERR_ITEM_NOT_FOUND))
+ conn.send(nbxmpp.Error(stanza, nbxmpp.ERR_ITEM_NOT_FOUND))
def IBBAllIqHandler(self, conn, stanza):
"""
@@ -966,8 +967,8 @@ class ConnectionIBBytestream(ConnectionBytestream):
file_props.direction = file_props.direction[1:]
self.SendHandler()
else:
- conn.send(xmpp.Error(stanza,
- xmpp.ERR_UNEXPECTED_REQUEST))
+ conn.send(nbxmpp.Error(stanza,
+ nbxmpp.ERR_UNEXPECTED_REQUEST))
break
else:
if stanza.getTag('data'):
@@ -975,7 +976,7 @@ class ConnectionIBBytestream(ConnectionBytestream):
reply = stanza.buildReply('result')
reply.delChild('data')
conn.send(reply)
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
elif syn_id == self.last_sent_ibb_id:
self.SendHandler()
diff --git a/src/common/proxy65_manager.py b/src/common/proxy65_manager.py
index 0af5e49ff..8a906a01b 100644
--- a/src/common/proxy65_manager.py
+++ b/src/common/proxy65_manager.py
@@ -26,11 +26,11 @@ import errno
import logging
log = logging.getLogger('gajim.c.proxy65_manager')
-import common.xmpp
+import nbxmpp
from common import gajim
from common import helpers
from socks5 import Socks5
-from common.xmpp.idlequeue import IdleObject
+from nbxmpp.idlequeue import IdleObject
from common.file_props import FilesProp
S_INITIAL = 0
@@ -90,7 +90,7 @@ class Proxy65Manager:
self.proxies[proxy]._on_connect_failure()
self.proxies[proxy].resolve_result(host, port, jid)
# we can have only one streamhost
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def error_cb(self, proxy, query):
sid = query.getAttr('sid')
@@ -138,9 +138,9 @@ class ProxyResolver:
def _on_connect_success(self):
log.debug('Host successfully connected %s:%s' % (self.host, self.port))
- iq = common.xmpp.Protocol(name='iq', to=self.jid, typ='set')
+ iq = nbxmpp.Protocol(name='iq', to=self.jid, typ='set')
query = iq.setTag('query')
- query.setNamespace(common.xmpp.NS_BYTESTREAM)
+ query.setNamespace(nbxmpp.NS_BYTESTREAM)
query.setAttr('sid', self.sid)
activate = query.setTag('activate')
@@ -212,9 +212,9 @@ class ProxyResolver:
"""
self.state = S_STARTED
self.active_connection = connection
- iq = common.xmpp.Protocol(name='iq', to=self.proxy, typ='get')
+ iq = nbxmpp.Protocol(name='iq', to=self.proxy, typ='get')
query = iq.setTag('query')
- query.setNamespace(common.xmpp.NS_BYTESTREAM)
+ query.setNamespace(nbxmpp.NS_BYTESTREAM)
connection.send(iq)
def __init__(self, proxy, sender_jid, testit):
diff --git a/src/common/pubsub.py b/src/common/pubsub.py
index 93aa9427e..d2bde78ed 100644
--- a/src/common/pubsub.py
+++ b/src/common/pubsub.py
@@ -21,7 +21,7 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
-import xmpp
+import nbxmpp
import gajim
import connection_handlers
import ged
@@ -44,8 +44,8 @@ class ConnectionPubSub:
def send_pb_subscription_query(self, jid, cb, *args, **kwargs):
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('get', to=jid)
- pb = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+ query = nbxmpp.Iq('get', to=jid)
+ pb = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
pb.addChild('subscriptions')
id_ = self.connection.send(query)
@@ -56,8 +56,8 @@ class ConnectionPubSub:
if not self.connection or self.connected < 2:
return
our_jid = gajim.get_jid_from_account(self.name)
- query = xmpp.Iq('set', to=jid)
- pb = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+ query = nbxmpp.Iq('set', to=jid)
+ pb = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
pb.addChild('subscribe', {'node': node, 'jid': our_jid})
id_ = self.connection.send(query)
@@ -68,8 +68,8 @@ class ConnectionPubSub:
if not self.connection or self.connected < 2:
return
our_jid = gajim.get_jid_from_account(self.name)
- query = xmpp.Iq('set', to=jid)
- pb = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+ query = nbxmpp.Iq('set', to=jid)
+ pb = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
pb.addChild('unsubscribe', {'node': node, 'jid': our_jid})
id_ = self.connection.send(query)
@@ -82,8 +82,8 @@ class ConnectionPubSub:
"""
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('set', to=jid)
- e = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+ query = nbxmpp.Iq('set', to=jid)
+ e = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
p = e.addChild('publish', {'node': node})
attrs = {}
if id_:
@@ -101,8 +101,8 @@ class ConnectionPubSub:
"""
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('get', to=jid)
- r = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+ query = nbxmpp.Iq('get', to=jid)
+ r = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
r = r.addChild('items', {'node': node})
id_ = self.connection.send(query)
@@ -115,8 +115,8 @@ class ConnectionPubSub:
"""
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('set', to=jid)
- r = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+ query = nbxmpp.Iq('set', to=jid)
+ r = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
r = r.addChild('retract', {'node': node, 'notify': '1'})
r = r.addChild('item', {'id': id_})
@@ -128,8 +128,8 @@ class ConnectionPubSub:
"""
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('set', to=jid)
- d = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER)
+ query = nbxmpp.Iq('set', to=jid)
+ d = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
d = d.addChild('purge', {'node': node})
self.connection.send(query)
@@ -140,8 +140,8 @@ class ConnectionPubSub:
"""
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('set', to=jid)
- d = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER)
+ query = nbxmpp.Iq('set', to=jid)
+ d = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
d = d.addChild('delete', {'node': node})
def response(con, resp, jid, node):
@@ -160,8 +160,8 @@ class ConnectionPubSub:
"""
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('set', to=jid)
- c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
+ query = nbxmpp.Iq('set', to=jid)
+ c = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
c = c.addChild('create', {'node': node})
if configure:
conf = c.addChild('configure')
@@ -173,8 +173,8 @@ class ConnectionPubSub:
def send_pb_configure(self, jid, node, form):
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('set', to=jid)
- c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER)
+ query = nbxmpp.Iq('set', to=jid)
+ c = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
c = c.addChild('configure', {'node': node})
c.addChild(node=form)
@@ -213,8 +213,8 @@ class ConnectionPubSub:
def request_pb_configuration(self, jid, node):
if not self.connection or self.connected < 2:
return
- query = xmpp.Iq('get', to=jid)
- e = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER)
+ query = nbxmpp.Iq('get', to=jid)
+ e = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER)
e = e.addChild('configure', {'node': node})
id_ = self.connection.getAnID()
query.setID(id_)
diff --git a/src/common/resolver.py b/src/common/resolver.py
index 5f1ce22f3..10ed614e8 100644
--- a/src/common/resolver.py
+++ b/src/common/resolver.py
@@ -31,7 +31,7 @@ if __name__ == '__main__':
common.configpaths.gajimpaths.init_profile()
from common import helpers
-from common.xmpp.idlequeue import IdleCommand
+from nbxmpp.idlequeue import IdleCommand
# it is good to check validity of arguments, when calling system commands
ns_type_pattern = re.compile('^[a-z]+$')
@@ -320,7 +320,7 @@ class NsLookup(IdleCommand):
if __name__ == '__main__':
import gobject
import gtk
- from xmpp import idlequeue
+ from nbxmpp import idlequeue
idlequeue = idlequeue.get_idlequeue()
resolver = get_resolver(idlequeue)
diff --git a/src/common/socks5.py b/src/common/socks5.py
index 1d35b4893..a8ce7ecd5 100644
--- a/src/common/socks5.py
+++ b/src/common/socks5.py
@@ -32,7 +32,7 @@ from errno import EINTR
from errno import EISCONN
from errno import EINPROGRESS
from errno import EAFNOSUPPORT
-from xmpp.idlequeue import IdleObject
+from nbxmpp.idlequeue import IdleObject
from file_props import FilesProp
from common import gajim
import jingle_xtls
diff --git a/src/common/stanza_session.py b/src/common/stanza_session.py
index 9e3ae6acb..d00bdf0b9 100644
--- a/src/common/stanza_session.py
+++ b/src/common/stanza_session.py
@@ -23,9 +23,9 @@
##
from common import gajim
-from common import xmpp
+import nbxmpp
from common.exceptions import DecryptionError, NegotiationError
-import xmpp.c14n
+import nbxmpp.c14n
import itertools
import random
@@ -123,17 +123,18 @@ class StanzaSession(object):
msg.setAttr('to', self.get_to())
self.conn.send_stanza(msg)
- if isinstance(msg, xmpp.Message):
+ if isinstance(msg, nbxmpp.Message):
self.last_send = time.time()
def reject_negotiation(self, body=None):
- msg = xmpp.Message()
+ msg = nbxmpp.Message()
feature = msg.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- x = xmpp.DataForm(typ='submit')
- x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn'))
- x.addChild(node=xmpp.DataField(name='accept', value='0'))
+ x = nbxmpp.DataForm(typ='submit')
+ x.addChild(node=nbxmpp.DataField(name='FORM_TYPE',
+ value='urn:xmpp:ssn'))
+ x.addChild(node=nbxmpp.DataField(name='accept', value='0'))
feature.addChild(node=x)
@@ -160,13 +161,14 @@ class StanzaSession(object):
# have XEP-0201 support
if send_termination and self.last_send > 0 and \
(self.received_thread_id or self.last_receive == 0):
- msg = xmpp.Message()
+ msg = nbxmpp.Message()
feature = msg.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- x = xmpp.DataForm(typ='submit')
- x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn'))
- x.addChild(node=xmpp.DataField(name='terminate', value='1'))
+ x = nbxmpp.DataForm(typ='submit')
+ x.addChild(node=nbxmpp.DataField(name='FORM_TYPE',
+ value='urn:xmpp:ssn'))
+ x.addChild(node=nbxmpp.DataField(name='terminate', value='1'))
feature.addChild(node=x)
@@ -190,24 +192,24 @@ class ArchivingStanzaSession(StanzaSession):
def negotiate_archiving(self):
self.negotiated = {}
- request = xmpp.Message()
+ request = nbxmpp.Message()
feature = request.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- x = xmpp.DataForm(typ='form')
+ x = nbxmpp.DataForm(typ='form')
- x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn',
- typ='hidden'))
- x.addChild(node=xmpp.DataField(name='accept', value='1', typ='boolean',
- required=True))
+ x.addChild(node=nbxmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn',
+ typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='accept', value='1',
+ typ='boolean', required=True))
- x.addChild(node=xmpp.DataField(name='logging', typ='list-single',
- options=self.archiving_logging_preference(), required=True))
+ x.addChild(node=nbxmpp.DataField(name='logging', typ='list-single',
+ options=self.archiving_logging_preference(), required=True))
- x.addChild(node=xmpp.DataField(name='disclosure', typ='list-single',
- options=['never'], required=True))
- x.addChild(node=xmpp.DataField(name='security', typ='list-single',
- options=['none'], required=True))
+ x.addChild(node=nbxmpp.DataField(name='disclosure', typ='list-single',
+ options=['never'], required=True))
+ x.addChild(node=nbxmpp.DataField(name='security', typ='list-single',
+ options=['none'], required=True))
feature.addChild(node=x)
@@ -223,27 +225,28 @@ class ArchivingStanzaSession(StanzaSession):
logging = self.archiving_logging_preference(options)
self.negotiated['logging'] = logging
- response = xmpp.Message()
+ response = nbxmpp.Message()
feature = response.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- x = xmpp.DataForm(typ='submit')
+ x = nbxmpp.DataForm(typ='submit')
- x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn'))
- x.addChild(node=xmpp.DataField(name='accept', value='true'))
+ x.addChild(node=nbxmpp.DataField(name='FORM_TYPE',
+ value='urn:xmpp:ssn'))
+ x.addChild(node=nbxmpp.DataField(name='accept', value='true'))
- x.addChild(node=xmpp.DataField(name='logging', value=logging))
+ x.addChild(node=nbxmpp.DataField(name='logging', value=logging))
self.status = 'responded-archiving'
feature.addChild(node=x)
if not logging:
- response = xmpp.Error(response, xmpp.ERR_NOT_ACCEPTABLE)
+ response = nbxmpp.Error(response, nbxmpp.ERR_NOT_ACCEPTABLE)
- feature = xmpp.Node(xmpp.NS_FEATURE + ' feature')
+ feature = nbxmpp.Node(nbxmpp.NS_FEATURE + ' feature')
- n = xmpp.Node('field')
+ n = nbxmpp.Node('field')
n['var'] = 'logging'
feature.addChild(node=n)
@@ -270,15 +273,15 @@ class ArchivingStanzaSession(StanzaSession):
self.negotiated['logging'] = form['logging']
- accept = xmpp.Message()
+ accept = nbxmpp.Message()
feature = accept.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- result = xmpp.DataForm(typ='result')
+ result = nbxmpp.DataForm(typ='result')
- result.addChild(node=xmpp.DataField(name='FORM_TYPE',
+ result.addChild(node=nbxmpp.DataField(name='FORM_TYPE',
value='urn:xmpp:ssn'))
- result.addChild(node=xmpp.DataField(name='accept', value='1'))
+ result.addChild(node=nbxmpp.DataField(name='accept', value='1'))
feature.addChild(node=result)
@@ -346,7 +349,7 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
def _is_buggy_gajim(self):
c = self._get_contact()
- if c and c.supports(xmpp.NS_ROSTERX):
+ if c and c.supports(nbxmpp.NS_ROSTERX):
return False
return True
@@ -429,7 +432,7 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
return stanza
def is_xep_200_encrypted(self, msg):
- msg.getTag('c', namespace=xmpp.NS_STANZA_CRYPTO)
+ msg.getTag('c', namespace=nbxmpp.NS_STANZA_CRYPTO)
def hmac(self, key, content):
return HMAC(key, content, self.hash_alg).digest()
@@ -485,7 +488,7 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
plaintext = self.decompress(m_compressed)
try:
- parsed = xmpp.Node(node='<node>' + plaintext + '</node>')
+ parsed = nbxmpp.Node(node='<node>' + plaintext + '</node>')
except Exception:
raise DecryptionError('decrypted <data/> not parseable as XML')
@@ -519,7 +522,7 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
def c7lize_mac_id(self, form):
kids = form.getChildren()
macable = [x for x in kids if x.getVar() not in ('mac', 'identity')]
- return ''.join(xmpp.c14n.c14n(el, self._is_buggy_gajim()) for el in \
+ return ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for el in \
macable)
def verify_identity(self, form, dh_i, sigmai, i_o):
@@ -539,7 +542,7 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
if self.negotiated['recv_pubkey']:
plaintext = self.decrypt(id_o)
- parsed = xmpp.Node(node='<node>' + plaintext + '</node>')
+ parsed = nbxmpp.Node(node='<node>' + plaintext + '</node>')
if self.negotiated['recv_pubkey'] == 'hash':
# fingerprint = parsed.getTagData('fingerprint')
@@ -553,7 +556,7 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
keyvalue.getTagData(x))) for x in ('Modulus', 'Exponent'))
eir_pubkey = RSA.construct((n, long(e)))
- pubkey_o = xmpp.c14n.c14n(keyvalue, self._is_buggy_gajim())
+ pubkey_o = nbxmpp.c14n.c14n(keyvalue, self._is_buggy_gajim())
else:
# FIXME DSA, etc.
raise NotImplementedError()
@@ -595,20 +598,20 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
fields = (pubkey.n, pubkey.e)
cb_fields = [base64.b64encode(crypto.encode_mpi(f)) for f in
- fields]
+ fields]
pubkey_s = '<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#"'
'><Modulus>%s</Modulus><Exponent>%s</Exponent></RSAKeyValue>' % \
- tuple(cb_fields)
+ tuple(cb_fields)
else:
pubkey_s = ''
- form_s2 = ''.join(xmpp.c14n.c14n(el, self._is_buggy_gajim()) for el in \
- form.getChildren())
+ form_s2 = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for el \
+ in form.getChildren())
old_c_s = self.c_s
content = self.n_o + self.n_s + crypto.encode_mpi(dh_i) + pubkey_s + \
- self.form_s + form_s2
+ self.form_s + form_s2
mac_s = self.hmac(self.ks_s, content)
@@ -637,76 +640,76 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
# FIXME save retained secret?
self.check_identity(tuple)
- return (xmpp.DataField(name='identity', value=base64.b64encode(id_s)),
- xmpp.DataField(name='mac', value=base64.b64encode(m_s)))
+ return (nbxmpp.DataField(name='identity', value=base64.b64encode(id_s)),
+ nbxmpp.DataField(name='mac', value=base64.b64encode(m_s)))
def negotiate_e2e(self, sigmai):
self.negotiated = {}
- request = xmpp.Message()
+ request = nbxmpp.Message()
feature = request.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- x = xmpp.DataForm(typ='form')
+ x = nbxmpp.DataForm(typ='form')
- x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn',
- typ='hidden'))
- x.addChild(node=xmpp.DataField(name='accept', value='1', typ='boolean',
- required=True))
+ x.addChild(node=nbxmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn',
+ typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='accept', value='1',
+ typ='boolean', required=True))
# this field is incorrectly called 'otr' in XEPs 0116 and 0217
- x.addChild(node=xmpp.DataField(name='logging', typ='list-single',
- options=self.logging_preference(), required=True))
+ x.addChild(node=nbxmpp.DataField(name='logging', typ='list-single',
+ options=self.logging_preference(), required=True))
# unsupported options: 'disabled', 'enabled'
- x.addChild(node=xmpp.DataField(name='disclosure', typ='list-single',
- options=['never'], required=True))
- x.addChild(node=xmpp.DataField(name='security', typ='list-single',
- options=['e2e'], required=True))
- x.addChild(node=xmpp.DataField(name='crypt_algs', value='aes128-ctr',
- typ='hidden'))
- x.addChild(node=xmpp.DataField(name='hash_algs', value='sha256',
- typ='hidden'))
- x.addChild(node=xmpp.DataField(name='compress', value='none',
- typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='disclosure', typ='list-single',
+ options=['never'], required=True))
+ x.addChild(node=nbxmpp.DataField(name='security', typ='list-single',
+ options=['e2e'], required=True))
+ x.addChild(node=nbxmpp.DataField(name='crypt_algs', value='aes128-ctr',
+ typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='hash_algs', value='sha256',
+ typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='compress', value='none',
+ typ='hidden'))
# unsupported options: 'iq', 'presence'
- x.addChild(node=xmpp.DataField(name='stanzas', typ='list-multi',
- options=['message']))
+ x.addChild(node=nbxmpp.DataField(name='stanzas', typ='list-multi',
+ options=['message']))
- x.addChild(node=xmpp.DataField(name='init_pubkey', options=['none', 'key',
- 'hash'], typ='list-single'))
+ x.addChild(node=nbxmpp.DataField(name='init_pubkey', options=['none',
+ 'key', 'hash'], typ='list-single'))
# FIXME store key, use hash
- x.addChild(node=xmpp.DataField(name='resp_pubkey', options=['none',
- 'key'], typ='list-single'))
+ x.addChild(node=nbxmpp.DataField(name='resp_pubkey', options=['none',
+ 'key'], typ='list-single'))
- x.addChild(node=xmpp.DataField(name='ver', value='1.0', typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='ver', value='1.0', typ='hidden'))
- x.addChild(node=xmpp.DataField(name='rekey_freq', value='4294967295',
- typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='rekey_freq', value='4294967295',
+ typ='hidden'))
- x.addChild(node=xmpp.DataField(name='sas_algs', value='sas28x5',
- typ='hidden'))
- x.addChild(node=xmpp.DataField(name='sign_algs',
- value='http://www.w3.org/2000/09/xmldsig#rsa-sha256', typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='sas_algs', value='sas28x5',
+ typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='sign_algs',
+ value='http://www.w3.org/2000/09/xmldsig#rsa-sha256', typ='hidden'))
self.n_s = crypto.generate_nonce()
- x.addChild(node=xmpp.DataField(name='my_nonce',
- value=base64.b64encode(self.n_s), typ='hidden'))
+ x.addChild(node=nbxmpp.DataField(name='my_nonce',
+ value=base64.b64encode(self.n_s), typ='hidden'))
modp_options = [ int(g) for g in gajim.config.get('esession_modp').split(
- ',') ]
+ ',') ]
- x.addChild(node=xmpp.DataField(name='modp', typ='list-single',
- options=[[None, y] for y in modp_options]))
+ x.addChild(node=nbxmpp.DataField(name='modp', typ='list-single',
+ options=[[None, y] for y in modp_options]))
x.addChild(node=self.make_dhfield(modp_options, sigmai))
self.sigmai = sigmai
- self.form_s = ''.join(xmpp.c14n.c14n(el, self._is_buggy_gajim()) for el \
- in x.getChildren())
+ self.form_s = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for \
+ el in x.getChildren())
feature.addChild(node=x)
@@ -789,19 +792,21 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
"""
4.3 esession response (bob)
"""
- response = xmpp.Message()
+ response = nbxmpp.Message()
feature = response.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- x = xmpp.DataForm(typ='submit')
+ x = nbxmpp.DataForm(typ='submit')
- x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn'))
- x.addChild(node=xmpp.DataField(name='accept', value='true'))
+ x.addChild(node=nbxmpp.DataField(name='FORM_TYPE',
+ value='urn:xmpp:ssn'))
+ x.addChild(node=nbxmpp.DataField(name='accept', value='true'))
for name in negotiated:
# some fields are internal and should not be sent
if not name in ('send_pubkey', 'recv_pubkey'):
- x.addChild(node=xmpp.DataField(name=name, value=negotiated[name]))
+ x.addChild(node=nbxmpp.DataField(name=name,
+ value=negotiated[name]))
self.negotiated = negotiated
@@ -837,24 +842,24 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
for name in to_add:
b64ed = base64.b64encode(to_add[name])
- x.addChild(node=xmpp.DataField(name=name, value=b64ed))
+ x.addChild(node=nbxmpp.DataField(name=name, value=b64ed))
- self.form_o = ''.join(xmpp.c14n.c14n(el, self._is_buggy_gajim()) for el \
- in form.getChildren())
- self.form_s = ''.join(xmpp.c14n.c14n(el, self._is_buggy_gajim()) for el \
- in x.getChildren())
+ self.form_o = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for \
+ el in form.getChildren())
+ self.form_s = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for \
+ el in x.getChildren())
self.status = 'responded-e2e'
feature.addChild(node=x)
if not_acceptable:
- response = xmpp.Error(response, xmpp.ERR_NOT_ACCEPTABLE)
+ response = nbxmpp.Error(response, nbxmpp.ERR_NOT_ACCEPTABLE)
- feature = xmpp.Node(xmpp.NS_FEATURE + ' feature')
+ feature = nbxmpp.Node(nbxmpp.NS_FEATURE + ' feature')
for f in not_acceptable:
- n = xmpp.Node('field')
+ n = nbxmpp.Node('field')
n['var'] = f
feature.addChild(node=n)
@@ -904,11 +909,11 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
self.negotiated = negotiated
- accept = xmpp.Message()
+ accept = nbxmpp.Message()
feature = accept.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- result = xmpp.DataForm(typ='result')
+ result = nbxmpp.DataForm(typ='result')
self.c_s = crypto.decode_mpi(base64.b64decode(form['counter']))
self.c_o = self.c_s ^ (2 ** (self.n - 1))
@@ -922,10 +927,10 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
self.d = crypto.decode_mpi(base64.b64decode(form['dhkeys']))
self.k = self.get_shared_secret(self.d, x, p)
- result.addChild(node=xmpp.DataField(name='FORM_TYPE',
+ result.addChild(node=nbxmpp.DataField(name='FORM_TYPE',
value='urn:xmpp:ssn'))
- result.addChild(node=xmpp.DataField(name='accept', value='1'))
- result.addChild(node=xmpp.DataField(name='nonce',
+ result.addChild(node=nbxmpp.DataField(name='accept', value='1'))
+ result.addChild(node=nbxmpp.DataField(name='nonce',
value=base64.b64encode(self.n_o)))
self.kc_s, self.km_s, self.ks_s = self.generate_initiator_keys(self.k)
@@ -944,12 +949,13 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
rshashes.append(crypto.random_bytes(rshash_size))
rshashes = [base64.b64encode(rshash) for rshash in rshashes]
- result.addChild(node=xmpp.DataField(name='rshashes', value=rshashes))
- result.addChild(node=xmpp.DataField(name='dhkeys',
- value=base64.b64encode(crypto.encode_mpi(e))))
+ result.addChild(node=nbxmpp.DataField(name='rshashes',
+ value=rshashes))
+ result.addChild(node=nbxmpp.DataField(name='dhkeys',
+ value=base64.b64encode(crypto.encode_mpi(e))))
- self.form_o = ''.join(xmpp.c14n.c14n(el, self._is_buggy_gajim()) for \
- el in form.getChildren())
+ self.form_o = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) \
+ for el in form.getChildren())
# MUST securely destroy K unless it will be used later to generate the
# final shared secret
@@ -970,12 +976,12 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
"""
4.5 esession accept (bob)
"""
- response = xmpp.Message()
+ response = nbxmpp.Message()
init = response.NT.init
- init.setNamespace(xmpp.NS_ESESSION_INIT)
+ init.setNamespace(nbxmpp.NS_ESESSION_INIT)
- x = xmpp.DataForm(typ='result')
+ x = nbxmpp.DataForm(typ='result')
for field in ('nonce', 'dhkeys', 'rshashes', 'identity', 'mac'):
# FIXME: will do nothing in real world...
@@ -1024,11 +1030,12 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
else:
srshash = crypto.random_bytes(32)
- x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn'))
- x.addChild(node=xmpp.DataField(name='nonce', value=base64.b64encode(
- self.n_o)))
- x.addChild(node=xmpp.DataField(name='srshash', value=base64.b64encode(
- srshash)))
+ x.addChild(node=nbxmpp.DataField(name='FORM_TYPE',
+ value='urn:xmpp:ssn'))
+ x.addChild(node=nbxmpp.DataField(name='nonce', value=base64.b64encode(
+ self.n_o)))
+ x.addChild(node=nbxmpp.DataField(name='srshash', value=base64.b64encode(
+ srshash)))
for datafield in self.make_identity(x, self.d):
x.addChild(node=datafield)
@@ -1151,7 +1158,7 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
dhs.append(base64.b64encode(He))
name = 'dhhashes'
- return xmpp.DataField(name=name, typ='hidden', value=dhs)
+ return nbxmpp.DataField(name=name, typ='hidden', value=dhs)
def terminate_e2e(self):
self.enable_encryption = False
@@ -1170,14 +1177,14 @@ class EncryptedStanzaSession(ArchivingStanzaSession):
If fields is None, the remote party has given us a bad cryptographic
value of some kind. Otherwise, list the fields we haven't implemented.
"""
- err = xmpp.Error(xmpp.Message(), xmpp.ERR_FEATURE_NOT_IMPLEMENTED)
+ err = nbxmpp.Error(nbxmpp.Message(), nbxmpp.ERR_FEATURE_NOT_IMPLEMENTED)
err.T.error.T.text.setData(reason)
if fields:
- feature = xmpp.Node(xmpp.NS_FEATURE + ' feature')
+ feature = nbxmpp.Node(nbxmpp.NS_FEATURE + ' feature')
for field in fields:
- fn = xmpp.Node('field')
+ fn = nbxmpp.Node('field')
fn['var'] = field
feature.addChild(node=feature)
diff --git a/src/common/xmpp/__init__.py b/src/common/xmpp/__init__.py
deleted file mode 100644
index 46037a1cb..000000000
--- a/src/common/xmpp/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# $Id: __init__.py,v 1.9 2005/03/07 09:34:51 snakeru Exp $
-
-"""
-Gajim maintains a fork of the xmpppy jabber python library. Most of the code is
-inherited but has been extended by implementation of non-blocking transports
-and new features like BOSH.
-
-Most of the xmpp classes are ancestors of PlugIn class to share a single set of methods in order to compile a featured and extensible XMPP client.
-
-Thanks and credits to the xmpppy developers. See: http://xmpppy.sourceforge.net/
-"""
-
-from protocol import *
-import simplexml, protocol, auth_nb, transports_nb, roster_nb
-import dispatcher_nb, features_nb, idlequeue, bosh, tls_nb, proxy_connectors
-from client_nb import NonBlockingClient
-from plugin import PlugIn
-from smacks import Smacks
diff --git a/src/common/xmpp/auth_nb.py b/src/common/xmpp/auth_nb.py
deleted file mode 100644
index 10d65abed..000000000
--- a/src/common/xmpp/auth_nb.py
+++ /dev/null
@@ -1,724 +0,0 @@
-## auth_nb.py
-## based on auth.py, changes backported up to revision 1.41
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-## modified by Dimitur Kirov <dkirov@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-"""
-Provides plugs for SASL and NON-SASL authentication mechanisms.
-Can be used both for client and transport authentication
-
-See client_nb.py
-"""
-
-from protocol import NS_SASL, NS_SESSION, NS_STREAMS, NS_BIND, NS_AUTH
-from protocol import NS_STREAM_MGMT
-from protocol import Node, NodeProcessed, isResultNode, Iq, Protocol, JID
-from plugin import PlugIn
-from smacks import Smacks
-import base64
-import random
-import itertools
-import dispatcher_nb
-import hashlib
-import hmac
-import hashlib
-
-import logging
-log = logging.getLogger('gajim.c.x.auth_nb')
-
-def HH(some): return hashlib.md5(some).hexdigest()
-def H(some): return hashlib.md5(some).digest()
-def C(some): return ':'.join(some)
-
-try:
- kerberos = __import__('kerberos')
- have_kerberos = True
-except ImportError:
- have_kerberos = False
-
-GSS_STATE_STEP = 0
-GSS_STATE_WRAP = 1
-SASL_FAILURE_IN_PROGRESS = 'failure-in-process'
-SASL_FAILURE = 'failure'
-SASL_SUCCESS = 'success'
-SASL_UNSUPPORTED = 'not-supported'
-SASL_IN_PROCESS = 'in-process'
-
-def challenge_splitter(data):
- """
- Helper function that creates a dict from challenge string
-
- Sample challenge string:
- username="example.org",realm="somerealm",\
- nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
- nc=00000001,qop="auth,auth-int,auth-conf",charset=utf-8
-
- Expected result for challan:
- dict['qop'] = ('auth','auth-int','auth-conf')
- dict['realm'] = 'somerealm'
- """
- X_KEYWORD, X_VALUE, X_END = 0, 1, 2
- quotes_open = False
- keyword, value = '', ''
- dict_ = {}
- arr = None
-
- expecting = X_KEYWORD
- for iter_ in range(len(data) + 1):
- end = False
- if iter_ == len(data):
- expecting = X_END
- end = True
- else:
- char = data[iter_]
- if expecting == X_KEYWORD:
- if char == '=':
- expecting = X_VALUE
- elif char in (',', ' ', '\t'):
- pass
- else:
- keyword = '%s%c' % (keyword, char)
- elif expecting == X_VALUE:
- if char == '"':
- if quotes_open:
- end = True
- else:
- quotes_open = True
- elif char in (',', ' ', '\t'):
- if quotes_open:
- if not arr:
- arr = [value]
- else:
- arr.append(value)
- value = ""
- else:
- end = True
- else:
- value = '%s%c' % (value, char)
- if end:
- if arr:
- arr.append(value)
- dict_[keyword] = arr
- arr = None
- else:
- dict_[keyword] = value
- value, keyword = '', ''
- expecting = X_KEYWORD
- quotes_open = False
- return dict_
-
-def scram_parse(chatter):
- return dict(s.split('=', 1) for s in chatter.split(','))
-
-class SASL(PlugIn):
- """
- Implements SASL authentication. Can be plugged into NonBlockingClient
- to start authentication
- """
-
- def __init__(self, username, password, on_sasl):
- """
- :param user: XMPP username
- :param password: XMPP password
- :param on_sasl: Callback, will be called after each SASL auth-step.
- """
- PlugIn.__init__(self)
- self.username = username
- self.password = password
- self.on_sasl = on_sasl
- self.realm = None
-
- def plugin(self, owner):
- if 'version' not in self._owner.Dispatcher.Stream._document_attrs:
- self.startsasl = SASL_UNSUPPORTED
- elif self._owner.Dispatcher.Stream.features:
- try:
- self.FeaturesHandler(self._owner.Dispatcher,
- self._owner.Dispatcher.Stream.features)
- except NodeProcessed:
- pass
- else:
- self.startsasl = None
-
- def plugout(self):
- """
- Remove SASL handlers from owner's dispatcher. Used internally
- """
- 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):
- """
- Start authentication. Result can be obtained via "SASL.startsasl"
- attribute and will be either SASL_SUCCESS or SASL_FAILURE
-
- Note that successfull auth will take at least two Dispatcher.Process()
- calls.
- """
- if self.startsasl:
- pass
- elif self._owner.Dispatcher.Stream.features:
- try:
- self.FeaturesHandler(self._owner.Dispatcher,
- self._owner.Dispatcher.Stream.features)
- except NodeProcessed:
- pass
- else:
- self._owner.RegisterHandler('features',
- self.FeaturesHandler, xmlns=NS_STREAMS)
-
- def FeaturesHandler(self, conn, feats):
- """
- Used to determine if server supports SASL auth. Used internally
- """
- if not feats.getTag('mechanisms', namespace=NS_SASL):
- self.startsasl='not-supported'
- log.info('SASL not supported by server')
- return
- self.mecs = []
- for mec in feats.getTag('mechanisms', namespace=NS_SASL).getTags(
- 'mechanism'):
- self.mecs.append(mec.getData())
-
- self._owner.RegisterHandler('challenge', self.SASLHandler,
- xmlns=NS_SASL)
- self._owner.RegisterHandler('failure', self.SASLHandler, xmlns=NS_SASL)
- self._owner.RegisterHandler('success', self.SASLHandler, xmlns=NS_SASL)
- self.MechanismHandler()
-
- def MechanismHandler(self):
- 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'
- self.startsasl = SASL_IN_PROCESS
- self._owner.send(str(node))
- raise NodeProcessed
- if "EXTERNAL" in self.mecs:
- self.mecs.remove('EXTERNAL')
- sasl_data = u'%s@%s' % (self.username, self._owner.Server)
- sasl_data = sasl_data.encode('utf-8').encode('base64').replace(
- '\n', '')
- node = Node('auth', attrs={'xmlns': NS_SASL,
- 'mechanism': 'EXTERNAL'}, payload=[sasl_data])
- self.mechanism = 'EXTERNAL'
- self.startsasl = SASL_IN_PROCESS
- self._owner.send(str(node))
- raise NodeProcessed
- if 'GSSAPI' in self.mecs and have_kerberos:
- self.mecs.remove('GSSAPI')
- try:
- self.gss_vc = kerberos.authGSSClientInit('xmpp@' + \
- self._owner.xmpp_hostname)[1]
- kerberos.authGSSClientStep(self.gss_vc, '')
- response = kerberos.authGSSClientResponse(self.gss_vc)
- node=Node('auth', attrs={'xmlns': NS_SASL,
- 'mechanism': 'GSSAPI'}, payload=(response or ''))
- self.mechanism = 'GSSAPI'
- self.gss_step = GSS_STATE_STEP
- self.startsasl = SASL_IN_PROCESS
- self._owner.send(str(node))
- raise NodeProcessed
- except kerberos.GSSError, e:
- log.info('GSSAPI authentication failed: %s' % str(e))
- if 'SCRAM-SHA-1' in self.mecs:
- self.mecs.remove('SCRAM-SHA-1')
- self.mechanism = 'SCRAM-SHA-1'
- self._owner._caller.get_password(self.set_password, self.mechanism)
- self.scram_step = 0
- self.startsasl = SASL_IN_PROCESS
- raise NodeProcessed
- if 'DIGEST-MD5' in self.mecs:
- self.mecs.remove('DIGEST-MD5')
- node = Node('auth', attrs={'xmlns': NS_SASL,
- 'mechanism': 'DIGEST-MD5'})
- self.mechanism = 'DIGEST-MD5'
- self.startsasl = SASL_IN_PROCESS
- self._owner.send(str(node))
- raise NodeProcessed
- if 'PLAIN' in self.mecs:
- self.mecs.remove('PLAIN')
- self.mechanism = 'PLAIN'
- self._owner._caller.get_password(self.set_password, self.mechanism)
- self.startsasl = SASL_IN_PROCESS
- raise NodeProcessed
- if 'X-MESSENGER-OAUTH2' in self.mecs:
- self.mecs.remove('X-MESSENGER-OAUTH2')
- self.mechanism = 'X-MESSENGER-OAUTH2'
- self._owner._caller.get_password(self.set_password, self.mechanism)
- self.startsasl = SASL_IN_PROCESS
- raise NodeProcessed
- self.startsasl = SASL_FAILURE
- log.info('I can only use EXTERNAL, SCRAM-SHA-1, DIGEST-MD5, GSSAPI and '
- 'PLAIN mecanisms.')
- if self.on_sasl:
- self.on_sasl()
- return
-
- def SASLHandler(self, conn, challenge):
- """
- Perform next SASL auth step. Used internally
- """
- if challenge.getNamespace() != NS_SASL:
- return
-
- def scram_base64(s):
- return ''.join(s.encode('base64').split('\n'))
-
- incoming_data = challenge.getData()
- data=base64.decodestring(incoming_data)
- ### Handle Auth result
- def on_auth_fail(reason):
- log.info('Failed SASL authentification: %s' % reason)
- self._owner.send(str(Node('abort', attrs={'xmlns': NS_SASL})))
- if len(self.mecs) > 0:
- # There are other mechanisms to test, but wait for <failure>
- # answer from server
- self.startsasl = SASL_FAILURE_IN_PROGRESS
- raise NodeProcessed
- if self.on_sasl:
- self.on_sasl()
- raise NodeProcessed
-
- if challenge.getName() == 'failure':
- if self.startsasl == SASL_FAILURE_IN_PROGRESS:
- self.MechanismHandler()
- raise NodeProcessed
- self.startsasl = SASL_FAILURE
- try:
- reason = challenge.getChildren()[0]
- except Exception:
- reason = challenge
- on_auth_fail(reason)
- elif challenge.getName() == 'success':
- if self.mechanism == 'SCRAM-SHA-1':
- # check data-with-success
- data = scram_parse(data)
- if data['v'] != scram_base64(self.scram_ServerSignature):
- on_auth_fail('ServerSignature is wrong')
-
- self.startsasl = SASL_SUCCESS
- log.info('Successfully authenticated with remote server.')
- handlers = self._owner.Dispatcher.dumpHandlers()
-
- # Bosh specific dispatcher replugging
- # save old features. They will be used in case we won't get response
- # on stream restart after SASL auth (happens with XMPP over BOSH
- # with Openfire)
- old_features = self._owner.Dispatcher.Stream.features
- self._owner.Dispatcher.PlugOut()
- dispatcher_nb.Dispatcher.get_instance().PlugIn(self._owner,
- after_SASL=True, old_features=old_features)
- self._owner.Dispatcher.restoreHandlers(handlers)
- self._owner.User = self.username
-
- if self.on_sasl:
- self.on_sasl()
- raise NodeProcessed
-
- ### Perform auth step
- log.info('Got challenge:' + data)
-
- if self.mechanism == 'GSSAPI':
- if self.gss_step == GSS_STATE_STEP:
- rc = kerberos.authGSSClientStep(self.gss_vc, incoming_data)
- if rc != kerberos.AUTH_GSS_CONTINUE:
- self.gss_step = GSS_STATE_WRAP
- elif self.gss_step == GSS_STATE_WRAP:
- rc = kerberos.authGSSClientUnwrap(self.gss_vc, incoming_data)
- response = kerberos.authGSSClientResponse(self.gss_vc)
- rc = kerberos.authGSSClientWrap(self.gss_vc, response,
- kerberos.authGSSClientUserName(self.gss_vc))
- response = kerberos.authGSSClientResponse(self.gss_vc)
- if not response:
- response = ''
- self._owner.send(Node('response', attrs={'xmlns': NS_SASL},
- payload=response).__str__())
- raise NodeProcessed
- if self.mechanism == 'SCRAM-SHA-1':
- hashfn = hashlib.sha1
-
- def HMAC(k, s):
- return hmac.HMAC(key=k, msg=s, digestmod=hashfn).digest()
-
- def XOR(x, y):
- r = (chr(ord(px) ^ ord(py)) for px, py in zip(x, y))
- return ''.join(r)
-
- def Hi(s, salt, iters):
- ii = 1
- try:
- s = s.encode('utf-8')
- except:
- pass
- ui_1 = HMAC(s, salt + '\0\0\0\01')
- ui = ui_1
- for i in range(iters - 1):
- ii += 1
- ui_1 = HMAC(s, ui_1)
- ui = XOR(ui, ui_1)
- return ui
-
- def scram_H(s):
- return hashfn(s).digest()
-
- if self.scram_step == 0:
- self.scram_step = 1
- self.scram_soup += ',' + data + ','
- data = scram_parse(data)
- # TODO: Should check cnonce here.
- # TODO: Channel binding data goes in here too.
- r = 'c=' + scram_base64(self.scram_gs2)
- r += ',r=' + data['r']
- self.scram_soup += r
- salt = data['s'].decode('base64')
- iter = int(data['i'])
- SaltedPassword = Hi(self.password, salt, iter)
- # TODO: Could cache this, along with salt+iter.
- ClientKey = HMAC(SaltedPassword, 'Client Key')
- StoredKey = scram_H(ClientKey)
- ClientSignature = HMAC(StoredKey, self.scram_soup)
- ClientProof = XOR(ClientKey, ClientSignature)
- r += ',p=' + scram_base64(ClientProof)
- ServerKey = HMAC(SaltedPassword, 'Server Key')
- self.scram_ServerSignature = HMAC(ServerKey, self.scram_soup)
- sasl_data = scram_base64(r)
- node = Node('response', attrs={'xmlns': NS_SASL},
- payload=[sasl_data])
- self._owner.send(str(node))
- raise NodeProcessed
-
- if self.scram_step == 1:
- data = scram_parse(data)
- if data['v'].decode('base64') != self.scram_ServerSignature:
- # TODO: Not clear what to do here - need to abort.
- raise Exception
- node = Node('response', attrs={'xmlns': NS_SASL});
- self._owner.send(str(node))
- raise NodeProcessed
-
- # magic foo...
- chal = challenge_splitter(data)
- if not self.realm and 'realm' in chal:
- self.realm = chal['realm']
- if 'qop' in chal and ((isinstance(chal['qop'], str) and \
- chal['qop'] =='auth') or (isinstance(chal['qop'], list) and 'auth' in \
- chal['qop'])):
- self.resp = {}
- self.resp['username'] = self.username
- if self.realm:
- self.resp['realm'] = self.realm
- else:
- self.resp['realm'] = self._owner.Server
- self.resp['nonce'] = chal['nonce']
- self.resp['cnonce'] = ''.join("%x" % randint(0, 2**28) for randint \
- in itertools.repeat(random.randint, 7))
- self.resp['nc'] = ('00000001')
- self.resp['qop'] = 'auth'
- self.resp['digest-uri'] = 'xmpp/' + self._owner.Server
- self.resp['charset'] = 'utf-8'
- # Password is now required
- self._owner._caller.get_password(self.set_password, self.mechanism)
- elif 'rspauth' in chal:
- # Check rspauth value
- if chal['rspauth'] != self.digest_rspauth:
- on_auth_fail('rspauth is wrong')
- self._owner.send(str(Node('response', attrs={'xmlns':NS_SASL})))
- else:
- self.startsasl = SASL_FAILURE
- log.info('Failed SASL authentification: unknown challenge')
- if self.on_sasl:
- self.on_sasl()
- raise NodeProcessed
-
- @staticmethod
- def _convert_to_iso88591(string):
- try:
- string = string.decode('utf-8').encode('iso-8859-1')
- except UnicodeEncodeError:
- pass
- return string
-
- def set_password(self, password):
- self.password = '' if password is None else password
- if self.mechanism == 'SCRAM-SHA-1':
- nonce = ''.join('%x' % randint(0, 2 ** 28) for randint in \
- itertools.repeat(random.randint, 7))
- self.scram_soup = 'n=' + self.username + ',r=' + nonce
- self.scram_gs2 = 'n,,' # No CB yet.
- sasl_data = (self.scram_gs2 + self.scram_soup).encode('base64').\
- replace('\n', '')
- node = Node('auth', attrs={'xmlns': NS_SASL,
- 'mechanism': self.mechanism}, payload=[sasl_data])
- elif self.mechanism == 'DIGEST-MD5':
- hash_username = self._convert_to_iso88591(self.resp['username'])
- hash_realm = self._convert_to_iso88591(self.resp['realm'])
- hash_password = self._convert_to_iso88591(self.password)
- A1 = C([H(C([hash_username, hash_realm, hash_password])),
- self.resp['nonce'], self.resp['cnonce']])
- A2 = C(['AUTHENTICATE', self.resp['digest-uri']])
- response = HH(C([HH(A1), self.resp['nonce'], self.resp['nc'],
- self.resp['cnonce'], self.resp['qop'], HH(A2)]))
- A2 = C(['', self.resp['digest-uri']])
- self.digest_rspauth = HH(C([HH(A1), self.resp['nonce'],
- self.resp['nc'], self.resp['cnonce'], self.resp['qop'],
- HH(A2)]))
- self.resp['response'] = response
- sasl_data = u''
- for key in ('charset', 'username', 'realm', 'nonce', 'nc', 'cnonce',
- 'digest-uri', 'response', 'qop'):
- if key in ('nc', 'qop', 'response', 'charset'):
- sasl_data += u"%s=%s," % (key, self.resp[key])
- else:
- sasl_data += u'%s="%s",' % (key, self.resp[key])
- sasl_data = sasl_data[:-1].encode('utf-8').encode('base64').replace(
- '\r', '').replace('\n', '')
- node = Node('response', attrs={'xmlns': NS_SASL},
- payload=[sasl_data])
- elif self.mechanism == 'PLAIN':
- sasl_data = u'\x00%s\x00%s' % (self.username, self.password)
- sasl_data = sasl_data.encode('utf-8').encode('base64').replace(
- '\n', '')
- node = Node('auth', attrs={'xmlns': NS_SASL, 'mechanism': 'PLAIN'},
- payload=[sasl_data])
- elif self.mechanism == 'X-MESSENGER-OAUTH2':
- node = Node('auth', attrs={'xmlns': NS_SASL,
- 'mechanism': 'X-MESSENGER-OAUTH2'})
- node.addData(password)
- self._owner.send(str(node))
-
-
-class NonBlockingNonSASL(PlugIn):
- """
- Implements old Non-SASL (JEP-0078) authentication used in jabberd1.4 and
- transport authentication
- """
-
- def __init__(self, user, password, resource, on_auth):
- """
- Caches username, password and resource for auth
- """
- PlugIn.__init__(self)
- self.user = user
- if password is None:
- self.password = ''
- else:
- self.password = password
- self.resource = resource
- self.on_auth = on_auth
-
- def plugin(self, owner):
- """
- Determine the best auth method (digest/0k/plain) and use it for auth.
- Returns used method name on success. Used internally
- """
- log.info('Querying server about possible auth methods')
- self.owner = owner
-
- owner.Dispatcher.SendAndWaitForResponse(
- Iq('get', NS_AUTH, payload=[Node('username', payload=[self.user])]),
- func=self._on_username)
-
- def _on_username(self, resp):
- if not isResultNode(resp):
- log.info('No result node arrived! Aborting...')
- return self.on_auth(None)
-
- iq=Iq(typ='set', node=resp)
- query = iq.getTag('query')
- query.setTagData('username', self.user)
- query.setTagData('resource', self.resource)
-
- if query.getTag('digest'):
- log.info("Performing digest authentication")
- query.setTagData('digest',
- hashlib.sha1(self.owner.Dispatcher.Stream._document_attrs['id']
- + self.password).hexdigest())
- if query.getTag('password'):
- query.delChild('password')
- self._method = 'digest'
- elif query.getTag('token'):
- token = query.getTagData('token')
- seq = query.getTagData('sequence')
- log.info("Performing zero-k authentication")
-
- def hasher(s):
- return hashlib.sha1(s).hexdigest()
-
- def hash_n_times(s, count):
- return count and hasher(hash_n_times(s, count-1)) or s
-
- hash_ = hash_n_times(hasher(hasher(self.password) + token),
- int(seq))
- query.setTagData('hash', hash_)
- self._method='0k'
- else:
- log.warn("Secure methods unsupported, performing plain text \
- authentication")
- self._method = 'plain'
- self._owner._caller.get_password(self._on_password, self._method)
- return
- resp = self.owner.Dispatcher.SendAndWaitForResponse(iq,
- func=self._on_auth)
-
- def _on_password(self, password):
- self.password = '' if password is None else password
- iq=Iq('set', NS_AUTH)
- query = iq.getTag('query')
- query.setTagData('username', self.user)
- query.setTagData('resource', self.resource)
- query.setTagData('password', self.password)
- resp = self.owner.Dispatcher.SendAndWaitForResponse(iq,
- func=self._on_auth)
-
- def _on_auth(self, resp):
- if isResultNode(resp):
- log.info('Sucessfully authenticated with remote host.')
- self.owner.User = self.user
- self.owner.Resource = self.resource
- self.owner._registered_name = self.owner.User + '@' + \
- self.owner.Server+ '/' + self.owner.Resource
- return self.on_auth(self._method)
- log.info('Authentication failed!')
- return self.on_auth(None)
-
-
-class NonBlockingBind(PlugIn):
- """
- Bind some JID to the current connection to allow router know of our
- location. Must be plugged after successful SASL auth
- """
-
- def __init__(self):
- PlugIn.__init__(self)
- self.bound = None
- self.supports_sm = False
- self.resuming = False
-
- def plugin(self, owner):
- ''' Start resource binding, if allowed at this time. Used internally. '''
- if self._owner.Dispatcher.Stream.features:
- try:
- self.FeaturesHandler(self._owner.Dispatcher,
- self._owner.Dispatcher.Stream.features)
- except NodeProcessed:
- pass
- else:
- self._owner.RegisterHandler('features', self.FeaturesHandler,
- xmlns=NS_STREAMS)
-
- def FeaturesHandler(self, conn, feats):
- """
- Determine if server supports resource binding and set some internal
- attributes accordingly.
-
- It also checks if server supports stream management
- """
-
- if feats.getTag('sm', namespace=NS_STREAM_MGMT):
- self.supports_sm = True # server supports stream management
- if self.resuming:
- self._owner._caller.sm.resume_request()
-
- if not feats.getTag('bind', namespace=NS_BIND):
- log.info('Server does not requested binding.')
- # we try to bind resource anyway
- #self.bound='failure'
- self.bound = []
- return
- if feats.getTag('session', namespace=NS_SESSION):
- self.session = 1
- else:
- self.session = -1
- self.bound = []
-
- def plugout(self):
- """
- Remove Bind handler from owner's dispatcher. Used internally
- """
- self._owner.UnregisterHandler('features', self.FeaturesHandler,
- xmlns=NS_STREAMS)
-
- def NonBlockingBind(self, resource=None, on_bound=None):
- """
- Perform binding. Use provided resource name or random (if not provided).
- """
- if self.resuming: # We don't bind if we resume the stream
- return
- self.on_bound = on_bound
- self._resource = resource
- if self._resource:
- self._resource = [Node('resource', payload=[self._resource])]
- else:
- self._resource = []
-
- self._owner.onreceive(None)
- self._owner.Dispatcher.SendAndWaitForResponse(
- Protocol('iq', typ='set', payload=[Node('bind',
- attrs={'xmlns': NS_BIND}, payload=self._resource)]),
- func=self._on_bound)
-
- def _on_bound(self, resp):
- if isResultNode(resp):
- if resp.getTag('bind') and resp.getTag('bind').getTagData('jid'):
- self.bound.append(resp.getTag('bind').getTagData('jid'))
- log.info('Successfully bound %s.' % self.bound[-1])
- jid = JID(resp.getTag('bind').getTagData('jid'))
- self._owner.User = jid.getNode()
- self._owner.Resource = jid.getResource()
- # Only negociate stream management after bounded
- sm = self._owner._caller.sm
- if self.supports_sm:
- # starts negociation
- sm.set_owner(self._owner)
- sm.negociate()
- self._owner.Dispatcher.sm = sm
-
- if hasattr(self, 'session') and self.session == -1:
- # Server don't want us to initialize a session
- log.info('No session required.')
- self.on_bound('ok')
- else:
- self._owner.SendAndWaitForResponse(Protocol('iq', typ='set',
- payload=[Node('session', attrs={'xmlns':NS_SESSION})]),
- func=self._on_session)
- return
- if resp:
- log.info('Binding failed: %s.' % resp.getTag('error'))
- self.on_bound(None)
- else:
- log.info('Binding failed: timeout expired.')
- self.on_bound(None)
-
- def _on_session(self, resp):
- self._owner.onreceive(None)
- if isResultNode(resp):
- log.info('Successfully opened session.')
- self.session = 1
- self.on_bound('ok')
- else:
- log.error('Session open failed.')
- self.session = 0
- self.on_bound(None)
diff --git a/src/common/xmpp/bosh.py b/src/common/xmpp/bosh.py
deleted file mode 100644
index 9bf5be7f3..000000000
--- a/src/common/xmpp/bosh.py
+++ /dev/null
@@ -1,581 +0,0 @@
-## bosh.py
-##
-##
-## Copyright (C) 2008 Tomas Karasek <tom.to.the.k@gmail.com>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-
-
-import locale, random
-from hashlib import sha1
-from transports_nb import NonBlockingTransport, NonBlockingHTTPBOSH,\
- CONNECTED, CONNECTING, DISCONNECTED, DISCONNECTING,\
- urisplit, DISCONNECT_TIMEOUT_SECONDS
-from protocol import BOSHBody, Protocol, NS_CLIENT
-from simplexml import Node
-
-import logging
-log = logging.getLogger('gajim.c.x.bosh')
-
-KEY_COUNT = 10
-
-# Fake file descriptor - it's used for setting read_timeout in idlequeue for
-# BOSH Transport. In TCP-derived transports this is file descriptor of socket.
-FAKE_DESCRIPTOR = -1337
-
-
-class NonBlockingBOSH(NonBlockingTransport):
- def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, certs,
- xmpp_server, domain, bosh_dict, proxy_creds):
- NonBlockingTransport.__init__(self, raise_event, on_disconnect, idlequeue,
- estabilish_tls, certs)
-
- self.bosh_sid = None
- if locale.getdefaultlocale()[0]:
- self.bosh_xml_lang = locale.getdefaultlocale()[0].split('_')[0]
- else:
- self.bosh_xml_lang = 'en'
-
- self.http_version = 'HTTP/1.1'
- self.http_persistent = True
- self.http_pipelining = bosh_dict['bosh_http_pipelining']
- self.bosh_to = domain
-
- self.route_host, self.route_port = xmpp_server
-
- self.bosh_wait = bosh_dict['bosh_wait']
- if not self.http_pipelining:
- self.bosh_hold = 1
- else:
- self.bosh_hold = bosh_dict['bosh_hold']
- self.bosh_requests = self.bosh_hold
- self.bosh_uri = bosh_dict['bosh_uri']
- self.bosh_content = bosh_dict['bosh_content']
- self.over_proxy = bosh_dict['bosh_useproxy']
- if estabilish_tls:
- self.bosh_secure = 'true'
- else:
- self.bosh_secure = 'false'
- self.use_proxy_auth = bosh_dict['useauth']
- self.proxy_creds = proxy_creds
- self.wait_cb_time = None
- self.http_socks = []
- self.stanza_buffer = []
- self.prio_bosh_stanzas = []
- self.current_recv_handler = None
- self.current_recv_socket = None
- self.key_stack = None
- self.ack_checker = None
- self.after_init = False
- self.proxy_dict = {}
- if self.over_proxy and self.estabilish_tls:
- self.proxy_dict['type'] = 'http'
- # with SSL over proxy, we do HTTP CONNECT to proxy to open a channel to
- # BOSH Connection Manager
- host, port = urisplit(self.bosh_uri)[1:3]
- self.proxy_dict['xmpp_server'] = (host, port)
- self.proxy_dict['credentials'] = self.proxy_creds
-
-
- def connect(self, conn_5tuple, on_connect, on_connect_failure):
- NonBlockingTransport.connect(self, conn_5tuple, on_connect, on_connect_failure)
-
- global FAKE_DESCRIPTOR
- FAKE_DESCRIPTOR = FAKE_DESCRIPTOR - 1
- self.fd = FAKE_DESCRIPTOR
-
- self.stanza_buffer = []
- self.prio_bosh_stanzas = []
-
- self.key_stack = KeyStack(KEY_COUNT)
- self.ack_checker = AckChecker()
- self.after_init = True
-
- self.http_socks.append(self.get_new_http_socket())
- self._tcp_connecting_started()
-
- self.http_socks[0].connect(
- conn_5tuple = conn_5tuple,
- on_connect = self._on_connect,
- on_connect_failure = self._on_connect_failure)
-
- def _on_connect(self):
- self.peerhost = self.http_socks[0].peerhost
- self.ssl_lib = self.http_socks[0].ssl_lib
- NonBlockingTransport._on_connect(self)
-
-
-
- def set_timeout(self, timeout):
- if self.get_state() != DISCONNECTED and self.fd != -1:
- NonBlockingTransport.set_timeout(self, timeout)
- else:
- log.warn('set_timeout: TIMEOUT NOT SET: state is %s, fd is %s' % (self.get_state(), self.fd))
-
- def on_http_request_possible(self):
- """
- Called when HTTP request it's possible to send a HTTP request. It can be when
- socket is connected or when HTTP response arrived
-
- There should be always one pending request to BOSH CM.
- """
- log.debug('on_http_req possible, state:\n%s' % self.get_current_state())
- if self.get_state()==DISCONNECTED: return
-
- #Hack for making the non-secure warning dialog work
- if self._owner.got_features:
- if (hasattr(self._owner, 'NonBlockingNonSASL') or hasattr(self._owner, 'SASL')):
- self.send_BOSH(None)
- else:
- # If we already got features and no auth module was plugged yet, we are
- # probably waiting for confirmation of the "not-secure-connection" dialog.
- # We don't send HTTP request in that case.
- # see http://lists.jabber.ru/pipermail/ejabberd/2008-August/004027.html
- return
- else:
- self.send_BOSH(None)
-
-
-
- def get_socket_in(self, state):
- """
- Get sockets in desired state
- """
- for s in self.http_socks:
- if s.get_state()==state: return s
- return None
-
-
- def get_free_socket(self):
- """
- Select and returns socket eligible for sending a data to
- """
- if self.http_pipelining:
- return self.get_socket_in(CONNECTED)
- else:
- last_recv_time, tmpsock = 0, None
- for s in self.http_socks:
- # we're interested only in CONNECTED socket with no requests pending
- if s.get_state()==CONNECTED and s.pending_requests==0:
- # if there's more of them, we want the one with the least recent data receive
- # (lowest last_recv_time)
- if (last_recv_time==0) or (s.last_recv_time < last_recv_time):
- last_recv_time = s.last_recv_time
- tmpsock = s
- if tmpsock:
- return tmpsock
- else:
- return None
-
-
- def send_BOSH(self, payload):
- """
- Tries to send a stanza in payload by appeding it to a buffer and plugging a
- free socket for writing.
- """
- total_pending_reqs = sum([s.pending_requests for s in self.http_socks])
-
- # when called after HTTP response (Payload=None) and when there are already
- # some pending requests and no data to send, or when the socket is
- # disconnected, we do nothing
- if payload is None and \
- total_pending_reqs > 0 and \
- self.stanza_buffer == [] and \
- self.prio_bosh_stanzas == [] or \
- self.get_state()==DISCONNECTED:
- return
-
- # Add xmlns to stanza to help ejabberd server
- if payload and isinstance(payload, Protocol):
- if not payload.getNamespace():
- payload.setNamespace(NS_CLIENT)
-
- # now the payload is put to buffer and will be sent at some point
- self.append_stanza(payload)
-
- # if we're about to make more requests than allowed, we don't send - stanzas will be
- # sent after HTTP response from CM, exception is when we're disconnecting - then we
- # send anyway
- if total_pending_reqs >= self.bosh_requests and self.get_state()!=DISCONNECTING:
- log.warn('attemp to make more requests than allowed by Connection Manager:\n%s' %
- self.get_current_state())
- return
-
- # when there's free CONNECTED socket, we plug it for write and the data will
- # be sent when write is possible
- if self.get_free_socket():
- self.plug_socket()
- return
-
- # if there is a connecting socket, we just wait for when it connects,
- # payload will be sent in a sec when the socket connects
- if self.get_socket_in(CONNECTING): return
-
- # being here means there are either DISCONNECTED sockets or all sockets are
- # CONNECTED with too many pending requests
- s = self.get_socket_in(DISCONNECTED)
-
- # if we have DISCONNECTED socket, lets connect it and plug for send
- if s:
- self.connect_and_flush(s)
- else:
- # otherwise create and connect a new one
- ss = self.get_new_http_socket()
- self.http_socks.append(ss)
- self.connect_and_flush(ss)
- return
-
- def plug_socket(self):
- stanza = None
- s = self.get_free_socket()
- if s:
- s._plug_idle(writable=True, readable=True)
- else:
- log.error('=====!!!!!!!!====> Couldn\'t get free socket in plug_socket())')
-
- def build_stanza(self, socket):
- """
- Build a BOSH body tag from data in buffers and adds key, rid and ack
- attributes to it
-
- This method is called from _do_send() of underlying transport. This is to
- ensure rid and keys will be processed in correct order. If I generate
- them before plugging a socket for write (and did it for two sockets/HTTP
- connections) in parallel, they might be sent in wrong order, which
- results in violating the BOSH session and server-side disconnect.
- """
- if self.prio_bosh_stanzas:
- stanza, add_payload = self.prio_bosh_stanzas.pop(0)
- if add_payload:
- stanza.setPayload(self.stanza_buffer)
- self.stanza_buffer = []
- else:
- stanza = self.boshify_stanzas(self.stanza_buffer)
- self.stanza_buffer = []
-
- stanza = self.ack_checker.backup_stanza(stanza, socket)
-
- key, newkey = self.key_stack.get()
- if key:
- stanza.setAttr('key', key)
- if newkey:
- stanza.setAttr('newkey', newkey)
-
-
- log.info('sending msg with rid=%s to sock %s' % (stanza.getAttr('rid'), id(socket)))
- self.renew_bosh_wait_timeout(self.bosh_wait + 3)
- return stanza
-
-
- def on_bosh_wait_timeout(self):
- log.error('Connection Manager didn\'t respond within %s + 3 seconds --> forcing disconnect' % self.bosh_wait)
- self.disconnect()
-
-
- def renew_bosh_wait_timeout(self, timeout):
- if self.wait_cb_time is not None:
- self.remove_bosh_wait_timeout()
- sched_time = self.idlequeue.set_alarm(self.on_bosh_wait_timeout, timeout)
- self.wait_cb_time = sched_time
-
- def remove_bosh_wait_timeout(self):
- self.idlequeue.remove_alarm(
- self.on_bosh_wait_timeout,
- self.wait_cb_time)
-
- def on_persistent_fallback(self, socket):
- """
- Called from underlying transport when server closes TCP connection
-
- :param socket: disconnected transport object
- """
- if socket.http_persistent:
- log.warn('Fallback to nonpersistent HTTP (no pipelining as well)')
- socket.http_persistent = False
- self.http_persistent = False
- self.http_pipelining = False
- socket.disconnect(do_callback=False)
- self.connect_and_flush(socket)
- else:
- socket.disconnect()
-
-
-
- def handle_body_attrs(self, stanza_attrs):
- """
- Called for each incoming body stanza from dispatcher. Checks body
- attributes.
- """
- self.remove_bosh_wait_timeout()
-
- if self.after_init:
- if stanza_attrs.has_key('sid'):
- # session ID should be only in init response
- self.bosh_sid = stanza_attrs['sid']
-
- if stanza_attrs.has_key('requests'):
- self.bosh_requests = int(stanza_attrs['requests'])
-
- if stanza_attrs.has_key('wait'):
- self.bosh_wait = int(stanza_attrs['wait'])
- self.after_init = False
-
- ack = None
- if stanza_attrs.has_key('ack'):
- ack = stanza_attrs['ack']
- self.ack_checker.process_incoming_ack(ack=ack,
- socket=self.current_recv_socket)
-
- if stanza_attrs.has_key('type'):
- if stanza_attrs['type'] in ['terminate', 'terminal']:
- condition = 'n/a'
- if stanza_attrs.has_key('condition'):
- condition = stanza_attrs['condition']
- if condition == 'n/a':
- log.info('Received sesion-ending terminating stanza')
- else:
- log.error('Received terminating stanza: %s - %s' % (condition,
- bosh_errors[condition]))
- self.disconnect()
- return
-
- if stanza_attrs['type'] == 'error':
- # recoverable error
- pass
- return
-
-
- def append_stanza(self, stanza):
- """
- Append stanza to a buffer to send
- """
- if stanza:
- if isinstance(stanza, tuple):
- # stanza is tuple of BOSH stanza and bool value for whether to add payload
- self.prio_bosh_stanzas.append(stanza)
- else:
- # stanza is XMPP stanza. Will be boshified before send.
- self.stanza_buffer.append(stanza)
-
-
- def send(self, stanza, now=False):
- self.send_BOSH(stanza)
-
-
-
- def get_current_state(self):
- t = '------ SOCKET_ID\tSOCKET_STATE\tPENDING_REQS\n'
- for s in self.http_socks:
- t = '%s------ %s\t%s\t%s\n' % (t, id(s), s.get_state(), s.pending_requests)
- t = '%s------ prio stanzas: %s, queued XMPP stanzas: %s, not_acked stanzas: %s' \
- % (t, self.prio_bosh_stanzas, self.stanza_buffer,
- self.ack_checker.get_not_acked_rids())
- return t
-
-
- def connect_and_flush(self, socket):
- socket.connect(
- conn_5tuple = self.conn_5tuple,
- on_connect = self.on_http_request_possible,
- on_connect_failure = self.disconnect)
-
-
- def boshify_stanzas(self, stanzas=[], body_attrs=None):
- """
- Wraps zero to many stanzas by body tag with xmlns and sid
- """
- log.debug('boshify_staza - type is: %s, stanza is %s' % (type(stanzas), stanzas))
- tag = BOSHBody(attrs={'sid': self.bosh_sid})
- tag.setPayload(stanzas)
- return tag
-
-
- def send_init(self, after_SASL=False):
- if after_SASL:
- t = BOSHBody(
- attrs={ 'to': self.bosh_to,
- 'sid': self.bosh_sid,
- 'xml:lang': self.bosh_xml_lang,
- 'xmpp:restart': 'true',
- 'secure': self.bosh_secure,
- 'xmlns:xmpp': 'urn:xmpp:xbosh'})
- else:
- t = BOSHBody(
- attrs={ 'content': self.bosh_content,
- 'hold': str(self.bosh_hold),
- 'route': 'xmpp:%s:%s' % (self.route_host, self.route_port),
- 'to': self.bosh_to,
- 'wait': str(self.bosh_wait),
- 'xml:lang': self.bosh_xml_lang,
- 'xmpp:version': '1.0',
- 'ver': '1.6',
- 'xmlns:xmpp': 'urn:xmpp:xbosh'})
- self.send_BOSH((t, True))
-
- def start_disconnect(self):
- NonBlockingTransport.start_disconnect(self)
- self.renew_bosh_wait_timeout(DISCONNECT_TIMEOUT_SECONDS)
- self.send_BOSH(
- (BOSHBody(attrs={'sid': self.bosh_sid, 'type': 'terminate'}), True))
-
-
- def get_new_http_socket(self):
- http_dict = {'http_uri': self.bosh_uri,
- 'http_version': self.http_version,
- 'http_persistent': self.http_persistent,
- 'add_proxy_headers': self.over_proxy and not self.estabilish_tls}
- if self.use_proxy_auth:
- http_dict['proxy_user'], http_dict['proxy_pass'] = self.proxy_creds
-
- s = NonBlockingHTTPBOSH(
- raise_event=self.raise_event,
- on_disconnect=self.disconnect,
- idlequeue = self.idlequeue,
- estabilish_tls = self.estabilish_tls,
- certs = self.certs,
- on_http_request_possible = self.on_http_request_possible,
- http_dict = http_dict,
- proxy_dict = self.proxy_dict,
- on_persistent_fallback = self.on_persistent_fallback)
-
- s.onreceive(self.on_received_http)
- s.set_stanza_build_cb(self.build_stanza)
- return s
-
-
- def onreceive(self, recv_handler):
- if recv_handler is None:
- recv_handler = self._owner.Dispatcher.ProcessNonBlocking
- self.current_recv_handler = recv_handler
-
-
- def on_received_http(self, data, socket):
- self.current_recv_socket = socket
- self.current_recv_handler(data)
-
-
- def disconnect(self, do_callback=True):
- self.remove_bosh_wait_timeout()
- if self.get_state() == DISCONNECTED: return
- self.fd = -1
- for s in self.http_socks:
- s.disconnect(do_callback=False)
- NonBlockingTransport.disconnect(self, do_callback)
-
-
-def get_rand_number():
- # with 50-bit random initial rid, session would have to go up
- # to 7881299347898368 messages to raise rid over 2**53
- # (see http://www.xmpp.org/extensions/xep-0124.html#rids)
- # it's also used for sequence key initialization
- r = random.Random()
- r.seed()
- return r.getrandbits(50)
-
-
-
-class AckChecker():
- """
- Class for generating rids and generating and checking acknowledgements in
- BOSH messages
- """
- def __init__(self):
- self.rid = get_rand_number()
- self.ack = 1
- self.last_rids = {}
- self.not_acked = []
-
-
- def get_not_acked_rids(self): return [rid for rid, st in self.not_acked]
-
- def backup_stanza(self, stanza, socket):
- socket.pending_requests += 1
- rid = self.get_rid()
- self.not_acked.append((rid, stanza))
- stanza.setAttr('rid', str(rid))
- self.last_rids[socket]=rid
-
- if self.rid != self.ack + 1:
- stanza.setAttr('ack', str(self.ack))
- return stanza
-
- def process_incoming_ack(self, socket, ack=None):
- socket.pending_requests -= 1
- if ack:
- ack = int(ack)
- else:
- ack = self.last_rids[socket]
-
- i = len([rid for rid, st in self.not_acked if ack >= rid])
- self.not_acked = self.not_acked[i:]
-
- self.ack = ack
-
-
- def get_rid(self):
- self.rid = self.rid + 1
- return self.rid
-
-
-
-
-
-class KeyStack():
- """
- Class implementing key sequences for BOSH messages
- """
- def __init__(self, count):
- self.count = count
- self.keys = []
- self.reset()
- self.first_call = True
-
- def reset(self):
- seed = str(get_rand_number())
- self.keys = [sha1(seed).hexdigest()]
- for i in range(self.count-1):
- curr_seed = self.keys[i]
- self.keys.append(sha1(curr_seed).hexdigest())
-
- def get(self):
- if self.first_call:
- self.first_call = False
- return (None, self.keys.pop())
-
- if len(self.keys)>1:
- return (self.keys.pop(), None)
- else:
- last_key = self.keys.pop()
- self.reset()
- new_key = self.keys.pop()
- return (last_key, new_key)
-
-# http://www.xmpp.org/extensions/xep-0124.html#errorstatus-terminal
-bosh_errors = {
- 'n/a': 'none or unknown condition in terminating body stanza',
- 'bad-request': 'The format of an HTTP header or binding element received from the client is unacceptable (e.g., syntax error), or Script Syntax is not supported.',
- 'host-gone': 'The target domain specified in the "to" attribute or the target host or port specified in the "route" attribute is no longer serviced by the connection manager.',
- 'host-unknown': 'The target domain specified in the "to" attribute or the target host or port specified in the "route" attribute is unknown to the connection manager.',
- 'improper-addressing': 'The initialization element lacks a "to" or "route" attribute (or the attribute has no value) but the connection manager requires one.',
- 'internal-server-error': 'The connection manager has experienced an internal error that prevents it from servicing the request.',
- 'item-not-found': '(1) "sid" is not valid, (2) "stream" is not valid, (3) "rid" is larger than the upper limit of the expected window, (4) connection manager is unable to resend response, (5) "key" sequence is invalid',
- 'other-request': 'Another request being processed at the same time as this request caused the session to terminate.',
- 'policy-violation': 'The client has broken the session rules (polling too frequently, requesting too frequently, too many simultaneous requests).',
- 'remote-connection-failed': 'The connection manager was unable to connect to, or unable to connect securely to, or has lost its connection to, the server.',
- 'remote-stream-error': 'Encapsulates an error in the protocol being transported.',
- 'see-other-uri': 'The connection manager does not operate at this URI (e.g., the connection manager accepts only SSL or TLS connections at some https: URI rather than the http: URI requested by the client). The client may try POSTing to the URI in the content of the <uri/> child element.',
- 'system-shutdown': 'The connection manager is being shut down. All active HTTP sessions are being terminated. No new sessions can be created.',
- 'undefined-condition': 'The error is not one of those defined herein; the connection manager SHOULD include application-specific information in the content of the <body/> wrapper.'
-}
diff --git a/src/common/xmpp/c14n.py b/src/common/xmpp/c14n.py
deleted file mode 100644
index 0d318a352..000000000
--- a/src/common/xmpp/c14n.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# -*- coding:utf-8 -*-
-## c14n.py
-##
-## Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-"""
-XML canonicalisation methods (for XEP-0116)
-"""
-
-from simplexml import ustr
-
-def c14n(node, is_buggy):
- s = "<" + node.name
- if node.namespace:
- if not node.parent or node.parent.namespace != node.namespace:
- s = s + ' xmlns="%s"' % node.namespace
-
- sorted_attrs = sorted(node.attrs.keys())
- for key in sorted_attrs:
- if not is_buggy and key == 'xmlns':
- continue
- val = ustr(node.attrs[key])
- # like XMLescape() but with whitespace and without &gt;
- s = s + ' %s="%s"' % ( key, normalise_attr(val) )
- s = s + ">"
- cnt = 0
- if node.kids:
- for a in node.kids:
- if (len(node.data)-1) >= cnt:
- s = s + normalise_text(node.data[cnt])
- s = s + c14n(a, is_buggy)
- cnt=cnt+1
- if (len(node.data)-1) >= cnt: s = s + normalise_text(node.data[cnt])
- if not node.kids and s.endswith('>'):
- s=s[:-1]+' />'
- else:
- s = s + "</" + node.name + ">"
- return s.encode('utf-8')
-
-def normalise_attr(val):
- return val.replace('&', '&amp;').replace('<', '&lt;').replace('"', '&quot;').replace('\t', '&#x9;').replace('\n', '&#xA;').replace('\r', '&#xD;')
-
-def normalise_text(val):
- return val.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('\r', '&#xD;')
diff --git a/src/common/xmpp/client_nb.py b/src/common/xmpp/client_nb.py
deleted file mode 100644
index 61ff769f2..000000000
--- a/src/common/xmpp/client_nb.py
+++ /dev/null
@@ -1,629 +0,0 @@
-## client_nb.py
-## based on client.py, changes backported up to revision 1.60
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-## modified by Dimitur Kirov <dkirov@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-# $Id: client.py,v 1.52 2006/01/02 19:40:55 normanr Exp $
-
-"""
-Client class establishs connection to XMPP Server and handles authentication
-"""
-
-import socket
-import transports_nb, dispatcher_nb, auth_nb, roster_nb, protocol, bosh
-from protocol import NS_TLS
-
-import logging
-log = logging.getLogger('gajim.c.x.client_nb')
-
-
-class NonBlockingClient:
- """
- Client class is XMPP connection mountpoint. Objects for authentication,
- network communication, roster, xml parsing ... are plugged to client object.
- Client implements the abstract behavior - mostly negotioation and callbacks
- handling, whereas underlying modules take care of feature-specific logic
- """
-
- def __init__(self, domain, idlequeue, caller=None):
- """
- Caches connection data
-
- :param domain: domain - for to: attribute (from account info)
- :param idlequeue: processing idlequeue
- :param caller: calling object - it has to implement methods
- _event_dispatcher which is called from dispatcher instance
- """
- self.Namespace = protocol.NS_CLIENT
- self.defaultNamespace = self.Namespace
-
- self.idlequeue = idlequeue
- self.disconnect_handlers = []
-
- self.Server = domain
- self.xmpp_hostname = None # FQDN hostname to connect to
-
- # caller is who initiated this client, it is in needed to register
- # the EventDispatcher
- self._caller = caller
- self._owner = self
- self._registered_name = None # our full jid, set after successful auth
- self.connected = ''
- self.ip_addresses = []
- self.socket = None
- self.on_connect = None
- self.on_proxy_failure = None
- self.on_connect_failure = None
- self.proxy = None
- self.got_features = False
- self.got_see_other_host = None
- self.stream_started = False
- self.disconnecting = False
- self.protocol_type = 'XMPP'
-
- def disconnect(self, message=''):
- """
- Called on disconnection - disconnect callback is picked based on state of
- the client.
- """
- # to avoid recursive calls
- if self.ip_addresses:
- self._try_next_ip()
- return
- if self.disconnecting: return
-
- log.info('Disconnecting NBClient: %s' % message)
-
- sasl_failed = False
- if 'NonBlockingRoster' in self.__dict__:
- self.NonBlockingRoster.PlugOut()
- if 'NonBlockingBind' in self.__dict__:
- self.NonBlockingBind.PlugOut()
- if 'NonBlockingNonSASL' in self.__dict__:
- self.NonBlockingNonSASL.PlugOut()
- if 'SASL' in self.__dict__:
- if 'startsasl' in self.SASL.__dict__ and \
- self.SASL.startsasl == 'failure-in-process':
- sasl_failed = True
- self.SASL.startsasl = 'failure'
- self._on_start_sasl()
- else:
- self.SASL.PlugOut()
- if 'NonBlockingTCP' in self.__dict__:
- self.NonBlockingTCP.PlugOut()
- if 'NonBlockingHTTP' in self.__dict__:
- self.NonBlockingHTTP.PlugOut()
- if 'NonBlockingBOSH' in self.__dict__:
- self.NonBlockingBOSH.PlugOut()
- # FIXME: we never unplug dispatcher, only on next connect
- # See _xmpp_connect_machine and SASLHandler
-
- connected = self.connected
- stream_started = self.stream_started
-
- self.connected = ''
- self.stream_started = False
-
- self.disconnecting = True
-
- log.debug('Client disconnected..')
- # Don't call any callback when it's a SASL failure.
- # SASL handler is already called
- if connected == '' and not sasl_failed:
- # if we're disconnecting before connection to XMPP sever is opened,
- # we don't call disconnect handlers but on_connect_failure callback
- if self.proxy:
- # with proxy, we have different failure callback
- log.debug('calling on_proxy_failure cb')
- self.on_proxy_failure(reason=message)
- else:
- log.debug('calling on_connect_failure cb')
- self.on_connect_failure()
- elif not sasl_failed:
- # we are connected to XMPP server
- if not stream_started:
- # if error occur before XML stream was opened, e.g. no response on
- # init request, we call the on_connect_failure callback because
- # proper connection is not established yet and it's not a proxy
- # issue
- log.debug('calling on_connect_failure cb')
- self._caller.streamError = message
- self.on_connect_failure()
- else:
- # with open connection, we are calling the disconnect handlers
- for i in reversed(self.disconnect_handlers):
- log.debug('Calling disconnect handler %s' % i)
- i()
- self.disconnecting = False
-
- def connect(self, on_connect, on_connect_failure, hostname=None, port=5222,
- on_proxy_failure=None, on_stream_error_cb=None, proxy=None,
- secure_tuple=('plain', None, None)):
- """
- Open XMPP connection (open XML streams in both directions)
-
- :param on_connect: called after stream is successfully opened
- :param on_connect_failure: called when error occures during connection
- :param hostname: hostname of XMPP server from SRV request
- :param port: port number of XMPP server
- :param on_proxy_failure: called if error occurres during TCP connection to
- proxy server or during proxy connecting process
- :param proxy: dictionary with proxy data. It should contain at least
- values for keys 'host' and 'port' - connection details for proxy serve
- and optionally keys 'user' and 'pass' as proxy credentials
- :param secure_tuple: tuple of (desired connection type, cacerts, mycerts)
- connection type can be 'ssl' - TLS established after TCP connection,
- 'tls' - TLS established after negotiation with starttls, or 'plain'.
- cacerts, mycerts - see tls_nb.NonBlockingTLS constructor for more
- details
- """
- self.on_connect = on_connect
- self.on_connect_failure=on_connect_failure
- self.on_proxy_failure = on_proxy_failure
- self.on_stream_error_cb = on_stream_error_cb
- self.desired_security, self.cacerts, self.mycerts = secure_tuple
- self.Connection = None
- self.Port = port
- self.proxy = proxy
-
- if hostname:
- self.xmpp_hostname = hostname
- else:
- self.xmpp_hostname = self.Server
-
- # We only check for SSL here as for TLS we will first have to start a
- # PLAIN connection and negotiate TLS afterwards.
- # establish_tls will instruct transport to start secure connection
- # directly
- establish_tls = self.desired_security == 'ssl'
- certs = (self.cacerts, self.mycerts)
-
- proxy_dict = {}
- tcp_host = self.xmpp_hostname
- tcp_port = self.Port
-
- if proxy:
- # with proxies, client connects to proxy instead of directly to
- # XMPP server ((hostname, port))
- # tcp_host is hostname of machine used for socket connection
- # (DNS request will be done for proxy or BOSH CM hostname)
- tcp_host, tcp_port, proxy_user, proxy_pass = \
- transports_nb.get_proxy_data_from_dict(proxy)
-
- if proxy['type'] == 'bosh':
- # Setup BOSH transport
- self.socket = bosh.NonBlockingBOSH.get_instance(
- on_disconnect=self.disconnect,
- raise_event=self.raise_event,
- idlequeue=self.idlequeue,
- estabilish_tls=establish_tls,
- certs=certs,
- proxy_creds=(proxy_user, proxy_pass),
- xmpp_server=(self.xmpp_hostname, self.Port),
- domain=self.Server,
- bosh_dict=proxy)
- self.protocol_type = 'BOSH'
- self.wait_for_restart_response = \
- proxy['bosh_wait_for_restart_response']
- else:
- # http proxy
- proxy_dict['type'] = proxy['type']
- proxy_dict['xmpp_server'] = (self.xmpp_hostname, self.Port)
- proxy_dict['credentials'] = (proxy_user, proxy_pass)
-
- if not proxy or proxy['type'] != 'bosh':
- # Setup ordinary TCP transport
- self.socket = transports_nb.NonBlockingTCP.get_instance(
- on_disconnect=self.disconnect,
- raise_event=self.raise_event,
- idlequeue=self.idlequeue,
- estabilish_tls=establish_tls,
- certs=certs,
- proxy_dict=proxy_dict)
-
- # plug transport into client as self.Connection
- self.socket.PlugIn(self)
-
- self._resolve_hostname(
- hostname=tcp_host,
- port=tcp_port,
- on_success=self._try_next_ip)
-
- def _resolve_hostname(self, hostname, port, on_success):
- """
- Wrapper for getaddinfo call
-
- FIXME: getaddinfo blocks
- """
- try:
- self.ip_addresses = socket.getaddrinfo(hostname, port,
- socket.AF_UNSPEC, socket.SOCK_STREAM)
- except socket.gaierror, (errnum, errstr):
- self.disconnect(message='Lookup failure for %s:%s, hostname: %s - %s' %
- (self.Server, self.Port, hostname, errstr))
- else:
- on_success()
-
- def _try_next_ip(self, err_message=None):
- """
- Iterate over IP addresses tries to connect to it
- """
- if err_message:
- log.debug('While looping over DNS A records: %s' % err_message)
- if self.ip_addresses == []:
- msg = 'Run out of hosts for name %s:%s.' % (self.Server, self.Port)
- msg = msg + ' Error for last IP: %s' % err_message
- self.disconnect(msg)
- else:
- self.current_ip = self.ip_addresses.pop(0)
- self.socket.connect(
- conn_5tuple=self.current_ip,
- on_connect=lambda: self._xmpp_connect(),
- on_connect_failure=self._try_next_ip)
-
- def incoming_stream_version(self):
- """
- Get version of xml stream
- """
- if 'version' in self.Dispatcher.Stream._document_attrs:
- return self.Dispatcher.Stream._document_attrs['version']
- else:
- return None
-
- def _xmpp_connect(self, socket_type=None):
- """
- Start XMPP connecting process - open the XML stream. Is called after TCP
- connection is established or after switch to TLS when successfully
- negotiated with <starttls>.
- """
- # socket_type contains info which transport connection was established
- if not socket_type:
- if self.Connection.ssl_lib:
- # When ssl_lib is set we connected via SSL
- socket_type = 'ssl'
- else:
- # PLAIN is default
- socket_type = 'plain'
- self.connected = socket_type
- self._xmpp_connect_machine()
-
- def _xmpp_connect_machine(self, mode=None, data=None):
- """
- Finite automaton taking care of stream opening and features tag handling.
- Calls _on_stream_start when stream is started, and disconnect() on
- failure.
- """
- log.info('-------------xmpp_connect_machine() >> mode: %s, data: %s...' %
- (mode, str(data)[:20]))
-
- def on_next_receive(mode):
- """
- Set desired on_receive callback on transport based on the state of
- connect_machine.
- """
- log.info('setting %s on next receive' % mode)
- if mode is None:
- self.onreceive(None) # switch to Dispatcher.ProcessNonBlocking
- else:
- self.onreceive(lambda _data:self._xmpp_connect_machine(mode, _data))
-
- if not mode:
- # starting state
- if self.__dict__.has_key('Dispatcher'):
- self.Dispatcher.PlugOut()
- self.got_features = False
- dispatcher_nb.Dispatcher.get_instance().PlugIn(self)
- on_next_receive('RECEIVE_DOCUMENT_ATTRIBUTES')
-
- elif mode == 'FAILURE':
- self.disconnect('During XMPP connect: %s' % data)
-
- elif mode == 'RECEIVE_DOCUMENT_ATTRIBUTES':
- if data:
- self.Dispatcher.ProcessNonBlocking(data)
- self.ip_addresses = []
- if not hasattr(self, 'Dispatcher') or \
- self.Dispatcher.Stream._document_attrs is None:
- self._xmpp_connect_machine(
- mode='FAILURE',
- data='Error on stream open')
- return
-
- # if terminating stanza was received after init request then client gets
- # disconnected from bosh transport plugin and we have to end the stream
- # negotiating process straight away.
- # fixes #4657
- if not self.connected: return
-
- if self.incoming_stream_version() == '1.0':
- if not self.got_features:
- on_next_receive('RECEIVE_STREAM_FEATURES')
- else:
- log.info('got STREAM FEATURES in first recv')
- self._xmpp_connect_machine(mode='STREAM_STARTED')
- else:
- log.info('incoming stream version less than 1.0')
- self._xmpp_connect_machine(mode='STREAM_STARTED')
-
- elif mode == 'RECEIVE_STREAM_FEATURES':
- if data:
- # sometimes <features> are received together with document
- # attributes and sometimes on next receive...
- self.Dispatcher.ProcessNonBlocking(data)
- if self.got_see_other_host:
- log.info('got see-other-host')
- self.onreceive(None)
- self.on_stream_error_cb(self, self.got_see_other_host)
- elif not self.got_features:
- self._xmpp_connect_machine(
- mode='FAILURE',
- data='Missing <features> in 1.0 stream')
- else:
- log.info('got STREAM FEATURES in second recv')
- self._xmpp_connect_machine(mode='STREAM_STARTED')
-
- elif mode == 'STREAM_STARTED':
- self._on_stream_start()
-
- def _on_stream_start(self):
- """
- Called after XMPP stream is opened. TLS negotiation may follow if
- supported and desired.
- """
- self.stream_started = True
- if not hasattr(self, 'onreceive'):
- # we may already have been disconnected
- return
- self.onreceive(None)
-
- if self.connected == 'plain':
- if self.desired_security == 'plain':
- # if we want and have plain connection, we're done now
- self._on_connect()
- else:
- # try to negotiate TLS
- if self.incoming_stream_version() != '1.0':
- # if stream version is less than 1.0, we can't do more
- log.info('While connecting with type = "tls": stream version ' +
- 'is less than 1.0')
- self._on_connect()
- return
- if self.Dispatcher.Stream.features.getTag('starttls'):
- # Server advertises TLS support, start negotiation
- self.stream_started = False
- log.info('TLS supported by remote server. Requesting TLS start.')
- self._tls_negotiation_handler()
- else:
- log.info('While connecting with type = "tls": TLS unsupported ' +
- 'by remote server')
- self._on_connect()
-
- elif self.connected in ['ssl', 'tls']:
- self._on_connect()
- else:
- assert False, 'Stream opened for unsupported connection'
-
- def _tls_negotiation_handler(self, con=None, tag=None):
- """
- Take care of TLS negotioation with <starttls>
- """
- log.info('-------------tls_negotiaton_handler() >> tag: %s' % tag)
- if not con and not tag:
- # starting state when we send the <starttls>
- self.RegisterHandlerOnce('proceed', self._tls_negotiation_handler,
- xmlns=NS_TLS)
- self.RegisterHandlerOnce('failure', self._tls_negotiation_handler,
- xmlns=NS_TLS)
- self.send('<starttls xmlns="%s"/>' % NS_TLS)
- else:
- # we got <proceed> or <failure>
- if tag.getNamespace() != NS_TLS:
- self.disconnect('Unknown namespace: %s' % tag.getNamespace())
- return
- tagname = tag.getName()
- if tagname == 'failure':
- self.disconnect('TLS <failure> received: %s' % tag)
- return
- log.info('Got starttls proceed response. Switching to TLS/SSL...')
- # following call wouldn't work for BOSH transport but it doesn't matter
- # because <starttls> negotiation with BOSH is forbidden
- self.Connection.tls_init(
- on_succ = lambda: self._xmpp_connect(socket_type='tls'),
- on_fail = lambda: self.disconnect('error while etabilishing TLS'))
-
- def _on_connect(self):
- """
- Preceed call of on_connect callback
- """
- self.onreceive(None)
- self.on_connect(self, self.connected)
-
- def raise_event(self, event_type, data):
- """
- Raise event to connection instance. DATA_SENT and DATA_RECIVED events
- are used in XML console to show XMPP traffic
- """
- log.info('raising event from transport: :::::%s::::\n_____________\n%s\n_____________\n' % (event_type, data))
- if hasattr(self, 'Dispatcher'):
- self.Dispatcher.Event('', event_type, data)
-
-###############################################################################
-### follows code for authentication, resource bind, session and roster download
-###############################################################################
-
- def auth(self, user, password, resource='', sasl=True, on_auth=None):
- """
- Authenticate connnection and bind resource. If resource is not provided
- random one or library name used
-
- :param user: XMPP username
- :param password: XMPP password
- :param resource: resource that shall be used for auth/connecting
- :param sasl: Boolean indicating if SASL shall be used. (default: True)
- :param on_auth: Callback, called after auth. On auth failure, argument
- is None.
- """
- self._User, self._Password = user, password
- self._Resource, self._sasl = resource, sasl
- self.on_auth = on_auth
- self._on_doc_attrs()
- return
-
- def _on_old_auth(self, res):
- """
- Callback used by NON-SASL auth. On auth failure, res is None
- """
- if res:
- self.connected += '+old_auth'
- self.on_auth(self, 'old_auth')
- else:
- self.on_auth(self, None)
-
- def _on_sasl_auth(self, res):
- """
- Used internally. On auth failure, res is None
- """
- self.onreceive(None)
- if res:
- self.connected += '+sasl'
- self.on_auth(self, 'sasl')
- else:
- self.on_auth(self, None)
-
- def _on_doc_attrs(self):
- """
- Plug authentication objects and start auth
- """
- if self._sasl:
- auth_nb.SASL.get_instance(self._User, self._Password,
- self._on_start_sasl).PlugIn(self)
- if not hasattr(self, 'SASL'):
- return
- if not self._sasl or self.SASL.startsasl == 'not-supported':
- if not self._Resource:
- self._Resource = 'xmpppy'
- auth_nb.NonBlockingNonSASL.get_instance(self._User, self._Password,
- self._Resource, self._on_old_auth).PlugIn(self)
- return
- self.SASL.auth()
- return True
-
- def _on_start_sasl(self, data=None):
- """
- Callback used by SASL, called on each auth step
- """
- if data:
- self.Dispatcher.ProcessNonBlocking(data)
- if not 'SASL' in self.__dict__:
- # SASL is pluged out, possible disconnect
- return
- if self.SASL.startsasl == 'in-process':
- return
- self.onreceive(None)
- if self.SASL.startsasl == 'failure':
- # wrong user/pass, stop auth
- if 'SASL' in self.__dict__:
- self.SASL.PlugOut()
- self.connected = None # FIXME: is this intended? We use ''elsewhere
- self._on_sasl_auth(None)
- elif self.SASL.startsasl == 'success':
- nb_bind = auth_nb.NonBlockingBind.get_instance()
- sm = self._caller.sm
- if sm._owner and sm.resumption:
- nb_bind.resuming = True
- sm.set_owner(self)
- self.Dispatcher.sm = sm
- nb_bind.PlugIn(self)
- self.on_auth(self, 'sasl')
- return
-
- nb_bind.PlugIn(self)
- self.onreceive(self._on_auth_bind)
- return True
-
- def _on_auth_bind(self, data):
- # FIXME: Why use this callback and not bind directly?
- if data:
- self.Dispatcher.ProcessNonBlocking(data)
- if self.NonBlockingBind.bound is None:
- return
- self.NonBlockingBind.NonBlockingBind(self._Resource, self._on_sasl_auth)
- return True
-
- def initRoster(self, version=''):
- """
- Plug in the roster
- """
- if not self.__dict__.has_key('NonBlockingRoster'):
- return roster_nb.NonBlockingRoster.get_instance(version=version).PlugIn(self)
-
- def getRoster(self, on_ready=None, force=False):
- """
- Return the Roster instance, previously plugging it in and requesting
- roster from server if needed
- """
- if self.__dict__.has_key('NonBlockingRoster'):
- return self.NonBlockingRoster.getRoster(on_ready, force)
- return None
-
- def sendPresence(self, jid=None, typ=None, requestRoster=0):
- """
- Send some specific presence state. Can also request roster from server if
- according agrument is set
- """
- if requestRoster:
- # FIXME: used somewhere?
- roster_nb.NonBlockingRoster.get_instance().PlugIn(self)
- self.send(dispatcher_nb.Presence(to=jid, typ=typ))
-
-###############################################################################
-### following methods are moved from blocking client class of xmpppy
-###############################################################################
-
- def RegisterDisconnectHandler(self, handler):
- """
- Register handler that will be called on disconnect
- """
- self.disconnect_handlers.append(handler)
-
- def UnregisterDisconnectHandler(self, handler):
- """
- Unregister handler that is called on disconnect
- """
- self.disconnect_handlers.remove(handler)
-
- def DisconnectHandler(self):
- """
- Default disconnect handler. Just raises an IOError. If you choosed to use
- this class in your production client, override this method or at least
- unregister it.
- """
- raise IOError('Disconnected from server.')
-
- def get_connect_type(self):
- """
- Return connection state. F.e.: None / 'tls' / 'plain+non_sasl'
- """
- return self.connected
-
- def get_peerhost(self):
- """
- Gets the ip address of the account, from which is made connection to the
- server (e.g. IP and port of gajim's socket)
-
- We will create listening socket on the same ip
- """
- # FIXME: tuple (ip, port) is expected (and checked for) but port num is
- # useless
- return self.socket.peerhost
diff --git a/src/common/xmpp/dispatcher_nb.py b/src/common/xmpp/dispatcher_nb.py
deleted file mode 100644
index 5c4a7a1c9..000000000
--- a/src/common/xmpp/dispatcher_nb.py
+++ /dev/null
@@ -1,639 +0,0 @@
-## dispatcher_nb.py
-## based on dispatcher.py
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-## modified by Dimitur Kirov <dkirov@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-
-"""
-Main xmpp decision making logic. Provides library with methods to assign
-different handlers to different XMPP stanzas and namespaces
-"""
-
-import simplexml, sys, locale
-import re
-from xml.parsers.expat import ExpatError
-from plugin import PlugIn
-from protocol import (NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, Iq, Presence,
- Message, Protocol, Node, Error, ERR_FEATURE_NOT_IMPLEMENTED, StreamError)
-import logging
-log = logging.getLogger('gajim.c.x.dispatcher_nb')
-
-#: default timeout to wait for response for our id
-DEFAULT_TIMEOUT_SECONDS = 25
-outgoingID = 0
-
-XML_DECLARATION = '<?xml version=\'1.0\'?>'
-
-# FIXME: ugly
-class Dispatcher():
- """
- Why is this here - I needed to redefine Dispatcher for BOSH and easiest way
- was to inherit original Dispatcher (now renamed to XMPPDispatcher). Trouble
- is that reference used to access dispatcher instance is in Client attribute
- named by __class__.__name__ of the dispatcher instance .. long story short:
-
- I wrote following to avoid changing each client.Dispatcher.whatever() in xmpp
-
- If having two kinds of dispatcher will go well, I will rewrite the dispatcher
- references in other scripts
- """
-
- def PlugIn(self, client_obj, after_SASL=False, old_features=None):
- if client_obj.protocol_type == 'XMPP':
- XMPPDispatcher().PlugIn(client_obj)
- elif client_obj.protocol_type == 'BOSH':
- BOSHDispatcher().PlugIn(client_obj, after_SASL, old_features)
- else:
- assert False # should never be reached
-
- @classmethod
- def get_instance(cls, *args, **kwargs):
- """
- Factory Method for object creation
-
- Use this instead of directly initializing the class in order to make
- unit testing much easier.
- """
- return cls(*args, **kwargs)
-
-
-class XMPPDispatcher(PlugIn):
- """
- Handles XMPP stream and is the first who takes control over a fresh stanza
-
- Is plugged into NonBlockingClient but can be replugged to restart handled
- stream headers (used by SASL f.e.).
- """
-
- def __init__(self):
- PlugIn.__init__(self)
- self.handlers = {}
- self._expected = {}
- self._defaultHandler = None
- self._pendingExceptions = []
- self._eventHandler = None
- self._cycleHandlers = []
- self._exported_methods=[self.RegisterHandler, self.RegisterDefaultHandler,
- self.RegisterEventHandler, self.UnregisterCycleHandler,
- self.RegisterCycleHandler, self.RegisterHandlerOnce,
- self.UnregisterHandler, self.RegisterProtocol,
- self.SendAndWaitForResponse, self.SendAndCallForResponse,
- self.getAnID, self.Event, self.send]
-
- # Let the dispatcher know if there is support for stream management
- self.sm = None
-
- # \ufddo -> \ufdef range
- c = u'\ufdd0'
- r = c.encode('utf8')
- while (c < u'\ufdef'):
- c = unichr(ord(c) + 1)
- r += '|' + c.encode('utf8')
-
- # \ufffe-\uffff, \u1fffe-\u1ffff, ..., \u10fffe-\u10ffff
- c = u'\ufffe'
- r += '|' + c.encode('utf8')
- r += '|' + unichr(ord(c) + 1).encode('utf8')
- while (c < u'\U0010fffe'):
- c = unichr(ord(c) + 0x10000)
- r += '|' + c.encode('utf8')
- r += '|' + unichr(ord(c) + 1).encode('utf8')
-
- self.invalid_chars_re = re.compile(r)
-
- def getAnID(self):
- global outgoingID
- outgoingID += 1
- return repr(outgoingID)
-
- def dumpHandlers(self):
- """
- Return set of user-registered callbacks in it's internal format. Used
- within the library to carry user handlers set over Dispatcher replugins
- """
- return self.handlers
-
- def restoreHandlers(self, handlers):
- """
- Restore user-registered callbacks structure from dump previously obtained
- via dumpHandlers. Used within the library to carry user handlers set over
- Dispatcher replugins.
- """
- self.handlers = handlers
-
- def _init(self):
- """
- Register default namespaces/protocols/handlers. Used internally
- """
- # FIXME: inject dependencies, do not rely that they are defined by our
- # owner
- self.RegisterNamespace('unknown')
- self.RegisterNamespace(NS_STREAMS)
- self.RegisterNamespace(self._owner.defaultNamespace)
- self.RegisterProtocol('iq', Iq)
- self.RegisterProtocol('presence', Presence)
- self.RegisterProtocol('message', Message)
- self.RegisterDefaultHandler(self.returnStanzaHandler)
- self.RegisterEventHandler(self._owner._caller._event_dispatcher)
- self.on_responses = {}
-
- def plugin(self, owner):
- """
- Plug the Dispatcher instance into Client class instance and send initial
- stream header. Used internally
- """
- self._init()
- self._owner.lastErrNode = None
- self._owner.lastErr = None
- self._owner.lastErrCode = None
- if hasattr(self._owner, 'StreamInit'):
- self._owner.StreamInit()
- else:
- self.StreamInit()
-
- def plugout(self):
- """
- Prepare instance to be destructed
- """
- self.Stream.dispatch = None
- self.Stream.features = None
- self.Stream.destroy()
- self._owner = None
- self.Stream = None
-
- def StreamInit(self):
- """
- Send an initial stream header
- """
- self._owner.Connection.sendqueue = []
- self.Stream = simplexml.NodeBuilder()
- self.Stream.dispatch = self.dispatch
- self.Stream._dispatch_depth = 2
- self.Stream.stream_header_received = self._check_stream_start
- self.Stream.features = None
- self._metastream = Node('stream:stream')
- self._metastream.setNamespace(self._owner.Namespace)
- self._metastream.setAttr('version', '1.0')
- self._metastream.setAttr('xmlns:stream', NS_STREAMS)
- self._metastream.setAttr('to', self._owner.Server)
- if locale.getdefaultlocale()[0]:
- self._metastream.setAttr('xml:lang',
- locale.getdefaultlocale()[0].split('_')[0])
- self._owner.send("%s%s>" % (XML_DECLARATION, str(self._metastream)[:-2]))
-
- def _check_stream_start(self, ns, tag, attrs):
- if ns != NS_STREAMS or tag!='stream':
- raise ValueError('Incorrect stream start: (%s,%s). Terminating.'
- % (tag, ns))
-
- def replace_non_character(self, data):
- return re.sub(self.invalid_chars_re, u'\ufffd'.encode('utf-8'), data)
-
- def ProcessNonBlocking(self, data):
- """
- Check incoming stream for data waiting
-
- :param data: data received from transports/IO sockets
- :return:
- 1) length of processed data if some data were processed;
- 2) '0' string if no data were processed but link is alive;
- 3) 0 (zero) if underlying connection is closed.
- """
- # FIXME:
- # When an error occurs we disconnect the transport directly. Client's
- # disconnect method will never be called.
- # Is this intended?
- # also look at transports start_disconnect()
- data = self.replace_non_character(data)
- for handler in self._cycleHandlers:
- handler(self)
- if len(self._pendingExceptions) > 0:
- _pendingException = self._pendingExceptions.pop()
- raise _pendingException[0], _pendingException[1], _pendingException[2]
- try:
- self.Stream.Parse(data)
- # end stream:stream tag received
- if self.Stream and self.Stream.has_received_endtag():
- self._owner.disconnect(self.Stream.streamError)
- return 0
- except ExpatError:
- log.error('Invalid XML received from server. Forcing disconnect.')
- self._owner.Connection.disconnect()
- return 0
- except ValueError, e:
- log.debug('ValueError: %s' % str(e))
- self._owner.Connection.pollend()
- return 0
- if len(self._pendingExceptions) > 0:
- _pendingException = self._pendingExceptions.pop()
- raise _pendingException[0], _pendingException[1], _pendingException[2]
- if len(data) == 0:
- return '0'
- return len(data)
-
- def RegisterNamespace(self, xmlns, order='info'):
- """
- Create internal structures for newly registered namespace
-
- You can register handlers for this namespace afterwards. By default
- one namespace is already registered
- (jabber:client or jabber:component:accept depending on context.
- """
- log.debug('Registering namespace "%s"' % xmlns)
- self.handlers[xmlns] = {}
- self.RegisterProtocol('unknown', Protocol, xmlns=xmlns)
- self.RegisterProtocol('default', Protocol, xmlns=xmlns)
-
- def RegisterProtocol(self, tag_name, Proto, xmlns=None, order='info'):
- """
- Used to declare some top-level stanza name to dispatcher
-
- Needed to start registering handlers for such stanzas. Iq, message and
- presence protocols are registered by default.
- """
- if not xmlns:
- xmlns=self._owner.defaultNamespace
- log.debug('Registering protocol "%s" as %s(%s)' %(tag_name, Proto, xmlns))
- self.handlers[xmlns][tag_name] = {type:Proto, 'default':[]}
-
- def RegisterNamespaceHandler(self, xmlns, handler, typ='', ns='',
- makefirst=0, system=0):
- """
- Register handler for processing all stanzas for specified namespace
- """
- self.RegisterHandler('default', handler, typ, ns, xmlns, makefirst,
- system)
-
- def RegisterHandler(self, name, handler, typ='', ns='', xmlns=None,
- makefirst=False, system=False):
- """
- Register user callback as stanzas handler of declared type
-
- Callback arguments:
- dispatcher instance (for replying), incoming return of previous handlers.
- The callback must raise xmpp.NodeProcessed just before return if it wants
- to prevent other callbacks to be called with the same stanza as argument
- _and_, more importantly library from returning stanza to sender with error set.
-
- :param name: name of stanza. F.e. "iq".
- :param handler: user callback.
- :param typ: value of stanza's "type" attribute. If not specified any
- value will match
- :param ns: namespace of child that stanza must contain.
- :param makefirst: insert handler in the beginning of handlers list instead
- of adding it to the end. Note that more common handlers i.e. w/o "typ"
- and " will be called first nevertheless.
- :param system: call handler even if NodeProcessed Exception were raised
- already.
- """
- if not xmlns:
- xmlns=self._owner.defaultNamespace
- log.debug('Registering handler %s for "%s" type->%s ns->%s(%s)' %
- (handler, name, typ, ns, xmlns))
- if not typ and not ns:
- typ='default'
- if xmlns not in self.handlers:
- self.RegisterNamespace(xmlns, 'warn')
- if name not in self.handlers[xmlns]:
- self.RegisterProtocol(name, Protocol, xmlns, 'warn')
- if typ+ns not in self.handlers[xmlns][name]:
- self.handlers[xmlns][name][typ+ns]=[]
- if makefirst:
- self.handlers[xmlns][name][typ+ns].insert(0, {'func':handler,
- 'system':system})
- else:
- self.handlers[xmlns][name][typ+ns].append({'func':handler,
- 'system':system})
-
- def RegisterHandlerOnce(self, name, handler, typ='', ns='', xmlns=None,
- makefirst=0, system=0):
- """
- Unregister handler after first call (not implemented yet)
- """
- # FIXME Drop or implement
- if not xmlns:
- xmlns = self._owner.defaultNamespace
- self.RegisterHandler(name, handler, typ, ns, xmlns, makefirst, system)
-
- def UnregisterHandler(self, name, handler, typ='', ns='', xmlns=None):
- """
- Unregister handler. "typ" and "ns" must be specified exactly the same as
- with registering.
- """
- if not xmlns:
- xmlns = self._owner.defaultNamespace
- if not typ and not ns:
- typ='default'
- if xmlns not in self.handlers:
- return
- if name not in self.handlers[xmlns]:
- return
- if typ+ns not in self.handlers[xmlns][name]:
- return
- for pack in self.handlers[xmlns][name][typ+ns]:
- if pack['func'] == handler:
- try:
- self.handlers[xmlns][name][typ+ns].remove(pack)
- except ValueError:
- pass
-
- def RegisterDefaultHandler(self, handler):
- """
- Specify the handler that will be used if no NodeProcessed exception were
- raised. This is returnStanzaHandler by default.
- """
- self._defaultHandler = handler
-
- def RegisterEventHandler(self, handler):
- """
- Register handler that will process events. F.e. "FILERECEIVED" event. See
- common/connection: _event_dispatcher()
- """
- self._eventHandler = handler
-
- def returnStanzaHandler(self, conn, stanza):
- """
- Return stanza back to the sender with <feature-not-implemented/> error
- set
- """
- if stanza.getType() in ('get', 'set'):
- conn._owner.send(Error(stanza, ERR_FEATURE_NOT_IMPLEMENTED))
-
- def RegisterCycleHandler(self, handler):
- """
- Register handler that will be called on every Dispatcher.Process() call
- """
- if handler not in self._cycleHandlers:
- self._cycleHandlers.append(handler)
-
- def UnregisterCycleHandler(self, handler):
- """
- Unregister handler that will is called on every Dispatcher.Process() call
- """
- if handler in self._cycleHandlers:
- self._cycleHandlers.remove(handler)
-
- def Event(self, realm, event, data):
- """
- Raise some event
-
- :param realm: scope of event. Usually a namespace.
- :param event: the event itself. F.e. "SUCCESSFUL SEND".
- :param data: data that comes along with event. Depends on event.
- """
- if self._eventHandler:
- self._eventHandler(realm, event, data)
- else:
- log.warning('Received unhandled event: %s' % event)
-
- def dispatch(self, stanza, session=None, direct=0):
- """
- Main procedure that performs XMPP stanza recognition and calling
- apppropriate handlers for it. Called by simplexml
- """
- # FIXME: Where do we set session and direct. Why? What are those intended
- # to do?
-
- #log.info('dispatch called: stanza = %s, session = %s, direct= %s'
- # % (stanza, session, direct))
- if not session:
- session = self
- session.Stream._mini_dom = None
- name = stanza.getName()
-
- if name == 'features':
- self._owner.got_features = True
- session.Stream.features = stanza
- if name == 'error':
- if stanza.getTag('see-other-host'):
- self._owner.got_see_other_host = stanza
-
- xmlns = stanza.getNamespace()
-
- # log.info('in dispatch, getting ns for %s, and the ns is %s'
- # % (stanza, xmlns))
- if xmlns not in self.handlers:
- log.warn("Unknown namespace: " + xmlns)
- xmlns = 'unknown'
- # features stanza has been handled before
- if name not in self.handlers[xmlns]:
- if name != 'features':
- log.warn("Unknown stanza: " + name)
- else:
- log.debug("Got %s/%s stanza" % (xmlns, name))
- name='unknown'
- else:
- log.debug("Got %s/%s stanza" % (xmlns, name))
-
- if stanza.__class__.__name__ == 'Node':
- # FIXME: this cannot work
- stanza=self.handlers[xmlns][name][type](node=stanza)
-
- typ = stanza.getType()
- if not typ:
- typ = ''
- stanza.props = stanza.getProperties()
- ID = stanza.getID()
-
- # If server supports stream management
- if self.sm and self.sm.enabled and (stanza.getName() != 'r' and
- stanza.getName() != 'a' and stanza.getName() != 'enabled' and
- stanza.getName() != 'resumed'):
- # increments the number of stanzas that has been handled
- self.sm.in_h = self.sm.in_h + 1
- list_ = ['default'] # we will use all handlers:
- if typ in self.handlers[xmlns][name]:
- list_.append(typ) # from very common...
- for prop in stanza.props:
- if prop in self.handlers[xmlns][name]:
- list_.append(prop)
- if typ and typ+prop in self.handlers[xmlns][name]:
- list_.append(typ+prop) # ...to very particular
-
- chain = self.handlers[xmlns]['default']['default']
- for key in list_:
- if key:
- chain = chain + self.handlers[xmlns][name][key]
-
- if ID in session._expected:
- user = 0
- if isinstance(session._expected[ID], tuple):
- cb, args = session._expected[ID]
- log.debug("Expected stanza arrived. Callback %s(%s) found!" %
- (cb, args))
- try:
- cb(session,stanza,**args)
- except Exception, typ:
- if typ.__class__.__name__ != 'NodeProcessed':
- raise
- else:
- log.debug("Expected stanza arrived!")
- session._expected[ID] = stanza
- else:
- user = 1
- for handler in chain:
- if user or handler['system']:
- try:
- handler['func'](session, stanza)
- except Exception, typ:
- if typ.__class__.__name__ != 'NodeProcessed':
- self._pendingExceptions.insert(0, sys.exc_info())
- return
- user=0
- if user and self._defaultHandler:
- self._defaultHandler(session, stanza)
-
- def _WaitForData(self, data):
- """
- Internal wrapper around ProcessNonBlocking. Will check for
- """
- if data is None:
- return
- res = self.ProcessNonBlocking(data)
- # 0 result indicates that we have closed the connection, e.g.
- # we have released dispatcher, so self._owner has no methods
- if not res:
- return
- for (_id, _iq) in self._expected.items():
- if _iq is None:
- # If the expected Stanza would have arrived, ProcessNonBlocking
- # would have placed the reply stanza in there
- continue
- if _id in self.on_responses:
- if len(self._expected) == 1:
- self._owner.onreceive(None)
- resp, args = self.on_responses[_id]
- del self.on_responses[_id]
- if args is None:
- resp(_iq)
- else:
- resp(self._owner, _iq, **args)
- del self._expected[_id]
-
- def SendAndWaitForResponse(self, stanza, timeout=None, func=None, args=None):
- """
- Send stanza and wait for recipient's response to it. Will call transports
- on_timeout callback if response is not retrieved in time
-
- Be aware: Only timeout of latest call of SendAndWait is active.
- """
- if timeout is None:
- timeout = DEFAULT_TIMEOUT_SECONDS
- _waitid = self.send(stanza)
- if func:
- self.on_responses[_waitid] = (func, args)
- if timeout:
- self._owner.set_timeout(timeout)
- self._owner.onreceive(self._WaitForData)
- self._expected[_waitid] = None
- return _waitid
-
- def SendAndCallForResponse(self, stanza, func=None, args=None):
- """
- Put stanza on the wire and call back when recipient replies. Additional
- callback arguments can be specified in args
- """
- self.SendAndWaitForResponse(stanza, 0, func, args)
-
- def send(self, stanza, now=False):
- """
- Wrap transports send method when plugged into NonBlockingClient. Makes
- sure stanzas get ID and from tag.
- """
- ID = None
- if type(stanza) not in [type(''), type(u'')]:
- if isinstance(stanza, Protocol):
- ID = stanza.getID()
- if ID is None:
- stanza.setID(self.getAnID())
- ID = stanza.getID()
- if self._owner._registered_name and not stanza.getAttr('from'):
- stanza.setAttr('from', self._owner._registered_name)
-
- # If no ID then it is a whitespace
- if self.sm and self.sm.enabled and ID:
- self.sm.uqueue.append(stanza)
- self.sm.out_h = self.sm.out_h + 1
- if len(self.sm.uqueue) > self.sm.max_queue:
- self.sm.request_ack()
-
- self._owner.Connection.send(stanza, now)
- return ID
-
-
-class BOSHDispatcher(XMPPDispatcher):
-
- def PlugIn(self, owner, after_SASL=False, old_features=None):
- self.old_features = old_features
- self.after_SASL = after_SASL
- XMPPDispatcher.PlugIn(self, owner)
-
- def StreamInit(self):
- """
- Send an initial stream header
- """
- self.Stream = simplexml.NodeBuilder()
- self.Stream.dispatch = self.dispatch
- self.Stream._dispatch_depth = 2
- self.Stream.stream_header_received = self._check_stream_start
- self.Stream.features = self.old_features
-
- self._metastream = Node('stream:stream')
- self._metastream.setNamespace(self._owner.Namespace)
- self._metastream.setAttr('version', '1.0')
- self._metastream.setAttr('xmlns:stream', NS_STREAMS)
- self._metastream.setAttr('to', self._owner.Server)
- if locale.getdefaultlocale()[0]:
- self._metastream.setAttr('xml:lang',
- locale.getdefaultlocale()[0].split('_')[0])
-
- self.restart = True
- self._owner.Connection.send_init(after_SASL=self.after_SASL)
-
- def StreamTerminate(self):
- """
- Send a stream terminator
- """
- self._owner.Connection.send_terminator()
-
- def ProcessNonBlocking(self, data=None):
- if self.restart:
- fromstream = self._metastream
- fromstream.setAttr('from', fromstream.getAttr('to'))
- fromstream.delAttr('to')
- data = '%s%s>%s' % (XML_DECLARATION, str(fromstream)[:-2], data)
- self.restart = False
- return XMPPDispatcher.ProcessNonBlocking(self, data)
-
- def dispatch(self, stanza, session=None, direct=0):
- if stanza.getName() == 'body' and stanza.getNamespace() == NS_HTTP_BIND:
-
- stanza_attrs = stanza.getAttrs()
- if 'authid' in stanza_attrs:
- # should be only in init response
- # auth module expects id of stream in document attributes
- self.Stream._document_attrs['id'] = stanza_attrs['authid']
- self._owner.Connection.handle_body_attrs(stanza_attrs)
-
- children = stanza.getChildren()
- if children:
- for child in children:
- # if child doesn't have any ns specified, simplexml (or expat)
- # thinks it's of parent's (BOSH body) namespace, so we have to
- # rewrite it to jabber:client
- if child.getNamespace() == NS_HTTP_BIND:
- child.setNamespace(self._owner.defaultNamespace)
- XMPPDispatcher.dispatch(self, child, session, direct)
- else:
- XMPPDispatcher.dispatch(self, stanza, session, direct)
diff --git a/src/common/xmpp/features_nb.py b/src/common/xmpp/features_nb.py
deleted file mode 100644
index 9dd39082e..000000000
--- a/src/common/xmpp/features_nb.py
+++ /dev/null
@@ -1,218 +0,0 @@
-## features.py
-##
-## Copyright (C) 2003-2004 Alexey "Snake" Nezhdanov
-## Copyright (C) 2007 Julien Pivotto <roidelapluie@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-# $Id: features.py,v 1.22 2005/09/30 20:13:04 mikealbon Exp $
-
-"""
-Different stuff that wasn't worth separating it into modules
-(Registration, Privacy Lists, ...)
-"""
-
-from protocol import NS_REGISTER, NS_PRIVACY, NS_DATA, Iq, isResultNode, Node
-
-def _on_default_response(disp, iq, cb):
- def _on_response(resp):
- if isResultNode(resp):
- if cb:
- cb(True)
- elif cb:
- cb(False)
- disp.SendAndCallForResponse(iq, _on_response)
-
-###############################################################################
-### Registration
-###############################################################################
-
-REGISTER_DATA_RECEIVED = 'REGISTER DATA RECEIVED'
-
-def getRegInfo(disp, host, info={}, sync=True):
- """
- Get registration form from remote host. Info dict can be prefilled
- :param disp: plugged dispatcher instance
- :param info: dict, like {'username':'joey'}.
-
- See JEP-0077 for details.
- """
- iq=Iq('get', NS_REGISTER, to=host)
- for i in info.keys():
- iq.setTagData(i, info[i])
- if sync:
- disp.SendAndCallForResponse(iq, lambda resp:
- _ReceivedRegInfo(disp.Dispatcher, resp, host))
- else:
- disp.SendAndCallForResponse(iq, _ReceivedRegInfo, {'agent': host })
-
-def _ReceivedRegInfo(con, resp, agent):
- Iq('get', NS_REGISTER, to=agent)
- if not isResultNode(resp):
- error_msg = resp.getErrorMsg()
- con.Event(NS_REGISTER, REGISTER_DATA_RECEIVED, (agent, None, False, error_msg, ''))
- return
- tag=resp.getTag('query', namespace=NS_REGISTER)
- if not tag:
- error_msg = resp.getErrorMsg()
- con.Event(NS_REGISTER, REGISTER_DATA_RECEIVED, (agent, None, False, error_msg, ''))
- return
- df=tag.getTag('x', namespace=NS_DATA)
- if df:
- con.Event(NS_REGISTER, REGISTER_DATA_RECEIVED, (agent, df, True, '',
- tag))
- return
- df={}
- for i in resp.getQueryPayload():
- if not isinstance(i, Node):
- continue
- df[i.getName()] = i.getData()
- con.Event(NS_REGISTER, REGISTER_DATA_RECEIVED, (agent, df, False, '', ''))
-
-def register(disp, host, info, cb, args=None):
- """
- Perform registration on remote server with provided info
-
- If registration fails you can get additional info from the dispatcher's
- owner attributes lastErrNode, lastErr and lastErrCode.
- """
- iq=Iq('set', NS_REGISTER, to=host)
- if not isinstance(info, dict):
- info=info.asDict()
- for i in info.keys():
- iq.setTag('query').setTagData(i, info[i])
- disp.SendAndCallForResponse(iq, cb, args)
-
-def unregister(disp, host, cb):
- """
- Unregisters with host (permanently removes account). Returns true on success
- """
- iq = Iq('set', NS_REGISTER, to=host, payload=[Node('remove')])
- _on_default_response(disp, iq, cb)
-
-def changePasswordTo(disp, newpassword, host=None, cb = None):
- """
- Changes password on specified or current (if not specified) server. Returns
- true on success.
- """
- if not host:
- host = disp._owner.Server
- iq = Iq('set', NS_REGISTER, to=host, payload=[Node('username',
- payload=[disp._owner.Server]), Node('password', payload=[newpassword])])
- _on_default_response(disp, iq, cb)
-
-###############################################################################
-### Privacy List
-###############################################################################
-
-PL_TYPE_JID = 'jid'
-PL_TYPE_GROUP = 'group'
-PL_TYPE_SUBC = 'subscription'
-PL_ACT_ALLOW = 'allow'
-PL_ACT_DENY = 'deny'
-
-PRIVACY_LISTS_RECEIVED = 'PRIVACY LISTS RECEIVED'
-PRIVACY_LIST_RECEIVED = 'PRIVACY LIST RECEIVED'
-PRIVACY_LISTS_ACTIVE_DEFAULT = 'PRIVACY LISTS ACTIVE DEFAULT'
-
-def getPrivacyLists(disp):
- """
- Request privacy lists from connected server. Returns dictionary of existing
- lists on success.
- """
- iq = Iq('get', NS_PRIVACY)
- def _on_response(resp):
- dict_ = {'lists': []}
- if not isResultNode(resp):
- disp.Event(NS_PRIVACY, PRIVACY_LISTS_RECEIVED, (False))
- return
- for list_ in resp.getQueryPayload():
- if list_.getName()=='list':
- dict_['lists'].append(list_.getAttr('name'))
- else:
- dict_[list_.getName()]=list_.getAttr('name')
- disp.Event(NS_PRIVACY, PRIVACY_LISTS_RECEIVED, (dict_))
- disp.SendAndCallForResponse(iq, _on_response)
-
-def getActiveAndDefaultPrivacyLists(disp):
- iq = Iq('get', NS_PRIVACY)
- def _on_response(resp):
- dict_ = {'active': '', 'default': ''}
- if not isResultNode(resp):
- disp.Event(NS_PRIVACY, PRIVACY_LISTS_ACTIVE_DEFAULT, (False))
- return
- for list_ in resp.getQueryPayload():
- if list_.getName() == 'active':
- dict_['active'] = list_.getAttr('name')
- elif list_.getName() == 'default':
- dict_['default'] = list_.getAttr('name')
- disp.Event(NS_PRIVACY, PRIVACY_LISTS_ACTIVE_DEFAULT, (dict_))
- disp.SendAndCallForResponse(iq, _on_response)
-
-def getPrivacyList(disp, listname):
- """
- Request specific privacy list listname. Returns list of XML nodes (rules)
- taken from the server responce.
- """
- def _on_response(resp):
- if not isResultNode(resp):
- disp.Event(NS_PRIVACY, PRIVACY_LIST_RECEIVED, (False))
- return
- disp.Event(NS_PRIVACY, PRIVACY_LIST_RECEIVED, (resp))
- iq = Iq('get', NS_PRIVACY, payload=[Node('list', {'name': listname})])
- disp.SendAndCallForResponse(iq, _on_response)
-
-def setActivePrivacyList(disp, listname=None, typ='active', cb=None):
- """
- Switch privacy list 'listname' to specified type. By default the type is
- 'active'. Returns true on success.
- """
- if listname:
- attrs={'name':listname}
- else:
- attrs={}
- iq = Iq('set', NS_PRIVACY, payload=[Node(typ, attrs)])
- _on_default_response(disp, iq, cb)
-
-def setDefaultPrivacyList(disp, listname=None):
- """
- Set the default privacy list as 'listname'. Returns true on success
- """
- return setActivePrivacyList(disp, listname, 'default')
-
-def setPrivacyList(disp, listname, tags):
- """
- Set the ruleset
-
- 'list' should be the simpleXML node formatted according to RFC 3921
- (XMPP-IM) I.e. Node('list',{'name':listname},payload=[...]).
-
- Returns true on success.
- """
- iq = Iq('set', NS_PRIVACY, xmlns = '')
- list_query = iq.getTag('query').setTag('list', {'name': listname})
- for item in tags:
- if 'type' in item and 'value' in item:
- item_tag = list_query.setTag('item', {'action': item['action'],
- 'order': item['order'], 'type': item['type'],
- 'value': item['value']})
- else:
- item_tag = list_query.setTag('item', {'action': item['action'],
- 'order': item['order']})
- if 'child' in item:
- for child_tag in item['child']:
- item_tag.setTag(child_tag)
- _on_default_response(disp, iq, None)
-
-def delPrivacyList(disp, listname, cb=None):
- ''' Deletes privacy list 'listname'. Returns true on success. '''
- iq = Iq('set', NS_PRIVACY, payload=[Node('list', {'name':listname})])
- _on_default_response(disp, iq, cb)
diff --git a/src/common/xmpp/idlequeue.py b/src/common/xmpp/idlequeue.py
deleted file mode 100644
index 86e33418f..000000000
--- a/src/common/xmpp/idlequeue.py
+++ /dev/null
@@ -1,550 +0,0 @@
-## idlequeue.py
-##
-## Copyright (C) 2006 Dimitur Kirov <dkirov@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-
-"""
-Idlequeues are Gajim's network heartbeat. Transports can be plugged as idle
-objects and be informed about possible IO
-"""
-
-import os
-import select
-import logging
-log = logging.getLogger('gajim.c.x.idlequeue')
-
-# needed for get_idleqeue
-try:
- import gobject
- HAVE_GOBJECT = True
-except ImportError:
- HAVE_GOBJECT = False
-
-# needed for idlecommand
-if os.name == 'nt':
- from subprocess import * # python24 only. we ask this for Windows
-elif os.name == 'posix':
- import fcntl
-
-FLAG_WRITE = 20 # write only
-FLAG_READ = 19 # read only
-FLAG_READ_WRITE = 23 # read and write
-FLAG_CLOSE = 16 # wait for close
-
-PENDING_READ = 3 # waiting read event
-PENDING_WRITE = 4 # waiting write event
-IS_CLOSED = 16 # channel closed
-
-
-def get_idlequeue():
- """
- Get an appropriate idlequeue
- """
- if os.name == 'nt':
- # gobject.io_add_watch does not work on windows
- return SelectIdleQueue()
- else:
- if HAVE_GOBJECT:
- # Gajim's default Idlequeue
- return GlibIdleQueue()
- else:
- # GUI less implementation
- return SelectIdleQueue()
-
-
-class IdleObject:
- """
- Idle listener interface. Listed methods are called by IdleQueue.
- """
-
- def __init__(self):
- self.fd = -1 #: filedescriptor, must be unique for each IdleObject
-
- def pollend(self):
- """
- Called on stream failure
- """
- pass
-
- def pollin(self):
- """
- Called on new read event
- """
- pass
-
- def pollout(self):
- """
- Called on new write event (connect in sockets is a pollout)
- """
- pass
-
- def read_timeout(self):
- """
- Called when timeout happened
- """
- pass
-
-
-class IdleCommand(IdleObject):
- """
- Can be subclassed to execute commands asynchronously by the idlequeue.
- Result will be optained via file descriptor of created pipe
- """
-
- def __init__(self, on_result):
- IdleObject.__init__(self)
- # how long (sec.) to wait for result ( 0 - forever )
- # it is a class var, instead of a constant and we can override it.
- self.commandtimeout = 0
- # when we have some kind of result (valid, ot not) we call this handler
- self.result_handler = on_result
- # if it is True, we can safetely execute the command
- self.canexecute = True
- self.idlequeue = None
- self.result =''
-
- def set_idlequeue(self, idlequeue):
- self.idlequeue = idlequeue
-
- def _return_result(self):
- if self.result_handler:
- self.result_handler(self.result)
- self.result_handler = None
-
- def _compose_command_args(self):
- return ['echo', 'da']
-
- def _compose_command_line(self):
- """
- Return one line representation of command and its arguments
- """
- return reduce(lambda left, right: left + ' ' + right,
- self._compose_command_args())
-
- def wait_child(self):
- if self.pipe.poll() is None:
- # result timeout
- if self.endtime < self.idlequeue.current_time():
- self._return_result()
- self.pipe.stdout.close()
- self.pipe.stdin.close()
- else:
- # child is still active, continue to wait
- self.idlequeue.set_alarm(self.wait_child, 0.1)
- else:
- # child has quit
- self.result = self.pipe.stdout.read()
- self._return_result()
- self.pipe.stdout.close()
- self.pipe.stdin.close()
-
- def start(self):
- if not self.canexecute:
- self.result = ''
- self._return_result()
- return
- if os.name == 'nt':
- self._start_nt()
- elif os.name == 'posix':
- self._start_posix()
-
- def _start_nt(self):
- # if gajim is started from noninteraactive shells stdin is closed and
- # cannot be forwarded, so we have to keep it open
- self.pipe = Popen(self._compose_command_args(), stdout=PIPE,
- bufsize = 1024, shell = True, stderr = STDOUT, stdin = PIPE)
- if self.commandtimeout >= 0:
- self.endtime = self.idlequeue.current_time() + self.commandtimeout
- self.idlequeue.set_alarm(self.wait_child, 0.1)
-
- def _start_posix(self):
- self.pipe = os.popen(self._compose_command_line())
- self.fd = self.pipe.fileno()
- fcntl.fcntl(self.pipe, fcntl.F_SETFL, os.O_NONBLOCK)
- self.idlequeue.plug_idle(self, False, True)
- if self.commandtimeout >= 0:
- self.idlequeue.set_read_timeout(self.fd, self.commandtimeout)
-
- def end(self):
- self.idlequeue.unplug_idle(self.fd)
- try:
- self.pipe.close()
- except:
- pass
-
- def pollend(self):
- self.idlequeue.remove_timeout(self.fd)
- self.end()
- self._return_result()
-
- def pollin(self):
- try:
- res = self.pipe.read()
- except Exception, e:
- res = ''
- if res == '':
- return self.pollend()
- else:
- self.result += res
-
- def read_timeout(self):
- self.end()
- self._return_result()
-
-
-class IdleQueue:
- """
- IdleQueue provide three distinct time based features. Uses select.poll()
-
- 1. Alarm timeout: Execute a callback after foo seconds
- 2. Timeout event: Call read_timeout() of an plugged object if a timeout
- has been set, but not removed in time.
- 3. Check file descriptor of plugged objects for read, write and error
- events
- """
-
- # (timeout, boolean)
- # Boolean is True if timeout is specified in seconds, False means miliseconds
- PROCESS_TIMEOUT = (100, False)
-
- def __init__(self):
- self.queue = {}
-
- # when there is a timeout it executes obj.read_timeout()
- # timeout is not removed automatically!
- # {fd1: {timeout1: func1, timeout2: func2}}
- # timout are unique (timeout1 must be != timeout2)
- # If func1 is None, read_time function is called
- self.read_timeouts = {}
-
- # cb, which are executed after XX sec., alarms are removed automatically
- self.alarms = {}
- self._init_idle()
-
- def _init_idle(self):
- """
- Hook method for subclassed. Will be called by __init__
- """
- self.selector = select.poll()
-
- def set_alarm(self, alarm_cb, seconds):
- """
- Set up a new alarm. alarm_cb will be called after specified seconds.
- """
- alarm_time = self.current_time() + seconds
- # almost impossible, but in case we have another alarm_cb at this time
- if alarm_time in self.alarms:
- self.alarms[alarm_time].append(alarm_cb)
- else:
- self.alarms[alarm_time] = [alarm_cb]
- return alarm_time
-
- def remove_alarm(self, alarm_cb, alarm_time):
- """
- Remove alarm callback alarm_cb scheduled on alarm_time. Returns True if
- it was removed sucessfully, otherwise False
- """
- if not alarm_time in self.alarms:
- return False
- i = -1
- for i in range(len(self.alarms[alarm_time])):
- # let's not modify the list inside the loop
- if self.alarms[alarm_time][i] is alarm_cb:
- break
- if i != -1:
- del self.alarms[alarm_time][i]
- if self.alarms[alarm_time] == []:
- del self.alarms[alarm_time]
- return True
- else:
- return False
-
- def remove_timeout(self, fd, timeout=None):
- """
- Remove the read timeout
- """
- log.info('read timeout removed for fd %s' % fd)
- if fd in self.read_timeouts:
- if timeout:
- if timeout in self.read_timeouts[fd]:
- del(self.read_timeouts[fd][timeout])
- if len(self.read_timeouts[fd]) == 0:
- del(self.read_timeouts[fd])
- else:
- del(self.read_timeouts[fd])
-
- def set_read_timeout(self, fd, seconds, func=None):
- """
- Seta a new timeout. If it is not removed after specified seconds,
- func or obj.read_timeout() will be called
-
- A filedescriptor fd can have several timeouts.
- """
- log_txt = 'read timeout set for fd %s on %s seconds' % (fd, seconds)
- if func:
- log_txt += ' with function ' + str(func)
- log.info(log_txt)
- timeout = self.current_time() + seconds
- if fd in self.read_timeouts:
- self.read_timeouts[fd][timeout] = func
- else:
- self.read_timeouts[fd] = {timeout: func}
-
- def _check_time_events(self):
- """
- Execute and remove alarm callbacks and execute func() or read_timeout()
- for plugged objects if specified time has ellapsed
- """
- current_time = self.current_time()
-
- for fd, timeouts in self.read_timeouts.items():
- if fd not in self.queue:
- self.remove_timeout(fd)
- continue
- for timeout, func in timeouts.items():
- if timeout > current_time:
- continue
- if func:
- log.debug('Calling %s for fd %s' % (func, fd))
- func()
- else:
- log.debug('Calling read_timeout for fd %s' % fd)
- self.queue[fd].read_timeout()
- self.remove_timeout(fd, timeout)
-
- times = self.alarms.keys()
- for alarm_time in times:
- if alarm_time > current_time:
- continue
- if alarm_time in self.alarms:
- for callback in self.alarms[alarm_time]:
- callback()
- if alarm_time in self.alarms:
- del(self.alarms[alarm_time])
-
- def plug_idle(self, obj, writable=True, readable=True):
- """
- Plug an IdleObject into idlequeue. Filedescriptor fd must be set
-
- :param obj: the IdleObject
- :param writable: True if obj has data to sent
- :param readable: True if obj expects data to be reiceived
- """
- if obj.fd == -1:
- return
- if obj.fd in self.queue:
- self.unplug_idle(obj.fd)
- self.queue[obj.fd] = obj
- if writable:
- if not readable:
- flags = FLAG_WRITE
- else:
- flags = FLAG_READ_WRITE
- else:
- if readable:
- flags = FLAG_READ
- else:
- # when we paused a FT, we expect only a close event
- flags = FLAG_CLOSE
- self._add_idle(obj.fd, flags)
-
- def _add_idle(self, fd, flags):
- """
- Hook method for subclasses, called by plug_idle
- """
- self.selector.register(fd, flags)
-
- def unplug_idle(self, fd):
- """
- Remove plugged IdleObject, specified by filedescriptor fd
- """
- if fd in self.queue:
- del(self.queue[fd])
- self._remove_idle(fd)
-
- def current_time(self):
- from time import time
- return time()
-
- def _remove_idle(self, fd):
- """
- Hook method for subclassed, called by unplug_idle
- """
- self.selector.unregister(fd)
-
- def _process_events(self, fd, flags):
- obj = self.queue.get(fd)
- if obj is None:
- self.unplug_idle(fd)
- return False
-
- read_write = False
- if flags & PENDING_READ:
- #print 'waiting read on %d, flags are %d' % (fd, flags)
- obj.pollin()
- read_write = True
-
- elif flags & PENDING_WRITE and not flags & IS_CLOSED:
- obj.pollout()
- read_write = True
-
- if flags & IS_CLOSED:
- # io error, don't expect more events
- self.remove_timeout(obj.fd)
- self.unplug_idle(obj.fd)
- obj.pollend()
- return False
-
- if read_write:
- return True
- return False
-
- def process(self):
- """
- Process idlequeue. Check for any pending timeout or alarm events. Call
- IdleObjects on possible and requested read, write and error events on
- their file descriptors
-
- Call this in regular intervals.
- """
- if not self.queue:
- # check for timeouts/alert also when there are no active fds
- self._check_time_events()
- return True
- try:
- waiting_descriptors = self.selector.poll(0)
- except select.error, e:
- waiting_descriptors = []
- if e[0] != 4: # interrupt
- raise
- for fd, flags in waiting_descriptors:
- self._process_events(fd, flags)
- self._check_time_events()
- return True
-
-
-class SelectIdleQueue(IdleQueue):
- """
- Extends IdleQueue to use select.select() for polling
-
- This class exisists for the sake of gtk2.8 on windows, which doesn't seem to
- support io_add_watch properly (yet)
- """
-
- def _init_idle(self):
- """
- Create a dict, which maps file/pipe/sock descriptor to glib event id
- """
- self.read_fds = {}
- self.write_fds = {}
- self.error_fds = {}
-
- def _add_idle(self, fd, flags):
- """
- This method is called when we plug a new idle object. Remove descriptor
- to read/write/error lists, according flags
- """
- if flags & 3:
- self.read_fds[fd] = fd
- if flags & 4:
- self.write_fds[fd] = fd
- self.error_fds[fd] = fd
-
- def _remove_idle(self, fd):
- """
- This method is called when we unplug a new idle object. Remove descriptor
- from read/write/error lists
- """
- if fd in self.read_fds:
- del(self.read_fds[fd])
- if fd in self.write_fds:
- del(self.write_fds[fd])
- if fd in self.error_fds:
- del(self.error_fds[fd])
-
- def process(self):
- if not self.write_fds and not self.read_fds:
- self._check_time_events()
- return True
- try:
- waiting_descriptors = select.select(self.read_fds.keys(),
- self.write_fds.keys(), self.error_fds.keys(), 0)
- except select.error, e:
- waiting_descriptors = ((), (), ())
- if e[0] != 4: # interrupt
- raise
- for fd in waiting_descriptors[0]:
- q = self.queue.get(fd)
- if q:
- q.pollin()
- for fd in waiting_descriptors[1]:
- q = self.queue.get(fd)
- if q:
- q.pollout()
- for fd in waiting_descriptors[2]:
- q = self.queue.get(fd)
- if q:
- q.pollend()
- self._check_time_events()
- return True
-
-
-class GlibIdleQueue(IdleQueue):
- """
- Extends IdleQueue to use glib io_add_wath, instead of select/poll In another
- 'non gui' implementation of Gajim IdleQueue can be used safetly
- """
-
- # (timeout, boolean)
- # Boolean is True if timeout is specified in seconds, False means miliseconds
- PROCESS_TIMEOUT = (2, True)
-
- def _init_idle(self):
- """
- Creates a dict, which maps file/pipe/sock descriptor to glib event id
- """
- self.events = {}
- # time() is already called in glib, we just get the last value
- # overrides IdleQueue.current_time()
- self.current_time = gobject.get_current_time
-
- def _add_idle(self, fd, flags):
- """
- This method is called when we plug a new idle object. Start listening for
- events from fd
- """
- res = gobject.io_add_watch(fd, flags, self._process_events,
- priority=gobject.PRIORITY_LOW)
- # store the id of the watch, so that we can remove it on unplug
- self.events[fd] = res
-
- def _process_events(self, fd, flags):
- try:
- return IdleQueue._process_events(self, fd, flags)
- except Exception:
- self._remove_idle(fd)
- self._add_idle(fd, flags)
- raise
-
- def _remove_idle(self, fd):
- """
- This method is called when we unplug a new idle object. Stop listening
- for events from fd
- """
- if not fd in self.events:
- return
- gobject.source_remove(self.events[fd])
- del(self.events[fd])
-
- def process(self):
- self._check_time_events()
diff --git a/src/common/xmpp/plugin.py b/src/common/xmpp/plugin.py
deleted file mode 100644
index 5ef82c931..000000000
--- a/src/common/xmpp/plugin.py
+++ /dev/null
@@ -1,96 +0,0 @@
-## plugin.py
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-# $Id: client.py,v 1.52 2006/01/02 19:40:55 normanr Exp $
-
-"""
-Provides PlugIn class functionality to develop extentions for xmpppy
-"""
-
-import logging
-log = logging.getLogger('gajim.c.x.plugin')
-
-class PlugIn:
- """
- Abstract xmpppy plugin infrastructure code, providing plugging in/out and
- debugging functionality
-
- Inherit to develop pluggable objects. No code change on the owner class
- required (the object where we plug into)
-
- For every instance of PlugIn class the 'owner' is the class in what the plug
- was plugged.
- """
-
- def __init__(self):
- self._exported_methods=[]
-
- def PlugIn(self, owner):
- """
- Attach to owner and register ourself and our _exported_methods in it.
- If defined by a subclass, call self.plugin(owner) to execute hook
- code after plugging
- """
- self._owner=owner
- log.info('Plugging %s __INTO__ %s' % (self, self._owner))
- if self.__class__.__name__ in owner.__dict__:
- log.debug('Plugging ignored: another instance already plugged.')
- return
- self._old_owners_methods=[]
- for method in self._exported_methods:
- if method.__name__ in owner.__dict__:
- self._old_owners_methods.append(owner.__dict__[method.__name__])
- owner.__dict__[method.__name__]=method
- if self.__class__.__name__.endswith('Dispatcher'):
- # FIXME: I need BOSHDispatcher or XMPPDispatcher on .Dispatcher
- # there must be a better way..
- owner.__dict__['Dispatcher']=self
- else:
- owner.__dict__[self.__class__.__name__]=self
-
- # Execute hook
- if hasattr(self, 'plugin'):
- return self.plugin(owner)
-
- def PlugOut(self):
- """
- Unregister our _exported_methods from owner and detach from it.
- If defined by a subclass, call self.plugout() after unplugging to execute
- hook code
- """
- log.info('Plugging %s __OUT__ of %s.' % (self, self._owner))
- for method in self._exported_methods:
- del self._owner.__dict__[method.__name__]
- for method in self._old_owners_methods:
- self._owner.__dict__[method.__name__]=method
- # FIXME: Dispatcher workaround
- if self.__class__.__name__.endswith('Dispatcher'):
- del self._owner.__dict__['Dispatcher']
- else:
- del self._owner.__dict__[self.__class__.__name__]
- # Execute hook
- if hasattr(self, 'plugout'):
- return self.plugout()
- del self._owner
-
- @classmethod
- def get_instance(cls, *args, **kwargs):
- """
- Factory Method for object creation
-
- Use this instead of directly initializing the class in order to make
- unit testing easier. For testing, this method can be patched to inject
- mock objects.
- """
- return cls(*args, **kwargs)
diff --git a/src/common/xmpp/protocol.py b/src/common/xmpp/protocol.py
deleted file mode 100644
index d4c5fb254..000000000
--- a/src/common/xmpp/protocol.py
+++ /dev/null
@@ -1,1489 +0,0 @@
-## protocol.py
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-# $Id: protocol.py,v 1.52 2006/01/09 22:08:57 normanr Exp $
-
-"""
-Protocol module contains tools that are needed for processing of xmpp-related
-data structures, including jabber-objects like JID or different stanzas and
-sub- stanzas) handling routines
-"""
-
-from simplexml import Node, NodeBuilder
-import time
-import string
-import hashlib
-
-def ascii_upper(s):
- trans_table = string.maketrans(string.ascii_lowercase,
- string.ascii_uppercase)
- return s.translate(trans_table)
-
-NS_ACTIVITY = 'http://jabber.org/protocol/activity' # XEP-0108
-NS_ADDRESS = 'http://jabber.org/protocol/address' # XEP-0033
-NS_AGENTS = 'jabber:iq:agents'
-NS_AMP = 'http://jabber.org/protocol/amp'
-NS_AMP_ERRORS = NS_AMP + '#errors'
-NS_ARCHIVE = 'urn:xmpp:archive' # XEP-0136
-NS_ARCHIVE_AUTO = NS_ARCHIVE + ':auto' # XEP-0136
-NS_ARCHIVE_MANAGE = NS_ARCHIVE + ':manage' # XEP-0136
-NS_ARCHIVE_MANUAL = NS_ARCHIVE + ':manual' # XEP-0136
-NS_ARCHIVE_PREF = NS_ARCHIVE + ':pref'
-NS_ATOM = 'http://www.w3.org/2005/Atom'
-NS_ATTENTION = 'urn:xmpp:attention:0' # XEP-0224
-NS_AUTH = 'jabber:iq:auth'
-NS_AVATAR = 'http://www.xmpp.org/extensions/xep-0084.html#ns-metadata'
-NS_BIND = 'urn:ietf:params:xml:ns:xmpp-bind'
-NS_BOB = 'urn:xmpp:bob' # XEP-0231
-NS_BOOKMARKS = 'storage:bookmarks' # XEP-0048
-NS_BROWSE = 'jabber:iq:browse'
-NS_BROWSING = 'http://jabber.org/protocol/browsing' # XEP-0195
-NS_BYTESTREAM = 'http://jabber.org/protocol/bytestreams' # XEP-0065
-NS_CAPS = 'http://jabber.org/protocol/caps' # XEP-0115
-NS_CAPTCHA = 'urn:xmpp:captcha' # XEP-0158
-NS_CARBONS = 'urn:xmpp:carbons:1' # XEP-0280
-NS_CHATSTATES = 'http://jabber.org/protocol/chatstates' # XEP-0085
-NS_CHATTING = 'http://jabber.org/protocol/chatting' # XEP-0194
-NS_CLIENT = 'jabber:client'
-NS_CONDITIONS = 'urn:xmpp:muc:conditions:0' # XEP-0306
-NS_COMMANDS = 'http://jabber.org/protocol/commands'
-NS_COMPONENT_ACCEPT = 'jabber:component:accept'
-NS_COMPONENT_1 = 'http://jabberd.jabberstudio.org/ns/component/1.0'
-NS_COMPRESS = 'http://jabber.org/protocol/compress' # XEP-0138
-NS_CONFERENCE = 'jabber:x:conference'
-NS_DATA = 'jabber:x:data' # XEP-0004
-NS_DATA_MEDIA = 'urn:xmpp:media-element' # XEP-0221
-NS_DELAY = 'jabber:x:delay'
-NS_DELAY2 = 'urn:xmpp:delay'
-NS_DIALBACK = 'jabber:server:dialback'
-NS_DISCO = 'http://jabber.org/protocol/disco'
-NS_DISCO_INFO = NS_DISCO + '#info'
-NS_DISCO_ITEMS = NS_DISCO + '#items'
-NS_ENCRYPTED = 'jabber:x:encrypted' # XEP-0027
-NS_ESESSION = 'http://www.xmpp.org/extensions/xep-0116.html#ns'
-NS_ESESSION_INIT = 'http://www.xmpp.org/extensions/xep-0116.html#ns-init' # XEP-0116
-NS_EVENT = 'jabber:x:event' # XEP-0022
-NS_FEATURE = 'http://jabber.org/protocol/feature-neg'
-NS_FILE = 'http://jabber.org/protocol/si/profile/file-transfer' # XEP-0096
-NS_FORWARD = 'urn:xmpp:forward:0' # XEP-0297
-NS_GAMING = 'http://jabber.org/protocol/gaming' # XEP-0196
-NS_GATEWAY = 'jabber:iq:gateway' # XEP-0100
-NS_GEOLOC = 'http://jabber.org/protocol/geoloc' # XEP-0080
-NS_GROUPCHAT = 'gc-1.0'
-NS_HTTP_AUTH = 'http://jabber.org/protocol/http-auth' # XEP-0070
-NS_HTTP_BIND = 'http://jabber.org/protocol/httpbind' # XEP-0124
-NS_IBB = 'http://jabber.org/protocol/ibb'
-NS_INVISIBLE = 'presence-invisible' # Jabberd2
-NS_IQ = 'iq' # Jabberd2
-NS_JINGLE ='urn:xmpp:jingle:1' # XEP-0166
-NS_JINGLE_ERRORS = 'urn:xmpp:jingle:errors:1' # XEP-0166
-NS_JINGLE_RTP = 'urn:xmpp:jingle:apps:rtp:1' # XEP-0167
-NS_JINGLE_RTP_AUDIO = 'urn:xmpp:jingle:apps:rtp:audio' # XEP-0167
-NS_JINGLE_RTP_VIDEO = 'urn:xmpp:jingle:apps:rtp:video' # XEP-0167
-NS_JINGLE_FILE_TRANSFER ='urn:xmpp:jingle:apps:file-transfer:3' # XEP-0234
-NS_JINGLE_XTLS='urn:xmpp:jingle:security:xtls:0' # XTLS: EXPERIMENTAL security layer of jingle
-NS_JINGLE_RAW_UDP = 'urn:xmpp:jingle:transports:raw-udp:1' # XEP-0177
-NS_JINGLE_ICE_UDP = 'urn:xmpp:jingle:transports:ice-udp:1' # XEP-0176
-NS_JINGLE_BYTESTREAM ='urn:xmpp:jingle:transports:s5b:1' # XEP-0260
-NS_JINGLE_IBB = 'urn:xmpp:jingle:transports:ibb:1' # XEP-0261
-NS_LAST = 'jabber:iq:last'
-NS_LOCATION = 'http://jabber.org/protocol/geoloc' # XEP-0080
-NS_MESSAGE = 'message' # Jabberd2
-NS_MOOD = 'http://jabber.org/protocol/mood' # XEP-0107
-NS_MUC = 'http://jabber.org/protocol/muc'
-NS_MUC_USER = NS_MUC + '#user'
-NS_MUC_ADMIN = NS_MUC + '#admin'
-NS_MUC_OWNER = NS_MUC + '#owner'
-NS_MUC_UNIQUE = NS_MUC + '#unique'
-NS_MUC_CONFIG = NS_MUC + '#roomconfig'
-NS_NICK = 'http://jabber.org/protocol/nick' # XEP-0172
-NS_OFFLINE = 'http://www.jabber.org/jeps/jep-0030.html' # XEP-0013
-NS_PHYSLOC = 'http://jabber.org/protocol/physloc' # XEP-0112
-NS_PING = 'urn:xmpp:ping' # XEP-0199
-NS_PRESENCE = 'presence' # Jabberd2
-NS_PRIVACY = 'jabber:iq:privacy'
-NS_PRIVATE = 'jabber:iq:private'
-NS_PROFILE = 'http://jabber.org/protocol/profile' # XEP-0154
-NS_PUBSUB = 'http://jabber.org/protocol/pubsub' # XEP-0060
-NS_PUBSUB_EVENT = 'http://jabber.org/protocol/pubsub#event'
-NS_PUBSUB_PUBLISH_OPTIONS = NS_PUBSUB + '#publish-options' # XEP-0060
-NS_PUBSUB_OWNER = 'http://jabber.org/protocol/pubsub#owner' # XEP-0060
-NS_REGISTER = 'jabber:iq:register'
-NS_ROSTER = 'jabber:iq:roster'
-NS_ROSTERNOTES = 'storage:rosternotes'
-NS_ROSTERX = 'http://jabber.org/protocol/rosterx' # XEP-0144
-NS_ROSTER_VER = 'urn:xmpp:features:rosterver' # XEP-0273
-NS_RPC = 'jabber:iq:rpc' # XEP-0009
-NS_RSM = 'http://jabber.org/protocol/rsm'
-NS_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl'
-NS_SECLABEL = 'urn:xmpp:sec-label:0'
-NS_SECLABEL_CATALOG = 'urn:xmpp:sec-label:catalog:2'
-NS_SEARCH = 'jabber:iq:search'
-NS_SERVER = 'jabber:server'
-NS_SESSION = 'urn:ietf:params:xml:ns:xmpp-session'
-NS_SI = 'http://jabber.org/protocol/si' # XEP-0096
-NS_SI_PUB = 'http://jabber.org/protocol/sipub' # XEP-0137
-NS_SIGNED = 'jabber:x:signed' # XEP-0027
-NS_SSN = 'urn:xmpp:ssn' # XEP-0155
-NS_STANZA_CRYPTO = 'http://www.xmpp.org/extensions/xep-0200.html#ns' # XEP-0200
-NS_STANZAS = 'urn:ietf:params:xml:ns:xmpp-stanzas'
-NS_STREAM = 'http://affinix.com/jabber/stream'
-NS_STREAMS = 'http://etherx.jabber.org/streams'
-NS_TIME = 'jabber:iq:time' # XEP-0900
-NS_TIME_REVISED = 'urn:xmpp:time' # XEP-0202
-NS_TLS = 'urn:ietf:params:xml:ns:xmpp-tls'
-NS_TUNE = 'http://jabber.org/protocol/tune' # XEP-0118
-NS_VACATION = 'http://jabber.org/protocol/vacation'
-NS_VCARD = 'vcard-temp'
-NS_GMAILNOTIFY = 'google:mail:notify'
-NS_GTALKSETTING = 'google:setting'
-NS_VCARD_UPDATE = NS_VCARD + ':x:update'
-NS_VERSION = 'jabber:iq:version'
-NS_VIEWING = 'http://jabber.org/protocol/viewing' # XEP--197
-NS_WAITINGLIST = 'http://jabber.org/protocol/waitinglist' # XEP-0130
-NS_XHTML_IM = 'http://jabber.org/protocol/xhtml-im' # XEP-0071
-NS_XHTML = 'http://www.w3.org/1999/xhtml' # "
-NS_DATA_LAYOUT = 'http://jabber.org/protocol/xdata-layout' # XEP-0141
-NS_DATA_VALIDATE = 'http://jabber.org/protocol/xdata-validate' # XEP-0122
-NS_XMPP_STREAMS = 'urn:ietf:params:xml:ns:xmpp-streams'
-NS_RECEIPTS = 'urn:xmpp:receipts'
-NS_PUBKEY_PUBKEY = 'urn:xmpp:pubkey:2' # XEP-0189
-NS_PUBKEY_REVOKE = 'urn:xmpp:revoke:2'
-NS_PUBKEY_ATTEST = 'urn:xmpp:attest:2'
-NS_STREAM_MGMT = 'urn:xmpp:sm:2' # XEP-198
-NS_HASHES = 'urn:xmpp:hashes:1' # XEP-300
-NS_HASHES_MD5 = 'urn:xmpp:hash-function-textual-names:md5'
-NS_HASHES_SHA1 = 'urn:xmpp:hash-function-textual-names:sha-1'
-NS_HASHES_SHA256 = 'urn:xmpp:hash-function-textual-names:sha-256'
-NS_HASHES_SHA512 = 'urn:xmpp:hash-function-textual-names:sha-512'
-
-xmpp_stream_error_conditions = '''
-bad-format -- -- -- The entity has sent XML that cannot be processed.
-bad-namespace-prefix -- -- -- The entity has sent a namespace prefix that is unsupported, or has sent no namespace prefix on an element that requires such a prefix.
-conflict -- -- -- The server is closing the active stream for this entity because a new stream has been initiated that conflicts with the existing stream.
-connection-timeout -- -- -- The entity has not generated any traffic over the stream for some period of time.
-host-gone -- -- -- The value of the 'to' attribute provided by the initiating entity in the stream header corresponds to a hostname that is no longer hosted by the server.
-host-unknown -- -- -- The value of the 'to' attribute provided by the initiating entity in the stream header does not correspond to a hostname that is hosted by the server.
-improper-addressing -- -- -- A stanza sent between two servers lacks a 'to' or 'from' attribute (or the attribute has no value).
-internal-server-error -- -- -- The server has experienced a misconfiguration or an otherwise-undefined internal error that prevents it from servicing the stream.
-invalid-from -- cancel -- -- The JID or hostname provided in a 'from' address does not match an authorized JID or validated domain negotiated between servers via SASL or dialback, or between a client and a server via authentication and resource authorization.
-invalid-id -- -- -- The stream ID or dialback ID is invalid or does not match an ID previously provided.
-invalid-namespace -- -- -- The streams namespace name is something other than "http://etherx.jabber.org/streams" or the dialback namespace name is something other than "jabber:server:dialback".
-invalid-xml -- -- -- The entity has sent invalid XML over the stream to a server that performs validation.
-not-authorized -- -- -- The entity has attempted to send data before the stream has been authenticated, or otherwise is not authorized to perform an action related to stream negotiation.
-policy-violation -- -- -- The entity has violated some local service policy.
-remote-connection-failed -- -- -- The server is unable to properly connect to a remote resource that is required for authentication or authorization.
-resource-constraint -- -- -- The server lacks the system resources necessary to service the stream.
-restricted-xml -- -- -- The entity has attempted to send restricted XML features such as a comment, processing instruction, DTD, entity reference, or unescaped character.
-see-other-host -- -- -- The server will not provide service to the initiating entity but is redirecting traffic to another host.
-system-shutdown -- -- -- The server is being shut down and all active streams are being closed.
-undefined-condition -- -- -- The error condition is not one of those defined by the other conditions in this list.
-unsupported-encoding -- -- -- The initiating entity has encoded the stream in an encoding that is not supported by the server.
-unsupported-stanza-type -- -- -- The initiating entity has sent a first-level child of the stream that is not supported by the server.
-unsupported-version -- -- -- The value of the 'version' attribute provided by the initiating entity in the stream header specifies a version of XMPP that is not supported by the server.
-xml-not-well-formed -- -- -- The initiating entity has sent XML that is not well-formed.'''
-
-xmpp_stanza_error_conditions = '''
-bad-request -- 400 -- modify -- The sender has sent XML that is malformed or that cannot be processed.
-conflict -- 409 -- cancel -- Access cannot be granted because an existing resource or session exists with the same name or address.
-feature-not-implemented -- 501 -- cancel -- The feature requested is not implemented by the recipient or server and therefore cannot be processed.
-forbidden -- 403 -- auth -- The requesting entity does not possess the required permissions to perform the action.
-gone -- 302 -- modify -- The recipient or server can no longer be contacted at this address.
-internal-server-error -- 500 -- wait -- The server could not process the stanza because of a misconfiguration or an otherwise-undefined internal server error.
-item-not-found -- 404 -- cancel -- The addressed JID or item requested cannot be found.
-jid-malformed -- 400 -- modify -- The value of the 'to' attribute in the sender's stanza does not adhere to the syntax defined in Addressing Scheme.
-not-acceptable -- 406 -- cancel -- The recipient or server understands the request but is refusing to process it because it does not meet criteria defined by the recipient or server.
-not-allowed -- 405 -- cancel -- The recipient or server does not allow any entity to perform the action.
-not-authorized -- 401 -- auth -- The sender must provide proper credentials before being allowed to perform the action, or has provided improper credentials.
-payment-required -- 402 -- auth -- The requesting entity is not authorized to access the requested service because payment is required.
-recipient-unavailable -- 404 -- wait -- The intended recipient is temporarily unavailable.
-redirect -- 302 -- modify -- The recipient or server is redirecting requests for this information to another entity.
-registration-required -- 407 -- auth -- The requesting entity is not authorized to access the requested service because registration is required.
-remote-server-not-found -- 404 -- cancel -- A remote server or service specified as part or all of the JID of the intended recipient does not exist.
-remote-server-timeout -- 504 -- wait -- A remote server or service specified as part or all of the JID of the intended recipient could not be contacted within a reasonable amount of time.
-resource-constraint -- 500 -- wait -- The server or recipient lacks the system resources necessary to service the request.
-service-unavailable -- 503 -- cancel -- The server or recipient does not currently provide the requested service.
-subscription-required -- 407 -- auth -- The requesting entity is not authorized to access the requested service because a subscription is required.
-undefined-condition -- 500 -- -- Undefined Condition
-unexpected-request -- 400 -- wait -- The recipient or server understood the request but was not expecting it at this time (e.g., the request was out of order).'''
-
-sasl_error_conditions = '''
-aborted -- -- -- The receiving entity acknowledges an <abort/> element sent by the initiating entity; sent in reply to the <abort/> element.
-incorrect-encoding -- -- -- The data provided by the initiating entity could not be processed because the [BASE64]Josefsson, S., The Base16, Base32, and Base64 Data Encodings, July 2003. encoding is incorrect (e.g., because the encoding does not adhere to the definition in Section 3 of [BASE64]Josefsson, S., The Base16, Base32, and Base64 Data Encodings, July 2003.); sent in reply to a <response/> element or an <auth/> element with initial response data.
-invalid-authzid -- -- -- The authzid provided by the initiating entity is invalid, either because it is incorrectly formatted or because the initiating entity does not have permissions to authorize that ID; sent in reply to a <response/> element or an <auth/> element with initial response data.
-invalid-mechanism -- -- -- The initiating entity did not provide a mechanism or requested a mechanism that is not supported by the receiving entity; sent in reply to an <auth/> element.
-mechanism-too-weak -- -- -- The mechanism requested by the initiating entity is weaker than server policy permits for that initiating entity; sent in reply to a <response/> element or an <auth/> element with initial response data.
-not-authorized -- -- -- The authentication failed because the initiating entity did not provide valid credentials (this includes but is not limited to the case of an unknown username); sent in reply to a <response/> element or an <auth/> element with initial response data.
-temporary-auth-failure -- -- -- The authentication failed because of a temporary error condition within the receiving entity; sent in reply to an <auth/> element or <response/> element.'''
-
-ERRORS, _errorcodes = {}, {}
-for ns, errname, errpool in ((NS_XMPP_STREAMS, 'STREAM',
-xmpp_stream_error_conditions), (NS_STANZAS, 'ERR', xmpp_stanza_error_conditions),
-(NS_SASL, 'SASL', sasl_error_conditions)):
- for err in errpool.split('\n')[1:]:
- cond, code, typ, text = err.split(' -- ')
- name = errname + '_' + ascii_upper(cond).replace('-', '_')
- locals()[name] = ns + ' ' + cond
- ERRORS[ns + ' ' + cond] = [code, typ, text]
- if code:
- _errorcodes[code] = cond
-del ns, errname, errpool, err, cond, code, typ, text
-
-def isResultNode(node):
- """
- Return true if the node is a positive reply
- """
- return node and node.getType() == 'result'
-
-def isErrorNode(node):
- """
- Return true if the node is a negative reply
- """
- return node and node.getType() == 'error'
-
-class NodeProcessed(Exception):
- """
- Exception that should be raised by handler when the handling should be
- stopped
- """
- pass
-
-class StreamError(Exception):
- """
- Base exception class for stream errors
- """
- pass
-
-class BadFormat(StreamError):
- pass
-
-class BadNamespacePrefix(StreamError):
- pass
-
-class Conflict(StreamError):
- pass
-
-class ConnectionTimeout(StreamError):
- pass
-
-class HostGone(StreamError):
- pass
-
-class HostUnknown(StreamError):
- pass
-
-class ImproperAddressing(StreamError):
- pass
-
-class InternalServerError(StreamError):
- pass
-
-class InvalidFrom(StreamError):
- pass
-
-class InvalidID(StreamError):
- pass
-
-class InvalidNamespace(StreamError):
- pass
-
-class InvalidXML(StreamError):
- pass
-
-class NotAuthorized(StreamError):
- pass
-
-class PolicyViolation(StreamError):
- pass
-
-class RemoteConnectionFailed(StreamError):
- pass
-
-class ResourceConstraint(StreamError):
- pass
-
-class RestrictedXML(StreamError):
- pass
-
-class SeeOtherHost(StreamError):
- pass
-
-class SystemShutdown(StreamError):
- pass
-
-class UndefinedCondition(StreamError):
- pass
-
-class UnsupportedEncoding(StreamError):
- pass
-
-class UnsupportedStanzaType(StreamError):
- pass
-
-class UnsupportedVersion(StreamError):
- pass
-
-class XMLNotWellFormed(StreamError):
- pass
-
-stream_exceptions = {'bad-format': BadFormat,
- 'bad-namespace-prefix': BadNamespacePrefix,
- 'conflict': Conflict,
- 'connection-timeout': ConnectionTimeout,
- 'host-gone': HostGone,
- 'host-unknown': HostUnknown,
- 'improper-addressing': ImproperAddressing,
- 'internal-server-error': InternalServerError,
- 'invalid-from': InvalidFrom,
- 'invalid-id': InvalidID,
- 'invalid-namespace': InvalidNamespace,
- 'invalid-xml': InvalidXML,
- 'not-authorized': NotAuthorized,
- 'policy-violation': PolicyViolation,
- 'remote-connection-failed': RemoteConnectionFailed,
- 'resource-constraint': ResourceConstraint,
- 'restricted-xml': RestrictedXML,
- 'see-other-host': SeeOtherHost,
- 'system-shutdown': SystemShutdown,
- 'undefined-condition': UndefinedCondition,
- 'unsupported-encoding': UnsupportedEncoding,
- 'unsupported-stanza-type': UnsupportedStanzaType,
- 'unsupported-version': UnsupportedVersion,
- 'xml-not-well-formed': XMLNotWellFormed}
-
-class JID:
- """
- JID can be built from string, modified, compared, serialised into string
- """
-
- def __init__(self, jid=None, node='', domain='', resource=''):
- """
- JID can be specified as string (jid argument) or as separate parts
-
- Examples:
- JID('node@domain/resource')
- JID(node='node',domain='domain.org')
- """
- if not jid and not domain:
- raise ValueError('JID must contain at least domain name')
- elif type(jid) == type(self):
- self.node, self.domain = jid.node, jid.domain
- self.resource = jid.resource
- elif domain:
- self.node, self.domain, self.resource = node, domain, resource
- else:
- if jid.find('@') + 1:
- self.node, jid = jid.split('@', 1)
- else:
- self.node = ''
- if jid.find('/')+1:
- self.domain, self.resource = jid.split('/', 1)
- else:
- self.domain, self.resource = jid, ''
-
- def getNode(self):
- """
- Return the node part of the JID
- """
- return self.node
-
- def setNode(self, node):
- """
- Set the node part of the JID to new value. Specify None to remove
- the node part
- """
- self.node = node.lower()
-
- def getDomain(self):
- """
- Return the domain part of the JID
- """
- return self.domain
-
- def setDomain(self, domain):
- """
- Set the domain part of the JID to new value
- """
- self.domain = domain.lower()
-
- def getResource(self):
- """
- Return the resource part of the JID
- """
- return self.resource
-
- def setResource(self, resource):
- """
- Set the resource part of the JID to new value. Specify None to remove the
- resource part
- """
- self.resource = resource
-
- def getStripped(self):
- """
- Return the bare representation of JID. I.e. string value w/o resource
- """
- return self.__str__(0)
-
- def __eq__(self, other):
- """
- Compare the JID to another instance or to string for equality
- """
- try:
- other = JID(other)
- except ValueError:
- return 0
- return self.resource == other.resource and \
- self.__str__(0) == other.__str__(0)
-
- def __ne__(self, other):
- """
- Compare the JID to another instance or to string for non-equality
- """
- return not self.__eq__(other)
-
- def bareMatch(self, other):
- """
- Compare the node and domain parts of the JID's for equality
- """
- return self.__str__(0) == JID(other).__str__(0)
-
- def __str__(self, wresource=1):
- """
- Serialise JID into string
- """
- if self.node:
- jid = self.node + '@' + self.domain
- else:
- jid = self.domain
- if wresource and self.resource:
- return jid + '/' + self.resource
- return jid
-
- def __hash__(self):
- """
- Produce hash of the JID, Allows to use JID objects as keys of the
- dictionary
- """
- return hash(str(self))
-
-class BOSHBody(Node):
- """
- <body> tag that wraps usual XMPP stanzas in XMPP over BOSH
- """
-
- def __init__(self, attrs={}, payload=[], node=None):
- Node.__init__(self, tag='body', attrs=attrs, payload=payload, node=node)
- self.setNamespace(NS_HTTP_BIND)
-
-
-class Protocol(Node):
- """
- A "stanza" object class. Contains methods that are common for presences, iqs
- and messages
- """
-
- def __init__(self, name=None, to=None, typ=None, frm=None, attrs={},
- payload=[], timestamp=None, xmlns=None, node=None):
- """
- Constructor, name is the name of the stanza
- i.e. 'message' or 'presence'or 'iq'
-
- to is the value of 'to' attribure, 'typ' - 'type' attribute
- frn - from attribure, attrs - other attributes mapping,
- payload - same meaning as for simplexml payload definition
- timestamp - the time value that needs to be stamped over stanza
- xmlns - namespace of top stanza node
- node - parsed or unparsed stana to be taken as prototype.
- """
- if not attrs:
- attrs = {}
- if to:
- attrs['to'] = to
- if frm:
- attrs['from'] = frm
- if typ:
- attrs['type'] = typ
- Node.__init__(self, tag=name, attrs=attrs, payload=payload, node=node)
- if not node and xmlns:
- self.setNamespace(xmlns)
- if self['to']:
- self.setTo(self['to'])
- if self['from']:
- self.setFrom(self['from'])
- if node and type(self) == type(node) and \
- self.__class__ == node.__class__ and self.attrs.has_key('id'):
- del self.attrs['id']
- self.timestamp = None
- for d in self.getTags('delay', namespace=NS_DELAY2):
- try:
- if d.getAttr('stamp') < self.getTimestamp2():
- self.setTimestamp(d.getAttr('stamp'))
- except Exception:
- pass
- if not self.timestamp:
- for x in self.getTags('x', namespace=NS_DELAY):
- try:
- if x.getAttr('stamp') < self.getTimestamp():
- self.setTimestamp(x.getAttr('stamp'))
- except Exception:
- pass
- if timestamp is not None:
- self.setTimestamp(timestamp) # To auto-timestamp stanza just pass timestamp=''
-
- def getTo(self):
- """
- Return value of the 'to' attribute
- """
- try:
- return self['to']
- except:
- return None
-
- def getFrom(self):
- """
- Return value of the 'from' attribute
- """
- try:
- return self['from']
- except:
- return None
-
- def getTimestamp(self):
- """
- Return the timestamp in the 'yyyymmddThhmmss' format
- """
- if self.timestamp:
- return self.timestamp
- return time.strftime('%Y%m%dT%H:%M:%S', time.gmtime())
-
- def getTimestamp2(self):
- """
- Return the timestamp in the 'yyyymmddThhmmss' format
- """
- if self.timestamp:
- return self.timestamp
- return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
-
- def getID(self):
- """
- Return the value of the 'id' attribute
- """
- return self.getAttr('id')
-
- def setTo(self, val):
- """
- Set the value of the 'to' attribute
- """
- self.setAttr('to', JID(val))
-
- def getType(self):
- """
- Return the value of the 'type' attribute
- """
- return self.getAttr('type')
-
- def setFrom(self, val):
- """
- Set the value of the 'from' attribute
- """
- self.setAttr('from', JID(val))
-
- def setType(self, val):
- """
- Set the value of the 'type' attribute
- """
- self.setAttr('type', val)
-
- def setID(self, val):
- """
- Set the value of the 'id' attribute
- """
- self.setAttr('id', val)
-
- def getError(self):
- """
- Return the error-condition (if present) or the textual description
- of the error (otherwise)
- """
- errtag = self.getTag('error')
- if errtag:
- for tag in errtag.getChildren():
- if tag.getName() != 'text':
- return tag.getName()
- return errtag.getData()
-
- def getErrorMsg(self):
- """
- Return the textual description of the error (if present)
- or the error condition
- """
- errtag = self.getTag('error')
- if errtag:
- for tag in errtag.getChildren():
- if tag.getName() == 'text':
- return tag.getData()
- return self.getError()
-
- def getErrorCode(self):
- """
- Return the error code. Obsolete.
- """
- return self.getTagAttr('error', 'code')
-
- def getStatusConditions(self):
- """
- Return the status conditions list as defined in XEP-0306.
- """
- conds = []
- condtag = self.getTag('conditions', namespace=NS_CONDITIONS)
- if condtag:
- for tag in condtag.getChildren():
- conds.append(tag.getName())
- return conds
-
- def setError(self, error, code=None):
- """
- Set the error code. Obsolete. Use error-conditions instead
- """
- if code:
- if str(code) in _errorcodes.keys():
- error = ErrorNode(_errorcodes[str(code)], text=error)
- else:
- error = ErrorNode(ERR_UNDEFINED_CONDITION, code=code,
- typ='cancel', text=error)
- elif type(error) in [type(''), type(u'')]:
- error=ErrorNode(error)
- self.setType('error')
- self.addChild(node=error)
-
- def setTimestamp(self, val=None):
- """
- Set the timestamp. timestamp should be the yyyymmddThhmmss string
- """
- if not val:
- val = time.strftime('%Y%m%dT%H:%M:%S', time.gmtime())
- self.timestamp=val
- self.setTag('x', {'stamp': self.timestamp}, namespace=NS_DELAY)
-
- def getProperties(self):
- """
- Return the list of namespaces to which belongs the direct childs of element
- """
- props = []
- for child in self.getChildren():
- prop = child.getNamespace()
- if prop not in props:
- props.append(prop)
- return props
-
- def __setitem__(self, item, val):
- """
- Set the item 'item' to the value 'val'
- """
- if item in ['to', 'from']:
- val = JID(val)
- return self.setAttr(item, val)
-
-
-class Message(Protocol):
- """
- XMPP Message stanza - "push" mechanism
- """
-
- def __init__(self, to=None, body=None, xhtml=None, typ=None, subject=None,
- attrs={}, frm=None, payload=[], timestamp=None, xmlns=NS_CLIENT,
- node=None):
- """
- You can specify recipient, text of message, type of message any
- additional attributes, sender of the message, any additional payload
- (f.e. jabber:x:delay element) and namespace in one go.
-
- Alternatively you can pass in the other XML object as the 'node'
- parameted to replicate it as message
- """
- Protocol.__init__(self, 'message', to=to, typ=typ, attrs=attrs, frm=frm,
- payload=payload, timestamp=timestamp, xmlns=xmlns, node=node)
- if body:
- self.setBody(body)
- if xhtml:
- self.setXHTML(xhtml)
- if subject is not None:
- self.setSubject(subject)
-
- def getBody(self):
- """
- Return text of the message
- """
- return self.getTagData('body')
-
- def getXHTML(self, xmllang=None):
- """
- Return serialized xhtml-im element text of the message
-
- TODO: Returning a DOM could make rendering faster.
- """
- xhtml = self.getTag('html')
- if xhtml:
- if xmllang:
- body = xhtml.getTag('body', attrs={'xml:lang': xmllang})
- else:
- body = xhtml.getTag('body')
- return str(body)
- return None
-
- def getSubject(self):
- """
- Return subject of the message
- """
- return self.getTagData('subject')
-
- def getThread(self):
- """
- Return thread of the message
- """
- return self.getTagData('thread')
-
- def setBody(self, val):
- """
- Set the text of the message"""
- self.setTagData('body', val)
-
- def setXHTML(self, val, xmllang=None):
- """
- Sets the xhtml text of the message (XEP-0071). The parameter is the
- "inner html" to the body.
- """
- try:
- if xmllang:
- dom = NodeBuilder('<body xmlns="%s" xml:lang="%s">%s</body>' \
- % (NS_XHTML, xmllang, val)).getDom()
- else:
- dom = NodeBuilder('<body xmlns="%s">%s</body>' % (NS_XHTML,
- val), 0).getDom()
- if self.getTag('html'):
- self.getTag('html').addChild(node=dom)
- else:
- self.setTag('html', namespace=NS_XHTML_IM).addChild(node=dom)
- except Exception, e:
- print "Error", e
- # FIXME: log. we could not set xhtml (parse error, whatever)
-
- def setSubject(self, val):
- """
- Set the subject of the message
- """
- self.setTagData('subject', val)
-
- def setThread(self, val):
- """
- Set the thread of the message
- """
- self.setTagData('thread', val)
-
- def buildReply(self, text=None):
- """
- Builds and returns another message object with specified text. The to,
- from, thread and type properties of new message are pre-set as reply to
- this message
- """
- m = Message(to=self.getFrom(), frm=self.getTo(), body=text,
- typ=self.getType())
- th = self.getThread()
- if th:
- m.setThread(th)
- return m
-
- def getStatusCode(self):
- """
- Return the status code of the message (for groupchat config change)
- """
- attrs = []
- for xtag in self.getTags('x'):
- for child in xtag.getTags('status'):
- attrs.append(child.getAttr('code'))
- return attrs
-
-class Presence(Protocol):
-
- def __init__(self, to=None, typ=None, priority=None, show=None, status=None,
- attrs={}, frm=None, timestamp=None, payload=[], xmlns=NS_CLIENT,
- node=None):
- """
- You can specify recipient, type of message, priority, show and status
- values any additional attributes, sender of the presence, timestamp, any
- additional payload (f.e. jabber:x:delay element) and namespace in one go.
- Alternatively you can pass in the other XML object as the 'node'
- parameted to replicate it as presence
- """
- Protocol.__init__(self, 'presence', to=to, typ=typ, attrs=attrs, frm=frm,
- payload=payload, timestamp=timestamp, xmlns=xmlns, node=node)
- if priority:
- self.setPriority(priority)
- if show:
- self.setShow(show)
- if status:
- self.setStatus(status)
-
- def getPriority(self):
- """
- Return the priority of the message
- """
- return self.getTagData('priority')
-
- def getShow(self):
- """
- Return the show value of the message
- """
- return self.getTagData('show')
-
- def getStatus(self):
- """
- Return the status string of the message
- """
- return self.getTagData('status')
-
- def setPriority(self, val):
- """
- Set the priority of the message
- """
- self.setTagData('priority', val)
-
- def setShow(self, val):
- """
- Set the show value of the message
- """
- self.setTagData('show', val)
-
- def setStatus(self, val):
- """
- Set the status string of the message
- """
- self.setTagData('status', val)
-
- def _muc_getItemAttr(self, tag, attr):
- for xtag in self.getTags('x'):
- if xtag.getNamespace() not in (NS_MUC_USER, NS_MUC_ADMIN):
- continue
- for child in xtag.getTags(tag):
- return child.getAttr(attr)
-
- def _muc_getSubTagDataAttr(self, tag, attr):
- for xtag in self.getTags('x'):
- if xtag.getNamespace() not in (NS_MUC_USER, NS_MUC_ADMIN):
- continue
- for child in xtag.getTags('item'):
- for cchild in child.getTags(tag):
- return cchild.getData(), cchild.getAttr(attr)
- return None, None
-
- def getRole(self):
- """
- Return the presence role (for groupchat)
- """
- return self._muc_getItemAttr('item', 'role')
-
- def getAffiliation(self):
- """
- Return the presence affiliation (for groupchat)
- """
- return self._muc_getItemAttr('item', 'affiliation')
-
- def getNewNick(self):
- """
- Return the status code of the presence (for groupchat)
- """
- return self._muc_getItemAttr('item', 'nick')
-
- def getJid(self):
- """
- Return the presence jid (for groupchat)
- """
- return self._muc_getItemAttr('item', 'jid')
-
- def getReason(self):
- """
- Returns the reason of the presence (for groupchat)
- """
- return self._muc_getSubTagDataAttr('reason', '')[0]
-
- def getActor(self):
- """
- Return the reason of the presence (for groupchat)
- """
- return self._muc_getSubTagDataAttr('actor', 'jid')[1]
-
- def getStatusCode(self):
- """
- Return the status code of the presence (for groupchat)
- """
- attrs = []
- for xtag in self.getTags('x'):
- for child in xtag.getTags('status'):
- attrs.append(child.getAttr('code'))
- return attrs
-
-class Iq(Protocol):
- """
- XMPP Iq object - get/set dialog mechanism
- """
-
- def __init__(self, typ=None, queryNS=None, attrs={}, to=None, frm=None,
- payload=[], xmlns=NS_CLIENT, node=None):
- """
- You can specify type, query namespace any additional attributes,
- recipient of the iq, sender of the iq, any additional payload (f.e.
- jabber:x:data node) and namespace in one go.
-
- Alternatively you can pass in the other XML object as the 'node'
- parameted to replicate it as an iq
- """
- Protocol.__init__(self, 'iq', to=to, typ=typ, attrs=attrs, frm=frm,
- xmlns=xmlns, node=node)
- if payload:
- self.setQueryPayload(payload)
- if queryNS:
- self.setQueryNS(queryNS)
-
- def getQuery(self):
- """
- Return the IQ's child element if it exists, None otherwise.
- """
- children = self.getChildren()
- if children and self.getType() != 'error' and \
- children[0].getName() != 'error':
- return children[0]
-
- def getQueryNS(self):
- """
- Return the namespace of the 'query' child element
- """
- tag = self.getQuery()
- if tag:
- return tag.getNamespace()
-
- def getQuerynode(self):
- """
- Return the 'node' attribute value of the 'query' child element
- """
- tag = self.getQuery()
- if tag:
- return tag.getAttr('node')
-
- def getQueryPayload(self):
- """
- Return the 'query' child element payload
- """
- tag = self.getQuery()
- if tag:
- return tag.getPayload()
-
- def getQueryChildren(self):
- """
- Return the 'query' child element child nodes
- """
- tag = self.getQuery()
- if tag:
- return tag.getChildren()
-
- def setQuery(self, name=None):
- """
- Change the name of the query node, creating it if needed. Keep the
- existing name if none is given (use 'query' if it's a creation).
- Return the query node.
- """
- query = self.getQuery()
- if query is None:
- query = self.addChild('query')
- if name is not None:
- query.setName(name)
- return query
-
- def setQueryNS(self, namespace):
- """
- Set the namespace of the 'query' child element
- """
- self.setQuery().setNamespace(namespace)
-
- def setQueryPayload(self, payload):
- """
- Set the 'query' child element payload
- """
- self.setQuery().setPayload(payload)
-
- def setQuerynode(self, node):
- """
- Set the 'node' attribute value of the 'query' child element
- """
- self.setQuery().setAttr('node', node)
-
- def buildReply(self, typ):
- """
- Build and return another Iq object of specified type. The to, from and
- query child node of new Iq are pre-set as reply to this Iq.
- """
- iq = Iq(typ, to=self.getFrom(), frm=self.getTo(),
- attrs={'id': self.getID()})
- iq.setQuery(self.getQuery().getName()).setNamespace(self.getQueryNS())
- return iq
-
-class Hashes(Node):
- """
- Hash elements for various XEPs as defined in XEP-300
- """
-
- """
- RECOMENDED HASH USE:
- Algorithm Support
- MD2 MUST NOT
- MD4 MUST NOT
- MD5 MAY
- SHA-1 MUST
- SHA-256 MUST
- SHA-512 SHOULD
- """
-
- supported = ('md5', 'sha-1', 'sha-256', 'sha-512')
-
- def __init__(self, nsp=NS_HASHES):
- Node.__init__(self, None, {}, [], None, None, False, None)
- self.setNamespace(nsp)
- self.setName('hash')
-
- def calculateHash(self, algo, file_string):
- """
- Calculate the hash and add it. It is preferable doing it here
- instead of doing it all over the place in Gajim.
- """
- hl = None
- hash_ = None
- # file_string can be a string or a file
- if type(file_string) == str: # if it is a string
- if algo == 'md5':
- hl = hashlib.md5()
- elif algo == 'sha-1':
- hl = hashlib.sha1()
- elif algo == 'sha-256':
- hl = hashlib.sha256()
- elif algo == 'sha-512':
- hl = hashlib.sha512()
-
- if hl:
- hl.update(file_string)
- hash_ = hl.hexdigest()
- else: # if it is a file
-
- if algo == 'md5':
- hl = hashlib.md5()
- elif algo == 'sha-1':
- hl = hashlib.sha1()
- elif algo == 'sha-256':
- hl = hashlib.sha256()
- elif algo == 'sha-512':
- hl = hashlib.sha512()
-
- if hl:
- for line in file_string:
- hl.update(line)
- hash_ = hl.hexdigest()
-
- return hash_
-
- def addHash(self, hash_, algo):
- self.setAttr('algo', algo)
- self.setData(hash_)
-
-class Acks(Node):
- """
- Acknowledgement elements for Stream Management
- """
- def __init__(self, nsp=NS_STREAM_MGMT):
- Node.__init__(self, None, {}, [], None, None, False, None)
- self.setNamespace(nsp)
-
- def buildAnswer(self, handled):
- """
- handled is the number of stanzas handled
- """
- self.setName('a')
- self.setAttr('h', handled)
-
- def buildRequest(self):
- self.setName('r')
-
- def buildEnable(self, resume=False):
- self.setName('enable')
- if resume:
- self.setAttr('resume', 'true')
-
- def buildResume(self, handled, previd):
- self.setName('resume')
- self.setAttr('h', handled)
- self.setAttr('previd', previd)
-
-class ErrorNode(Node):
- """
- XMPP-style error element
-
- In the case of stanza error should be attached to XMPP stanza.
- In the case of stream-level errors should be used separately.
- """
-
- def __init__(self, name, code=None, typ=None, text=None):
- """
- Mandatory parameter: name - name of error condition.
- Optional parameters: code, typ, text.
- Used for backwards compartibility with older jabber protocol.
- """
- if name in ERRORS:
- cod, type_, txt = ERRORS[name]
- ns = name.split()[0]
- else:
- cod, ns, type_, txt = '500', NS_STANZAS, 'cancel', ''
- if typ:
- type_ = typ
- if code:
- cod = code
- if text:
- txt = text
- Node.__init__(self, 'error', {}, [Node(name)])
- if type_:
- self.setAttr('type', type_)
- if not cod:
- self.setName('stream:error')
- if txt:
- self.addChild(node=Node(ns + ' text', {}, [txt]))
- if cod:
- self.setAttr('code', cod)
-
-class Error(Protocol):
- """
- Used to quickly transform received stanza into error reply
- """
-
- def __init__(self, node, error, reply=1):
- """
- Create error reply basing on the received 'node' stanza and the 'error'
- error condition
-
- If the 'node' is not the received stanza but locally created ('to' and
- 'from' fields needs not swapping) specify the 'reply' argument as false.
- """
- if reply:
- Protocol.__init__(self, to=node.getFrom(), frm=node.getTo(), node=node)
- else:
- Protocol.__init__(self, node=node)
- self.setError(error)
- if node.getType() == 'error':
- self.__str__ = self.__dupstr__
-
- def __dupstr__(self, dup1=None, dup2=None):
- """
- Dummy function used as preventor of creating error node in reply to error
- node. I.e. you will not be able to serialise "double" error into string.
- """
- return ''
-
-class DataField(Node):
- """
- This class is used in the DataForm class to describe the single data item
-
- If you are working with jabber:x:data (XEP-0004, XEP-0068, XEP-0122) then
- you will need to work with instances of this class.
- """
-
- def __init__(self, name=None, value=None, typ=None, required=0, desc=None,
- options=[], node=None):
- """
- Create new data field of specified name,value and type
-
- Also 'required','desc' and 'options' fields can be set. Alternatively
- other XML object can be passed in as the 'node' parameted
- to replicate it as a new datafiled.
- """
- Node.__init__(self, 'field', node=node)
- if name:
- self.setVar(name)
- if isinstance(value, (list, tuple)):
- self.setValues(value)
- elif value:
- self.setValue(value)
- if typ:
- self.setType(typ)
- elif not typ and not node:
- self.setType('text-single')
- if required:
- self.setRequired(required)
- if desc:
- self.setDesc(desc)
- if options:
- self.setOptions(options)
-
- def setRequired(self, req=1):
- """
- Change the state of the 'required' flag
- """
- if req:
- self.setTag('required')
- else:
- try:
- self.delChild('required')
- except ValueError:
- return
-
- def isRequired(self):
- """
- Return in this field a required one
- """
- return self.getTag('required')
-
- def setDesc(self, desc):
- """
- Set the description of this field
- """
- self.setTagData('desc', desc)
-
- def getDesc(self):
- """
- Return the description of this field
- """
- return self.getTagData('desc')
-
- def setValue(self, val):
- """
- Set the value of this field
- """
- self.setTagData('value', val)
-
- def getValue(self):
- return self.getTagData('value')
-
- def setValues(self, lst):
- """
- Set the values of this field as values-list. Replaces all previous filed
- values! If you need to just add a value - use addValue method
- """
- while self.getTag('value'):
- self.delChild('value')
- for val in lst:
- self.addValue(val)
-
- def addValue(self, val):
- """
- Add one more value to this field. Used in 'get' iq's or such
- """
- self.addChild('value', {}, [val])
-
- def getValues(self):
- """
- Return the list of values associated with this field
- """
- ret = []
- for tag in self.getTags('value'):
- ret.append(tag.getData())
- return ret
-
- def getOptions(self):
- """
- Return label-option pairs list associated with this field
- """
- ret = []
- for tag in self.getTags('option'):
- ret.append([tag.getAttr('label'), tag.getTagData('value')])
- return ret
-
- def setOptions(self, lst):
- """
- Set label-option pairs list associated with this field
- """
- while self.getTag('option'):
- self.delChild('option')
- for opt in lst:
- self.addOption(opt)
-
- def addOption(self, opt):
- """
- Add one more label-option pair to this field
- """
- if isinstance(opt, basestring):
- self.addChild('option').setTagData('value', opt)
- else:
- self.addChild('option', {'label': opt[0]}).setTagData('value',
- opt[1])
-
- def getType(self):
- """
- Get type of this field
- """
- return self.getAttr('type')
-
- def setType(self, val):
- """
- Set type of this field
- """
- return self.setAttr('type', val)
-
- def getVar(self):
- """
- Get 'var' attribute value of this field
- """
- return self.getAttr('var')
-
- def setVar(self, val):
- """
- Set 'var' attribute value of this field
- """
- return self.setAttr('var', val)
-
-class DataForm(Node):
- """
- Used for manipulating dataforms in XMPP
-
- Relevant XEPs: 0004, 0068, 0122. Can be used in disco, pub-sub and many
- other applications.
- """
- def __init__(self, typ=None, data=[], title=None, node=None):
- """
- Create new dataform of type 'typ'. 'data' is the list of DataField
- instances that this dataform contains, 'title' - the title string. You
- can specify the 'node' argument as the other node to be used as base for
- constructing this dataform
-
- title and instructions is optional and SHOULD NOT contain newlines.
- Several instructions MAY be present.
- 'typ' can be one of ('form' | 'submit' | 'cancel' | 'result' )
- 'typ' of reply iq can be ( 'result' | 'set' | 'set' | 'result' ) respectively.
- 'cancel' form can not contain any fields. All other forms contains AT LEAST one field.
- 'title' MAY be included in forms of type "form" and "result"
- """
- Node.__init__(self, 'x', node=node)
- if node:
- newkids = []
- for n in self.getChildren():
- if n.getName() == 'field':
- newkids.append(DataField(node=n))
- else:
- newkids.append(n)
- self.kids = newkids
- if typ:
- self.setType(typ)
- self.setNamespace(NS_DATA)
- if title:
- self.setTitle(title)
- if isinstance(data, dict):
- newdata = []
- for name in data.keys():
- newdata.append(DataField(name, data[name]))
- data = newdata
- for child in data:
- if isinstance(child, basestring):
- self.addInstructions(child)
- elif child.__class__.__name__ == 'DataField':
- self.kids.append(child)
- else:
- self.kids.append(DataField(node=child))
-
- def getType(self):
- """
- Return the type of dataform
- """
- return self.getAttr('type')
-
- def setType(self, typ):
- """
- Set the type of dataform
- """
- self.setAttr('type', typ)
-
- def getTitle(self):
- """
- Return the title of dataform
- """
- return self.getTagData('title')
-
- def setTitle(self, text):
- """
- Set the title of dataform
- """
- self.setTagData('title', text)
-
- def getInstructions(self):
- """
- Return the instructions of dataform
- """
- return self.getTagData('instructions')
-
- def setInstructions(self, text):
- """
- Set the instructions of dataform
- """
- self.setTagData('instructions', text)
-
- def addInstructions(self, text):
- """
- Add one more instruction to the dataform
- """
- self.addChild('instructions', {}, [text])
-
- def getField(self, name):
- """
- Return the datafield object with name 'name' (if exists)
- """
- return self.getTag('field', attrs={'var': name})
-
- def setField(self, name):
- """
- Create if nessessary or get the existing datafield object with name
- 'name' and return it
- """
- f = self.getField(name)
- if f:
- return f
- return self.addChild(node=DataField(name))
-
- def asDict(self):
- """
- Represent dataform as simple dictionary mapping of datafield names to
- their values
- """
- ret = {}
- for field in self.getTags('field'):
- name = field.getAttr('var')
- typ = field.getType()
- if isinstance(typ, basestring) and typ.endswith('-multi'):
- val = []
- for i in field.getTags('value'):
- val.append(i.getData())
- else:
- val = field.getTagData('value')
- ret[name] = val
- if self.getTag('instructions'):
- ret['instructions'] = self.getInstructions()
- return ret
-
- def __getitem__(self, name):
- """
- Simple dictionary interface for getting datafields values by their names
- """
- item = self.getField(name)
- if item:
- return item.getValue()
- raise IndexError('No such field')
-
- def __setitem__(self, name, val):
- """
- Simple dictionary interface for setting datafields values by their names
- """
- return self.setField(name).setValue(val)
-
diff --git a/src/common/xmpp/proxy_connectors.py b/src/common/xmpp/proxy_connectors.py
deleted file mode 100644
index 2e020013e..000000000
--- a/src/common/xmpp/proxy_connectors.py
+++ /dev/null
@@ -1,238 +0,0 @@
-## proxy_connectors.py
-## based on transports_nb.py
-##
-## Copyright (C) 2003-2004 Alexey "Snake" Nezhdanov
-## modified by Dimitur Kirov <dkirov@gmail.com>
-## modified by Tomas Karasek <tom.to.the.k@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-"""
-Module containing classes for proxy connecting. So far its HTTP CONNECT and
-SOCKS5 proxy
-
-Authentication to NTLM (Microsoft implementation) proxies can be next.
-"""
-
-import struct, socket, base64
-import logging
-log = logging.getLogger('gajim.c.x.proxy_connectors')
-
-class ProxyConnector:
- """
- Interface for proxy-connecting object - when tunnneling XMPP over proxies,
- some connecting process usually has to be done before opening stream. Proxy
- connectors are used right after TCP connection is estabilished
- """
-
- def __init__(self, send_method, onreceive, old_on_receive, on_success,
- on_failure, xmpp_server, proxy_creds=(None, None)):
- """
- Creates proxy connector, starts connecting immediately and gives control
- back to transport afterwards
-
- :param send_method: transport send method
- :param onreceive: method to set on_receive callbacks
- :param old_on_receive: on_receive callback that should be set when
- proxy connection was successful
- :param on_success: called after proxy connection was successfully opened
- :param on_failure: called when errors occured while connecting
- :param xmpp_server: tuple of (hostname, port)
- :param proxy_creds: tuple of (proxy_user, proxy_credentials)
- """
- self.send = send_method
- self.onreceive = onreceive
- self.old_on_receive = old_on_receive
- self.on_success = on_success
- self.on_failure = on_failure
- self.xmpp_server = xmpp_server
- self.proxy_user, self.proxy_pass = proxy_creds
- self.old_on_receive = old_on_receive
-
- self.start_connecting()
-
- @classmethod
- def get_instance(cls, *args, **kwargs):
- """
- Factory Method for object creation
-
- Use this instead of directly initializing the class in order to make unit
- testing much easier.
- """
- return cls(*args, **kwargs)
-
- def start_connecting(self):
- raise NotImplementedError
-
- def connecting_over(self):
- self.onreceive(self.old_on_receive)
- self.on_success()
-
-class HTTPCONNECTConnector(ProxyConnector):
- def start_connecting(self):
- """
- Connect to a proxy, supply login and password to it (if were specified
- while creating instance). Instruct proxy to make connection to the target
- server.
- """
- log.info('Proxy server contacted, performing authentification')
- connector = ['CONNECT %s:%s HTTP/1.1' % self.xmpp_server,
- 'Proxy-Connection: Keep-Alive',
- 'Pragma: no-cache',
- 'Host: %s:%s' % self.xmpp_server,
- 'User-Agent: Gajim']
- if self.proxy_user and self.proxy_pass:
- credentials = '%s:%s' % (self.proxy_user, self.proxy_pass)
- credentials = base64.encodestring(credentials).strip()
- connector.append('Proxy-Authorization: Basic '+credentials)
- connector.append('\r\n')
- self.onreceive(self._on_headers_sent)
- self.send('\r\n'.join(connector))
-
- def _on_headers_sent(self, reply):
- if reply is None:
- return
- self.reply = reply.replace('\r', '')
- try:
- proto, code, desc = reply.split('\n')[0].split(' ', 2)
- except:
- log.error("_on_headers_sent:", exc_info=True)
- #traceback.print_exc()
- self.on_failure('Invalid proxy reply')
- return
- if code <> '200':
- log.error('Invalid proxy reply: %s %s %s' % (proto, code, desc))
- self.on_failure('Invalid proxy reply')
- return
- if len(reply) != 2:
- pass
- self.connecting_over()
-
-
-class SOCKS5Connector(ProxyConnector):
- """
- SOCKS5 proxy connection class. Allows to use SOCKS5 proxies with
- (optionally) simple authentication (only USERNAME/PASSWORD auth)
- """
-
- def start_connecting(self):
- log.info('Proxy server contacted, performing authentification')
- if self.proxy_user and self.proxy_pass:
- to_send = '\x05\x02\x00\x02'
- else:
- to_send = '\x05\x01\x00'
- self.onreceive(self._on_greeting_sent)
- self.send(to_send)
-
- def _on_greeting_sent(self, reply):
- if reply is None:
- return
- if len(reply) != 2:
- self.on_failure('Invalid proxy reply')
- return
- if reply[0] != '\x05':
- log.info('Invalid proxy reply')
- self.on_failure('Invalid proxy reply')
- return
- if reply[1] == '\x00':
- return self._on_proxy_auth('\x01\x00')
- elif reply[1] == '\x02':
- to_send = '\x01' + chr(len(self.proxy_user)) + self.proxy_user +\
- chr(len(self.proxy_pass)) + self.proxy_pass
- self.onreceive(self._on_proxy_auth)
- self.send(to_send)
- else:
- if reply[1] == '\xff':
- log.error('Authentification to proxy impossible: no acceptable '
- 'auth method')
- self.on_failure('Authentification to proxy impossible: no '
- 'acceptable authentification method')
- return
- log.error('Invalid proxy reply')
- self.on_failure('Invalid proxy reply')
- return
-
- def _on_proxy_auth(self, reply):
- if reply is None:
- return
- if len(reply) != 2:
- log.error('Invalid proxy reply')
- self.on_failure('Invalid proxy reply')
- return
- if reply[0] != '\x01':
- log.error('Invalid proxy reply')
- self.on_failure('Invalid proxy reply')
- return
- if reply[1] != '\x00':
- log.error('Authentification to proxy failed')
- self.on_failure('Authentification to proxy failed')
- return
- log.info('Authentification successfull. Jabber server contacted.')
- # Request connection
- req = "\x05\x01\x00"
- # If the given destination address is an IP address, we'll
- # use the IPv4 address request even if remote resolving was specified.
- try:
- self.ipaddr = socket.inet_aton(self.xmpp_server[0])
- req = req + "\x01" + self.ipaddr
- except socket.error:
- # Well it's not an IP number, so it's probably a DNS name.
-# if self.__proxy[3]==True:
- # Resolve remotely
- self.ipaddr = None
- req = req + "\x03" + chr(len(self.xmpp_server[0])) + self.xmpp_server[0]
-# else:
-# # Resolve locally
-# self.ipaddr = socket.inet_aton(socket.gethostbyname(self.xmpp_server[0]))
-# req = req + "\x01" + ipaddr
- req = req + struct.pack(">H", self.xmpp_server[1])
- self.onreceive(self._on_req_sent)
- self.send(req)
-
- def _on_req_sent(self, reply):
- if reply is None:
- return
- if len(reply) < 10:
- log.error('Invalid proxy reply')
- self.on_failure('Invalid proxy reply')
- return
- if reply[0] != '\x05':
- log.error('Invalid proxy reply')
- self.on_failure('Invalid proxy reply')
- return
- if reply[1] != "\x00":
- # Connection failed
- if ord(reply[1])<9:
- errors = ['general SOCKS server failure',
- 'connection not allowed by ruleset',
- 'Network unreachable',
- 'Host unreachable',
- 'Connection refused',
- 'TTL expired',
- 'Command not supported',
- 'Address type not supported'
- ]
- txt = errors[ord(reply[1])-1]
- else:
- txt = 'Invalid proxy reply'
- log.error(txt)
- self.on_failure(txt)
- return
- # Get the bound address/port
- elif reply[3] == "\x01":
- begin, end = 3, 7
- elif reply[3] == "\x03":
- begin, end = 4, 4 + reply[4]
- else:
- log.error('Invalid proxy reply')
- self.on_failure('Invalid proxy reply')
- return
- self.connecting_over()
diff --git a/src/common/xmpp/roster_nb.py b/src/common/xmpp/roster_nb.py
deleted file mode 100644
index 9f520e3d3..000000000
--- a/src/common/xmpp/roster_nb.py
+++ /dev/null
@@ -1,368 +0,0 @@
-## roster_nb.py
-## based on roster.py
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-## modified by Dimitur Kirov <dkirov@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-# $Id: roster.py,v 1.17 2005/05/02 08:38:49 snakeru Exp $
-
-
-"""
-Simple roster implementation. Can be used though for different tasks like
-mass-renaming of contacts.
-"""
-
-from protocol import JID, Iq, Presence, Node, NodeProcessed, NS_MUC_USER, NS_ROSTER
-from plugin import PlugIn
-
-import logging
-log = logging.getLogger('gajim.c.x.roster_nb')
-
-
-class NonBlockingRoster(PlugIn):
- """
- Defines a plenty of methods that will allow you to manage roster. Also
- automatically track presences from remote JIDs taking into account that
- every JID can have multiple resources connected. Does not currently support
- 'error' presences. You can also use mapping interface for access to the
- internal representation of contacts in roster
- """
-
- def __init__(self, version=None):
- """
- Init internal variables
- """
- PlugIn.__init__(self)
- self.version = version
- self._data = {}
- self._set=None
- self._exported_methods=[self.getRoster]
- self.received_from_server = False
-
- def Request(self, force=0):
- """
- Request roster from server if it were not yet requested (or if the
- 'force' argument is set)
- """
- if self._set is None:
- self._set = 0
- elif not force:
- return
-
- iq = Iq('get', NS_ROSTER)
- if self.version is not None:
- iq.setTagAttr('query', 'ver', self.version)
- id_ = self._owner.getAnID()
- iq.setID(id_)
- self._owner.send(iq)
- log.info('Roster requested from server')
- return id_
-
- def RosterIqHandler(self, dis, stanza):
- """
- Subscription tracker. Used internally for setting items state in internal
- roster representation
- """
- sender = stanza.getAttr('from')
- if not sender is None and not sender.bareMatch(
- self._owner.User + '@' + self._owner.Server):
- return
- query = stanza.getTag('query')
- if query:
- self.received_from_server = True
- self.version = stanza.getTagAttr('query', 'ver')
- if self.version is None:
- self.version = ''
- for item in query.getTags('item'):
- jid=item.getAttr('jid')
- if item.getAttr('subscription')=='remove':
- if self._data.has_key(jid): del self._data[jid]
- # 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')
- self._data[jid]['ask']=item.getAttr('ask')
- self._data[jid]['subscription']=item.getAttr('subscription')
- self._data[jid]['groups']=[]
- if not self._data[jid].has_key('resources'): self._data[jid]['resources']={}
- for group in item.getTags('group'):
- if group.getData() not in self._data[jid]['groups']:
- 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 <iq type='error'/>
-
- def PresenceHandler(self, dis, pres):
- """
- Presence tracker. Used internally for setting items' resources state in
- internal roster representation
- """
- if pres.getTag('x', namespace=NS_MUC_USER):
- return
- jid=pres.getFrom()
- if not jid:
- # If no from attribue, it's from server
- jid=self._owner.Server
- jid=JID(jid)
- if not self._data.has_key(jid.getStripped()): self._data[jid.getStripped()]={'name':None,'ask':None,'subscription':'none','groups':['Not in roster'],'resources':{}}
- if type(self._data[jid.getStripped()]['resources'])!=type(dict()):
- self._data[jid.getStripped()]['resources']={}
- item=self._data[jid.getStripped()]
- typ=pres.getType()
-
- if not typ:
- log.info('Setting roster item %s for resource %s...'%(jid.getStripped(), jid.getResource()))
- item['resources'][jid.getResource()]=res={'show':None,'status':None,'priority':'0','timestamp':None}
- if pres.getTag('show'): res['show']=pres.getShow()
- if pres.getTag('status'): res['status']=pres.getStatus()
- if pres.getTag('priority'): res['priority']=pres.getPriority()
- if not pres.getTimestamp(): pres.setTimestamp()
- res['timestamp']=pres.getTimestamp()
- elif typ=='unavailable' and item['resources'].has_key(jid.getResource()): del item['resources'][jid.getResource()]
- # Need to handle type='error' also
-
- def _getItemData(self, jid, dataname):
- """
- Return specific jid's representation in internal format. Used internally
- """
- jid = jid[:(jid+'/').find('/')]
- return self._data[jid][dataname]
-
- def _getResourceData(self, jid, dataname):
- """
- Return specific jid's resource representation in internal format. Used
- internally
- """
- if jid.find('/') + 1:
- jid, resource = jid.split('/', 1)
- if self._data[jid]['resources'].has_key(resource):
- return self._data[jid]['resources'][resource][dataname]
- elif self._data[jid]['resources'].keys():
- lastpri = -129
- for r in self._data[jid]['resources'].keys():
- if int(self._data[jid]['resources'][r]['priority']) > lastpri:
- resource, lastpri=r, int(self._data[jid]['resources'][r]['priority'])
- return self._data[jid]['resources'][resource][dataname]
-
- def delItem(self, jid):
- """
- Delete contact 'jid' from roster
- """
- self._owner.send(Iq('set', NS_ROSTER, payload=[Node('item', {'jid': jid, 'subscription': 'remove'})]))
-
- def getAsk(self, jid):
- """
- Return 'ask' value of contact 'jid'
- """
- return self._getItemData(jid, 'ask')
-
- def getGroups(self, jid):
- """
- Return groups list that contact 'jid' belongs to
- """
- return self._getItemData(jid, 'groups')
-
- def getName(self, jid):
- """
- Return name of contact 'jid'
- """
- return self._getItemData(jid, 'name')
-
- def getPriority(self, jid):
- """
- Return priority of contact 'jid'. 'jid' should be a full (not bare) JID
- """
- return self._getResourceData(jid, 'priority')
-
- def getRawRoster(self):
- """
- Return roster representation in internal format
- """
- return self._data
-
- def getRawItem(self, jid):
- """
- Return roster item 'jid' representation in internal format
- """
- return self._data[jid[:(jid+'/').find('/')]]
-
- def getShow(self, jid):
- """
- Return 'show' value of contact 'jid'. 'jid' should be a full (not bare)
- JID
- """
- return self._getResourceData(jid, 'show')
-
- def getStatus(self, jid):
- """
- Return 'status' value of contact 'jid'. 'jid' should be a full (not bare)
- JID
- """
- return self._getResourceData(jid, 'status')
-
- def getSubscription(self, jid):
- """
- Return 'subscription' value of contact 'jid'
- """
- return self._getItemData(jid, 'subscription')
-
- def getResources(self, jid):
- """
- Return list of connected resources of contact 'jid'
- """
- return self._data[jid[:(jid+'/').find('/')]]['resources'].keys()
-
- def setItem(self, jid, name=None, groups=[]):
- """
- Rename contact 'jid' and sets the groups list that it now belongs to
- """
- iq = Iq('set', NS_ROSTER)
- query = iq.getTag('query')
- attrs = {'jid': jid}
- if name:
- attrs['name'] = name
- item = query.setTag('item', attrs)
- for group in groups:
- item.addChild(node=Node('group', payload=[group]))
- self._owner.send(iq)
-
- def setItemMulti(self, items):
- """
- Rename multiple contacts and sets their group lists
- """
- iq = Iq('set', NS_ROSTER)
- query = iq.getTag('query')
- for i in items:
- attrs = {'jid': i['jid']}
- if i['name']:
- attrs['name'] = i['name']
- item = query.setTag('item', attrs)
- for group in i['groups']:
- item.addChild(node=Node('group', payload=[group]))
- self._owner.send(iq)
-
- def getItems(self):
- """
- Return list of all [bare] JIDs that the roster is currently tracks
- """
- return self._data.keys()
-
- def keys(self):
- """
- Same as getItems. Provided for the sake of dictionary interface
- """
- return self._data.keys()
-
- def __getitem__(self, item):
- """
- Get the contact in the internal format. Raises KeyError if JID 'item' is
- not in roster
- """
- return self._data[item]
-
- def getItem(self, item):
- """
- Get the contact in the internal format (or None if JID 'item' is not in
- roster)
- """
- if self._data.has_key(item):
- return self._data[item]
-
- def Subscribe(self, jid):
- """
- Send subscription request to JID 'jid'
- """
- self._owner.send(Presence(jid, 'subscribe'))
-
- def Unsubscribe(self, jid):
- """
- Ask for removing our subscription for JID 'jid'
- """
- self._owner.send(Presence(jid, 'unsubscribe'))
-
- def Authorize(self, jid):
- """
- Authorize JID 'jid'. Works only if these JID requested auth previously
- """
- self._owner.send(Presence(jid, 'subscribed'))
-
- def Unauthorize(self, jid):
- """
- Unauthorise JID 'jid'. Use for declining authorisation request or for
- removing existing authorization
- """
- self._owner.send(Presence(jid, 'unsubscribed'))
-
- def getRaw(self):
- """
- Return the internal data representation of the roster
- """
- return self._data
-
- def setRaw(self, data):
- """
- Return the internal data representation of the roster
- """
- self._data = data
- self._data[self._owner.User + '@' + self._owner.Server] = {
- 'resources': {},
- 'name': None,
- 'ask': None,
- 'subscription': None,
- 'groups': None
- }
- self._set = 1
-
- def plugin(self, owner, request=1):
- """
- Register presence and subscription trackers in the owner's dispatcher.
- Also request roster from server if the 'request' argument is set. Used
- internally
- """
- self._owner.RegisterHandler('iq', self.RosterIqHandler, 'result', NS_ROSTER, makefirst = 1)
- self._owner.RegisterHandler('iq', self.RosterIqHandler, 'set', NS_ROSTER)
- self._owner.RegisterHandler('presence', self.PresenceHandler)
- if request:
- return self.Request()
-
- def _on_roster_set(self, data):
- if data:
- self._owner.Dispatcher.ProcessNonBlocking(data)
- if not self._set:
- return
- if not hasattr(self, '_owner') or not self._owner:
- # Connection has been closed by receiving a <stream:error> for ex,
- return
- self._owner.onreceive(None)
- if self.on_ready:
- self.on_ready(self)
- self.on_ready = None
- return True
-
- def getRoster(self, on_ready=None, force=False):
- """
- Request roster from server if neccessary and returns self
- """
- return_self = True
- if not self._set:
- self.on_ready = on_ready
- self._owner.onreceive(self._on_roster_set)
- return_self = False
- elif on_ready:
- on_ready(self)
- return_self = False
- if return_self or force:
- return self
- return None
diff --git a/src/common/xmpp/simplexml.py b/src/common/xmpp/simplexml.py
deleted file mode 100644
index 4a11cda7d..000000000
--- a/src/common/xmpp/simplexml.py
+++ /dev/null
@@ -1,692 +0,0 @@
-## simplexml.py based on Mattew Allum's xmlstream.py
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-# $Id: simplexml.py,v 1.27 2005/04/30 07:20:27 snakeru Exp $
-
-"""
-Simplexml module provides xmpppy library with all needed tools to handle XML
-nodes and XML streams. I'm personally using it in many other separate
-projects. It is designed to be as standalone as possible
-"""
-
-import xml.parsers.expat
-import logging
-log = logging.getLogger('gajim.c.x.simplexml')
-
-def XMLescape(txt):
- """
- Return provided string with symbols & < > " replaced by their respective XML
- entities
- """
- # replace also FORM FEED and ESC, because they are not valid XML chars
- return txt.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;").replace(u'\x0C', "").replace(u'\x1B', "")
-
-ENCODING='utf-8'
-
-def ustr(what):
- """
- Converts object "what" to unicode string using it's own __str__ method if
- accessible or unicode method otherwise
- """
- if isinstance(what, unicode):
- return what
- try:
- r = what.__str__()
- except AttributeError:
- r = str(what)
- if not isinstance(r, unicode):
- return unicode(r, ENCODING)
- return r
-
-class Node(object):
- """
- Node class describes syntax of separate XML Node. It have a constructor that
- permits node creation from set of "namespace name", attributes and payload
- of text strings and other nodes. It does not natively support building node
- from text string and uses NodeBuilder class for that purpose. After
- creation node can be mangled in many ways so it can be completely changed.
- Also node can be serialised into string in one of two modes: default (where
- the textual representation of node describes it exactly) and "fancy" - with
- whitespace added to make indentation and thus make result more readable by
- human.
-
- Node class have attribute FORCE_NODE_RECREATION that is defaults to False
- thus enabling fast node replication from the some other node. The drawback
- of the fast way is that new node shares some info with the "original" node
- that is changing the one node may influence the other. Though it is rarely
- needed (in xmpppy it is never needed at all since I'm usually never using
- original node after replication (and using replication only to move upwards
- on the classes tree).
- """
-
- FORCE_NODE_RECREATION = 0
-
- def __init__(self, tag=None, attrs={}, payload=[], parent=None, nsp=None,
- node_built=False, node=None):
- """
- Takes "tag" argument as the name of node (prepended by namespace, if
- needed and separated from it by a space), attrs dictionary as the set of
- arguments, payload list as the set of textual strings and child nodes
- that this node carries within itself and "parent" argument that is
- another node that this one will be the child of. Also the __init__ can be
- provided with "node" argument that is either a text string containing
- exactly one node or another Node instance to begin with. If both "node"
- and other arguments is provided then the node initially created as
- replica of "node" provided and then modified to be compliant with other
- arguments.
- """
- if node:
- if self.FORCE_NODE_RECREATION and isinstance(node, Node):
- node = str(node)
- if not isinstance(node, Node):
- node = NodeBuilder(node, self)
- node_built = True
- else:
- self.name, self.namespace, self.attrs, self.data, self.kids, self.parent, self.nsd = node.name, node.namespace, {}, [], [], node.parent, {}
- for key in node.attrs.keys():
- self.attrs[key] = node.attrs[key]
- for data in node.data:
- self.data.append(data)
- for kid in node.kids:
- self.kids.append(kid)
- for k, v in node.nsd.items():
- self.nsd[k] = v
- else:
- self.name, self.namespace, self.attrs, self.data, self.kids, self.parent, self.nsd = 'tag', '', {}, [], [], None, {}
- if parent:
- self.parent = parent
- self.nsp_cache = {}
- if nsp:
- for k, v in nsp.items(): self.nsp_cache[k] = v
- for attr, val in attrs.items():
- if attr == 'xmlns':
- self.nsd[u''] = val
- elif attr.startswith('xmlns:'):
- self.nsd[attr[6:]] = val
- self.attrs[attr]=attrs[attr]
- if tag:
- if node_built:
- pfx, self.name = (['']+tag.split(':'))[-2:]
- self.namespace = self.lookup_nsp(pfx)
- else:
- if ' ' in tag:
- self.namespace, self.name = tag.split()
- else:
- self.name = tag
- if isinstance(payload, basestring): payload=[payload]
- for i in payload:
- if isinstance(i, Node):
- self.addChild(node=i)
- else:
- self.data.append(ustr(i))
-
- def lookup_nsp(self, pfx=''):
- ns = self.nsd.get(pfx, None)
- if ns is None:
- ns = self.nsp_cache.get(pfx, None)
- if ns is None:
- if self.parent:
- ns = self.parent.lookup_nsp(pfx)
- self.nsp_cache[pfx] = ns
- else:
- return 'http://www.gajim.org/xmlns/undeclared'
- return ns
-
- def __str__(self, fancy=0):
- """
- Method used to dump node into textual representation. If "fancy" argument
- is set to True produces indented output for readability
- """
- s = (fancy-1) * 2 * ' ' + "<" + self.name
- if self.namespace:
- if not self.parent or self.parent.namespace!=self.namespace:
- if 'xmlns' not in self.attrs:
- s = s + ' xmlns="%s"'%self.namespace
- for key in self.attrs.keys():
- val = ustr(self.attrs[key])
- s = s + ' %s="%s"' % ( key, XMLescape(val) )
- s = s + ">"
- cnt = 0
- if self.kids:
- if fancy: s = s + "\n"
- for a in self.kids:
- if not fancy and (len(self.data)-1)>=cnt: s=s+XMLescape(self.data[cnt])
- elif (len(self.data)-1)>=cnt: s=s+XMLescape(self.data[cnt].strip())
- if isinstance(a, str) or isinstance(a, unicode):
- s = s + a.__str__()
- else:
- s = s + a.__str__(fancy and fancy+1)
- cnt=cnt+1
- if not fancy and (len(self.data)-1) >= cnt: s = s + XMLescape(self.data[cnt])
- elif (len(self.data)-1) >= cnt: s = s + XMLescape(self.data[cnt].strip())
- if not self.kids and s.endswith('>'):
- s=s[:-1]+' />'
- if fancy: s = s + "\n"
- else:
- if fancy and not self.data: s = s + (fancy-1) * 2 * ' '
- s = s + "</" + self.name + ">"
- if fancy: s = s + "\n"
- return s
-
- 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
- else: newnode=Node(tag=name, parent=self, attrs=attrs, payload=payload)
- if namespace:
- newnode.setNamespace(namespace)
- self.kids.append(newnode)
- return newnode
-
- def addData(self, data):
- """
- Add some CDATA to node
- """
- self.data.append(ustr(data))
-
- def clearData(self):
- """
- Remove all CDATA from the node
- """
- self.data = []
-
- def delAttr(self, key):
- """
- Delete an attribute "key"
- """
- del self.attrs[key]
-
- def delChild(self, node, attrs={}):
- """
- Delete the "node" from the node's childs list, if "node" is an instance.
- Else delete the first node that have specified name and (optionally)
- attributes
- """
- if not isinstance(node, Node):
- node = self.getTag(node, attrs)
- self.kids.remove(node)
- return node
-
- def getAttrs(self):
- """
- Return all node's attributes as dictionary
- """
- return self.attrs
-
- def getAttr(self, key):
- """
- Return value of specified attribute
- """
- return self.attrs.get(key)
-
- def getChildren(self):
- """
- Return all node's child nodes as list
- """
- return self.kids
-
- def getData(self):
- """
- Return all node CDATA as string (concatenated)
- """
- return ''.join(self.data)
-
- def getName(self):
- """
- Return the name of node
- """
- return self.name
-
- def getNamespace(self):
- """
- Return the namespace of node
- """
- return self.namespace
-
- def getParent(self):
- """
- Returns the parent of node (if present)
- """
- return self.parent
-
- def getPayload(self):
- """
- Return the payload of node i.e. list of child nodes and CDATA entries.
- F.e. for "<node>text1<nodea/><nodeb/> text2</node>" will be returned
- list: ['text1', <nodea instance>, <nodeb instance>, ' text2']
- """
- ret = []
- for i in range(len(self.kids)+len(self.data)+1):
- try:
- if self.data[i]:
- ret.append(self.data[i])
- except IndexError:
- pass
- try:
- ret.append(self.kids[i])
- except IndexError:
- pass
- return ret
-
- def getTag(self, name, attrs={}, namespace=None):
- """
- Filter all child nodes using specified arguments as filter. Return the
- first found or None if not found
- """
- return self.getTags(name, attrs, namespace, one=1)
-
- def getTagAttr(self, tag, attr):
- """
- Return attribute value of the child with specified name (or None if no
- such attribute)
- """
- try:
- return self.getTag(tag).attrs[attr]
- except:
- return None
-
- def getTagData(self, tag):
- """
- Return cocatenated CDATA of the child with specified name
- """
- try:
- return self.getTag(tag).getData()
- except Exception:
- return None
-
- def getTags(self, name, attrs={}, namespace=None, one=0):
- """
- Filter all child nodes using specified arguments as filter. Returns the
- list of nodes found
- """
- nodes = []
- for node in self.kids:
- if namespace and namespace != node.getNamespace():
- continue
- if node.getName() == name:
- for key in attrs.keys():
- if key not in node.attrs or node.attrs[key]!=attrs[key]:
- break
- else:
- nodes.append(node)
- if one and nodes:
- return nodes[0]
- if not one:
- return nodes
-
- def iterTags(self, name, attrs={}, namespace=None):
- """
- Iterate over all children using specified arguments as filter
- """
- for node in self.kids:
- if namespace is not None and namespace != node.getNamespace():
- continue
- if node.getName() == name:
- for key in attrs.keys():
- if key not in node.attrs or \
- node.attrs[key]!=attrs[key]:
- break
- else:
- yield node
-
- def setAttr(self, key, val):
- """
- Set attribute "key" with the value "val"
- """
- self.attrs[key] = val
-
- def setData(self, data):
- """
- Set node's CDATA to provided string. Resets all previous CDATA!
- """
- self.data = [ustr(data)]
-
- def setName(self, val):
- """
- Change the node name
- """
- self.name = val
-
- def setNamespace(self, namespace):
- """
- Changes the node namespace
- """
- self.namespace = namespace
-
- def setParent(self, node):
- """
- Set node's parent to "node". WARNING: do not checks if the parent already
- present and not removes the node from the list of childs of previous
- parent
- """
- self.parent = node
-
- def setPayload(self, payload, add=0):
- """
- Set node payload according to the list specified. WARNING: completely
- replaces all node's previous content. If you wish just to add child or
- CDATA - use addData or addChild methods
- """
- if isinstance(payload, basestring):
- payload = [payload]
- if add:
- self.kids += payload
- else:
- self.kids = payload
-
- def setTag(self, name, attrs={}, namespace=None):
- """
- Same as getTag but if the node with specified namespace/attributes not
- found, creates such node and returns it
- """
- node = self.getTags(name, attrs, namespace=namespace, one=1)
- if node:
- return node
- else:
- return self.addChild(name, attrs, namespace=namespace)
-
- def setTagAttr(self, tag, attr, val):
- """
- Create new node (if not already present) with name "tag" and set it's
- attribute "attr" to value "val"
- """
- try:
- self.getTag(tag).attrs[attr] = val
- except Exception:
- self.addChild(tag, attrs={attr: val})
-
- def setTagData(self, tag, val, attrs={}):
- """
- Creates new node (if not already present) with name "tag" and
- (optionally) attributes "attrs" and sets it's CDATA to string "val"
- """
- try:
- self.getTag(tag, attrs).setData(ustr(val))
- except Exception:
- self.addChild(tag, attrs, payload = [ustr(val)])
-
- def has_attr(self, key):
- """
- Check if node have attribute "key"
- """
- return key in self.attrs
-
- def __getitem__(self, item):
- """
- Return node's attribute "item" value
- """
- return self.getAttr(item)
-
- def __setitem__(self, item, val):
- """
- Set node's attribute "item" value
- """
- return self.setAttr(item, val)
-
- def __delitem__(self, item):
- """
- Delete node's attribute "item"
- """
- return self.delAttr(item)
-
- def __contains__(self, item):
- """
- Check if node has attribute "item"
- """
- return self.has_attr(item)
-
- def __getattr__(self, attr):
- """
- Reduce memory usage caused by T/NT classes - use memory only when needed
- """
- if attr == 'T':
- self.T = T(self)
- return self.T
- if attr == 'NT':
- self.NT = NT(self)
- return self.NT
- raise AttributeError
-
-class T:
- """
- Auxiliary class used to quick access to node's child nodes
- """
-
- def __init__(self, node):
- self.__dict__['node'] = node
-
- def __getattr__(self, attr):
- return self.node.setTag(attr)
-
- def __setattr__(self, attr, val):
- if isinstance(val, Node):
- Node.__init__(self.node.setTag(attr), node=val)
- else:
- return self.node.setTagData(attr, val)
-
- def __delattr__(self, attr):
- return self.node.delChild(attr)
-
-class NT(T):
- """
- Auxiliary class used to quick create node's child nodes
- """
-
- def __getattr__(self, attr):
- return self.node.addChild(attr)
-
- def __setattr__(self, attr, val):
- if isinstance(val, Node):
- self.node.addChild(attr, node=val)
- else:
- return self.node.addChild(attr, payload=[val])
-
-class NodeBuilder:
- """
- Builds a Node class minidom from data parsed to it. This class used for two
- purposes:
- 1. Creation an XML Node from a textual representation. F.e. reading a
- config file. See an XML2Node method.
- 2. Handling an incoming XML stream. This is done by mangling the
- __dispatch_depth parameter and redefining the dispatch method.
-
- You do not need to use this class directly if you do not designing your own
- XML handler
- """
-
- def __init__(self, data=None, initial_node=None):
- """
- Take two optional parameters: "data" and "initial_node"
-
- By default class initialised with empty Node class instance. Though, if
- "initial_node" is provided it used as "starting point". You can think
- about it as of "node upgrade". "data" (if provided) feeded to parser
- immidiatedly after instance init.
- """
- log.debug("Preparing to handle incoming XML stream.")
- self._parser = xml.parsers.expat.ParserCreate()
- self._parser.StartElementHandler = self.starttag
- self._parser.EndElementHandler = self.endtag
- self._parser.StartNamespaceDeclHandler = self.handle_namespace_start
- self._parser.CharacterDataHandler = self.handle_cdata
- self._parser.buffer_text = True
- self.Parse = self._parser.Parse
-
- self.__depth = 0
- self.__last_depth = 0
- self.__max_depth = 0
- self._dispatch_depth = 1
- self._document_attrs = None
- self._document_nsp = None
- self._mini_dom=initial_node
- self.last_is_data = 1
- self._ptr=None
- self.data_buffer = None
- self.streamError = ''
- if data:
- self._parser.Parse(data, 1)
-
- def check_data_buffer(self):
- if self.data_buffer:
- self._ptr.data.append(''.join(self.data_buffer))
- del self.data_buffer[:]
- self.data_buffer = None
-
- def destroy(self):
- """
- Method used to allow class instance to be garbage-collected
- """
- self.check_data_buffer()
- self._parser.StartElementHandler = None
- self._parser.EndElementHandler = None
- self._parser.CharacterDataHandler = None
- self._parser.StartNamespaceDeclHandler = None
-
- def starttag(self, tag, attrs):
- """
- XML Parser callback. Used internally
- """
- self.check_data_buffer()
- self._inc_depth()
- log.info("STARTTAG.. DEPTH -> %i , tag -> %s, attrs -> %s" % (self.__depth, tag, `attrs`))
- if self.__depth == self._dispatch_depth:
- if not self._mini_dom :
- self._mini_dom = Node(tag=tag, attrs=attrs, nsp = self._document_nsp, node_built=True)
- else:
- Node.__init__(self._mini_dom, tag=tag, attrs=attrs, nsp = self._document_nsp, node_built=True)
- self._ptr = self._mini_dom
- elif self.__depth > self._dispatch_depth:
- self._ptr.kids.append(Node(tag=tag, parent=self._ptr, attrs=attrs, node_built=True))
- self._ptr = self._ptr.kids[-1]
- if self.__depth == 1:
- self._document_attrs = {}
- self._document_nsp = {}
- nsp, name = (['']+tag.split(':'))[-2:]
- for attr, val in attrs.items():
- if attr == 'xmlns':
- self._document_nsp[u''] = val
- elif attr.startswith('xmlns:'):
- self._document_nsp[attr[6:]] = val
- else:
- self._document_attrs[attr] = val
- ns = self._document_nsp.get(nsp, 'http://www.gajim.org/xmlns/undeclared-root')
- try:
- self.stream_header_received(ns, name, attrs)
- except ValueError, e:
- self._document_attrs = None
- raise ValueError(str(e))
- if not self.last_is_data and self._ptr.parent:
- self._ptr.parent.data.append('')
- self.last_is_data = 0
-
- def endtag(self, tag ):
- """
- XML Parser callback. Used internally
- """
- log.info("DEPTH -> %i , tag -> %s" % (self.__depth, tag))
- self.check_data_buffer()
- if self.__depth == self._dispatch_depth:
- if self._mini_dom.getName() == 'error':
- children = self._mini_dom.getChildren()
- if children:
- self.streamError = children[0].getName()
- else:
- self.streamError = self._mini_dom.getData()
- self.dispatch(self._mini_dom)
- elif self.__depth > self._dispatch_depth:
- self._ptr = self._ptr.parent
- else:
- log.info("Got higher than dispatch level. Stream terminated?")
- self._dec_depth()
- self.last_is_data = 0
- if self.__depth == 0: self.stream_footer_received()
-
- def handle_cdata(self, data):
- if self.last_is_data:
- if self.data_buffer:
- self.data_buffer.append(data)
- elif self._ptr:
- self.data_buffer = [data]
- self.last_is_data = 1
-
- def handle_namespace_start(self, prefix, uri):
- """
- XML Parser callback. Used internally
- """
- self.check_data_buffer()
-
- def getDom(self):
- """
- Return just built Node
- """
- self.check_data_buffer()
- return self._mini_dom
-
- def dispatch(self, stanza):
- """
- Get called when the NodeBuilder reaches some level of depth on it's way
- up with the built node as argument. Can be redefined to convert incoming
- XML stanzas to program events
- """
- pass
-
- def stream_header_received(self, ns, tag, attrs):
- """
- Method called when stream just opened
- """
- self.check_data_buffer()
-
- def stream_footer_received(self):
- """
- Method called when stream just closed
- """
- self.check_data_buffer()
-
- def has_received_endtag(self, level=0):
- """
- Return True if at least one end tag was seen (at level)
- """
- return self.__depth <= level and self.__max_depth > level
-
- def _inc_depth(self):
- self.__last_depth = self.__depth
- self.__depth += 1
- self.__max_depth = max(self.__depth, self.__max_depth)
-
- def _dec_depth(self):
- self.__last_depth = self.__depth
- self.__depth -= 1
-
-def XML2Node(xml):
- """
- Convert supplied textual string into XML node. Handy f.e. for reading
- configuration file. Raises xml.parser.expat.parsererror if provided string
- is not well-formed XML
- """
- return NodeBuilder(xml).getDom()
-
-def BadXML2Node(xml):
- """
- Convert supplied textual string into XML node. Survives if xml data is
- cutted half way round. I.e. "<html>some text <br>some more text". Will raise
- xml.parser.expat.parsererror on misplaced tags though. F.e. "<b>some text
- <br>some more text</b>" will not work
- """
- return NodeBuilder(xml).getDom()
diff --git a/src/common/xmpp/smacks.py b/src/common/xmpp/smacks.py
deleted file mode 100644
index d82785ac4..000000000
--- a/src/common/xmpp/smacks.py
+++ /dev/null
@@ -1,132 +0,0 @@
-from protocol import Acks
-from protocol import NS_STREAM_MGMT
-import logging
-log = logging.getLogger('gajim.c.x.smacks')
-
-class Smacks():
- '''
- This is Smacks is the Stream Management class. It takes care of requesting
- and sending acks. Also, it keeps track of the unhandled outgoing stanzas.
-
- The dispatcher has to be able to access this class to increment the
- number of handled stanzas
- '''
-
- def __init__(self, con):
- self.con = con # Connection object
- self.out_h = 0 # Outgoing stanzas handled
- self.in_h = 0 # Incoming stanzas handled
- self.uqueue = [] # Unhandled stanzas queue
- self.session_id = None
- self.resumption = False # If server supports resume
- # Max number of stanzas in queue before making a request
- self.max_queue = 5
- self._owner = None
- self.resuming = False
- self.enabled = False # If SM is enabled
- self.location = None
-
- def set_owner(self, owner):
- self._owner = owner
-
- # Register handlers
- owner.Dispatcher.RegisterNamespace(NS_STREAM_MGMT)
- owner.Dispatcher.RegisterHandler('enabled', self._neg_response,
- xmlns=NS_STREAM_MGMT)
- owner.Dispatcher.RegisterHandler('r', self.send_ack,
- xmlns=NS_STREAM_MGMT)
- owner.Dispatcher.RegisterHandler('a', self.check_ack,
- xmlns=NS_STREAM_MGMT)
- owner.Dispatcher.RegisterHandler('resumed', self.check_ack,
- xmlns=NS_STREAM_MGMT)
- owner.Dispatcher.RegisterHandler('failed', self.error_handling,
- xmlns=NS_STREAM_MGMT)
-
- def _neg_response(self, disp, stanza):
- r = stanza.getAttr('resume')
- if r == 'true' or r == 'True' or r == '1':
- self.resumption = True
- self.session_id = stanza.getAttr('id')
-
- if r == 'false' or r == 'False' or r == '0':
- self.negociate(False)
-
- l = stanza.getAttr('location')
- if l:
- self.location = l
-
- def negociate(self, resume=True):
- # Every time we attempt to negociate, we must erase all previous info
- # about any previous session
- self.uqueue = []
- self.in_h = 0
- self.out_h = 0
- self.session_id = None
- self.enabled = True
-
- stanza = Acks()
- stanza.buildEnable(resume)
- self._owner.Connection.send(stanza, now=True)
-
- def resume_request(self):
- if not self.session_id:
- self.resuming = False
- log.error('Attempted to resume without a valid session id ')
- return
- resume = Acks()
- resume.buildResume(self.in_h, self.session_id)
- self._owner.Connection.send(resume, False)
-
- def send_ack(self, disp, stanza):
- ack = Acks()
- ack.buildAnswer(self.in_h)
- self._owner.Connection.send(ack, False)
-
- def request_ack(self):
- r = Acks()
- r.buildRequest()
- self._owner.Connection.send(r, False)
-
- def check_ack(self, disp, stanza):
- '''
- Checks if the number of stanzas sent are the same as the
- number of stanzas received by the server. Pops stanzas that were
- handled by the server from the queue.
- '''
- h = int(stanza.getAttr('h'))
- diff = self.out_h - h
-
- if len(self.uqueue) < diff or diff < 0:
- log.error('Server and client number of stanzas handled mismatch ')
- else:
- while (len(self.uqueue) > diff):
- self.uqueue.pop(0)
-
- if stanza.getName() == 'resumed':
- self.enabled = True
- self.resuming = True
- self.con.set_oldst()
- if self.uqueue != []:
- for i in self.uqueue:
- self._owner.Connection.send(i, False)
-
- def error_handling(self, disp, stanza):
- # If the server doesn't recognize previd, forget about resuming
- # Ask for service discovery, etc..
- if stanza.getTag('item-not-found'):
- self.resuming = False
- self.enabled = False
- # we need to bind a resource
- self._owner.NonBlockingBind.resuming = False
- self._owner._on_auth_bind(None)
- return
-
- # Doesn't support resumption
- if stanza.getTag('feature-not-implemented'):
- self.negociate(False)
- return
-
- if stanza.getTag('unexpected-request'):
- self.enabled = False
- log.error('Gajim failed to negociate Stream Management')
- return
diff --git a/src/common/xmpp/stringprepare.py b/src/common/xmpp/stringprepare.py
deleted file mode 100644
index 5e3d343b5..000000000
--- a/src/common/xmpp/stringprepare.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# -*- coding:utf-8 -*-
-## src/common/xmpp/stringprepare.py
-##
-## Copyright (C) 2001-2005 Twisted Matrix Laboratories
-## Copyright (C) 2005-2012 Yann Leboulanger <asterix AT lagaule.org>
-## Copyright (C) 2006 Stefan Bethge <stefan AT lanpartei.de>
-## Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-import stringprep
-import unicodedata
-from encodings import idna
-
-class ILookupTable:
- """
- Interface for character lookup classes
- """
-
- def lookup(self, c):
- """
- Return whether character is in this table
- """
- pass
-
-class IMappingTable:
- """
- Interface for character mapping classes
- """
-
- def map(self, c):
- """
- Return mapping for character
- """
- pass
-
-class LookupTableFromFunction:
-
- __implements__ = ILookupTable
-
- def __init__(self, in_table_function):
- self.lookup = in_table_function
-
-class LookupTable:
-
- __implements__ = ILookupTable
-
- def __init__(self, table):
- self._table = table
-
- def lookup(self, c):
- return c in self._table
-
-class MappingTableFromFunction:
-
- __implements__ = IMappingTable
-
- def __init__(self, map_table_function):
- self.map = map_table_function
-
-class EmptyMappingTable:
-
- __implements__ = IMappingTable
-
- def __init__(self, in_table_function):
- self._in_table_function = in_table_function
-
- def map(self, c):
- if self._in_table_function(c):
- return None
- else:
- return c
-
-class Profile:
- def __init__(self, mappings=[], normalize=True, prohibiteds=[],
- check_unassigneds=True, check_bidi=True):
- self.mappings = mappings
- self.normalize = normalize
- self.prohibiteds = prohibiteds
- self.do_check_unassigneds = check_unassigneds
- self.do_check_bidi = check_bidi
-
- def prepare(self, string):
- result = self.map(string)
- if self.normalize:
- result = unicodedata.normalize("NFKC", result)
- self.check_prohibiteds(result)
- if self.do_check_unassigneds:
- self.check_unassigneds(result)
- if self.do_check_bidi:
- self.check_bidirectionals(result)
- return result
-
- def map(self, string):
- result = []
-
- for c in string:
- result_c = c
-
- for mapping in self.mappings:
- result_c = mapping.map(c)
- if result_c != c:
- break
-
- if result_c is not None:
- result.append(result_c)
-
- return u"".join(result)
-
- def check_prohibiteds(self, string):
- for c in string:
- for table in self.prohibiteds:
- if table.lookup(c):
- raise UnicodeError, "Invalid character %s" % repr(c)
-
- def check_unassigneds(self, string):
- for c in string:
- if stringprep.in_table_a1(c):
- raise UnicodeError, "Unassigned code point %s" % repr(c)
-
- def check_bidirectionals(self, string):
- found_LCat = False
- found_RandALCat = False
-
- for c in string:
- if stringprep.in_table_d1(c):
- found_RandALCat = True
- if stringprep.in_table_d2(c):
- found_LCat = True
-
- if found_LCat and found_RandALCat:
- raise UnicodeError, "Violation of BIDI Requirement 2"
-
- if found_RandALCat and not (stringprep.in_table_d1(string[0]) and
- stringprep.in_table_d1(string[-1])):
- raise UnicodeError, "Violation of BIDI Requirement 3"
-
-
-class NamePrep:
- """
- Implements preparation of internationalized domain names
-
- This class implements preparing internationalized domain names using the
- rules defined in RFC 3491, section 4 (Conversion operations).
-
- We do not perform step 4 since we deal with unicode representations of
- domain names and do not convert from or to ASCII representations using
- punycode encoding. When such a conversion is needed, the L{idna} standard
- library provides the C{ToUnicode()} and C{ToASCII()} functions. Note that
- L{idna} itself assumes UseSTD3ASCIIRules to be false.
-
- The following steps are performed by C{prepare()}:
-
- * Split the domain name in labels at the dots (RFC 3490, 3.1)
- * Apply nameprep proper on each label (RFC 3491)
- * Enforce the restrictions on ASCII characters in host names by
- assuming STD3ASCIIRules to be true. (STD 3)
- * Rejoin the labels using the label separator U+002E (full stop).
- """
-
- # Prohibited characters.
- prohibiteds = [unichr(n) for n in range(0x00, 0x2c + 1) +
- range(0x2e, 0x2f + 1) +
- range(0x3a, 0x40 + 1) +
- range(0x5b, 0x60 + 1) +
- range(0x7b, 0x7f + 1) ]
-
- def prepare(self, string):
- result = []
-
- labels = idna.dots.split(string)
-
- if labels and len(labels[-1]) == 0:
- trailing_dot = '.'
- del labels[-1]
- else:
- trailing_dot = ''
-
- for label in labels:
- result.append(self.nameprep(label))
-
- return ".".join(result)+trailing_dot
-
- def check_prohibiteds(self, string):
- for c in string:
- if c in self.prohibiteds:
- raise UnicodeError, "Invalid character %s" % repr(c)
-
- def nameprep(self, label):
- label = idna.nameprep(label)
- self.check_prohibiteds(label)
- if len(label) == 0:
- raise UnicodeError, "Invalid empty name"
- if label[0] == '-':
- raise UnicodeError, "Invalid leading hyphen-minus"
- if label[-1] == '-':
- raise UnicodeError, "Invalid trailing hyphen-minus"
- return label
-
-C_11 = LookupTableFromFunction(stringprep.in_table_c11)
-C_12 = LookupTableFromFunction(stringprep.in_table_c12)
-C_21 = LookupTableFromFunction(stringprep.in_table_c21)
-C_22 = LookupTableFromFunction(stringprep.in_table_c22)
-C_3 = LookupTableFromFunction(stringprep.in_table_c3)
-C_4 = LookupTableFromFunction(stringprep.in_table_c4)
-C_5 = LookupTableFromFunction(stringprep.in_table_c5)
-C_6 = LookupTableFromFunction(stringprep.in_table_c6)
-C_7 = LookupTableFromFunction(stringprep.in_table_c7)
-C_8 = LookupTableFromFunction(stringprep.in_table_c8)
-C_9 = LookupTableFromFunction(stringprep.in_table_c9)
-
-B_1 = EmptyMappingTable(stringprep.in_table_b1)
-B_2 = MappingTableFromFunction(stringprep.map_table_b2)
-
-nodeprep = Profile(mappings=[B_1, B_2],
- prohibiteds=[C_11, C_12, C_21, C_22,
- C_3, C_4, C_5, C_6, C_7, C_8, C_9,
- LookupTable([u'"', u'&', u"'", u'/',
- u':', u'<', u'>', u'@'])])
-
-resourceprep = Profile(mappings=[B_1,],
- prohibiteds=[C_12, C_21, C_22,
- C_3, C_4, C_5, C_6, C_7, C_8, C_9])
-
-nameprep = NamePrep()
diff --git a/src/common/xmpp/tls_nb.py b/src/common/xmpp/tls_nb.py
deleted file mode 100644
index 9425bcf17..000000000
--- a/src/common/xmpp/tls_nb.py
+++ /dev/null
@@ -1,461 +0,0 @@
-## tls_nb.py
-## based on transports_nb.py
-##
-## Copyright (C) 2003-2004 Alexey "Snake" Nezhdanov
-## modified by Dimitur Kirov <dkirov@gmail.com>
-## modified by Tomas Karasek <tom.to.the.k@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-import socket
-from plugin import PlugIn
-
-import sys
-import os
-import time
-
-import traceback
-
-import logging
-log = logging.getLogger('gajim.c.x.tls_nb')
-
-USE_PYOPENSSL = False
-
-PYOPENSSL = 'PYOPENSSL'
-PYSTDLIB = 'PYSTDLIB'
-
-try:
- #raise ImportError("Manually disabled PyOpenSSL")
- import OpenSSL.SSL
- import OpenSSL.crypto
- USE_PYOPENSSL = True
- log.info("PyOpenSSL loaded")
-except ImportError:
- log.debug("Import of PyOpenSSL failed:", exc_info=True)
-
- # FIXME: Remove these prints before release, replace with a warning dialog.
- print >> sys.stderr, "=" * 79
- print >> sys.stderr, "PyOpenSSL not found, falling back to Python builtin SSL objects (insecure)."
- print >> sys.stderr, "=" * 79
-
-def gattr(obj, attr, default=None):
- try:
- return getattr(obj, attr)
- except AttributeError:
- return default
-
-
-class SSLWrapper:
- """
- Abstract SSLWrapper base class
- """
-
- class Error(IOError):
- """
- Generic SSL Error Wrapper
- """
-
- def __init__(self, sock=None, exc=None, errno=None, strerror=None,
- peer=None):
- self.parent = IOError
-
- errno = errno or gattr(exc, 'errno') or exc[0]
- strerror = strerror or gattr(exc, 'strerror') or gattr(exc, 'args')
- if not isinstance(strerror, basestring):
- strerror = repr(strerror)
-
- self.sock = sock
- self.exc = exc
- self.peer = peer
- self.exc_name = None
- self.exc_args = None
- self.exc_str = None
- self.exc_repr = None
-
- if self.exc is not None:
- self.exc_name = str(self.exc.__class__)
- self.exc_args = gattr(self.exc, 'args')
- self.exc_str = str(self.exc)
- self.exc_repr = repr(self.exc)
- if not errno:
- try:
- if isinstance(exc, OpenSSL.SSL.SysCallError):
- if self.exc_args[0] > 0:
- errno = self.exc_args[0]
- strerror = self.exc_args[1]
- except: pass
-
- self.parent.__init__(self, errno, strerror)
-
- if self.peer is None and sock is not None:
- try:
- ppeer = self.sock.getpeername()
- if len(ppeer) == 2 and isinstance(ppeer[0], basestring) \
- and isinstance(ppeer[1], int):
- self.peer = ppeer
- except:
- pass
-
- def __str__(self):
- s = str(self.__class__)
- if self.peer:
- s += " for %s:%d" % self.peer
- if self.errno is not None:
- s += ": [Errno: %d]" % self.errno
- if self.strerror:
- s += " (%s)" % self.strerror
- if self.exc_name:
- s += ", Caused by %s" % self.exc_name
- if self.exc_str:
- if self.strerror:
- s += "(%s)" % self.exc_str
- else: s += "(%s)" % str(self.exc_args)
- return s
-
- def __init__(self, sslobj, sock=None):
- self.sslobj = sslobj
- self.sock = sock
- log.debug("%s.__init__ called with %s", self.__class__, sslobj)
-
- def recv(self, data, flags=None):
- """
- Receive wrapper for SSL object
-
- We can return None out of this function to signal that no data is
- available right now. Better than an exception, which differs
- depending on which SSL lib we're using. Unfortunately returning ''
- can indicate that the socket has been closed, so to be sure, we avoid
- this by returning None.
- """
- raise NotImplementedError
-
- def send(self, data, flags=None, now=False):
- """
- Send wrapper for SSL object
- """
- raise NotImplementedError
-
-
-class PyOpenSSLWrapper(SSLWrapper):
- """
- Wrapper class for PyOpenSSL's recv() and send() methods
- """
-
- def __init__(self, *args):
- self.parent = SSLWrapper
- self.parent.__init__(self, *args)
-
- def is_numtoolarge(self, e):
- ''' Magic methods don't need documentation '''
- t = ('asn1 encoding routines', 'a2d_ASN1_OBJECT', 'first num too large')
- return (isinstance(e.args, (list, tuple)) and len(e.args) == 1 and
- isinstance(e.args[0], (list, tuple)) and len(e.args[0]) == 2 and
- e.args[0][0] == e.args[0][1] == t)
-
- def recv(self, bufsize, flags=None):
- retval = None
- try:
- if flags is None:
- retval = self.sslobj.recv(bufsize)
- else:
- retval = self.sslobj.recv(bufsize, flags)
- except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError), e:
- log.debug("Recv: Want-error: " + repr(e))
- except OpenSSL.SSL.SysCallError, e:
- log.debug("Recv: Got OpenSSL.SSL.SysCallError: " + repr(e),
- exc_info=True)
- raise SSLWrapper.Error(self.sock or self.sslobj, e)
- except OpenSSL.SSL.ZeroReturnError, e:
- # end-of-connection raises ZeroReturnError instead of having the
- # connection's .recv() method return a zero-sized result.
- raise SSLWrapper.Error(self.sock or self.sslobj, e, -1)
- except OpenSSL.SSL.Error, e:
- if self.is_numtoolarge(e):
- # warn, but ignore this exception
- log.warning("Recv: OpenSSL: asn1enc: first num too large (ignored)")
- else:
- log.debug("Recv: Caught OpenSSL.SSL.Error:", exc_info=True)
- raise SSLWrapper.Error(self.sock or self.sslobj, e)
- return retval
-
- def send(self, data, flags=None, now=False):
- try:
- if flags is None:
- return self.sslobj.send(data)
- else:
- return self.sslobj.send(data, flags)
- except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError), e:
- #log.debug("Send: " + repr(e))
- time.sleep(0.1) # prevent 100% CPU usage
- except OpenSSL.SSL.SysCallError, e:
- log.error("Send: Got OpenSSL.SSL.SysCallError: " + repr(e),
- exc_info=True)
- raise SSLWrapper.Error(self.sock or self.sslobj, e)
- except OpenSSL.SSL.Error, e:
- if self.is_numtoolarge(e):
- # warn, but ignore this exception
- log.warning("Send: OpenSSL: asn1enc: first num too large (ignored)")
- else:
- log.error("Send: Caught OpenSSL.SSL.Error:", exc_info=True)
- raise SSLWrapper.Error(self.sock or self.sslobj, e)
- return 0
-
-
-class StdlibSSLWrapper(SSLWrapper):
- """
- Wrapper class for Python socket.ssl read() and write() methods
- """
-
- def __init__(self, *args):
- self.parent = SSLWrapper
- self.parent.__init__(self, *args)
-
- def recv(self, bufsize, flags=None):
- # we simply ignore flags since ssl object doesn't support it
- try:
- return self.sslobj.read(bufsize)
- except socket.sslerror, e:
- log.debug("Recv: Caught socket.sslerror: " + repr(e), exc_info=True)
- if e.args[0] not in (socket.SSL_ERROR_WANT_READ, socket.SSL_ERROR_WANT_WRITE):
- raise SSLWrapper.Error(self.sock or self.sslobj, e)
- return None
-
- def send(self, data, flags=None, now=False):
- # we simply ignore flags since ssl object doesn't support it
- try:
- return self.sslobj.write(data)
- except socket.sslerror, e:
- log.debug("Send: Caught socket.sslerror:", exc_info=True)
- if e.args[0] not in (socket.SSL_ERROR_WANT_READ, socket.SSL_ERROR_WANT_WRITE):
- raise SSLWrapper.Error(self.sock or self.sslobj, e)
- return 0
-
-
-class NonBlockingTLS(PlugIn):
- """
- TLS connection used to encrypts already estabilished tcp connection
-
- Can be plugged into NonBlockingTCP and will make use of StdlibSSLWrapper or
- PyOpenSSLWrapper.
- """
-
- def __init__(self, cacerts, mycerts):
- """
- :param cacerts: path to pem file with certificates of known XMPP servers
- :param mycerts: path to pem file with certificates of user trusted servers
- """
- PlugIn.__init__(self)
- self.cacerts = cacerts
- self.mycerts = mycerts
-
- # from ssl.h (partial extract)
- ssl_h_bits = { "SSL_ST_CONNECT": 0x1000, "SSL_ST_ACCEPT": 0x2000,
- "SSL_CB_LOOP": 0x01, "SSL_CB_EXIT": 0x02,
- "SSL_CB_READ": 0x04, "SSL_CB_WRITE": 0x08,
- "SSL_CB_ALERT": 0x4000,
- "SSL_CB_HANDSHAKE_START": 0x10, "SSL_CB_HANDSHAKE_DONE": 0x20}
-
- def plugin(self, owner):
- """
- Use to PlugIn TLS into transport and start establishing immediately.
- Returns True if TLS/SSL was established correctly, otherwise False
- """
- log.info('Starting TLS estabilishing')
- try:
- res = self._startSSL()
- except Exception, e:
- log.error("PlugIn: while trying _startSSL():", exc_info=True)
- return False
- return res
-
- def _dumpX509(self, cert, stream=sys.stderr):
- print >> stream, "Digest (SHA-1):", cert.digest("sha1")
- print >> stream, "Digest (MD5):", cert.digest("md5")
- print >> stream, "Serial #:", cert.get_serial_number()
- print >> stream, "Version:", cert.get_version()
- print >> stream, "Expired:", ("Yes" if cert.has_expired() else "No")
- print >> stream, "Subject:"
- self._dumpX509Name(cert.get_subject(), stream)
- print >> stream, "Issuer:"
- self._dumpX509Name(cert.get_issuer(), stream)
- self._dumpPKey(cert.get_pubkey(), stream)
-
- def _dumpX509Name(self, name, stream=sys.stderr):
- print >> stream, "X509Name:", str(name)
-
- def _dumpPKey(self, pkey, stream=sys.stderr):
- typedict = {OpenSSL.crypto.TYPE_RSA: "RSA",
- OpenSSL.crypto.TYPE_DSA: "DSA"}
- print >> stream, "PKey bits:", pkey.bits()
- print >> stream, "PKey type: %s (%d)" % (typedict.get(pkey.type(),
- "Unknown"), pkey.type())
-
- def _startSSL(self):
- """
- Immediatedly switch socket to TLS mode. Used internally
- """
- log.debug("_startSSL called")
-
- if USE_PYOPENSSL:
- result = self._startSSL_pyOpenSSL()
- else:
- result = self._startSSL_stdlib()
-
- if result:
- log.debug('Synchronous handshake completed')
- return True
- else:
- return False
-
- def _load_cert_file(self, cert_path, cert_store, logg=True):
- if not os.path.isfile(cert_path):
- return
- try:
- f = open(cert_path)
- except IOError, e:
- log.warning('Unable to open certificate file %s: %s' % \
- (cert_path, str(e)))
- return
- lines = f.readlines()
- i = 0
- begin = -1
- for line in lines:
- if 'BEGIN CERTIFICATE' in line:
- begin = i
- elif 'END CERTIFICATE' in line and begin > -1:
- cert = ''.join(lines[begin:i+2])
- try:
- x509cert = OpenSSL.crypto.load_certificate(
- OpenSSL.crypto.FILETYPE_PEM, cert)
- cert_store.add_cert(x509cert)
- except OpenSSL.crypto.Error, exception_obj:
- if logg:
- log.warning('Unable to load a certificate from file %s: %s' %\
- (cert_path, exception_obj.args[0][0][2]))
- except:
- log.warning('Unknown error while loading certificate from file '
- '%s' % cert_path)
- begin = -1
- i += 1
-
- def _startSSL_pyOpenSSL(self):
- log.debug("_startSSL_pyOpenSSL called")
- tcpsock = self._owner
- # NonBlockingHTTPBOSH instance has no attribute _owner
- if hasattr(tcpsock, '_owner') and tcpsock._owner._caller.client_cert \
- and os.path.exists(tcpsock._owner._caller.client_cert):
- conn = tcpsock._owner._caller
- # FIXME make a checkbox for Client Cert / SSLv23 / TLSv1
- # If we are going to use a client cert/key pair for authentication,
- # we choose TLSv1 method.
- tcpsock._sslContext = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
- log.debug('Using client cert and key from %s' % conn.client_cert)
- try:
- p12 = OpenSSL.crypto.load_pkcs12(open(conn.client_cert).read(),
- conn.client_cert_passphrase)
- except OpenSSL.crypto.Error, exception_obj:
- log.warning('Unable to load client pkcs12 certificate from '
- 'file %s: %s ... Is it a valid PKCS12 cert?' % \
- (conn.client_cert, exception_obj.args))
- except:
- log.warning('Unknown error while loading certificate from file '
- '%s' % conn.client_cert)
- else:
- log.info('PKCS12 Client cert loaded OK')
- try:
- tcpsock._sslContext.use_certificate(p12.get_certificate())
- tcpsock._sslContext.use_privatekey(p12.get_privatekey())
- log.info('p12 cert and key loaded')
- except OpenSSL.crypto.Error, exception_obj:
- log.warning('Unable to extract client certificate from '
- 'file %s' % conn.client_cert)
- except Exception, msg:
- log.warning('Unknown error extracting client certificate '
- 'from file %s: %s' % (conn.client_cert, msg))
- else:
- log.info('client cert and key loaded OK')
- else:
- # See http://docs.python.org/dev/library/ssl.html
- tcpsock._sslContext = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
- flags = OpenSSL.SSL.OP_NO_SSLv2
- try:
- flags |= OpenSSL.SSL.OP_NO_TICKET
- except AttributeError, e:
- # py-OpenSSL < 0.9 or old OpenSSL
- flags |= 16384
- tcpsock._sslContext.set_options(flags)
-
- tcpsock.ssl_errnum = 0
- tcpsock._sslContext.set_verify(OpenSSL.SSL.VERIFY_PEER,
- self._ssl_verify_callback)
- try:
- tcpsock._sslContext.load_verify_locations(self.cacerts)
- except:
- log.warning('Unable to load SSL certificates from file %s' % \
- os.path.abspath(self.cacerts))
- store = tcpsock._sslContext.get_cert_store()
- self._load_cert_file(self.mycerts, store)
- if os.path.isdir('/etc/ssl/certs'):
- for f in os.listdir('/etc/ssl/certs'):
- # We don't logg because there is a lot a duplicated certs in this
- # folder
- self._load_cert_file(os.path.join('/etc/ssl/certs', f), store,
- logg=False)
-
- tcpsock._sslObj = OpenSSL.SSL.Connection(tcpsock._sslContext,
- tcpsock._sock)
- tcpsock._sslObj.set_connect_state() # set to client mode
- wrapper = PyOpenSSLWrapper(tcpsock._sslObj)
- tcpsock._recv = wrapper.recv
- tcpsock._send = wrapper.send
-
- log.debug("Initiating handshake...")
- try:
- tcpsock._sslObj.do_handshake()
- except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError), e:
- pass
- except:
- log.error('Error while TLS handshake: ', exc_info=True)
- return False
- self._owner.ssl_lib = PYOPENSSL
- return True
-
- def _startSSL_stdlib(self):
- log.debug("_startSSL_stdlib called")
- tcpsock=self._owner
- try:
- tcpsock._sock.setblocking(True)
- tcpsock._sslObj = socket.ssl(tcpsock._sock, None, None)
- tcpsock._sock.setblocking(False)
- tcpsock._sslIssuer = tcpsock._sslObj.issuer()
- tcpsock._sslServer = tcpsock._sslObj.server()
- wrapper = StdlibSSLWrapper(tcpsock._sslObj, tcpsock._sock)
- tcpsock._recv = wrapper.recv
- tcpsock._send = wrapper.send
- except:
- log.error("Exception caught in _startSSL_stdlib:", exc_info=True)
- return False
- self._owner.ssl_lib = PYSTDLIB
- return True
-
- def _ssl_verify_callback(self, sslconn, cert, errnum, depth, ok):
- # Exceptions can't propagate up through this callback, so print them here.
- try:
- self._owner.ssl_fingerprint_sha1 = cert.digest('sha1')
- self._owner.ssl_certificate = cert
- self._owner.ssl_errnum = errnum
- self._owner.ssl_cert_pem = OpenSSL.crypto.dump_certificate(
- OpenSSL.crypto.FILETYPE_PEM, cert)
- return True
- except:
- log.error("Exception caught in _ssl_info_callback:", exc_info=True)
- # Make sure something is printed, even if log is disabled.
- traceback.print_exc()
diff --git a/src/common/xmpp/transports_nb.py b/src/common/xmpp/transports_nb.py
deleted file mode 100644
index 9430ef654..000000000
--- a/src/common/xmpp/transports_nb.py
+++ /dev/null
@@ -1,786 +0,0 @@
-## transports_nb.py
-## based on transports.py
-##
-## Copyright (C) 2003-2004 Alexey "Snake" Nezhdanov
-## modified by Dimitur Kirov <dkirov@gmail.com>
-## modified by Tomas Karasek <tom.to.the.k@gmail.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-"""
-Transports are objects responsible for connecting to XMPP server and putting
-data to wrapped sockets in in desired form (SSL, TLS, TCP, for HTTP proxy,
-for SOCKS5 proxy...)
-
-Transports are not aware of XMPP stanzas and only responsible for low-level
-connection handling.
-"""
-
-from simplexml import ustr
-from plugin import PlugIn
-from idlequeue import IdleObject
-import proxy_connectors
-import tls_nb
-
-import socket
-import errno
-import time
-import traceback
-import base64
-import urlparse
-
-import logging
-log = logging.getLogger('gajim.c.x.transports_nb')
-
-def urisplit(uri):
- """
- Function for splitting URI string to tuple (protocol, host, port, path).
- e.g. urisplit('http://httpcm.jabber.org:123/webclient') returns ('http',
- 'httpcm.jabber.org', 123, '/webclient') return 443 as default port if proto
- is https else 80
- """
- splitted = urlparse.urlsplit(uri)
- proto, host, path = splitted.scheme, splitted.hostname, splitted.path
- try:
- port = splitted.port
- except ValueError:
- log.warn('port cannot be extracted from BOSH URL %s, using default port' \
- % uri)
- port = ''
- if not port:
- if proto == 'https':
- port = 443
- else:
- port = 80
- return proto, host, port, path
-
-def get_proxy_data_from_dict(proxy):
- tcp_host, tcp_port, proxy_user, proxy_pass = None, None, None, None
- proxy_type = proxy['type']
- if proxy_type == 'bosh' and not proxy['bosh_useproxy']:
- # with BOSH not over proxy we have to parse the hostname from BOSH URI
- proto, tcp_host, tcp_port, path = urisplit(proxy['bosh_uri'])
- else:
- # with proxy!=bosh or with bosh over HTTP proxy we're connecting to proxy
- # machine
- tcp_host, tcp_port = proxy['host'], proxy['port']
- if proxy.get('useauth', False):
- proxy_user, proxy_pass = proxy['user'], proxy['pass']
- return tcp_host, tcp_port, proxy_user, proxy_pass
-
-#: timeout to connect to the server socket, it doesn't include auth
-CONNECT_TIMEOUT_SECONDS = 30
-
-#: how long to wait for a disconnect to complete
-DISCONNECT_TIMEOUT_SECONDS = 5
-
-#: size of the buffer which reads data from server
-# if lower, more stanzas will be fragmented and processed twice
-RECV_BUFSIZE = 32768 # 2x maximum size of ssl packet, should be plenty
-# FIXME: (#2634) gajim breaks with #RECV_BUFSIZE = 16
-# it's inefficient but should work. Problem is that connect machine makes wrong
-# assumptions and that we only check for pending data in sockets but not in SSL
-# buffer...
-
-DATA_RECEIVED = 'DATA RECEIVED'
-DATA_SENT = 'DATA SENT'
-DATA_ERROR = 'DATA ERROR'
-
-DISCONNECTED = 'DISCONNECTED'
-DISCONNECTING = 'DISCONNECTING'
-CONNECTING = 'CONNECTING'
-PROXY_CONNECTING = 'PROXY_CONNECTING'
-CONNECTED = 'CONNECTED'
-STATES = (DISCONNECTED, CONNECTING, PROXY_CONNECTING, CONNECTED, DISCONNECTING)
-
-class NonBlockingTransport(PlugIn):
- """
- Abstract class representing a transport
-
- Subclasses CAN have different constructor signature but connect method SHOULD
- be the same.
- """
-
- def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
- certs):
- """
- Each trasport class can have different constructor but it has to have at
- least all the arguments of NonBlockingTransport constructor
-
- :param raise_event: callback for monitoring of sent and received data
- :param on_disconnect: callback called on disconnection during runtime
- :param idlequeue: processing idlequeue
- :param estabilish_tls: boolean whether to estabilish TLS connection after
- TCP connection is done
- :param certs: tuple of (cacerts, mycerts) see constructor of
- tls_nb.NonBlockingTLS for more details
- """
- PlugIn.__init__(self)
- self.raise_event = raise_event
- self.on_disconnect = on_disconnect
- self.on_connect = None
- self.on_connect_failure = None
- self.idlequeue = idlequeue
- self.on_receive = None
- self.server = None
- self.port = None
- self.conn_5tuple = None
- self.set_state(DISCONNECTED)
- self.estabilish_tls = estabilish_tls
- self.certs = certs
- # type of used ssl lib (if any) will be assigned to this member var
- self.ssl_lib = None
- self._exported_methods=[self.onreceive, self.set_send_timeout,
- self.set_send_timeout2, self.set_timeout, self.remove_timeout,
- self.start_disconnect]
-
- # time to wait for SOME stanza to come and then send keepalive
- self.sendtimeout = 0
-
- # in case we want to something different than sending keepalives
- self.on_timeout = None
- self.on_timeout2 = None
-
- def plugin(self, owner):
- owner.Connection = self
-
- def plugout(self):
- self._owner.Connection = None
- self._owner = None
- self.disconnect(do_callback=False)
-
- def connect(self, conn_5tuple, on_connect, on_connect_failure):
- """
- Creates and connects transport to server and port defined in conn_5tuple
- which should be item from list returned from getaddrinfo
-
- :param conn_5tuple: 5-tuple returned from getaddrinfo
- :param on_connect: callback called on successful connect to the server
- :param on_connect_failure: callback called on failure when connecting
- """
- self.on_connect = on_connect
- self.on_connect_failure = on_connect_failure
- self.server, self.port = conn_5tuple[4][:2]
- self.conn_5tuple = conn_5tuple
-
- def set_state(self, newstate):
- assert(newstate in STATES)
- self.state = newstate
-
- def get_state(self):
- return self.state
-
- def _on_connect(self):
- """
- Preceeds call of on_connect callback
- """
- # data is reference to socket wrapper instance. We don't need it in client
- # because
- self.set_state(CONNECTED)
- self.on_connect()
-
- def _on_connect_failure(self, err_message):
- """
- Preceeds call of on_connect_failure callback
- """
- # In case of error while connecting we need to disconnect transport
- # but we don't want to call DisconnectHandlers from client,
- # thus the do_callback=False
- self.disconnect(do_callback=False)
- self.on_connect_failure(err_message=err_message)
-
- def send(self, raw_data, now=False):
- if self.get_state() == DISCONNECTED:
- log.error('Unable to send %s \n because state is %s.' %
- (raw_data, self.get_state()))
-
- def disconnect(self, do_callback=True):
- self.set_state(DISCONNECTED)
- if do_callback:
- # invoke callback given in __init__
- self.on_disconnect()
-
- def onreceive(self, recv_handler):
- """
- Set the on_receive callback.
-
- onreceive(None) sets callback to Dispatcher.ProcessNonBlocking which is
- the default one that will decide what to do with received stanza based on
- its tag name and namespace.
-
- Do not confuse it with on_receive() method, which is the callback
- itself.
- """
- if not recv_handler:
- if hasattr(self, '_owner') and hasattr(self._owner, 'Dispatcher'):
- self.on_receive = self._owner.Dispatcher.ProcessNonBlocking
- else:
- log.warn('No Dispatcher plugged. Received data will not be processed')
- self.on_receive = None
- return
- self.on_receive = recv_handler
-
- def _tcp_connecting_started(self):
- self.set_state(CONNECTING)
-
- def read_timeout(self):
- """
- Called when there's no response from server in defined timeout
- """
- if self.on_timeout:
- self.on_timeout()
- self.renew_send_timeout()
-
- def read_timeout2(self):
- """
- called when there's no response from server in defined timeout
- """
- if self.on_timeout2:
- self.on_timeout2()
- self.renew_send_timeout2()
-
- def renew_send_timeout(self):
- if self.on_timeout and self.sendtimeout > 0:
- self.set_timeout(self.sendtimeout)
-
- def renew_send_timeout2(self):
- if self.on_timeout2 and self.sendtimeout2 > 0:
- self.set_timeout2(self.sendtimeout2)
-
- def set_timeout(self, timeout):
- self.idlequeue.set_read_timeout(self.fd, timeout)
-
- def set_timeout2(self, timeout2):
- self.idlequeue.set_read_timeout(self.fd, timeout2, self.read_timeout2)
-
- def get_fd(self):
- pass
-
- def remove_timeout(self):
- self.idlequeue.remove_timeout(self.fd)
-
- def set_send_timeout(self, timeout, on_timeout):
- self.sendtimeout = timeout
- if self.sendtimeout > 0:
- self.on_timeout = on_timeout
- else:
- self.on_timeout = None
-
- def set_send_timeout2(self, timeout2, on_timeout2):
- self.sendtimeout2 = timeout2
- if self.sendtimeout2 > 0:
- self.on_timeout2 = on_timeout2
- else:
- self.on_timeout2 = None
-
- # FIXME: where and why does this need to be called
- def start_disconnect(self):
- self.set_state(DISCONNECTING)
-
-
-class NonBlockingTCP(NonBlockingTransport, IdleObject):
- """
- Non-blocking TCP socket wrapper
-
- It is used for simple XMPP connection. Can be connected via proxy and can
- estabilish TLS connection.
- """
- def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
- certs, proxy_dict=None):
- """
- :param proxy_dict: dictionary with proxy data as loaded from config file
- """
- NonBlockingTransport.__init__(self, raise_event, on_disconnect, idlequeue,
- estabilish_tls, certs)
- IdleObject.__init__(self)
-
- # queue with messages to be send
- self.sendqueue = []
-
- # bytes remained from the last send message
- self.sendbuff = ''
-
- self.proxy_dict = proxy_dict
- self.on_remote_disconnect = self.disconnect
-
- # FIXME: transport should not be aware xmpp
- def start_disconnect(self):
- NonBlockingTransport.start_disconnect(self)
- self.send('</stream:stream>', now=True)
- self.disconnect()
-
- def connect(self, conn_5tuple, on_connect, on_connect_failure):
- NonBlockingTransport.connect(self, conn_5tuple, on_connect,
- on_connect_failure)
- log.info('NonBlockingTCP Connect :: About to connect to %s:%s' %
- (self.server, self.port))
-
- try:
- self._sock = socket.socket(*conn_5tuple[:3])
- except socket.error, (errnum, errstr):
- self._on_connect_failure('NonBlockingTCP Connect: Error while creating\
- socket: %s %s' % (errnum, errstr))
- return
-
- self._send = self._sock.send
- self._recv = self._sock.recv
- self.fd = self._sock.fileno()
-
- # we want to be notified when send is possible to connected socket because
- # it means the TCP connection is estabilished
- self._plug_idle(writable=True, readable=False)
- self.peerhost = None
-
- # variable for errno symbol that will be found from exception raised
- # from connect()
- errnum = 0
- errstr = str()
-
- # set timeout for TCP connecting - if nonblocking connect() fails, pollend
- # is called. If if succeeds pollout is called.
- self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT_SECONDS)
-
- try:
- self._sock.setblocking(False)
- self._sock.connect((self.server, self.port))
- except Exception, exc:
- errnum, errstr = exc.args
-
- if errnum in (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK):
- # connecting in progress
- log.info('After NB connect() of %s. "%s" raised => CONNECTING' %
- (id(self), errstr))
- self._tcp_connecting_started()
- return
-
- # if there was some other exception, call failure callback and unplug
- # transport which will also remove read_timeouts for descriptor
- self._on_connect_failure('Exception while connecting to %s:%s - %s %s' %
- (self.server, self.port, errnum, errstr))
-
- def _connect_to_proxy(self):
- self.set_state(PROXY_CONNECTING)
- if self.proxy_dict['type'] == 'socks5':
- proxyclass = proxy_connectors.SOCKS5Connector
- elif self.proxy_dict['type'] == 'http' :
- proxyclass = proxy_connectors.HTTPCONNECTConnector
- proxyclass.get_instance(
- send_method=self.send,
- onreceive=self.onreceive,
- old_on_receive=self.on_receive,
- on_success=self._on_connect,
- on_failure=self._on_connect_failure,
- xmpp_server=self.proxy_dict['xmpp_server'],
- proxy_creds=self.proxy_dict['credentials'])
-
- def _on_connect(self):
- """
- Preceed invoking of on_connect callback. TCP connection is already
- estabilished by this time
- """
- if self.estabilish_tls:
- self.tls_init(
- on_succ = lambda: NonBlockingTransport._on_connect(self),
- on_fail = lambda: self._on_connect_failure(
- 'error while estabilishing TLS'))
- else:
- NonBlockingTransport._on_connect(self)
-
- def tls_init(self, on_succ, on_fail):
- """
- Estabilishes TLS/SSL using this TCP connection by plugging a
- NonBlockingTLS module
- """
- cacerts, mycerts = self.certs
- result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts).PlugIn(self)
- if result:
- on_succ()
- else:
- on_fail()
-
- def pollin(self):
- """
- Called by idlequeu when receive on plugged socket is possible
- """
- log.info('pollin called, state == %s' % self.get_state())
- self._do_receive()
-
- def pollout(self):
- """
- Called by idlequeu when send to plugged socket is possible
- """
- log.info('pollout called, state == %s' % self.get_state())
-
- if self.get_state() == CONNECTING:
- log.info('%s socket wrapper connected' % id(self))
- self.idlequeue.remove_timeout(self.fd)
- self._plug_idle(writable=False, readable=False)
- self.peerhost = self._sock.getsockname()
- if self.proxy_dict:
- self._connect_to_proxy()
- else:
- self._on_connect()
- else:
- self._do_send()
-
- def pollend(self):
- """
- Called by idlequeue on TCP connection errors
- """
- log.info('pollend called, state == %s' % self.get_state())
-
- if self.get_state() == CONNECTING:
- self._on_connect_failure('Error during connect to %s:%s' %
- (self.server, self.port))
- else:
- self.disconnect()
-
- def disconnect(self, do_callback=True):
- if self.get_state() == DISCONNECTED:
- return
- self.set_state(DISCONNECTED)
- self.idlequeue.unplug_idle(self.fd)
- if 'NonBlockingTLS' in self.__dict__:
- self.NonBlockingTLS.PlugOut()
- try:
- self._sock.shutdown(socket.SHUT_RDWR)
- self._sock.close()
- except socket.error, (errnum, errstr):
- log.info('Error while disconnecting socket: %s' % errstr)
- self.fd = -1
- NonBlockingTransport.disconnect(self, do_callback)
-
- def read_timeout(self):
- log.info('read_timeout called, state == %s' % self.get_state())
- if self.get_state() == CONNECTING:
- # if read_timeout is called during connecting, connect() didn't end yet
- # thus we have to call the tcp failure callback
- self._on_connect_failure('Error during connect to %s:%s' %
- (self.server, self.port))
- else:
- NonBlockingTransport.read_timeout(self)
-
- def set_timeout(self, timeout):
- if self.get_state() != DISCONNECTED and self.fd != -1:
- NonBlockingTransport.set_timeout(self, timeout)
- else:
- log.warn('set_timeout: TIMEOUT NOT SET: state is %s, fd is %s' %
- (self.get_state(), self.fd))
-
- def remove_timeout(self):
- if self.fd:
- NonBlockingTransport.remove_timeout(self)
- else:
- log.warn('remove_timeout: no self.fd state is %s' % self.get_state())
-
- def send(self, raw_data, now=False):
- """
- Append raw_data to the queue of messages to be send. If supplied data is
- unicode string, encode it to utf-8.
- """
- NonBlockingTransport.send(self, raw_data, now)
-
- r = self.encode_stanza(raw_data)
-
- if now:
- self.sendqueue.insert(0, r)
- self._do_send()
- else:
- self.sendqueue.append(r)
-
- self._plug_idle(writable=True, readable=True)
-
- def encode_stanza(self, stanza):
- """
- Encode str or unicode to utf-8
- """
- if isinstance(stanza, unicode):
- stanza = stanza.encode('utf-8')
- elif not isinstance(stanza, str):
- stanza = ustr(stanza).encode('utf-8')
- return stanza
-
- def _plug_idle(self, writable, readable):
- """
- Plug file descriptor of socket to Idlequeue
-
- Plugged socket will be watched for "send possible" or/and "recv possible"
- events. pollin() callback is invoked on "recv possible", pollout() on
- "send_possible".
-
- Plugged socket will always be watched for "error" event - in that case,
- pollend() is called.
- """
- log.info('Plugging fd %d, W:%s, R:%s' % (self.fd, writable, readable))
- self.idlequeue.plug_idle(self, writable, readable)
-
- def _do_send(self):
- """
- Called when send() to connected socket is possible. First message from
- sendqueue will be sent
- """
- if not self.sendbuff:
- if not self.sendqueue:
- log.warn('calling send on empty buffer and queue')
- self._plug_idle(writable=False, readable=True)
- return None
- self.sendbuff = self.sendqueue.pop(0)
- try:
- send_count = self._send(self.sendbuff)
- if send_count:
- sent_data = self.sendbuff[:send_count]
- self.sendbuff = self.sendbuff[send_count:]
- self._plug_idle(
- writable=((self.sendqueue!=[]) or (self.sendbuff!='')),
- readable=True)
- self.raise_event(DATA_SENT, sent_data)
-
- except Exception:
- log.error('_do_send:', exc_info=True)
- traceback.print_exc()
- self.disconnect()
-
- def _do_receive(self):
- """
- Reads all pending incoming data. Will call owner's disconnected() method
- if appropriate
- """
- received = None
- errnum = 0
- errstr = 'No Error Set'
-
- try:
- # get as many bites, as possible, but not more than RECV_BUFSIZE
- received = self._recv(RECV_BUFSIZE)
- except socket.error, (errnum, errstr):
- log.info("_do_receive: got %s:" % received, exc_info=True)
- except tls_nb.SSLWrapper.Error, e:
- log.info("_do_receive, caught SSL error, got %s:" % received,
- exc_info=True)
- errnum, errstr = e.errno, e.strerror
-
- if received == '':
- errstr = 'zero bytes on recv'
-
- if (self.ssl_lib is None and received == '') or \
- (self.ssl_lib == tls_nb.PYSTDLIB and errnum == 8 ) or \
- (self.ssl_lib == tls_nb.PYOPENSSL and errnum == -1 ):
- # 8 in stdlib: errstr == EOF occured in violation of protocol
- # -1 in pyopenssl: errstr == Unexpected EOF
- log.info("Disconnected by remote server: #%s, %s" % (errnum, errstr))
- self.on_remote_disconnect()
- return
-
- if errnum:
- log.info("Connection to %s:%s lost: %s %s" % (self.server, self.port,
- errnum, errstr), exc_info=True)
- self.disconnect()
- return
-
- # this branch is for case of non-fatal SSL errors - None is returned from
- # recv() but no errnum is set
- if received is None:
- return
-
- # we have received some bytes, stop the timeout!
- self.remove_timeout()
- self.renew_send_timeout()
- self.renew_send_timeout2()
- # pass received data to owner
- if self.on_receive:
- self.raise_event(DATA_RECEIVED, received)
- self._on_receive(received)
- else:
- # This should never happen, so we need the debug.
- # (If there is no handler on receive specified, data is passed to
- # Dispatcher.ProcessNonBlocking)
- log.error('SOCKET %s Unhandled data received: %s' % (id(self),
- received))
- self.disconnect()
-
- def _on_receive(self, data):
- """
- Preceeds on_receive callback. It peels off and checks HTTP headers in
- HTTP classes, in here it just calls the callback
- """
- self.on_receive(data)
-
-
-class NonBlockingHTTP(NonBlockingTCP):
- """
- Socket wrapper that creates HTTP message out of sent data and peels-off HTTP
- headers from incoming messages
- """
-
- def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
- certs, on_http_request_possible, on_persistent_fallback, http_dict,
- proxy_dict=None):
- """
- :param on_http_request_possible: method to call when HTTP request to
- socket owned by transport is possible.
- :param on_persistent_fallback: callback called when server ends TCP
- connection. It doesn't have to be fatal for HTTP session.
- :param http_dict: dictionary with data for HTTP request and headers
- """
- NonBlockingTCP.__init__(self, raise_event, on_disconnect, idlequeue,
- estabilish_tls, certs, proxy_dict)
-
- self.http_protocol, self.http_host, self.http_port, self.http_path = \
- urisplit(http_dict['http_uri'])
- self.http_protocol = self.http_protocol or 'http'
- self.http_path = self.http_path or '/'
- self.http_version = http_dict['http_version']
- self.http_persistent = http_dict['http_persistent']
- self.add_proxy_headers = http_dict['add_proxy_headers']
-
- if 'proxy_user' in http_dict and 'proxy_pass' in http_dict:
- self.proxy_user, self.proxy_pass = http_dict['proxy_user'], http_dict[
- 'proxy_pass']
- else:
- self.proxy_user, self.proxy_pass = None, None
-
- # buffer for partial responses
- self.recvbuff = ''
- self.expected_length = 0
- self.pending_requests = 0
- self.on_http_request_possible = on_http_request_possible
- self.last_recv_time = 0
- self.close_current_connection = False
- self.on_remote_disconnect = lambda: on_persistent_fallback(self)
-
- def http_send(self, raw_data, now=False):
- self.send(self.build_http_message(raw_data), now)
-
- def _on_receive(self, data):
- """
- Preceeds passing received data to owner class. Gets rid of HTTP headers
- and checks them.
- """
- if self.get_state() == PROXY_CONNECTING:
- NonBlockingTCP._on_receive(self, data)
- return
-
- # append currently received data to HTTP msg in buffer
- self.recvbuff = '%s%s' % (self.recvbuff or '', data)
- statusline, headers, httpbody, buffer_rest = self.parse_http_message(
- self.recvbuff)
-
- if not (statusline and headers and httpbody):
- log.debug('Received incomplete HTTP response')
- return
-
- if statusline[1] != '200':
- log.error('HTTP Error: %s %s' % (statusline[1], statusline[2]))
- self.disconnect()
- return
- self.expected_length = int(headers['Content-Length'])
- if 'Connection' in headers and headers['Connection'].strip()=='close':
- self.close_current_connection = True
-
- if self.expected_length > len(httpbody):
- # If we haven't received the whole HTTP mess yet, let's end the thread.
- # It will be finnished from one of following recvs on plugged socket.
- log.info('not enough bytes in HTTP response - %d expected, got %d' %
- (self.expected_length, len(httpbody)))
- else:
- # First part of buffer has been extraced and is going to be handled,
- # remove it from buffer
- self.recvbuff = buffer_rest
-
- # everything was received
- self.expected_length = 0
-
- if not self.http_persistent or self.close_current_connection:
- # not-persistent connections disconnect after response
- self.disconnect(do_callback=False)
- self.close_current_connection = False
- self.last_recv_time = time.time()
- self.on_receive(data=httpbody, socket=self)
- self.on_http_request_possible()
-
- def build_http_message(self, httpbody, method='POST'):
- """
- Builds http message with given body. Values for headers and status line
- fields are taken from class variables
- """
- absolute_uri = '%s://%s:%s%s' % (self.http_protocol, self.http_host,
- self.http_port, self.http_path)
- headers = ['%s %s %s' % (method, absolute_uri, self.http_version),
- 'Host: %s:%s' % (self.http_host, self.http_port),
- 'User-Agent: Gajim',
- 'Content-Type: text/xml; charset=utf-8',
- 'Content-Length: %s' % len(str(httpbody))]
- if self.add_proxy_headers:
- headers.append('Proxy-Connection: keep-alive')
- headers.append('Pragma: no-cache')
- if self.proxy_user and self.proxy_pass:
- credentials = '%s:%s' % (self.proxy_user, self.proxy_pass)
- credentials = base64.encodestring(credentials).strip()
- headers.append('Proxy-Authorization: Basic %s' % credentials)
- else:
- headers.append('Connection: Keep-Alive')
- headers.append('\r\n')
- headers = '\r\n'.join(headers)
- return('%s%s' % (headers, httpbody))
-
- def parse_http_message(self, message):
- """
- Split http message into a tuple:
- (statusline - list of e.g. ['HTTP/1.1', '200', 'OK'],
- headers - dictionary of headers e.g. {'Content-Length': '604',
- 'Content-Type': 'text/xml; charset=utf-8'},
- httpbody - string with http body)
- http_rest - what is left in the message after a full HTTP header + body
- """
- splitted = message.split('\r\n\r\n')
- if len(splitted) < 2:
- # no complete http message. Keep filling the buffer until we find one
- buffer_rest = message
- return ('', '', '', buffer_rest)
- else:
- (header, httpbody) = splitted[:2]
- header = header.replace('\r', '')
- header = header.lstrip('\n')
- header = header.split('\n')
- statusline = header[0].split(' ', 2)
- header = header[1:]
- headers = {}
- for dummy in header:
- row = dummy.split(' ', 1)
- headers[row[0][:-1]] = row[1]
- body_size = headers['Content-Length']
- rest_splitted = splitted[2:]
- while (len(httpbody) < body_size) and rest_splitted:
- # Complete httpbody until it has the announced size
- httpbody = '\n\n'.join([httpbody, rest_splitted.pop(0)])
- buffer_rest = "\n\n".join(rest_splitted)
- return (statusline, headers, httpbody, buffer_rest)
-
-
-class NonBlockingHTTPBOSH(NonBlockingHTTP):
- """
- Class for BOSH HTTP connections. Slightly redefines HTTP transport by
- calling bosh bodytag generating callback before putting data on wire
- """
-
- def set_stanza_build_cb(self, build_cb):
- self.build_cb = build_cb
-
- def _do_send(self):
- if self.state == PROXY_CONNECTING:
- NonBlockingTCP._do_send(self)
- return
- if not self.sendbuff:
- stanza = self.build_cb(socket=self)
- stanza = self.encode_stanza(stanza)
- stanza = self.build_http_message(httpbody=stanza)
- self.sendbuff = stanza
- NonBlockingTCP._do_send(self)
diff --git a/src/common/zeroconf/client_zeroconf.py b/src/common/zeroconf/client_zeroconf.py
index cfe963d09..52a7ca1f0 100644
--- a/src/common/zeroconf/client_zeroconf.py
+++ b/src/common/zeroconf/client_zeroconf.py
@@ -18,15 +18,15 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
from common import gajim
-import common.xmpp
-from common.xmpp.idlequeue import IdleObject
-from common.xmpp import dispatcher_nb, simplexml
-from common.xmpp.plugin import *
-from common.xmpp.simplexml import ustr
-from common.xmpp.transports_nb import DATA_RECEIVED, DATA_SENT, DATA_ERROR
+import nbxmpp
+from nbxmpp.idlequeue import IdleObject
+from nbxmpp import dispatcher_nb, simplexml
+from nbxmpp.plugin import *
+from nbxmpp.simplexml import ustr
+from nbxmpp.transports_nb import DATA_RECEIVED, DATA_SENT, DATA_ERROR
from common.zeroconf import zeroconf
-from common.xmpp.protocol import *
+from nbxmpp.protocol import *
import socket
import errno
import sys
@@ -309,24 +309,23 @@ class P2PClient(IdleObject):
self._caller.peerhost = self.Connection._sock.getsockname()
self.RegisterHandler('message', lambda conn,
data:self._caller._messageCB(self.Server, conn, data))
- self.RegisterHandler('iq', self._caller._siSetCB, 'set',
- common.xmpp.NS_SI)
+ self.RegisterHandler('iq', self._caller._siSetCB, 'set', nbxmpp.NS_SI)
self.RegisterHandler('iq', self._caller._siErrorCB, 'error',
- common.xmpp.NS_SI)
+ nbxmpp.NS_SI)
self.RegisterHandler('iq', self._caller._siResultCB, 'result',
- common.xmpp.NS_SI)
+ nbxmpp.NS_SI)
self.RegisterHandler('iq', self._caller._bytestreamSetCB, 'set',
- common.xmpp.NS_BYTESTREAM)
+ nbxmpp.NS_BYTESTREAM)
self.RegisterHandler('iq', self._caller._bytestreamResultCB, 'result',
- common.xmpp.NS_BYTESTREAM)
+ nbxmpp.NS_BYTESTREAM)
self.RegisterHandler('iq', self._caller._bytestreamErrorCB, 'error',
- common.xmpp.NS_BYTESTREAM)
+ nbxmpp.NS_BYTESTREAM)
self.RegisterHandler('iq', self._caller._DiscoverItemsGetCB, 'get',
- common.xmpp.NS_DISCO_ITEMS)
+ nbxmpp.NS_DISCO_ITEMS)
self.RegisterHandler('iq', self._caller._JingleCB, 'result')
self.RegisterHandler('iq', self._caller._JingleCB, 'error')
self.RegisterHandler('iq', self._caller._JingleCB, 'set',
- common.xmpp.NS_JINGLE)
+ nbxmpp.NS_JINGLE)
class P2PConnection(IdleObject, PlugIn):
def __init__(self, sock_hash, _sock, host=None, port=None, caller=None,
diff --git a/src/common/zeroconf/connection_handlers_zeroconf.py b/src/common/zeroconf/connection_handlers_zeroconf.py
index b3568b364..ce5273123 100644
--- a/src/common/zeroconf/connection_handlers_zeroconf.py
+++ b/src/common/zeroconf/connection_handlers_zeroconf.py
@@ -28,7 +28,7 @@ import socket
from calendar import timegm
-import common.xmpp
+import nbxmpp
from common import helpers
from common import gajim
@@ -111,12 +111,12 @@ connection_handlers.ConnectionHandlersBase, connection_handlers.ConnectionJingle
return
if self.commandItemsQuery(con, iq_obj):
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
node = iq_obj.getTagAttr('query', 'node')
if node is None:
result = iq_obj.buildReply('result')
self.connection.send(result)
- raise common.xmpp.NodeProcessed
- if node==common.xmpp.NS_COMMANDS:
+ raise nbxmpp.NodeProcessed
+ if node==nbxmpp.NS_COMMANDS:
self.commandListQuery(con, iq_obj)
- raise common.xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
diff --git a/src/common/zeroconf/connection_zeroconf.py b/src/common/zeroconf/connection_zeroconf.py
index 7e8a372a9..5f2c8d2a5 100644
--- a/src/common/zeroconf/connection_zeroconf.py
+++ b/src/common/zeroconf/connection_zeroconf.py
@@ -418,14 +418,14 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
# send a stanza untouched
if not self.connection:
return
- if not isinstance(stanza, common.xmpp.Node):
- stanza = common.xmpp.Protocol(node=stanza)
+ if not isinstance(stanza, nbxmpp.Node):
+ stanza = nbxmpp.Protocol(node=stanza)
self.connection.send(stanza)
def _event_dispatcher(self, realm, event, data):
CommonConnection._event_dispatcher(self, realm, event, data)
if realm == '':
- if event == common.xmpp.transports_nb.DATA_ERROR:
+ if event == nbxmpp.transports_nb.DATA_ERROR:
thread_id = data[1]
frm = unicode(data[0])
session = self.get_or_create_session(frm, thread_id)
diff --git a/src/dataforms_widget.py b/src/dataforms_widget.py
index eab227235..3702cbdcc 100644
--- a/src/dataforms_widget.py
+++ b/src/dataforms_widget.py
@@ -78,7 +78,7 @@ class DataFormWidget(gtk.Alignment, object):
def set_data_form(self, dataform):
"""
- Set the data form (xmpp.DataForm) displayed in widget
+ Set the data form (nbxmpp.DataForm) displayed in widget
"""
assert isinstance(dataform, dataforms.DataForm)
diff --git a/src/disco.py b/src/disco.py
index 2101bdc89..a18a7d9ac 100644
--- a/src/disco.py
+++ b/src/disco.py
@@ -59,7 +59,7 @@ import adhoc_commands
import search_window
from common import gajim
-from common import xmpp
+import nbxmpp
from common.exceptions import GajimGeneralException
from common import helpers
from common import ged
@@ -350,7 +350,7 @@ class ServicesCache:
# NS_DISCO_ITEMS anyways.
# Allow browsing for unknown types aswell.
if (not features and not identities) or \
- xmpp.NS_DISCO_ITEMS in features or xmpp.NS_BROWSE in features:
+ nbxmpp.NS_DISCO_ITEMS in features or nbxmpp.NS_BROWSE in features:
return ToplevelAgentBrowser
return None
@@ -1502,11 +1502,11 @@ class ToplevelAgentBrowser(AgentBrowser):
def _update_actions(self, jid, node, identities, features, data):
AgentBrowser._update_actions(self, jid, node, identities, features, data)
- if self.execute_button and xmpp.NS_COMMANDS in features:
+ if self.execute_button and nbxmpp.NS_COMMANDS in features:
self.execute_button.set_sensitive(True)
- if self.search_button and xmpp.NS_SEARCH in features:
+ if self.search_button and nbxmpp.NS_SEARCH in features:
self.search_button.set_sensitive(True)
- if self.register_button and xmpp.NS_REGISTER in features:
+ if self.register_button and nbxmpp.NS_REGISTER in features:
# We can register this agent
registered_transports = []
jid_list = gajim.contacts.get_jid_list(self.account)
@@ -1520,13 +1520,13 @@ class ToplevelAgentBrowser(AgentBrowser):
else:
self.register_button.set_label(_('Re_gister'))
self.register_button.set_sensitive(True)
- if self.join_button and xmpp.NS_MUC in features:
+ if self.join_button and nbxmpp.NS_MUC in features:
self.join_button.set_sensitive(True)
def _default_action(self, jid, node, identities, features, data):
if AgentBrowser._default_action(self, jid, node, identities, features, data):
return True
- if xmpp.NS_REGISTER in features:
+ if nbxmpp.NS_REGISTER in features:
# Register if we can't browse
self.on_register_button_clicked()
return True
@@ -2239,7 +2239,7 @@ class DiscussionGroupsBrowser(AgentBrowser):
# we now know subscriptions, update button states
self.update_actions()
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _on_pep_subscribe(self, conn, request, groupnode):
"""
@@ -2255,7 +2255,7 @@ class DiscussionGroupsBrowser(AgentBrowser):
self.update_actions()
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
def _on_pep_unsubscribe(self, conn, request, groupnode):
"""
@@ -2271,7 +2271,7 @@ class DiscussionGroupsBrowser(AgentBrowser):
self.update_actions()
- raise xmpp.NodeProcessed
+ raise nbxmpp.NodeProcessed
# Fill the global agent type info dictionary
_agent_type_info = _gen_agent_type_info()
diff --git a/src/filetransfers_window.py b/src/filetransfers_window.py
index 8db9bf24e..40edc2d26 100644
--- a/src/filetransfers_window.py
+++ b/src/filetransfers_window.py
@@ -36,7 +36,7 @@ from common import helpers
from common.file_props import FilesProp
from common.protocol.bytestream import (is_transfer_active, is_transfer_paused,
is_transfer_stopped)
-from common.xmpp.protocol import NS_JINGLE_FILE_TRANSFER
+from nbxmpp.protocol import NS_JINGLE_FILE_TRANSFER
import logging
log = logging.getLogger('gajim.filetransfer_window')
@@ -684,14 +684,14 @@ class FileTransfersWindow:
# Converts date-time from seconds from epoch to iso 8601
import time, datetime
ts = time.gmtime(epoch)
- dt = datetime.datetime(ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour,
+ dt = datetime.datetime(ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour,
ts.tm_min, ts.tm_sec)
return dt.isoformat()
def get_send_file_props(self, account, contact, file_path, file_name,
file_desc=''):
"""
- Create new file_props object and set initial file transfer
+ Create new file_props object and set initial file transfer
properties in it
"""
if os.path.isfile(file_path):
diff --git a/src/gajim.py b/src/gajim.py
index f26480581..b006bf37e 100644
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -62,6 +62,12 @@ if os.name == 'nt':
new_list.insert(0, os.path.join(os.getcwd(), 'gtk', 'bin'))
os.environ['PATH'] = ';'.join(new_list)
+try:
+ import nbxmpp
+except ImportError:
+ print 'Gajim needs python-nbxmpp to run. Quiting...'
+ sys.exit()
+
from common import demandimport
demandimport.enable()
demandimport.ignore += ['gobject._gobject', 'libasyncns', 'i18n',
diff --git a/src/groups.py b/src/groups.py
index 21c5742c9..0b44088f2 100644
--- a/src/groups.py
+++ b/src/groups.py
@@ -21,7 +21,8 @@
'''Window to create new post for discussion groups service.'''
-from common import gajim, xmpp
+from common import gajim
+from nbxmpp import Node
import gtkgui_helpers
class GroupsPostWindow:
@@ -56,7 +57,7 @@ class GroupsPostWindow:
Gather info from widgets and send it as a message
"""
# constructing item to publish... that's atom:entry element
- item = xmpp.Node('entry', {'xmlns':'http://www.w3.org/2005/Atom'})
+ item = Node('entry', {'xmlns':'http://www.w3.org/2005/Atom'})
author = item.addChild('author')
author.addChild('name', {}, [self.from_entry.get_text()])
item.addChild('generator', {}, ['Gajim'])
diff --git a/src/gui_interface.py b/src/gui_interface.py
index b231087c3..b16c178e8 100644
--- a/src/gui_interface.py
+++ b/src/gui_interface.py
@@ -69,8 +69,8 @@ from session import ChatControlSession
import common.sleepy
-from common.xmpp import idlequeue
-from common.xmpp import Hashes
+from nbxmpp import idlequeue
+from nbxmpp import Hashes
from common.zeroconf import connection_zeroconf
from common import resolver
from common import caps_cache
diff --git a/src/gui_menu_builder.py b/src/gui_menu_builder.py
index 09173aab0..7d9d3a8e9 100644
--- a/src/gui_menu_builder.py
+++ b/src/gui_menu_builder.py
@@ -25,7 +25,8 @@ import message_control
from common import gajim
from common import helpers
-from common.xmpp.protocol import NS_COMMANDS, NS_FILE, NS_MUC, NS_ESESSION, NS_JINGLE_FILE_TRANSFER
+from nbxmpp.protocol import NS_COMMANDS, NS_FILE, NS_MUC, NS_ESESSION
+from nbxmpp.protocol import NS_JINGLE_FILE_TRANSFER
def build_resources_submenu(contacts, account, action, room_jid=None,
room_account=None, cap=None):
diff --git a/src/negotiation.py b/src/negotiation.py
index d6dd8b7c3..a8287a3a0 100644
--- a/src/negotiation.py
+++ b/src/negotiation.py
@@ -24,7 +24,7 @@ import dataforms_widget
from common import dataforms
from common import gajim
-from common import xmpp
+import nbxmpp
def describe_features(features):
"""
@@ -55,10 +55,10 @@ class FeatureNegotiationWindow:
self.window.show_all()
def on_ok_button_clicked(self, widget):
- acceptance = xmpp.Message(self.jid)
+ acceptance = nbxmpp.Message(self.jid)
acceptance.setThread(self.session.thread_id)
feature = acceptance.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
form = self.data_form_widget.data_form
form.setAttr('type', 'submit')
@@ -70,14 +70,14 @@ class FeatureNegotiationWindow:
self.window.destroy()
def on_cancel_button_clicked(self, widget):
- rejection = xmpp.Message(self.jid)
+ rejection = nbxmpp.Message(self.jid)
rejection.setThread(self.session.thread_id)
feature = rejection.NT.feature
- feature.setNamespace(xmpp.NS_FEATURE)
+ feature.setNamespace(nbxmpp.NS_FEATURE)
- x = xmpp.DataForm(typ='submit')
- x.addChild(node=xmpp.DataField('FORM_TYPE', value='urn:xmpp:ssn'))
- x.addChild(node=xmpp.DataField('accept', value='false', typ='boolean'))
+ x = nbxmpp.DataForm(typ='submit')
+ x.addChild(node=nbxmpp.DataField('FORM_TYPE', value='urn:xmpp:ssn'))
+ x.addChild(node=nbxmpp.DataField('accept', value='false', typ='boolean'))
feature.addChild(node=x)
diff --git a/src/roster_window.py b/src/roster_window.py
index 0a6a123de..d901ce0f8 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -70,7 +70,7 @@ from common import dbus_support
if dbus_support.supported:
import dbus
-from common.xmpp.protocol import NS_FILE
+from nbxmpp.protocol import NS_FILE
from common.pep import MOODS, ACTIVITIES
#(icon, name, type, jid, account, editable, second pixbuf)
diff --git a/src/session.py b/src/session.py
index 31bc1bcda..c43f5c930 100644
--- a/src/session.py
+++ b/src/session.py
@@ -31,8 +31,6 @@ from common import ged
from common.connection_handlers_events import ChatstateReceivedEvent, \
InformationEvent
-import common.xmpp
-
import message_control
import notify