Exemple #1
0
 def __init__(ctx):
     ctx.question = untwisted.oneMany()
     ctx.answer = untwisted.oneMany()
     ctx.authority = untwisted.oneMany()
     ctx.additional = untwisted.oneMany()
Exemple #2
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)
Exemple #3
0
 def __init__(ctx):
   ctx.question = untwisted.oneMany()
   ctx.answer = untwisted.oneMany()
   ctx.authority = untwisted.oneMany()
   ctx.additional = untwisted.oneMany()
Exemple #4
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)