def _parse_file(descriptor_file, validate=False, **kwargs):
    """
  Iterates over the hidden service descriptors in a file.

  :param file descriptor_file: file with descriptor content
  :param bool validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param dict kwargs: additional arguments for the descriptor constructor

  :returns: iterator for :class:`~stem.descriptor.hidden_service_descriptor.HiddenServiceDescriptor`
    instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is **True**
    * **IOError** if the file can't be read
  """

    while True:
        descriptor_content = _read_until_keywords('signature', descriptor_file)

        # we've reached the 'signature', now include the pgp style block
        block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
        descriptor_content += _read_until_keywords(block_end_prefix,
                                                   descriptor_file, True)

        if descriptor_content:
            if descriptor_content[0].startswith(b'@type'):
                descriptor_content = descriptor_content[1:]

            yield HiddenServiceDescriptor(bytes.join(b'', descriptor_content),
                                          validate, **kwargs)
        else:
            break  # done parsing file
def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
  """
  Iterates over the extra-info descriptors in a file.

  :param file descriptor_file: file with descriptor content
  :param bool is_bridge: parses the file as being a bridge descriptor
  :param bool validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param dict kwargs: additional arguments for the descriptor constructor

  :returns: iterator for :class:`~stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor`
    instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is **True**
    * **IOError** if the file can't be read
  """

  while True:
    extrainfo_content = _read_until_keywords('router-signature', descriptor_file)

    # we've reached the 'router-signature', now include the pgp style block
    block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
    extrainfo_content += _read_until_keywords(block_end_prefix, descriptor_file, True)

    if extrainfo_content:
      if extrainfo_content[0].startswith(b'@type'):
        extrainfo_content = extrainfo_content[1:]

      if is_bridge:
        yield BridgeExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate, **kwargs)
      else:
        yield RelayExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate, **kwargs)
    else:
      break  # done parsing file
Exemple #3
0
def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
  """
  Iterates over the extra-info descriptors in a file.

  :param file descriptor_file: file with descriptor content
  :param bool is_bridge: parses the file as being a bridge descriptor
  :param bool validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param dict kwargs: additional arguments for the descriptor constructor

  :returns: iterator for :class:`~stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor`
    instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is **True**
    * **IOError** if the file can't be read
  """

  while True:
    extrainfo_content = _read_until_keywords("router-signature", descriptor_file)

    # we've reached the 'router-signature', now include the pgp style block
    block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
    extrainfo_content += _read_until_keywords(block_end_prefix, descriptor_file, True)

    if extrainfo_content:
      if is_bridge:
        yield BridgeExtraInfoDescriptor(bytes.join(b"", extrainfo_content), validate, **kwargs)
      else:
        yield RelayExtraInfoDescriptor(bytes.join(b"", extrainfo_content), validate, **kwargs)
    else:
      break  # done parsing file
def _parse_file(descriptor_file, validate = False, **kwargs):
  """
  Iterates over the hidden service descriptors in a file.

  :param file descriptor_file: file with descriptor content
  :param bool validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param dict kwargs: additional arguments for the descriptor constructor

  :returns: iterator for :class:`~stem.descriptor.hidden_service_descriptor.HiddenServiceDescriptor`
    instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is **True**
    * **IOError** if the file can't be read
  """

  while True:
    descriptor_content = _read_until_keywords('signature', descriptor_file)

    # we've reached the 'signature', now include the pgp style block
    block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
    descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True)

    if descriptor_content:
      if descriptor_content[0].startswith(b'@type'):
        descriptor_content = descriptor_content[1:]

      yield HiddenServiceDescriptor(bytes.join(b'', descriptor_content), validate, **kwargs)
    else:
      break  # done parsing file
Exemple #5
0
def _parse_file(descriptor_file, validate=False, onion_address=None, **kwargs):
    while True:
        descriptor_content = _read_until_keywords('signature', descriptor_file)

        # we've reached the 'signature', now include the pgp style block
        block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
        descriptor_content += _read_until_keywords(block_end_prefix,
                                                   descriptor_file, True)

        if descriptor_content:
            if descriptor_content[0].startswith(b'@type'):
                descriptor_content = descriptor_content[1:]

            yield Hsv3Descriptor(bytes.join(b'', descriptor_content),
                                 validate,
                                 onion_address=onion_address,
                                 **kwargs)
        else:
            break  # done parsing file
