[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [bridgedb/master] Deprecate b.Bridges.PluggableTransport for b.bridges.PluggableTransport.
commit eeb5b7c9d72a4758f8c5dc70b67c8233548c91bf
Author: Isis Lovecruft <isis@xxxxxxxxxxxxxx>
Date: Sun Sep 7 00:04:17 2014 +0000
Deprecate b.Bridges.PluggableTransport for b.bridges.PluggableTransport.
This replaces the legacy `bridgedb.Bridges.PluggableTransport` class,
which had several issues, including:
- `assert` statements without catching errors
- Cyclically referential data structures which contain __del__()
methods. (Which means that these structures cannot be garbage
collected!! see https://stackoverflow.com/a/10962484)
* ADD new `bridgedb.bridges` module for replacing old code in
`bridgedb.Bridges`.
* MOVE legacy implementation `bridgedb.Bridges.PluggableTransport` to
`bridgedb.test.deprecated` module for automated regression testing.
* ADD new implementation, `bridgedb.bridges.PluggableTransport`, which
is mostly backward-compatible with the old implementation, except
that instead of taking an entire `bridgedb.Bridges.Bridge` class as
its first argument, it takes just the uppercased, hexadecimal
fingerprint of that bridge. This was done because the legacy `Bridge`
and `PluggableTransport` classes posed a serialization problem due to
infinitely self-referencing eachother, i.e. the
`bridgedb.Bridges.Bridge.transports` attribute was a list of
`bridgedb.Bridges.PluggableTransport`s, which in turn referenced
their `bridgedb.Bridges.Bridge`, which referenced a list of
bridgedb.Bridges.PluggableTransport`s... turtles all the way down,
and they never get garbage collected, they just end up in Python's
`gc.garbage` list for "the programmer to manually deal with".
* FIXES part of #12505 https://bugs.torproject.org/12505
---
lib/bridgedb/Bridges.py | 104 -------------
lib/bridgedb/Main.py | 23 ++-
lib/bridgedb/bridges.py | 290 +++++++++++++++++++++++++++++++++++++
lib/bridgedb/test/deprecated.py | 112 ++++++++++++++
lib/bridgedb/test/test_Bridges.py | 7 +-
lib/bridgedb/test/test_Tests.py | 2 +
6 files changed, 424 insertions(+), 114 deletions(-)
diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py
index fa718c0..dead9f2 100644
--- a/lib/bridgedb/Bridges.py
+++ b/lib/bridgedb/Bridges.py
@@ -451,110 +451,6 @@ re_ipv6 = re.compile("\[([a-fA-F0-9:]+)\]:(.*$)")
re_ipv4 = re.compile("((?:\d{1,3}\.?){4}):(.*$)")
-class PluggableTransport(object):
- """A PT with reference to the parent bridge on which it is running."""
-
- def __init__(self, bridge, methodname, address, port, argdict=None):
- """Create a ``PluggableTransport`` describing a PT running on a bridge.
-
- Pluggable transports are described within a bridge's ``@type
- bridge-extrainfo`` descriptor, see the ``Specifications: Client
- behavior`` section and the ``TOR_PT_SERVER_TRANSPORT_OPTIONS``
- description in pt-spec.txt_ for additional specification.
-
- :type bridge: :class:`Bridge`
- :param bridge: The parent bridge running this pluggable transport
- instance, i.e. the main ORPort bridge whose
- ``@type bridge-server-descriptor`` contains a hash digest for a
- ``@type bridge-extrainfo-document``, the latter of which contains
- the parameter of this pluggable transport in its ``transport``
- line.
-
- :param str methodname: The canonical "name" for this pluggable
- transport, i.e. the one which would be specified in a torrc
- file. For example, ``"obfs2"``, ``"obfs3"``, ``"scramblesuit"``
- would all be pluggable transport method names.
-
- :param str address: The IP address of the transport. Currently (as of
- 20 March 2014), there are no known, widely-deployed pluggable
- transports which support IPv6. Ergo, this is very likely going to
- be an IPv4 address.
-
- :param int port: A integer specifying the port which this pluggable
- transport is listening on. (This should likely be whatever port the
- bridge specified in its ``ServerTransportPlugin`` torrc line,
- unless the pluggable transport is running in "managed" mode.)
-
- :param dict argdict: Some PTs can take additional arguments, which
- must be distributed to the client out-of-band. These are present
- in the ``@type bridge-extrainfo-document``, in the ``transport``
- line like so::
-
- METHOD SP ADDR ":" PORT SP [K=V[,K=V[,K=V[â?¦]]]]
-
- where K is the **argdict** key, and V is the value. For example,
- in the case of ``scramblesuit``, for which the client must supply
- a shared secret to the ``scramblesuit`` instance running on the
- bridge, the **argdict** would be something like::
-
- {'password': 'NEQGQYLUMUQGK5TFOJ4XI2DJNZTS4LRO'}
-
- .. _pt-spec.txt:
- https://gitweb.torproject.org/torspec.git/blob/HEAD:/pt-spec.txt
- """
- #XXX: assert are disabled with python -O
- assert isinstance(bridge, Bridge)
- assert type(address) in (ipaddr.IPv4Address, ipaddr.IPv6Address)
- assert type(port) is int
- assert (0 < port < 65536)
- assert type(methodname) is str
-
- self.bridge = bridge
- self.address = address
- self.port = port
- self.methodname = methodname
- if type(argdict) is dict:
- self.argdict = argdict
- else: self.argdict = {}
-
- def getTransportLine(self, includeFingerprint=False, bridgePrefix=False):
- """Get a torrc line for this pluggable transport.
-
- This method does not return lines which are prefixed with the word
- 'bridge', as they would be in a torrc file. Instead, lines returned
- look like this:
-
- obfs3 245.102.100.252:23619 59ca743e89b508e16b8c7c6d2290efdfd14eea98
-
- :param bool includeFingerprints: If ``True``, include the digest of
- this bridges public identity key in the torrc line.
- :param bool bridgePrefix: If ``True``, add ``'Bridge '`` to the
- beginning of each returned line (suitable for pasting directly
- into a torrc file).
- :rtype: str
- :returns: A configuration line for adding this pluggable transport
- into a torrc file.
- """
- sections = []
-
- if bridgePrefix:
- sections.append('Bridge')
-
- if isinstance(self.address, ipaddr.IPv6Address):
- host = "%s [%s]:%d" % (self.methodname, self.address, self.port)
- else:
- host = "%s %s:%d" % (self.methodname, self.address, self.port)
- sections.append(host)
-
- if includeFingerprint:
- sections.append(self.bridge.fingerprint)
-
- args = " ".join(["%s=%s" % (k, v) for k, v in self.argdict.items()])
- sections.append(args)
-
- line = ' '.join(sections)
- return line
-
def parseExtraInfoFile(f):
"""
parses lines in Bridges extra-info documents.
diff --git a/lib/bridgedb/Main.py b/lib/bridgedb/Main.py
index ce3edc5..e1963f5 100644
--- a/lib/bridgedb/Main.py
+++ b/lib/bridgedb/Main.py
@@ -27,6 +27,9 @@ from bridgedb import proxy
from bridgedb import safelog
from bridgedb import schedule
from bridgedb import util
+from bridgedb.bridges import InvalidPluggableTransportIP
+from bridgedb.bridges import MalformedPluggableTransport
+from bridgedb.bridges import PluggableTransport
from bridgedb.configure import loadConfig
from bridgedb.configure import Conf
from bridgedb.parse import options
@@ -128,13 +131,19 @@ def load(state, splitter, clear=False):
if bridges[ID].running:
logging.info("Adding %s transport to running bridge"
% method_name)
- bridgePT = Bridges.PluggableTransport(
- bridges[ID], method_name, address, port, argdict)
- bridges[ID].transports.append(bridgePT)
- if not bridgePT in bridges[ID].transports:
- logging.critical(
- "Added a transport, but it disappeared!",
- "\tTransport: %r" % bridgePT)
+ try:
+ bridgePT = PluggableTransport(Bridges.toHex(ID),
+ method_name, address,
+ port, argdict)
+ except (InvalidPluggableTransportIP,
+ MalformedPluggableTransport) as error:
+ logging.warn(error)
+ else:
+ bridges[ID].transports.append(bridgePT)
+ if not bridgePT in bridges[ID].transports:
+ logging.critical(
+ "Added a transport, but it disappeared!",
+ "\tTransport: %r" % bridgePT)
except KeyError as error:
logging.error("Could not find bridge with fingerprint '%s'."
% Bridges.toHex(ID))
diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py
new file mode 100644
index 0000000..65d4d02
--- /dev/null
+++ b/lib/bridgedb/bridges.py
@@ -0,0 +1,290 @@
+# -*- coding: utf-8 ; test-case-name: bridgedb.test.test_bridges -*-
+#
+# This file is part of BridgeDB, a Tor bridge distribution system.
+#
+# :authors: please see the AUTHORS file for attributions
+# :copyright: (c) 2013-2014, Isis Lovecruft
+# (c) 2007-2014, The Tor Project, Inc.
+# :license: see LICENSE for licensing information
+
+"""Classes for manipulating and storing Bridges and their attributes."""
+
+
+import ipaddr
+import logging
+import os
+
+from bridgedb.parse.addr import isValidIP
+from bridgedb.parse.fingerprint import isValidFingerprint
+
+
+class MalformedBridgeInfo(ValueError):
+ """Raised when some information about a bridge appears malformed."""
+
+
+class MalformedPluggableTransport(MalformedBridgeInfo):
+ """Raised when information used to initialise a :class:`PluggableTransport`
+ appears malformed.
+ """
+
+class InvalidPluggableTransportIP(MalformedBridgeInfo):
+ """Raised when a :class:`PluggableTransport` has an invalid address."""
+
+
+class PluggableTransport(object):
+ """A single instance of a Pluggable Transport (PT) offered by a
+ :class:`Bridge`.
+
+ Pluggable transports are described within a bridge's
+ ``@type bridge-extrainfo`` descriptor, see the
+ ``Specifications: Client behavior`` section and the
+ ``TOR_PT_SERVER_TRANSPORT_OPTIONS`` description in pt-spec.txt_ for
+ additional specification.
+
+ .. _pt-spec.txt:
+ https://gitweb.torproject.org/torspec.git/blob/HEAD:/pt-spec.txt
+
+ :type fingerprint: str
+ :ivar fingerprint: The uppercased, hexadecimal fingerprint of the identity
+ key of the parent bridge running this pluggable transport instance,
+ i.e. the main ORPort bridge whose ``@type bridge-server-descriptor``
+ contains a hash digest for a ``@type bridge-extrainfo-document``, the
+ latter of which contains the parameter of this pluggable transport in
+ its ``transport`` line.
+
+ :type methodname: str
+ :ivar methodname: The canonical "name" for this pluggable transport,
+ i.e. the one which would be specified in a torrc file. For example,
+ ``"obfs2"``, ``"obfs3"``, ``"scramblesuit"`` would all be pluggable
+ transport method names.
+
+ :type address: ``ipaddr.IPv4Address`` or ``ipaddr.IPv6Address``
+ :ivar address: The IP address of the transport. Currently (as of 20 March
+ 2014), there are no known, widely-deployed pluggable transports which
+ support IPv6. Ergo, this is very likely going to be an IPv4 address.
+
+ :type port: int
+ :ivar port: A integer specifying the port which this pluggable transport
+ is listening on. (This should likely be whatever port the bridge
+ specified in its ``ServerTransportPlugin`` torrc line, unless the
+ pluggable transport is running in "managed" mode.)
+
+ :type arguments: dict
+ :ivar arguments: Some PTs can take additional arguments, which must be
+ distributed to the client out-of-band. These are present in the
+ ``@type bridge-extrainfo-document``, in the ``transport`` line like
+ so::
+
+ METHOD SP ADDR ":" PORT SP [K=V[,K=V[,K=V[â?¦]]]]
+
+ where K is the key in **arguments**, and V is the value. For example,
+ in the case of ``scramblesuit``, for which the client must supply a
+ shared secret to the ``scramblesuit`` instance running on the bridge,
+ the **arguments** would be something like::
+
+ {'password': 'NEQGQYLUMUQGK5TFOJ4XI2DJNZTS4LRO'}
+ """
+
+ def __init__(self, fingerprint=None, methodname=None,
+ address=None, port=None, arguments=None):
+ """Create a ``PluggableTransport`` describing a PT running on a bridge.
+
+ :param str fingerprint: The uppercased, hexadecimal fingerprint of the
+ identity key of the parent bridge running this pluggable transport.
+ :param str methodname: The canonical "name" for this pluggable
+ transport. See :data:`methodname`.
+ :param str address: The IP address of the transport. See
+ :data:`address`.
+ :param int port: A integer specifying the port which this pluggable
+ transport is listening on.
+ :param dict arguments: Any additional arguments which the PT takes,
+ which must be distributed to the client out-of-band. See
+ :data:`arguments`.
+ """
+ self.fingerprint = fingerprint
+ self.address = address
+ self.port = port
+ self.methodname = methodname
+ self.arguments = arguments
+
+ # Because we can intitialise this class with the __init__()
+ # parameters, or use the ``updateFromStemTransport()`` method, we'll
+ # only use the ``_runChecks()`` method now if we were initialised with
+ # parameters:
+ if (self.fingerprint or self.address or self.port or
+ self.methodname or self.arguments):
+ self._runChecks()
+
+ def _parseArgumentsIntoDict(self, argumentList):
+ """Convert a list of Pluggable Transport arguments into a dictionary
+ suitable for :data:`arguments`.
+
+ :param list argumentList: A list of Pluggable Transport
+ arguments. There might be multiple, comma-separated ``K=V``
+ Pluggable Transport arguments in a single item in the
+ **argumentList**, or each item might be its own ``K=V``; we don't
+ care and we should be able to parse it either way.
+ :rtype: dict
+ :returns: A dictionary of all the ``K=V`` Pluggable Transport
+ arguments.
+ """
+ argDict = {}
+
+ # PT argumentss are comma-separated in the extrainfo
+ # descriptors. While there *shouldn't* be anything after them that was
+ # separated by a space (and hence would wind up being in a different
+ # item in `arguments`), if there was we'll join it to the rest of the
+ # PT arguments with a comma so that they are parsed as if they were PT
+ # arguments as well:
+ allArguments = ','.join(argumentList)
+
+ for arg in allArguments.split(','):
+ try:
+ key, value = arg.split('=')
+ except ValueError:
+ logging.warn(" Couldn't parse K=V from PT arg: %r" % arg)
+ else:
+ logging.debug(" Parsed PT Argument: %s: %s" % (key, value))
+ argDict[key] = value
+
+ return argDict
+
+ def _runChecks(self):
+ """Validate that we were initialised with acceptable parameters.
+
+ We currently check that:
+
+ 1. The :data:`fingerprint` is valid, according to
+ :func:`~bridgedb.parse.fingerprint.isValidFingerprint`.
+
+ 2. The :data:`address` is valid, according to
+ :func:`~bridgedb.parse.addr.isValidIP`.
+
+ 3. The :data:`port` is an integer, and that it is between the values
+ of ``0`` and ``65535`` (inclusive).
+
+ 4. The :data:`arguments` is a dictionary.
+
+ :raises MalformedPluggableTransport: if any of the above checks fails.
+ """
+ if not isValidFingerprint(self.fingerprint):
+ raise MalformedPluggableTransport(
+ ("Cannot create PluggableTransport with bad Bridge "
+ "fingerprint: %r.") % self.fingerprint)
+
+ valid = isValidIP(self.address)
+ if not valid:
+ raise InvalidPluggableTransportIP(
+ ("Cannot create PluggableTransport with address '%s'. "
+ "type(address)=%s.") % (self.address, type(self.address)))
+ self.address = ipaddr.IPAddress(self.address)
+
+ try:
+ # Coerce the port to be an integer:
+ self.port = int(self.port)
+ except TypeError:
+ raise MalformedPluggableTransport(
+ ("Cannot create PluggableTransport with port type: %s.")
+ % type(self.port))
+ else:
+ if not (0 <= self.port <= 65535):
+ raise MalformedPluggableTransport(
+ ("Cannot create PluggableTransport with out-of-range port:"
+ " %r.") % self.port)
+
+ if not isinstance(self.arguments, dict):
+ raise MalformedPluggableTransport(
+ ("Cannot create PluggableTransport with arguments type: %s")
+ % type(self.arguments))
+
+ def getTransportLine(self, includeFingerprint=True, bridgePrefix=False):
+ """Get a Bridge Line for this :class:`PluggableTransport`.
+
+ .. glossary::
+
+ Bridge Line
+ A "Bridge Line" is how BridgeDB refers to lines in a ``torrc``
+ file which should begin with the word ``"Bridge"``, and it is how
+ a client tells their Tor process that they would like to use a
+ particular bridge.
+
+ .. note:: If **bridgePrefix** is ``False``, this method does not
+ return lines which are prefixed with the word 'bridge', as they
+ would be in a torrc file. Instead, lines returned look like this::
+
+ obfs3 245.102.100.252:23619 59ca743e89b508e16b8c7c6d2290efdfd14eea98
+
+ This was made configurable to fix Vidalia being a brain-damaged
+ piece of shit (#5851_). TorLaucher replaced Vidalia soon after,
+ and TorLauncher is intelligent enough to understand
+ :term:`Bridge Line`s regardless of whether or not they are prefixed
+ with the word "Bridge".
+
+ .. _#5851: https://bugs.torproject.org/5851
+
+ :param bool includeFingerprints: If ``True``, include the digest of
+ this bridges public identity key in the torrc line.
+ :param bool bridgePrefix: If ``True``, add ``'Bridge '`` to the
+ beginning of each returned line (suitable for pasting directly
+ into a ``torrc`` file).
+ :rtype: str
+ :returns: A configuration line for adding this Pluggable Transport
+ into a ``torrc`` file.
+ """
+ sections = []
+
+ if bridgePrefix:
+ sections.append('Bridge')
+
+ if self.address.version == 6:
+ # If the address was IPv6, put brackets around it:
+ host = '%s [%s]:%d' % (self.methodname, self.address, self.port)
+ else:
+ host = '%s %s:%d' % (self.methodname, self.address, self.port)
+ sections.append(host)
+
+ if includeFingerprint:
+ sections.append(self.fingerprint)
+
+ for key, value in self.arguments.items():
+ sections.append('%s=%s' % (key, value))
+
+ line = ' '.join(sections)
+
+ return line
+
+ def updateFromStemTransport(self, fingerprint, methodname, kitchenSink):
+ """Update this :class:`PluggableTransport` from the data structure
+ which Stem uses.
+
+ Stem's
+ :api:`stem.descriptor.extrainfo_descriptor.BridgeExtraInfoDescriptor`
+ parses extrainfo ``transport`` lines into a dictionary with the
+ following structure::
+
+ {u'obfs2': (u'34.230.223.87', 37339, []),
+ u'obfs3': (u'34.230.223.87', 37338, []),
+ u'obfs4': (u'34.230.223.87', 37341, [
+ (u'iat-mode=0,'
+ u'node-id=2a79f14120945873482b7823caabe2fcde848722,'
+ u'public-key=0a5b046d07f6f971b7776de682f57c5b9cdc8fa060db7ef59de82e721c8098f4')]),
+ u'scramblesuit': (u'34.230.223.87', 37340, [
+ u'password=ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'])}
+
+ This method will initialise this class from the dictionary key
+ (**methodname**) and its tuple of values (**kitchenSink**).
+
+ :param str fingerprint: The uppercased, hexadecimal fingerprint of the
+ identity key of the parent bridge running this pluggable transport.
+ :param str methodname: The :data:`methodname` of this Pluggable
+ Transport.
+ :param tuple kitchenSink: Everything else that was on the
+ ``transport`` line in the bridge's extrainfo descriptor, which
+ Stem puts into the 3-tuples shown in the example above.
+ """
+ self.fingerprint = fingerprint
+ self.methodname = methodname
+ self.address = kitchenSink[0]
+ self.port = kitchenSink[1]
+ self.arguments = self._parseArgumentsIntoDict(kitchenSink[2])
+ self._runChecks()
diff --git a/lib/bridgedb/test/deprecated.py b/lib/bridgedb/test/deprecated.py
index a972a52..40cfe0a 100644
--- a/lib/bridgedb/test/deprecated.py
+++ b/lib/bridgedb/test/deprecated.py
@@ -123,6 +123,118 @@ class ParseORAddressError(Exception):
@deprecate.deprecated(
+ Version('bridgedb', 0, 2, 4),
+ replacement='bridgedb.bridges.PluggableTransport')
+class PluggableTransport(object):
+ """A PT with reference to the parent bridge on which it is running.
+
+ Deprecated :class:`bridgedb.Bridges.PluggableTransport`, replaced in
+ bridgedb-0.2.4, by :class:`bridgedb.bridges.PluggableTransport`.
+ """
+
+ def __init__(self, bridge, methodname, address, port, argdict=None):
+ """Create a ``PluggableTransport`` describing a PT running on a bridge.
+
+ Pluggable transports are described within a bridge's ``@type
+ bridge-extrainfo`` descriptor, see the ``Specifications: Client
+ behavior`` section and the ``TOR_PT_SERVER_TRANSPORT_OPTIONS``
+ description in pt-spec.txt_ for additional specification.
+
+ :type bridge: :class:`Bridge`
+ :param bridge: The parent bridge running this pluggable transport
+ instance, i.e. the main ORPort bridge whose
+ ``@type bridge-server-descriptor`` contains a hash digest for a
+ ``@type bridge-extrainfo-document``, the latter of which contains
+ the parameter of this pluggable transport in its ``transport``
+ line.
+
+ :param str methodname: The canonical "name" for this pluggable
+ transport, i.e. the one which would be specified in a torrc
+ file. For example, ``"obfs2"``, ``"obfs3"``, ``"scramblesuit"``
+ would all be pluggable transport method names.
+
+ :param str address: The IP address of the transport. Currently (as of
+ 20 March 2014), there are no known, widely-deployed pluggable
+ transports which support IPv6. Ergo, this is very likely going to
+ be an IPv4 address.
+
+ :param int port: A integer specifying the port which this pluggable
+ transport is listening on. (This should likely be whatever port the
+ bridge specified in its ``ServerTransportPlugin`` torrc line,
+ unless the pluggable transport is running in "managed" mode.)
+
+ :param dict argdict: Some PTs can take additional arguments, which
+ must be distributed to the client out-of-band. These are present
+ in the ``@type bridge-extrainfo-document``, in the ``transport``
+ line like so::
+
+ METHOD SP ADDR ":" PORT SP [K=V[,K=V[,K=V[â?¦]]]]
+
+ where K is the **argdict** key, and V is the value. For example,
+ in the case of ``scramblesuit``, for which the client must supply
+ a shared secret to the ``scramblesuit`` instance running on the
+ bridge, the **argdict** would be something like::
+
+ {'password': 'NEQGQYLUMUQGK5TFOJ4XI2DJNZTS4LRO'}
+
+ .. _pt-spec.txt:
+ https://gitweb.torproject.org/torspec.git/blob/HEAD:/pt-spec.txt
+ """
+ #XXX: assert are disabled with python -O
+ assert isinstance(bridge, Bridge)
+ assert type(address) in (ipaddr.IPv4Address, ipaddr.IPv6Address)
+ assert type(port) is int
+ assert (0 < port < 65536)
+ assert type(methodname) is str
+
+ self.bridge = bridge
+ self.address = address
+ self.port = port
+ self.methodname = methodname
+ if type(argdict) is dict:
+ self.argdict = argdict
+ else: self.argdict = {}
+
+ def getTransportLine(self, includeFingerprint=False, bridgePrefix=False):
+ """Get a torrc line for this pluggable transport.
+
+ This method does not return lines which are prefixed with the word
+ 'bridge', as they would be in a torrc file. Instead, lines returned
+ look like this:
+
+ obfs3 245.102.100.252:23619 59ca743e89b508e16b8c7c6d2290efdfd14eea98
+
+ :param bool includeFingerprints: If ``True``, include the digest of
+ this bridges public identity key in the torrc line.
+ :param bool bridgePrefix: If ``True``, add ``'Bridge '`` to the
+ beginning of each returned line (suitable for pasting directly
+ into a torrc file).
+ :rtype: str
+ :returns: A configuration line for adding this pluggable transport
+ into a torrc file.
+ """
+ sections = []
+
+ if bridgePrefix:
+ sections.append('Bridge')
+
+ if isinstance(self.address, ipaddr.IPv6Address):
+ host = "%s [%s]:%d" % (self.methodname, self.address, self.port)
+ else:
+ host = "%s %s:%d" % (self.methodname, self.address, self.port)
+ sections.append(host)
+
+ if includeFingerprint:
+ sections.append(self.bridge.fingerprint)
+
+ args = " ".join(["%s=%s" % (k, v) for k, v in self.argdict.items()])
+ sections.append(args)
+
+ line = ' '.join(sections)
+ return line
+
+
+@xxxxxxxxxxxxxxxxxxxx(
Version('bridgedb', 0, 0, 1),
replacement='bridgedb.parse.addr.PortList')
class PortList:
diff --git a/lib/bridgedb/test/test_Bridges.py b/lib/bridgedb/test/test_Bridges.py
index 93d6c10..2c7d09b 100644
--- a/lib/bridgedb/test/test_Bridges.py
+++ b/lib/bridgedb/test/test_Bridges.py
@@ -15,6 +15,7 @@ from binascii import a2b_hex
from twisted.trial import unittest
from bridgedb import Bridges
+from bridgedb.bridges import PluggableTransport
from bridgedb.parse.addr import PortList
import hashlib
@@ -125,9 +126,9 @@ class BridgeClassTest(unittest.TestCase):
id_digest=self.id_digest,
or_addresses=self.or_addresses)
ptArgs = {'password': 'NEQGQYLUMUQGK5TFOJ4XI2DJNZTS4LRO'}
- pt = Bridges.PluggableTransport(bridge, 'scramblesuit',
- ipaddr.IPAddress('42.42.42.42'), 4242,
- ptArgs)
+ pt = PluggableTransport(bridge.fingerprint, 'scramblesuit',
+ ipaddr.IPAddress('42.42.42.42'), 4242,
+ ptArgs)
bridge.transports.append(pt)
bridgeLine = bridge.getConfigLine(includeFingerprint=True,
transport='scramblesuit')
diff --git a/lib/bridgedb/test/test_Tests.py b/lib/bridgedb/test/test_Tests.py
index 816cd40..e57f4a1 100644
--- a/lib/bridgedb/test/test_Tests.py
+++ b/lib/bridgedb/test/test_Tests.py
@@ -94,6 +94,8 @@ def monkeypatchTests():
patcher.addPatch(Tests.bridgedb.Bridges, 'fromHex', binascii.a2b_hex)
patcher.addPatch(Tests.bridgedb.Bridges, 'is_valid_fingerprint',
deprecated.is_valid_fingerprint)
+ patcher.addPatch(Tests.bridgedb.Bridges, 'PluggableTransport',
+ deprecated.PluggableTransport)
return patcher
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits