Ejemplo n.º 1
0
    def _NH_IncomingFileTransferHandlerDidEnd(self, notification):
        notification.center.remove_observer(self, sender=self)

        remote_hash = self.file_selector.hash
        if not self.transfer_finished:
            log.msg('File transfer of %s cancelled' % os.path.basename(self.filename))
            self.remove_bogus_file(self.filename)
            self.status = 'INCOMPLETE'
        else:
            local_hash = 'sha1:' + ':'.join(re.findall(r'..', self.hash.hexdigest().upper()))
            if local_hash != remote_hash:
                log.warning('Hash of transferred file does not match the remote hash (file may have changed).')
                self.status = 'HASH_MISSMATCH'
                self.remove_bogus_file(self.filename)
            else:
                self.status = 'OK'

        self_uri = SIPURI.new(self.session.local_identity.uri)
        self_uri.parameters.clear()
        sender_uri = SIPURI.new(self.session.remote_identity.uri)
        sender_uri.parameters.clear()

        self.session = None
        self.stream = None

        file = File(self.filename, remote_hash, self.file_selector.size)
        notification.center.post_notification('IncomingFileTransferHandlerGotFile', sender=self, data=NotificationData(local_uri=self_uri, remote_uri=sender_uri, file=file))
Ejemplo n.º 2
0
    def lookup_destination(self, target_uri):
        assert isinstance(target_uri, SIPURI)

        lookup = DNSLookup()
        self.notification_center.add_observer(self, sender=lookup)
        settings = SIPSimpleSettings()

        if isinstance(self.account,
                      Account) and self.account.sip.outbound_proxy is not None:
            uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                         port=self.account.sip.outbound_proxy.port,
                         parameters={
                             'transport':
                             self.account.sip.outbound_proxy.transport
                         })
            self.log_info(u"Starting DNS lookup for %s through proxy %s" %
                          (target_uri.host, uri))
        elif isinstance(self.account,
                        Account) and self.account.sip.always_use_my_proxy:
            uri = SIPURI(host=self.account.id.domain)
            self.log_info(
                u"Starting DNS lookup for %s via proxy of account %s" %
                (target_uri.host, self.account.id))
        else:
            uri = target_uri
            self.log_info(u"Starting DNS lookup for %s" % target_uri.host)
        lookup.lookup_sip_proxy(uri, settings.sip.transport_list)
Ejemplo n.º 3
0
 def start(self):
     if not self.refer_to_uri.startswith(('sip:', 'sips:')):
         self.refer_to_uri = 'sip:%s' % self.refer_to_uri
     try:
         self.refer_to_uri = SIPURI.parse(self.refer_to_uri)
     except SIPCoreError:
         log.msg('Room %s - failed to add %s' % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.reject(488)
         return
     notification_center = NotificationCenter()
     notification_center.add_observer(self, sender=self._refer_request)
     if self.method == 'INVITE':
         self._refer_request.accept()
         settings = SIPSimpleSettings()
         account = DefaultAccount()
         if account.sip.outbound_proxy is not None:
             uri = SIPURI(host=account.sip.outbound_proxy.host,
                          port=account.sip.outbound_proxy.port,
                          parameters={'transport': account.sip.outbound_proxy.transport})
         else:
             uri = self.refer_to_uri
         lookup = DNSLookup()
         notification_center.add_observer(self, sender=lookup)
         lookup.lookup_sip_proxy(uri, settings.sip.transport_list)
     elif self.method == 'BYE':
         log.msg('Room %s - %s removed %s from the room' % (self.room_uri_str, self._refer_headers.get('From').uri, self.refer_to_uri))
         self._refer_request.accept()
         conference_application = ConferenceApplication()
         conference_application.remove_participant(self.refer_to_uri, self.room_uri)
         self._refer_request.end(200)
     else:
         self._refer_request.reject(488)
Ejemplo n.º 4
0
    def _CH_publish(self, command):
        if command.state is None or self._publication is None and command.state is SameState:
            command.signal()
            return

        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._publication_timer is not None and self._publication_timer.active(
        ):
            self._publication_timer.cancel()
        self._publication_timer = None

        if self._publication is None:
            duration = command.refresh_interval or self.account.sip.publish_interval
            from_header = FromHeader(self.account.uri,
                                     self.account.display_name)
            self._publication = Publication(
                from_header,
                self.event,
                self.payload_type.content_type,
                credentials=self.account.credentials,
                duration=duration,
                extra_headers=self.extra_headers)
            notification_center.add_observer(self, sender=self._publication)
            notification_center.post_notification(
                self.__class__.__name__ + 'WillPublish',
                sender=self,
                data=NotificationData(state=command.state, duration=duration))
        else:
            notification_center.post_notification(
                self.__class__.__name__ + 'WillRefresh',
                sender=self,
                data=NotificationData(state=command.state))

        try:
            # Lookup routes
            valid_transports = self.__transports__.intersection(
                settings.sip.transport_list)
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, valid_transports).wait()
            except DNSLookupError, e:
                retry_after = random.uniform(self._dns_wait,
                                             2 * self._dns_wait)
                self._dns_wait = limit(2 * self._dns_wait, max=30)
                raise PublicationError('DNS lookup failed: %s' % e,
                                       retry_after=retry_after)
            else:
Ejemplo n.º 5
0
    def start(self, restart=False):
        notification_center = NotificationCenter()
        file_path = self._file_selector.name.decode() if isinstance(
            self._file_selector.name, bytes) else self._file_selector.name

        self.ft_info = FileTransferInfo(
            transfer_id=str(uuid.uuid4()),
            direction='outgoing',
            file_size=self._file_selector.size,
            local_uri=format_identity_to_string(self.account)
            if self.account is not BonjourAccount() else 'bonjour.local',
            remote_uri=self.remote_identity,
            file_path=file_path)

        self.status = NSLocalizedString("Offering File...", "Label")
        self.ft_info.status = "proposing"

        self.log_info("Initiating DNS Lookup of %s to %s" %
                      (self.account, self.target_uri))
        lookup = DNSLookup()
        notification_center.add_observer(self, sender=lookup)

        if isinstance(self.account,
                      Account) and self.account.sip.outbound_proxy is not None:
            uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                         port=self.account.sip.outbound_proxy.port,
                         parameters={
                             'transport':
                             self.account.sip.outbound_proxy.transport
                         })
            self.log_info("Initiating DNS Lookup for %s (through proxy %s)" %
                          (self.target_uri, uri))
        elif isinstance(self.account,
                        Account) and self.account.sip.always_use_my_proxy:
            uri = SIPURI(host=self.account.id.domain)
            self.log_info(
                "Initiating DNS Lookup for %s (through account %s proxy)" %
                (self.target_uri, self.account.id))
        else:
            uri = self.target_uri
            self.log_info("Initiating DNS Lookup for %s" % self.target_uri)

        settings = SIPSimpleSettings()

        tls_name = None
        if isinstance(self.account, Account):
            tls_name = self.account.sip.tls_name or self.account.id.domain

        lookup.lookup_sip_proxy(uri,
                                settings.sip.transport_list,
                                tls_name=tls_name)

        if restart:
            notification_center.post_notification(
                "BlinkFileTransferWillRestart", self)
        else:
            notification_center.post_notification(
                "BlinkFileTransferNewOutgoing", sender=self)
