示例#1
0
  def test_with_detached_ephemeral_hidden_services(self):
    """
    Exercises creating detached ephemeral hidden services and methods when
    they're present.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      response = controller.create_ephemeral_hidden_service(4567, detached = True)
      self.assertEqual([], controller.list_ephemeral_hidden_services())
      self.assertEqual([response.service_id], controller.list_ephemeral_hidden_services(detached = True))

      # drop and recreate the service

      self.assertEqual(True, controller.remove_ephemeral_hidden_service(response.service_id))
      self.assertEqual([], controller.list_ephemeral_hidden_services(detached = True))
      controller.create_ephemeral_hidden_service(4567, key_type = response.private_key_type, key_content = response.private_key, detached = True)
      self.assertEqual([response.service_id], controller.list_ephemeral_hidden_services(detached = True))

      # other controllers should be able to see this service, and drop it

      with runner.get_tor_controller() as second_controller:
        self.assertEqual([response.service_id], second_controller.list_ephemeral_hidden_services(detached = True))
        self.assertEqual(True, second_controller.remove_ephemeral_hidden_service(response.service_id))
        self.assertEqual([], controller.list_ephemeral_hidden_services(detached = True))

        # recreate the service and confirms that it outlives this controller

        response = second_controller.create_ephemeral_hidden_service(4567, detached = True)

      self.assertEqual([response.service_id], controller.list_ephemeral_hidden_services(detached = True))
      controller.remove_ephemeral_hidden_service(response.service_id)
示例#2
0
  def test_with_ephemeral_hidden_services(self):
    """
    Exercises creating ephemeral hidden services and methods when they're
    present.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      # try creating a service with an invalid ports

      for ports in (4567890, [4567, 4567890], {4567: '-:4567'}):
        exc_msg = "ADD_ONION response didn't have an OK status: Invalid VIRTPORT/TARGET"
        self.assertRaisesRegexp(stem.ProtocolError, exc_msg, controller.create_ephemeral_hidden_service, ports)

      response = controller.create_ephemeral_hidden_service(4567)
      self.assertEqual([response.service_id], controller.list_ephemeral_hidden_services())
      self.assertTrue(response.private_key is not None)
      self.assertEqual({}, response.client_auth)

      # drop the service

      self.assertEqual(True, controller.remove_ephemeral_hidden_service(response.service_id))
      self.assertEqual([], controller.list_ephemeral_hidden_services())

      # recreate the service with the same private key

      recreate_response = controller.create_ephemeral_hidden_service(4567, key_type = response.private_key_type, key_content = response.private_key)
      self.assertEqual([response.service_id], controller.list_ephemeral_hidden_services())
      self.assertEqual(response.service_id, recreate_response.service_id)

      # the response only includes the private key when making a new one

      self.assertEqual(None, recreate_response.private_key)
      self.assertEqual(None, recreate_response.private_key_type)

      # create a service where we never see the private key

      response = controller.create_ephemeral_hidden_service(4568, discard_key = True)
      self.assertTrue(response.service_id in controller.list_ephemeral_hidden_services())
      self.assertEqual(None, response.private_key)
      self.assertEqual(None, response.private_key_type)

      # other controllers shouldn't be able to see these hidden services

      with runner.get_tor_controller() as second_controller:
        self.assertEqual(2, len(controller.list_ephemeral_hidden_services()))
        self.assertEqual(0, len(second_controller.list_ephemeral_hidden_services()))
示例#3
0
    def test_get_streams(self):
        """
    Tests Controller.get_streams().
    """

        if test.runner.require_control(self):
            return
        elif test.runner.require_online(self):
            return

        host = '38.229.72.14'  # www.torproject.org
        port = 443

        runner = test.runner.get_runner()
        with runner.get_tor_controller() as controller:
            # we only need one proxy port, so take the first
            socks_listener = controller.get_socks_listeners()[0]

            with test.network.Socks(socks_listener) as s:
                s.settimeout(30)
                s.connect((host, port))
                streams = controller.get_streams()

        # Because we do not get a stream id when opening a stream,
        #  try to match the target for which we asked a stream.

        self.assertTrue('%s:%s' %
                        (host, port) in [stream.target for stream in streams])
