Esempio n. 1
0
    def __init__(self, areaMapper, nClusters, key,
                 ipCategories=None, answerParameters=None):
        """Create a Distributor that decides which bridges to distribute based
        upon the client's IP address and the current time.

        :type areaMapper: callable
        :param areaMapper: A function that maps IP addresses arbitrarily to
            strings, such that addresses which map to identical strings are
            considered to be in the same "area" (for some arbitrary definition
            of "area"). See :func:`bridgedb.Dist.uniformMap` for an example.
        :param integer nClusters: The number of clusters to group IP addresses
            into. Note that if PROXY_LIST_FILES is set in bridgedb.conf, then
            the actual number of clusters is one higher than ``nClusters``,
            because the set of known open proxies constitutes its own
            category.
            DOCDOC What exactly does a cluster *do*?
        :param bytes key: The master HMAC key for this distributor. All added
            bridges are HMACed with this key in order to place them into the
            hashrings.
        :type ipCategories: iterable or None
        :param ipCategories: DOCDOC
        :type answerParameters: :class:`bridgedb.Bridges.BridgeRingParameters`
        :param answerParameters: A mechanism for ensuring that the set of
            bridges that this distributor answers a client with fit certain
            parameters, i.e. that an answer has "at least two obfsproxy
            bridges" or "at least one bridge on port 443", etc.
        """
        self.areaMapper = areaMapper
        self.nClusters = nClusters
        self.answerParameters = answerParameters

        if not ipCategories:
            ipCategories = []
        if not answerParameters:
            answerParameters = []
        self.rings = []

        self.categories = []
        for c in ipCategories:
            self.categories.append(c)

        key2 = getHMAC(key, "Assign-Bridges-To-Rings")
        key3 = getHMAC(key, "Order-Areas-In-Rings")
        self.areaOrderHmac = getHMACFunc(key3, hex=False)
        key4 = getHMAC(key, "Assign-Areas-To-Rings")
        self.areaClusterHmac = getHMACFunc(key4, hex=True)

        # add splitter and cache the default rings
        # plus leave room for dynamic filters
        #
        # XXX Why is the "extra room" hardcoded to be 5? Shouldn't it be some
        #     fraction of the number of clusters/categories? --isis
        ring_cache_size  = self.nClusters + len(ipCategories) + 5
        self.splitter = bridgedb.Bridges.FilteredBridgeSplitter(
            key2, max_cached_rings=ring_cache_size)
        logging.debug("Added splitter %s to IPBasedDistributor."
                      % self.splitter.__class__)

        self.setDistributorName('HTTPS')
Esempio n. 2
0
    def __init__(self,
                 totalSubrings,
                 key,
                 proxies=None,
                 answerParameters=None):
        """Create a Distributor that decides which bridges to distribute based
        upon the client's IP address and the current time.

        :param int totalSubrings: The number of subhashrings to group clients
            into. Note that if ``PROXY_LIST_FILES`` is set in bridgedb.conf,
            then the actual number of clusters is one higher than
            ``totalSubrings``, because the set of all known open proxies is
            given its own subhashring.
        :param bytes key: The master HMAC key for this distributor. All added
            bridges are HMACed with this key in order to place them into the
            hashrings.
        :type proxies: :class:`~bridgedb.proxy.ProxySet`
        :param proxies: A :class:`bridgedb.proxy.ProxySet` containing known
            Tor Exit relays and other known proxies.  These will constitute
            the extra cluster, and any client requesting bridges from one of
            these **proxies** will be distributed bridges from a separate
            subhashring that is specific to Tor/proxy users.
        :type answerParameters:
            :class:`bridgedb.bridgerings.BridgeRingParameters`
        :param answerParameters: A mechanism for ensuring that the set of
            bridges that this distributor answers a client with fit certain
            parameters, i.e. that an answer has "at least two obfsproxy
            bridges" or "at least one bridge on port 443", etc.
        """
        super(HTTPSDistributor, self).__init__(key)
        self.totalSubrings = totalSubrings
        self.answerParameters = answerParameters

        if proxies:
            logging.info("Added known proxies to HTTPS distributor...")
            self.proxies = proxies
            self.totalSubrings += 1
            self.proxySubring = self.totalSubrings
        else:
            logging.warn("No known proxies were added to HTTPS distributor!")
            self.proxies = proxy.ProxySet()
            self.proxySubring = 0

        self.ringCacheSize = self.totalSubrings * 3

        key2 = getHMAC(key, "Assign-Bridges-To-Rings")
        key3 = getHMAC(key, "Order-Areas-In-Rings")
        key4 = getHMAC(key, "Assign-Areas-To-Rings")

        self._clientToPositionHMAC = getHMACFunc(key3, hex=False)
        self._subnetToSubringHMAC = getHMACFunc(key4, hex=True)
        self.hashring = FilteredBridgeSplitter(key2, self.ringCacheSize)
        self.name = 'HTTPS'
        logging.debug("Added %s to %s distributor." %
                      (self.hashring.__class__.__name__, self.name))