Ejemplo n.º 6
0
 def validate(self, value):
     if value.startswith(('sip:', 'sips:')):
         uri = value
     else:
         uri = 'sip:' + value
     try:
         SIPURI.parse(uri)
     except SIPCoreError:
         raise ValueError('invalid SIP URI: {}'.format(value))
     return value
Ejemplo n.º 7
0
 def validate(self, value):
     prefix, sep, suffix = value.partition(':')
     if sep and prefix in ('sip', 'sips'):
         aor = suffix
     else:
         aor = value
     try:
         SIPURI.parse('sip:' + aor)
     except SIPCoreError:
         raise ValueError('invalid SIP URI: {}'.format(value))
     return aor
Ejemplo n.º 8
0
    def get_audio_recordings(self):
        result = []
        historydir = self.get_audio_recordings_directory()

        for acct in os.listdir(historydir):
            dirname = historydir + "/" + acct
            if not os.path.isdir(dirname):
                continue

            files = [
                dirname + "/" + f for f in os.listdir(dirname)
                if f.endswith(".wav")
            ]

            for file in files:
                try:
                    toks = file.split("/")[-1].split("-", 2)
                    if len(toks) == 3:
                        date, time, rest = toks
                        timestamp = date[:4] + "/" + date[4:6] + "/" + date[
                            6:8] + " " + time[:2] + ":" + time[2:4]

                        pos = rest.rfind("-")
                        if pos >= 0:
                            remote = rest[:pos]
                        else:
                            remote = rest
                        try:
                            identity = SIPURI.parse('sip:' + str(remote))
                            remote_party = format_identity_to_string(
                                identity, check_contact=True)
                        except SIPCoreError:
                            remote_party = "%s" % (remote)

                    else:
                        try:
                            identity = SIPURI.parse('sip:' + str(file[:-4]))
                            remote_party = format_identity_to_string(
                                identity, check_contact=True)
                        except SIPCoreError:
                            remote_party = file[:-4]
                        timestamp = datetime.fromtimestamp(int(
                            stat.st_ctime)).strftime("%E %T")

                    stat = os.stat(file)
                    result.append((timestamp, remote_party, file))
                except:
                    import traceback
                    traceback.print_exc()
                    pass

        result.sort(lambda a, b: cmp(a[0], b[0]))
        return result
Ejemplo n.º 9
0
    def start(self):
        notification_center = NotificationCenter()
        self.greenlet = api.getcurrent()
        settings = SIPSimpleSettings()
        account = AccountManager().sylkserver_account
        if account.sip.outbound_proxy is not None:
            uri = SIPURI(
                host=account.sip.outbound_proxy.host,
                port=account.sip.outbound_proxy.port,
                parameters={'transport': account.sip.outbound_proxy.transport})
        else:
            uri = self.destination_uri
        lookup = DNSLookup()
        try:
            routes = lookup.lookup_sip_proxy(
                uri, settings.sip.transport_list).wait()
        except DNSLookupError:
            notification_center.post_notification(
                'OutgoingFileTransferHandlerDidFail', sender=self)
            return

        self.session = Session(account)
        self.stream = FileTransferStream(self.file_selector, 'sendonly')
        notification_center.add_observer(self, sender=self.session)
        notification_center.add_observer(self, sender=self.stream)
        from_header = FromHeader(self.sender_uri, u'SIPStache File Transfer')
        to_header = ToHeader(self.destination_uri)
        transport = routes[0].transport
        parameters = {} if transport == 'udp' else {'transport': transport}
        contact_header = ContactHeader(
            SIPURI(user=self.sender_uri.user,
                   host=SIPConfig.local_ip.normalized,
                   port=getattr(Engine(), '%s_port' % transport),
                   parameters=parameters))
        extra_headers = []
        if ThorNodeConfig.enabled:
            extra_headers.append(Header('Thor-Scope', 'sipstache-file'))
        extra_headers.append(
            Header('X-Originator-From', str(self.destination_uri)))
        self.session.connect(from_header,
                             to_header,
                             contact_header=contact_header,
                             routes=routes,
                             streams=[self.stream],
                             is_focus=False,
                             extra_headers=extra_headers)
        notification_center.post_notification(
            'OutgoingFileTransferHandlerDidStart', sender=self)
Ejemplo n.º 10
0
 def __init__(self, account, target_uri, filename, hash):
     self.account = account
     self._file_selector = FileSelector(name=os.path.basename(filename),
                                        hash=hash)
     self.remote_identity = format_identity_to_string(target_uri)
     self.target_uri = SIPURI.new(target_uri)
     self._ended = False
Ejemplo n.º 11
0
 def send_publish(self, uri, body):
     if self.outbound_proxy is None:
         return
     uri = self.sip_prefix_re.sub('', uri)
     publication = Publication(
         FromHeader(SIPURI(uri)),
         "xcap-diff",
         "application/xcap-diff+xml",
         duration=0,
         extra_headers=[Header('Thor-Scope', 'publish-xcap')])
     NotificationCenter().add_observer(self, sender=publication)
     route_header = RouteHeader(
         SIPURI(host=self.outbound_proxy.host,
                port=self.outbound_proxy.port,
                parameters=dict(transport=self.outbound_proxy.transport)))
     publication.publish(body, route_header, timeout=5)
Ejemplo n.º 12
0
 def __init__(self, request):
     self.finished = False
     request.notifyFinish().addCallbacks(self._responseSucceeded, self._responseFailed)
     jsondata = request.content.getvalue()
     try:
         data = jsonlib.loads(jsondata)
     except (jsonlib.DecodeError, ValueError):
         if not self.finished:
             request.setResponseCode(400, 'Could not decode JSON data')
             request.finish()
         return
     try:
         target_uri = data.get('target_uri', '')
         if not re.match('^(sip:|sips:)', target_uri):
             target_uri = 'sip:%s' % target_uri
         target_uri = SIPURI.parse(target_uri)
     except SIPCoreError:
         if not self.finished:
             request.setResponseCode(400, 'Supplied SIP URI is invalid')
             request.finish()
         return
     cache = DataCache()
     data = cache.get(str(target_uri))
     if data is not None:
         if not self.finished:
             request.setHeader('Content-Type', 'application/json')
             request.write(jsonlib.dumps(data))
             request.finish()
         return
     self._target_uri = target_uri
     self._request = request
     self._handler = SIPOptionsRequestHandler(target_uri)
     NotificationCenter().add_observer(self, sender=self._handler)
     self._handler.start()
Ejemplo n.º 13
0
 def parse(cls, value):
     if isinstance(value, BaseSIPURI):
         user = unicode(value.user)
         host = unicode(value.host)
         resource = unicode(value.parameters.get('gr', '')) or None
         return cls(user, host, resource)
     elif isinstance(value, JID):
         user = value.user
         host = value.host
         resource = value.resource
         return cls(user, host, resource)
     elif not isinstance(value, basestring):
         raise TypeError('uri needs to be a string')
     if not value.startswith(('sip:', 'sips:', 'xmpp:')):
         raise ValueError('invalid uri scheme for %s' % value)
     if value.startswith(('sip:', 'sips:')):
         try:
             uri = SIPURI.parse(value)
         except SIPCoreError:
             raise ValueError('invalid SIP uri: %s' % value)
         user = unicode(uri.user)
         host = unicode(uri.host)
         resource = unicode(uri.parameters.get('gr', '')) or None
     else:
         try:
             jid = JID(value[5:])
         except Exception:
             raise ValueError('invalid XMPP uri: %s' % value)
         user = jid.user
         host = jid.host
         resource = jid.resource
     return cls(user, host, resource)
