Exemple #1
0
    def test_router_status_entry(self):
        """
    Tests creation of router status entries.
    """

        desc_without_fingerprint = RelayDescriptor.create()
        exc_msg = 'Server descriptor lacks a fingerprint. This is an optional field, but required to make a router status entry.'
        self.assertRaisesRegexp(
            ValueError, exc_msg,
            desc_without_fingerprint.make_router_status_entry)

        desc = RelayDescriptor.create({
            'router':
            'caerSidi 71.35.133.197 9001 0 0',
            'published':
            '2012-02-29 04:03:19',
            'fingerprint':
            '4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE44',
            'or-address':
            ['71.35.133.197:9001', '[12ab:2e19:3bcf::02:9970]:9001'],
            'onion-key':
            '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' %
            stem.descriptor.CRYPTO_BLOB,
            'signing-key':
            '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' %
            stem.descriptor.CRYPTO_BLOB,
        }).make_router_status_entry()

        self.assertEqual(
            stem.descriptor.router_status_entry.RouterStatusEntryV3,
            type(desc))
        self.assertEqual('caerSidi', desc.nickname)
        self.assertEqual('4F0C867DF0EF68160568C826838F482CEA7CFE44',
                         desc.fingerprint)
        self.assertEqual(datetime.datetime(2012, 2, 29, 4, 3, 19),
                         desc.published)
        self.assertEqual('71.35.133.197', desc.address)
        self.assertEqual(9001, desc.or_port)
        self.assertEqual(None, desc.dir_port)
        self.assertEqual(['Fast', 'Named', 'Running', 'Stable', 'Valid'],
                         desc.flags)
        self.assertEqual(None, desc.version)
        self.assertEqual(None, desc.version_line)

        self.assertEqual([('71.35.133.197', 9001, False),
                          ('12ab:2e19:3bcf::02:9970', 9001, True)],
                         desc.or_addresses)
        self.assertEqual(None, desc.identifier_type)
        self.assertEqual(None, desc.identifier)
        self.assertEqual('4F0069BF91C04581B7C3CA9272E2D3228D4EA571',
                         desc.digest)
        self.assertEqual(153600, desc.bandwidth)
        self.assertEqual(None, desc.measured)
        self.assertEqual(False, desc.is_unmeasured)
        self.assertEqual([], desc.unrecognized_bandwidth_entries)
        self.assertEqual(stem.exit_policy.MicroExitPolicy('reject 1-65535'),
                         desc.exit_policy)
        self.assertEqual([], desc.microdescriptor_hashes)