Esempio n. 3
0
    def __init__(self, totalSubrings, key, proxies=None, answerParameters=None):
        """Create a Distributor that decides which bridges to distribute based
        upon the client's IP address and the current time.

        :param int totalSubrings: The number of subhashrings to group clients
            into. Note that if ``PROXY_LIST_FILES`` is set in bridgedb.conf,
            then the actual number of clusters is one higher than
            ``totalSubrings``, because the set of all known open proxies is
            given its own subhashring.
        :param bytes key: The master HMAC key for this distributor. All added
            bridges are HMACed with this key in order to place them into the
            hashrings.
        :type proxies: :class:`~bridgedb.proxy.ProxySet`
        :param proxies: A :class:`bridgedb.proxy.ProxySet` containing known
            Tor Exit relays and other known proxies.  These will constitute
            the extra cluster, and any client requesting bridges from one of
            these **proxies** will be distributed bridges from a separate
            subhashring that is specific to Tor/proxy users.
        :type answerParameters: :class:`bridgedb.Bridges.BridgeRingParameters`
        :param answerParameters: A mechanism for ensuring that the set of
            bridges that this distributor answers a client with fit certain
            parameters, i.e. that an answer has "at least two obfsproxy
            bridges" or "at least one bridge on port 443", etc.
        """
        super(HTTPSDistributor, self).__init__(key)
        self.totalSubrings = totalSubrings
        self.answerParameters = answerParameters

        if proxies:
            logging.info("Added known proxies to HTTPS distributor...")
            self.proxies = proxies
            self.totalSubrings += 1
            self.proxySubring = self.totalSubrings
        else:
            logging.warn("No known proxies were added to HTTPS distributor!")
            self.proxies = proxy.ProxySet()
            self.proxySubring = 0

        self.ringCacheSize = self.totalSubrings * 3

        key2 = getHMAC(key, "Assign-Bridges-To-Rings")
        key3 = getHMAC(key, "Order-Areas-In-Rings")
        key4 = getHMAC(key, "Assign-Areas-To-Rings")

        self._clientToPositionHMAC = getHMACFunc(key3, hex=False)
        self._subnetToSubringHMAC = getHMACFunc(key4, hex=True)
        self.hashring = FilteredBridgeSplitter(key2, self.ringCacheSize)
        self.name = 'HTTPS'
        logging.debug("Added %s to %s distributor." %
                      (self.hashring.__class__.__name__, self.name))
Esempio n. 4
0
 def __init__(self, key):
     self.hmac = getHMACFunc(key, hex=True)
     self.ringsByName = {}
     self.totalP = 0
     self.pValues = []
     self.rings = []
     self.statsHolders = []