示例#4
0
  def test_is_set(self):
    """
    Exercises our is_set() method.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      custom_options = controller._get_custom_options()
      self.assertTrue('ControlPort' in custom_options or 'ControlSocket' in custom_options)
      self.assertEqual('1', custom_options['DownloadExtraInfo'])
      self.assertEqual('1112', custom_options['SocksPort'])

      self.assertTrue(controller.is_set('DownloadExtraInfo'))
      self.assertTrue(controller.is_set('SocksPort'))
      self.assertFalse(controller.is_set('CellStatistics'))
      self.assertFalse(controller.is_set('ConnLimit'))

      # check we update when setting and resetting values

      controller.set_conf('ConnLimit', '1005')
      self.assertTrue(controller.is_set('ConnLimit'))

      controller.reset_conf('ConnLimit')
      self.assertFalse(controller.is_set('ConnLimit'))
示例#5
0
  def test_get_server_descriptor(self):
    """
    Basic checks for get_server_descriptor().
    """

    runner = test.runner.get_runner()

    if test.runner.require_control(self):
      return
    elif runner.get_tor_version() >= Requirement.MICRODESCRIPTOR_IS_DEFAULT:
      test.runner.skip(self, "(requires server descriptors)")
      return

    with runner.get_tor_controller() as controller:
      # we should balk at invalid content
      self.assertRaises(ValueError, controller.get_server_descriptor, None)
      self.assertRaises(ValueError, controller.get_server_descriptor, "")
      self.assertRaises(ValueError, controller.get_server_descriptor, 5)
      self.assertRaises(ValueError, controller.get_server_descriptor, "z" * 30)

      # try with a relay that doesn't exist
      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, "blargg")
      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, "5" * 40)

      test_relay = self._get_router_status_entry(controller)

      desc_by_fingerprint = controller.get_server_descriptor(test_relay.fingerprint)
      desc_by_nickname = controller.get_server_descriptor(test_relay.nickname)

      self.assertEqual(desc_by_fingerprint, desc_by_nickname)
示例#6
0
    def test_get_server_descriptors(self):
        """
    Fetches a few descriptors via the get_server_descriptors() method.
    """

        runner = test.runner.get_runner()

        if test.runner.require_control(self):
            return
        elif runner.get_tor_version(
        ) >= Requirement.MICRODESCRIPTOR_IS_DEFAULT:
            test.runner.skip(self, '(requires server descriptors)')
            return

        with runner.get_tor_controller() as controller:
            count = 0

            for desc in controller.get_server_descriptors():
                self.assertTrue(desc.fingerprint is not None)
                self.assertTrue(desc.nickname is not None)

                # Se don't want to take the time to read the whole thing. We already
                # have another test that reads the full cached descriptors (and takes a
                # while to do so).

                count += 1
                if count > 10:
                    break
示例#7
0
  def test_mapaddress(self):
    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      controller.map_address({'1.2.1.2': 'ifconfig.me'})

      s = None
      response = None

      # try up to 10 times to rule out transient network failures

      for _ in range(10):
        try:
          s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          s.settimeout(30)
          s.connect(('127.0.0.1', int(controller.get_conf('SocksPort'))))
          test.network.negotiate_socks(s, '1.2.1.2', 80)
          s.sendall(stem.util.str_tools._to_bytes(test.network.ip_request))  # make the http request for the ip address
          response = s.recv(1000)

          if response:
            break
        except (stem.ProtocolError, socket.timeout):
          continue
        finally:
          if s:
            s.close()

      self.assertTrue(response)

      # everything after the blank line is the 'data' in a HTTP response.
      # The response data for our request for request should be an IP address + '\n'

      ip_addr = response[response.find(b'\r\n\r\n'):].strip()
      self.assertTrue(stem.util.connection.is_valid_ipv4_address(stem.util.str_tools._to_unicode(ip_addr)), "'%s' isn't an address" % ip_addr)
示例#8
0
  def test_close_stream(self):
    """
    Tests Controller.close_stream with valid and invalid input.
    """

    if test.runner.require_control(self):
      return
    elif test.runner.require_online(self):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      # use the first socks listener
      socks_listener = controller.get_socks_listeners()[0]
      with test.network.Socks(socks_listener) as s:
        s.settimeout(30)
        s.connect(("www.torproject.org", 443))
        # There's only one stream right now.  Right?
        built_stream = controller.get_streams()[0]
        # Make sure we have the stream for which we asked, otherwise
        # the next assertion would be a false positive.
        self.assertEqual([built_stream.id], [stream.id for stream in controller.get_streams()])
        # Try to close our stream...
        controller.close_stream(built_stream.id)
        # ...which means there are zero streams.
        self.assertEqual([], controller.get_streams())

      # unknown stream
      self.assertRaises(stem.InvalidArguments, controller.close_stream, "blarg")
示例#9
0
  def test_get_server_descriptor(self):
    """
    Basic checks for get_server_descriptor().
    """

    runner = test.runner.get_runner()

    if test.runner.require_control(self):
      return
    elif runner.get_tor_version() >= Requirement.MICRODESCRIPTOR_IS_DEFAULT:
      test.runner.skip(self, "(requires server descriptors)")
      return

    with runner.get_tor_controller() as controller:
      # we should balk at invalid content
      self.assertRaises(ValueError, controller.get_server_descriptor, None)
      self.assertRaises(ValueError, controller.get_server_descriptor, "")
      self.assertRaises(ValueError, controller.get_server_descriptor, 5)
      self.assertRaises(ValueError, controller.get_server_descriptor, "z" * 30)

      # try with a relay that doesn't exist
      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, "blargg")
      self.assertRaises(stem.ControllerError, controller.get_server_descriptor, "5" * 40)

      test_relay = self._get_router_status_entry(controller)

      desc_by_fingerprint = controller.get_server_descriptor(test_relay.fingerprint)
      desc_by_nickname = controller.get_server_descriptor(test_relay.nickname)

      self.assertEqual(desc_by_fingerprint, desc_by_nickname)
示例#10
0
    def test_close_stream(self):
        """
    Tests Controller.close_stream with valid and invalid input.
    """

        if test.runner.require_control(self):
            return
        elif test.runner.require_online(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            # use the first socks listener
            socks_listener = controller.get_socks_listeners()[0]
            with test.network.Socks(socks_listener) as s:
                s.settimeout(30)
                s.connect(("www.torproject.org", 443))
                # There's only one stream right now.  Right?
                built_stream = controller.get_streams()[0]
                # Make sure we have the stream for which we asked, otherwise
                # the next assertion would be a false positive.
                self.assertEqual(
                    [built_stream.id],
                    [stream.id for stream in controller.get_streams()])
                # Try to close our stream...
                controller.close_stream(built_stream.id)
                # ...which means there are zero streams.
                self.assertEqual([], controller.get_streams())

            # unknown stream
            self.assertRaises(stem.InvalidArguments, controller.close_stream,
                              "blarg")
示例#11
0
  def test_close_circuit(self):
    """
    Tests Controller.close_circuit with valid and invalid input.
    """

    if test.runner.require_control(self):
      return
    elif test.runner.require_online(self):
      return
    elif test.runner.require_version(self, Requirement.EXTENDCIRCUIT_PATH_OPTIONAL):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      circuit_id = controller.new_circuit()
      controller.close_circuit(circuit_id)
      circuit_output = controller.get_info("circuit-status")
      circ = [x.split()[0] for x in circuit_output.splitlines()]
      self.assertFalse(circuit_id in circ)

      circuit_id = controller.new_circuit()
      controller.close_circuit(circuit_id, "IfUnused")
      circuit_output = controller.get_info("circuit-status")
      circ = [x.split()[0] for x in circuit_output.splitlines()]
      self.assertFalse(circuit_id in circ)

      circuit_id = controller.new_circuit()
      self.assertRaises(stem.InvalidArguments, controller.close_circuit, circuit_id + "1024")
      self.assertRaises(stem.InvalidRequest, controller.close_circuit, "")
示例#12
0
  def test_protocolinfo(self):
    """
    Test that the convenient method protocolinfo() works.
    """

    if test.runner.require_control(self):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller(False) as controller:
      protocolinfo = controller.get_protocolinfo()
      self.assertTrue(isinstance(protocolinfo, stem.response.protocolinfo.ProtocolInfoResponse))

      # Doing a sanity test on the ProtocolInfoResponse instance returned.
      tor_options = runner.get_options()
      tor_version = runner.get_tor_version()
      auth_methods = []

      if test.runner.Torrc.COOKIE in tor_options:
        auth_methods.append(stem.response.protocolinfo.AuthMethod.COOKIE)

        if tor_version >= stem.version.Requirement.AUTH_SAFECOOKIE:
          auth_methods.append(stem.response.protocolinfo.AuthMethod.SAFECOOKIE)

      if test.runner.Torrc.PASSWORD in tor_options:
        auth_methods.append(stem.response.protocolinfo.AuthMethod.PASSWORD)

      if not auth_methods:
        auth_methods.append(stem.response.protocolinfo.AuthMethod.NONE)

      self.assertEqual(tuple(auth_methods), protocolinfo.auth_methods)
示例#13
0
    def test_close_circuit(self):
        """
    Tests Controller.close_circuit with valid and invalid input.
    """

        if test.runner.require_control(self):
            return
        elif test.runner.require_online(self):
            return
        elif test.runner.require_version(
                self, Requirement.EXTENDCIRCUIT_PATH_OPTIONAL):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            circuit_id = controller.new_circuit()
            controller.close_circuit(circuit_id)
            circuit_output = controller.get_info('circuit-status')
            circ = [x.split()[0] for x in circuit_output.splitlines()]
            self.assertFalse(circuit_id in circ)

            circuit_id = controller.new_circuit()
            controller.close_circuit(circuit_id, 'IfUnused')
            circuit_output = controller.get_info('circuit-status')
            circ = [x.split()[0] for x in circuit_output.splitlines()]
            self.assertFalse(circuit_id in circ)

            circuit_id = controller.new_circuit()
            self.assertRaises(stem.InvalidArguments, controller.close_circuit,
                              circuit_id + '1024')
            self.assertRaises(stem.InvalidRequest, controller.close_circuit,
                              '')
示例#14
0
  def test_loadconf(self):
    """
    Exercises Controller.load_conf with valid and invalid requests.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      oldconf = runner.get_torrc_contents()

      try:
        # Check a request that changes our DataDir. Tor should rightfully balk
        # at this...
        #
        #   InvalidRequest: Transition not allowed: Failed to parse/validate
        #   config: While Tor is running, changing DataDirectory
        #   ("/home/atagar/Desktop/stem/test/data"->"/home/atagar/.tor") is not
        #   allowed.

        self.assertRaises(stem.InvalidRequest, controller.load_conf, 'ContactInfo confloaded')

        try:
          controller.load_conf('Blahblah blah')
          self.fail()
        except stem.InvalidArguments as exc:
          self.assertEqual(['Blahblah'], exc.arguments)

        # valid config

        controller.load_conf(runner.get_torrc_contents() + '\nContactInfo confloaded\n')
        self.assertEqual('confloaded', controller.get_conf('ContactInfo'))
      finally:
        # reload original valid config
        controller.load_conf(oldconf)
        controller.reset_conf('__OwningControllerProcess')