Ejemplo n.º 14
0
 def _start_outgoing_sip_session(self, streams):
     notification_center = NotificationCenter()
     # self.xmpp_identity is our local identity on the SIP side
     from_uri = self.xmpp_identity.uri.as_sip_uri()
     from_uri.parameters.pop('gr', None)    # no GRUU in From header
     to_uri = self.sip_identity.uri.as_sip_uri()
     to_uri.parameters.pop('gr', None)      # no GRUU in To header
     # TODO: need to fix GRUU in the proxy
     #contact_uri = self.xmpp_identity.uri.as_sip_uri()
     #contact_uri.parameters['gr'] = encode_resource(contact_uri.parameters['gr'].decode('utf-8'))
     lookup = DNSLookup()
     settings = SIPSimpleSettings()
     account = DefaultAccount()
     if account.sip.outbound_proxy is not None:
         uri = SIPURI(host=account.sip.outbound_proxy.host,
                      port=account.sip.outbound_proxy.port,
                      parameters={'transport': account.sip.outbound_proxy.transport})
     else:
         uri = to_uri
     try:
         routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()
     except DNSLookupError:
         log.warning('DNS lookup error while looking for %s proxy' % uri)
         notification_center.post_notification('MedialSessionHandlerDidFail', sender=self, data=NotificationData(reason='DNS lookup error'))
         return
     route = routes.pop(0)
     from_header = FromHeader(from_uri)
     to_header = ToHeader(to_uri)
     self.sip_session = Session(account)
     notification_center.add_observer(self, sender=self.sip_session)
     self.sip_session.connect(from_header, to_header, route=route, streams=streams)
Ejemplo n.º 15
0
 def parse(cls, value):
     if isinstance(value, BaseSIPURI):
         user = unicode(value.user)
         host = unicode(value.host)
         resource = unicode(value.parameters.get('gr', '')) or None
         return cls(user, host, resource)
     elif isinstance(value, JID):
         user = value.user
         host = value.host
         resource = value.resource
         return cls(user, host, resource)
     elif not isinstance(value, basestring):
         raise TypeError('uri needs to be a string')
     if not value.startswith(('sip:', 'sips:', 'xmpp:')):
         raise ValueError('invalid uri scheme for %s' % value)
     if value.startswith(('sip:', 'sips:')):
         try:
             uri = SIPURI.parse(value)
         except SIPCoreError:
             raise ValueError('invalid SIP uri: %s' % value)
         user = unicode(uri.user)
         host = unicode(uri.host)
         resource = unicode(uri.parameters.get('gr', '')) or None
     else:
         try:
             jid = JID(value[5:])
         except Exception:
             raise ValueError('invalid XMPP uri: %s' % value)
         user = jid.user
         host = jid.host
         resource = jid.resource
     return cls(user, host, resource)
Ejemplo n.º 16
0
def is_anonymous(uri):
    """
        Check if the given URI is an anonymous uri
        """
    anon_users = ('asterisk', 'unknown', 'anonymous')

    if isinstance(uri, (SIPURI, FrozenSIPURI)):
        if uri.user.lower() in anon_users:
            return True

        return (uri.user is None or uri.user.lower() == 'anonymous') and (
            uri.host is None or uri.host.lower() == 'anonymous.invalid')
    else:
        if not (uri.startswith('sip:') or uri.startswith('sips:')):
            uri = "sip:%s" % uri
        try:
            sip_uri = SIPURI.parse(str(uri))
        except:
            return False
        else:
            if sip_uri.user is not None and sip_uri.user.decode().lower(
            ) in anon_users:
                return True

            return (sip_uri.user is None or sip_uri.user.decode().lower()
                    == 'anonymous') and (sip_uri.host is None
                                         or sip_uri.host.decode().lower()
                                         == 'anonymous.invalid')
Ejemplo n.º 17
0
 def __init__(self, request):
     self.finished = False
     request.notifyFinish().addCallbacks(self._responseSucceeded,
                                         self._responseFailed)
     jsondata = request.content.getvalue()
     try:
         data = jsonlib.loads(jsondata)
     except (jsonlib.DecodeError, ValueError):
         if not self.finished:
             request.setResponseCode(400, 'Could not decode JSON data')
             request.finish()
         return
     try:
         target_uri = data.get('target_uri', '')
         if not re.match('^(sip:|sips:)', target_uri):
             target_uri = 'sip:%s' % target_uri
         target_uri = SIPURI.parse(target_uri)
     except SIPCoreError:
         if not self.finished:
             request.setResponseCode(400, 'Supplied SIP URI is invalid')
             request.finish()
         return
     cache = DataCache()
     data = cache.get(str(target_uri))
     if data is not None:
         if not self.finished:
             request.setHeader('Content-Type', 'application/json')
             request.write(jsonlib.dumps(data))
             request.finish()
         return
     self._target_uri = target_uri
     self._request = request
     self._handler = SIPOptionsRequestHandler(target_uri)
     NotificationCenter().add_observer(self, sender=self._handler)
     self._handler.start()
Ejemplo n.º 18
0
 def _start_outgoing_sip_session(self, target_uri):
     notification_center = NotificationCenter()
     # self.xmpp_identity is our local identity
     from_uri = self.xmpp_identity.uri.as_sip_uri()
     del from_uri.parameters['gr']    # no GRUU in From header
     contact_uri = self.xmpp_identity.uri.as_sip_uri()
     contact_uri.parameters['gr'] = encode_resource(contact_uri.parameters['gr'].decode('utf-8'))
     to_uri = target_uri.as_sip_uri()
     lookup = DNSLookup()
     settings = SIPSimpleSettings()
     account = DefaultAccount()
     if account.sip.outbound_proxy is not None:
         uri = SIPURI(host=account.sip.outbound_proxy.host,
                      port=account.sip.outbound_proxy.port,
                      parameters={'transport': account.sip.outbound_proxy.transport})
     else:
         uri = to_uri
     try:
         routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()
     except DNSLookupError:
         log.warning('DNS lookup error while looking for %s proxy' % uri)
         notification_center.post_notification('ChatSessionDidFail', sender=self, data=NotificationData(reason='DNS lookup error'))
         return
     self.msrp_stream = MediaStreamRegistry.get('chat')()
     route = routes.pop(0)
     from_header = FromHeader(from_uri)
     to_header = ToHeader(to_uri)
     contact_header = ContactHeader(contact_uri)
     self.sip_session = Session(account)
     notification_center.add_observer(self, sender=self.sip_session)
     notification_center.add_observer(self, sender=self.msrp_stream)
     self.sip_session.connect(from_header, to_header, contact_header=contact_header, route=route, streams=[self.msrp_stream])
