Example #1
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
Example #2
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
Example #3
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
Example #4
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')
Example #5
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()
Example #6
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)
Example #7
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)
Example #8
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)
Example #9
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()
Example #10
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
Example #11
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
    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
    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
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
Example #16
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
Example #17
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)
Example #18
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)
Example #19
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))
Example #20
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)
Example #21
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)
Example #22
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, str):
         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
Example #23
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
Example #24
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 ""
Example #25
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
Example #26
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')
Example #27
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)
Example #28
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)
Example #29
0
 def __init__(self,
              account,
              contact,
              content,
              content_type='text/plain',
              recipients=None,
              courtesy_recipients=None,
              subject=None,
              timestamp=None,
              required=None,
              additional_headers=None,
              id=None):
     self.lookup = None
     self.account = account
     self.uri = contact.uri.uri
     self.content_type = content_type
     self.content = content
     self.id = id if id is not None else str(uuid.uuid4())
     self.timestamp = timestamp if timestamp is not None else ISOTimestamp.now(
     )
     self.sip_uri = SIPURI.parse('sip:%s' % self.uri)
Example #30
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
Example #31
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()
Example #32
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))
Example #33
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')
Example #34
0
 def parse(cls, value):
     match = cls._format_re.match(value)
     if match is None:
         raise ValueError('Cannot parse identity value: %r' % value)
     return cls(SIPURI.parse(match.group('uri')), match.group('display_name'))
Example #35
0
    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 as 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:
                self._dns_wait = 1

            # Register by trying each route in turn
            register_timeout = time() + 30
            for route in routes:
                remaining_time = register_timeout - time()
                if remaining_time > 0:
                    try:
                        contact_uri = self.account.contact[NoGRUU, route]
                    except KeyError:
                        continue
                    contact_header = ContactHeader(contact_uri)
                    contact_header.parameters[
                        '+sip.instance'] = '"<%s>"' % settings.instance_id
                    if self.account.nat_traversal.use_ice:
                        contact_header.parameters['+sip.ice'] = None
                    route_header = RouteHeader(route.uri)
                    try:
                        self._registration.register(contact_header,
                                                    route_header,
                                                    timeout=limit(
                                                        remaining_time,
                                                        min=1,
                                                        max=10))
                    except SIPCoreError:
                        raise RegistrationError('Internal error',
                                                retry_after=5)
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPRegistrationDidSucceed':
                                break
                            if notification.name == 'SIPRegistrationDidEnd':
                                raise RegistrationError(
                                    'Registration expired', retry_after=0
                                )  # registration expired while we were trying to re-register
                    except SIPRegistrationDidFail as e:
                        notification_data = NotificationData(
                            code=e.data.code,
                            reason=e.data.reason,
                            registration=self._registration,
                            registrar=route)
                        notification_center.post_notification(
                            'SIPAccountRegistrationGotAnswer',
                            sender=self.account,
                            data=notification_data)
                        if e.data.code == 401:
                            # Authentication failed, so retry the registration in some time
                            raise RegistrationError('Authentication failed',
                                                    retry_after=random.uniform(
                                                        60, 120))
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.register_interval:
                                refresh_interval = e.data.min_expires
                            else:
                                refresh_interval = None
                            raise RegistrationError(
                                'Interval too short',
                                retry_after=random.uniform(60, 120),
                                refresh_interval=refresh_interval)
                        else:
                            # Otherwise just try the next route
                            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
                retry_after = random.uniform(self._register_wait,
                                             2 * self._register_wait)
                self._register_wait = limit(self._register_wait * 2, max=30)
                raise RegistrationError('No more routes to try',
                                        retry_after=retry_after)
        except RegistrationError as e:
            self.registered = False
            notification_center.remove_observer(self,
                                                sender=self._registration)
            notification_center.post_notification(
                'SIPAccountRegistrationDidFail',
                sender=self.account,
                data=NotificationData(error=e.error,
                                      retry_after=e.retry_after))

            def register():
                if self.active:
                    self._command_channel.send(
                        Command('register',
                                command.event,
                                refresh_interval=e.refresh_interval))
                self._registration_timer = None

            self._registration_timer = reactor.callLater(
                e.retry_after, register)
            self._registration = None
            self.account.contact.public_gruu = None
            self.account.contact.temporary_gruu = None
 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',
Example #37
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
Example #38
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)
Example #39
0
 def parse(cls, value):
     match = cls._format_re.match(value)
     if match is None:
         raise ValueError('Cannot parse identity value: %r' % value)
     return cls(SIPURI.parse(match.group('uri')),
                match.group('display_name'))
Example #40
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)
Example #41
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 #42
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