Esempio n. 5
0
    def __init__(self, key, max_cached_rings=3):
        """Create a hashring which filters bridges into sub hashrings.

        :type key: DOCDOC
        :param key: An HMAC key.
        :param int max_cached_rings: XXX max_cached_rings appears to not be
             used anywhere.

        :ivar filterRings: A dictionary of subrings which has the form
             ``{ringname: (filterFn, subring)}``, where:
                 - ``ringname`` is a unique string identifying the subring.
                 - ``filterFn`` is a callable which filters Bridges in some
                   manner, i.e. by whether they are IPv4 or IPv6, etc.
                 - ``subring`` is any of the horribly-implemented,
                   I-guess-it-passes-for-some-sort-of-hashring classes in this
                   module.
        :ivar hmac: DOCDOC
        :ivar bridges: DOCDOC
        :type distributorName: str
        :ivar distributorName: The name of this splitter's distributor. See
             :meth:`~bridgedb.distributors.https.distributor.HTTPSDistributor.setDistributorName`.
        """
        self.key = key
        self.filterRings = {}
        self.hmac = getHMACFunc(key, hex=True)
        self.bridges = []
        self.distributorName = ''

        #XXX: unused
        self.max_cached_rings = max_cached_rings
Esempio n. 6
0
 def __init__(self, key):
     self.hmac = getHMACFunc(key, hex=True)
     self.ringsByName = {}
     self.totalP = 0
     self.pValues = []
     self.rings = []
     self.statsHolders = []
Esempio n. 7
0
    def __init__(self, key, max_cached_rings=3):
        """Create a hashring which filters bridges into sub hashrings.

        :type key: DOCDOC
        :param key: An HMAC key.
        :param int max_cached_rings: XXX max_cached_rings appears to not be
             used anywhere.

        :ivar filterRings: A dictionary of subrings which has the form
             ``{ringname: (filterFn, subring)}``, where:
                 - ``ringname`` is a unique string identifying the subring.
                 - ``filterFn`` is a callable which filters Bridges in some
                   manner, i.e. by whether they are IPv4 or IPv6, etc.
                 - ``subring`` is any of the horribly-implemented,
                   I-guess-it-passes-for-some-sort-of-hashring classes in this
                   module.
        :ivar hmac: DOCDOC
        :ivar bridges: DOCDOC
        :type distributorName: str
        :ivar distributorName: The name of this splitter's distributor. See
             :meth:`~bridgedb.distributors.https.distributor.HTTPSDistributor.setDistributorName`.
        """
        self.key = key
        self.filterRings = {}
        self.hmac = getHMACFunc(key, hex=True)
        self.bridges = []
        self.distributorName = ''

        #XXX: unused
        self.max_cached_rings = max_cached_rings
Esempio n. 8
0
    def __init__(self,
                 key,
                 domainmap,
                 domainrules,
                 answerParameters=None,
                 whitelist=None):
        """Create a bridge distributor which uses email.

        :type emailHmac: callable
        :param emailHmac: An hmac function used to order email addresses
            within a ring. See :func:`~bridgedb.crypto.getHMACFunc`.
        :param dict domainmap: A map from lowercase domains that we support
            mail from to their canonical forms. See `EMAIL_DOMAIN_MAP` option
            in `bridgedb.conf`.
        :param domainrules: DOCDOC
        :param answerParameters: DOCDOC
        :type whitelist: dict or ``None``
        :param whitelist: A dictionary that maps whitelisted email addresses
            to GnuPG fingerprints.
        """
        super(EmailDistributor, self).__init__(key)

        self.domainmap = domainmap
        self.domainrules = domainrules
        self.whitelist = whitelist or dict()
        self.answerParameters = answerParameters

        key1 = getHMAC(key, "Map-Addresses-To-Ring")
        key2 = getHMAC(key, "Order-Bridges-In-Ring")

        self.emailHmac = getHMACFunc(key1, hex=False)
        #XXX cache options not implemented
        self.hashring = FilteredBridgeSplitter(key2, max_cached_rings=5)

        self.name = "Email"