Ejemplo n.º 19
0
    def get_recordings(self, filter_uris=[]):
        result = []
        historydir = self.get_recordings_directory()

        for acct in os.listdir(historydir):
            dirname = historydir + "/" + acct
            if not os.path.isdir(dirname):
                continue

            files = [dirname+"/"+f for f in os.listdir(dirname)]

            for file in files:
                try:
                    recording_type = "audio" if file.endswith(".wav") else "video"
                    stat = os.stat(file)
                    toks = file.split("/")[-1].split("-", 2)
                    if len(toks) == 3:
                        date, time, rest = toks
                        timestamp = date[:4]+"/"+date[4:6]+"/"+date[6:8]+" "+time[:2]+":"+time[2:4]

                        pos = rest.rfind(".")
                        if pos >= 0:
                            remote = rest[:pos]
                        else:
                            remote = rest
                        try:
                            identity = SIPURI.parse('sip:'+str(remote))
                            remote_party = format_identity_to_string(identity, check_contact=True)
                        except SIPCoreError:
                            remote_party = "%s" % (remote)

                    else:
                        try:
                            identity = SIPURI.parse('sip:'+str(file[:-4]))
                            remote_party = format_identity_to_string(identity, check_contact=True)
                        except SIPCoreError:
                            remote_party = file[:-4]
                        timestamp = datetime.fromtimestamp(int(stat.st_ctime)).strftime("%E %T")

                    if filter_uris and remote_party not in filter_uris:
                        continue
                    result.append((timestamp, remote_party, file, recording_type))
                except Exception:
                    pass

        sorted(result, key=lambda x: x[0])
        return result
Ejemplo n.º 20
0
    def sendReplicationMessage(self,
                               response_code,
                               content,
                               content_type="message/cpim",
                               timestamp=None):
        timestamp = timestamp or ISOTimestamp.now()
        # Lookup routes
        if self.account.sip.outbound_proxy is not None:
            uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                         port=self.account.sip.outbound_proxy.port,
                         parameters={
                             'transport':
                             self.account.sip.outbound_proxy.transport
                         })
        else:
            uri = SIPURI(host=self.account.id.domain)

        route = None
        if self.last_route is None:
            lookup = DNSLookup()
            settings = SIPSimpleSettings()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError:
                pass
            else:
                route = routes[0]
        else:
            route = self.last_route

        if route:
            extra_headers = [
                Header("X-Offline-Storage", "no"),
                Header("X-Replication-Code", str(response_code)),
                Header("X-Replication-Timestamp", str(ISOTimestamp.now()))
            ]
            message_request = Message(FromHeader(self.account.uri,
                                                 self.account.display_name),
                                      ToHeader(self.account.uri),
                                      RouteHeader(route.uri),
                                      content_type,
                                      content,
                                      credentials=self.account.credentials,
                                      extra_headers=extra_headers)
            message_request.send(
                15 if content_type != "application/im-iscomposing+xml" else 5)
Ejemplo n.º 21
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)
Ejemplo n.º 22
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)
Ejemplo n.º 23
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)
Ejemplo n.º 24
0
    def get_audio_recordings(self, filter_uris=[]):
        result = []
        historydir = self.get_audio_recordings_directory()

        for acct in os.listdir(historydir):
            dirname = historydir + "/" + acct
            if not os.path.isdir(dirname):
                continue

            files = [dirname+"/"+f for f in os.listdir(dirname) if f.endswith(".wav")]

            for file in files:
                try:
                    stat = os.stat(file)
                    toks = file.split("/")[-1].split("-", 2)
                    if len(toks) == 3:
                        date, time, rest = toks
                        timestamp = date[:4]+"/"+date[4:6]+"/"+date[6:8]+" "+time[:2]+":"+time[2:4]

                        pos = rest.rfind("-")
                        if pos >= 0:
                            remote = rest[:pos]
                        else:
                            remote = rest
                        try:
                            identity = SIPURI.parse('sip:'+str(remote))
                            remote_party = format_identity_to_string(identity, check_contact=True)
                        except SIPCoreError:
                            remote_party = "%s" % (remote)

                    else:
                        try:
                            identity = SIPURI.parse('sip:'+str(file[:-4]))
                            remote_party = format_identity_to_string(identity, check_contact=True)
                        except SIPCoreError:
                            remote_party = file[:-4]
                        timestamp = datetime.fromtimestamp(int(stat.st_ctime)).strftime("%E %T")

                    if filter_uris and remote_party not in filter_uris:
                        continue
                    result.append((timestamp, remote_party, file))
                except Exception:
                    pass

        result.sort(lambda a,b: cmp(a[0],b[0]))
        return result
Ejemplo n.º 25
0
 def send_publish(self, uri, body):
     uri = re.sub("^(sip:|sips:)", "", uri)
     destination_node = self.provisioning.lookup(uri)
     if destination_node is not None:
         # TODO: add configuration settings for SIP transport. -Saul
         publication = Publication(
             FromHeader(SIPURI(uri)),
             "xcap-diff",
             "application/xcap-diff+xml",
             duration=0,
             extra_headers=[Header('Thor-Scope', 'publish-xcap')])
         NotificationCenter().add_observer(self, sender=publication)
         route_header = RouteHeader(
             SIPURI(host=str(destination_node),
                    port='5060',
                    parameters=dict(transport='udp')))
         publication.publish(body, route_header, timeout=5)
    def _CH_register(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._registration_timer is not None and self._registration_timer.active(
        ):
            self._registration_timer.cancel()
        self._registration_timer = None

        # Initialize the registration
        if self._registration is None:
            duration = command.refresh_interval or self.account.sip.register_interval
            self._registration = Registration(
                FromHeader(self.account.uri, self.account.display_name),
                credentials=self.account.credentials,
                duration=duration,
                extra_headers=[Header('Supported', 'gruu')])
            notification_center.add_observer(self, sender=self._registration)
            notification_center.post_notification('SIPAccountWillRegister',
                                                  sender=self.account)
        else:
            notification_center.post_notification(
                'SIPAccountRegistrationWillRefresh', sender=self.account)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in settings.sip.transport_list:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError, e:
                retry_after = random.uniform(self._dns_wait,
                                             2 * self._dns_wait)
                self._dns_wait = limit(2 * self._dns_wait, max=30)
                raise RegistrationError('DNS lookup failed: %s' % e,
                                        retry_after=retry_after)
            else:
Ejemplo n.º 27
0
    def _NH_BlinkFileTransferDidComputeHash(self, sender, data):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        self.stream = FileTransferStream(self.account, self.file_selector,
                                         'sendonly')
        self.session = Session(self.account)

        notification_center.add_observer(self, sender=self.session)
        notification_center.add_observer(self, sender=self.stream)

        self.status = "Offering File..."
        self.ft_info.status = "proposing"

        BlinkLogger().log_info(u"Initiating DNS Lookup of %s to %s" %
                               (self.account, self.target_uri))
        lookup = DNSLookup()
        notification_center.add_observer(self, sender=lookup)

        if isinstance(self.account,
                      Account) and self.account.sip.outbound_proxy is not None:
            uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                         port=self.account.sip.outbound_proxy.port,
                         parameters={
                             'transport':
                             self.account.sip.outbound_proxy.transport
                         })
            BlinkLogger().log_info(
                u"Initiating DNS Lookup for SIP routes of %s (through proxy %s)"
                % (self.target_uri, uri))
        elif isinstance(self.account,
                        Account) and self.account.sip.always_use_my_proxy:
            uri = SIPURI(host=self.account.id.domain)
            BlinkLogger().log_info(
                u"Initiating DNS Lookup for SIP routes of %s (through account %s proxy)"
                % (self.target_uri, self.account.id))
        else:
            uri = self.target_uri
            BlinkLogger().log_info(
                u"Initiating DNS Lookup for SIP routes of %s" %
                self.target_uri)
        notification_center.post_notification(
            "BlinkFileTransferInitiated",
            self,
            data=TimestampedNotificationData())
        lookup.lookup_sip_proxy(uri, settings.sip.transport_list)
