Esempio n. 1
0
    def incoming_message(self, message_request, data):
        content_type = data.headers.get('Content-Type', Null).content_type
        from_header = data.headers.get('From', Null)
        to_header = data.headers.get('To', Null)
        if Null in (content_type, from_header, to_header):
            message_request.answer(400)
            return
        log.info('New SIP Message from %s to %s' % (from_header.uri, to_header.uri))

        # Check domain
        if from_header.uri.host not in XMPPGatewayConfig.domains:
            log.info('Message rejected: From domain is not a local XMPP domain')
            message_request.answer(606)
            return

        if content_type == 'message/cpim':
            try:
                cpim_message = CPIMPayload.decode(data.body)
            except CPIMParserError:
                log.info('Message rejected: CPIM parse error')
                message_request.answer(400)
                return
            else:
                body = cpim_message.content
                content_type = cpim_message.content_type
                sender = cpim_message.sender or from_header
                from_uri = sender.uri
        else:
            body = data.body
            from_uri = from_header.uri
        to_uri = str(to_header.uri)
        message_request.answer(200)
        if from_uri.parameters.get('gr', None) is None:
            from_uri = SIPURI.new(from_uri)
            from_uri.parameters['gr'] = generate_sylk_resource()
        sender = Identity(FrozenURI.parse(from_uri))
        recipient = Identity(FrozenURI.parse(to_uri))
        if content_type in ('text/plain', 'text/html'):
            if content_type == 'text/plain':
                html_body = None
            else:
                html_body = body
                body = None
            if XMPPGatewayConfig.use_msrp_for_chat:
                message = NormalMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
            else:
                message = ChatMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
        elif content_type == IsComposingDocument.content_type:
            if not XMPPGatewayConfig.use_msrp_for_chat:
                try:
                    msg = IsComposingMessage.parse(body)
                except ParserError:
                    pass
                else:
                    state = 'composing' if msg.state == 'active' else 'paused'
                    message = ChatComposingIndication(sender, recipient, state, use_receipt=False)
                    self.xmpp_manager.send_stanza(message)
Esempio n. 2
0
    def incoming_message(self, message_request, data):
        content_type = data.headers.get('Content-Type', Null).content_type
        from_header = data.headers.get('From', Null)
        to_header = data.headers.get('To', Null)
        if Null in (content_type, from_header, to_header):
            message_request.answer(400)
            return
        log.msg('New SIP Message from %s to %s' % (from_header.uri, to_header.uri))

        # Check domain
        if from_header.uri.host not in XMPPGatewayConfig.domains:
            log.msg('Message rejected: From domain is not a local XMPP domain')
            message_request.answer(606)
            return

        if content_type == 'message/cpim':
            try:
                cpim_message = CPIMMessage.parse(data.body)
            except CPIMParserError:
                log.msg('Message rejected: CPIM parse error')
                message_request.answer(400)
                return
            else:
                body = cpim_message.body
                content_type = cpim_message.content_type
                sender = cpim_message.sender or from_header
                from_uri = sender.uri
        else:
            body = data.body
            from_uri = from_header.uri
        to_uri = str(to_header.uri)
        message_request.answer(200)
        if from_uri.parameters.get('gr', None) is None:
            from_uri = SIPURI.new(from_uri)
            from_uri.parameters['gr'] = generate_sylk_resource()
        sender = Identity(FrozenURI.parse(from_uri))
        recipient = Identity(FrozenURI.parse(to_uri))
        if content_type in ('text/plain', 'text/html'):
            if content_type == 'text/plain':
                html_body = None
            else:
                html_body = body
                body = None
            if XMPPGatewayConfig.use_msrp_for_chat:
                message = NormalMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
            else:
                message = ChatMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
        elif content_type == IsComposingDocument.content_type:
            if not XMPPGatewayConfig.use_msrp_for_chat:
                try:
                    msg = IsComposingMessage.parse(body)
                except ParserError:
                    pass
                else:
                    state = 'composing' if msg.state == 'active' else 'paused'
                    message = ChatComposingIndication(sender, recipient, state, use_receipt=False)
                    self.xmpp_manager.send_stanza(message)
Esempio n. 3
0
    def incoming_message(self, message_request, data):
        content_type = data.headers.get("Content-Type", Null).content_type
        from_header = data.headers.get("From", Null)
        to_header = data.headers.get("To", Null)
        if Null in (content_type, from_header, to_header):
            message_request.answer(400)
            return
        log.msg("New SIP Message from %s to %s" % (from_header.uri, to_header.uri))

        # Check domain
        if from_header.uri.host not in XMPPGatewayConfig.domains:
            log.msg("Message rejected: From domain is not a local XMPP domain")
            message_request.answer(606)
            return

        if content_type == "message/cpim":
            try:
                cpim_message = CPIMPayload.decode(data.body)
            except CPIMParserError:
                log.msg("Message rejected: CPIM parse error")
                message_request.answer(400)
                return
            else:
                body = cpim_message.content
                content_type = cpim_message.content_type
                sender = cpim_message.sender or from_header
                from_uri = sender.uri
        else:
            body = data.body
            from_uri = from_header.uri
        to_uri = str(to_header.uri)
        message_request.answer(200)
        if from_uri.parameters.get("gr", None) is None:
            from_uri = SIPURI.new(from_uri)
            from_uri.parameters["gr"] = generate_sylk_resource()
        sender = Identity(FrozenURI.parse(from_uri))
        recipient = Identity(FrozenURI.parse(to_uri))
        if content_type in ("text/plain", "text/html"):
            if content_type == "text/plain":
                html_body = None
            else:
                html_body = body
                body = None
            if XMPPGatewayConfig.use_msrp_for_chat:
                message = NormalMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
            else:
                message = ChatMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
        elif content_type == IsComposingDocument.content_type:
            if not XMPPGatewayConfig.use_msrp_for_chat:
                try:
                    msg = IsComposingMessage.parse(body)
                except ParserError:
                    pass
                else:
                    state = "composing" if msg.state == "active" else "paused"
                    message = ChatComposingIndication(sender, recipient, state, use_receipt=False)
                    self.xmpp_manager.send_stanza(message)