示例#15
0
    def test_mapaddress(self):
        if test.runner.require_control(self):
            return
        elif test.runner.require_online(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            controller.map_address({'1.2.1.2': 'ifconfig.me'})

            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(
                ('127.0.0.1',
                 int(
                     controller.get_conf('SocksListenAddress').rsplit(':',
                                                                      1)[1])))
            test.network.negotiate_socks(s, '1.2.1.2', 80)
            s.sendall(test.network.ip_request
                      )  # make the http request for the ip address
            response = s.recv(1000)

            # everything after the blank line is the 'data' in a HTTP response.
            # The response data for our request for request should be an IP address + '\n'
            ip_addr = response[response.find("\r\n\r\n"):].strip()

            self.assertTrue(
                stem.util.connection.is_valid_ipv4_address(ip_addr))
示例#16
0
  def test_enable_feature(self):
    """
    Test Controller.enable_feature with valid and invalid inputs.
    """

    if test.runner.require_control(self):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      if not test.runner.require_version(self, stem.version.Version("0.1.2.2-alpha")):
        controller.enable_feature("VERBOSE_NAMES")

      self.assertTrue(controller.is_feature_enabled("VERBOSE_NAMES"))

      orconn_output = controller.get_info('orconn-status')

      # the orconn-status results will be empty if we don't have a connection
      if orconn_output == '':
        if test.runner.require_online(self):
          return

      self.assertTrue("VERBOSE_NAMES" in controller._enabled_features)
      self.assertRaises(stem.InvalidArguments, controller.enable_feature, ["NOT", "A", "FEATURE"])

      try:
        controller.enable_feature(["NOT", "A", "FEATURE"])
      except stem.InvalidArguments as exc:
        self.assertEqual(["NOT"], exc.arguments)
      else:
        self.fail()
示例#17
0
    def test_get_network_statuses(self):
        """
    Fetches a few descriptors via the get_network_statuses() method.
    """

        runner = test.runner.get_runner()

        if test.runner.require_control(self):
            return

        with runner.get_tor_controller() as controller:
            count = 0

            for desc in controller.get_network_statuses():
                self.assertTrue(desc.fingerprint is not None)
                self.assertTrue(desc.nickname is not None)

                unrecognized_lines = desc.get_unrecognized_lines()

                if unrecognized_lines:
                    self.fail('Unrecognized descriptor content: %s' %
                              unrecognized_lines)

                count += 1
                if count > 10:
                    break
示例#18
0
文件: controller.py 项目: eoinof/stem
 def test_get_server_descriptor(self):
   """
   Compares get_server_descriptor() against our cached descriptors.
   """
   
   runner = test.runner.get_runner()
   descriptor_path = runner.get_test_dir("cached-descriptors")
   
   if test.runner.require_control(self): return
   elif not os.path.exists(descriptor_path):
     test.runner.skip(self, "(no cached descriptors)")
     return
   
   with runner.get_tor_controller() as controller:
     # we should balk at invalid content
     self.assertRaises(ValueError, controller.get_server_descriptor, None)
     self.assertRaises(ValueError, controller.get_server_descriptor, "")
     self.assertRaises(ValueError, controller.get_server_descriptor, 5)
     self.assertRaises(ValueError, controller.get_server_descriptor, "z" * 30)
     
     # try with a relay that doesn't exist
     self.assertRaises(stem.socket.ControllerError, controller.get_server_descriptor, "blargg")
     self.assertRaises(stem.socket.ControllerError, controller.get_server_descriptor, "5" * 40)
     
     first_descriptor = None
     with stem.descriptor.reader.DescriptorReader([descriptor_path]) as reader:
       for desc in reader:
         if desc.nickname != "Unnamed":
           first_descriptor = desc
           break
     
     self.assertEqual(first_descriptor, controller.get_server_descriptor(first_descriptor.fingerprint))
     self.assertEqual(first_descriptor, controller.get_server_descriptor(first_descriptor.nickname))
示例#19
0
文件: controller.py 项目: ouzel/stem
  def test_get_network_statuses(self):
    """
    Fetches a few descriptors via the get_network_statuses() method.
    """

    runner = test.runner.get_runner()

    if test.runner.require_control(self):
      return

    with runner.get_tor_controller() as controller:
      count = 0

      for desc in controller.get_network_statuses():
        self.assertTrue(desc.fingerprint is not None)
        self.assertTrue(desc.nickname is not None)

        unrecognized_lines = desc.get_unrecognized_lines()

        if unrecognized_lines:
          self.fail("Unrecognized descriptor content: %s" % unrecognized_lines)

        count += 1
        if count > 10:
          break
示例#20
0
    def test_loadconf(self):
        """
    Exercises Controller.load_conf with valid and invalid requests.
    """

        if test.runner.require_control(self):
            return
        elif test.runner.require_version(self,
                                         stem.version.Requirement.LOADCONF):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            oldconf = runner.get_torrc_contents()

            try:
                # invalid requests
                self.assertRaises(stem.InvalidRequest, controller.load_conf,
                                  "ContactInfo confloaded")

                try:
                    controller.load_conf("Blahblah blah")
                    self.fail()
                except stem.InvalidArguments, exc:
                    self.assertEqual(["Blahblah"], exc.arguments)

                # valid config

                controller.load_conf(runner.get_torrc_contents() +
                                     "\nContactInfo confloaded\n")
                self.assertEqual("confloaded",
                                 controller.get_conf("ContactInfo"))
            finally:
示例#21
0
  def test_protocolinfo(self):
    """
    Test that the convenient method protocolinfo() works.
    """

    if test.runner.require_control(self):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller(False) as controller:
      protocolinfo = controller.get_protocolinfo()
      self.assertTrue(isinstance(protocolinfo, stem.response.protocolinfo.ProtocolInfoResponse))

      # Doing a sanity test on the ProtocolInfoResponse instance returned.
      tor_options = runner.get_options()
      tor_version = runner.get_tor_version()
      auth_methods = []

      if test.runner.Torrc.COOKIE in tor_options:
        auth_methods.append(stem.response.protocolinfo.AuthMethod.COOKIE)

        if tor_version >= stem.version.Requirement.AUTH_SAFECOOKIE:
          auth_methods.append(stem.response.protocolinfo.AuthMethod.SAFECOOKIE)

      if test.runner.Torrc.PASSWORD in tor_options:
        auth_methods.append(stem.response.protocolinfo.AuthMethod.PASSWORD)

      if not auth_methods:
        auth_methods.append(stem.response.protocolinfo.AuthMethod.NONE)

      self.assertEqual(tuple(auth_methods), protocolinfo.auth_methods)
示例#22
0
  def test_loadconf(self):
    """
    Exercises Controller.load_conf with valid and invalid requests.
    """

    if test.runner.require_control(self):
      return
    elif test.runner.require_version(self, stem.version.Requirement.LOADCONF):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      oldconf = runner.get_torrc_contents()

      try:
        # invalid requests
        self.assertRaises(stem.InvalidRequest, controller.load_conf, "ContactInfo confloaded")

        try:
          controller.load_conf("Blahblah blah")
          self.fail()
        except stem.InvalidArguments as exc:
          self.assertEqual(["Blahblah"], exc.arguments)

        # valid config

        controller.load_conf(runner.get_torrc_contents() + "\nContactInfo confloaded\n")
        self.assertEqual("confloaded", controller.get_conf("ContactInfo"))
      finally:
        # reload original valid config
        controller.load_conf(oldconf)
示例#23
0
文件: controller.py 项目: ouzel/stem
  def test_get_server_descriptors(self):
    """
    Fetches a few descriptors via the get_server_descriptors() method.
    """

    runner = test.runner.get_runner()

    if test.runner.require_control(self):
      return
    elif runner.get_tor_version() >= Requirement.MICRODESCRIPTOR_IS_DEFAULT:
      test.runner.skip(self, "(requires server descriptors)")
      return

    with runner.get_tor_controller() as controller:
      count = 0

      for desc in controller.get_server_descriptors():
        self.assertTrue(desc.fingerprint is not None)
        self.assertTrue(desc.nickname is not None)

        # Se don't want to take the time to read the whole thing. We already
        # have another test that reads the full cached descriptors (and takes a
        # while to do so).

        count += 1
        if count > 10:
          break
示例#24
0
  def test_get_streams(self):
    """
    Tests Controller.get_streams().
    """

    if test.runner.require_control(self):
      return
    elif test.runner.require_online(self):
      return

    host = "38.229.72.14"   # www.torproject.org
    port = 443

    runner = test.runner.get_runner()
    with runner.get_tor_controller() as controller:
      # we only need one proxy port, so take the first
      socks_listener = controller.get_socks_listeners()[0]

      with test.network.Socks(socks_listener) as s:
        s.settimeout(30)
        s.connect((host, port))
        streams = controller.get_streams()

    # Because we do not get a stream id when opening a stream,
    #  try to match the target for which we asked a stream.

    self.assertTrue("%s:%s" % (host, port) in [stream.target for stream in streams])
示例#25
0
    def test_get_listeners(self):
        """
    Test Controller.get_listeners against a running tor instance.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            self.assertEqual([], controller.get_listeners(Listener.OR))
            self.assertEqual([], controller.get_listeners(Listener.DIR))
            self.assertEqual([('127.0.0.1', test.runner.SOCKS_PORT)],
                             controller.get_listeners(Listener.SOCKS))
            self.assertEqual([], controller.get_listeners(Listener.TRANS))
            self.assertEqual([], controller.get_listeners(Listener.NATD))
            self.assertEqual([], controller.get_listeners(Listener.DNS))

            if test.runner.Torrc.PORT in runner.get_options():
                self.assertEqual([('127.0.0.1', test.runner.CONTROL_PORT)],
                                 controller.get_listeners(Listener.CONTROL))
            else:
                self.assertEqual([],
                                 controller.get_listeners(Listener.CONTROL))
示例#26
0
    def test_enable_feature(self):
        """
    Test Controller.enable_feature with valid and invalid inputs.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            if not test.runner.require_version(
                    self, stem.version.Version('0.1.2.2-alpha')):
                controller.enable_feature('VERBOSE_NAMES')

            self.assertTrue(controller.is_feature_enabled('VERBOSE_NAMES'))

            orconn_output = controller.get_info('orconn-status')

            # the orconn-status results will be empty if we don't have a connection
            if orconn_output == '':
                if test.runner.require_online(self):
                    return

            self.assertTrue('VERBOSE_NAMES' in controller._enabled_features)
            self.assertRaises(stem.InvalidArguments, controller.enable_feature,
                              ['NOT', 'A', 'FEATURE'])

            try:
                controller.enable_feature(['NOT', 'A', 'FEATURE'])
            except stem.InvalidArguments as exc:
                self.assertEqual(['NOT'], exc.arguments)
            else:
                self.fail()
示例#27
0
  def test_repurpose_circuit(self):
    """
    Tests Controller.repurpose_circuit with valid and invalid input.
    """

    if test.runner.require_control(self):
      return
    elif test.runner.require_online(self):
      return
    elif test.runner.require_version(self, Requirement.EXTENDCIRCUIT_PATH_OPTIONAL):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      circ_id = controller.new_circuit()
      controller.repurpose_circuit(circ_id, "CONTROLLER")
      circuit = controller.get_circuit(circ_id)
      self.assertTrue(circuit.purpose == "CONTROLLER")

      controller.repurpose_circuit(circ_id, "GENERAL")
      circuit = controller.get_circuit(circ_id)
      self.assertTrue(circuit.purpose == "GENERAL")

      self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, 'f934h9f3h4', "fooo")
      self.assertRaises(stem.InvalidRequest, controller.repurpose_circuit, '4', "fooo")
