def getdynamic(buffer):
    """getdynamic parses a string containing a SIP message and returns a
    dictionary object containing dynamic parts of that message"""

    # here's a nice list of things that we want to extract
    dynamicheaders = dict()
    dynamicheaders['via'] = dict()
    dynamicheaders['from'] = dict()
    dynamicheaders['to'] = dict()
    dynamicheaders['call-id'] = dict()
    dynamicheaders['contact'] = dict()
    dynamicheaders['warning'] = dict()
    dynamicheaders['content-length'] = dict()
    dynamicheaders['user-agent'] = dict()
    dynamicheaders['warning']['warning'] = '(.*)'
    dynamicheaders['via']['protocol'] = 'SIP/2.0/(\w+)'
    dynamicheaders['via']['ip'] = 'SIP/2.0/\w+\s*([\w\d\:\.]*)'
    dynamicheaders['via']['received'] = 'received\s*=\s*([^;]*)'
    dynamicheaders['via']['branch'] = 'branch\s*=\s*([^;]*)'
    dynamicheaders['via']['rport'] = 'rport\s*=\s*([^;]*)'
    dynamicheaders['via']['maddr'] = 'maddr\s*=\s*([^;]*)'
    dynamicheaders['via']['ttl'] = 'ttl\s*=\s*([^;]*)'
    dynamicheaders['from']['tag'] = 'tag\s*=\s*([^;]*)'
    dynamicheaders['to']['tag'] = 'tag\s*=\s*([^;]*)'
    dynamicheaders['to']['addr'] = '^\s*(.*?)\;'
    dynamicheaders['from']['addr'] = '^\s*(.*?)=?;'
    dynamicheaders['contact']['addr'] = '(.*)\;*'
    dynamicheaders['call-id']['callid'] = '([\d\w\-\.]+)'
    dynamicheaders['content-length']['length'] = '(.*)'
    dynamicheaders['user-agent']['ua'] = '(.*)'

    from helper import parseHeader
    import re
    result = dict()
    ph = parseHeader(buffer)
    if ph.has_key('headers'):
        for dynhead in dynamicheaders.keys():
            if ph['headers'].has_key(dynhead):
                for regexname in dynamicheaders[dynhead].keys():
                    for headerentry in ph['headers'][dynhead]:
                        m = re.search(dynamicheaders[dynhead][regexname],
                                      headerentry)
                        if m is not None:
                            if not result.has_key(dynhead):
                                result[dynhead] = dict()
                            result[dynhead][regexname] = m.group(1)
    return result
