Example #1
0
        def __call__(ctx, qname, qtype=A, qclass=IN, server=server[0]):
            ctx = type.__call__(ctx)

            transport = yield udp.connect(server, 'domain')()

            query = message()

            query.id = '\0\0'

            query.qr = 0
            query.opcode = 0
            query.aa = 0
            query.tc = 0
            query.rd = 1

            query.ra = 0
            query.z = 0
            query.rcode = 0

            query.question.append(question(qname, qtype, qclass))

            transport.write(str(query))

            ctx.recv = yield transport.recv()

            response = message()

            response.id = ctx.recv[:2]

            response.qr = ord(ctx.recv[2]) >> 7
            response.opcode = ord(ctx.recv[2]) >> 3 & 0xf
            response.aa = ord(ctx.recv[2]) >> 2 & 1
            response.tc = ord(ctx.recv[2]) >> 1 & 1
            response.rd = ord(ctx.recv[2]) & 1

            response.ra = ord(ctx.recv[3]) >> 7
            response.z = ord(ctx.recv[3]) >> 4 & 7
            response.rcode = ord(ctx.recv[3]) & 0xf

            qdcount = ord(ctx.recv[4]) << 8 | ord(ctx.recv[5])
            ancount = ord(ctx.recv[6]) << 8 | ord(ctx.recv[7])
            nscount = ord(ctx.recv[8]) << 8 | ord(ctx.recv[9])
            arcount = ord(ctx.recv[10]) << 8 | ord(ctx.recv[11])

            ctx.offset = 12

            for _ in range(qdcount):
                response.question.append(ctx.question(ctx.offset))

            for _ in range(ancount):
                response.answer.append(ctx.rr(ctx.offset))

            for _ in range(nscount):
                response.authority.append(ctx.rr(ctx.offset))

            for _ in range(arcount):
                response.additional.append(ctx.rr(ctx.offset))

            if response.rcode:
                raise response

            #return ...
            raise StopIteration(response)
Example #2
0
def client(method, requestUri, initiator):
    match = qwer(rfc3261.requestUri,
                 '$').match(requestUri, '( host, hostname, maddrParam, port )')

    # We define TARGET as the value of the maddr parameter of the URI, if
    # present, otherwise, the host value of the hostport component of the URI
    if match.maddrParam:
        target = match.maddrParam.host

    else:
        target = match.host

    if match.port:
        port = match.port

    elif target.hostname:
        try:
            result = yield dns.lookup('_sip._udp.' + str(target), dns.SRV)

        except dns.message as e:
            if dns.nameError != e.rcode:
                raise

            port = 'sip'

        else:
            target = result.answer.target
            port = result.answer.port

    else:
        port = 'sip'

    transport = yield udp.connect(str(target), port)()

    asdf = request()

    asdf.method = method
    asdf.requestUri = requestUri
    asdf.sipVersion = 'SIP/2.0'

    asdf.header.append('To', requestUri)
    asdf.header.append(
        'From', initiator + ';tag=' + untwisted.randstr(
            6,
            '!%\'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_`abcdefghijklmnopqrstuvwxyz~'
        ))
    asdf.header.append(
        'Call-ID',
        untwisted.randstr(
            6,
            '!"%\'()*+-./0123456789:<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]_`abcdefghijklmnopqrstuvwxyz{}~'
        ) + '@' + domain)
    asdf.header.append('CSeq', '0 ' + method)

    # A UAC MUST insert a Max-Forwards header field into each request it
    # originates with a value that SHOULD be 70
    asdf.header.append('Max-Forwards', '70')

    host, port = transport.socket.getsockname()
    sentBy = host + ':' + str(port)

    # The branch ID inserted by an element compliant with this specification MUST
    # always begin with the characters "z9hG4bK"
    #asdf.header.append('Via', 'SIP/2.0/UDP {};branch=z9hG4bK'.format(sentBy) + untwisted.randstr(6, '!%\'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_`abcdefghijklmnopqrstuvwxyz~'))
    asdf.header.append(
        'Via',
        'SIP/2.0/UDP {0};branch=z9hG4bK'.format(sentBy) + untwisted.randstr(
            6,
            '!%\'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_`abcdefghijklmnopqrstuvwxyz~'
        ))

    asdf.content = ''

    transport.write(str(asdf))

    while True:
        recv = yield transport.recv()

        match = rfc3261.response.match(
            recv, '( sipVersion, statusCode, reasonPhrase, messageBody )')
        if int(match.statusCode) not in range(100, 200):
            result = response()

            result.sipVersion = str(match.sipVersion)
            result.statusCode = int(match.statusCode)
            result.reasonPhrase = str(match.reasonPhrase)

            result.content = str(match.messageBody)

            if int(result) not in range(200, 300):
                raise result

            #return ...
            raise StopIteration(result)