示例#28
0
    def test_repurpose_circuit(self):
        """
    Tests Controller.repurpose_circuit with valid and invalid input.
    """

        if test.runner.require_control(self):
            return
        elif test.runner.require_online(self):
            return
        elif test.runner.require_version(
                self, Requirement.EXTENDCIRCUIT_PATH_OPTIONAL):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            circ_id = controller.new_circuit()
            controller.repurpose_circuit(circ_id, 'CONTROLLER')
            circuit = controller.get_circuit(circ_id)
            self.assertTrue(circuit.purpose == 'CONTROLLER')

            controller.repurpose_circuit(circ_id, 'GENERAL')
            circuit = controller.get_circuit(circ_id)
            self.assertTrue(circuit.purpose == 'GENERAL')

            self.assertRaises(stem.InvalidRequest,
                              controller.repurpose_circuit, 'f934h9f3h4',
                              'fooo')
            self.assertRaises(stem.InvalidRequest,
                              controller.repurpose_circuit, '4', 'fooo')
示例#29
0
    def test_event_handling(self):
        """
    Add a couple listeners for various events and make sure that they receive
    them. Then remove the listeners.
    """

        if test.runner.require_control(self):
            return

        event_notice1, event_notice2 = threading.Event(), threading.Event()
        event_buffer1, event_buffer2 = [], []

        def listener1(event):
            event_buffer1.append(event)
            event_notice1.set()

        def listener2(event):
            event_buffer2.append(event)
            event_notice2.set()

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            controller.add_event_listener(listener1, EventType.BW)
            controller.add_event_listener(listener2, EventType.BW,
                                          EventType.DEBUG)

            # BW events occure at the rate of one per second, so wait a bit to let
            # some accumulate.

            event_notice1.wait(4)
            self.assertTrue(len(event_buffer1) >= 1)
            event_notice1.clear()

            event_notice2.wait(4)
            self.assertTrue(len(event_buffer2) >= 1)
            event_notice2.clear()

            # Checking that a listener's no longer called after being removed.

            controller.remove_event_listener(listener2)

            buffer2_size = len(event_buffer2)

            event_notice1.wait(4)
            self.assertTrue(len(event_buffer1) >= 2)

            event_notice2.wait(4)
            self.assertEqual(buffer2_size, len(event_buffer2))

            for event in event_buffer1:
                self.assertTrue(isinstance(event, stem.response.events.Event))
                self.assertEqual(2, len(event.positional_args))
                self.assertEqual({}, event.keyword_args)

                self.assertTrue(
                    isinstance(event, stem.response.events.BandwidthEvent))
                self.assertTrue(hasattr(event, 'read'))
                self.assertTrue(hasattr(event, 'written'))
示例#30
0
  def test_event_handling(self):
    """
    Add a couple listeners for various events and make sure that they receive
    them. Then remove the listeners.
    """

    if test.runner.require_control(self):
      return

    event_notice1, event_notice2 = threading.Event(), threading.Event()
    event_buffer1, event_buffer2 = [], []

    def listener1(event):
      event_buffer1.append(event)
      event_notice1.set()

    def listener2(event):
      event_buffer2.append(event)
      event_notice2.set()

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      controller.add_event_listener(listener1, EventType.BW)
      controller.add_event_listener(listener2, EventType.BW, EventType.DEBUG)

      # BW events occure at the rate of one per second, so wait a bit to let
      # some accumulate.

      event_notice1.wait(2)
      self.assertTrue(len(event_buffer1) >= 1)
      event_notice1.clear()

      event_notice2.wait(2)
      self.assertTrue(len(event_buffer2) >= 1)
      event_notice2.clear()

      # Checking that a listener's no longer called after being removed.

      controller.remove_event_listener(listener2)

      buffer2_size = len(event_buffer2)

      event_notice1.wait(2)
      self.assertTrue(len(event_buffer1) >= 2)

      event_notice2.wait(2)
      self.assertEqual(buffer2_size, len(event_buffer2))

      for event in event_buffer1:
        self.assertTrue(isinstance(event, stem.response.events.Event))
        self.assertEqual(2, len(event.positional_args))
        self.assertEqual({}, event.keyword_args)

        self.assertTrue(isinstance(event, stem.response.events.BandwidthEvent))
        self.assertTrue(hasattr(event, 'read'))
        self.assertTrue(hasattr(event, 'written'))