Example #2
0
def getdynamic(buffer):
    """getdynamic parses a string containing a SIP message and returns a
    dictionary object containing dynamic parts of that message"""
    
    # here's a nice list of things that we want to extract
    dynamicheaders = dict()
    dynamicheaders['via'] = dict()
    dynamicheaders['from'] = dict()
    dynamicheaders['to'] = dict()
    dynamicheaders['call-id'] = dict()
    dynamicheaders['contact'] = dict()
    dynamicheaders['warning'] = dict()
    dynamicheaders['content-length'] = dict()
    dynamicheaders['user-agent'] = dict()
    dynamicheaders['warning']['warning'] = '(.*)'    
    dynamicheaders['via']['protocol'] = 'SIP/2.0/(\w+)'
    dynamicheaders['via']['ip'] = 'SIP/2.0/\w+\s*([\w\d\:\.]*)'
    dynamicheaders['via']['received'] = 'received\s*=\s*([^;]*)'
    dynamicheaders['via']['branch'] = 'branch\s*=\s*([^;]*)'
    dynamicheaders['via']['rport'] = 'rport\s*=\s*([^;]*)'
    dynamicheaders['via']['maddr'] = 'maddr\s*=\s*([^;]*)'
    dynamicheaders['via']['ttl'] = 'ttl\s*=\s*([^;]*)'
    dynamicheaders['from']['tag'] = 'tag\s*=\s*([^;]*)'
    dynamicheaders['to']['tag'] = 'tag\s*=\s*([^;]*)'
    dynamicheaders['to']['addr'] = '^\s*(.*?)\;'
    dynamicheaders['from']['addr'] = '^\s*(.*?)=?;'
    dynamicheaders['contact']['addr'] = '(.*)\;*'
    dynamicheaders['call-id']['callid'] = '([\d\w\-\.]+)'
    dynamicheaders['content-length']['length'] = '(.*)'
    dynamicheaders['user-agent']['ua'] = '(.*)'

    
    from helper import parseHeader
    import re
    result = dict()
    ph = parseHeader(buffer)
    if ph.has_key('headers'):
        for dynhead in dynamicheaders.keys():
            if ph['headers'].has_key(dynhead):
                for regexname in dynamicheaders[dynhead].keys():
                    for headerentry in ph['headers'][dynhead]:
                        m = re.search(dynamicheaders[dynhead][regexname],headerentry)
                        if m is not None:
                            if not result.has_key(dynhead):
                                result[dynhead] = dict()
                            result[dynhead][regexname] = m.group(1)                            
    return result
    def getResponse(self):
        from helper import getNonce,getCredentials,getRealm,getCID,getTag        
        from base64 import b64decode
        from helper import parseHeader
        from helper import mysendto
        import re
        # we got stuff to read off the socket
        from socket import error as socketerror
        buff,srcaddr = self.sock.recvfrom(8192)
        try:
            extension = getTag(buff)
        except TypeError:
            
            extension = None
        if extension is None:
            self.nomore = True
            return
        try:
            firstline = buff.splitlines()[0]
        except (ValueError,IndexError,AttributeError):
            self.log.error("could not get the 1st line")
            return

        # send an ack to any responses which match
        _tmp = parseHeader(buff)
        if _tmp['code'] >= 200:
            self.log.debug('will try to send an ACK response')
            if _tmp['code'] >= 300:
                # handle differently
                pass
            if not _tmp.has_key('headers'):
                self.log.debug('no headers?')
                return
            if not _tmp['headers'].has_key('from'):
                self.log.debug('no from?')
                return
            if not _tmp['headers'].has_key('cseq'):
                self.log.debug('no cseq')
                return
            if not _tmp['headers'].has_key('call-id'):
                self.log.debug('no caller id')
                return
            username = _tmp['headers']['from'][0].split('"')[1]
            cseq = _tmp['headers']['cseq'][0]
            cid = _tmp['headers']['call-id'][0]
            ackreq = self.createRequest('ACK',
                                   username=username,
                                   cid=cid,
                                   cseq=cseq,
                                   )
            self.log.debug('here is your ack request: %s' % ackreq)
            mysendto(self.sock,ackreq,(self.dsthost,self.dstport))
            #self.sock.sendto(ackreq,(self.dsthost,self.dstport))

        if firstline != self.BADUSER:
            if buff.startswith(self.PROXYAUTHREQ) \
            or buff.startswith(self.INVALIDPASS) \
            or buff.startswith(self.AUTHREQ):
                if self.realm is None:
                    self.realm = getRealm(buff)
                self.log.info("extension '%s' exists - requires authentication" % extension)
                self.resultauth[extension] = 'reqauth'
                
                if self.sessionpath is not None and self.dbsyncs:
                    self.resultauth.sync()
            elif buff.startswith(self.TRYING):
                pass
            elif buff.startswith(self.RINGING):
                pass
            elif buff.startswith(self.OKEY):
                self.log.info("extension '%s' exists - authentication not required" % extension)
                self.resultauth[extension] = 'noauth'
                if self.sessionpath is not None and self.dbsyncs:
                    self.resultauth.sync()
            else:
                sys.exit(1)
                self.log.warn("extension '%s' probably exists but the response is unexpected" % extension)
                self.log.debug("response: %s" % firstline)
                self.resultauth[extension] = 'weird'
                
                if self.sessionpath is not None and self.dbsyncs:
                    self.resultauth.sync()
        elif buff.startswith(self.NOTFOUND):
            self.log.debug("User '%s' not found" % extension)
        
        # Prefix not found, lets go to the next one. Should we add a warning here???
        elif buff.startswith(self.SERVICEUN):
            pass
        elif buff.startswith(self.TRYING):
            pass
        elif buff.startswith(self.RINGING):
            pass
        elif buff.startswith(self.OKEY):
            pass
        elif buff.startswith(self.DECLINED):
            pass
        elif buff.startswith(self.NOTALLOWED):
            self.log.warn("method not allowed")
            self.nomore = True
            return
        elif buff.startswith(self.BADREQUEST):
            self.log.error("Protocol / interopability error! The remote side most probably has problems with parsing your SIP messages!")
            self.nomore = True
            return
        else:
            self.log.warn("We got an unknown response")
            #self.log.error("Response: %s" % `buff`)
            self.log.debug("1st line: %s" % `firstline`)
            self.log.debug("Bad user: %s" % `self.BADUSER`)
            self.nomore = True