Esempio n. 9
0
    def __init__(self, key, domainmap, domainrules,
                 answerParameters=None, whitelist=None):
        """Create a bridge distributor which uses email.

        :type emailHmac: callable
        :param emailHmac: An hmac function used to order email addresses
            within a ring. See :func:`~bridgedb.crypto.getHMACFunc`.
        :param dict domainmap: A map from lowercase domains that we support
            mail from to their canonical forms. See `EMAIL_DOMAIN_MAP` option
            in `bridgedb.conf`.
        :param domainrules: DOCDOC
        :param answerParameters: DOCDOC
        :type whitelist: dict or ``None``
        :param whitelist: A dictionary that maps whitelisted email addresses
            to GnuPG fingerprints.
        """
        super(EmailDistributor, self).__init__(key)

        self.domainmap = domainmap
        self.domainrules = domainrules
        self.whitelist = whitelist or dict()
        self.answerParameters = answerParameters

        key1 = getHMAC(key, "Map-Addresses-To-Ring")
        key2 = getHMAC(key, "Order-Bridges-In-Ring")

        self.emailHmac = getHMACFunc(key1, hex=False)
        #XXX cache options not implemented
        self.hashring = FilteredBridgeSplitter(key2, max_cached_rings=5)

        self.name = "Email"
Esempio n. 10
0
File: Dist.py Progetto: wfn/bridgedb
    def __init__(self, key, domainmap, domainrules,
                 answerParameters=None):
        """Create a bridge distributor which uses email.

        :type emailHmac: callable
        :param emailHmac: An hmac function used to order email addresses
            within a ring. See :func:`~bridgedb.crypto.getHMACFunc`.
        :param dict domainmap: A map from lowercase domains that we support
            mail from to their canonical forms. See `EMAIL_DOMAIN_MAP` option
            in `bridgedb.conf`.
        :param domainrules: DOCDOC
        :param answerParameters: DOCDOC
        """
        key1 = getHMAC(key, "Map-Addresses-To-Ring")
        self.emailHmac = getHMACFunc(key1, hex=False)

        key2 = getHMAC(key, "Order-Bridges-In-Ring")
        # XXXX clear the store when the period rolls over!
        self.domainmap = domainmap
        self.domainrules = domainrules
        self.answerParameters = answerParameters

        #XXX cache options not implemented
        self.splitter = bridgedb.Bridges.FilteredBridgeSplitter(
            key2, max_cached_rings=5)

        self.setDistributorName('Email')
Esempio n. 11
0
    def setUp(self):
        """Create a Bridge whose address is 1.1.1.1, orPort is 1111, and
        fingerprint is 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.  Also,
        create an HMAC function whose key is 'plasma'.
        """
        self.bridge = Bridge()
        self.bridge.address = '1.1.1.1'
        self.bridge.orPort = 1111
        self.bridge.fingerprint = 'a' * 40

        self.hmac = getHMACFunc('plasma')
Esempio n. 12
0
    def setUp(self):
        """Create a Bridge whose address is 1.1.1.1, orPort is 1111, and
        fingerprint is 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.  Also,
        create an HMAC function whose key is 'plasma'.
        """
        self.bridge = Bridge()
        self.bridge.address = '1.1.1.1'
        self.bridge.orPort = 1111
        self.bridge.fingerprint = 'a' * 40

        self.hmac = getHMACFunc('plasma')
Esempio n. 13
0
    def setUp(self):
        """Create a Bridge whose address is 1.1.1.1, orPort is 1111, and
        fingerprint is 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.  Also,
        create an HMAC function whose key is 'plasma'.
        """
        self.bridge = Bridge()
        self.bridge.address = '1.1.1.1'
        self.bridge.orPort = 1111
        self.bridge.fingerprint = 'a' * 40

        self.hmac = getHMACFunc('plasma')

        PluggableTransport.probing_resistant_transports = [
            'scramblesuit', 'obfs4'
        ]