示例#31
0
 def test_authenticate_general_controller(self):
   """
   Tests that the authenticate function can authenticate via a Controller.
   """
   
   runner = test.runner.get_runner()
   with runner.get_tor_controller(False) as controller:
     stem.connection.authenticate(controller, test.runner.CONTROL_PASSWORD, runner.get_chroot())
     test.runner.exercise_controller(self, controller)
示例#32
0
  def test_event_handling(self):
    """
    Add a couple listeners for various events and make sure that they receive
    them. Then remove the listeners.
    """

    event_notice1, event_notice2 = threading.Event(), threading.Event()
    event_buffer1, event_buffer2 = [], []

    def listener1(event):
      event_buffer1.append(event)
      event_notice1.set()

    def listener2(event):
      event_buffer2.append(event)
      event_notice2.set()

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      controller.add_event_listener(listener1, EventType.CONF_CHANGED)
      controller.add_event_listener(listener2, EventType.CONF_CHANGED, EventType.DEBUG)

      # The NodeFamily is a harmless option we can toggle
      controller.set_conf('NodeFamily', 'FD4CC275C5AA4D27A487C6CA29097900F85E2C33')

      # Wait for the event. Assert that we get it within 10 seconds
      event_notice1.wait(10)
      self.assertEqual(len(event_buffer1), 1)
      event_notice1.clear()

      event_notice2.wait(10)
      self.assertTrue(len(event_buffer2) >= 1)
      event_notice2.clear()

      # Checking that a listener's no longer called after being removed.

      controller.remove_event_listener(listener2)

      buffer2_size = len(event_buffer2)

      controller.set_conf('NodeFamily', 'A82F7EFDB570F6BC801805D0328D30A99403C401')
      event_notice1.wait(10)
      self.assertEqual(len(event_buffer1), 2)
      event_notice1.clear()

      self.assertEqual(buffer2_size, len(event_buffer2))

      for event in event_buffer1:
        self.assertTrue(isinstance(event, stem.response.events.Event))
        self.assertEqual(0, len(event.positional_args))
        self.assertEqual({}, event.keyword_args)

        self.assertTrue(isinstance(event, stem.response.events.ConfChangedEvent))

      controller.reset_conf('NodeFamily')
示例#33
0
文件: controller.py 项目: eoinof/stem
 def test_getconf(self):
   """
   Exercises GETCONF with valid and invalid queries.
   """
   
   if test.runner.require_control(self): return
   
   runner = test.runner.get_runner()
   
   with runner.get_tor_controller() as controller:
     socket = controller.get_socket()
     if isinstance(socket, stem.socket.ControlPort):
       connection_value = str(socket.get_port())
       config_key = "ControlPort"
     elif isinstance(socket, stem.socket.ControlSocketFile):
       connection_value = str(socket.get_socket_path())
       config_key = "ControlSocket"
     
     # successful single query
     self.assertEqual(connection_value, controller.get_conf(config_key))
     self.assertEqual(connection_value, controller.get_conf(config_key, "la-di-dah"))
     
     # succeessful batch query
     expected = {config_key: [connection_value]}
     self.assertEqual(expected, controller.get_conf_map([config_key]))
     self.assertEqual(expected, controller.get_conf_map([config_key], "la-di-dah"))
     
     request_params = ["ControlPORT", "dirport", "datadirectory"]
     reply_params = controller.get_conf_map(request_params, multiple=False).keys()
     self.assertEqual(set(request_params), set(reply_params))
     
     # non-existant option(s)
     self.assertRaises(stem.socket.InvalidArguments, controller.get_conf, "blarg")
     self.assertEqual("la-di-dah", controller.get_conf("blarg", "la-di-dah"))
     self.assertRaises(stem.socket.InvalidArguments, controller.get_conf_map, "blarg")
     self.assertEqual("la-di-dah", controller.get_conf_map("blarg", "la-di-dah"))
     
     self.assertRaises(stem.socket.InvalidRequest, controller.get_conf_map, ["blarg", "huadf"], multiple = True)
     self.assertEqual("la-di-dah", controller.get_conf_map(["erfusdj", "afiafj"], "la-di-dah", multiple = True))
     
     # multivalue configuration keys
     nodefamilies = [("abc", "xyz", "pqrs"), ("mno", "tuv", "wxyz")]
     controller.msg("SETCONF %s" % " ".join(["nodefamily=\"" + ",".join(x) + "\"" for x in nodefamilies]))
     self.assertEqual([",".join(n) for n in nodefamilies], controller.get_conf("nodefamily", multiple = True))
     controller.msg("RESETCONF NodeFamily")
     
     # empty input
     self.assertEqual(None, controller.get_conf(""))
     self.assertEqual({}, controller.get_conf_map([]))
     self.assertEqual({}, controller.get_conf_map([""]))
     self.assertEqual(None, controller.get_conf("          "))
     self.assertEqual({}, controller.get_conf_map(["    ", "        "]))
     
     self.assertEqual("la-di-dah", controller.get_conf("", "la-di-dah"))
     self.assertEqual({}, controller.get_conf_map("", "la-di-dah"))
     self.assertEqual({}, controller.get_conf_map([], "la-di-dah"))
示例#34
0
 def test_get_socks_ports(self):
   """
   Test Controller.get_socks_ports against a running tor instance.
   """
   if test.runner.require_control(self): return
   
   runner = test.runner.get_runner()
   
   with runner.get_tor_controller() as controller:
     self.assertEqual([('127.0.0.1', 1112)], controller.get_socks_listeners())
示例#35
0
  def test_authenticate(self):
    """
    Test that the convenient method authenticate() works.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller(False) as controller:
      controller.authenticate(test.runner.CONTROL_PASSWORD)
      test.runner.exercise_controller(self, controller)
示例#36
0
  def test_rejecting_unanonymous_hidden_services_creation(self):
    """
    Attempt to create a non-anonymous hidden service despite not setting
    HiddenServiceSingleHopMode and HiddenServiceNonAnonymousMode.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      self.assertEqual('Tor is in anonymous hidden service mode', str(controller.msg('ADD_ONION NEW:BEST Flags=NonAnonymous Port=4567')))
示例#37
0
  def test_authenticate_general_controller(self):
    """
    Tests that the authenticate function can authenticate via a Controller.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller(False) as controller:
      stem.connection.authenticate(controller, test.runner.CONTROL_PASSWORD, runner.get_chroot())
      test.runner.exercise_controller(self, controller)
示例#38
0
  def test_get_version(self):
    """
    Test that the convenient method get_version() works.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      version = controller.get_version()
      self.assertTrue(isinstance(version, stem.version.Version))
      self.assertEqual(version, test.tor_version())