Exemple #6
0
def _parse_file(descriptor_file: BinaryIO, is_bridge = False, validate = False, **kwargs: Any) -> Iterator['stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor']:
  """
  Iterates over the extra-info descriptors in a file.

  :param descriptor_file: file with descriptor content
  :param is_bridge: parses the file as being a bridge descriptor
  :param validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param kwargs: additional arguments for the descriptor constructor

  :returns: iterator for :class:`~stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor`
    instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is **True**
    * **IOError** if the file can't be read
  """

  if kwargs:
    raise ValueError('BUG: keyword arguments unused by extrainfo descriptors')

  while True:
    if not is_bridge:
      extrainfo_content = _read_until_keywords('router-signature', descriptor_file)

      # we've reached the 'router-signature', now include the pgp style block

      block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
      extrainfo_content += _read_until_keywords(block_end_prefix, descriptor_file, True)
    else:
      extrainfo_content = _read_until_keywords('router-digest', descriptor_file, True)

    if extrainfo_content:
      if extrainfo_content[0].startswith(b'@type'):
        extrainfo_content = extrainfo_content[1:]

      if is_bridge:
        yield BridgeExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate)
      else:
        yield RelayExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate)
    else:
      break  # done parsing file
def _parse_file(descriptor_file, desc_type=None, validate=False, **kwargs):
    """
  Iterates over the hidden service descriptors in a file.

  :param file descriptor_file: file with descriptor content
  :param class desc_type: BaseHiddenServiceDescriptor subclass
  :param bool validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param dict kwargs: additional arguments for the descriptor constructor

  :returns: iterator for :class:`~stem.descriptor.hidden_service.HiddenServiceDescriptorV2`
    instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is **True**
    * **IOError** if the file can't be read
  """

    if desc_type is None:
        desc_type = HiddenServiceDescriptorV2

    # Hidden service v3 ends with a signature line, whereas v2 has a pgp style
    # block following it.

    while True:
        descriptor_content = _read_until_keywords('signature', descriptor_file,
                                                  True)

        if desc_type == HiddenServiceDescriptorV2:
            block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
            descriptor_content += _read_until_keywords(block_end_prefix,
                                                       descriptor_file, True)

        if descriptor_content:
            if descriptor_content[0].startswith(b'@type'):
                descriptor_content = descriptor_content[1:]

            yield desc_type(bytes.join(b'', descriptor_content), validate,
                            **kwargs)
        else:
            break  # done parsing file
Exemple #8
0
def _parse_file(descriptor_file, is_bridge=False, validate=True, **kwargs):
    """
  Iterates over the server descriptors in a file.

  :param file descriptor_file: file with descriptor content
  :param bool is_bridge: parses the file as being a bridge descriptor
  :param bool validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param dict kwargs: additional arguments for the descriptor constructor

  :returns: iterator for ServerDescriptor instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is True
    * **IOError** if the file can't be read
  """

    # Handler for relay descriptors
    #
    # Cached descriptors consist of annotations followed by the descriptor
    # itself. For instance...
    #
    #   @downloaded-at 2012-03-14 16:31:05
    #   @source "145.53.65.130"
    #   router caerSidi 71.35.143.157 9001 0 0
    #   platform Tor 0.2.1.30 on Linux x86_64
    #   <rest of the descriptor content>
    #   router-signature
    #   -----BEGIN SIGNATURE-----
    #   <signature for the above descriptor>
    #   -----END SIGNATURE-----
    #
    # Metrics descriptor files are the same, but lack any annotations. The
    # following simply does the following...
    #
    #   - parse as annotations until we get to "router"
    #   - parse as descriptor content until we get to "router-signature" followed
    #     by the end of the signature block
    #   - construct a descriptor and provide it back to the caller
    #
    # Any annotations after the last server descriptor is ignored (never provided
    # to the caller).

    while True:
        annotations = _read_until_keywords("router", descriptor_file)
        descriptor_content = _read_until_keywords("router-signature",
                                                  descriptor_file)

        # we've reached the 'router-signature', now include the pgp style block
        block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
        descriptor_content += _read_until_keywords(block_end_prefix,
                                                   descriptor_file, True)

        if descriptor_content:
            # strip newlines from annotations
            annotations = map(bytes.strip, annotations)

            descriptor_text = bytes.join(b"", descriptor_content)

            if is_bridge:
                yield BridgeDescriptor(descriptor_text, validate, annotations,
                                       **kwargs)
            else:
                yield RelayDescriptor(descriptor_text, validate, annotations,
                                      **kwargs)
        else:
            if validate and annotations:
                orphaned_annotations = stem.util.str_tools._to_unicode(
                    b'\n'.join(annotations))
                raise ValueError(
                    'Content conform to being a server descriptor:\n%s' %
                    orphaned_annotations)

            break  # done parsing descriptors