Ejemplo n.º 28
0
    def checkURI(self, uri):
        if checkValidPhoneNumber(uri):
            return True

        if uri.startswith(('https:', 'http:')):
            url = urllib.parse.urlparse(uri)
            if url.scheme not in ('http', 'https'):
                return False
            return True

        if not uri.startswith(('sip:', 'sips:')):
            uri = "sip:%s" % uri
        try:
            SIPURI.parse(str(uri))
        except SIPCoreError:
            return False

        return True
def validateParticipant(uri):
    if not (uri.startswith('sip:') or uri.startswith('sips:')):
        uri = "sip:%s" % uri
    try:
        sip_uri = SIPURI.parse(str(uri))
    except SIPCoreError:
        return False
    else:
        return sip_uri.user is not None and sip_uri.host is not None
Ejemplo n.º 30
0
    def checkURI(self, uri):
        if checkValidPhoneNumber(uri):
            return True

        if uri.startswith(('https:', 'http:')):
            url = urlparse.urlparse(uri)
            if url.scheme not in (u'http', u'https'):
                return False
            return True

        if not uri.startswith(('sip:', 'sips:')):
            uri = "sip:%s" % uri
        try:
            SIPURI.parse(str(uri))
        except SIPCoreError:
            return False

        return True
Ejemplo n.º 31
0
def validateParticipant(uri):
    if not (uri.startswith('sip:') or uri.startswith('sips:')):
        uri = "sip:%s" % uri
    try:
        sip_uri = SIPURI.parse(str(uri))
    except SIPCoreError:
        return False
    else:
        return sip_uri.user is not None and sip_uri.host is not None
Ejemplo n.º 32
0
    def send(self):
        lookup = DNSLookup()
        settings = SIPSimpleSettings()
        account = DefaultAccount()
        if account.sip.outbound_proxy is not None:
            uri = SIPURI(
                host=account.sip.outbound_proxy.host,
                port=account.sip.outbound_proxy.port,
                parameters={'transport': account.sip.outbound_proxy.transport})
        else:
            uri = self.to_uri
        try:
            routes = lookup.lookup_sip_proxy(
                uri, settings.sip.transport_list).wait()
        except DNSLookupError:
            msg = 'DNS lookup error while looking for %s proxy' % uri
            log.warning(msg)
            raise SIPMessageError(0, msg)
        else:
            route = routes.pop(0)
            from_header = FromHeader(self.from_uri)
            to_header = ToHeader(self.to_uri)
            route_header = RouteHeader(route.uri)
            notification_center = NotificationCenter()
            for chunk in chunks(self.body, 1000):
                if self.use_cpim:
                    additional_headers = []
                    payload = CPIMPayload(
                        self.body.encode('utf-8'),
                        self.content_type,
                        charset='utf-8',
                        sender=ChatIdentity(self.from_uri, None),
                        recipients=[ChatIdentity(self.to_uri, None)],
                        additional_headers=additional_headers)

                    payload, content_type = payload.encode()
                else:
                    content_type = self.content_type
                    payload = self.body.encode('utf-8')

                request = SIPMessageRequest(from_header, to_header,
                                            route_header, content_type,
                                            payload)
                notification_center.add_observer(self, sender=request)
                self._requests.add(request)
                request.send()
            error = None
            count = len(self._requests)
            while count > 0:
                notification = self._channel.wait()
                if notification.name == 'SIPMessageDidFail':
                    error = (notification.data.code, notification.data.reason)
                count -= 1
            self._requests.clear()
            if error is not None:
                raise SIPMessageError(*error)
Ejemplo n.º 33
0
def normalize_sip_uri_for_outgoing_session(target_uri, account):
    def format_uri(uri,
                   default_domain,
                   idd_prefix=None,
                   prefix=None,
                   strip_digits=None):
        if default_domain is not None:
            if "@" not in uri:
                if _pstn_match_regexp.match(uri):
                    username = strip_addressbook_special_characters(uri)
                    if idd_prefix:
                        username = _pstn_plus_regexp.sub(idd_prefix, username)
                    if strip_digits and len(username) > strip_digits:
                        username = username[strip_digits:]
                    if prefix:
                        username = prefix + username
                else:
                    username = uri
                uri = "%s@%s" % (username, default_domain)
            elif "." not in uri.split("@", 1)[1]:
                uri += "." + default_domain
        if not uri.startswith("sip:") and not uri.startswith("sips:"):
            uri = "sip:%s" % uri
        return uri

    try:
        target_uri = str(target_uri)
    except:
        show_error_panel(
            NSLocalizedString(
                "SIP address must not contain unicode characters: %s", "Label")
            % target_uri)
        return None

    if '@' not in target_uri and isinstance(account, BonjourAccount):
        show_error_panel(
            NSLocalizedString(
                "SIP address must contain host in bonjour mode: %s", "Label") %
            target_uri)
        return None

    target_uri = format_uri(
        target_uri,
        account.id.domain if not isinstance(account, BonjourAccount) else None,
        account.pstn.idd_prefix if not isinstance(account, BonjourAccount) else
        None, account.pstn.prefix if not isinstance(account, BonjourAccount)
        else None, account.pstn.strip_digits
        if not isinstance(account, BonjourAccount) else None)

    try:
        target_uri = SIPURI.parse(target_uri)
    except SIPCoreError:
        show_error_panel(
            NSLocalizedString("Invalid SIP address: %s", "Label") % target_uri)
        return None
    return target_uri
 def incoming_sip_message(self, message_request, data):
     # Handle incoming MESSAGE
     from_header = data.headers.get('From', Null)
     to_header = data.headers.get('To', Null)
     content_type = data.headers.get('Content-Type', Null)[0]
     if from_header is Null or to_header is Null:
         message_request.answer(400)
         return
     message_request.answer(200)
     if content_type not in ('text/plain', 'text/html'):
         return
     source_uri = SIPURI.new(to_header.uri)
     destination_uri = SIPURI.new(from_header.uri)
     try:
         fact = self.facts.next()
     except StopIteration:
         return
     else:
         self.send_chuck_norris_fact(source_uri, destination_uri, fact)
Ejemplo n.º 35
0
 def _refresh(self):
     account = DefaultAccount()
     transport = self.route.transport
     parameters = {} if transport == 'udp' else {'transport': transport}
     contact_uri = SIPURI(user=account.contact.username,
                          host=SIPConfig.local_ip.normalized,
                          port=getattr(Engine(), '%s_port' % transport),
                          parameters=parameters)
     contact_header = ContactHeader(contact_uri)
     self._referral.refresh(contact_header=contact_header, timeout=2)
Ejemplo n.º 36
0
 def get_uri(self):
     from sipsimple.core import SIPURI
     if self.transport in ('udp', 'tcp') and self.port == 5060:
         port = None
     elif self.transport == 'tls' and self.port == 5061:
         port = None
     else:
         port = self.port
     parameters = {'transport': self.transport} if self.transport != 'udp' else {}
     return SIPURI(host=self.address, port=port, parameters=parameters)