示例#39
0
  def test_with_ephemeral_hidden_services_basic_auth_no_credentials(self):
    """
    Exercises creating ephemeral hidden services when attempting to use basic
    auth but not including any credentials.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      exc_msg = "ADD_ONION response didn't have an OK status: No auth clients specified"
      self.assertRaisesRegexp(stem.ProtocolError, exc_msg, controller.create_ephemeral_hidden_service, 4567, basic_auth = {})
示例#40
0
    def test_set_conf(self):
        """
    Exercises set_conf(), reset_conf(), and set_options() methods with valid
    and invalid requests.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()
        tmpdir = tempfile.mkdtemp()

        with runner.get_tor_controller() as controller:
            try:
                # successfully set a single option
                connlimit = int(controller.get_conf("ConnLimit"))
                controller.set_conf("connlimit", str(connlimit - 1))
                self.assertEqual(connlimit - 1, int(controller.get_conf("ConnLimit")))

                # successfully set a single list option
                exit_policy = ["accept *:7777", "reject *:*"]
                controller.set_conf("ExitPolicy", exit_policy)
                self.assertEqual(exit_policy, controller.get_conf("ExitPolicy", multiple=True))

                # fail to set a single option
                try:
                    controller.set_conf("invalidkeyboo", "abcde")
                    self.fail()
                except stem.InvalidArguments, exc:
                    self.assertEqual(["invalidkeyboo"], exc.arguments)

                # resets configuration parameters
                controller.reset_conf("ConnLimit", "ExitPolicy")
                self.assertEqual(connlimit, int(controller.get_conf("ConnLimit")))
                self.assertEqual(None, controller.get_conf("ExitPolicy"))

                # successfully sets multiple config options
                controller.set_options({"connlimit": str(connlimit - 2), "contactinfo": "stem@testing"})

                self.assertEqual(connlimit - 2, int(controller.get_conf("ConnLimit")))
                self.assertEqual("stem@testing", controller.get_conf("contactinfo"))

                # fail to set multiple config options
                try:
                    controller.set_options({"contactinfo": "stem@testing", "bombay": "vadapav"})
                    self.fail()
                except stem.InvalidArguments, exc:
                    self.assertEqual(["bombay"], exc.arguments)

                # context-sensitive keys (the only retched things for which order matters)
                controller.set_options((("HiddenServiceDir", tmpdir), ("HiddenServicePort", "17234 127.0.0.1:17235")))

                self.assertEqual(tmpdir, controller.get_conf("HiddenServiceDir"))
                self.assertEqual("17234 127.0.0.1:17235", controller.get_conf("HiddenServicePort"))
示例#41
0
  def test_get_socks_ports(self):
    """
    Test Controller.get_socks_ports against a running tor instance.
    """

    if test.runner.require_control(self):
      return

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      self.assertEqual([('127.0.0.1', 1112)], controller.get_socks_listeners())
示例#42
0
    def test_get_network_status(self):
        """
    Compares get_network_status() against our cached descriptors.
    """

        runner = test.runner.get_runner()
        descriptor_path = runner.get_test_dir("cached-consensus")

        if test.runner.require_control(self):
            return
        elif not os.path.exists(descriptor_path):
            test.runner.skip(self, "(no cached descriptors)")
            return

        with runner.get_tor_controller() as controller:
            # we should balk at invalid content
            self.assertRaises(ValueError, controller.get_network_status, None)
            self.assertRaises(ValueError, controller.get_network_status, "")
            self.assertRaises(ValueError, controller.get_network_status, 5)
            self.assertRaises(ValueError, controller.get_network_status,
                              "z" * 30)

            # try with a relay that doesn't exist
            self.assertRaises(stem.ControllerError,
                              controller.get_network_status, "blargg")
            self.assertRaises(stem.ControllerError,
                              controller.get_network_status, "5" * 40)

            # our cached consensus is v3 but the control port can only be queried for
            # v2 or v1 network status information

            test.runner.skip(self, "(https://trac.torproject.org/7163)")
            return

            first_descriptor = None
            with stem.descriptor.reader.DescriptorReader([descriptor_path
                                                          ]) as reader:
                for desc in reader:
                    if desc.nickname != "Unnamed":
                        # truncate to just the first couple lines and reconstruct as a v2 entry
                        truncated_content = "\n".join(
                            str(desc).split("\n")[:2])

                        first_descriptor = stem.descriptor.router_status_entry.RouterStatusEntryV2(
                            truncated_content)
                        break

            self.assertEqual(
                first_descriptor,
                controller.get_network_status(first_descriptor.fingerprint))
            self.assertEqual(
                first_descriptor,
                controller.get_network_status(first_descriptor.nickname))
示例#43
0
    def test_authenticate(self):
        """
    Test that the convenient method authenticate() works.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller(False) as controller:
            controller.authenticate(test.runner.CONTROL_PASSWORD)
            test.runner.exercise_controller(self, controller)
示例#44
0
 def test_get_circuits(self):
   """
   Fetches circuits via the get_circuits() method.
   """
   
   if test.runner.require_control(self): return
   elif test.runner.require_online(self): return
   elif test.runner.require_version(self, Requirement.EXTENDCIRCUIT_PATH_OPTIONAL): return
   
   runner = test.runner.get_runner()
   with runner.get_tor_controller() as controller:
     new_circ = controller.new_circuit()
     circuits = controller.get_circuits()
     self.assertTrue(new_circ in [circ.id for circ in circuits])
示例#45
0
    def test_get_version(self):
        """
    Test that the convenient method get_version() works.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            version = controller.get_version()
            self.assertTrue(isinstance(version, stem.version.Version))
            self.assertEqual(version, runner.get_tor_version())