def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs):
  """
  Iterates over the server descriptors in a file.

  :param file descriptor_file: file with descriptor content
  :param bool is_bridge: parses the file as being a bridge descriptor
  :param bool validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param dict kwargs: additional arguments for the descriptor constructor

  :returns: iterator for ServerDescriptor instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is True
    * **IOError** if the file can't be read
  """

  # Handler for relay descriptors
  #
  # Cached descriptors consist of annotations followed by the descriptor
  # itself. For instance...
  #
  #   @downloaded-at 2012-03-14 16:31:05
  #   @source "145.53.65.130"
  #   router caerSidi 71.35.143.157 9001 0 0
  #   platform Tor 0.2.1.30 on Linux x86_64
  #   <rest of the descriptor content>
  #   router-signature
  #   -----BEGIN SIGNATURE-----
  #   <signature for the above descriptor>
  #   -----END SIGNATURE-----
  #
  # Metrics descriptor files are the same, but lack any annotations. The
  # following simply does the following...
  #
  #   - parse as annotations until we get to 'router'
  #   - parse as descriptor content until we get to 'router-signature' followed
  #     by the end of the signature block
  #   - construct a descriptor and provide it back to the caller
  #
  # Any annotations after the last server descriptor is ignored (never provided
  # to the caller).

  while True:
    annotations = _read_until_keywords('router', descriptor_file)
    descriptor_content = _read_until_keywords('router-signature', descriptor_file)

    # we've reached the 'router-signature', now include the pgp style block
    block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
    descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True)

    if descriptor_content:
      if descriptor_content[0].startswith(b'@type'):
        descriptor_content = descriptor_content[1:]

      # strip newlines from annotations
      annotations = map(bytes.strip, annotations)

      descriptor_text = bytes.join(b'', descriptor_content)

      if is_bridge:
        yield BridgeDescriptor(descriptor_text, validate, annotations, **kwargs)
      else:
        yield RelayDescriptor(descriptor_text, validate, annotations, **kwargs)
    else:
      if validate and annotations:
        orphaned_annotations = stem.util.str_tools._to_unicode(b'\n'.join(annotations))
        raise ValueError('Content conform to being a server descriptor:\n%s' % orphaned_annotations)

      break  # done parsing descriptors
Exemple #10
0
def _parse_file(
    descriptor_file: BinaryIO,
    is_bridge: bool = False,
    validate: bool = False,
    **kwargs: Any
) -> Iterator['stem.descriptor.server_descriptor.ServerDescriptor']:
    """
  Iterates over the server descriptors in a file.

  :param descriptor_file: file with descriptor content
  :param is_bridge: parses the file as being a bridge descriptor
  :param validate: checks the validity of the descriptor's content if
    **True**, skips these checks otherwise
  :param kwargs: additional arguments for the descriptor constructor

  :returns: iterator for ServerDescriptor instances in the file

  :raises:
    * **ValueError** if the contents is malformed and validate is True
    * **IOError** if the file can't be read
  """

    # Handler for relay descriptors
    #
    # Cached descriptors consist of annotations followed by the descriptor
    # itself. For instance...
    #
    #   @downloaded-at 2012-03-14 16:31:05
    #   @source "145.53.65.130"
    #   router caerSidi 71.35.143.157 9001 0 0
    #   platform Tor 0.2.1.30 on Linux x86_64
    #   <rest of the descriptor content>
    #   router-signature
    #   -----BEGIN SIGNATURE-----
    #   <signature for the above descriptor>
    #   -----END SIGNATURE-----
    #
    # Metrics descriptor files are the same, but lack any annotations. The
    # following simply does the following...
    #
    #   - parse as annotations until we get to 'router'
    #   - parse as descriptor content until we get to 'router-signature' followed
    #     by the end of the signature block
    #   - construct a descriptor and provide it back to the caller
    #
    # Any annotations after the last server descriptor is ignored (never provided
    # to the caller).

    while True:
        # skip annotations

        while True:
            pos = descriptor_file.tell()

            if not descriptor_file.readline().startswith(b'@'):
                descriptor_file.seek(pos)
                break

        if not is_bridge:
            descriptor_content = _read_until_keywords('router-signature',
                                                      descriptor_file)

            # we've reached the 'router-signature', now include the pgp style block

            block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0]
            descriptor_content += _read_until_keywords(block_end_prefix,
                                                       descriptor_file, True)
        else:
            descriptor_content = _read_until_keywords('router-digest',
                                                      descriptor_file, True)

        if descriptor_content:
            if descriptor_content[0].startswith(b'@type'):
                descriptor_content = descriptor_content[1:]

            descriptor_text = bytes.join(b'', descriptor_content)

            if is_bridge:
                if kwargs:
                    raise ValueError(
                        'BUG: keyword arguments unused by bridge descriptors')

                yield BridgeDescriptor(descriptor_text, validate)
            else:
                yield RelayDescriptor(descriptor_text, validate, **kwargs)
        else:
            break  # done parsing descriptors