Example #4
0
    def getResponse(self):
        from helper import getNonce,getCredentials,getRealm,getCID,getTag        
        from base64 import b64decode
        from helper import parseHeader
        from helper import mysendto
        import re
        # we got stuff to read off the socket
        from socket import error as socketerror
        buff,srcaddr = self.sock.recvfrom(8192)
        try:
            extension = getTag(buff)
        except TypeError:
            self.log.error('could not decode to tag')
            extension = None
        if extension is None:
            self.nomore = True
            return
        try:
            firstline = buff.splitlines()[0]
        except (ValueError,IndexError,AttributeError):
            self.log.error("could not get the 1st line")
            return
        if not self.disableack:
            # send an ack to any responses which match
            _tmp = parseHeader(buff)
            if 300 > _tmp['code'] >= 200:
                self.log.debug('will try to send an ACK response')                
                if not _tmp.has_key('headers'):
                    self.log.debug('no headers?')
                    return
                if not _tmp['headers'].has_key('from'):
                    self.log.debug('no from?')
                    return
                if not _tmp['headers'].has_key('cseq'):
                    self.log.debug('no cseq')
                    return
                if not _tmp['headers'].has_key('call-id'):
                    self.log.debug('no caller id')
                    return
                try:
                    username = getTag(buff)#_tmp['headers']['from'][0].split('"')[1]
                except IndexError:
                    self.log.warn('could not parse the from address %s' % _tmp['headers']['from'])
                    username = '******'
                cseq = _tmp['headers']['cseq'][0]
                cid = _tmp['headers']['call-id'][0]
                ackreq = self.createRequest('ACK',
                                       username=username,
                                       cid=cid,
                                       cseq=cseq,
                                       )
                self.log.debug('here is your ack request: %s' % ackreq)
                mysendto(self.sock,ackreq,(self.dsthost,self.dstport))
                #self.sock.sendto(ackreq,(self.dsthost,self.dstport))

        if firstline != self.BADUSER:
            if buff.startswith(self.PROXYAUTHREQ) \
            or buff.startswith(self.INVALIDPASS) \
            or buff.startswith(self.AUTHREQ):
                if self.realm is None:
                    self.realm = getRealm(buff)
                self.log.info("extension '%s' exists - requires authentication" % extension)
                self.resultauth[extension] = 'reqauth'
                if self.sessionpath is not None and self.dbsyncs:
                    self.resultauth.sync()
            elif buff.startswith(self.TRYING):
                pass
            elif buff.startswith(self.RINGING):
                pass
            elif buff.startswith(self.OKEY):
                self.log.info("extension '%s' exists - authentication not required" % extension)
                self.resultauth[extension] = 'noauth'
                if self.sessionpath is not None and self.dbsyncs:
                    self.resultauth.sync()
            else:
                self.log.warn("extension '%s' probably exists but the response is unexpected" % extension)
                self.log.debug("response: %s" % firstline)
                self.resultauth[extension] = 'weird'
                if self.sessionpath is not None and self.dbsyncs:
                    self.resultauth.sync()
        elif buff.startswith(self.NOTFOUND):
            self.log.debug("User '%s' not found" % extension)
        elif buff.startswith(self.INEXISTENTTRANSACTION):
            pass
        
        # Prefix not found, lets go to the next one. Should we add a warning here???
        elif buff.startswith(self.SERVICEUN):
            pass
        elif buff.startswith(self.TRYING):
            pass
        elif buff.startswith(self.RINGING):
            pass
        elif buff.startswith(self.OKEY):
            pass
        elif buff.startswith(self.DECLINED):
            pass
        elif buff.startswith(self.NOTALLOWED):
            self.log.warn("method not allowed")
            self.nomore = True
            return
        elif buff.startswith(self.BADREQUEST):
            self.log.error("Protocol / interopability error! The remote side most probably has problems with parsing your SIP messages!")
            self.nomore = True
            return
        else:
            self.log.warn("We got an unknown response")
            self.log.error("Response: %s" % `buff`)
            self.log.debug("1st line: %s" % `firstline`)
            self.log.debug("Bad user: %s" % `self.BADUSER`)
            self.nomore = True