Example #1
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
Example #2
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.msg("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.msg(
                    "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.msg("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.msg("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
Example #3
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)
Example #4
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)