Example #3
0
    def __call__(ctx, qname, qtype=A, qclass=IN, server=server[0]):
      ctx = type.__call__(ctx)

      transport = yield udp.connect(server, 'domain')()

      query = message()

      query.id = '\0\0'

      query.qr = 0
      query.opcode = 0
      query.aa = 0
      query.tc = 0
      query.rd = 1

      query.ra = 0
      query.z = 0
      query.rcode = 0

      query.question.append(question(qname, qtype, qclass))

      transport.write(str(query))

      ctx.recv = yield transport.recv()

      response = message()

      response.id = ctx.recv[:2]

      response.qr = ord(ctx.recv[2]) >> 7
      response.opcode = ord(ctx.recv[2]) >> 3 & 0xf
      response.aa = ord(ctx.recv[2]) >> 2 & 1
      response.tc = ord(ctx.recv[2]) >> 1 & 1
      response.rd = ord(ctx.recv[2]) & 1

      response.ra = ord(ctx.recv[3]) >> 7
      response.z = ord(ctx.recv[3]) >> 4 & 7
      response.rcode = ord(ctx.recv[3]) & 0xf

      qdcount = ord(ctx.recv[4]) << 8 | ord(ctx.recv[5])
      ancount = ord(ctx.recv[6]) << 8 | ord(ctx.recv[7])
      nscount = ord(ctx.recv[8]) << 8 | ord(ctx.recv[9])
      arcount = ord(ctx.recv[10]) << 8 | ord(ctx.recv[11])

      ctx.offset = 12

      for _ in range(qdcount):
        response.question.append(ctx.question(ctx.offset))

      for _ in range(ancount):
        response.answer.append(ctx.rr(ctx.offset))

      for _ in range(nscount):
        response.authority.append(ctx.rr(ctx.offset))

      for _ in range(arcount):
        response.additional.append(ctx.rr(ctx.offset))

      if response.rcode:
        raise response

      #return ...
      raise StopIteration(response)
Example #4
0
def client(method, requestUri, initiator):
  match = qwer(rfc3261.requestUri, '$').match(requestUri, '( host, hostname, maddrParam, port )')

  # We define TARGET as the value of the maddr parameter of the URI, if
  # present, otherwise, the host value of the hostport component of the URI
  if match.maddrParam:
    target = match.maddrParam.host

  else:
    target = match.host

  if match.port:
    port = match.port

  elif target.hostname:
    try:
      result = yield dns.lookup('_sip._udp.' + str(target), dns.SRV)

    except dns.message as e:
      if dns.nameError != e.rcode:
        raise

      port = 'sip'

    else:
      target = result.answer.target
      port = result.answer.port

  else:
    port = 'sip'

  transport = yield udp.connect(str(target), port)()

  asdf = request()

  asdf.method = method
  asdf.requestUri = requestUri
  asdf.sipVersion = 'SIP/2.0'

  asdf.header.append('To', requestUri)
  asdf.header.append('From', initiator + ';tag=' + untwisted.randstr(6, '!%\'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_`abcdefghijklmnopqrstuvwxyz~'))
  asdf.header.append('Call-ID', untwisted.randstr(6, '!"%\'()*+-./0123456789:<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]_`abcdefghijklmnopqrstuvwxyz{}~') + '@' + domain)
  asdf.header.append('CSeq', '0 ' + method)

  # A UAC MUST insert a Max-Forwards header field into each request it
  # originates with a value that SHOULD be 70
  asdf.header.append('Max-Forwards', '70')

  host, port = transport.socket.getsockname()
  sentBy = host + ':' + str(port)

  # The branch ID inserted by an element compliant with this specification MUST
  # always begin with the characters "z9hG4bK"
  #asdf.header.append('Via', 'SIP/2.0/UDP {};branch=z9hG4bK'.format(sentBy) + untwisted.randstr(6, '!%\'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_`abcdefghijklmnopqrstuvwxyz~'))
  asdf.header.append('Via', 'SIP/2.0/UDP {0};branch=z9hG4bK'.format(sentBy) + untwisted.randstr(6, '!%\'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_`abcdefghijklmnopqrstuvwxyz~'))

  asdf.content = ''

  transport.write(str(asdf))

  while True:
    recv = yield transport.recv()

    match = rfc3261.response.match(recv, '( sipVersion, statusCode, reasonPhrase, messageBody )')
    if int(match.statusCode) not in range(100, 200):
      result = response()

      result.sipVersion = str(match.sipVersion)
      result.statusCode = int(match.statusCode)
      result.reasonPhrase = str(match.reasonPhrase)

      result.content = str(match.messageBody)

      if int(result) not in range(200, 300):
        raise result

      #return ...
      raise StopIteration(result)