Esempio n. 14
0
    def getHashringPlacement(self, key, client=None):
        """Create an HMAC of some **client** info using a **key**.

        :param str key: The key to use for HMACing.
        :param str client: Some (hopefully unique) information about the
            client who is requesting bridges, such as an IP or email address.
        :rtype: long
        :returns: A long specifying index of the first node in a hashring to
            be distributed to the client. This value should obviously be used
            mod the number of nodes in the hashring.
        """
        if not client:
            client = self.client

        # Get an HMAC with the key of the client identifier:
        digest = getHMACFunc(key)(client)
        # Take the lower 8 bytes of the digest and convert to a long:
        position = long(digest[:8], 16)
        return position
Esempio n. 15
0
    def getHashringPlacement(self, key, client=None):
        """Create an HMAC of some **client** info using a **key**.

        :param str key: The key to use for HMACing.
        :param str client: Some (hopefully unique) information about the
            client who is requesting bridges, such as an IP or email address.
        :rtype: long
        :returns: A long specifying index of the first node in a hashring to
            be distributed to the client. This value should obviously be used
            mod the number of nodes in the hashring.
        """
        if not client:
            client = type('')(self.client)

        # Get an HMAC with the key of the client identifier:
        digest = getHMACFunc(key)(client)
        # Take the lower 8 bytes of the digest and convert to a long:
        position = int(digest[:8], 16)
        return position
Esempio n. 16
0
 def __init__(self, key, rings):
     self.hmac = getHMACFunc(key, hex=True)
     self.rings = rings[:]
Esempio n. 17
0
 def __init__(self, key, rings):
     self.hmac = getHMACFunc(key, hex=True)
     self.rings = rings[:]
     for r in self.rings:
         assert (isinstance(r, BridgeHolder))
Esempio n. 18
0
 def __init__(self, key, rings):
     self.hmac = getHMACFunc(key, hex=True)
     self.rings = rings[:]
     for r in self.rings:
         assert(isinstance(r, BridgeHolder))
Esempio n. 19
0
    def __init__(self, key, answerParameters=None):
        """Create a new BridgeRing, using key as its hmac key.

        :type key: bytes
        :param key: The HMAC key, generated with
             :func:`~bridgedb.crypto.getKey`.
        :type answerParameters: :class:`BridgeRingParameters`
        :param answerParameters: DOCDOC
        :ivar dict bridges: A dictionary which maps HMAC keys to
            :class:`~bridgedb.bridges.Bridge`s.
        :ivar dict bridgesByID: A dictionary which maps raw hash digests of
            bridge ID keys to :class:`~bridgedb.bridges.Bridge`s.
        :type hmac: callable
        :ivar hmac: An HMAC function, which uses the **key** parameter to
             generate new HMACs for storing, inserting, and retrieving
             :class:`~bridgedb.bridges.Bridge`s within mappings.
        :ivar bool isSorted: ``True`` if ``sortedKeys`` is currently sorted.
        :ivar list sortedKeys: A sorted list of all of the HMACs.
        :ivar str name: A string which identifies this hashring, used mostly
            for differentiating this hashring in log messages, but it is also
            used for naming subrings. If this hashring is a subring, the
            ``name`` will include whatever distinguishing parameters
            differentiate that particular subring (i.e. ``'(port-443
            subring)'`` or ``'(Stable subring)'``)
        :type subrings: list
        :ivar subrings: A list of other ``BridgeRing``s, each of which
            contains bridges of a particular type. For example, a subring
            might contain only ``Bridge``s which have been given the "Stable"
            flag, or it might contain only IPv6 bridges. Each item in this
            list should be a 4-tuple::

                (type, value, count, ring)

            where:

              - ``type`` is a string which describes what kind of parameter is
                used to determine if a ``Bridge`` belongs in that subring,
                i.e. ``'port'`` or ``'flag'``.

              - ``value`` is a specific value pertaining to the ``type``,
                e.g. ``type='port'; value=443``.

              - ``count`` is an integer for the current total number of
                bridges in the subring.

              - ``ring`` is a :class:`BridgeRing`; it is the subhashring which
                contains ``count`` number of
                :class:`~bridgedb.bridges.Bridge`s of a certain ``type``.
        """
        self.bridges = {}
        self.bridgesByID = {}
        self.hmac = getHMACFunc(key, hex=False)
        self.isSorted = False
        self.sortedKeys = []
        if answerParameters is None:
            answerParameters = BridgeRingParameters()
        self.answerParameters = answerParameters

        self.subrings = []
        for port, count in self.answerParameters.needPorts:
            #note that we really need to use the same key here, so that
            # the mapping is in the same order for all subrings.
            self.subrings.append(('port', port, count, BridgeRing(key, None)))
        for flag, count in self.answerParameters.needFlags:
            self.subrings.append(('flag', flag, count, BridgeRing(key, None)))

        self.setName("Ring")
