def on_invite(self, element): """ Handler that responds to channel invites from other users. This will acknowledge the request by joining the room indicated in the xml payload. :param element: A <message/> element, instance of `twisted.words.xish.domish.Element` """ channel = '' password = '' # NOTE: check for either http://xmpp.org/extensions/xep-0045.html#invite # or direct invites http://xmpp.org/extensions/xep-0249.html if xpath.matches('/message/x/invite', element): from_jid = jid.JID(element['from']) to_jid = jid.JID(element['to']) if from_jid.host == self.conference_host: channel = from_jid.userhost() else: channel = to_jid.userhost() # This is a hack around a unicode bug in twisted queryForString strings = xpath.queryForStringList('/message/x/password', element) if strings: password = strings[0] elif xpath.matches('/message/x[@xmlns="jabber:x:conference"]', element): # Direct invite x = xpath.queryForNodes('/message/x', element)[0] channel = x['jid'] password = x.attributes.get('password', '') else: # Probably not an invite, but the overly greedy xpath matched it. Ignore. return self.join(channel, password=password)
def mypublish(self, events): for event in events: msg = domish.Element((None, "item")) child = msg.addElement((event, "id")) if events[event].has_key("fullname"): child.addElement("fullname", content=events[event]["fullname"]) if events[event].has_key("lines"): lines = child.addElement("lines") if events[event]["lines"].has_key("id"): lines.addElement("id", content=events[event]["lines"]["id"]) if events[event]["lines"].has_key("channel"): lines.addElement("channel", content=events[event]["lines"]["channel"]) if events[event]["lines"].has_key("number"): lines.addElement("number", content=events[event]["lines"]["number"]) if events[event]["lines"].has_key("presence_line"): presence_line = lines.addElement("presence_line") presence_line.addElement("color", content=events[event]["lines"] ["presence_line"]["color"]) presence_line.addElement("longname", content=events[event]["lines"] ["presence_line"]["longname"]) reactor.callLater(0, self.publish, jid.JID(CONFIG["xmpp"]["pubsub"]), "ctitoxmpp", (msg, ), jid.JID(CONFIG["xmpp"]["from"]))
def test_inequality(self): """ Test JID inequality. """ j1 = jid.JID("user1@host/resource") j2 = jid.JID("user2@host/resource") self.assertNotEqual(j1, j2)
def test_hashable(self): """ Test JID hashability. """ j1 = jid.JID("user@host/resource") j2 = jid.JID("user@host/resource") self.assertEqual(hash(j1), hash(j2))
def onVCardGet(self, stanza): log.debug("%s requested vCard for %s" % (stanza['from'], stanza['to'])) jid_from = jid.JID(stanza['from']) jid_to = jid.JID(stanza['to']) try: # are we requesting vCard for a user we have blocked? if self.parent.is_presence_allowed(jid_to, jid_from) == -1: log.debug("requesting vCard for a blocked user, bouncing error") e = error.StanzaError('not-acceptable', 'cancel') errstanza = e.toResponse(stanza) errstanza.error.addElement((xmlstream2.NS_IQ_BLOCKING_ERRORS, 'blocked')) self.send(errstanza) else: fpr = self.parent.is_presence_allowed(jid_from, jid_to) log.debug("is_presence_allowed: %d" % (fpr, )) if fpr != 1: raise Exception() fpr = self.parent.keyring.get_fingerprint(jid_to.user) keydata = self.parent.keyring.get_key(jid_to.user, fpr) iq = xmlstream.toResponse(stanza, 'result') # add vcard vcard = iq.addElement((xmlstream2.NS_XMPP_VCARD4, 'vcard')) vcard_key = vcard.addElement((None, 'key')) vcard_data = vcard_key.addElement((None, 'uri')) vcard_data.addContent(xmlstream2.DATA_PGP_PREFIX + base64.b64encode(keydata)) self.send(iq) except: self.parent.error(stanza)
def _do_store(self, stanza, expire=None): global dbpool receipt = xmlstream2.extract_receipt(stanza, 'request') if receipt: # this is indeed generated by server :) msgId = receipt['id'] else: # WARNING stanza id must be server generated msgId = stanza['id'] args = ( msgId, util.jid_to_userid(jid.JID(stanza['from'])), util.jid_to_userid(jid.JID(stanza['to'])), stanza.getAttribute('type'), stanza.toXml().encode('utf-8').decode('utf-8'), int(time.time()*1e3), expire ) # for presence we want to overwrite old requests if stanza.name == 'presence': op = 'REPLACE' else: op = 'INSERT' return dbpool.runOperation('%s INTO stanzas_%s (id, sender, recipient, type, content, timestamp, expire_timestamp) VALUES(?, ?, ?, ?, ?, ?, ?)' % (op, stanza.name, ), args)
def onVerify(self, verify): try: receivingServer = jid.JID(verify['from']).host originatingServer = jid.JID(verify['to']).host except (KeyError, jid.InvalidFormat): raise error.StreamError('improper-addressing') if originatingServer not in self.service.domains: raise error.StreamError('host-unknown') if (self.xmlstream.otherEntity and receivingServer != self.xmlstream.otherEntity.host): raise error.StreamError('invalid-from') streamID = verify.getAttribute('id', '') key = unicode(verify) calculatedKey = generateKey(self.service.secret, receivingServer, originatingServer, streamID) validity = (key == calculatedKey) and 'valid' or 'invalid' reply = domish.Element((NS_DIALBACK, 'verify')) reply['from'] = originatingServer reply['to'] = receivingServer reply['id'] = streamID reply['type'] = validity self.xmlstream.send(reply)
def testSettingInvalidMechanism(self): """ Test using a bad SASL authentication mechanism. """ self.authenticator.jid = jid.JID('*****@*****.**') self.authenticator.password = '******' feature = domish.Element((NS_XMPP_SASL, 'mechanisms')) feature.addElement('mechanism', content="BAD") self.xmlstream.features[(feature.uri, feature.name)] = feature try: self.init.setMechanism() failed = False except sasl.SASLNoAcceptableMechanism: failed = True self.failUnless(failed) ## also test anonymous fail self.authenticator.jid = jid.JID('example.com') self.authenticator.password = '******' feature = domish.Element((NS_XMPP_SASL, 'mechanisms')) feature.addElement('mechanism', content="BAD") self.xmlstream.features[(feature.uri, feature.name)] = feature try: self.init.setMechanism() failed = False except sasl.SASLNoAcceptableMechanism: failed = True self.failUnless(failed)
def setUp(self): self.service = FakeService() self.factory = server.XMPPS2SServerFactory(self.service) self.xmlstream = self.factory.buildProtocol(None) self.transport = StringTransport() self.xmlstream.thisEntity = jid.JID('example.org') self.xmlstream.otherEntity = jid.JID('example.com')
def parse_config(config_file): if not os.path.exists(config_file): config = ConfigParser.ConfigParser() config.add_section("misc") config.set("misc", "mynickname", "") config.add_section("auth") config.set("auth", "jid", "") config.set("auth", "password", "") config.set("auth", "destination_jid", "") config.write(open(config_file, 'w')) return filemode = stat.S_IMODE(os.stat(config_file).st_mode) & 0777 if filemode != 384: os.chmod(config_file, 0600) ret={} config = ConfigParser.ConfigParser() cfh = config.read(config_file) if not cfh: return ret thejid = config.get('auth', 'jid') password = config.get('auth', 'password') destination_jid = config.get('auth', 'destination_jid') mynickname = config.get('misc', 'mynickname') if not thejid or not password or not destination_jid: return ret return { 'jid' : jid.JID(thejid), 'password' : password, 'destination_jid' : jid.JID(destination_jid), 'mynickname' : mynickname }
def onProbe(self, stanza): """Handle presence probes.""" if stanza.consumed: return log.debug("probe request: %s" % (stanza.toXml(), )) stanza.consumed = True to = jid.JID(stanza['to']) sender = jid.JID(stanza['from']) # are we probing a user we have blocked? if self.parent.is_presence_allowed(to, sender) == -1: log.debug("probing blocked user, bouncing error") e = error.StanzaError('not-acceptable', 'cancel') errstanza = e.toResponse(stanza) errstanza.error.addElement((xmlstream2.NS_IQ_BLOCKING_ERRORS, 'blocked')) self.send(errstanza) elif self.parent.is_presence_allowed(sender, to) == 1: gid = stanza.getAttribute('id') if not self.send_user_presence(gid, sender, to): response = xmlstream.toResponse(stanza, 'error') # TODO include error cause? self.send(response)
def resolveJID(self, _jid): """Transform host attribute of JID from server name to network name.""" if isinstance(_jid, jid.JID): return jid.JID(tuple=(_jid.user, self.network, _jid.resource)) else: _jid = jid.JID(_jid) _jid.host = self.network return _jid
def testCancelSubscriptions(self): # execute subscription first self.testSubscribe() jid_from = jid.JID('[email protected]/TEST001') jid_to = jid.JID('*****@*****.**') self.resolver.cancelSubscriptions(self.resolver.translateJID(jid_from)) self.assertEqual(len(self.resolver.subscriptions[jid_to]), 0, 'Subscriptions not maching.')
def test_equality(self): """ Test JID equality. """ j1 = jid.JID("user@host/resource") j2 = jid.JID("user@host/resource") self.assertNotIdentical(j1, j2) self.assertEqual(j1, j2)
def __init__(self): if 'JID' in settings.SERVER: self.jid = jid.JID(settings.SERVER['JID']) else: self.jid = jid.JID('{user}@{host}'.format(user=settings.SERVER['USERNAME'], host=settings.SERVER['HOST'])) self.auth = client.XMPPAuthenticator(self.jid, settings.SERVER['PASSWORD']) XmlStreamFactoryMixin.__init__(self, self.auth) self.client = Client(factory=self)
def resolveJID(self, _jid): """Transform host attribute of JID from network name to component name.""" host = util.component_jid(self.servername, util.COMPONENT_C2S) if isinstance(_jid, jid.JID): return jid.JID(tuple=(_jid.user, host, _jid.resource)) else: _jid = jid.JID(_jid) _jid.host = host return _jid
def testSubscribe(self): jid_from = jid.JID('[email protected]/TEST001') jid_to = jid.JID('*****@*****.**') gid = util.rand_str(8) self.resolver.subscribe(self.resolver.translateJID(jid_from), self.resolver.translateJID(jid_to), gid, False) subscriptions = { jid.JID('*****@*****.**') : [ jid.JID('[email protected]/TEST001') ] } self.assertDictEqual(self.resolver.subscriptions, subscriptions, 'Subscriptions not maching.')
def testUnsubscribe(self): # execute subscription first self.testSubscribe() jid_from = jid.JID('*****@*****.**') jid_to = jid.JID('*****@*****.**') self.resolver.unsubscribe(self.resolver.translateJID(jid_to), self.resolver.translateJID(jid_from)) self.assertEqual(len(self.resolver.subscriptions), 0, 'Subscriptions not maching.')
def send(author, to, msg): # esta funcion envia los mensajes global thexmlstream message = domish.Element(('jabber:client', 'message')) message["to"] = jid.JID(to).full() message["from"] = jid.JID(author).full() message["type"] = "chat" message.addElement("body", "jabber:client", msg + "- ya lo sabia adicotalainformatica1") thexmlstream.send(message)
def test_makeFieldsUnknownTypeJIDMulti(self): """ Without type, multiple JID values sets field type jid-multi. """ values = {'pubsub#contact': [jid.JID('*****@*****.**'), jid.JID('*****@*****.**')]} form = data_form.Form('result') form.makeFields(values) field = form.fields['pubsub#contact'] self.assertEqual(None, field.fieldType) self.assertEqual(values, form.getValues())
def test_sendHeaderInitiating(self): """ Test addressing when initiating a stream. """ xs = self.xmlstream xs.thisEntity = jid.JID('thisHost') xs.otherEntity = jid.JID('otherHost') xs.initiating = True xs.sendHeader() splitHeader = xs.transport.value()[0:-1].split(b' ') self.assertIn(b"to='otherhost'", splitHeader) self.assertIn(b"from='thishost'", splitHeader)
def setUp(self): self.output = [] self.xmlstream = xmlstream.XmlStream(xmlstream.Authenticator()) self.xmlstream.thisEntity = jid.JID('example.org') self.xmlstream.otherEntity = jid.JID('example.com') self.xmlstream.send = self.output.append self.router = component.Router() self.service = server.ServerService(self.router, secret='mysecret', domain='example.org') self.service.xmlstream = self.xmlstream
def _store(self, stanza, network, _id, expire): # remove ourselves from pending if not self._exiting: try: del self._pending_offline[_id] except: pass # WARNING using deepcopy is not safe from copy import deepcopy stanza = deepcopy(stanza) # if no receipt request is found, generate a unique id for the message receipt = xmlstream2.extract_receipt(stanza, 'request') if not receipt: if _id: stanza['id'] = _id else: stanza['id'] = util.rand_str(30, util.CHARSBOX_AZN_LOWERCASE) # store message for bare network JID jid_to = jid.JID(stanza['to']) # WARNING this is actually useless jid_to.host = network stanza['to'] = jid_to.userhost() # sender JID should be a network JID jid_from = jid.JID(stanza['from']) # WARNING this is actually useless jid_from.host = network stanza['from'] = jid_from.full() try: del stanza['origin'] except KeyError: pass # safe uri for persistance stanza.uri = stanza.defaultUri = sm.C2SManager.namespace log.debug("storing offline message for %s" % (stanza['to'], )) try: d = self._do_store(stanza, expire) if self._exiting: return d except: # TODO log this import traceback traceback.print_exc() return stanza['id']
def test_sendHeaderReceiving(self): """ Test addressing when receiving a stream. """ xs = self.xmlstream xs.thisEntity = jid.JID('thisHost') xs.otherEntity = jid.JID('otherHost') xs.initiating = False xs.sid = 'session01' xs.sendHeader() splitHeader = xs.transport.value()[0:-1].split(' ') self.assertIn("to='otherhost'", splitHeader) self.assertIn("from='thishost'", splitHeader) self.assertIn("id='session01'", splitHeader)
def push(self, stanza): """Push a presence to this stub.""" ptype = stanza.getAttribute('type') if ptype == 'unavailable': raise ValueError('only available presences are allowed.') ujid = jid.JID(stanza['from']) # update local jid self.jid = ujid.userhostJID() # recreate presence stanza for local use presence = domish.Element((None, 'presence')) for attr in ('type', 'from'): if stanza.hasAttribute(attr): presence[attr] = stanza[attr] if stanza.hasAttribute('type'): self.type = stanza['type'] else: self.type = None for child in ('status', 'show', 'priority', 'delay'): e = getattr(stanza, child) if e: self.__set__(child, e.__str__()) presence.addChild(e) self._avail[ujid.resource] = presence
def _getSubscriptions(self, cursor, state): self._checkNodeExists(cursor) query = """SELECT jid, resource, state, subscription_type, subscription_depth FROM subscriptions NATURAL JOIN nodes NATURAL JOIN entities WHERE node=%s""" values = [self.nodeIdentifier] if state: query += " AND state=%s" values.append(state) cursor.execute(query, values) rows = cursor.fetchall() subscriptions = [] for row in rows: subscriber = jid.JID('%s/%s' % (row.jid, row.resource)) options = {} if row.subscription_type: options['pubsub#subscription_type'] = row.subscription_type if row.subscription_depth: options['pubsub#subscription_depth'] = row.subscription_depth subscriptions.append( Subscription(self.nodeIdentifier, subscriber, row.state, options)) return subscriptions
def testBasic(self): """ Test basic operations. Setup an XMPPClientFactory, which sets up an XMPPAuthenticator, and let it produce a protocol instance. Then inspect the instance variables of the authenticator and XML stream objects. """ self.client_jid = jid.JID('[email protected]/resource') # Get an XmlStream instance. Note that it gets initialized with the # XMPPAuthenticator (that has its associateWithXmlStream called) that # is in turn initialized with the arguments to the factory. xs = client.XMPPClientFactory(self.client_jid, 'secret').buildProtocol(None) # test authenticator's instance variables self.assertEqual('example.com', xs.authenticator.otherHost) self.assertEqual(self.client_jid, xs.authenticator.jid) self.assertEqual('secret', xs.authenticator.password) # test list of initializers version, tls, sasl, bind, session = xs.initializers self.assert_(isinstance(tls, xmlstream.TLSInitiatingInitializer)) self.assert_(isinstance(sasl, SASLInitiatingInitializer)) self.assert_(isinstance(bind, client.BindInitializer)) self.assert_(isinstance(session, client.SessionInitializer)) self.assertFalse(tls.required) self.assertTrue(sasl.required) self.assertFalse(bind.required) self.assertFalse(session.required)
def fromElement(klass, e, from_host=None): p_type = e.getAttribute('type') if e.show: show = str(e.show) else: show = None if e.status: status = e.status.__str__() else: status = None try: priority = int(e.priority.__str__()) except: priority = 0 try: delay = e.delay['stamp'] except: delay = None sender = jid.JID(e['from']).userhostJID() if from_host is not None: sender.host = from_host p = klass(sender) p.__set__('type', p_type) p.__set__('show', show) p.__set__('status', status) p.__set__('priority', priority) p.__set__('delay', delay) if not p_type: p.push(e) return p
def _presence(stanza, callback, timeout, buf): # presence probe error - finish here if stanza.getAttribute('type') == 'error': # TODO duplicated code self.xmlstream.removeObserver("/presence/group[@id='%s']" % (stanza['id'], ), _presence) self.xmlstream.removeObserver("/presence[@type='error'][@id='%s']" % (stanza['id'], ), _presence) if not callback.called: # cancel timeout timeout.cancel() # fire deferred callback.callback(buf) return sender = jid.JID(stanza['from']) log.debug("JID %s found!" % (sender.full(), )) stanza.consumed = True buf.append(sender) chain = stanza.group # end of presence chain!!! if not chain or int(chain['count']) == len(buf): # TODO duplicated code self.xmlstream.removeObserver("/presence/group[@id='%s']" % (stanza['id'], ), _presence) self.xmlstream.removeObserver("/presence[@type='error'][@id='%s']" % (stanza['id'], ), _presence) if not callback.called: # cancel timeout timeout.cancel() # fire deferred callback.callback(buf)
def test_userhostJID(self): """ Test getting a JID object of the bare JID. """ j1 = jid.JID("user@host/resource") j2 = jid.internJID("user@host") self.assertIdentical(j2, j1.userhostJID())