Esempio n. 4
0
 def unavailableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = MUCAvailabilityPresence(sender, recipient, available=False, id=id)
     NotificationCenter().post_notification('XMPPMucGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 5
0
 def probeReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = ProbePresence(sender, recipient, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceProbe', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 6
0
 def probeReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = ProbePresence(sender, recipient, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceProbe', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 7
0
 def unavailableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = MUCAvailabilityPresence(sender, recipient, available=False, id=id)
     NotificationCenter().post_notification('XMPPMucGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 8
0
    def send_available(self, stanza):
        sender_uri = FrozenURI.parse('xmpp:' + stanza.element['from'])
        sender = Identity(sender_uri)
        recipient_uri = FrozenURI.parse('xmpp:' + stanza.element['to'])
        recipient = Identity(recipient_uri)

        available = AvailabilityPresence(sender=recipient, recipient=sender)
        self.send(available.to_xml_element())
Esempio n. 9
0
    def send_available(self, stanza):
        sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
        sender = Identity(sender_uri)
        recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
        recipient = Identity(recipient_uri)

        available = AvailabilityPresence(sender=recipient, recipient=sender)
        self.send(available.to_xml_element())
Esempio n. 10
0
 def _process_subscription_stanza(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     type = stanza.element.getAttribute('type')
     presence_stanza = SubscriptionPresence(sender, recipient, type, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceSubscriptionStatus', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 11
0
 def _process_subscription_stanza(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     type = stanza.element.getAttribute('type')
     presence_stanza = SubscriptionPresence(sender, recipient, type, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceSubscriptionStatus', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 12
0
 def availableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     show = stanza.show
     statuses = stanza.statuses
     presence_stanza = AvailabilityPresence(sender, recipient, available=True, show=show, statuses=statuses, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 13
0
 def availableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     show = stanza.show
     statuses = stanza.statuses
     presence_stanza = AvailabilityPresence(sender, recipient, available=True, show=show, statuses=statuses, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
Esempio n. 14
0
    def _start_outgoing_jingle_session(self, streams):
        if self.xmpp_identity.uri.resource is not None:
            self.sip_session.reject()
            return
        xmpp_manager = XMPPManager()
        local_jid = self.sip_identity.uri.as_xmpp_jid()
        remote_jid = self.xmpp_identity.uri.as_xmpp_jid()

        # If this was an invitation to a conference, use the information in the Referred-By header
        if self.sip_identity.uri.host in xmpp_manager.muc_domains and self.sip_session.transfer_info and self.sip_session.transfer_info.referred_by:
            try:
                referred_by_uri = SIPURI.parse(self.sip_session.transfer_info.referred_by)
            except SIPCoreError:
                self.sip_session.reject(488)
                return
            else:
                inviter_uri = FrozenURI(referred_by_uri.user, referred_by_uri.host)
                local_jid = inviter_uri.as_xmpp_jid()

        # Use disco to gather potential JIDs to call
        d = xmpp_manager.disco_client_protocol.requestItems(remote_jid, sender=local_jid)
        try:
            items = block_on(d)
        except Exception:
            items = []
        if not items:
            self.sip_session.reject(480)
            return

        # Check which items support Jingle
        valid = []
        for item in items:
            d = xmpp_manager.disco_client_protocol.requestInfo(item.entity, nodeIdentifier=item.nodeIdentifier, sender=local_jid)
            try:
                info = block_on(d)
            except Exception:
                continue
            if jingle.NS_JINGLE in info.features and jingle.NS_JINGLE_APPS_RTP in info.features:
                valid.append(item.entity)
        if not valid:
            self.sip_session.reject(480)
            return

        # TODO: start multiple sessions?
        self._xmpp_identity = Identity(FrozenURI.parse(valid[0]))

        notification_center = NotificationCenter()
        if self.sip_identity.uri.host in xmpp_manager.muc_domains:
            self.jingle_session = JingleSession(xmpp_manager.jingle_coin_protocol)
        else:
            self.jingle_session = JingleSession(xmpp_manager.jingle_protocol)
        notification_center.add_observer(self, sender=self.jingle_session)
        self.jingle_session.connect(self.sip_identity, self.xmpp_identity, streams, is_focus=self.sip_session.remote_focus)
Esempio n. 15
0
    def _start_outgoing_jingle_session(self, streams):
        if self.xmpp_identity.uri.resource is not None:
            self.sip_session.reject()
            return
        xmpp_manager = XMPPManager()
        local_jid = self.sip_identity.uri.as_xmpp_jid()
        remote_jid = self.xmpp_identity.uri.as_xmpp_jid()

        # If this was an invitation to a conference, use the information in the Referred-By header
        if self.sip_identity.uri.host in xmpp_manager.muc_domains and self.sip_session.transfer_info and self.sip_session.transfer_info.referred_by:
            try:
                referred_by_uri = SIPURI.parse(self.sip_session.transfer_info.referred_by)
            except SIPCoreError:
                self.sip_session.reject(488)
                return
            else:
                inviter_uri = FrozenURI(referred_by_uri.user, referred_by_uri.host)
                local_jid = inviter_uri.as_xmpp_jid()

        # Use disco to gather potential JIDs to call
        d = xmpp_manager.disco_client_protocol.requestItems(remote_jid, sender=local_jid)
        try:
            items = block_on(d)
        except Exception:
            items = []
        if not items:
            self.sip_session.reject(480)
            return

        # Check which items support Jingle
        valid = []
        for item in items:
            d = xmpp_manager.disco_client_protocol.requestInfo(item.entity, nodeIdentifier=item.nodeIdentifier, sender=local_jid)
            try:
                info = block_on(d)
            except Exception:
                continue
            if jingle.NS_JINGLE in info.features and jingle.NS_JINGLE_APPS_RTP in info.features:
                valid.append(item.entity)
        if not valid:
            self.sip_session.reject(480)
            return

        # TODO: start multiple sessions?
        self._xmpp_identity = Identity(FrozenURI.parse(valid[0]))

        notification_center = NotificationCenter()
        if self.sip_identity.uri.host in xmpp_manager.muc_domains:
            self.jingle_session = JingleSession(xmpp_manager.jingle_coin_protocol)
        else:
            self.jingle_session = JingleSession(xmpp_manager.jingle_protocol)
        notification_center.add_observer(self, sender=self.jingle_session)
        self.jingle_session.connect(self.sip_identity, self.xmpp_identity, streams, is_focus=self.sip_session.remote_focus)
Esempio n. 16
0
    def init_incoming(self, stanza):
        self._id = stanza.jingle.sid
        self._local_identity = Identity(FrozenURI.parse(stanza.recipient))
        self._remote_identity = Identity(FrozenURI.parse(stanza.sender))
        self._local_jid = self._local_identity.uri.as_xmpp_jid()
        self._remote_jid = self._remote_identity.uri.as_xmpp_jid()

        remote_sdp = jingle_to_sdp(stanza.jingle)
        try:
            self._sdp_negotiator = SDPNegotiator.create_with_remote_offer(remote_sdp)
        except SIPCoreError, e:
            self._fail(originator='local', reason='general-error', description=str(e))
            return
Esempio n. 17
0
 def onInvitation(self, msg):
     sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
     recipient = Identity(recipient_uri)
     invited_user_uri = FrozenURI.parse('xmpp:'+msg.x.invite['to'])
     invited_user = Identity(invited_user_uri)
     if msg.x.invite.reason is not None and msg.x.invite.reason.uri == MUC_USER_NS:
         reason = unicode(msg.x.invite.reason)
     else:
         reason = None
     invitation = IncomingInvitationMessage(sender, recipient, invited_user=invited_user, reason=reason, id=msg.getAttribute('id', None))
     NotificationCenter().post_notification('XMPPMucGotInvitation', sender=self.parent, data=NotificationData(invitation=invitation))
Esempio n. 18
0
 def onGroupChat(self, msg):
     sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
     recipient = Identity(recipient_uri)
     body = None
     html_body = None
     if msg.html is not None:
         html_body = msg.html.toXml()
     if msg.body is not None:
         body = unicode(msg.body)
     message = GroupChatMessage(sender, recipient, body, html_body, id=msg.getAttribute('id', None))
     NotificationCenter().post_notification('XMPPMucGotGroupChat', sender=self.parent, data=NotificationData(message=message))
Esempio n. 19
0
    def init_incoming(self, stanza):
        self._id = stanza.jingle.sid
        self._local_identity = Identity(FrozenURI.parse(stanza.recipient))
        self._remote_identity = Identity(FrozenURI.parse(stanza.sender))
        self._local_jid = self._local_identity.uri.as_xmpp_jid()
        self._remote_jid = self._remote_identity.uri.as_xmpp_jid()

        remote_sdp = jingle_to_sdp(stanza.jingle)
        try:
            self._sdp_negotiator = SDPNegotiator.create_with_remote_offer(remote_sdp)
        except SIPCoreError, e:
            self._fail(originator='local', reason='general-error', description=str(e))
            return
Esempio n. 20
0
 def onInvitation(self, msg):
     sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
     recipient = Identity(recipient_uri)
     invited_user_uri = FrozenURI.parse('xmpp:'+msg.x.invite['to'])
     invited_user = Identity(invited_user_uri)
     if msg.x.invite.reason is not None and msg.x.invite.reason.uri == MUC_USER_NS:
         reason = unicode(msg.x.invite.reason)
     else:
         reason = None
     invitation = IncomingInvitationMessage(sender, recipient, invited_user=invited_user, reason=reason, id=msg.getAttribute('id', None))
     NotificationCenter().post_notification('XMPPMucGotInvitation', sender=self.parent, data=NotificationData(invitation=invitation))
Esempio n. 21
0
    def incoming_subscription(self, subscribe_request, data):
        from_header = data.headers.get('From', Null)
        to_header = data.headers.get('To', Null)
        if Null in (from_header, to_header):
            subscribe_request.reject(400)
            return

        if XMPPGatewayConfig.log_presence:
            log.info('SIP subscription from %s to %s' % (format_uri(
                from_header.uri, 'sip'), format_uri(to_header.uri, 'xmpp')))

        if subscribe_request.event != 'presence':
            if XMPPGatewayConfig.log_presence:
                log.info(
                    'SIP subscription rejected: only presence event is supported'
                )
            subscribe_request.reject(489)
            return

        # Check domain
        remote_identity_uri = data.headers['From'].uri
        if remote_identity_uri.host not in XMPPGatewayConfig.domains:
            if XMPPGatewayConfig.log_presence:
                log.info(
                    'SIP subscription rejected: From domain is not a local XMPP domain'
                )
            subscribe_request.reject(606)
            return

        # Get URI representing the SIP side
        sip_leg_uri = FrozenURI(remote_identity_uri.user,
                                remote_identity_uri.host)

        # Get URI representing the XMPP side
        request_uri = data.request_uri
        xmpp_leg_uri = FrozenURI(request_uri.user, request_uri.host)

        try:
            handler = self.s2x_presence_subscriptions[(sip_leg_uri,
                                                       xmpp_leg_uri)]
        except KeyError:
            sip_identity = Identity(sip_leg_uri,
                                    data.headers['From'].display_name)
            xmpp_identity = Identity(xmpp_leg_uri)
            handler = S2XPresenceHandler(sip_identity, xmpp_identity)
            self.s2x_presence_subscriptions[(sip_leg_uri,
                                             xmpp_leg_uri)] = handler
            NotificationCenter().add_observer(self, sender=handler)
            handler.start()

        handler.add_sip_subscription(subscribe_request)
Esempio n. 22
0
 def _NH_ChatStreamGotMessage(self, notification):
     # Notification is sent by the MSRP stream
     message = notification.data.message
     content_type = message.content_type.lower()
     if content_type not in ('text/plain', 'text/html'):
         return
     if content_type == 'text/plain':
         html_body = None
         body = message.body
     else:
         html_body = message.body
         body = None
     if self._sip_session_timer is not None and self._sip_session_timer.active():
         self._sip_session_timer.reset(SESSION_TIMEOUT)
     chunk = notification.data.chunk
     if self.started:
         self.xmpp_session.send_message(body, html_body, message_id=chunk.message_id)
         if self.use_receipts:
             self._pending_msrp_chunks[chunk.message_id] = chunk
         else:
             self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
     else:
         sender = self.sip_identity
         recipient_uri = FrozenURI.parse(message.recipients[0].uri)
         recipient = Identity(recipient_uri, message.recipients[0].display_name)
         xmpp_manager = XMPPManager()
         xmpp_manager.send_stanza(ChatMessage(sender, recipient, body, html_body))
         self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
Esempio n. 23
0
 def _NH_ChatStreamGotMessage(self, notification):
     # Notification is sent by the MSRP stream
     if not self._xmpp_muc_session:
         return
     message = notification.data.message
     content_type = message.content_type.lower()
     if content_type not in ('text/plain', 'text/html'):
         return
     if content_type == 'text/plain':
         html_body = None
         body = message.content
     else:
         html_body = message.content
         body = None
     resource = message.sender.display_name or str(message.sender.uri)
     sender = Identity(
         FrozenURI(self.sip_identity.uri.user, self.sip_identity.uri.host,
                   resource))
     self._xmpp_muc_session.send_message(sender,
                                         body,
                                         html_body,
                                         message_id='MUC.' +
                                         uuid.uuid4().hex)
     self._msrp_stream.msrp_session.send_report(notification.data.chunk,
                                                200, 'OK')
Esempio n. 24
0
 def end(self):
     if self.ended:
         return
     notification_center = NotificationCenter()
     if self._xmpp_muc_session is not None:
         notification_center.remove_observer(self,
                                             sender=self._xmpp_muc_session)
         # Send indication that the user has been kicked from the room
         sender = Identity(
             FrozenURI(self.sip_identity.uri.user,
                       self.sip_identity.uri.host, self.nickname))
         stanza = MUCAvailabilityPresence(sender,
                                          self.xmpp_identity,
                                          available=False)
         stanza.jid = self.xmpp_identity
         stanza.muc_statuses.append('307')
         xmpp_manager = XMPPManager()
         xmpp_manager.send_muc_stanza(stanza)
         self._xmpp_muc_session.end()
         self._xmpp_muc_session = None
     if self._sip_session is not None:
         notification_center.remove_observer(self, sender=self._sip_session)
         self._sip_session.end()
         self._sip_session = None
     self.ended = True
     notification_center.post_notification('X2SMucHandlerDidEnd',
                                           sender=self)
Esempio n. 25
0
 def _NH_ChatStreamGotMessage(self, notification):
     # Notification is sent by the MSRP stream
     message = notification.data.message
     content_type = message.content_type.lower()
     if content_type not in ('text/plain', 'text/html'):
         return
     if content_type == 'text/plain':
         html_body = None
         body = message.content
     else:
         html_body = message.content
         body = None
     if self._sip_session_timer is not None and self._sip_session_timer.active(
     ):
         self._sip_session_timer.reset(SESSION_TIMEOUT)
     chunk = notification.data.chunk
     if self.started:
         self.xmpp_session.send_message(body,
                                        html_body,
                                        message_id=chunk.message_id)
         if self.use_receipts:
             self._pending_msrp_chunks[chunk.message_id] = chunk
         else:
             self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
     else:
         sender = self.sip_identity
         recipient_uri = FrozenURI.parse(message.recipients[0].uri)
         recipient = Identity(recipient_uri,
                              message.recipients[0].display_name)
         xmpp_manager = XMPPManager()
         xmpp_manager.send_stanza(
             ChatMessage(sender, recipient, body, html_body))
         self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
Esempio n. 26
0
 def _NH_ChatStreamDidDeliverMessage(self, notification):
     # Echo back the message to the sender
     stanza = self._pending_messages_map.pop(notification.data.message_id)
     stanza.sender, stanza.recipient = stanza.recipient, stanza.sender
     stanza.sender.uri = FrozenURI(stanza.sender.uri.user,
                                   stanza.sender.uri.host, self.nickname)
     xmpp_manager = XMPPManager()
     xmpp_manager.send_muc_stanza(stanza)
Esempio n. 27
0
 def _NH_XMPPGotMucAddParticipantRequest(self, notification):
     sender = notification.data.sender
     recipient = notification.data.recipient
     participant = notification.data.participant
     muc_uri = FrozenURI(recipient.uri.user, recipient.uri.host)
     sender_uri = FrozenURI(sender.uri.user, sender.uri.host)
     participant_uri = FrozenURI(participant.uri.user, participant.uri.host)
     sender = Identity(sender_uri)
     recipient = Identity(muc_uri)
     participant = Identity(participant_uri)
     try:
         handler = self.x2s_muc_add_participant_handlers[(muc_uri, participant_uri)]
     except KeyError:
         handler = X2SMucInvitationHandler(sender, recipient, participant)
         self.x2s_muc_add_participant_handlers[(muc_uri, participant_uri)] = handler
         notification.center.add_observer(self, sender=handler)
         handler.start()
Esempio n. 28
0
 def _NH_SIPSessionGotConferenceInfo(self, notification):
     # Translate to XMPP payload
     xmpp_manager = XMPPManager()
     own_uri = FrozenURI(self.xmpp_identity.uri.user,
                         self.xmpp_identity.uri.host)
     conference_info = notification.data.conference_info
     new_participants = set()
     for user in conference_info.users:
         user_uri = FrozenURI.parse(user.entity if user.entity.startswith((
             'sip:', 'sips:')) else 'sip:' + user.entity)
         nickname = user.display_text.value if user.display_text else user.entity
         new_participants.add((user_uri, nickname))
     # Remove participants that are no longer in the room
     for uri, nickname in self._participants - new_participants:
         sender = Identity(
             FrozenURI(self.sip_identity.uri.user,
                       self.sip_identity.uri.host, nickname))
         stanza = MUCAvailabilityPresence(sender,
                                          self.xmpp_identity,
                                          available=False)
         xmpp_manager.send_muc_stanza(stanza)
     # Send presence for current participants
     for uri, nickname in new_participants:
         if uri == own_uri:
             continue
         sender = Identity(
             FrozenURI(self.sip_identity.uri.user,
                       self.sip_identity.uri.host, nickname))
         stanza = MUCAvailabilityPresence(sender,
                                          self.xmpp_identity,
                                          available=True)
         stanza.jid = Identity(uri)
         xmpp_manager.send_muc_stanza(stanza)
     self._participants = new_participants
     # Send own status last
     sender = Identity(
         FrozenURI(self.sip_identity.uri.user, self.sip_identity.uri.host,
                   self.nickname))
     stanza = MUCAvailabilityPresence(sender,
                                      self.xmpp_identity,
                                      available=True)
     stanza.jid = self.xmpp_identity
     stanza.muc_statuses.append('110')
     xmpp_manager.send_muc_stanza(stanza)
Esempio n. 29
0
 def _NH_XMPPMucGotGroupChat(self, notification):
     message = notification.data.message
     muc_uri = FrozenURI(message.recipient.uri.user, message.recipient.uri.host)
     try:
         session = self.muc_session_manager.incoming[(muc_uri, message.sender.uri)]
     except KeyError:
         # Ignore groupchat messages if there was no session created
         pass
     else:
         session.channel.send(message)
Esempio n. 30
0
    def _NH_SIPSessionDidStart(self, notification):
        log.info("SIP session %s started" % self.sip_session.call_id)
        self._sip_session_timer = reactor.callLater(SESSION_TIMEOUT,
                                                    self._inactivity_timeout)

        if self.sip_session.direction == 'outgoing':
            # Time to set sip_identity and create the XMPPChatSession
            contact_uri = self.sip_session._invitation.remote_contact_header.uri
            if contact_uri.parameters.get('gr') is not None:
                sip_leg_uri = FrozenURI(contact_uri.user, contact_uri.host,
                                        contact_uri.parameters.get('gr'))
            else:
                tmp = self.sip_session.remote_identity.uri
                sip_leg_uri = FrozenURI(tmp.user, tmp.host,
                                        generate_sylk_resource())
            self.sip_identity = Identity(
                sip_leg_uri, self.sip_session.remote_identity.display_name)
            session = XMPPChatSession(local_identity=self.sip_identity,
                                      remote_identity=self.xmpp_identity)
            self.xmpp_session = session
            # Session is now established on both ends
            self.started = True
            # Try to wakeup XMPP clients
            self.xmpp_session.send_composing_indication('active')
            self.xmpp_session.send_message(' ', 'text/plain')
        else:
            if self.xmpp_session is not None:
                # Session is now established on both ends
                self.started = True
                # Try to wakeup XMPP clients
                self.xmpp_session.send_composing_indication('active')
                self.xmpp_session.send_message(' ', 'text/plain')
            else:
                # Try to wakeup XMPP clients
                sender = self.sip_identity
                tmp = self.sip_session.local_identity.uri
                recipient_uri = FrozenURI(tmp.user, tmp.host)
                recipient = Identity(recipient_uri)
                xmpp_manager = XMPPManager()
                xmpp_manager.send_stanza(
                    ChatMessage(sender, recipient, ' ', 'text/plain'))
                # Send queued messages
                self._send_queued_messages()
Esempio n. 31
0
    def init_incoming(self, stanza):
        self._id = stanza.jingle.sid
        self._local_identity = Identity(FrozenURI.parse(stanza.recipient))
        self._remote_identity = Identity(FrozenURI.parse(stanza.sender))
        self._local_jid = self._local_identity.uri.as_xmpp_jid()
        self._remote_jid = self._remote_identity.uri.as_xmpp_jid()

        remote_sdp = jingle_to_sdp(stanza.jingle)
        try:
            self._sdp_negotiator = SDPNegotiator.create_with_remote_offer(
                remote_sdp)
        except SIPCoreError as e:
            self._fail(originator='local',
                       reason='general-error',
                       description=str(e))
            return

        self.proposed_streams = []
        for index, media_stream in enumerate(remote_sdp.media):
            if media_stream.port != 0:
                for stream_type in MediaStreamRegistry:
                    try:
                        stream = stream_type.new_from_sdp(
                            self, remote_sdp, index)
                    except InvalidStreamError:
                        break
                    except UnknownStreamError:
                        continue
                    else:
                        stream.index = index
                        self.proposed_streams.append(stream)
                        break

        if self.proposed_streams:
            self.direction = 'incoming'
            self.state = 'incoming'
            NotificationCenter().post_notification(
                'JingleSessionNewIncoming',
                sender=self,
                data=NotificationData(streams=self.proposed_streams))
        else:
            self._fail(originator='local', reason='unsupported-applications')
Esempio n. 32
0
 def onGroupChat(self, msg):
     sender_uri = FrozenURI.parse('xmpp:' + msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:' + msg['to'])
     recipient = Identity(recipient_uri)
     body = None
     html_body = None
     if msg.html is not None:
         html_body = msg.html.toXml()
     if msg.body is not None:
         body = unicode(msg.body)
     message = GroupChatMessage(sender,
                                recipient,
                                body,
                                html_body,
                                id=msg.getAttribute('id', None))
     NotificationCenter().post_notification(
         'XMPPMucGotGroupChat',
         sender=self.parent,
         data=NotificationData(message=message))
Esempio n. 33
0
 def _NH_XMPPGotMucJoinRequest(self, notification):
     stanza = notification.data.stanza
     muc_uri = FrozenURI(stanza.recipient.uri.user, stanza.recipient.uri.host)
     nickname = stanza.recipient.uri.resource
     try:
         handler = self.x2s_muc_sessions[(stanza.sender.uri, muc_uri)]
     except KeyError:
         xmpp_identity = stanza.sender
         sip_identity = stanza.recipient
         sip_identity.uri = muc_uri
         handler = X2SMucHandler(sip_identity, xmpp_identity, nickname)
         handler._first_stanza = stanza
         notification.center.add_observer(self, sender=handler)
         handler.start()
         # Check if there was a pending join request on the SIP side
         try:
             handler = self.s2x_muc_add_participant_handlers[(muc_uri, FrozenURI(stanza.sender.uri.user, stanza.sender.uri.host))]
         except KeyError:
             pass
         else:
             handler.stop()
Esempio n. 34
0
 def new_from_sip_session(cls, session):
     proposed_stream_types = set(
         [stream.type for stream in session.proposed_streams])
     streams = []
     for stream_type in proposed_stream_types:
         try:
             klass = JingleMediaStreamRegistry.get(stream_type)
         except Exception:
             continue
         streams.append(klass())
     if not streams:
         session.reject(488)
         return None
     session.send_ring_indication()
     instance = cls()
     NotificationCenter().add_observer(instance, sender=session)
     # Get URI representing the SIP side
     contact_uri = session._invitation.remote_contact_header.uri
     if contact_uri.parameters.get('gr') is not None:
         sip_leg_uri = FrozenURI(contact_uri.user, contact_uri.host,
                                 contact_uri.parameters.get('gr'))
     else:
         tmp = session.remote_identity.uri
         sip_leg_uri = FrozenURI(tmp.user, tmp.host,
                                 generate_sylk_resource())
     instance._sip_identity = Identity(sip_leg_uri)
     # Get URI representing the XMPP side
     request_uri = session.request_uri
     remote_resource = request_uri.parameters.get('gr', None)
     if remote_resource is not None:
         try:
             remote_resource = decode_resource(remote_resource)
         except (TypeError, UnicodeError):
             remote_resource = None
     xmpp_leg_uri = FrozenURI(request_uri.user, request_uri.host,
                              remote_resource)
     instance._xmpp_identity = Identity(xmpp_leg_uri)
     instance.sip_session = session
     instance._start_outgoing_jingle_session(streams)
     return instance
Esempio n. 35
0
 def _NH_XMPPGotPresenceProbe(self, notification):
     stanza = notification.data.presence_stanza
     if stanza.recipient.uri.resource is not None:
         # Skip directed presence
         return
     sender_uri = stanza.sender.uri
     sender_uri_bare = FrozenURI(sender_uri.user, sender_uri.host)
     try:
         subscription = self.subscription_manager.incoming_subscriptions[(stanza.recipient.uri, sender_uri_bare)]
     except KeyError:
         notification.center.post_notification('XMPPGotPresenceSubscriptionRequest', sender=self, data=NotificationData(stanza=stanza))
     else:
         subscription.channel.send(stanza)
Esempio n. 36
0
 def _NH_XMPPMucGotPresenceAvailability(self, notification):
     stanza = notification.data.presence_stanza
     if not stanza.sender.uri.resource:
         return
     muc_uri = FrozenURI(stanza.recipient.uri.user, stanza.recipient.uri.host)
     try:
         session = self.muc_session_manager.incoming[(muc_uri, stanza.sender.uri)]
     except KeyError:
         if stanza.available:
             notification.center.post_notification('XMPPGotMucJoinRequest', sender=self, data=NotificationData(stanza=stanza))
         else:
             notification.center.post_notification('XMPPGotMucLeaveRequest', sender=self, data=NotificationData(stanza=stanza))
     else:
         session.channel.send(stanza)
Esempio n. 37
0
 def _NH_XMPPGotPresenceAvailability(self, notification):
     stanza = notification.data.presence_stanza
     if stanza.recipient.uri.resource is not None:
         # Skip directed presence
         return
     sender_uri = stanza.sender.uri
     sender_uri_bare = FrozenURI(sender_uri.user, sender_uri.host)
     try:
         subscription = self.subscription_manager.outgoing_subscriptions[(stanza.recipient.uri, sender_uri_bare)]
     except KeyError:
         # Ignore incoming presence stanzas if there is no subscription
         pass
     else:
         subscription.channel.send(stanza)
Esempio n. 38
0
 def _NH_XMPPGotPresenceSubscriptionRequest(self, notification):
     stanza = notification.data.stanza
     # Disregard the resource part, the presence request could be a probe instead of a subscribe
     sender_uri = stanza.sender.uri
     sender_uri_bare = FrozenURI(sender_uri.user, sender_uri.host)
     try:
         handler = self.x2s_presence_subscriptions[(sender_uri_bare, stanza.recipient.uri)]
     except KeyError:
         xmpp_identity = stanza.sender
         xmpp_identity.uri = sender_uri_bare
         sip_identity = stanza.recipient
         handler = X2SPresenceHandler(sip_identity, xmpp_identity)
         self.x2s_presence_subscriptions[(sender_uri_bare, stanza.recipient.uri)] = handler
         notification.center.add_observer(self, sender=handler)
         handler.start()
Esempio n. 39
0
 def _onMessage(self, message):
     if message.handled:
         return
     messageType = message.getAttribute("type")
     if messageType == 'error':
         return
     if messageType not in self.messageTypes:
         message['type'] = 'normal'
     if messageType == 'groupchat':
         self.onGroupChat(message)
     else:
         to_uri = FrozenURI.parse('xmpp:' + message['to'])
         if to_uri.host in self.parent.domains:
             # Check if it's an invitation
             if message.x is not None and message.x.invite is not None and message.x.invite.uri == MUC_USER_NS:
                 self.onInvitation(message)
         else:
             # TODO: give error, private messages not supported
             pass
Esempio n. 40
0
 def _onMessage(self, message):
     if message.handled:
         return
     messageType = message.getAttribute("type")
     if messageType == 'error':
         return
     if messageType not in self.messageTypes:
         message['type'] = 'normal'
     if messageType == 'groupchat':
         self.onGroupChat(message)
     else:
         to_uri = FrozenURI.parse('xmpp:'+message['to'])
         if to_uri.host in self.parent.domains:
             # Check if it's an invitation
             if message.x is not None and message.x.invite is not None and message.x.invite.uri == MUC_USER_NS:
                 self.onInvitation(message)
         else:
             # TODO: give error, private messages not supported
             pass
Esempio n. 41
0
 def _process_pidf(self, body):
     try:
         pidf_doc = pidf.PIDF.parse(body)
     except ParserError as e:
         log.warn('Error parsing PIDF document: %s' % e)
         return
     # Build XML stanzas out of PIDF documents
     try:
         person = next(p for p in pidf_doc.persons)
     except StopIteration:
         person = None
     for service in pidf_doc.services:
         sip_contact = self.sip_identity.uri.as_sip_uri()
         if service.device_info is not None:
             sip_contact.parameters[
                 'gr'] = 'urn:uuid:%s' % service.device_info.id
         else:
             sip_contact.parameters['gr'] = service.id
         sender = Identity(FrozenURI.parse(sip_contact))
         if service.status.extended is not None:
             available = service.status.extended != 'offline'
         else:
             available = service.status.basic == 'open'
         stanza = AvailabilityPresence(sender, self.xmpp_identity,
                                       available)
         for note in service.notes:
             stanza.statuses[note.lang] = note
         if service.status.extended is not None:
             if service.status.extended == 'away':
                 stanza.show = 'away'
             elif service.status.extended == 'busy':
                 stanza.show = 'dnd'
         elif person is not None and person.activities is not None:
             activities = set(list(person.activities))
             if 'away' in activities:
                 stanza.show = 'away'
             elif {'holiday', 'vacation'}.intersection(activities):
                 stanza.show = 'xa'
             elif 'busy' in activities:
                 stanza.show = 'dnd'
         self._xmpp_subscription.send_presence(stanza)
Esempio n. 42
0
 def _NH_XMPPGotChatMessage(self, notification):
     # This notification is only processed here untill the ChatSessionHandler
     # has both (SIP and XMPP) sessions established
     message = notification.data.message
     sender = message.sender
     recipient = message.recipient
     if XMPPGatewayConfig.use_msrp_for_chat:
         if recipient.uri.resource is None:
             # If recipient resource is not set the session is started from
             # the XMPP side
             sip_leg_uri = FrozenURI.new(recipient.uri)
             xmpp_leg_uri = FrozenURI.new(sender.uri)
             try:
                 handler = self.pending_sessions[(sip_leg_uri, xmpp_leg_uri)]
                 handler.enqueue_xmpp_message(message)
             except KeyError:
                 # Check if we have any already open chat session and dispatch it there
                 try:
                     handler = next(
                         h
                         for h in self.chat_sessions
                         if h.xmpp_identity.uri.user == xmpp_leg_uri.user
                         and h.xmpp_identity.uri.host == xmpp_leg_uri.host
                         and h.sip_identity.uri.user == sip_leg_uri.user
                         and h.sip_identity.uri.host == sip_leg_uri.host
                     )
                 except StopIteration:
                     # Not found, need to create a new handler and a outgoing SIP session
                     xmpp_identity = Identity(xmpp_leg_uri)
                     handler = ChatSessionHandler.new_from_xmpp_stanza(xmpp_identity, sip_leg_uri)
                     key = (sip_leg_uri, xmpp_leg_uri)
                     self.pending_sessions[key] = handler
                     NotificationCenter().add_observer(self, sender=handler)
                 handler.enqueue_xmpp_message(message)
         else:
             # Find handler pending XMPP confirmation
             sip_leg_uri = FrozenURI.new(recipient.uri)
             xmpp_leg_uri = FrozenURI(sender.uri.user, sender.uri.host)
             try:
                 handler = self.pending_sessions[(sip_leg_uri, xmpp_leg_uri)]
             except KeyError:
                 # Find handler pending XMPP confirmation
                 sip_leg_uri = FrozenURI(recipient.uri.user, recipient.uri.host)
                 xmpp_leg_uri = FrozenURI.new(sender.uri)
                 try:
                     handler = self.pending_sessions[(sip_leg_uri, xmpp_leg_uri)]
                 except KeyError:
                     # Try harder, maybe the XMPP client changed his from
                     try:
                         handler = next(
                             h
                             for h in self.chat_sessions
                             if h.xmpp_identity.uri.user == xmpp_leg_uri.user
                             and h.xmpp_identity.uri.host == xmpp_leg_uri.host
                             and h.sip_identity.uri.user == sip_leg_uri.user
                             and h.sip_identity.uri.host == sip_leg_uri.host
                         )
                     except StopIteration:
                         # It's a new XMPP session to a full JID, disregard the full JID and start a new SIP session to the bare JID
                         xmpp_identity = Identity(xmpp_leg_uri)
                         handler = ChatSessionHandler.new_from_xmpp_stanza(xmpp_identity, sip_leg_uri)
                         key = (sip_leg_uri, xmpp_leg_uri)
                         self.pending_sessions[key] = handler
                         NotificationCenter().add_observer(self, sender=handler)
                 handler.enqueue_xmpp_message(message)
             else:
                 # Found handle, create XMPP session and establish session
                 session = XMPPChatSession(local_identity=recipient, remote_identity=sender)
                 handler.enqueue_xmpp_message(message)
                 handler.xmpp_identity = session.remote_identity
                 handler.xmpp_session = session
     else:
         sip_message_sender = SIPMessageSender(message)
         try:
             sip_message_sender.send().wait()
         except SIPMessageError as e:
             # TODO report back an error stanza
             log.error("Error sending SIP Message: %s" % e)
Esempio n. 43
0
 def _NH_XMPPGotChatMessage(self, notification):
     # This notification is only processed here untill the ChatSessionHandler
     # has both (SIP and XMPP) sessions established
     message = notification.data.message
     sender = message.sender
     recipient = message.recipient
     if XMPPGatewayConfig.use_msrp_for_chat:
         if recipient.uri.resource is None:
             # If recipient resource is not set the session is started from
             # the XMPP side
             sip_leg_uri = FrozenURI.new(recipient.uri)
             xmpp_leg_uri = FrozenURI.new(sender.uri)
             try:
                 handler = self.pending_sessions[(sip_leg_uri,
                                                  xmpp_leg_uri)]
                 handler.enqueue_xmpp_message(message)
             except KeyError:
                 # Check if we have any already open chat session and dispatch it there
                 try:
                     handler = next(
                         h for h in self.chat_sessions
                         if h.xmpp_identity.uri.user == xmpp_leg_uri.user
                         and h.xmpp_identity.uri.host == xmpp_leg_uri.host
                         and h.sip_identity.uri.user == sip_leg_uri.user
                         and h.sip_identity.uri.host == sip_leg_uri.host)
                 except StopIteration:
                     # Not found, need to create a new handler and a outgoing SIP session
                     xmpp_identity = Identity(xmpp_leg_uri)
                     handler = ChatSessionHandler.new_from_xmpp_stanza(
                         xmpp_identity, sip_leg_uri)
                     key = (sip_leg_uri, xmpp_leg_uri)
                     self.pending_sessions[key] = handler
                     NotificationCenter().add_observer(self, sender=handler)
                 handler.enqueue_xmpp_message(message)
         else:
             # Find handler pending XMPP confirmation
             sip_leg_uri = FrozenURI.new(recipient.uri)
             xmpp_leg_uri = FrozenURI(sender.uri.user, sender.uri.host)
             try:
                 handler = self.pending_sessions[(sip_leg_uri,
                                                  xmpp_leg_uri)]
             except KeyError:
                 # Find handler pending XMPP confirmation
                 sip_leg_uri = FrozenURI(recipient.uri.user,
                                         recipient.uri.host)
                 xmpp_leg_uri = FrozenURI.new(sender.uri)
                 try:
                     handler = self.pending_sessions[(sip_leg_uri,
                                                      xmpp_leg_uri)]
                 except KeyError:
                     # Try harder, maybe the XMPP client changed his from
                     try:
                         handler = next(
                             h for h in self.chat_sessions
                             if h.xmpp_identity.uri.user ==
                             xmpp_leg_uri.user and h.xmpp_identity.uri.host
                             == xmpp_leg_uri.host and
                             h.sip_identity.uri.user == sip_leg_uri.user and
                             h.sip_identity.uri.host == sip_leg_uri.host)
                     except StopIteration:
                         # It's a new XMPP session to a full JID, disregard the full JID and start a new SIP session to the bare JID
                         xmpp_identity = Identity(xmpp_leg_uri)
                         handler = ChatSessionHandler.new_from_xmpp_stanza(
                             xmpp_identity, sip_leg_uri)
                         key = (sip_leg_uri, xmpp_leg_uri)
                         self.pending_sessions[key] = handler
                         NotificationCenter().add_observer(self,
                                                           sender=handler)
                 handler.enqueue_xmpp_message(message)
             else:
                 # Found handle, create XMPP session and establish session
                 session = XMPPChatSession(local_identity=recipient,
                                           remote_identity=sender)
                 handler.enqueue_xmpp_message(message)
                 handler.xmpp_identity = session.remote_identity
                 handler.xmpp_session = session
     else:
         sip_message_sender = SIPMessageSender(message)
         try:
             sip_message_sender.send().wait()
         except SIPMessageError as e:
             # TODO report back an error stanza
             log.error('Error sending SIP Message: %s' % e)
Esempio n. 44
0
    def incoming_chat_session(self, session):
        # Check if this session is really an invitation to add a participant to a conference room / muc
        if session.remote_identity.uri.host in self.xmpp_manager.muc_domains and 'isfocus' in session._invitation.remote_contact_header.parameters:
            try:
                referred_by_uri = SIPURI.parse(
                    session.transfer_info.referred_by)
            except SIPCoreError:
                log.info(
                    "SIP multiparty session invitation %s failed: invalid Referred-By header"
                    % session.call_id)
                session.reject(488)
                return
            muc_uri = FrozenURI(session.remote_identity.uri.user,
                                session.remote_identity.uri.host)
            inviter_uri = FrozenURI(referred_by_uri.user, referred_by_uri.host)
            recipient_uri = FrozenURI(session.local_identity.uri.user,
                                      session.local_identity.uri.host)
            sender = Identity(muc_uri)
            recipient = Identity(recipient_uri)
            inviter = Identity(inviter_uri)
            try:
                handler = self.s2x_muc_add_participant_handlers[(
                    muc_uri, recipient_uri)]
            except KeyError:
                handler = S2XMucInvitationHandler(session, sender, recipient,
                                                  inviter)
                self.s2x_muc_add_participant_handlers[(
                    muc_uri, recipient_uri)] = handler
                NotificationCenter().add_observer(self, sender=handler)
                handler.start()
            else:
                log.info(
                    "SIP multiparty session invitation %s failed: there is another invitation in progress from %s to %s"
                    % (session.call_id, format_uri(inviter_uri, 'sip'),
                       format_uri(recipient_uri, 'xmpp')))
                session.reject(480)
            return

        # Check domain
        if session.remote_identity.uri.host not in XMPPGatewayConfig.domains:
            log.info(
                'Session rejected: From domain is not a local XMPP domain')
            session.reject(606, 'Not Acceptable')
            return

        # Get URI representing the SIP side
        contact_uri = session._invitation.remote_contact_header.uri
        if contact_uri.parameters.get('gr') is not None:
            sip_leg_uri = FrozenURI(contact_uri.user, contact_uri.host,
                                    contact_uri.parameters.get('gr'))
        else:
            tmp = session.remote_identity.uri
            sip_leg_uri = FrozenURI(tmp.user, tmp.host,
                                    generate_sylk_resource())

        # Get URI representing the XMPP side
        request_uri = session.request_uri
        remote_resource = request_uri.parameters.get('gr', None)
        if remote_resource is not None:
            try:
                remote_resource = decode_resource(remote_resource)
            except (TypeError, UnicodeError):
                remote_resource = None
        xmpp_leg_uri = FrozenURI(request_uri.user, request_uri.host,
                                 remote_resource)

        try:
            handler = self.pending_sessions[(sip_leg_uri, xmpp_leg_uri)]
        except KeyError:
            pass
        else:
            # There is another pending session with same identifiers, can't accept this one
            log.info(
                'Session rejected: other session with same identifiers in progress'
            )
            session.reject(488)
            return

        sip_identity = Identity(sip_leg_uri,
                                session.remote_identity.display_name)
        handler = ChatSessionHandler.new_from_sip_session(
            sip_identity, session)
        NotificationCenter().add_observer(self, sender=handler)
        key = (sip_leg_uri, xmpp_leg_uri)
        self.pending_sessions[key] = handler

        if xmpp_leg_uri.resource is not None:
            # Incoming session target contained GRUU, so create XMPPChatSession immediately
            xmpp_session = XMPPChatSession(
                local_identity=handler.sip_identity,
                remote_identity=Identity(xmpp_leg_uri))
            handler.xmpp_identity = xmpp_session.remote_identity
            handler.xmpp_session = xmpp_session
Esempio n. 45
0
    def onMessage(self, msg):
        notification_center = NotificationCenter()

        sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
        sender = Identity(sender_uri)
        recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
        recipient = Identity(recipient_uri)

        msg_type = msg.getAttribute('type')
        msg_id = msg.getAttribute('id', None)
        is_empty = msg.body is None and msg.html is None

        if msg_type == 'error':
            error_type = msg.error['type']
            conditions = [(child.name, child.defaultUri) for child in msg.error.elements()]
            error_message = ErrorStanza('message', sender, recipient, error_type, conditions, id=msg_id)
            notification_center.post_notification('XMPPGotErrorMessage', sender=self.parent, data=NotificationData(error_message=error_message))
            return

        if msg_type in (None, 'normal', 'chat') and not is_empty:
            body = None
            html_body = None
            if msg.html is not None:
                html_body = msg.html.toXml()
            if msg.body is not None:
                body = unicode(msg.body)
            try:
                elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS)
            except StopIteration:
                use_receipt = False
            else:
                use_receipt = elem.name == u'request'
            if msg_type == 'chat':
                message = ChatMessage(sender, recipient, body, html_body, id=msg_id, use_receipt=use_receipt)
                notification_center.post_notification('XMPPGotChatMessage', sender=self.parent, data=NotificationData(message=message))
            else:
                message = NormalMessage(sender, recipient, body, html_body, id=msg_id, use_receipt=use_receipt)
                notification_center.post_notification('XMPPGotNormalMessage', sender=self.parent, data=NotificationData(message=message))
            return

        # Check if it's a composing indication
        if msg_type == 'chat' and is_empty:
            for elem in msg.elements():
                try:
                    elem = next(c for c in msg.elements() if c.uri == CHATSTATES_NS)
                except StopIteration:
                    pass
                else:
                    composing_indication = ChatComposingIndication(sender, recipient, elem.name, id=msg_id)
                    notification_center.post_notification('XMPPGotComposingIndication', sender=self.parent, data=NotificationData(composing_indication=composing_indication))
                    return

        # Check if it's a receipt acknowledgement
        if is_empty:
            try:
                elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS)
            except StopIteration:
                pass
            else:
                if elem.name == u'received' and msg_id is not None:
                    receipt = MessageReceipt(sender, recipient, msg_id)
                    notification_center.post_notification('XMPPGotReceipt', sender=self.parent, data=NotificationData(receipt=receipt))