示例#46
0
    def test_mapaddress(self):
        if test.runner.require_control(self):
            return
        elif test.runner.require_online(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            controller.map_address({'1.2.1.2': 'ifconfig.me'})

            s = None
            response = None

            # try up to 10 times to rule out transient network failures

            for _ in xrange(10):
                try:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.settimeout(30)
                    s.connect(
                        ('127.0.0.1',
                         int(
                             controller.get_conf('SocksListenAddress').rsplit(
                                 ':', 1)[1])))
                    test.network.negotiate_socks(s, '1.2.1.2', 80)
                    s.sendall(
                        stem.util.str_tools._to_bytes(test.network.ip_request)
                    )  # make the http request for the ip address
                    response = s.recv(1000)

                    if response:
                        break
                except (stem.ProtocolError, socket.timeout):
                    continue
                finally:
                    if s:
                        s.close()

            self.assertTrue(response)

            # everything after the blank line is the 'data' in a HTTP response.
            # The response data for our request for request should be an IP address + '\n'

            ip_addr = response[response.find(b'\r\n\r\n'):].strip()
            self.assertTrue(
                stem.util.connection.is_valid_ipv4_address(
                    stem.util.str_tools._to_unicode(ip_addr)))
示例#47
0
  def test_wrong_password_with_controller(self):
    """
    We ran into a race condition where providing the wrong password to the
    Controller caused inconsistent responses. Checking for that...

    https://trac.torproject.org/projects/tor/ticket/22679
    """

    runner = test.runner.get_runner()

    if test.runner.Torrc.PASSWORD not in runner.get_options() or test.runner.Torrc.COOKIE in runner.get_options():
      self.skipTest('(requires only password auth)')

    for i in range(10):
      with runner.get_tor_controller(False) as controller:
        self.assertRaises(stem.connection.IncorrectPassword, controller.authenticate, 'wrong_password')
示例#48
0
  def test_with_ephemeral_hidden_services_basic_auth(self):
    """
    Exercises creating ephemeral hidden services that uses basic authentication.
    """

    runner = test.runner.get_runner()

    with runner.get_tor_controller() as controller:
      response = controller.create_ephemeral_hidden_service(4567, basic_auth = {'alice': 'nKwfvVPmTNr2k2pG0pzV4g', 'bob': None})
      self.assertEqual([response.service_id], controller.list_ephemeral_hidden_services())
      self.assertTrue(response.private_key is not None)
      self.assertEqual(['bob'], list(response.client_auth.keys()))  # newly created credentials were only created for bob

      # drop the service

      self.assertEqual(True, controller.remove_ephemeral_hidden_service(response.service_id))
      self.assertEqual([], controller.list_ephemeral_hidden_services())
示例#49
0
  def test_get_circuits(self):
    """
    Fetches circuits via the get_circuits() method.
    """

    if test.runner.require_control(self):
      return
    elif test.runner.require_online(self):
      return
    elif test.runner.require_version(self, Requirement.EXTENDCIRCUIT_PATH_OPTIONAL):
      return

    runner = test.runner.get_runner()
    with runner.get_tor_controller() as controller:
      new_circ = controller.new_circuit()
      circuits = controller.get_circuits()
      self.assertTrue(new_circ in [circ.id for circ in circuits])
示例#50
0
    def test_get_server_descriptor(self):
        """
    Compares get_server_descriptor() against our cached descriptors.
    """

        runner = test.runner.get_runner()
        descriptor_path = runner.get_test_dir("cached-descriptors")

        if test.runner.require_control(self):
            return
        elif not os.path.exists(descriptor_path):
            test.runner.skip(self, "(no cached descriptors)")
            return

        with runner.get_tor_controller() as controller:
            # we should balk at invalid content
            self.assertRaises(ValueError, controller.get_server_descriptor,
                              None)
            self.assertRaises(ValueError, controller.get_server_descriptor, "")
            self.assertRaises(ValueError, controller.get_server_descriptor, 5)
            self.assertRaises(ValueError, controller.get_server_descriptor,
                              "z" * 30)

            # try with a relay that doesn't exist
            self.assertRaises(stem.ControllerError,
                              controller.get_server_descriptor, "blargg")
            self.assertRaises(stem.ControllerError,
                              controller.get_server_descriptor, "5" * 40)

            test.runner.skip(self, "(https://trac.torproject.org/7163)")
            return

            first_descriptor = None
            with stem.descriptor.reader.DescriptorReader([descriptor_path
                                                          ]) as reader:
                for desc in reader:
                    if desc.nickname != "Unnamed":
                        first_descriptor = desc
                        break

            self.assertEqual(
                first_descriptor,
                controller.get_server_descriptor(first_descriptor.fingerprint))
            self.assertEqual(
                first_descriptor,
                controller.get_server_descriptor(first_descriptor.nickname))
示例#51
0
  def test_wrong_password_with_controller(self):
    """
    We ran into a race condition where providing the wrong password to the
    Controller caused inconsistent responses. Checking for that...

    https://trac.torproject.org/projects/tor/ticket/22679
    """

    runner = test.runner.get_runner()

    if test.runner.Torrc.PASSWORD not in runner.get_options() or test.runner.Torrc.COOKIE in runner.get_options():
      self.skipTest('(requires only password auth)')
      return

    for i in range(10):
      with runner.get_tor_controller(False) as controller:
        self.assertRaises(stem.connection.IncorrectPassword, controller.authenticate, 'wrong_password')
示例#52
0
    def test_getinfo(self):
        """
    Exercises GETINFO with valid and invalid queries.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            # successful single query

            torrc_path = runner.get_torrc_path()
            self.assertEqual(torrc_path, controller.get_info('config-file'))
            self.assertEqual(torrc_path,
                             controller.get_info('config-file', 'ho hum'))

            expected = {'config-file': torrc_path}
            self.assertEqual(expected, controller.get_info(['config-file']))
            self.assertEqual(expected,
                             controller.get_info(['config-file'], 'ho hum'))

            # successful batch query, we don't know the values so just checking for
            # the keys

            getinfo_params = set(['version', 'config-file', 'config/names'])
            self.assertEqual(
                getinfo_params,
                set(
                    controller.get_info(
                        ['version', 'config-file', 'config/names']).keys()))

            # non-existant option

            self.assertRaises(stem.ControllerError, controller.get_info,
                              'blarg')
            self.assertEqual('ho hum', controller.get_info('blarg', 'ho hum'))

            # empty input

            self.assertRaises(stem.ControllerError, controller.get_info, '')
            self.assertEqual('ho hum', controller.get_info('', 'ho hum'))

            self.assertEqual({}, controller.get_info([]))
            self.assertEqual({}, controller.get_info([], {}))
示例#53
0
    def test_get_exit_policy(self):
        """
    Sanity test for get_exit_policy(). We have the default policy (no
    ExitPolicy set) which is a little... long due to the boilerplate.
    """

        if test.runner.require_control(self):
            return

        expected = ExitPolicy(
            'reject 0.0.0.0/8:*',
            'reject 169.254.0.0/16:*',
            'reject 127.0.0.0/8:*',
            'reject 192.168.0.0/16:*',
            'reject 10.0.0.0/8:*',
            'reject 172.16.0.0/12:*',
            # this is where 'reject [public_addr]:*' may or may not be
            'reject *:25',
            'reject *:119',
            'reject *:135-139',
            'reject *:445',
            'reject *:563',
            'reject *:1214',
            'reject *:4661-4666',
            'reject *:6346-6429',
            'reject *:6699',
            'reject *:6881-6999',
            'accept *:*',
        )

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            # We can't simply compare the policies because the tor policy may or may
            # not have a reject entry for our public address. Hence, stripping it
            # from the policy's string, then comparing those.

            policy_str = str(controller.get_exit_policy())

            public_addr_start = policy_str.find('reject 172.16.0.0/12:*') + 22
            public_addr_end = policy_str.find(', reject *:25')

            policy_str = policy_str[:public_addr_start] + policy_str[
                public_addr_end:]
            self.assertEqual(str(expected), policy_str)
示例#54
0
 def test_saveconf(self):
   if test.runner.require_control(self): return
   
   runner = test.runner.get_runner()
   
   # only testing for success, since we need to run out of disk space to test
   # for failure
   with runner.get_tor_controller() as controller:
     oldconf = runner.get_torrc_contents()
     
     try:
       controller.set_conf("ContactInfo", "confsaved")
       controller.save_conf()
       with file(runner.get_torrc_path()) as torrcfile:
         self.assertTrue("\nContactInfo confsaved\n" in torrcfile.read())
     finally:
       controller.load_conf(oldconf)
       controller.save_conf()
示例#55
0
    def test_loadconf(self):
        """
    Exercises Controller.load_conf with valid and invalid requests.
    """

        if test.runner.require_control(self):
            return
        elif test.runner.require_version(self,
                                         stem.version.Requirement.LOADCONF):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            oldconf = runner.get_torrc_contents()

            try:
                # Check a request that changes our DataDir. Tor should rightfully balk
                # at this...
                #
                #   InvalidRequest: Transition not allowed: Failed to parse/validate
                #   config: While Tor is running, changing DataDirectory
                #   ("/home/atagar/Desktop/stem/test/data"->"/home/atagar/.tor") is not
                #   allowed.

                self.assertRaises(stem.InvalidRequest, controller.load_conf,
                                  'ContactInfo confloaded')

                try:
                    controller.load_conf('Blahblah blah')
                    self.fail()
                except stem.InvalidArguments as exc:
                    self.assertEqual(['Blahblah'], exc.arguments)

                # valid config

                controller.load_conf(runner.get_torrc_contents() +
                                     '\nContactInfo confloaded\n')
                self.assertEqual('confloaded',
                                 controller.get_conf('ContactInfo'))
            finally:
                # reload original valid config
                controller.load_conf(oldconf)
                controller.reset_conf('__OwningControllerProcess')
示例#56
0
    def test_saveconf(self):
        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()

        # only testing for success, since we need to run out of disk space to test
        # for failure
        with runner.get_tor_controller() as controller:
            oldconf = runner.get_torrc_contents()

            try:
                controller.set_conf("ContactInfo", "confsaved")
                controller.save_conf()

                with open(runner.get_torrc_path()) as torrcfile:
                    self.assertTrue(
                        "\nContactInfo confsaved\n" in torrcfile.read())
            finally:
                controller.load_conf(oldconf)
                controller.save_conf()
示例#57
0
    def test_get_microdescriptors(self):
        """
    Fetches a few descriptors via the get_microdescriptors() method.
    """

        runner = test.runner.get_runner()

        if test.runner.require_control(self):
            return
        elif not os.path.exists(runner.get_test_dir('cached-descriptors')):
            test.runner.skip(self, '(no cached microdescriptors)')
            return

        with runner.get_tor_controller() as controller:
            count = 0

            for desc in controller.get_microdescriptors():
                self.assertTrue(desc.onion_key is not None)

                count += 1
                if count > 10:
                    break
示例#58
0
    def test_set_conf(self):
        """
    Exercises set_conf(), reset_conf(), and set_options() methods with valid
    and invalid requests.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()
        tmpdir = tempfile.mkdtemp()

        with runner.get_tor_controller() as controller:
            try:
                # successfully set a single option
                connlimit = int(controller.get_conf('ConnLimit'))
                controller.set_conf('connlimit', str(connlimit - 1))
                self.assertEqual(connlimit - 1,
                                 int(controller.get_conf('ConnLimit')))

                # successfully set a single list option
                exit_policy = ['accept *:7777', 'reject *:*']
                controller.set_conf('ExitPolicy', exit_policy)
                self.assertEqual(
                    exit_policy,
                    controller.get_conf('ExitPolicy', multiple=True))

                # fail to set a single option
                try:
                    controller.set_conf('invalidkeyboo', 'abcde')
                    self.fail()
                except stem.InvalidArguments as exc:
                    self.assertEqual(['invalidkeyboo'], exc.arguments)

                # resets configuration parameters
                controller.reset_conf('ConnLimit', 'ExitPolicy')
                self.assertEqual(connlimit,
                                 int(controller.get_conf('ConnLimit')))
                self.assertEqual(None, controller.get_conf('ExitPolicy'))

                # successfully sets multiple config options
                controller.set_options({
                    'connlimit': str(connlimit - 2),
                    'contactinfo': 'stem@testing',
                })

                self.assertEqual(connlimit - 2,
                                 int(controller.get_conf('ConnLimit')))
                self.assertEqual('stem@testing',
                                 controller.get_conf('contactinfo'))

                # fail to set multiple config options
                try:
                    controller.set_options({
                        'contactinfo': 'stem@testing',
                        'bombay': 'vadapav',
                    })
                    self.fail()
                except stem.InvalidArguments as exc:
                    self.assertEqual(['bombay'], exc.arguments)

                # context-sensitive keys (the only retched things for which order matters)
                controller.set_options((
                    ('HiddenServiceDir', tmpdir),
                    ('HiddenServicePort', '17234 127.0.0.1:17235'),
                ))

                self.assertEqual(tmpdir,
                                 controller.get_conf('HiddenServiceDir'))
                self.assertEqual('17234 127.0.0.1:17235',
                                 controller.get_conf('HiddenServicePort'))
            finally:
                # reverts configuration changes
                controller.set_options((
                    ('ExitPolicy', 'reject *:*'),
                    ('ConnLimit', None),
                    ('ContactInfo', None),
                    ('HiddenServiceDir', None),
                    ('HiddenServicePort', None),
                ),
                                       reset=True)

                shutil.rmtree(tmpdir)
示例#59
0
    def test_getconf(self):
        """
    Exercises GETCONF with valid and invalid queries.
    """

        if test.runner.require_control(self):
            return

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            control_socket = controller.get_socket()

            if isinstance(control_socket, stem.socket.ControlPort):
                connection_value = str(control_socket.get_port())
                config_key = 'ControlPort'
            elif isinstance(control_socket, stem.socket.ControlSocketFile):
                connection_value = str(control_socket.get_socket_path())
                config_key = 'ControlSocket'

            # successful single query
            self.assertEqual(connection_value, controller.get_conf(config_key))
            self.assertEqual(connection_value,
                             controller.get_conf(config_key, 'la-di-dah'))

            # succeessful batch query
            expected = {config_key: [connection_value]}
            self.assertEqual(expected, controller.get_conf_map([config_key]))
            self.assertEqual(
                expected, controller.get_conf_map([config_key], 'la-di-dah'))

            request_params = ['ControlPORT', 'dirport', 'datadirectory']
            reply_params = controller.get_conf_map(request_params,
                                                   multiple=False).keys()
            self.assertEqual(set(request_params), set(reply_params))

            # queries an option that is unset

            self.assertEqual(None, controller.get_conf('HTTPSProxy'))
            self.assertEqual('la-di-dah',
                             controller.get_conf('HTTPSProxy', 'la-di-dah'))
            self.assertEqual([],
                             controller.get_conf('HTTPSProxy', [],
                                                 multiple=True))

            # non-existant option(s)
            self.assertRaises(stem.InvalidArguments, controller.get_conf,
                              'blarg')
            self.assertEqual('la-di-dah',
                             controller.get_conf('blarg', 'la-di-dah'))
            self.assertRaises(stem.InvalidArguments, controller.get_conf_map,
                              'blarg')
            self.assertEqual({'blarg': 'la-di-dah'},
                             controller.get_conf_map('blarg', 'la-di-dah'))

            self.assertRaises(stem.InvalidRequest,
                              controller.get_conf_map, ['blarg', 'huadf'],
                              multiple=True)
            self.assertEqual({
                'erfusdj': 'la-di-dah',
                'afiafj': 'la-di-dah'
            },
                             controller.get_conf_map(['erfusdj', 'afiafj'],
                                                     'la-di-dah',
                                                     multiple=True))

            # multivalue configuration keys
            nodefamilies = [('abc', 'xyz', 'pqrs'), ('mno', 'tuv', 'wxyz')]
            controller.msg('SETCONF %s' % ' '.join(
                ['nodefamily="' + ','.join(x) + '"' for x in nodefamilies]))
            self.assertEqual([','.join(n) for n in nodefamilies],
                             controller.get_conf('nodefamily', multiple=True))
            controller.msg('RESETCONF NodeFamily')

            # empty input
            self.assertEqual(None, controller.get_conf(''))
            self.assertEqual({}, controller.get_conf_map([]))
            self.assertEqual({}, controller.get_conf_map(['']))
            self.assertEqual(None, controller.get_conf('          '))
            self.assertEqual({}, controller.get_conf_map(['    ', '        ']))

            self.assertEqual('la-di-dah', controller.get_conf('', 'la-di-dah'))
            self.assertEqual({}, controller.get_conf_map('', 'la-di-dah'))
            self.assertEqual({}, controller.get_conf_map([], 'la-di-dah'))
示例#60
0
    def test_reattaching_listeners(self):
        """
    Checks that event listeners are re-attached when a controller disconnects
    then reconnects to tor.
    """

        if test.runner.require_control(self):
            return

        event_notice = threading.Event()
        event_buffer = []

        def listener(event):
            event_buffer.append(event)
            event_notice.set()

        runner = test.runner.get_runner()

        with runner.get_tor_controller() as controller:
            controller.add_event_listener(listener, EventType.BW)

            # Get a BW event or two. These should be emitted each second but under
            # heavy system load that's not always the case.

            event_notice.wait(4)
            self.assertTrue(len(event_buffer) >= 1)

            # disconnect and check that we stop getting events

            controller.close()
            event_notice.clear()
            event_buffer = []

            event_notice.wait(2)
            self.assertTrue(len(event_buffer) == 0)

            # reconnect and check that we get events again

            controller.connect()
            controller.authenticate(password=test.runner.CONTROL_PASSWORD)

            event_notice.wait(4)
            self.assertTrue(len(event_buffer) >= 1)

            # disconnect

            controller.close()
            event_notice.clear()
            event_buffer = []

            # reconnect and check that we get events again

            controller.connect()
            stem.connection.authenticate(controller,
                                         password=test.runner.CONTROL_PASSWORD)

            event_notice.wait(4)
            self.assertTrue(len(event_buffer) >= 1)

            # disconnect

            controller.close()
            event_notice.clear()
            event_buffer = []

            # Reconnect and check that we get events again. This is being done by
            # calling AUTHENTICATE manually so skipping cookie auth.

            tor_options = test.runner.get_runner().get_options()

            if not test.runner.Torrc.COOKIE in tor_options:
                controller.connect()

                if test.runner.Torrc.PASSWORD in tor_options:
                    controller.msg('AUTHENTICATE "%s"' %
                                   test.runner.CONTROL_PASSWORD)
                else:
                    controller.msg('AUTHENTICATE')

                event_notice.wait(4)
                self.assertTrue(len(event_buffer) >= 1)