Example #5
0
def request(server, messageMethod=binding):
  try:
    transport = yield udp.connect(server, 'stun')()

  # Avoid error: service/proto not found
  except socket.error:
    transport = yield udp.connect(server, 3478)()

  request = message()

  request.messageMethod = messageMethod
  request.messageClass = 0x0000

  request.magicCookie = '\x21\x12\xa4\x42'
  request.transactionId = os.urandom(12)

  transport.write(str(request))

  recv = yield transport.recv()

  response = message()

  response.messageMethod = ord(recv[0]) << 6 & 0xf800 | ord(recv[1]) >> 1 & 0xf0 | ord(recv[1]) & 0xf
  response.messageClass = ord(recv[0]) << 8 & 0x100 | ord(recv[1]) & 0x10

  response.magicCookie = recv[4:8]
  response.transactionId = recv[8:20]

  recv = recv[20:]

  while recv:
    type = ord(recv[0]) << 8 | ord(recv[1])
    length = ord(recv[2]) << 8 | ord(recv[3])

    itm = attribute(recv[4:4 + length])

    # Each STUN attribute MUST end on a 32-bit boundary
    recv = recv[4 + length - length % -4:]

    if type in (MAPPED_ADDRESS, ALTERNATE_SERVER):

      #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |0 0 0 0 0 0 0 0|    Family     |             Port              |
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |                                                               |
      # |                 Address (32 bits or 128 bits)                 |
      # |                                                               |
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      itm.family = ord(itm.value[1])
      itm.port = ord(itm.value[2]) << 8 | ord(itm.value[3])

      if IPv4 == itm.family:
        itm.address = socket.inet_ntop(socket.AF_INET, itm.value[4:])

      elif IPv6 == itm.family:
        itm.address = socket.inet_ntop(socket.AF_INET6, itm.value[4:])

    elif ERROR_CODE == type:

      #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |          Reserved, should be 0          |Class|    Number     |
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |                    Reason Phrase (variable)               ...
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      itm['class'] = ord(itm.value[2])
      itm.number = ord(itm.value[3])
      itm.reasonPhrase = itm.value[4:]

    elif UNKNOWN_ATTRIBUTES == type:

      #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |       Attribute 1 Type        |       Attribute 2 Type        |
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |       Attribute 3 Type        |       Attribute 4 Type    ...
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      itm.attributeType = untwisted.oneMany(*(ord(itm.value[offset]) << 8 | ord(itm.value[offset + 1]) for offset in range(0, len(itm.value), 2)))

    elif XOR_MAPPED_ADDRESS == type:

      #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |0 0 0 0 0 0 0 0|    Family     |            X-Port             |
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      # |                                                               |
      # |                X-Address (32 bits or 128 bits)                |
      # |                                                               |
      # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      itm.family = ord(itm.value[1])
      itm.port = (ord(itm.value[2]) ^ ord(response.magicCookie[0])) << 8 | ord(itm.value[3]) ^ ord(response.magicCookie[1])

      if IPv4 == itm.family:
        itm.address = socket.inet_ntop(socket.AF_INET, ''.join(chr(ord(address) ^ ord(magicCookie)) for address, magicCookie in zip(itm.value[4:], response.magicCookie)))

      elif IPv6 == itm.family:
        itm.address = socket.inet_ntop(socket.AF_INET6, ''.join(chr(ord(address) ^ ord(magicCookie)) for address, magicCookie in zip(itm.value[4:], response.magicCookie + response.transactionId)))

    response.attribute.append(type, itm)

  if 0x0100 != response.messageClass:
    raise response

  #return ...
  raise StopIteration(response)