Exemple #2
0
  def test_outdated_relays(self, downloader_mock, stdout_mock):
    downloader_mock().get_server_descriptors.return_value = [
      RelayDescriptor.create({'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}),
      RelayDescriptor.create({'platform': 'node-Tor 0.1.0 on Linux x86_64'}),
      RelayDescriptor.create({'opt': 'contact Random Person [email protected]', 'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}),
      RelayDescriptor.create({'opt': 'contact Sambuddha Basu', 'platform': 'node-Tor 0.1.0 on Linux x86_64'}),
    ]

    exec_documentation_example('outdated_relays.py')

    self.assertCountEqual(OUTDATED_RELAYS_OUTPUT.splitlines(), stdout_mock.getvalue().splitlines())
Exemple #3
0
    def test_with_bridge_distribution(self):
        """
    Include a preferred method of bridge distribution.
    """

        desc = RelayDescriptor.create({'bridge-distribution-request': 'email'})
        self.assertEqual(BridgeDistribution.EMAIL, desc.bridge_distribution)
Exemple #4
0
  def test_ntor_onion_key(self):
    """
    Checks a 'ntor-onion-key' line.
    """

    desc = RelayDescriptor.create({'ntor-onion-key': 'Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU='})
    self.assertEqual('Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU=', desc.ntor_onion_key)
Exemple #5
0
  def test_ipv6_policy(self):
    """
    Checks a 'ipv6-policy' line.
    """

    desc = RelayDescriptor.create({'ipv6-policy': 'accept 22-23,53,80,110'})
    self.assertEqual(stem.exit_policy.MicroExitPolicy('accept 22-23,53,80,110'), desc.exit_policy_v6)
Exemple #6
0
  def test_unrecognized_line(self):
    """
    Includes unrecognized content in the descriptor.
    """

    desc = RelayDescriptor.create({'pepperjack': 'is oh so tasty!'})
    self.assertEqual(['pepperjack is oh so tasty!'], desc.get_unrecognized_lines())
Exemple #7
0
  def test_unrecognized_line(self):
    """
    Includes unrecognized content in the descriptor.
    """

    desc = RelayDescriptor.create({'pepperjack': 'is oh so tasty!'})
    self.assertEqual(['pepperjack is oh so tasty!'], desc.get_unrecognized_lines())
Exemple #8
0
  def test_ntor_onion_key(self):
    """
    Checks a 'ntor-onion-key' line.
    """

    desc = RelayDescriptor.create({'ntor-onion-key': 'Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU='})
    self.assertEqual('Od2Sj3UXFyDjwESLXk6fhatqW9z/oBL/vAKJ+tbDqUU=', desc.ntor_onion_key)
Exemple #9
0
  def test_invalid_attributes(self):
    """
    Attempts to make a csv with attributes that don't exist.
    """

    desc = RelayDescriptor.create()
    self.assertRaises(ValueError, export_csv, desc, ('nickname', 'blarg!'))
Exemple #10
0
  def test_with_opt(self):
    """
    Includes an 'opt <keyword> <value>' entry.
    """

    desc = RelayDescriptor.create({'opt': 'contact www.atagar.com/contact/'})
    self.assertEqual(b'www.atagar.com/contact/', desc.contact)
Exemple #11
0
  def test_ipv6_policy(self):
    """
    Checks a 'ipv6-policy' line.
    """

    desc = RelayDescriptor.create({'ipv6-policy': 'accept 22-23,53,80,110'})
    self.assertEqual(stem.exit_policy.MicroExitPolicy('accept 22-23,53,80,110'), desc.exit_policy_v6)
Exemple #12
0
    def test_minimal_descriptor(self):
        """
    Exports a single minimal tor server descriptor.
    """

        if stem.prereq._is_python_26():
            self.skipTest('(header added in python 2.7)')
            return

        desc = RelayDescriptor.create({
            'router': 'caerSidi 71.35.133.197 9001 0 0',
            'published': '2012-03-01 17:15:27',
        })

        desc_csv = export_csv(desc,
                              included_fields=('nickname', 'address',
                                               'published'),
                              header=False)
        expected = 'caerSidi,71.35.133.197,2012-03-01 17:15:27\n'
        self.assertEqual(expected, desc_csv)

        desc_csv = export_csv(desc,
                              included_fields=('nickname', 'address',
                                               'published'),
                              header=True)
        expected = 'nickname,address,published\n' + expected
        self.assertEqual(expected, desc_csv)
Exemple #13
0
  def test_with_opt(self):
    """
    Includes an 'opt <keyword> <value>' entry.
    """

    desc = RelayDescriptor.create({'opt': 'contact www.atagar.com/contact/'})
    self.assertEqual(b'www.atagar.com/contact/', desc.contact)
Exemple #14
0
  def test_protocols(self):
    """
    Checks a 'proto' line.
    """

    desc = RelayDescriptor.create({'proto': 'Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2'})
    self.assertEqual({'Cons': [1], 'Desc': [1], 'DirCache': [1], 'HSDir': [1], 'HSIntro': [3], 'HSRend': [1], 'Link': [1, 2, 3, 4], 'LinkAuth': [1], 'Microdesc': [1], 'Relay': [1, 2]}, desc.protocols)
Exemple #15
0
  def test_protocols(self):
    """
    Checks a 'proto' line.
    """

    desc = RelayDescriptor.create({'proto': 'Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 Link=1-4 LinkAuth=1 Microdesc=1 Relay=1-2'})
    self.assertEqual({'Cons': [1], 'Desc': [1], 'DirCache': [1], 'HSDir': [1], 'HSIntro': [3], 'HSRend': [1], 'Link': [1, 2, 3, 4], 'LinkAuth': [1], 'Microdesc': [1], 'Relay': [1, 2]}, desc.protocols)
Exemple #16
0
    def test_invalid_attributes(self):
        """
    Attempts to make a csv with attributes that don't exist.
    """

        desc = RelayDescriptor.create()
        self.assertRaises(ValueError, export_csv, desc, ('nickname', 'blarg!'))
Exemple #17
0
  def test_extrainfo_sha256_digest(self):
    """
    Extrainfo descriptor line with both a hex and base64 encoded sha256 digest.
    """

    desc = RelayDescriptor.create({'extra-info-digest': '03272BF7C68484AFBDA508DAE3734D809E4A5BC4 DWMz1AEdqPlcroubwx3lPEoGbT+oX7S2BH653sPIqfI'})
    self.assertEqual('03272BF7C68484AFBDA508DAE3734D809E4A5BC4', desc.extra_info_digest)
    self.assertEqual('DWMz1AEdqPlcroubwx3lPEoGbT+oX7S2BH653sPIqfI', desc.extra_info_sha256_digest)
Exemple #18
0
    def test_multiple_descriptor_types(self):
        """
    Attempts to make a csv with multiple descriptor types.
    """

        self.assertRaises(
            ValueError, export_csv,
            (RelayDescriptor.create(), BridgeDescriptor.create()))
Exemple #19
0
  def test_mirror_mirror_on_the_wall_4(self, get_desc_mock, stdout_mock):
    get_desc_mock.return_value = iter([RelayDescriptor.create({
      'router': 'caerSidi 71.35.133.197 9001 0 0',
      'fingerprint': '2C3C 4662 5698 B6D6 7DF3 2BC1 918A D3EE 1F99 06B1',
    }, exit_policy = ExitPolicy('accept *:*'), validate = False)])

    exec_documentation_example('collector_reading.py')
    self.assertEqual('  caerSidi (2C3C46625698B6D67DF32BC1918AD3EE1F9906B1)\n', stdout_mock.getvalue())
Exemple #20
0
  def test_extrainfo_sha256_digest(self):
    """
    Extrainfo descriptor line with both a hex and base64 encoded sha256 digest.
    """

    desc = RelayDescriptor.create({'extra-info-digest': '03272BF7C68484AFBDA508DAE3734D809E4A5BC4 DWMz1AEdqPlcroubwx3lPEoGbT+oX7S2BH653sPIqfI'})
    self.assertEqual('03272BF7C68484AFBDA508DAE3734D809E4A5BC4', desc.extra_info_digest)
    self.assertEqual('DWMz1AEdqPlcroubwx3lPEoGbT+oX7S2BH653sPIqfI', desc.extra_info_sha256_digest)
Exemple #21
0
  def test_read_history_empty(self):
    """
    Parses a read-history with an empty value.
    """

    desc = RelayDescriptor.create({'opt read-history': '2005-12-17 01:23:11 (900 s) '})
    self.assertEqual(datetime.datetime(2005, 12, 17, 1, 23, 11), desc.read_history_end)
    self.assertEqual(900, desc.read_history_interval)
    self.assertEqual([], desc.read_history_values)
Exemple #22
0
  def test_read_history_empty(self):
    """
    Parses a read-history with an empty value.
    """

    desc = RelayDescriptor.create({'opt read-history': '2005-12-17 01:23:11 (900 s) '})
    self.assertEqual(datetime.datetime(2005, 12, 17, 1, 23, 11), desc.read_history_end)
    self.assertEqual(900, desc.read_history_interval)
    self.assertEqual([], desc.read_history_values)
Exemple #23
0
  def test_platform_for_node_tor(self):
    """
    Parse a platform line belonging to a node-Tor relay.
    """

    desc = RelayDescriptor.create({'platform': 'node-Tor 0.1.0 on Linux x86_64'})
    self.assertEqual(b'node-Tor 0.1.0 on Linux x86_64', desc.platform)
    self.assertEqual(stem.version.Version('0.1.0'), desc.tor_version)
    self.assertEqual('Linux x86_64', desc.operating_system)
Exemple #24
0
  def test_platform_for_node_tor(self):
    """
    Parse a platform line belonging to a node-Tor relay.
    """

    desc = RelayDescriptor.create({'platform': 'node-Tor 0.1.0 on Linux x86_64'})
    self.assertEqual(b'node-Tor 0.1.0 on Linux x86_64', desc.platform)
    self.assertEqual(stem.version.Version('0.1.0'), desc.tor_version)
    self.assertEqual('Linux x86_64', desc.operating_system)
Exemple #25
0
  def test_minimal_relay_descriptor(self):
    """
    Basic sanity check that we can parse a relay server descriptor with minimal
    attributes.
    """

    desc = RelayDescriptor.create({'router': 'caerSidi 71.35.133.197 9001 0 0'})
    self.assertEqual('caerSidi', desc.nickname)
    self.assertEqual('71.35.133.197', desc.address)
    self.assertEqual(None, desc.fingerprint)
Exemple #26
0
  def test_published_leap_year(self):
    """
    Constructs with a published entry for a leap year, and when the date is
    invalid.
    """

    expect_invalid_attr(self, {'published': '2011-02-29 04:03:19'}, 'published')

    desc = RelayDescriptor.create({'published': '2012-02-29 04:03:19'})
    self.assertEqual(datetime.datetime(2012, 2, 29, 4, 3, 19), desc.published)
Exemple #27
0
  def test_minimal_relay_descriptor(self):
    """
    Basic sanity check that we can parse a relay server descriptor with minimal
    attributes.
    """

    desc = RelayDescriptor.create({'router': 'caerSidi 71.35.133.197 9001 0 0'})
    self.assertEqual('caerSidi', desc.nickname)
    self.assertEqual('71.35.133.197', desc.address)
    self.assertEqual(None, desc.fingerprint)
Exemple #28
0
  def test_published_leap_year(self):
    """
    Constructs with a published entry for a leap year, and when the date is
    invalid.
    """

    expect_invalid_attr(self, {'published': '2011-02-29 04:03:19'}, 'published')

    desc = RelayDescriptor.create({'published': '2012-02-29 04:03:19'})
    self.assertEqual(datetime.datetime(2012, 2, 29, 4, 3, 19), desc.published)
Exemple #29
0
    def test_mirror_mirror_on_the_wall_4(self, reader_mock, stdout_mock):
        reader = reader_mock().__enter__()
        reader.__iter__.return_value = iter([
            RelayDescriptor.create(
                {'router': 'caerSidi 71.35.133.197 9001 0 0'})
        ])

        exec_documentation_example('past_descriptors.py')
        self.assertEqual('found relay caerSidi (None)\n',
                         stdout_mock.getvalue())
Exemple #30
0
    def test_outdated_relays(self, stdout_mock, downloader_mock):
        downloader_mock().get_server_descriptors.return_value = [
            RelayDescriptor.create(
                {'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}),
            RelayDescriptor.create(
                {'platform': 'node-Tor 0.1.0 on Linux x86_64'}),
            RelayDescriptor.create({
                'opt':
                'contact Random Person [email protected]',
                'platform':
                'node-Tor 0.2.3.0 on Linux x86_64'
            }),
            RelayDescriptor.create({
                'opt': 'contact Sambuddha Basu',
                'platform': 'node-Tor 0.1.0 on Linux x86_64'
            }),
        ]

        import outdated_relays

        self.assertEqual(EXPECTED_OUTDATED_RELAYS, stdout_mock.getvalue())
Exemple #31
0
    def test_read_with_parse_file(self, stdout_mock, parse_file_mock):
        parse_file_mock.return_value = [
            RelayDescriptor.create({
                'fingerprint':
                '4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE44'
            })
        ]

        import read_with_parse_file

        self.assertEqual('4F0C867DF0EF68160568C826838F482CEA7CFE44\n',
                         stdout_mock.getvalue())
Exemple #32
0
    def test_file_output(self):
        """
    Basic test for the export_csv_file() function, checking that it provides
    the same output as export_csv().
    """

        desc = RelayDescriptor.create()
        desc_csv = export_csv(desc)

        csv_buffer = StringIO()
        export_csv_file(csv_buffer, desc)

        self.assertEqual(desc_csv, csv_buffer.getvalue())
Exemple #33
0
  def test_file_output(self):
    """
    Basic test for the export_csv_file() function, checking that it provides
    the same output as export_csv().
    """

    desc = RelayDescriptor.create()
    desc_csv = export_csv(desc)

    csv_buffer = StringIO()
    export_csv_file(csv_buffer, desc)

    self.assertEqual(desc_csv, csv_buffer.getvalue())
Exemple #34
0
  def test_router_status_entry(self):
    """
    Tests creation of router status entries.
    """

    desc_without_fingerprint = RelayDescriptor.create()
    exc_msg = 'Server descriptor lacks a fingerprint. This is an optional field, but required to make a router status entry.'
    self.assertRaisesRegexp(ValueError, exc_msg, desc_without_fingerprint.make_router_status_entry)

    desc = RelayDescriptor.create({
      'router': 'caerSidi 71.35.133.197 9001 0 0',
      'published': '2012-02-29 04:03:19',
      'fingerprint': '4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE44',
      'or-address': ['71.35.133.197:9001', '[12ab:2e19:3bcf::02:9970]:9001'],
      'onion-key': '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % stem.descriptor.CRYPTO_BLOB,
      'signing-key': '\n-----BEGIN RSA PUBLIC KEY-----%s-----END RSA PUBLIC KEY-----' % stem.descriptor.CRYPTO_BLOB,
    }).make_router_status_entry()

    self.assertEqual(stem.descriptor.router_status_entry.RouterStatusEntryV3, type(desc))
    self.assertEqual('caerSidi', desc.nickname)
    self.assertEqual('4F0C867DF0EF68160568C826838F482CEA7CFE44', desc.fingerprint)
    self.assertEqual(datetime.datetime(2012, 2, 29, 4, 3, 19), desc.published)
    self.assertEqual('71.35.133.197', desc.address)
    self.assertEqual(9001, desc.or_port)
    self.assertEqual(None, desc.dir_port)
    self.assertEqual(['Fast', 'Named', 'Running', 'Stable', 'Valid'], desc.flags)
    self.assertEqual(None, desc.version)
    self.assertEqual(None, desc.version_line)

    self.assertEqual([('71.35.133.197', 9001, False), ('12ab:2e19:3bcf::02:9970', 9001, True)], desc.or_addresses)
    self.assertEqual(None, desc.identifier_type)
    self.assertEqual(None, desc.identifier)
    self.assertEqual('4F0069BF91C04581B7C3CA9272E2D3228D4EA571', desc.digest)
    self.assertEqual(153600, desc.bandwidth)
    self.assertEqual(None, desc.measured)
    self.assertEqual(False, desc.is_unmeasured)
    self.assertEqual([], desc.unrecognized_bandwidth_entries)
    self.assertEqual(stem.exit_policy.MicroExitPolicy('reject 1-65535'), desc.exit_policy)
    self.assertEqual([], desc.microdescriptor_hashes)
Exemple #35
0
    def test_mirror_mirror_on_the_wall_5(self, downloader_mock, stdout_mock):
        def tutorial_example():
            from stem.descriptor.remote import DescriptorDownloader
            from stem.util import str_tools

            # provides a mapping of observed bandwidth to the relay nicknames
            def get_bw_to_relay():
                bw_to_relay = {}

                downloader = DescriptorDownloader()

                try:
                    for desc in downloader.get_server_descriptors().run():
                        if desc.exit_policy.is_exiting_allowed():
                            bw_to_relay.setdefault(desc.observed_bandwidth,
                                                   []).append(desc.nickname)
                except Exception as exc:
                    print('Unable to retrieve the server descriptors: %s' %
                          exc)

                return bw_to_relay

            # prints the top fifteen relays

            bw_to_relay = get_bw_to_relay()
            count = 1

            for bw_value in sorted(bw_to_relay.keys(), reverse=True):
                for nickname in bw_to_relay[bw_value]:
                    print('%i. %s (%s/s)' %
                          (count, nickname, str_tools.size_label(bw_value, 2)))
                    count += 1

                    if count > 15:
                        return

        exit_descriptor = RelayDescriptor.content({
            'router':
            'speedyexit 149.255.97.109 9001 0 0'
        }).replace(b'reject *:*', b'accept *:*')
        exit_descriptor = RelayDescriptor(exit_descriptor)

        downloader_mock().get_server_descriptors().run.return_value = [
            exit_descriptor,
            RelayDescriptor.create(),  # non-exit
            exit_descriptor,
            exit_descriptor,
        ]

        tutorial_example()
        self.assertEqual(MIRROR_MIRROR_OUTPUT, stdout_mock.getvalue())
Exemple #36
0
  def test_multiple_descriptors(self):
    """
    Exports multiple descriptors, making sure that we get them back in the same
    order.
    """

    nicknames = ('relay1', 'relay3', 'relay2', 'caerSidi', 'zeus')
    descriptors = []

    for nickname in nicknames:
      router_line = '%s 71.35.133.197 9001 0 0' % nickname
      descriptors.append(RelayDescriptor.create({'router': router_line}))

    expected = '\n'.join(nicknames) + '\n'
    self.assertEqual(expected, export_csv(descriptors, included_fields = ('nickname',), header = False))
Exemple #37
0
    def test_saving_and_loading_descriptors(self):
        server_desc = RelayDescriptor.create(
            {'router': 'caerSidi 71.35.133.197 9001 0 0'})

        with patch('stem.descriptor.remote.get_server_descriptors',
                   _download_of(server_desc)):
            try:
                import saving_and_loading_descriptors

                with open('/tmp/descriptor_dump') as descriptor_file:
                    self.assertTrue(descriptor_file.read().startswith(
                        'router caerSidi 71.35.133.197'))
            finally:
                if os.path.exists('/tmp/descriptor_dump'):
                    os.remove('/tmp/descriptor_dump')
Exemple #38
0
  def test_excludes_private_attr(self):
    """
    Checks that the default attributes for our csv output doesn't include private fields.
    """

    if stem.prereq._is_python_26():
      self.skipTest('(header added in python 2.7)')
      return

    desc = RelayDescriptor.create()
    desc_csv = export_csv(desc)

    self.assertTrue(',signature' in desc_csv)
    self.assertFalse(',_digest' in desc_csv)
    self.assertFalse(',_annotation_lines' in desc_csv)
Exemple #39
0
    def test_collector_reading(self, stdout_mock, server_desc_mock):
        server_desc_mock.return_value = [
            RelayDescriptor.create(
                {
                    'router':
                    'caerSidi 71.35.133.197 9001 0 0',
                    'fingerprint':
                    '4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE44',
                },
                exit_policy=ExitPolicy('accept *:*')),
        ]

        import collector_reading

        self.assertEqual(EXPECTED_COLLECTOR_READING, stdout_mock.getvalue())
Exemple #40
0
    def test_excludes_private_attr(self):
        """
    Checks that the default attributes for our csv output doesn't include private fields.
    """

        if stem.prereq._is_python_26():
            self.skipTest('(header added in python 2.7)')
            return

        desc = RelayDescriptor.create()
        desc_csv = export_csv(desc)

        self.assertTrue(',signature' in desc_csv)
        self.assertFalse(',_digest' in desc_csv)
        self.assertFalse(',_annotation_lines' in desc_csv)
Exemple #41
0
    def test_check_digests(self):
        import check_digests as module
        fingerprint = 'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB'

        extrainfo_desc = RelayExtraInfoDescriptor.create()
        server_desc = RelayDescriptor.create(
            {'extra-info-digest': extrainfo_desc.digest()}, sign=True)

        encoded_digest = base64.b64encode(
            binascii.unhexlify(server_desc.digest())).rstrip(b'=')

        consensus_desc = RouterStatusEntryV3.create({
            'r':
            'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s %s 2012-08-06 11:19:31 71.35.150.29 9001 0'
            % encoded_digest.decode('utf-8'),
        })

        bad_consensus_desc = RouterStatusEntryV3.create({
            'r':
            'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 71.35.150.29 9001 0',
        })

        with patch('stem.descriptor.remote.get_server_descriptors',
                   _download_of(server_desc)):
            with patch('stem.descriptor.remote.get_extrainfo_descriptors',
                       _download_of(extrainfo_desc)):
                # correctly signed descriptors

                with patch('stem.descriptor.remote.get_consensus',
                           _download_of(consensus_desc)):
                    with patch('sys.stdout',
                               new_callable=io.StringIO) as stdout_mock:
                        module.validate_relay(fingerprint)
                        self.assertEqual(EXPECTED_CHECK_DIGESTS_OK,
                                         stdout_mock.getvalue())

                # incorrect server descriptor digest

                with patch('stem.descriptor.remote.get_consensus',
                           _download_of(bad_consensus_desc)):
                    with patch('sys.stdout',
                               new_callable=io.StringIO) as stdout_mock:
                        module.validate_relay(fingerprint)
                        self.assertEqual(
                            EXPECTED_CHECK_DIGESTS_BAD % server_desc.digest(),
                            stdout_mock.getvalue())
Exemple #42
0
    def test_tor_descriptors(self, stdout_mock, downloader_mock):
        exit_descriptor = RelayDescriptor.content({
            'router':
            'speedyexit 149.255.97.109 9001 0 0'
        }).replace(b'reject *:*', b'accept *:*')
        exit_descriptor = RelayDescriptor(exit_descriptor)

        downloader_mock().get_server_descriptors().run.return_value = [
            exit_descriptor,
            RelayDescriptor.create(),  # non-exit
            exit_descriptor,
            exit_descriptor,
        ]

        import tor_descriptors

        self.assertEqual(EXPECTED_TOR_DESCRIPTORS, stdout_mock.getvalue())
Exemple #43
0
  def test_mirror_mirror_on_the_wall_5(self, downloader_mock, stdout_mock):
    def tutorial_example():
      from stem.descriptor.remote import DescriptorDownloader
      from stem.util import str_tools

      # provides a mapping of observed bandwidth to the relay nicknames
      def get_bw_to_relay():
        bw_to_relay = {}

        downloader = DescriptorDownloader()

        try:
          for desc in downloader.get_server_descriptors().run():
            if desc.exit_policy.is_exiting_allowed():
              bw_to_relay.setdefault(desc.observed_bandwidth, []).append(desc.nickname)
        except Exception as exc:
          print('Unable to retrieve the server descriptors: %s' % exc)

        return bw_to_relay

      # prints the top fifteen relays

      bw_to_relay = get_bw_to_relay()
      count = 1

      for bw_value in sorted(bw_to_relay.keys(), reverse = True):
        for nickname in bw_to_relay[bw_value]:
          print('%i. %s (%s/s)' % (count, nickname, str_tools.size_label(bw_value, 2)))
          count += 1

          if count > 15:
            return

    exit_descriptor = RelayDescriptor.content({'router': 'speedyexit 149.255.97.109 9001 0 0'}).replace(b'reject *:*', b'accept *:*')
    exit_descriptor = RelayDescriptor(exit_descriptor)

    downloader_mock().get_server_descriptors().run.return_value = [
      exit_descriptor,
      RelayDescriptor.create(),  # non-exit
      exit_descriptor,
      exit_descriptor,
    ]

    tutorial_example()
    self.assertEqual(MIRROR_MIRROR_OUTPUT, stdout_mock.getvalue())
Exemple #44
0
    def test_multiple_descriptors(self):
        """
    Exports multiple descriptors, making sure that we get them back in the same
    order.
    """

        nicknames = ('relay1', 'relay3', 'relay2', 'caerSidi', 'zeus')
        descriptors = []

        for nickname in nicknames:
            router_line = '%s 71.35.133.197 9001 0 0' % nickname
            descriptors.append(RelayDescriptor.create({'router': router_line}))

        expected = '\n'.join(nicknames) + '\n'
        self.assertEqual(
            expected,
            export_csv(descriptors,
                       included_fields=('nickname', ),
                       header=False))
Exemple #45
0
  def test_minimal_descriptor(self):
    """
    Exports a single minimal tor server descriptor.
    """

    if stem.prereq._is_python_26():
      self.skipTest('(header added in python 2.7)')
      return

    desc = RelayDescriptor.create({
      'router': 'caerSidi 71.35.133.197 9001 0 0',
      'published': '2012-03-01 17:15:27',
    })

    desc_csv = export_csv(desc, included_fields = ('nickname', 'address', 'published'), header = False)
    expected = 'caerSidi,71.35.133.197,2012-03-01 17:15:27\n'
    self.assertEqual(expected, desc_csv)

    desc_csv = export_csv(desc, included_fields = ('nickname', 'address', 'published'), header = True)
    expected = 'nickname,address,published\n' + expected
    self.assertEqual(expected, desc_csv)
Exemple #46
0
  def test_read_and_write_history(self):
    """
    Parses a read-history and write-history entry. This is now a deprecated
    field for relay server descriptors but is still found in archives and
    extra-info descriptors.
    """

    for field in ('read-history', 'write-history'):
      value = '2005-12-16 18:00:48 (900 s) 81,8848,8927,8927,83,8848'
      desc = RelayDescriptor.create({'opt %s' % field: value})

      if field == 'read-history':
        attr = (desc.read_history_end, desc.read_history_interval, desc.read_history_values)
      else:
        attr = (desc.write_history_end, desc.write_history_interval, desc.write_history_values)

      expected_end = datetime.datetime(2005, 12, 16, 18, 0, 48)
      expected_values = [81, 8848, 8927, 8927, 83, 8848]

      self.assertEqual(expected_end, attr[0])
      self.assertEqual(900, attr[1])
      self.assertEqual(expected_values, attr[2])
Exemple #47
0
  def test_read_and_write_history(self):
    """
    Parses a read-history and write-history entry. This is now a deprecated
    field for relay server descriptors but is still found in archives and
    extra-info descriptors.
    """

    for field in ('read-history', 'write-history'):
      value = '2005-12-16 18:00:48 (900 s) 81,8848,8927,8927,83,8848'
      desc = RelayDescriptor.create({'opt %s' % field: value})

      if field == 'read-history':
        attr = (desc.read_history_end, desc.read_history_interval, desc.read_history_values)
      else:
        attr = (desc.write_history_end, desc.write_history_interval, desc.write_history_values)

      expected_end = datetime.datetime(2005, 12, 16, 18, 0, 48)
      expected_values = [81, 8848, 8927, 8927, 83, 8848]

      self.assertEqual(expected_end, attr[0])
      self.assertEqual(900, attr[1])
      self.assertEqual(expected_values, attr[2])
Exemple #48
0
    def test_download_descriptor(self):
        import download_descriptor

        with patch('sys.stdout', new_callable=io.StringIO) as stdout_mock:
            with patch('stem.descriptor.remote.get_server_descriptors',
                       _download_of([])):
                download_descriptor.main(['--help'])
                self.assertTrue(stdout_mock.getvalue().startswith(
                    "Downloads a descriptor through Tor's ORPort"))

        with patch('sys.stdout', new_callable=io.StringIO) as stdout_mock:
            download_descriptor.main(['--type', 'kaboom'])
            self.assertEqual(EXPECTED_DOWNLOAD_DESCRIPTOR_UNKNOWN_TYPE,
                             stdout_mock.getvalue())

        server_desc = RelayDescriptor.create(
            {'router': 'caerSidi 71.35.133.197 9001 0 0'})

        with patch('sys.stdout', new_callable=io.StringIO) as stdout_mock:
            with patch('stem.descriptor.remote.get_server_descriptors',
                       _download_of(server_desc)):
                download_descriptor.main(['--dirport', '1.2.3.4:443'])
                self.assertTrue(stdout_mock.getvalue().startswith(
                    EXPECTED_DOWNLOAD_DESCRIPTOR_PREFIX))
Exemple #49
0
 def test_descriptor_signing(self):
   RelayDescriptor.create(sign = True)
   self.assertRaisesRegexp(NotImplementedError, 'Signing of BridgeDescriptor not implemented', BridgeDescriptor.create, sign = True)
Exemple #50
0
  def test_mirror_mirror_on_the_wall_4(self, reader_mock, stdout_mock):
    reader = reader_mock().__enter__()
    reader.__iter__.return_value = iter([RelayDescriptor.create({'router': 'caerSidi 71.35.133.197 9001 0 0'})])

    exec_documentation_example('past_descriptors.py')
    self.assertEqual('found relay caerSidi (None)\n', stdout_mock.getvalue())
Exemple #51
0
  def test_multiple_descriptor_types(self):
    """
    Attempts to make a csv with multiple descriptor types.
    """

    self.assertRaises(ValueError, export_csv, (RelayDescriptor.create(), BridgeDescriptor.create()))
Exemple #52
0
from stem.descriptor.server_descriptor import RelayDescriptor

# prints 'caerSidi (71.35.133.197:9001)'
desc = RelayDescriptor.create()
print("%s (%s:%s)" % (desc.nickname, desc.address, desc.or_port))

# prints 'demo (127.0.0.1:80)'
desc = RelayDescriptor.create({'router': 'demo 127.0.0.1 80 0 0'})
print("%s (%s:%s)" % (desc.nickname, desc.address, desc.or_port))