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 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
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