Esempio n. 20
0
 def __init__(self, key, rings):
     self.hmac = getHMACFunc(key, hex=True)
     self.rings = rings[:]
Esempio n. 21
0
    def __init__(self, key, answerParameters=None):
        """Create a new BridgeRing, using key as its hmac key.

        :type key: bytes
        :param key: The HMAC key, generated with
             :func:`~bridgedb.crypto.getKey`.
        :type answerParameters: :class:`BridgeRingParameters`
        :param answerParameters: DOCDOC
        :ivar dict bridges: A dictionary which maps HMAC keys to
            :class:`~bridgedb.bridges.Bridge`s.
        :ivar dict bridgesByID: A dictionary which maps raw hash digests of
            bridge ID keys to :class:`~bridgedb.bridges.Bridge`s.
        :type hmac: callable
        :ivar hmac: An HMAC function, which uses the **key** parameter to
             generate new HMACs for storing, inserting, and retrieving
             :class:`~bridgedb.bridges.Bridge`s within mappings.
        :ivar bool isSorted: ``True`` if ``sortedKeys`` is currently sorted.
        :ivar list sortedKeys: A sorted list of all of the HMACs.
        :ivar str name: A string which identifies this hashring, used mostly
            for differentiating this hashring in log messages, but it is also
            used for naming subrings. If this hashring is a subring, the
            ``name`` will include whatever distinguishing parameters
            differentiate that particular subring (i.e. ``'(port-443
            subring)'`` or ``'(Stable subring)'``)
        :type subrings: list
        :ivar subrings: A list of other ``BridgeRing``s, each of which
            contains bridges of a particular type. For example, a subring
            might contain only ``Bridge``s which have been given the "Stable"
            flag, or it might contain only IPv6 bridges. Each item in this
            list should be a 4-tuple::

                (type, value, count, ring)

            where:

              - ``type`` is a string which describes what kind of parameter is
                used to determine if a ``Bridge`` belongs in that subring,
                i.e. ``'port'`` or ``'flag'``.

              - ``value`` is a specific value pertaining to the ``type``,
                e.g. ``type='port'; value=443``.

              - ``count`` is an integer for the current total number of
                bridges in the subring.

              - ``ring`` is a :class:`BridgeRing`; it is the subhashring which
                contains ``count`` number of
                :class:`~bridgedb.bridges.Bridge`s of a certain ``type``.
        """
        self.bridges = {}
        self.bridgesByID = {}
        self.hmac = getHMACFunc(key, hex=False)
        self.isSorted = False
        self.sortedKeys = []
        if answerParameters is None:
            answerParameters = BridgeRingParameters()
        self.answerParameters = answerParameters

        self.subrings = []
        for port,count in self.answerParameters.needPorts:
            #note that we really need to use the same key here, so that
            # the mapping is in the same order for all subrings.
            self.subrings.append( ('port',port,count,BridgeRing(key,None)) )
        for flag,count in self.answerParameters.needFlags:
            self.subrings.append( ('flag',flag,count,BridgeRing(key,None)) )

        self.setName("Ring")