Ejemplo n.º 37
0
 def incoming_sip_message(self, message_request, data):
     # Handle incoming MESSAGE
     from_header = data.headers.get('From', Null)
     to_header = data.headers.get('To', Null)
     content_type = data.headers.get('Content-Type', Null)[0]
     if from_header is Null or to_header is Null:
         message_request.answer(400)
         return
     message_request.answer(200)
     if content_type not in ('text/plain', 'text/html'):
         return
     source_uri = SIPURI.new(to_header.uri)
     destination_uri = SIPURI.new(from_header.uri)
     try:
         fact = self.facts.next()
     except StopIteration:
         return
     else:
         self.send_chuck_norris_fact(source_uri, destination_uri, fact)
Ejemplo n.º 38
0
    def _setup_new_subscriptions(self, urilist):
        # TODO: Add check to see active subscriptions so it doesn't subscribe twice
        # sets up a new subscription with the given list of URI's
        for uri in urilist:
            tempuri = uri
            if tempuri is None:
                tempuri = ToHeader(
                    SIPURI(user=self.account.id.username,
                           host=self.account.id.domain))
            else:
                if '@' not in tempuri:
                    tempuri = '%s@%s' % (tempuri, self.account.id.domain)
                if not uri.startswith('sip:') and not tempuri.startswith(
                        'sips:'):
                    tempuri = 'sip:' + tempuri
                try:
                    tempuri = ToHeader(SIPURI.parse(tempuri))
                except SIPCoreError:
                    self.output.put('Illegal SIP URI: %s' % tempuri)
                    return 1
            self.subscriptionqueue.append(tempuri)
        #reactor.callLater(0, self._subscribe)
        settings = SIPSimpleSettings()

        self._subscription_timeout = time() + 30

        lookup = DNSLookup()
        notification_center = NotificationCenter()
        notification_center.add_observer(self, sender=lookup)
        proxyuri = None
        if self.account.sip.outbound_proxy is not None:
            proxyuri = SIPURI(host=self.account.sip.outbound_proxy.host,
                              port=self.account.sip.outbound_proxy.port,
                              parameters={
                                  'transport':
                                  self.account.sip.outbound_proxy.transport
                              })
        elif self.account.sip.always_use_my_proxy:
            proxyuri = SIPURI(host=self.account.id.domain)
        else:
            proxyuri = self.subscriptionqueue[0].uri
        lookup.lookup_sip_proxy(proxyuri, settings.sip.transport_list)
Ejemplo n.º 39
0
 def sendReplicationMessage(self,
                            response_code,
                            text,
                            content_type="message/cpim",
                            timestamp=None):
     timestamp = timestamp or datetime.datetime.now(tzlocal())
     # Lookup routes
     if self.account.sip.outbound_proxy is not None:
         uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                      port=self.account.sip.outbound_proxy.port,
                      parameters={
                          'transport':
                          self.account.sip.outbound_proxy.transport
                      })
     else:
         uri = SIPURI(host=self.account.id.domain)
     lookup = DNSLookup()
     settings = SIPSimpleSettings()
     try:
         routes = lookup.lookup_sip_proxy(
             uri, settings.sip.transport_list).wait()
     except DNSLookupError:
         pass
     else:
         utf8_encode = content_type not in (
             'application/im-iscomposing+xml', 'message/cpim')
         extra_headers = [
             Header("X-Offline-Storage", "no"),
             Header("X-Replication-Code", str(response_code)),
             Header("X-Replication-Timestamp",
                    str(Timestamp(datetime.datetime.now())))
         ]
         message_request = Message(
             FromHeader(self.account.uri, self.account.display_name),
             ToHeader(self.account.uri),
             RouteHeader(routes[0].get_uri()),
             content_type,
             text.encode('utf-8') if utf8_encode else text,
             credentials=self.account.credentials,
             extra_headers=extra_headers)
         message_request.send(
             15 if content_type != "application/im-iscomposing+xml" else 5)
Ejemplo n.º 40
0
 def create_uri(cls, account, address):
     if not address.startswith(('sip:', 'sips:')):
         address = 'sip:' + address
     username, separator, domain = address.partition('@')
     if not domain and isinstance(account, Account):
         domain = account.id.domain
     elif '.' not in domain and isinstance(account, Account):
         domain += '.' + account.id.domain
     elif not domain:
         raise ValueError('SIP address without domain')
     address = username + '@' + domain
     return SIPURI.parse(str(address))
Ejemplo n.º 41
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)
Ejemplo n.º 42
0
 def privmsg(self, user, channel, message):
     if channel == '*':
         return
     username = user.split('!', 1)[0]
     if username == self.nickname:
         return
     if channel == self.nickname:
         self.msg(username, "Sorry, I don't support private messages, I'm a bot.")
         return
     uri = SIPURI.parse('sip:%s@%s' % (urllib.quote(username), self.factory.config.server[0]))
     irc_message = IRCMessage(username, uri, message.decode('utf-8'))
     data = NotificationData(message=irc_message)
     NotificationCenter().post_notification('IRCBotGotMessage', self.factory, data)
Ejemplo n.º 43
0
 def parse(cls, value):
     match = cls._re_format.match(value)
     if not match:
         raise ValueError('Cannot parse message/cpim identity header value: %r' % value)
     groupdict =  match.groupdict()
     display_name = groupdict['display_name']
     uri = groupdict['uri']
     # FIXME: silly hack for sip-chatserver which sends incorrect URIs. -Luci
     if not uri.startswith(u'sip:') and not uri.startswith(u'sips:'):
         uri = u'sip:' + uri
     # FIXME: SIPURI is not unicode friendly and expects a str. -Luci
     uri = SIPURI.parse(str(uri))
     return cls(uri, display_name)
Ejemplo n.º 44
0
    def resolveAvatarUrl(self, url):
        if url.startswith("/avatar/"):
            uri = SIPURI.parse(url[8:].decode("hex"))

            # TODO: see if there is an official way to get this, including notification of changes
            # also needs fixing of webodf, allowing custom avatar renderer
            if self.account.uri == uri:
                avatar = IconManager().get('avatar')
                return avatar.filename if avatar != None else self.default_user_icon_filename

            contact, contact_uri = URIUtils.find_contact(uri)
            return contact.icon.filename

        return ""
Ejemplo n.º 45
0
 def __eq__(self, other):
     if isinstance(other, ChatIdentity):
         return self.uri.user == other.uri.user and self.uri.host == other.uri.host
     elif isinstance(other, BaseSIPURI):
         return self.uri.user == other.user and self.uri.host == other.host
     elif isinstance(other, basestring):
         try:
             other_uri = SIPURI.parse(other)
         except Exception:
             return False
         else:
             return self.uri.user == other_uri.user and self.uri.host == other_uri.host
     else:
         return NotImplemented
Ejemplo n.º 46
0
def is_anonymous(uri):
    """
        Check if the given URI is an anonymous uri
        """
    if isinstance(uri, (SIPURI, FrozenSIPURI)):
        return (uri.user is None or uri.user.lower() == 'anonymous') and (uri.host is None or uri.host.lower() == 'anonymous.invalid')
    else:
        if not (uri.startswith('sip:') or uri.startswith('sips:')):
            uri = "sip:%s" % uri
        try:
            sip_uri = SIPURI.parse(str(uri))
        except:
            return False
        else:
            return (sip_uri.user is None or sip_uri.user.lower() == 'anonymous') and (sip_uri.host is None or sip_uri.host.lower() == 'anonymous.invalid')
Ejemplo n.º 47
0
def is_sip_aor_format(uri):
    """
    Check if the given URI is a full SIP URI with username and host.
    """
    if isinstance(uri, (SIPURI, FrozenSIPURI)):
        return uri.user is not None and uri.host is not None
    else:
        if not (uri.startswith('sip:') or uri.startswith('sips:')):
            uri = "sip:%s" % uri
        try:
            sip_uri = SIPURI.parse(str(uri))
        except:
            return False
        else:
            return sip_uri.user is not None and sip_uri.host is not None
Ejemplo n.º 48
0
 def __init__(self, account, target_uri, filename, hash):
     self.account = account
     self.end_session_when_done = True
     self.error = False
     self.file_selector = FileSelector(name=filename, hash=hash)
     self.finished_transfer = False
     self.hash = hashlib.sha1()
     self.interrupted = False
     self.remote_identity = format_identity_to_string(target_uri)
     self.session = None
     self.session_ended = False
     self.started = False
     self.stream = None
     self.target_uri = SIPURI.new(target_uri)
     self.timer = None
     self.transfer_id = str(uuid.uuid1())
Ejemplo n.º 49
0
 def _NH_DNSLookupDidSucceed(self, notification):
     notification_center = NotificationCenter()
     notification_center.remove_observer(self, sender=notification.sender)
     account = DefaultAccount()
     conference_application = ConferenceApplication()
     try:
         room = conference_application.get_room(self.room_uri)
     except RoomNotFoundError:
         log.msg("Room %s - failed to add %s" % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     active_media = set(room.active_media).intersection(("audio", "chat"))
     if not active_media:
         log.msg("Room %s - failed to add %s" % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     registry = MediaStreamRegistry()
     for stream_type in active_media:
         self.streams.append(registry.get(stream_type)())
     self.session = Session(account)
     notification_center.add_observer(self, sender=self.session)
     original_from_header = self._refer_headers.get("From")
     if original_from_header.display_name:
         original_identity = "%s <%s@%s>" % (
             original_from_header.display_name,
             original_from_header.uri.user,
             original_from_header.uri.host,
         )
     else:
         original_identity = "%s@%s" % (original_from_header.uri.user, original_from_header.uri.host)
     from_header = FromHeader(SIPURI.new(self.room_uri), u"Conference Call")
     to_header = ToHeader(self.refer_to_uri)
     extra_headers = []
     if self._refer_headers.get("Referred-By", None) is not None:
         extra_headers.append(Header.new(self._refer_headers.get("Referred-By")))
     else:
         extra_headers.append(Header("Referred-By", str(original_from_header.uri)))
     if ThorNodeConfig.enabled:
         extra_headers.append(Header("Thor-Scope", "conference-invitation"))
     extra_headers.append(Header("X-Originator-From", str(original_from_header.uri)))
     extra_headers.append(SubjectHeader(u"Join conference request from %s" % original_identity))
     route = notification.data.result[0]
     self.session.connect(
         from_header, to_header, route=route, streams=self.streams, is_focus=True, extra_headers=extra_headers
     )
Ejemplo n.º 50
0
    def _lookup_sip_proxy(self, account):
        sip_uri = SIPURI.parse('sip:%s' % account)

        # The proxy dance: Sofia-SIP seems to do a DNS lookup per SIP message when a domain is passed
        # as the proxy, so do the resolution ourselves and give it pre-resolver proxy URL. Since we use
        # caching to avoid long delays, we randomize the results matching the highest priority route's
        # transport.
        proxy = GeneralConfig.outbound_sip_proxy
        if proxy is not None:
            proxy_uri = SIPURI(host=proxy.host,
                               port=proxy.port,
                               parameters={'transport': proxy.transport})
        else:
            proxy_uri = SIPURI(host=sip_uri.host)
        settings = SIPSimpleSettings()
        try:
            routes = self.resolver.lookup_sip_proxy(proxy_uri, settings.sip.transport_list).wait()
        except DNSLookupError, e:
            raise DNSLookupError('DNS lookup error: %s' % e)
Ejemplo n.º 51
0
def normalize_sip_uri_for_outgoing_session(target_uri, account):
    def format_uri(uri, default_domain, idd_prefix = None, prefix = None, strip_digits=None):
        if default_domain is not None:
            if "@" not in uri:
                if _pstn_match_regexp.match(uri):
                    username = strip_addressbook_special_characters(uri)
                    if idd_prefix:
                        username = _pstn_plus_regexp.sub(idd_prefix, username)
                    if strip_digits and len(username) > strip_digits:
                        username = username[strip_digits:]
                    if prefix:
                        username = prefix + username
                else:
                    username = uri
                uri = "%s@%s" % (username, default_domain)
            elif "." not in uri.split("@", 1)[1]:
                uri += "." + default_domain
        if not uri.startswith("sip:") and not uri.startswith("sips:"):
            uri = "sip:%s" % uri
        return uri


    try:
        target_uri = str(target_uri)
    except:
        show_error_panel(NSLocalizedString("SIP address must not contain unicode characters: %s", "Label") % target_uri)
        return None

    if '@' not in target_uri and isinstance(account, BonjourAccount):
        show_error_panel(NSLocalizedString("SIP address must contain host in bonjour mode: %s", "Label") % target_uri)
        return None

    target_uri = format_uri(target_uri, account.id.domain if not isinstance(account, BonjourAccount) else None, account.pstn.idd_prefix if not isinstance(account, BonjourAccount) else None, account.pstn.prefix if not isinstance(account, BonjourAccount) else None, account.pstn.strip_digits if not isinstance(account, BonjourAccount) else None)

    try:
        target_uri = SIPURI.parse(target_uri)
    except SIPCoreError:
        show_error_panel(NSLocalizedString("Invalid SIP address: %s", "Label") % target_uri)
        return None
    return target_uri
Ejemplo n.º 52
0
    def _OH_account_add(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                account = data['account']
                password = data['password']
            except KeyError:
                raise APIError('Invalid parameters: "account" and "password" must be specified')

            if account in self.accounts_map:
                log.warn('Account %s already added' % account)
                data = dict(sylkrtc='error', transaction=transaction, error='Account already added')
                self._send_data(json.dumps(data))
                return

            # Validate URI
            uri = 'sip:%s' % account
            try:
                sip_uri = SIPURI.parse(uri)
            except SIPCoreError:
                raise APIError('Invalid account specified: %s' % account)
            if not {'*', sip_uri.host}.intersection(GeneralConfig.sip_domains):
                raise APIError('SIP domain not allowed: %s' % sip_uri.host)

            # Create and store our mapping
            account_info = AccountInfo(account, password)
            self.accounts_map[account_info.id] = account_info

            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('Account %s added' % account)
        except APIError, e:
            log.error('account_add: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Ejemplo n.º 53
0
	def call(self, account_name, callee, wave_file, length=None):
		logging.info("calling from: %s - to: %s", account_name, callee)
		# Setup wave playback
		self.player = WavePlayer(SIPApplication.voice_audio_mixer, wave_file, loop_count=0, initial_play=False)
		
		# configure callee and route to him/her
		callee_header = ToHeader(SIPURI.parse(callee))
		routes = [Route("62.220.31.184", 5060, "udp")]
		
		# locate caller
		account = self.accounts.get(account_name, None)
		if account is None:
			raise Exception("No account with that name found")
		
		# finally make the call
		session = Session(account)
		session.connect(callee_header, routes, [AudioStream()])
		
		# if we got a length, end the call after it
		if not length is None:
			time.sleep(length)
			session.end()
Ejemplo n.º 54
0
def is_anonymous(uri):
    """
        Check if the given URI is an anonymous uri
        """
    anon_users = ('asterisk', 'unknown', 'anonymous')

    if isinstance(uri, (SIPURI, FrozenSIPURI)):
        if uri.user.lower() in anon_users:
            return True

        return (uri.user is None or uri.user.lower() == 'anonymous') and (uri.host is None or uri.host.lower() == 'anonymous.invalid')
    else:
        if not (uri.startswith('sip:') or uri.startswith('sips:')):
            uri = "sip:%s" % uri
        try:
            sip_uri = SIPURI.parse(str(uri))
        except:
            return False
        else:
            if sip_uri.user is not None and sip_uri.user.lower() in anon_users:
                return True

            return (sip_uri.user is None or sip_uri.user.lower() == 'anonymous') and (sip_uri.host is None or sip_uri.host.lower() == 'anonymous.invalid')
Ejemplo n.º 55
0
                 continue
         else:
             notification_data = NotificationData(code=notification.data.code, reason=notification.data.reason, registration=self._registration, registrar=route)
             notification_center.post_notification('SIPAccountRegistrationGotAnswer', sender=self.account, data=notification_data)
             self.registered = True
             # Save GRUU
             try:
                 header = next(header for header in notification.data.contact_header_list if header.parameters.get('+sip.instance', '').strip('"<>') == settings.instance_id)
             except StopIteration:
                 self.account.contact.public_gruu = None
                 self.account.contact.temporary_gruu = None
             else:
                 public_gruu = header.parameters.get('pub-gruu', None)
                 temporary_gruu = header.parameters.get('temp-gruu', None)
                 try:
                     self.account.contact.public_gruu = SIPURI.parse(public_gruu.strip('"'))
                 except (AttributeError, SIPCoreError):
                     self.account.contact.public_gruu = None
                 try:
                     self.account.contact.temporary_gruu = SIPURI.parse(temporary_gruu.strip('"'))
                 except (AttributeError, SIPCoreError):
                     self.account.contact.temporary_gruu = None
             notification_data = NotificationData(contact_header=notification.data.contact_header,
                                                  contact_header_list=notification.data.contact_header_list,
                                                  expires=notification.data.expires_in, registrar=route)
             notification_center.post_notification('SIPAccountRegistrationDidSucceed', sender=self.account, data=notification_data)
             self._register_wait = 1
             command.signal()
             break
 else:
     # There are no more routes to try, reschedule the registration
Ejemplo n.º 56
0
    def _NH_SIPEngineGotMessage(self, sender, data):
        account = AccountManager().find_account(data.request_uri)
        if not account:
            BlinkLogger().log_warning(u"Could not find recipient account for message to %s, using default" % data.request_uri)
            account = AccountManager().default_account

        is_cpim = False
        cpim_message = None
        replication_message = False

        if data.content_type == 'message/cpim':
            try:
                cpim_message = CPIMMessage.parse(data.body)
            except CPIMParserError:
                BlinkLogger().log_warning(u"SMS from %s has invalid CPIM content" % format_identity_to_string(data.from_header))
                return
            else:
                is_cpim = True
                body = cpim_message.body
                content_type = cpim_message.content_type
                sender_identity = cpim_message.sender or data.from_header
                if cpim_message.sender and data.from_header.uri == data.to_header.uri and data.from_header.uri == cpim_message.sender.uri:
                    replication_message = True
                    window_tab_identity = cpim_message.recipients[0] if cpim_message.recipients else data.to_header
                else:
                    window_tab_identity = data.from_header
        else:
            body = data.body.decode('utf-8')
            content_type = data.content_type
            sender_identity = data.from_header
            window_tab_identity = sender_identity

        is_html = content_type == 'text/html'

        if content_type in ('text/plain', 'text/html'):
            BlinkLogger().log_info(u"Got SMS from %s" % format_identity_to_string(sender_identity))
        elif content_type == 'application/im-iscomposing+xml':
            # body must not be utf-8 decoded
            body = cpim_message.body if is_cpim else data.body
            msg = IsComposingMessage.parse(body)
            state = msg.state.value
            refresh = msg.refresh.value if msg.refresh is not None else None
            content_type = msg.content_type.value if msg.content_type is not None else None
            last_active = msg.last_active.value if msg.last_active is not None else None

            viewer = self.openMessageWindow(SIPURI.new(window_tab_identity.uri), window_tab_identity.display_name, account, create_if_needed=False, note_new_message=False)
            if viewer:
                viewer.gotIsComposing(self.windowForViewer(viewer), state, refresh, last_active)
            return
        else:
            BlinkLogger().log_warning(u"SMS from %s has unknown content-type %s" % (format_identity_to_string(data.from_header), data.content_type))
            return

        # display the message
        note_new_message = False if replication_message else True
        viewer = self.openMessageWindow(SIPURI.new(window_tab_identity.uri), window_tab_identity.display_name, account, note_new_message=note_new_message)
        self.windowForViewer(viewer).noteNewMessageForSession_(viewer)
        replication_state = None
        replication_timestamp = None

        if replication_message:
            replicated_response_code = data.headers.get('X-Replication-Code', Null).body
            if replicated_response_code == '202':
                replication_state = 'deferred'
            elif replicated_response_code == '200':
                replication_state = 'delivered'
            else:
                replication_state = 'failed'
            replicated_timestamp = data.headers.get('X-Replication-Timestamp', Null).body
            try:
                replication_timestamp = Timestamp.parse(replicated_timestamp)
            except (TypeError, ValueError):
                replication_timestamp = Timestamp(datetime.datetime.now(tzlocal()))

        viewer.gotMessage(sender_identity, body, is_html, replication_state, replication_timestamp)
        self.windowForViewer(viewer).noteView_isComposing_(viewer, False)

        if replication_message:
            return

        if not self.windowForViewer(viewer).window().isKeyWindow():
            # notify growl
            growl_data = TimestampedNotificationData()
            if is_html:
                growl_data.content = html2txt(body)
            else:
                growl_data.content = body
            growl_data.sender = format_identity_to_string(sender_identity, format='compact')
            self.notification_center.post_notification("GrowlGotSMS", sender=self, data=growl_data)
Ejemplo n.º 57
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
Ejemplo n.º 58
0
 def as_sip_uri(self):
     uri = SIPURI(user=str(self.user), host=str(self.host))
     if self.resource is not None:
         uri.parameters['gr'] = self.resource.encode('utf-8')
     return uri
Ejemplo n.º 59
0
def URIValidator(value):
    account = SIP_PREFIX_RE.sub('', value)
    try:
        SIPURI.parse('sip:%s' % account)
    except SIPCoreError:
        raise errors.ValidationError('invalid account: %s' % value)