Example #6
0
def request(server, messageMethod=binding):
    try:
        transport = yield udp.connect(server, 'stun')()

    # Avoid error: service/proto not found
    except socket.error:
        transport = yield udp.connect(server, 3478)()

    request = message()

    request.messageMethod = messageMethod
    request.messageClass = 0x0000

    request.magicCookie = '\x21\x12\xa4\x42'
    request.transactionId = os.urandom(12)

    transport.write(str(request))

    recv = yield transport.recv()

    response = message()

    response.messageMethod = ord(recv[0]) << 6 & 0xf800 | ord(
        recv[1]) >> 1 & 0xf0 | ord(recv[1]) & 0xf
    response.messageClass = ord(recv[0]) << 8 & 0x100 | ord(recv[1]) & 0x10

    response.magicCookie = recv[4:8]
    response.transactionId = recv[8:20]

    recv = recv[20:]

    while recv:
        type = ord(recv[0]) << 8 | ord(recv[1])
        length = ord(recv[2]) << 8 | ord(recv[3])

        itm = attribute(recv[4:4 + length])

        # Each STUN attribute MUST end on a 32-bit boundary
        recv = recv[4 + length - length % -4:]

        if type in (MAPPED_ADDRESS, ALTERNATE_SERVER):

            #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |0 0 0 0 0 0 0 0|    Family     |             Port              |
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |                                                               |
            # |                 Address (32 bits or 128 bits)                 |
            # |                                                               |
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            itm.family = ord(itm.value[1])
            itm.port = ord(itm.value[2]) << 8 | ord(itm.value[3])

            if IPv4 == itm.family:
                itm.address = socket.inet_ntop(socket.AF_INET, itm.value[4:])

            elif IPv6 == itm.family:
                itm.address = socket.inet_ntop(socket.AF_INET6, itm.value[4:])

        elif ERROR_CODE == type:

            #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |          Reserved, should be 0          |Class|    Number     |
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |                    Reason Phrase (variable)               ...
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            itm['class'] = ord(itm.value[2])
            itm.number = ord(itm.value[3])
            itm.reasonPhrase = itm.value[4:]

        elif UNKNOWN_ATTRIBUTES == type:

            #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |       Attribute 1 Type        |       Attribute 2 Type        |
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |       Attribute 3 Type        |       Attribute 4 Type    ...
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            itm.attributeType = untwisted.oneMany(
                *(ord(itm.value[offset]) << 8 | ord(itm.value[offset + 1])
                  for offset in range(0, len(itm.value), 2)))

        elif XOR_MAPPED_ADDRESS == type:

            #  0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |0 0 0 0 0 0 0 0|    Family     |            X-Port             |
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            # |                                                               |
            # |                X-Address (32 bits or 128 bits)                |
            # |                                                               |
            # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            itm.family = ord(itm.value[1])
            itm.port = (ord(itm.value[2])
                        ^ ord(response.magicCookie[0])) << 8 | ord(
                            itm.value[3]) ^ ord(response.magicCookie[1])

            if IPv4 == itm.family:
                itm.address = socket.inet_ntop(
                    socket.AF_INET, ''.join(
                        chr(ord(address) ^ ord(magicCookie))
                        for address, magicCookie in zip(
                            itm.value[4:], response.magicCookie)))

            elif IPv6 == itm.family:
                itm.address = socket.inet_ntop(
                    socket.AF_INET6, ''.join(
                        chr(ord(address) ^ ord(magicCookie))
                        for address, magicCookie in zip(
                            itm.value[4:], response.magicCookie +
                            response.transactionId)))

        response.attribute.append(type, itm)

    if 0x0100 != response.messageClass:
        raise response

    #return ...
    raise StopIteration(response)