tor-commits
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
January 2014
- 23 participants
- 2272 discussions
commit a74fb1ae635c9f79fc872469775273c1e9d1b1e7
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 08:42:38 2013 +0000
Rewrite the descriptor generator.
* ADD better descriptor generator, it makes descriptors according to
dir-spec.txt now. They are even signed with OpenSSL generated RSA keys, and
have all the embedded document hashes and fingerprints of the correct keys
used for signing and everything.
---
scripts/gen_bridge_descriptors | 836 ++++++++++++++++++++++++++++++++++++----
1 file changed, 755 insertions(+), 81 deletions(-)
diff --git a/scripts/gen_bridge_descriptors b/scripts/gen_bridge_descriptors
index ff0f589..e272600 100644
--- a/scripts/gen_bridge_descriptors
+++ b/scripts/gen_bridge_descriptors
@@ -1,107 +1,781 @@
-#!/usr/bin/env python -tt
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# gen_bridge_descriptors
+# ----------------------
+# XXX describeme
+#
+# :authors: Matthew Finkel
+# Isis Lovecruft <isis(a)torproject.org> 0xA3ADB67A2CDB8B35
+# :licence: distributed with BridgeDB, see included LICENSE file
+# :copyright: (c) 2013 Matthew Finkel
+# (c) 2013 Isis Agora Lovecruft
+# (c) 2013 The Tor Project, Inc.
+#______________________________________________________________________________
+from __future__ import print_function
+from __future__ import absolute_import
+from __future__ import unicode_literals
+
+import argparse
+import binascii
+import hashlib
+import ipaddr
+import math
import sys
import random
+import re
import time
-import ipaddr
+
from datetime import datetime
-import binascii
+from codecs import open as open
+
+try:
+ import OpenSSL.crypto
+except (ImportError, NameError) as error:
+ print("This script requires pyOpenSSL>=0.13.0")
+ raise SystemExit(error.message)
+try:
+ from bridgedb.parse import versions
+except (ImportError, NameError) as error:
+ print(error.message)
+ print("WARNING: Cannot import bridgedb package!",
+ "Generated descriptor content won't accurately reflect descriptor",
+ "information created by different Tor versions.", sep='\n\t')
+try:
+ import nacl
+ import nacl.secret
+except (ImportError, NameError, IOError):
+ nacl = secret = None
+
+
+#: The version of this script
+__version__ = '0.2.0'
+
+#: The <major>.<minor>.<micro>.<rev> version numbers for tor, taken from the
+#: 'server-versions' line of a consensus file
+SERVER_VERSIONS = """0.2.2.39,0.2.3.24-rc,0.2.3.25,
+0.2.4.5-alpha,0.2.4.6-alpha,0.2.4.7-alpha,0.2.4.8-alpha,0.2.4.9-alpha,
+0.2.4.10-alpha,0.2.4.11-alpha,0.2.4.12-alpha,0.2.4.14-alpha,0.2.4.15-rc,
+0.2.4.16-rc,0.2.4.17-rc,0.2.5.1-alpha""".replace('\n', '').split(',')
+
+#: Strings found in PEM-encoded objects created by Tor
+TOR_BEGIN_KEY = "-----BEGIN RSA PUBLIC KEY-----"
+TOR_END_KEY = "-----END RSA PUBLIC KEY-----"
+TOR_BEGIN_SK = "-----BEGIN RSA PRIVATE KEY-----"
+TOR_END_SK = "-----END RSA PRIVATE KEY-----"
+TOR_BEGIN_SIG = "-----BEGIN SIGNATURE-----"
+TOR_END_SIG = "-----END SIGNATURE-----"
+
+#: Strings found in PEM-encoded objects created by OpenSSL
+OPENSSL_BEGIN_KEY = "-----BEGIN PRIVATE KEY-----"
+OPENSSL_END_KEY = "-----END PRIVATE KEY-----"
+OPENSSL_BEGIN_CERT = "-----BEGIN CERTIFICATE-----"
+OPENSSL_END_CERT = "-----END CERTIFICATE-----"
+
+PEM = OpenSSL.crypto.FILETYPE_PEM
+
+class OpenSSLKeyGenError(Exception):
+ """Raised when there is a problem generating a new key."""
-def usage():
- print "syntax: generatedescriptors.py <count>\n"\
- " count: number of descriptors to generate\n"
+
+def getArgParser():
+ """Get our :class:`~argparse.ArgumentParser`."""
+ parser = argparse.ArgumentParser(add_help=True)
+ parser.version = __version__
+ parser.description = "Generate a signed set of network-status, "
+ parser.description += "extra-info, and server descriptor documents "
+ parser.description += "for mock Tor relays or bridges."
+ infoargs = parser.add_mutually_exclusive_group()
+ verbargs = parser.add_mutually_exclusive_group()
+ infoargs.add_argument("-v", "--verbose", action="store_true",
+ help="print information to stdout")
+ infoargs.add_argument("-q", "--quiet", action="store_true",
+ help="don't print anything")
+ verbargs.add_argument("--version", action="store_true",
+ help="print the %s version and exit".format(
+ parser.prog))
+ group = parser.add_argument_group()
+ group.title = "required arguments"
+ group.add_argument("-n", "--descriptors", default=0,
+ help="generate <n> descriptor sets", type=int)
+ return parser
def randomIP():
- return randomIP4()
+ """Create a random IPv4 or IPv6 address."""
+ maybe = int(random.getrandbits(1))
+ ip = randomIPv4() if maybe else randomIPv6()
+ return ip
-def randomIP4():
- return ipaddr.IPAddress(random.getrandbits(32))
+def randomIPv4():
+ """Create a random IPv4 address."""
+ return ipaddr.IPv4Address(random.getrandbits(32))
-def randomPort():
- return random.randint(1,65535)
+def randomIPv6():
+ """Create a random IPv6 address."""
+ return ipaddr.IPv6Address(random.getrandbits(128))
-def gettimestamp():
- return time.strftime("%Y-%m-%d %H:%M:%S")
+def randomPort():
+ """Get a random integer in the range [1024, 65535]."""
+ return random.randint(1025, 65535)
def getHexString(size):
s = ""
for i in xrange(size):
- s+= random.choice("ABCDEF0123456789")
+ s += random.choice("ABCDEF0123456789")
return s
-def generateDesc():
-
- baseDesc = "router Unnamed %s %s 0 %s\n"\
- "opt fingerprint %s\n"\
- "opt @purpose bridge\n"\
- "opt published %s\n"\
- "router-signature\n"
- fp = "DEAD BEEF F00F DEAD BEEF F00F " + \
- getHexString(4) + " " + getHexString(4) + " " + \
- getHexString(4) + " " + getHexString(4)
- ip = randomIP()
- orport = randomPort()
- dirport = randomPort()
- ID = binascii.a2b_hex(fp.replace(" ", ""))
- df = baseDesc % (ip, orport, dirport, fp, gettimestamp())
- return (df, (ID, ip, orport, dirport))
-
-def generateStatus(info, ID=None, ip=None, orport=None, dirport=None):
- baseStatus = "r %s %s %s %s %s %d %d\n"\
- "s Running Stable\n"
-
- if info and len(info) == 4:
- ID = info[0]
- ip = info[1]
- orport = info[2]
- dirport = info[3]
- return "".join(baseStatus % ("namedontmattah", binascii.b2a_base64(ID)[:-2],
- "randomstring", gettimestamp(), ip,
- orport, dirport))
-
-def generateExtraInfo(fp, ip=None):
- baseExtraInfo = "extra-info %s %s\n"\
- "transport %s %s:%d\n"\
- "router-signature\n"
- if not ip:
- ip = randomIP()
- return "".join(baseExtraInfo % ("namedontmattah", fp,
- random.choice(["obfs2", "obfs3", "obfs2"]),
- ip, randomPort()))
-if __name__ == "__main__":
- if len(sys.argv) != 2:
- usage()
- sys.exit(0)
+def makeTimeStamp(now=None, fmt=None, variation=False, period=None):
+ """Get a random timestamp suitable for a bridge server descriptor.
+
+ :param int now: The time, in seconds since the Epoch, to generate the
+ timestamp for (and to consider as the maximum time, if other options
+ are enabled).
+ :param string fmt: A strftime(3) format string for the timestamp. If not
+ given, defaults to ISO-8601 format without the 'T' separator.
+ :param bool variation: If True, enable timestamp variation. Otherwise,
+ make all timestamps be set to the current time.
+ :type period: int or None
+ :param period: If given, vary the generated timestamps to be a random time
+ between ``period`` hours ago and the current time. If None, generate
+ completely random timestamps which are anywhere between the Unix Epoch
+ and the current time. This parameter only has an effect if
+ ``variation`` is enabled.
+ """
+ now = int(now) if now is not None else int(time.time())
+ fmt = fmt if fmt else "%Y-%m-%d %H:%M:%S"
+
+ if variation:
+ then = 1
+ if period is not None:
+ secs = int(period) * 3600
+ then = now - secs
+ # Get a random number between one epochseconds number and another
+ diff = random.randint(then, now)
+ # Then rewind the clock
+ now = diff
+
+ return time.strftime(fmt, time.localtime(now))
+
+def shouldHaveOptPrefix(version):
+ """Returns true if a tor ``version`` should have the 'opt ' prefix.
+
+ In tor, up to and including, version 0.2.3.25, server-descriptors (bridge
+ or regular) prefixed several lines with 'opt '. For the 0.2.3.x series,
+ these lines were:
+ - 'protocols'
+ - 'fingerprint'
+ - 'hidden-service-dir'
+ - 'extra-info-digest'
+
+ :param string version: One of ``SERVER_VERSIONS``.
+ :rtype: bool
+ :returns: True if we should include the 'opt ' prefix.
+ """
+ changed_in = versions.Version('0.2.4.1-alpha', package='tor')
+ our_version = versions.Version(version, package='tor')
+ if our_version < changed_in:
+ return True
+ return False
+
+def makeProtocolsLine(version=None):
+ """Generate an appropriate [bridge-]server-descriptor 'protocols' line.
+
+ :param string version: One of ``SERVER_VERSIONS``.
+ :rtype: string
+ :returns: An '@type [bridge-]server-descriptor' 'protocols' line.
+ """
+ line = ''
+ if (version is not None) and shouldHaveOptPrefix(version):
+ line += 'opt '
+ line += 'protocols Link 1 2 Circuit 1'
+ return line
+
+def convertToSpaceyFingerprint(fingerprint):
+ """Convert a colon-delimited fingerprint to be space-delimited.
+
+ Given a fingerprint with sets of two hexidecimal characters separated by
+ colons, for example a certificate or key fingerprint output from OpenSSL:
+ |
+ | 51:58:9E:8B:BF:5C:F6:5A:68:CB:6D:F4:C7:6F:98:C6:B2:02:69:45
+ |
+
+ convert it to the following format:
+ |
+ | 5158 9E8B BF5C F65A 68CB 6DF4 C76F 98C6 B202 6945
+ |
+
+ :param string fingerprint: A 2-character colon-delimited hex fingerprint.
+ :rtype: string
+ :returns: A 4-character space-delimited fingerprint.
+ """
+ # The boolean of the non-equality is necessary because -1 is somehow
+ # truthy in Python…
+ check = lambda f: bool(f.find(':') != -1)
+
+ while True:
+ if check(fingerprint):
+ fingerprint = ''.join(fingerprint.split(':', 1))
+ if check(fingerprint):
+ fingerprint = ' '.join(fingerprint.split(':', 1))
+ continue
+ break
+ break
+
+ return fingerprint
+
+def makeFingerprintLine(fingerprint, version=None):
+ """Generate an appropriate [bridge-]server-descriptor 'fingerprint' line.
+
+ For example, for tor-0.2.3.25 and prior versions, this would look like:
+ |
+ | opt fingerprint D4BB C339 2560 1B7F 226E 133B A85F 72AF E734 0B29
+ |
+
+ :param string version: One of ``SERVER_VERSIONS``.
+ :param string timestamp: The timestamp, in seconds since Epoch, to record
+ in the 'published' line.
+ :rtype: string
+ :returns: An '@type [bridge-]server-descriptor' 'published' line.
+ """
+ line = ''
+ if (version is not None) and shouldHaveOptPrefix(version):
+ line += 'opt '
+ line += 'fingerprint %s' % convertToSpaceyFingerprint(fingerprint)
+ return line
+
+def makeBandwidthLine(variance=30):
+ """Create a random 'bandwidth' line with some plausible burst variance.
+
+ From torspec.git/dir-spec.txt, §2.1 "Router descriptors":
+ | "bandwidth" bandwidth-avg bandwidth-burst bandwidth-observed NL
+ |
+ | [Exactly once]
+ |
+ | Estimated bandwidth for this router, in bytes per second. The
+ | "average" bandwidth is the volume per second that the OR is willing
+ | to sustain over long periods; the "burst" bandwidth is the volume
+ | that the OR is willing to sustain in very short intervals. The
+ | "observed" value is an estimate of the capacity this relay can
+ | handle. The relay remembers the max bandwidth sustained output over
+ | any ten second period in the past day, and another sustained input.
+ | The "observed" value is the lesser of these two numbers.
+
+ The "observed" bandwidth, in this function, is taken as some random value,
+ bounded between 20KB/s and 2MB/s. For example, say:
+
+ >>> import math
+ >>> variance = 25
+ >>> observed = 180376
+ >>> percentage = float(variance) / 100.
+ >>> percentage
+ 0.25
+
+ The ``variance`` in this context is the percentage of the "observed"
+ bandwidth, which will be added to the "observed" bandwidth, and becomes
+ the value for the "burst" bandwidth:
+
+ >>> burst = observed + math.ceil(observed * percentage)
+ >>> assert burst > observed
+
+ This doesn't do much, since the "burst" bandwidth in a real
+ [bridge-]server-descriptor is reported by the OR; this function mostly
+ serves to avoid generating completely-crazy, totally-implausible bandwidth
+ values. The "average" bandwidth value is then just the mean value of the
+ other two.
+
+ :param integer variance: The percent of the fake "observed" bandwidth to
+ increase the "burst" bandwidth by.
+ :rtype: string
+ :returns: A "bandwidth" line for a [bridge-]server-descriptor.
+ """
+ observed = random.randint(20 * 2**10, 2 * 2**30)
+ percentage = float(variance) / 100.
+ burst = int(observed + math.ceil(observed * percentage))
+ bandwidths = [burst, observed]
+ nitems = len(bandwidths) if (len(bandwidths) > 0) else float('nan')
+ avg = int(math.ceil(float(sum(bandwidths)) / nitems))
+ line = "bandwidth %s %s %s" % (avg, burst, observed)
+ return line
+
+def makeExtraInfoDigestLine(hexdigest, version):
+ """Create a line to embed the hex SHA-1 digest of the extrainfo.
+
+ :param string hexdigest: Should be the hex-encoded (uppercase) output of
+ the SHA-1 digest of the generated extrainfo document (this is the
+ extra-info descriptor, just without the signature at the end). This is
+ the same exact digest which gets signed by the OR server identity key,
+ and that signature is appended to the extrainfo document to create the
+ extra-info descriptor.
+ :param string version: One of ``SERVER_VERSIONS``.
+ :rtype: string
+ :returns: An ``@type [bridge-]server-descriptor`` 'extra-info-digest'
+ line.
+ """
+ line = ''
+ if (version is not None) and shouldHaveOptPrefix(version):
+ line += 'opt '
+ line += 'extra-info-digest %s' % hexdigest
+ return line
+
+def makeHSDirLine(version):
+ """This line doesn't do much… all the cool kids are HSDirs these days.
+
+ :param string version: One of ``SERVER_VERSIONS``.
+ :rtype: string
+ :returns: An ``@type [bridge-]server-descriptor`` 'hidden-service-dir'
+ line.
+ """
+ line = ''
+ if (version is not None) and shouldHaveOptPrefix(version):
+ line += 'opt '
+ line += 'hidden-service-dir'
+ return line
+
+def createRSAKey(bits=1024):
+ """Create a new RSA keypair.
+
+ :param integer bits: The bitlength of the keypair to generate.
+ :rtype: :class:`OpenSSL.crypto.PKey`
+ :returns: An RSA keypair of bitlength ``bits``.
+ """
+ key = OpenSSL.crypto.PKey()
+ key.generate_key(OpenSSL.crypto.TYPE_RSA, bits)
+ if not key.check():
+ raise OpenSSLKeyGenError("Couldn't create new RSA 1024-bit key")
+ return key
+
+def createNTORKey():
+ """Create a Curve25519 key."""
+ if nacl is None:
+ raise NotImplemented
+
+def createKey(selfsign=True, digest='sha1'):
+ """Create a set of public and private RSA keypairs and corresponding certs.
+
+ :param boolean selfsign: If True, use the private key to sign the public
+ certificate (otherwise, the private key will only sign the private
+ certificate to which it is attached).
+ :param string digest: The digest to use. (default: 'sha1')
+ :rtype: 4-tuple
+ :returns: (private_key, private_cert, public_key, public_cert)
+ """
+ privateKey = createRSAKey()
+ privateCert = attachKey(privateKey, createTLSCert())
+ publicKey = privateCert.get_pubkey()
+ publicCert = attachKey(publicKey, createTLSCert(), selfsign=False)
+
+ if selfsign:
+ # We already signed the publicCert with the publicKey, now we need to
+ # sign the publicCert with the privateKey
+ publicCert.sign(privateKey, digest)
+
+ return (privateKey, privateCert, publicKey, publicCert)
- df = ''
- sf = ''
- ei = ''
- count = int(sys.argv[1])
- for i in xrange(count):
- desc, info = generateDesc()
- df += desc
+def attachKey(key, cert, selfsign=True, digest='sha1', pem=False):
+ """Attach a key to a cert and optionally self-sign the cert.
- sf += generateStatus(info)
- ei += generateExtraInfo(binascii.b2a_hex(info[0]))
+ :type key: :class:`OpenSSL.crypto.PKey`
+ :param key: A previously generated key, used to generate the other half of
+ the keypair.
+ :type cert: :class:`OpenSSL.crypto.X509`
+ :param cert: A TLS certificate without a public key attached to it, such
+ as one created with :func:`createTLSCert`.
+ :param boolean selfsign: If True, use the ``key`` to self-sign the
+ ``cert``. Note that this will result in several nasty OpenSSL errors
+ if you attempt to export the public key of a cert in order to create
+ another cert which *only* holds the public key. (Otherwise, if you
+ used the first cert in the following example, it contains both halves
+ of the RSA keypair.) Do this instead:
+ >>> secret_key = createRSAKey()
+ >>> secret_cert = attachKey(secret_key, createTLSCert(selfsign=True))
+ >>> public_key = secret_cert.get_pubkey()
+ >>> public_cert = attachKey(public_key, createTLSCert, selfsign=False)
+
+ :param string digest: The digest to use. Check your OpenSSL installation
+ to see which are supported. We pretty much only care about 'sha1' and
+ 'sha256' here.
+ :param boolean pem: If True, return a 3-tuple of PEM-encoded strings, one
+ for each of (certificate, private_key, public_key), where
+ 'certificate' is the original ``cert`` with the ``key`` attached,
+ 'private_key' is the private RSA modulus, primes, and exponents
+ exported from the 'certificate', and 'public_key' is the public RSA
+ modulus exported from the cert. NOTE: Using this when passing in a key
+ with only the public RSA modulus (as described above) will result in
+ nasty OpenSSL errors. Trust me, you do *not* want to try to parse
+ OpenSSL's errors.
+ :raises: An infinite, labyrinthine mire of non-Euclidean OpenSSL errors
+ with non-deterministic messages and self-referential errorcodes,
+ tangled upon itself in contempt of sanity, hope, and decent software
+ engineering practices.
+ :returns: If ``pem`` is True, then the values described there are
+ returned. Otherwise, returns the ``cert`` with the ``key`` attached to
+ it.
+ """
+ # Attach the key to the certificate
+ cert.set_pubkey(key)
+
+ if selfsign:
+ # Self-sign the cert with the key, using the specified hash digest
+ cert.sign(key, digest)
+
+ if pem:
+ certificate = OpenSSL.crypto.dump_certificate(PEM, cert)
+ private_key = OpenSSL.crypto.dump_privatekey(PEM, key)
+ public_key = OpenSSL.crypto.dump_privatekey(PEM, cert.get_pubkey())
+ return certificate, private_key, public_key
+ return cert
+
+def createTLSCert(lifetime=None):
+ """Create a TLS certificate.
+
+ :param integer lifetime: The time, in seconds, that the certificate should
+ remain valid for.
+ :rtype: :class:`OpenSSL.crypto.X509`
+ :returns: A certificate, unsigned, and without a key attached to it.
+ """
+ if not lifetime:
+ # see `router_initialize_tls_context()` in src/or/router.c
+ lifetime = 5 + random.randint(0, 361)
+ lifetime = lifetime * 24 * 3600
+ if int(random.getrandbits(1)):
+ lifetime -= 1
+
+ cert = OpenSSL.crypto.X509()
+ cert.gmtime_adj_notBefore(0) # Not valid before now
+ cert.gmtime_adj_notAfter(lifetime)
+ return cert
+
+def createTLSLinkCert(lifetime=7200):
+ """Create a certificate for the TLS link layer.
+
+ The TLS certificate used for the link layer between Tor relays, and
+ between clients and their bridges/guards, has a shorter lifetime than the
+ other certificates. Currently, these certs expire after two hours.
+
+ :param integer lifetime: The time, in seconds, that the certificate should
+ remain valid for.
+ :rtype: :class:`OpenSSL.crypto.X509`
+ :returns: A certificate, unsigned, and without a key attached to it.
+ """
+ cert = createTLSCert(lifetime)
+ cert.get_subject().CN = 'www.' + getHexString(16) + '.net'
+ cert.get_issuer().CN = 'www.' + getHexString(10) + '.com'
+ return cert
+
+def getPEMPublicKey(cert):
+ publicKey = OpenSSL.crypto.dump_privatekey(PEM, cert.get_pubkey())
+ # It says "PRIVATE KEY" just because the stupid pyOpenSSL wrapper is
+ # braindamaged. You can check that it doesn't include the RSA private
+ # exponents and primes by substituting ``OpenSSL.crypto.FILETYPE_TEXT``
+ # for the above ``PEM``.
+ publicKey = re.sub(OPENSSL_BEGIN_KEY, TOR_BEGIN_KEY, publicKey)
+ publicKey = re.sub(OPENSSL_END_KEY, TOR_END_KEY, publicKey)
+ return publicKey
+
+def getPEMPrivateKey(key):
+ privateKey = OpenSSL.crypto.dump_privatekey(PEM, key)
+ privateKey = re.sub(OPENSSL_BEGIN_KEY, TOR_BEGIN_SK, privateKey)
+ privateKey = re.sub(OPENSSL_END_KEY, TOR_END_SK, privateKey)
+ return privateKey
+
+def makeOnionKeys(bridge=True, digest='sha1'):
+ """Make all the keys and certificates necessary to fake an OR.
+
+ :param boolean bridge: If False, generate a server OR ID key, a signing
+ key, and a TLS certificate/key pair. If True, generate a client ID key
+ as well.
+ :param string digest: The digest to use. (default: 'sha1')
+ :returns: The server ID key, and a tuple of strings (fingerprint,
+ onion-key, signing-key), where onion-key and secret key are the strings
+ which should directly go into a server-descriptor. There are a *ton* of
+ keys and certs in the this function. If you need more for some reason,
+ this is definitely the thing you want to modify.
+ """
+ serverID = createKey(True)
+ SIDSKey, SIDSCert, SIDPKey, SIDPCert = serverID
+ serverLinkCert = createTLSLinkCert()
+ serverLinkCert.sign(SIDSKey, digest)
+
+ if bridge:
+ # For a bridge, a "client" ID key is used to generate the fingerprint
+ clientID = createKey(True)
+ CIDSKey, CIDSCert, CIDPKey, CIDPCert = clientID
+
+ # XXX I think we're missing some of the signatures
+ # see torspec.git/tor-spec.txt §4.2 on CERTS cells
+ clientLinkCert = createTLSLinkCert()
+ clientLinkCert.sign(CIDSKey, digest)
+ else:
+ CIDSKey, CIDSCert, CIDPKey, CIDPCert = serverID
+
+ signing = createKey()
+ signSKey, signSCert, signPKey, signPCert = signing
+ onion = createKey()
+ onionSKey, onionSCert, onionPKey, onionPCert = onion
+
+ # This is the fingerprint of the server ID key, if we aren't a bridge. If
+ # we are a bridge, then this is the real fingerprint, which goes into our
+ # descriptor (but not the one that other ORs see when they connect to us)
+ fingerprint = CIDPCert.digest(digest)
+
+ onionKeyString = 'onion-key\n%s' % getPEMPublicKey(onionPCert)
+ signingKeyString = 'signing-key\n%s' % getPEMPublicKey(signPCert)
+
+ # XXX we don't need anything else… right?
+ return SIDSKey, (fingerprint, onionKeyString, signingKeyString)
+
+def generateExtraInfo(fingerprint, ts, ipv4, port):
+ """Create an OR extra-info document.
+
+ See §2.2 "Extra-info documents" in torspec.git/dir-spec.txt.
+
+ :param string fingerprint: A space-separated, hex-encoded, SHA-1 digest of
+ the OR's private identity key. See :func:`convertToSpaceyFingerprint`.
+ :param string ts: An ISO-8601 timestamp. See :func:`makeTimeStamp`.
+ :param string ipv4: An IPv4 address.
+ :param string port: The OR's ORPort.
+ :rtype: string
+ :returns: An extra-info document (unsigned).
+ """
+ extra = []
+ extra.append("extra-info Unnamed %s" % fingerprint)
+ extra.append("published %s" % ts)
+ extra.append("write-history %s (900 s)\n3188736,2226176,2866176" % ts)
+ extra.append("read-history %s (900 s)\n3891200,2483200,2698240" % ts)
+ extra.append("dirreq-write-history %s (900 s)\n1024,0,2048" % ts)
+ extra.append("dirreq-read-history %s (900 s)\n0,0,0" % ts)
+ extra.append("geoip-db-digest %s\ngeoip6-db-digest %s"
+ % (getHexString(40), getHexString(40)))
+ extra.append("dirreq-stats-end %s (86400 s)\ndirreq-v3-ips" % ts)
+ extra.append("dirreq-v3-reqs\ndirreq-v3-resp")
+ extra.append(
+ "ok=16,not-enough-sigs=0,unavailable=0,not-found=0,not-modified=0,busy=0")
+ extra.append("dirreq-v3-direct-dl complete=0,timeout=0,running=0")
+ extra.append("dirreq-v3-tunneled-dl complete=12,timeout=0,running=0")
+ extra.append("transport obfs3 %s:%d" % (ipv4, port + 1))
+ extra.append("transport obfs2 %s:%d" % (ipv4, port + 2))
+ extra.append("bridge-stats-end %s (86400 s)\nbridge-ips ca=8" % ts)
+ extra.append("bridge-ip-versions v4=8,v6=0\nbridge-ip-transports <OR>=8")
+ extra.append("router-signature")
+
+ return '\n'.join(extra)
+
+def generateNetstatus(idkey_digest, server_desc_digest, timestamp,
+ ipv4, orport, ipv6=None, dirport=None,
+ flags='Fast Guard Running Stable Valid',
+ bandwidth_line=None):
+
+ idkey_b64 = binascii.b2a_base64(idkey_digest)
+ idb64 = str(idkey_b64).strip().rstrip('=========')
+ server_b64 = binascii.b2a_base64(server_desc_digest)
+ srvb64 = str(server_b64).strip()
+
+ if bandwidth_line is not None:
+ bw = int(bandwidth_line.split()[-1]) / 1024 # The 'observed' value
+ dirport = dirport if dirport else 0
+
+ status = []
+ status.append("r Unnamed %s %s %s %s %s %d" % (idb64, srvb64, timestamp,
+ ipv4, orport, dirport))
+ if ipv6 is not None:
+ status.append("a [%s]:%s" % (ipv6, orport))
+ status.append("s %s\nw Bandwidth=%s\np reject 1-65535\n" % (flags, bw))
+
+ return '\n'.join(status)
+
+def signDescriptorDigest(key, descriptorDigest, digest='sha1'):
+ """Ugh...I hate OpenSSL.
+
+ The extra-info-digest is a SHA-1 hash digest of the extrainfo document,
+ that is, the entire extrainfo descriptor up until the end of the
+ 'router-signature' line and including the newline, but not the actual
+ signature.
+
+ The signature at the end of the extra-info descriptor is a signature of
+ the above extra-info-digest. This signature is appended to the end of the
+ extrainfo document, and the extra-info-digest is added to the
+ 'extra-info-digest' line of the [bridge-]server-descriptor.
+
+ The first one of these was created with a raw digest, the second with a
+ hexdigest. They both encode the the 'sha1' digest type if you check the
+ `-asnparse` output (instead of `-raw -hexdump`).
+
+ ∃!isisⒶwintermute:(feature/9865 *$<>)~/code/torproject/bridgedb/scripts ∴ openssl rsautl -inkey eiprivkey -verify -in eisig1 -raw -hexdump
+ 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0050 - ff ff ff ff ff ff ff ff-ff ff ff ff 00 30 21 30 .............0!0
+ 0060 - 09 06 05 2b 0e 03 02 1a-05 00 04 14 42 25 41 fb ...+........B%A.
+ 0070 - 82 ef 11 f4 5f 2c 95 53-67 2d bb fe 7f c2 34 7f ...._,.Sg-....4.
+ ∃!isisⒶwintermute:(feature/9865 *$<>)~/code/torproject/bridgedb/scripts ∴ openssl rsautl -inkey eiprivkey -verify -in eisig2 -raw -hexdump
+ 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
+ 0050 - ff ff ff ff ff ff ff ff-ff ff ff ff 00 30 21 30 .............0!0
+ 0060 - 09 06 05 2b 0e 03 02 1a-05 00 04 14 44 30 ab 90 ...+........D0..
+ 0070 - 93 d1 08 21 df 87 c2 39-2a 04 1c a5 bb 34 44 cd ...!...9*....4D.
+
+ see http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptograp…
+ for why this function is totally wrong.
+ """
+ sig = binascii.b2a_base64(OpenSSL.crypto.sign(key, descriptorDigest,
+ digest))
+ sigCopy = sig
+ originalLength = len(sigCopy.replace('\n', ''))
+
+ # Only put 64 bytes of the base64 signature per line:
+ sigSplit = []
+ while len(sig) > 0:
+ sigSplit.append(sig[:64])
+ sig = sig[64:]
+ sigFormatted = '\n'.join(sigSplit)
+
+ sigFormattedCopy = sigFormatted
+ formattedLength = len(sigFormattedCopy.replace('\n', ''))
+
+ if originalLength != formattedLength:
+ print("WARNING: signDescriptorDocument(): %s"
+ % "possible bad reformatting for signature.")
+ print("DEBUG: signDescriptorDocument(): original=%d formatted=%d"
+ % (originalLength, formattedLength))
+ print("DEBUG: original:\n%s\nformatted:\n%s"
+ % (sigCopy, sigFormatted))
+
+ sigWithHeaders = TOR_BEGIN_SIG + '\n' \
+ + sigFormatted \
+ + TOR_END_SIG + '\n'
+ return sigWithHeaders
+
+def generateDescriptors():
+ """Create keys, certs, signatures, documents and descriptors for an OR.
+
+ :returns:
+ A 3-tuple of strings:
+ - a ``@type [bridge-]extra-info`` descriptor,
+ - a ``@type [bridge-]server-descriptor``, and
+ - a ``@type network-status`` document
+ for a mock Tor relay/bridge.
+ """
+ ipv4 = randomIPv4()
+ ipv6 = randomIPv6()
+ port = randomPort()
+
+ vers = random.choice(SERVER_VERSIONS)
+ uptime = int(random.randint(1800, 63072000))
+ bandwidth = makeBandwidthLine()
+ timestamp = makeTimeStamp(variation=True, period=36)
+ protocols = makeProtocolsLine(vers)
+
+ idkey, (fingerprint, onionkey, signingkey) = makeOnionKeys()
+ idkey_private = getPEMPrivateKey(idkey)
+ idkey_digest = hashlib.sha1(idkey_private).digest()
+
+ fpr = convertToSpaceyFingerprint(fingerprint)
+
+ extrainfo_document = generateExtraInfo(fpr, timestamp, ipv4, port)
+ extrainfo_digest = hashlib.sha1(extrainfo_document).digest()
+ extrainfo_hexdigest = hashlib.sha1(extrainfo_document).hexdigest().upper()
+ extrainfo_sig = signDescriptorDigest(idkey, extrainfo_digest)
+ extrainfo_desc = extrainfo_document + extrainfo_sig
+
+ server = []
+ server.append("@purpose bridge")
+ server.append("router Unnamed %s %s 0 0" % (ipv4, port))
+ server.append("or-address [%s]:%s" % (ipv6, port))
+ server.append("platform Tor %s on Linux" % vers)
+ server.append("%s\npublished %s" % (protocols, timestamp))
+ server.append("%s" % makeFingerprintLine(fingerprint, vers))
+ server.append("uptime %s\n%s" % (uptime, bandwidth))
+ server.append("%s" % makeExtraInfoDigestLine(extrainfo_hexdigest, vers))
+ server.append("%s%s%s" % (onionkey, signingkey, makeHSDirLine(vers)))
+ server.append("contact Somebody <somebody(a)example.com>")
+ if nacl is not None:
+ server.append("ntor-onion-key %s"
+ % binascii.b2a_base64(createNTORKey()))
+ server.append("reject *:*\nrouter-signature\n")
+ server_desc = '\n'.join(server)
+
+ server_desc_digest = hashlib.sha1(server_desc).digest()
+ netstatus_desc = generateNetstatus(idkey_digest, server_desc_digest,
+ timestamp, ipv4, port, ipv6=ipv6,
+ bandwidth_line=bandwidth)
+ server_desc += signDescriptorDigest(idkey, server_desc_digest)
+ return extrainfo_desc, server_desc, netstatus_desc
+
+def writeDescToFile(filename, descriptors):
+ """Open ``filename`` and write a string containing descriptors into it.
+
+ :param string filename: The name of the file to write to.
+ :param string descriptors: A giant string containing descriptors,
+ newlines, formatting, whatever is necessary to make it look like a
+ file tor would generate.
+ """
+ encoding = sys.getfilesystemencoding()
+ descript = descriptors.encode(encoding, 'replace')
try:
- f = open("networkstatus-bridges", 'w')
- f.write(sf)
- f.close()
- except:
- print "Failed to open or write to status file"
+ with open(filename, 'wb', encoding=encoding, errors='replace') as fh:
+ fh.write(descript)
+ fh.flush()
+ except (IOError, OSError) as err:
+ print("Failure while attempting to write descriptors to file '%s': %s"
+ % (filename, err.message))
+
+def create(count):
+ """Generate all types of descriptors and write them to files.
+
+ :param integer count: How many sets of descriptors to generate, i.e. how
+ many mock bridges/relays to create.
+ """
+ if nacl is None:
+ print("WARNING: Can't import PyNaCl. NTOR key generation is disabled.")
+ print("Generating %d bridge descriptors..." % int(count))
+ server_descriptors = list()
+ netstatus_consensus = list()
+ extrainfo_descriptors = list()
try:
- f = open("bridge-descriptors", 'w')
- f.write(df)
- f.close()
- except:
- print "Failed to open or write to descriptor file"
+ for i in xrange(int(count)):
+ extrainfo, server, netstatus = generateDescriptors()
+ server_descriptors.append(server)
+ netstatus_consensus.append(netstatus)
+ extrainfo_descriptors.append(extrainfo)
+ except KeyboardInterrupt as keyint:
+ print("Received keyboard interrupt.")
+ print("Stopping descriptor creation and exiting.")
+ code = 1515
+ finally:
+ print("Writing descriptors to files...", end="")
+ descriptor_files = {
+ "networkstatus-bridges": ''.join(netstatus_consensus),
+ "bridge-descriptors": ''.join(server_descriptors),
+ "extra-infos": ''.join(extrainfo_descriptors)}
+ for fn, giantstring in descriptor_files.items():
+ writeDescToFile(fn, giantstring)
+ print("Done.")
+ code = 0
+ sys.exit(code)
+if __name__ == "__main__":
try:
- f = open("extra-infos", 'w')
- f.write(ei)
- f.close()
- except:
- print "Failed to open or write to extra-info file"
+ parser = getArgParser()
+ options = parser.parse_args()
+
+ if options.quiet:
+ print = lambda x: True
+ if options.version:
+ print("gen_bridge_descriptors-%s" % __version__)
+ sys.exit(0)
+ if options.descriptors and (options.descriptors > 0):
+ create(options.descriptors)
+ else:
+ sys.exit(parser.format_help())
+
+ except Exception as error:
+ sys.exit(error)
1
0
[bridgedb/master] Add documentation on current bridge descriptor formats.
by isis@torproject.org 12 Jan '14
by isis@torproject.org 12 Jan '14
12 Jan '14
commit d880b0aa5d3a9fd6598dcd482736af6f834562f6
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 08:57:01 2013 +0000
Add documentation on current bridge descriptor formats.
These aren't sanitised -- they are completely faked. There has been so much
confusion over what these things look like...I really just want something that
I can point to. I (or anyone else) should update the metrics dataformat pages,
as well as perhaps provide better clarification in tor-spec.git for the lines
whose format is unclear.
* ADD docs/DESCRIPTORS.md.
---
doc/DESCRIPTORS.md | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 190 insertions(+)
diff --git a/doc/DESCRIPTORS.md b/doc/DESCRIPTORS.md
new file mode 100644
index 0000000..087d4e0
--- /dev/null
+++ b/doc/DESCRIPTORS.md
@@ -0,0 +1,190 @@
+-*- mode: markdown ; coding: utf-8 -*-
+
+# DESCRIPTORS
+
+## Bridge router descriptors
+
+As of tor-0.2.3.35, bridge router descriptors (found in the
+`bridge-descriptors` file), contain the 'opt ' prefix before certain
+fields. They look like this:
+
+ @purpose bridge
+ router Unnamed 10.0.1.113 9001 0 0
+ platform Tor 0.2.3.25 on Linux
+ opt protocols Link 1 2 Circuit 1
+ published 2013-10-22 02:34:48
+ opt fingerprint D4BB C339 2560 1B7F 226E 133B A85F 72AF E734 0B29
+ uptime 938148
+ bandwidth 25200 49200 44033
+ opt extra-info-digest 3ABD120FCA67B18D48C8C8725B75EC7387A82C17
+ onion-key
+ -----BEGIN RSA PUBLIC KEY-----
+ MIGJAoGBAL1bKPn8DUH5+EcnbSrdaIp2XU1gwJxCPTLdw4wDGNHT91a3liT/u8en
+ FJYWIjc0g62hhZqJdkJkzxZypBoPUhMdF+wSKDVvNFBHRPPdJftrKTBuXEDg9ho1
+ Ku5hGXpeWA9/ZVlZylI1EC0wMU/VYVF98v51TkURUiCoAX69IumZAgM8AAE=
+ -----END RSA PUBLIC KEY-----
+ signing-key
+ -----BEGIN RSA PUBLIC KEY-----
+ MIGJAoGBAOUKKy1AqC5GyVNOUFDsBjQ6bYS+8yVIqgDo0g0yzN+arrEkPRs1xqUk
+ xWuk1IhwUIpZN3F6rwuzWbCFMkRW4TA4Zih55SRdAY1z9sLq5Fog+1dJtMiXlP5+
+ JCqIA44vfMUwpXG9DzgdTG4//UoJ0gKL62whVizcM9y/o4vyY0EFAgMBAAE=
+ -----END RSA PUBLIC KEY-----
+ opt hidden-service-dir
+ reject *:*
+ router-signature
+ -----BEGIN SIGNATURE-----
+ rd981ZHtDmF1wiw37lpOh2PrBRunD5wb+WaYpZsKSwDv3hQFOTUwROQvUJY26wYH
+ QT+02oM24yEfGXrs0uwWg4ycnmmskurrJKpNDPSJynYHKy82mxTNNE66Jr3FqytC
+ VXAN4HoclQiNWdgZF3kAdCXW+8YR/rqyYtSOaLFOxgs=
+ -----END SIGNATURE-----
+
+As of tor-0.2.4.15, bridge router descriptors may be missig the 'opt ' prefix,
+and thus appear like this:
+
+ @purpose bridge
+ router Unnamed 10.0.1.171 9001 0 0
+ platform Tor 0.2.4.17-rc on Linux
+ protocols Link 1 2 Circuit 1
+ published 2013-10-22 02:34:55
+ fingerprint 6CE8 83D8 75E0 7996 7732 29E8 CA67 7A62 2B7F 05EF
+ uptime 386679
+ bandwidth 1073741824 1073741824 55832
+ extra-info-digest FDAB376C3D6F1AA727C31EC6006745FB48663652
+ onion-key
+ -----BEGIN RSA PUBLIC KEY-----
+ MIGJAoGBAL9L3mAtj8PtPSWFJ1s9gRm76b5OWL+46X2nL4dWl0eW6z+b88tlAFN5
+ EZXEJ4OB8OnLzF4Q0vbSvWm2StqK+68M7FFCTp8c2ldrejJRK6PvTcBy/B0cejCF
+ 16+GUBw402j8znpxJFolT7A1zD5FvuPxU+2paN/hUqPTiNQDKkghAgMBAAE=
+ -----END RSA PUBLIC KEY-----
+ signing-key
+ -----BEGIN RSA PUBLIC KEY-----
+ MIGJAoGBAMepPKfnpG/EnoFC3xlRfckgmAS2DASLcAy9MWmVmHy9pvwNZauO2gtd
+ WTbuQRI56xT25aIZhX0k0HkAPe4S3LOz+Llg2x7S/zpyDMtLkSDXvBdc+uBWea3u
+ 9O1w+SLxa4YujADMuhuiBDR3BYGQcibmMhwhLAgxZ0b/62m/VIb7AgMBAAE=
+ -----END RSA PUBLIC KEY-----
+ hidden-service-dir
+ ntor-onion-key E2YxIe8jZvZ28DkTeU0PonF9D9Qr6/5QsP29AWrUAno=
+ contact Somebody <somebody AT nowhere DOT net>
+ reject *:*
+ router-signature
+ -----BEGIN SIGNATURE-----
+ q5Wk1Sg6K84WZjXcbu8n7owGERVdAKMGQ/YBX7fv9jQo0OnTijFAF7SNUTmy7ZlI
+ wtiwqhquDB3BTZ4FL9yZeoBnVhzlWGpzwef8zAQ5ivlPckYfUWHKRO4eux9tebkT
+ B3RnIjfPs6q+m8gGz0ZDk7x7f3oDwyz/TKCgpZubp/w=
+ -----END SIGNATURE-----
+
+# Extra-info descriptors
+
+Bridge extra-info descriptors (from the `cached-extrainfo` and
+`cached-extrainfo.new` files) contain extra data pertaining to a bridge. A
+minimal bridge extra-info descriptor looks like this:
+
+ extra-info Unnamed BFB9D952B9965847C42A0E214077C7DACA69275F
+ published 2013-10-22 02:30:12
+ write-history 2013-10-22 02:16:37 (900 s)
+ 92160,15360,9216,4096,173056,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,558080,552960,9216,6144,97280,5120,4096,3072,99328,9216,6144,4096,102400,11264,0,0,114688,6144,0,0,0,711680,31744,660480,23552,7168,5120,57344,8192,6144,4096,195584,24576,8192,8192,186368,6144,8192,8192,152576,16384,11264,10240,119808,33792,11264,6144
+ read-history 2013-10-22 02:16:37 (900 s)
+ 1079296,33792,10240,7168,1199104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3818496,586752,14336,11264,1107968,10240,8192,6144,1134592,12288,9216,7168,1186816,22528,4096,0,1222656,11264,0,0,0,1857536,73728,1215488,23552,10240,5120,504832,13312,10240,8192,1510400,44032,13312,11264,1271808,9216,11264,11264,1173504,48128,15360,13312,1154048,70656,15360,9216
+ router-signature
+ -----BEGIN SIGNATURE-----
+ u4qIZVeW67OPH7JTLsdHUVgUbqnjRjaIZwiQeUeBjTVO/NDJqZq5xeBDQGT3lNXN
+ 0/wm+X+2XuEDbQY2WryKC4pZ80/ArKlXUPRlblaw8soz22Q+6WtOJ/XOgFG1AzHz
+ L6IYwgtDs3BXEx3p7bTtfFTg2resiyU+T3XT6FBDHvU=
+ -----END SIGNATURE-----
+
+Whereas a more dense bridge extra-info descriptor looks like this:
+
+ extra-info Unnamed 48C9D4F2440997ACB32C88479A97B3ABF9820AF3
+ published 2013-10-22 03:19:50
+ write-history 2013-10-22 02:57:54 (900 s)
+ 87040,8192,6144,86016,23552,2048,16384,8192,79872,8192,72704,10240,19456,78848,9216,6144,4096,2048,97280,18432,70656,30720,9216,9216,628736,77824,4096,4096,10240,144384,9216,48128,38912,92160,27648,6144,2048,16384,6144,92160,18432,51200,12288,16384,69632,7168,8192,1024,76800,14336,1024,82944,13312,79872,7168,22528,95232,60416,17408,4096,5120,17408,89088,1024,5120,132096,8192,19456,5120,6144,8192,103424,7168,91136,3072,8192,44032,10240,5120,19456,68608,100352,19456,3072,82944,20480,6144,8192,63488,13312,5120,14336,76800,8192,59392,8192
+ read-history 2013-10-22 03:12:54 (900 s)
+ 11264,9216,1069056,40960,6144,16384,11264,1053696,11264,1031168,22528,22528,668672,29696,9216,6144,2048,1068032,31744,486400,60416,13312,8192,1206272,674816,3072,8192,14336,1183744,26624,464896,409600,135168,205824,8192,5120,17408,9216,1125376,33792,481280,24576,16384,683008,8192,11264,1024,1080320,13312,1024,1108992,26624,739328,17408,31744,995328,227328,51200,3072,8192,21504,1173504,4096,6144,1225728,30720,22528,5120,9216,11264,1195008,15360,745472,5120,11264,483328,17408,8192,24576,715776,1115136,49152,2048,927744,28672,10240,11264,688128,20480,8192,17408,1048576,11264,630784,11264,7168
+ geoip-db-digest 207A8167FC83230884A7B463B8EE12385CF1874F
+ geoip6-db-digest 7F82A502C248B0CFBCCF6FE370919E34E04A21FA
+ dirreq-write-history 2013-10-21 18:36:36 (900 s)
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1329152,2048
+ dirreq-read-history 2013-10-21 18:36:36 (900 s)
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,199680,2048
+
+If a bridge extra-info descriptor has the `dirreq-read-history` or the
+`dirreq-write-history` lines shown above, then either of the following lines
+will come after it (but not both):
+
+ dirreq-stats-end 2013-10-21 17:27:06 (86400 s)
+ bridge-stats-end 2013-10-21 17:27:06 (86400 s)
+
+Optionally followed by:
+
+ dirreq-v3-ips
+ dirreq-v2-ips
+ dirreq-v3-reqs
+ dirreq-v2-reqs
+ dirreq-v3-resp
+ ok=0,not-enough-sigs=0,unavailable=0,not-found=0,not-modified=0,busy=0
+ dirreq-v2-resp ok=0,unavailable=0,not-found=0,not-modified=0,busy=0
+ dirreq-v3-direct-dl complete=0,timeout=0,running=0
+ dirreq-v2-direct-dl complete=0,timeout=0,running=0
+ dirreq-v3-tunneled-dl complete=0,timeout=0,running=0
+ dirreq-v2-tunneled-dl complete=0,timeout=0,running=0
+ bridge-stats-end 2013-10-21 17:28:15 (86400 s)
+ bridge-ips de=8,nl=8,us=8
+
+And, if it include the `bridge-ips` line, it MAY include the following right
+afterwards:
+
+ bridge-ip-versions v4=16,v6=8
+
+An extra-info descriptor will always end with a signature, like this:
+
+ router-signature
+ -----BEGIN SIGNATURE-----
+ f4ed3BwfcbH36E9ODxDSideWhld5IhlsBi9alOh10UFCuqdvXcCkgzjB0s3EC5sf
+ hOjQkH96MdF8mtqGtJdEyA00lCqDkCulIrlgDlJRsj9AI29KeMjLPNb+7erNzPPL
+ 40f0vr+zuKQfUiI0piSR4txrEdAY58dDY0Hl1yEcsfo=
+ -----END SIGNATURE-----
+
+## An bridge extra-info descriptor for a bridge with pluggable transports
+
+The following is an example of a bridge which supports the `obfs2` and `obfs3`
+obproxy pluggable transport types:
+
+ extra-info Unnamed DD91800E06C195B0AF804E30DB07830AC991AFD4
+ published 2013-10-22 02:14:04
+ write-history 2013-10-22 01:59:38 (900 s)
+ 3188736,2226176,2866176,2256896,2229248,2721792
+ read-history 2013-10-22 01:59:38 (900 s)
+ 3891200,2483200,2698240,1789952,1921024,2811904
+ dirreq-write-history 2013-10-22 01:59:38 (900 s)
+ 1024,0,2048,0,1024,0
+ dirreq-read-history 2013-10-22 01:59:38 (900 s)
+ 0,0,0,0,0,0
+ geoip-db-digest 67D32F60547F141E16FB0705D1F1710471697228
+ geoip6-db-digest 9082A502C248B0CFBCCF6F9370919E34E04B21F2
+ dirreq-stats-end 2013-10-21 13:04:22 (86400 s)
+ dirreq-v3-ips
+ dirreq-v3-reqs
+ dirreq-v3-resp
+ ok=16,not-enough-sigs=0,unavailable=0,not-found=0,not-modified=0,busy=0
+ dirreq-v3-direct-dl complete=0,timeout=0,running=0
+ dirreq-v3-tunneled-dl complete=12,timeout=0,running=0
+ transport obfs3 10.0.1.111:3333
+ transport obfs2 10.0.1.111:2222
+ bridge-stats-end 2013-10-21 13:04:24 (86400 s)
+ bridge-ips ca=8
+ bridge-ip-versions v4=8,v6=0
+ bridge-ip-transports <OR>=8
+ router-signature
+ -----BEGIN SIGNATURE-----
+ Bo/HHLbGEj90z+JWlHQgbahrAh83prAUicv3fgdldrIjbHrPRpJ2ep9r/WgJY4KO
+ TANz3XcqqfhUI5rg2AzjUif8xHUZv152xqgErZEXxn+m4JmEU03qAShT0e8eMj2S
+ D9FLbPlXw4NWy9B32IT/luOHsENaAJNvOv7ociMPnsM=
+ -----END SIGNATURE-----
+
+## Bridge router microdescriptors
+
+ r Unnamed /wywABJee98ZPOiCGYM1dpgQc70 NpK1tsi97A+SH8s0evowXkRcyr8 2013-10-22 01:49:45 88.200.197.4 9001 0
+ a [6212:b13d:252e:479d:32b8:d713:3718:2fac]:9001
+ s Fast Guard Running Stable Valid
+ w Bandwidth=53
+ p reject 1-65535
1
0
[bridgedb/master] Fix the interface between bridgedb and the descriptor generator.
by isis@torproject.org 12 Jan '14
by isis@torproject.org 12 Jan '14
12 Jan '14
commit fd4d3007997b2d827fc95b30edbcde93e331f3e0
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 08:49:18 2013 +0000
Fix the interface between bridgedb and the descriptor generator.
---
lib/bridgedb/opt.py | 27 +++++++++++++++++++++++----
lib/bridgedb/runner.py | 26 ++++++++++++--------------
setup.py | 9 +++++----
3 files changed, 40 insertions(+), 22 deletions(-)
diff --git a/lib/bridgedb/opt.py b/lib/bridgedb/opt.py
index bedfaec..d3532b6 100644
--- a/lib/bridgedb/opt.py
+++ b/lib/bridgedb/opt.py
@@ -53,8 +53,6 @@ class BaseOptions(usage.Options):
private relays acting as bridges into the Tor network. See `bridgedb
<command> --help` for addition help.""")
- optFlags = [['verbose', 'v', 'Log to stdout']]
-
def opt_rundir(self, rundir):
"""Change to this directory"""
if not rundir:
@@ -75,6 +73,19 @@ class BaseOptions(usage.Options):
usage.Options.__init__(self)
self['rundir'] = os.path.join(os.getcwdu(), 'run')
self['version'] = self.opt_version
+ self['verbosity'] = 30
+
+ def opt_quiet(self):
+ """Decrease verbosity"""
+ # We use '10' because then it corresponds to the log levels
+ self['verbosity'] -= 10
+
+ def opt_verbose(self):
+ """Increase verbosity"""
+ self['verbosity'] += 10
+
+ opt_q = opt_quiet
+ opt_v = opt_verbose
def opt_version(self):
"""Display BridgeDB's version and exit."""
@@ -90,7 +101,6 @@ class TestOptions(BaseOptions):
optFlags = [['coverage', 'c', 'Generate coverage statistics']]
optParameters = [
- ['descriptors', 'n', 1000, 'Generate <N> fake bridge descriptors'],
['file', 'f', None, 'Run tests in specific file(s) (trial only)'],
['unittests', 'u', False, 'Run unittests in bridgedb.Tests'],
['trial', 't', True, 'Run twisted.trial tests in bridgedb.test']]
@@ -108,6 +118,14 @@ class TestOptions(BaseOptions):
"""Parse any additional arguments after the options and flags."""
self['test_args'] = args
+class MockOptions(BaseOptions):
+ """Suboptions for creating necessary conditions for testing purposes."""
+
+ optParameters = [
+ ['descriptors', 'n', 1000,
+ '''Generate <n> mock bridge descriptor sets
+ (types: netstatus, extrainfo, server)''']]
+
class MainOptions(BaseOptions):
"""Main commandline options parser for BridgeDB."""
@@ -118,4 +136,5 @@ class MainOptions(BaseOptions):
optParameters = [
['config', 'c', 'bridgedb.conf', 'Configuration file']]
subCommands = [
- ['test', None, TestOptions, "Run twisted.trial tests or unittests"]]
+ ['test', None, TestOptions, "Run twisted.trial tests or unittests"],
+ ['mock', None, MockOptions, "Generate a testing environment"]]
diff --git a/lib/bridgedb/runner.py b/lib/bridgedb/runner.py
index 7f38e95..3ba61ec 100644
--- a/lib/bridgedb/runner.py
+++ b/lib/bridgedb/runner.py
@@ -32,24 +32,22 @@ def generateDescriptors(options):
"""
import subprocess
+ proc = None
+ rundir = options['rundir']
script = 'gen_bridge_descriptors'
count = options.subOptions['descriptors']
try:
- print("Generating %s bridge descriptors..." % str(howmany))
- proc = subprocess.Popen([script, str(count)])
- except Exception as exc:
- print(exc)
- print("There was an error generating bridge descriptors.")
- else:
- proc.wait()
- if proc.returncode:
- print("There was an error generating bridge descriptors. (%s: %d)"
- % ("Returncode", proc.returncode))
- else:
- print("Sucessfully bridge generated descriptors.")
+ proc = subprocess.Popen([script, '-n', str(count)],
+ close_fds=True, cwd=rundir)
finally:
- del subprocess
- return
+ if proc is not None:
+ proc.wait()
+ if proc.returncode:
+ print("There was an error generating bridge descriptors.",
+ "(Returncode: %d)" % proc.returncode)
+ else:
+ print("Sucessfully bridge generated descriptors.")
+ del subprocess
def runTrial(options):
"""Run Twisted trial based unittests, optionally with coverage.
diff --git a/setup.py b/setup.py
index d01f646..f73347f 100644
--- a/setup.py
+++ b/setup.py
@@ -74,7 +74,6 @@ install_i18n = os.path.join('bridgedb', 'i18n')
# Directory to install docs, license, and other text resources into:
install_docs = os.path.join('share', 'doc', 'bridgedb')
-
def get_cmdclass():
"""Get our cmdclass dictionary for use in setuptool.setup().
@@ -255,11 +254,13 @@ setuptools.setup(
url='https://www.torproject.org',
download_url='https://gitweb.torproject.org/bridgedb.git',
package_dir={'': 'lib'},
- packages=['bridgedb'],
+ packages=['bridgedb',
+ 'bridgedb.parse',
+ 'bridgedb.test'],
scripts=['scripts/bridgedb',
'scripts/gen_bridge_descriptors'],
- extras_require={'test': ["sure>=0.4.5",
- "trialcoverage>=0.3.12"]},
+ extras_require={'test': ["sure==0.4.5",
+ "trialcoverage==0.3.12"]},
zip_safe=False,
cmdclass=get_cmdclass(),
include_package_data=True,
1
0
[bridgedb/master] Include class for varying the tor versions in generated descriptors.
by isis@torproject.org 12 Jan '14
by isis@torproject.org 12 Jan '14
12 Jan '14
commit f5d37262448c23839eb37a99c75fa469791f74a8
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 09:10:25 2013 +0000
Include class for varying the tor versions in generated descriptors.
---
lib/bridgedb/parse/versions.py | 70 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/lib/bridgedb/parse/__init__.py b/lib/bridgedb/parse/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lib/bridgedb/parse/versions.py b/lib/bridgedb/parse/versions.py
new file mode 100644
index 0000000..94d16b2
--- /dev/null
+++ b/lib/bridgedb/parse/versions.py
@@ -0,0 +1,70 @@
+
+
+from twisted.python import util as txutil
+
+
+class Version(txutil.Version):
+ """Holds, parses, and does comparison operations for version numbers.
+
+ :attr string major: The major version number.
+ :attr string minor: The minor version number.
+ :attr string micro: The micro version number.
+ :attr string prerelease: Sometime, another number, though often suffixed
+ with a `-`, `+`, or `#`.
+ """
+
+ def __init__(self, version, package=None):
+ """Create a version object.
+
+ Comparisons may be computed between instances of :class:`Version`s.
+
+ :param string version: One of ``SERVER_VERSIONS``.
+ :param string package: The package or program which we are creating a
+ version number for, i.e. for "tor-0.2.5.1-alpha" the ``package``
+ would be "tor".
+ """
+ if version.find('.') == -1:
+ print("Version.__init__(): %r doesn't look like a version string!"
+ % version.__repr__())
+
+ major, minor, micro, prerelease = ['' for x in xrange(4)]
+
+ components = version.split('.')
+ if len(components) > 0:
+ try:
+ prerelease = components.pop()
+ micro = components.pop()
+ minor = components.pop()
+ major = components.pop()
+ except IndexError:
+ pass
+ super(Version, self).__init__(package, major, minor, micro, prerelease)
+
+ def base(self):
+ """Get the base version number (with prerelease).
+
+ :rtype: string
+ :returns: A version number, without the package/program name, and with
+ the prefix (if available). For example: '0.2.5.1-alpha'.
+ """
+ prerelease = getPrefixedPrerelease()
+ return '%d.%d.%d%s' % (self.major, self.minor, self.micro, prerelease)
+
+ def getPrefixedPrerelease(self, separator='.'):
+ """Get the prerelease string, prefixed by the separator ``prefix``.
+
+ :param string separator: The separator to use between the rest of the
+ version string and the :attr:`prerelease` string.
+ :rtype: string
+ :returns: The separator plus the ``prefix``, i.e. '.1-alpha'.
+ """
+ pre = ''
+ if self.prerelease is not None:
+ pre = prefix + self.prerelease
+ return pre
+
+ def __repr__(self):
+ prerelease = getPrefixedPrerelease('')
+ return '%s(package=%r, major=%d, minor=%d, micro=%d, prerelease=%s)' \
+ % (self.__class__.__name__, str(self.package),
+ self.major, self.minor, self.micro, self.prerelease)
1
0
commit 5c86df37fa1938508144bb52c971a3c31be0b310
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 10:16:46 2013 +0000
Update bridgedb.conf.
* REMOVE RUN_IN_DIR
* CHANGE EXTRA_INFO_FILES to a list with the correct filenames.
* CHANGE HTTPS options to bind to 127.0.0.1:6789 by default (for testing).
* ADD missing HTTP_N_BRIDGES_PER_ANSWER option.
* CHANGE to enabling bridge fingerprints by default.
* CHANGE to GPG signing emails by default.
---
bridgedb.conf | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/bridgedb.conf b/bridgedb.conf
index b565b37..88aa231 100644
--- a/bridgedb.conf
+++ b/bridgedb.conf
@@ -2,10 +2,6 @@
#==========
# General-purpose options.
-# We chdir to this directory when we start; all files with relative
-# pathnames are created under this directory
-RUN_IN_DIR = "~/run/"
-
# Either a file in which to write our pid, or None
PIDFILE = "bridgedb.pid"
@@ -34,16 +30,16 @@ STATUS_FILE = "networkstatus-bridges"
# File from which we read extra-info entries, for learning pluggable
# transports
-EXTRA_INFO_FILE = "extra-infos"
+EXTRA_INFO_FILES = ["cached-extrainfo", "cached-extrainfo.new"]
# Only consider routers whose purpose matches this string.
BRIDGE_PURPOSE = "bridge"
# File to store persistent info in.
-DB_FILE = "./bridgedist.db"
+DB_FILE = "bridgedist.db"
# File to log changes to persistent info in. For debugging and bugfixing.
-DB_LOG_FILE = "./bridgedist.log"
+DB_LOG_FILE = "bridgedist.log"
# File in which we store our secret HMAC root key.
-MASTER_KEY_FILE = "./secret_key"
+MASTER_KEY_FILE = "secret_key"
# File to which we dump bridge pool assignments for statistics.
ASSIGNMENTS_FILE = "assignments.log"
@@ -77,9 +73,9 @@ HTTPS_DIST = True
HTTPS_SHARE=10
# An IP address (form "1.2.3.4") where we listen for HTTPS connections.
# "None" to listen on the default interface.
-HTTPS_BIND_IP=None
+HTTPS_BIND_IP='127.0.0.1'
# Port to listen on for incoming HTTPS connections
-HTTPS_PORT=3443
+HTTPS_PORT=6789
# Certificate file
HTTPS_CERT_FILE="cert"
# Private key file.
@@ -95,10 +91,11 @@ HTTP_UNENCRYPTED_PORT=None
HTTP_USE_IP_FROM_FORWARDED_HEADER = False
# How many bridges do we give back in an answer?
HTTPS_N_BRIDGES_PER_ANSWER=3
+HTTP_N_BRIDGES_PER_ANSWER=3
# Should we tell http users about the bridge fingerprints? Turn this on
# once we have the vidalia/tor interaction fixed for everbody.
-HTTPS_INCLUDE_FINGERPRINTS=False
+HTTPS_INCLUDE_FINGERPRINTS=True
#==========
# Options related to Email
@@ -147,11 +144,11 @@ EMAIL_N_BRIDGES_PER_ANSWER=3
# Should we tell http users about the bridge fingerprints? Turn this on
# once we have the vidalia/tor interaction fixed for everbody.
-EMAIL_INCLUDE_FINGERPRINTS=False
+EMAIL_INCLUDE_FINGERPRINTS = True
# Configuration options for GPG signed messages
-EMAIL_GPG_SIGNING_ENABLED = False
-EMAIL_GPG_SIGNING_KEY = ''
+EMAIL_GPG_SIGNING_ENABLED = True
+EMAIL_GPG_SIGNING_KEY = 'gnupghome/TESTING.subkeys.sec'
#==========
# Options related to unallocated bridges.
1
0
[bridgedb/master] Fix scripts/gen_bridge_descriptors to create two cached-extrainfo files.
by isis@torproject.org 12 Jan '14
by isis@torproject.org 12 Jan '14
12 Jan '14
commit 0b64895b448d1dd1066696f79a65745897a10c4e
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 10:11:29 2013 +0000
Fix scripts/gen_bridge_descriptors to create two cached-extrainfo files.
We usually have 'cached-extrainfo' and 'cached-extrainfo.new', not
'extra-infos'.
---
scripts/gen_bridge_descriptors | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/scripts/gen_bridge_descriptors b/scripts/gen_bridge_descriptors
index e272600..c7ffcee 100644
--- a/scripts/gen_bridge_descriptors
+++ b/scripts/gen_bridge_descriptors
@@ -752,10 +752,19 @@ def create(count):
code = 1515
finally:
print("Writing descriptors to files...", end="")
+
+ cached = "cached-extrainfo.new"
descriptor_files = {
"networkstatus-bridges": ''.join(netstatus_consensus),
"bridge-descriptors": ''.join(server_descriptors),
- "extra-infos": ''.join(extrainfo_descriptors)}
+ "cached-extrainfo.new": ''.join(extrainfo_descriptors)}
+
+ if not os.path.isfile(cached):
+ with open(cached, 'wb') as fh:
+ fh.flush()
+ if os.path.isfile(cached)
+ os.rename(cached, "cached-extrainfo")
+
for fn, giantstring in descriptor_files.items():
writeDescToFile(fn, giantstring)
print("Done.")
1
0
[bridgedb/master] Merge branch 'feature/9865-test-runner-2-r1' into develop
by isis@torproject.org 12 Jan '14
by isis@torproject.org 12 Jan '14
12 Jan '14
commit 1f695a46474ef7520bd94f58ed720ff2a1990859
Merge: 6255494 f5d3726
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 09:16:31 2013 +0000
Merge branch 'feature/9865-test-runner-2-r1' into develop
.travis.yml | 40 +-
doc/DESCRIPTORS.md | 190 +++++++++
lib/bridgedb/Main.py | 64 +--
lib/bridgedb/Tests.py | 42 +-
lib/bridgedb/opt.py | 140 +++++++
lib/bridgedb/parse/versions.py | 70 ++++
lib/bridgedb/runner.py | 97 +++++
requirements.txt | 10 +-
scripts/bridgedb | 54 ++-
scripts/executioner | 35 ++
scripts/gen_bridge_descriptors | 836 ++++++++++++++++++++++++++++++++++++----
scripts/make-ssl-cert | 56 +++
setup.py | 11 +-
13 files changed, 1468 insertions(+), 177 deletions(-)
1
0
commit ed7e1392cd5ec4a6d416c133f640b6bab1fa5d7c
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Oct 26 10:12:54 2013 +0000
Update README with new commands.
* FIX also the markdown formatting of indented blocks in some places.
---
README | 92 +++++++++++++++++++++++++++-------------------------------------
1 file changed, 39 insertions(+), 53 deletions(-)
diff --git a/README b/README
index 98f20c2..cdacdb2 100644
--- a/README
+++ b/README
@@ -50,48 +50,60 @@ BridgeDB requires the following OS-level dependencies:
As well as any Python dependencies in requirements.txt.
-### Deploying BridgeDB in a Python virtualenv
+### Deploying BridgeDB
- - Install Python 2.7 or later, and other OS-level dependencies. On Debian,
- you can do:
+BridgeDB should work with or without a Python virtualenv.
- sudo apt-get install build-essential python python-dev \
- python-setuptools openssl sqlite3 tor-geoip libgpgme11-dev
+ - Install Python 2.7, and other OS-level dependencies. On Debian, you can do:
+
+ sudo apt-get install build-essential python python-dev \
+ python-setuptools openssl sqlite3 tor-geoip libgpgme11-dev
- Install Pip 1.3.1 or later. Debian has this version, but if for some reason
that or a newer version isn't available, the easiest way to install a newer
Pip is to use the Pip development teams's [getpip
script](https://raw.github.com/pypa/pip/master/contrib/get-pip.py):
- wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
- sudo python get-pip.py
+ wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
+ sudo python get-pip.py
- - Use Pip to install virtualenv and [virtualenvwrapper](https://virtualenvwrapper.readthedocs.org):
+ - (virtualenv installs only) Use Pip to install virtualenv and
+ [virtualenvwrapper](https://virtualenvwrapper.readthedocs.org):
- sudo pip install --upgrade virtualenv virtualenvwrapper
+ sudo pip install --upgrade virtualenv virtualenvwrapper
- - Configure virtualenvwrapper and create a virtualenv for Bridgedb:
+ - (virtualenv installs only) Configure virtualenvwrapper and create a
+ virtualenv for Bridgedb:
- WORKON_HOME=${HOME}/.virtualenvs
- export WORKON_HOME
- mkdir -p $WORKON_HOME
- source $(which virtualenvwrapper.sh)
- git clone https://git.torproject.org/bridgedb.git && cd bridgedb
- mkvirtualenv -a $PWD -r requirements.txt --unzip-setuptools \
+ WORKON_HOME=${HOME}/.virtualenvs
+ export WORKON_HOME
+ mkdir -p $WORKON_HOME
+ source $(which virtualenvwrapper.sh)
+ git clone https://git.torproject.org/bridgedb.git && cd bridgedb
+ mkvirtualenv -a $PWD -r requirements.txt --unzip-setuptools \
--setuptools bridgedb
From now on, to use BridgeDB's virtualenv, just do ```$ workon bridgedb```
(after sourcing virtualenvwrapper.sh, as before). To exit the virtualenv
without exiting the shell, do ```$ deactivate```.
- - To run unit tests:
+ - (virtualenv installs only) To install, set PYTHONPATH to include the root
+ directory of the virtualenv:
+
+ export PYTHONPATH=$PYTHONPATH:${VIRTUAL_ENV}/lib/python2.7/site-packages
+
+ - Then proceed as usual:
+
+ python setup.py install --record installed-files.txt
- python setup.py test
+### Testing BridgeDB
- - To install BridgeDB:
+To create a bunch of fake bridge descriptors to test BridgeDB, do:
- python setup.py install
+ bridgedb mock [-n NUMBER_OF_DESCRIPTORS]
+Then to run unittests, see the ```bridgedb test``` and ```bridgedb trial```
+commands.
### Enabling additional features:
@@ -100,33 +112,10 @@ As well as any Python dependencies in requirements.txt.
**Using New Translations**: This should be done when newly completed
translations are available in Transifex.
-Clone/Update the
-[translations repository](https://gitweb.torproject.org/translation.git),
-checkout the ```bridgedb_completed``` branch, and copy the .po files into
-```lib/bridgedb/i18n/```.
-
-Assuming a side-by-side repo layout (if you're in the parent directory of the
-bridgedb repo):
-
- git clone https://gitweb.torproject.org/translation.git
- git fetch --all
- cd translation && git checkout bridgedb_completed
- cd .. && rsync -PCAXrv \
- --filter 'include ./translation/*/LC_MESSAGES/bridgedb.po' \
- --filter 'exclude .gitignore' \
- ./translation/ ./bridgedb/lib/bridgedb/i18n/
-
-and then convert them to binary (.mo) format so that they can be installed:
-
- cd bridgedb && python setup.py compile_catalog
-
-Don't forget to reinstall BridgeDB to update the templates!
-
- python setup.py install
-
-[xxx outdated, these commands seem to not exist...]
-
- python setup.py trans && python setup.py install_data
+Piece of cake. Running ```maint/get-completed-translations``` will take care
+of cloning *only* the ```bridgedb_completed``` branch of Tor's
+[translations repo](https://gitweb.torproject.org/translation.git) and placing
+all the updated files in their correct locations.
**Requesting Translations for Altered/Added Source Code**: This should be done
whenever any of the strings requiring translation -- _("they are formatted
@@ -161,7 +150,7 @@ complete, the finished .po files should be placed into the
#### Enabling HTTPS
Create a self-signed certificate with:
- openssl req -x509 -new -nodes > cert
+ maint/make-ssl-cert
Or, place an existing certificate in the path specified in bridgedb.conf by
the ```HTTPS_CERT_FILE``` option, and a private key where ```HTTPS_KEY_FILE```
@@ -212,11 +201,8 @@ Enter the following commands at the ```sqlite>``` prompt:
## Running BridgeDB
-To run BridgeDB, simply make any necessary changes to bridgedb.conf, navigate
-to the runtime directory (the ```RUN_IN_DIR``` option in bridgedb.conf), and
-do:
-
- bridgedb -c bridgedb.conf
+To run BridgeDB, simply make any necessary changes to bridgedb.conf, and
+do: ```bridgedb```.
When you have new lists of bridges, replace the old files and do:
1
0
[bridgedb/master] Remove compiled components of the .po files removed in the last commit.
by isis@torproject.org 12 Jan '14
by isis@torproject.org 12 Jan '14
12 Jan '14
commit b2b0c11094325962c5b4f88f3d5964f738b8c149
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Mon Aug 12 08:03:51 2013 +0000
Remove compiled components of the .po files removed in the last commit.
The strings have changed so much due to the new web interface design that it
is useless to keep the old versions around because they only map to ~20% of
the strings. Not entirely sure how this is done, but I thought it made the
most sense to only include translations which are 100% complete.
---
lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.mo | Bin 3320 -> 0 bytes
lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.po | 74 -----------------------
lib/bridgedb/i18n/eo/LC_MESSAGES/bridgedb.mo | Bin 3061 -> 0 bytes
lib/bridgedb/i18n/hu/LC_MESSAGES/bridgedb.mo | Bin 3294 -> 0 bytes
lib/bridgedb/i18n/ko/LC_MESSAGES/bridgedb.mo | Bin 3387 -> 0 bytes
lib/bridgedb/i18n/my/LC_MESSAGES/bridgedb.mo | Bin 4868 -> 0 bytes
lib/bridgedb/i18n/pl_PL/LC_MESSAGES/bridgedb.mo | Bin 3433 -> 0 bytes
lib/bridgedb/i18n/sl_SI/LC_MESSAGES/bridgedb.mo | Bin 3235 -> 0 bytes
8 files changed, 74 deletions(-)
diff --git a/lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.mo b/lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.mo
deleted file mode 100644
index 020e524..0000000
Binary files a/lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.mo and /dev/null differ
diff --git a/lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.po
deleted file mode 100644
index 1f2188a..0000000
--- a/lib/bridgedb/i18n/cs/LC_MESSAGES/bridgedb.po
+++ /dev/null
@@ -1,74 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Elisa <valhalla(a)gishpuppy.com>, 2011.
-# <gsanky+transifex(a)gmail.com>, 2011.
-msgid ""
-msgstr ""
-"Project-Id-Version: The Tor Project\n"
-"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-01-01 07:48-0800\n"
-"PO-Revision-Date: 2012-02-14 10:04+0000\n"
-"Last-Translator: Sanky <gsanky+transifex(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: cs\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
-
-#: lib/bridgedb/I18n.py:21
-msgid "Here are your bridge relays: "
-msgstr "Tady jsou vaše přemosťující spojení:"
-
-#: lib/bridgedb/I18n.py:23
-msgid ""
-"Bridge relays (or \"bridges\" for short) are Tor relays that aren't listed\n"
-"in the main directory. Since there is no complete public list of them,\n"
-"even if your ISP is filtering connections to all the known Tor relays,\n"
-"they probably won't be able to block all the bridges."
-msgstr "Přemosťující spojení (nebo zkráceně \"mosty\") jsou Tor relaye, které nejsou zaznamenány v hlavním adresáři Tor relayí. Protože neexistuje veřejný seznam těchto uzlů, ani váš poskytovatel internetu, pokud blokuje připojení ke všem známým Tor relayím, pravděpodobně nedokáže zablokovat všechny mosty."
-
-#: lib/bridgedb/I18n.py:28
-msgid ""
-"To use the above lines, go to Vidalia's Network settings page, and click\n"
-"\"My ISP blocks connections to the Tor network\". Then add each bridge\n"
-"address one at a time."
-msgstr "Pro použití zmíněných řádek jděte do síťového nastavení Vidalie a klikněte na \"My ISP blocks connections to the Tor network\" (Můj ISP blokuje připojení k síti Tor). Poté přidejte mosty adresu po adrese."
-
-#: lib/bridgedb/I18n.py:32
-msgid ""
-"Configuring more than one bridge address will make your Tor connection\n"
-"more stable, in case some of the bridges become unreachable."
-msgstr "Nastavení více než jednoho mostu udělá vaše Tor připojení stabilnější v případě, že by se staly některé mosty nedostupné."
-
-#: lib/bridgedb/I18n.py:35
-msgid ""
-"Another way to find public bridge addresses is to send mail to\n"
-"bridges(a)torproject.org with the line \"get bridges\" by itself in the body\n"
-"of the mail. However, so we can make it harder for an attacker to learn\n"
-"lots of bridge addresses, you must send this request from an email address at\n"
-"one of the following domains:"
-msgstr "Další způsob jak získat veřejné adresy mostů je posláním emailu na bridges(a)torproject.org pouze s textem \"get bridges\" v těle emailu. Abychom ztížili útočníkovi získat velký počet adres mostů, musí emailová adresa vaší žádosti pocházet z jedné z těchto domén:"
-
-#: lib/bridgedb/I18n.py:41
-msgid "[This is an automated message; please do not reply.]"
-msgstr "[Toto je automatická zpráva; prosím, neodpovídejte na ni]"
-
-#: lib/bridgedb/I18n.py:43
-msgid ""
-"Another way to find public bridge addresses is to visit\n"
-"https://bridges.torproject.org/. The answers you get from that page\n"
-"will change every few days, so check back periodically if you need more\n"
-"bridge addresses."
-msgstr "Další způsob, jak najít adresy veřejných mostů, je jít na https://bridges.torproject.org/. Odpovědi, které naleznete na stránce se pravidelně mění, takže stránku pravidelně kontrolujte, pokud potřebujete víc adres mostů."
-
-#: lib/bridgedb/I18n.py:48
-msgid "(no bridges currently available)"
-msgstr "(nejsou momentálně dostupné žádné mosty)"
-
-#: lib/bridgedb/I18n.py:50
-msgid "(e-mail requests not currently supported)"
-msgstr "(e-mailové žádosti nejsou momentálně podporovány)"
diff --git a/lib/bridgedb/i18n/eo/LC_MESSAGES/bridgedb.mo b/lib/bridgedb/i18n/eo/LC_MESSAGES/bridgedb.mo
deleted file mode 100644
index 571e493..0000000
Binary files a/lib/bridgedb/i18n/eo/LC_MESSAGES/bridgedb.mo and /dev/null differ
diff --git a/lib/bridgedb/i18n/hu/LC_MESSAGES/bridgedb.mo b/lib/bridgedb/i18n/hu/LC_MESSAGES/bridgedb.mo
deleted file mode 100644
index 7c316c7..0000000
Binary files a/lib/bridgedb/i18n/hu/LC_MESSAGES/bridgedb.mo and /dev/null differ
diff --git a/lib/bridgedb/i18n/ko/LC_MESSAGES/bridgedb.mo b/lib/bridgedb/i18n/ko/LC_MESSAGES/bridgedb.mo
deleted file mode 100644
index 180092b..0000000
Binary files a/lib/bridgedb/i18n/ko/LC_MESSAGES/bridgedb.mo and /dev/null differ
diff --git a/lib/bridgedb/i18n/my/LC_MESSAGES/bridgedb.mo b/lib/bridgedb/i18n/my/LC_MESSAGES/bridgedb.mo
deleted file mode 100644
index 8a87769..0000000
Binary files a/lib/bridgedb/i18n/my/LC_MESSAGES/bridgedb.mo and /dev/null differ
diff --git a/lib/bridgedb/i18n/pl_PL/LC_MESSAGES/bridgedb.mo b/lib/bridgedb/i18n/pl_PL/LC_MESSAGES/bridgedb.mo
deleted file mode 100644
index 1cd6b23..0000000
Binary files a/lib/bridgedb/i18n/pl_PL/LC_MESSAGES/bridgedb.mo and /dev/null differ
diff --git a/lib/bridgedb/i18n/sl_SI/LC_MESSAGES/bridgedb.mo b/lib/bridgedb/i18n/sl_SI/LC_MESSAGES/bridgedb.mo
deleted file mode 100644
index 33e4d8c..0000000
Binary files a/lib/bridgedb/i18n/sl_SI/LC_MESSAGES/bridgedb.mo and /dev/null differ
1
0
[bridgedb/master] Update i18n/ with completed .po catalogues from translations repo.
by isis@torproject.org 12 Jan '14
by isis@torproject.org 12 Jan '14
12 Jan '14
commit 48e4ed7eef648d234b0e60b09cf5966dc6f62ee7
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Mon Aug 12 02:25:28 2013 +0000
Update i18n/ with completed .po catalogues from translations repo.
---
lib/bridgedb/i18n/ar/LC_MESSAGES/bridgedb.po | 6 +-
lib/bridgedb/i18n/da/LC_MESSAGES/bridgedb.po | 137 +++++++++++++---------
lib/bridgedb/i18n/de/LC_MESSAGES/bridgedb.po | 2 +-
lib/bridgedb/i18n/el/LC_MESSAGES/bridgedb.po | 8 +-
lib/bridgedb/i18n/fa/LC_MESSAGES/bridgedb.po | 6 +-
lib/bridgedb/i18n/fr/LC_MESSAGES/bridgedb.po | 2 +-
lib/bridgedb/i18n/he/LC_MESSAGES/bridgedb.po | 137 +++++++++++++---------
lib/bridgedb/i18n/hr_HR/LC_MESSAGES/bridgedb.po | 139 ++++++++++++++---------
lib/bridgedb/i18n/lv/LC_MESSAGES/bridgedb.po | 2 +-
lib/bridgedb/i18n/ms_MY/LC_MESSAGES/bridgedb.po | 137 +++++++++++++---------
lib/bridgedb/i18n/nl/LC_MESSAGES/bridgedb.po | 138 +++++++++++++---------
lib/bridgedb/i18n/sv/LC_MESSAGES/bridgedb.po | 137 +++++++++++++---------
lib/bridgedb/i18n/th/LC_MESSAGES/bridgedb.po | 101 ++++++++++++++++
lib/bridgedb/i18n/zh_CN/LC_MESSAGES/bridgedb.po | 12 +-
14 files changed, 622 insertions(+), 342 deletions(-)
diff --git a/lib/bridgedb/i18n/ar/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/ar/LC_MESSAGES/bridgedb.po
index 1de6a00..93cce5f 100644
--- a/lib/bridgedb/i18n/ar/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/ar/LC_MESSAGES/bridgedb.po
@@ -5,8 +5,8 @@
# Translators:
# allamiro <allamiro(a)gmail.com>, 2011
# محمد الحرقان <malham1(a)gmail.com>, 2011
-# Sherief <sheriefalaa.w(a)gmail.com>, 2013
-# Sherief <sheriefalaa.w(a)gmail.com>, 2013
+# Sherief Alaa <sheriefalaa.w(a)gmail.com>, 2013
+# Sherief Alaa <sheriefalaa.w(a)gmail.com>, 2013
# محمد الحرقان <malham1(a)gmail.com>, 2011
msgid ""
msgstr ""
@@ -15,7 +15,7 @@ msgstr ""
"POT-Creation-Date: 2013-03-27 21:41+0000\n"
"PO-Revision-Date: 2013-04-29 09:24+0000\n"
"Last-Translator: runasand <runa.sandvik(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language-Team: Arabic (http://www.transifex.com/projects/p/torproject/language/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/lib/bridgedb/i18n/da/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/da/LC_MESSAGES/bridgedb.po
index c0bfbfa..534c8dc 100644
--- a/lib/bridgedb/i18n/da/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/da/LC_MESSAGES/bridgedb.po
@@ -1,73 +1,102 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
+# Translations template for BridgeDB.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
-# <theoliver(a)live.co.uk>, 2011.
+# Translators:
+# OliverMller <theoliver(a)live.co.uk>, 2011
+# torebjornson <tore.bjornson(a)gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-01-01 07:48-0800\n"
-"PO-Revision-Date: 2012-02-14 10:04+0000\n"
-"Last-Translator: OliverMller <theoliver(a)live.co.uk>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"POT-Creation-Date: 2013-03-27 21:41+0000\n"
+"PO-Revision-Date: 2013-06-30 06:20+0000\n"
+"Last-Translator: torebjornson <tore.bjornson(a)gmail.com>\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/torproject/language/da/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
"Language: da\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: lib/bridgedb/I18n.py:21
-msgid "Here are your bridge relays: "
-msgstr "Her er dine relæer:"
+#: lib/bridgedb/templates/base.html:33
+msgid "What are bridges?"
+msgstr "Hvad er broer?"
-#: lib/bridgedb/I18n.py:23
+#: lib/bridgedb/templates/base.html:34
+#, python-format
msgid ""
-"Bridge relays (or \"bridges\" for short) are Tor relays that aren't listed\n"
-"in the main directory. Since there is no complete public list of them,\n"
-"even if your ISP is filtering connections to all the known Tor relays,\n"
-"they probably won't be able to block all the bridges."
-msgstr "Bridge relæer (eller \"broer\" for korte) er Tor relæer, der ikke er anført i de vigtigste bibliotek. Da der ikke er fuldstændig offentlig liste over dem, selv hvis din internetudbyder filtrerer forbindelser til alle de kendte Tor relæer, Er de sandsynligvis ikke være i stand til at blokere alle broerne."
+"%s Bridge relays %s are Tor relays that help you circumvent censorship."
+msgstr "%s Bro relæer %s er Tor relæer der hjælper Dem med at undgå censur."
-#: lib/bridgedb/I18n.py:28
-msgid ""
-"To use the above lines, go to Vidalia's Network settings page, and click\n"
-"\"My ISP blocks connections to the Tor network\". Then add each bridge\n"
-"address one at a time."
-msgstr "For at bruge ovenstående linjer, skal du gå til Vidalia Network siden med indstillinger, og klik på \"Min internetudbyder blokerer forbindelser til Tor netværket\". Så tilføj hver bro adresse én ad gangen."
+#: lib/bridgedb/templates/base.html:39
+msgid "I need an alternative way of getting bridges!"
+msgstr "Jeg har brug for en alternativ metode til at få broer på!"
-#: lib/bridgedb/I18n.py:32
+#: lib/bridgedb/templates/base.html:40
+#, python-format
msgid ""
-"Configuring more than one bridge address will make your Tor connection\n"
-"more stable, in case some of the bridges become unreachable."
-msgstr "Konfiguration af mere end én bro adresse vil gøre din Tor forbindelse mere stabil, hvis nogle af broerne bliver uopnåelig."
+"Another way to find public bridge addresses is to send an email (from a %s "
+"or a %s address) to %s with the line 'get bridges' by itself in the body of "
+"the mail."
+msgstr "En anden måde at finde offentlige bro adresser på, er at sende en email (fra en %s eller en %s adresse) til %s kun indeholdende linjen 'få broer' i selve mailen."
+
+#: lib/bridgedb/templates/base.html:48
+msgid "My bridges don't work! I need help!"
+msgstr "Mine broer virker ikke! Jeg har brug for hjælp!"
-#: lib/bridgedb/I18n.py:35
+#: lib/bridgedb/templates/base.html:49
+#, python-format
msgid ""
-"Another way to find public bridge addresses is to send mail to\n"
-"bridges(a)torproject.org with the line \"get bridges\" by itself in the body\n"
-"of the mail. However, so we can make it harder for an attacker to learn\n"
-"lots of bridge addresses, you must send this request from an email address at\n"
-"one of the following domains:"
-msgstr "En anden måde at finde offentlige bro adresser er at sende mail til bridges(a)torproject.org med linjen \"get bridges\" i selve mailen. Men, så vi kan gøre det sværere for en hacker at få massere af bro-adresser, skal du sende denne anmodning fra en e-mail-adresse på en af de følgende domæner:"
-
-#: lib/bridgedb/I18n.py:41
-msgid "[This is an automated message; please do not reply.]"
-msgstr "[Dette er en automatisk meddelelse; Svar venligst ikke.]"
-
-#: lib/bridgedb/I18n.py:43
+"If your Tor doesn't work, you should email %s. Try including as much info "
+"about your case as you can, including the list of bridges you used, the "
+"bundle filename/version you used, the messages that Tor gave out, etc."
+msgstr "Hvis dine Tor broer ikke virker, så email %s. Inkludér venligst mest mulig information om Deres sag, f.eks. hvilke broer De har brugt, versionsnummereret på den software bundle De bruger og eventuelle beskeder som Tor gav."
+
+#: lib/bridgedb/templates/bridges.html:10
msgid ""
-"Another way to find public bridge addresses is to visit\n"
-"https://bridges.torproject.org/. The answers you get from that page\n"
-"will change every few days, so check back periodically if you need more\n"
-"bridge addresses."
-msgstr "En anden måde at finde offentlige bro adresser er at besøge https://bridges.torproject.org/. Svarene du får fra den side vil ændre sig hver par dag, så kig ind jævnligt, hvis du har brug for flere bro-adresser."
-
-#: lib/bridgedb/I18n.py:48
-msgid "(no bridges currently available)"
-msgstr "(Ingen broer er i øjeblikket til rådighed)"
-
-#: lib/bridgedb/I18n.py:50
-msgid "(e-mail requests not currently supported)"
-msgstr "(E-mail anmodninger, understøttes ikke i øjeblikket)"
+"To use the above lines, go to Vidalia's Network settings page, and click "
+"\"My ISP blocks connections to the Tor network\". Then add each bridge "
+"address one at a time."
+msgstr "For at bruge ovenstående linjer, gå da til Vidalias netværksindstillinger side, og klik på \"Min Internet Udbyder blokerer forbindelse til Tor netværket\". Tilføj efterfølgende hver enkelt bro én ad gangen."
+
+#: lib/bridgedb/templates/bridges.html:13
+msgid "No bridges currently available"
+msgstr "Ingen broer er tilgængelige."
+
+#: lib/bridgedb/templates/captcha.html:6
+msgid "Upgrade your browser to Firefox"
+msgstr "Opgrader Deres Firefox browser"
+
+#: lib/bridgedb/templates/captcha.html:8
+msgid "Type the two words"
+msgstr "Indtast de to ord"
+
+#: lib/bridgedb/templates/index.html:6
+msgid "Step 1"
+msgstr "Første skridt"
+
+#: lib/bridgedb/templates/index.html:8
+#, python-format
+msgid "Get %s Tor Browser Bundle %s"
+msgstr "Få %s Tor Browser Bundlen %s"
+
+#: lib/bridgedb/templates/index.html:13
+msgid "Step 2"
+msgstr "Andet skridt"
+
+#: lib/bridgedb/templates/index.html:15
+#, python-format
+msgid "Get %s bridges %s"
+msgstr "Få %s broer %s"
+
+#: lib/bridgedb/templates/index.html:19
+msgid "Step 3"
+msgstr "Tredje skridt"
+
+#: lib/bridgedb/templates/index.html:21
+#, python-format
+msgid "Now %s add the bridges to Tor %s"
+msgstr "Addér nu %s broer til Tor %s"
diff --git a/lib/bridgedb/i18n/de/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/de/LC_MESSAGES/bridgedb.po
index cce3eb5..cf5cbf7 100644
--- a/lib/bridgedb/i18n/de/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/de/LC_MESSAGES/bridgedb.po
@@ -11,7 +11,7 @@ msgstr ""
"POT-Creation-Date: 2013-03-27 21:41+0000\n"
"PO-Revision-Date: 2013-04-29 09:24+0000\n"
"Last-Translator: runasand <runa.sandvik(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language-Team: German (http://www.transifex.com/projects/p/torproject/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/lib/bridgedb/i18n/el/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/el/LC_MESSAGES/bridgedb.po
index c66264b..84b43e8 100644
--- a/lib/bridgedb/i18n/el/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/el/LC_MESSAGES/bridgedb.po
@@ -3,6 +3,8 @@
# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
+# Translators:
+# kotkotkot <kotakota(a)gmail.com>, 2013
# kotkotkot <kotakota(a)gmail.com>, 2012
# mitzie <soldizach(a)gmail.com>, 2013
# Wasilis <inactive+Wasilis(a)transifex.com>, 2013
@@ -11,8 +13,8 @@ msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
"POT-Creation-Date: 2013-03-27 21:41+0000\n"
-"PO-Revision-Date: 2013-05-20 02:05+0000\n"
-"Last-Translator: Wasilis <inactive+Wasilis(a)transifex.com>\n"
+"PO-Revision-Date: 2013-07-28 18:20+0000\n"
+"Last-Translator: kotkotkot <kotakota(a)gmail.com>\n"
"Language-Team: Greek (http://www.transifex.com/projects/p/torproject/language/el/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -23,7 +25,7 @@ msgstr ""
#: lib/bridgedb/templates/base.html:33
msgid "What are bridges?"
-msgstr "Τι ειναι οι γεφυρες?"
+msgstr "Τι είναι οι γέφυρες?"
#: lib/bridgedb/templates/base.html:34
#, python-format
diff --git a/lib/bridgedb/i18n/fa/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/fa/LC_MESSAGES/bridgedb.po
index 8ea4587..31e7a1c 100644
--- a/lib/bridgedb/i18n/fa/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/fa/LC_MESSAGES/bridgedb.po
@@ -4,7 +4,7 @@
#
# Translators:
# arashaalaei <aalaeiarash(a)gmail.com>, 2011
-# Ardeshir <ardeshir(a)redteam.io>, 2013
+# Ardeshir, 2013
# perspolis <rezarms(a)yahoo.com>, 2011
msgid ""
msgstr ""
@@ -12,8 +12,8 @@ msgstr ""
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
"POT-Creation-Date: 2013-03-27 21:41+0000\n"
"PO-Revision-Date: 2013-05-01 00:10+0000\n"
-"Last-Translator: Ardeshir <ardeshir(a)redteam.io>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Last-Translator: Ardeshir\n"
+"Language-Team: Persian (http://www.transifex.com/projects/p/torproject/language/fa/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/lib/bridgedb/i18n/fr/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/fr/LC_MESSAGES/bridgedb.po
index 211d3de..1b29b05 100644
--- a/lib/bridgedb/i18n/fr/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/fr/LC_MESSAGES/bridgedb.po
@@ -13,7 +13,7 @@ msgstr ""
"POT-Creation-Date: 2013-03-27 21:41+0000\n"
"PO-Revision-Date: 2013-04-30 15:07+0000\n"
"Last-Translator: lunar <lunar(a)torproject.org>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language-Team: French (http://www.transifex.com/projects/p/torproject/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/lib/bridgedb/i18n/he/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/he/LC_MESSAGES/bridgedb.po
index 61f8a15..2c00bfb 100644
--- a/lib/bridgedb/i18n/he/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/he/LC_MESSAGES/bridgedb.po
@@ -1,74 +1,103 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
+# Translations template for BridgeDB.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
-# <aharonoosh1(a)gmail.com>, 2012.
-# <static.172(a)gmail.com>, 2012.
+# Translators:
+# aharonoosh <aharonoosh1(a)gmail.com>, 2012
+# GenghisKhan <genghiskhan(a)gmx.ca>, 2013
+# static172 <static.172(a)gmail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-01-01 07:48-0800\n"
-"PO-Revision-Date: 2012-10-03 10:10+0000\n"
-"Last-Translator: aharonoosh <aharonoosh1(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"POT-Creation-Date: 2013-03-27 21:41+0000\n"
+"PO-Revision-Date: 2013-07-21 06:40+0000\n"
+"Last-Translator: GenghisKhan <genghiskhan(a)gmx.ca>\n"
+"Language-Team: Hebrew (http://www.transifex.com/projects/p/torproject/language/he/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
"Language: he\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: lib/bridgedb/I18n.py:21
-msgid "Here are your bridge relays: "
-msgstr "הנה ממסרי הגשר שלך:"
+#: lib/bridgedb/templates/base.html:33
+msgid "What are bridges?"
+msgstr "מהם גשרים?"
-#: lib/bridgedb/I18n.py:23
+#: lib/bridgedb/templates/base.html:34
+#, python-format
msgid ""
-"Bridge relays (or \"bridges\" for short) are Tor relays that aren't listed\n"
-"in the main directory. Since there is no complete public list of them,\n"
-"even if your ISP is filtering connections to all the known Tor relays,\n"
-"they probably won't be able to block all the bridges."
-msgstr "ממסרי גשר (או \"גשרים\" בקיצור) הם ממסרי Tor שאינם רשומים\nבספרייה הראשית. מאחר ואין רשימה מלאה ציבורית שלהם,\n גם אם ספק האינטרנט שלך הוא סינון חיבורים לכל ממסרי הטור הידועים,\n הם כנראה לא יוכלו לחסום את כל הגשרים."
+"%s Bridge relays %s are Tor relays that help you circumvent censorship."
+msgstr "%s ממסרי גשר %s הינם ממסרי Tor אשר מסייעים לך להערים על צנזורה."
-#: lib/bridgedb/I18n.py:28
-msgid ""
-"To use the above lines, go to Vidalia's Network settings page, and click\n"
-"\"My ISP blocks connections to the Tor network\". Then add each bridge\n"
-"address one at a time."
-msgstr "כדי להשתמש בקווים הנ\"ל, עבור לדף הגדרות הרשת של Vidalia, ולחץ על\n \"קשרי ISP שלי חוסם את רשת Tor\". ואז הוסף כל גשר\n כתובת אחת בכל פעם."
+#: lib/bridgedb/templates/base.html:39
+msgid "I need an alternative way of getting bridges!"
+msgstr "אני זקוק לדרך חלופית לקבלת גשרים!"
-#: lib/bridgedb/I18n.py:32
+#: lib/bridgedb/templates/base.html:40
+#, python-format
msgid ""
-"Configuring more than one bridge address will make your Tor connection\n"
-"more stable, in case some of the bridges become unreachable."
-msgstr "הגדרת כתובת יותר מגשר אחד תעשה את חיבור תור\n יציב יותר, במקרה של כמה גשרים זה יהפך לבלתי ניתן להשגה."
+"Another way to find public bridge addresses is to send an email (from a %s "
+"or a %s address) to %s with the line 'get bridges' by itself in the body of "
+"the mail."
+msgstr "דרך אחרת למציאת כתובת של גשר פומבי הינה שליחת דוא״ל (מתוך כתובת %s או %s) אל %s עם השורה 'get bridges' כשלעצמו בתוך גוף ההודעה."
+
+#: lib/bridgedb/templates/base.html:48
+msgid "My bridges don't work! I need help!"
+msgstr "הגשרים שלי לא עובדים! אני זקוק לעזרה!"
-#: lib/bridgedb/I18n.py:35
+#: lib/bridgedb/templates/base.html:49
+#, python-format
msgid ""
-"Another way to find public bridge addresses is to send mail to\n"
-"bridges(a)torproject.org with the line \"get bridges\" by itself in the body\n"
-"of the mail. However, so we can make it harder for an attacker to learn\n"
-"lots of bridge addresses, you must send this request from an email address at\n"
-"one of the following domains:"
-msgstr "עוד דרך למצא כתובת גשר פומבי היא לשלוח מייל לbridges@torproject.org\nאך ורק עם השורה \"get bridges\" בגוף המייל.\nלמרות זאת, כדי שנקשה על התוקפים להשיג הרבה כתובות של גשרים, הינך חייב לשלוח את הבקשה הזו מאחד הדומיינים ההבאים:"
-
-#: lib/bridgedb/I18n.py:41
-msgid "[This is an automated message; please do not reply.]"
-msgstr "[זוהי הודעה אוטומטית. נא לא להשיב עליה."
-
-#: lib/bridgedb/I18n.py:43
+"If your Tor doesn't work, you should email %s. Try including as much info "
+"about your case as you can, including the list of bridges you used, the "
+"bundle filename/version you used, the messages that Tor gave out, etc."
+msgstr "אם Tor לא עובד אצלך, עליך לשלוח דוא״ל אל %s. נסה לכלול כמה שיותר מידע אודות המקרה שלך כלל שביכולתך לעשות כן, כולל את רשימת הגשרים אשר השתמשת בה, שם הקובץ/גרסא של האגודה (bundle) שהשתמשת, ההודעות אשר Tor מסר וכו׳."
+
+#: lib/bridgedb/templates/bridges.html:10
msgid ""
-"Another way to find public bridge addresses is to visit\n"
-"https://bridges.torproject.org/. The answers you get from that page\n"
-"will change every few days, so check back periodically if you need more\n"
-"bridge addresses."
-msgstr "דרך נוספת למצא גשרים פומביים היא לבקר ב\nhttps://bridges.torproject.org/.\nהתשובות שתקבל בעמוד זה ישתנו כל כמה ימים, תבדוק כל כמה זמן עמוד זה אם תצתרך בכתובות גשרים נוספים."
-
-#: lib/bridgedb/I18n.py:48
-msgid "(no bridges currently available)"
-msgstr "(אין גשרים זמינים כרגע)"
-
-#: lib/bridgedb/I18n.py:50
-msgid "(e-mail requests not currently supported)"
-msgstr "(בקשות אימייל אינן זמינות כעת)"
+"To use the above lines, go to Vidalia's Network settings page, and click "
+"\"My ISP blocks connections to the Tor network\". Then add each bridge "
+"address one at a time."
+msgstr "כדי להשתמש בשורות לעיל, המשך אל עמוד הגדרות רשת בתוך Vidalia, והקלק \"ספק האינטרנט שלי חוסם חיבורים לרשת Tor\". אחרי כן הוסף כל כתובת גשר אחת בכל פעם."
+
+#: lib/bridgedb/templates/bridges.html:13
+msgid "No bridges currently available"
+msgstr "אין גשרים זמינים כעת"
+
+#: lib/bridgedb/templates/captcha.html:6
+msgid "Upgrade your browser to Firefox"
+msgstr "שדרג את הדפדפן שלך אל Firefox"
+
+#: lib/bridgedb/templates/captcha.html:8
+msgid "Type the two words"
+msgstr "הקש את שתי המילים"
+
+#: lib/bridgedb/templates/index.html:6
+msgid "Step 1"
+msgstr "צעד 1"
+
+#: lib/bridgedb/templates/index.html:8
+#, python-format
+msgid "Get %s Tor Browser Bundle %s"
+msgstr "השג את %s Tor Browser Bundle %s"
+
+#: lib/bridgedb/templates/index.html:13
+msgid "Step 2"
+msgstr "צעד 2"
+
+#: lib/bridgedb/templates/index.html:15
+#, python-format
+msgid "Get %s bridges %s"
+msgstr "השג %s גשרים %s"
+
+#: lib/bridgedb/templates/index.html:19
+msgid "Step 3"
+msgstr "צעד 3"
+
+#: lib/bridgedb/templates/index.html:21
+#, python-format
+msgid "Now %s add the bridges to Tor %s"
+msgstr "כעת %s הוסף את הגשרים אל Tor %s"
diff --git a/lib/bridgedb/i18n/hr_HR/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/hr_HR/LC_MESSAGES/bridgedb.po
index 9902e82..b4f04ab 100644
--- a/lib/bridgedb/i18n/hr_HR/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/hr_HR/LC_MESSAGES/bridgedb.po
@@ -1,74 +1,103 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
+# Translations template for BridgeDB.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
-# Armando Vega <synaan(a)gmail.com>, 2012.
-# <trebelnik2(a)gmail.com>, 2012.
+# Translators:
+# dlb031 <abuljan031(a)gmail.com>, 2013
+# Armando Vega <synaan(a)gmail.com>, 2012
+# gogo <trebelnik2(a)gmail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-01-01 07:48-0800\n"
-"PO-Revision-Date: 2012-05-09 07:55+0000\n"
-"Last-Translator: gogo <trebelnik2(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"POT-Creation-Date: 2013-03-27 21:41+0000\n"
+"PO-Revision-Date: 2013-07-31 07:38+0000\n"
+"Last-Translator: dlb031 <abuljan031(a)gmail.com>\n"
+"Language-Team: Croatian (Croatia) (http://www.transifex.com/projects/p/torproject/language/hr_HR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
"Language: hr_HR\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-#: lib/bridgedb/I18n.py:21
-msgid "Here are your bridge relays: "
-msgstr "Ovdje su vaši mostni releji: "
+#: lib/bridgedb/templates/base.html:33
+msgid "What are bridges?"
+msgstr "Što su mostovi?"
-#: lib/bridgedb/I18n.py:23
+#: lib/bridgedb/templates/base.html:34
+#, python-format
msgid ""
-"Bridge relays (or \"bridges\" for short) are Tor relays that aren't listed\n"
-"in the main directory. Since there is no complete public list of them,\n"
-"even if your ISP is filtering connections to all the known Tor relays,\n"
-"they probably won't be able to block all the bridges."
-msgstr "Mostni releji (ili skraćeno \"mostovi\") su Tor releji koji nisu navedeni\nu glavnom imeniku. Kako ne postoji putpuna javna lista,\nčak i ako vaš ISP filtrira veze prema svim poznatim Tor relejima,\nvjerojatno neće moći blokirati sve mostove."
+"%s Bridge relays %s are Tor relays that help you circumvent censorship."
+msgstr "%s Mostni releji %s su Tor releji koji vam pomažu zaobići cenzuru."
-#: lib/bridgedb/I18n.py:28
-msgid ""
-"To use the above lines, go to Vidalia's Network settings page, and click\n"
-"\"My ISP blocks connections to the Tor network\". Then add each bridge\n"
-"address one at a time."
-msgstr "Za korištenje gore navedenih redova, posjetite stranicu\nMrežnih Postavki u Vidaliji, te kliknite \"Moj ISP blokira\nveze prema Tor mreži\". Onda dodajte jednu po jednu\nadresu mostova."
+#: lib/bridgedb/templates/base.html:39
+msgid "I need an alternative way of getting bridges!"
+msgstr "Trebam alternativni način dobivanja mostova!"
-#: lib/bridgedb/I18n.py:32
+#: lib/bridgedb/templates/base.html:40
+#, python-format
msgid ""
-"Configuring more than one bridge address will make your Tor connection\n"
-"more stable, in case some of the bridges become unreachable."
-msgstr "Podešavanjem više od jedne adrese mostova će učiniti vašu\nTor vezu stabilnijom, u nekim slučajevima neki od mostova\npostanu nedostupni."
+"Another way to find public bridge addresses is to send an email (from a %s "
+"or a %s address) to %s with the line 'get bridges' by itself in the body of "
+"the mail."
+msgstr "Još jedan način za pronalazak javnih mostnih adresa je poslati email (sa %s ili %s adrese) da %s samo s rečenicom 'dobiti mostove' u sadržaju maila."
+
+#: lib/bridgedb/templates/base.html:48
+msgid "My bridges don't work! I need help!"
+msgstr "Moji mostovi ne rade! Treba mi pomoć!"
-#: lib/bridgedb/I18n.py:35
+#: lib/bridgedb/templates/base.html:49
+#, python-format
msgid ""
-"Another way to find public bridge addresses is to send mail to\n"
-"bridges(a)torproject.org with the line \"get bridges\" by itself in the body\n"
-"of the mail. However, so we can make it harder for an attacker to learn\n"
-"lots of bridge addresses, you must send this request from an email address at\n"
-"one of the following domains:"
-msgstr "Još jedan način pronalaska adresa javnih mostova je slanjem\ne-pošte na bridges(a)torproject.org sa redom \"get bridges\" samim\nu tijelu e-pošte. Doduše, kako bismo učinili teškim napadačima\notkrivanje mnogo adresa mostova, morate poslati ovaj zahtjev\nsa adrese e-pošte na jednoj od sljedećih domena:"
-
-#: lib/bridgedb/I18n.py:41
-msgid "[This is an automated message; please do not reply.]"
-msgstr "[Ovo je automatizirana poruka; molimo ne odgovarati.]"
-
-#: lib/bridgedb/I18n.py:43
+"If your Tor doesn't work, you should email %s. Try including as much info "
+"about your case as you can, including the list of bridges you used, the "
+"bundle filename/version you used, the messages that Tor gave out, etc."
+msgstr "Ako vaš Tor ne radi, pošaljite email na %s. Probajte uključiti što više informacija o svom slučaju, uključujući popis mostova koje ste koristili, bunde ime datoteke/verziju koju ste koristili, poruke koje je slao Tor, itd."
+
+#: lib/bridgedb/templates/bridges.html:10
msgid ""
-"Another way to find public bridge addresses is to visit\n"
-"https://bridges.torproject.org/. The answers you get from that page\n"
-"will change every few days, so check back periodically if you need more\n"
-"bridge addresses."
-msgstr "Još jedan način za pronalazak adresa javnih mostova\nje posjećivanje https://bridges.torproject.org/. Odgovori\nkoje dobijete sa te stranice se mjenjaju svakih nekoliko\ndana, pa redovno provjeravajte ako trebate još adresa."
-
-#: lib/bridgedb/I18n.py:48
-msgid "(no bridges currently available)"
-msgstr "(trenutno nema dostupnih mostova)"
-
-#: lib/bridgedb/I18n.py:50
-msgid "(e-mail requests not currently supported)"
-msgstr "(zahtjevi e-pošte trenutno nisu podržani)"
+"To use the above lines, go to Vidalia's Network settings page, and click "
+"\"My ISP blocks connections to the Tor network\". Then add each bridge "
+"address one at a time."
+msgstr "Za korištenje gore navedenih redova, posjetite stranicu Mrežnih Postavki u VIdaliji, te kliknite \"Moj ISP blokira veze prema Tor mreži\". Onda dodajte sve mostne adrese jednu po jednu."
+
+#: lib/bridgedb/templates/bridges.html:13
+msgid "No bridges currently available"
+msgstr "Nema trenutno dostupnih mostova"
+
+#: lib/bridgedb/templates/captcha.html:6
+msgid "Upgrade your browser to Firefox"
+msgstr "Nadogradite vaš preglednik na Firefox"
+
+#: lib/bridgedb/templates/captcha.html:8
+msgid "Type the two words"
+msgstr "Napišite ove dvije riječi"
+
+#: lib/bridgedb/templates/index.html:6
+msgid "Step 1"
+msgstr "Korak 1"
+
+#: lib/bridgedb/templates/index.html:8
+#, python-format
+msgid "Get %s Tor Browser Bundle %s"
+msgstr "Dobijte %s Tor Preglednički Paket %s"
+
+#: lib/bridgedb/templates/index.html:13
+msgid "Step 2"
+msgstr "Korak 2"
+
+#: lib/bridgedb/templates/index.html:15
+#, python-format
+msgid "Get %s bridges %s"
+msgstr "Dobijte %s mostove %s"
+
+#: lib/bridgedb/templates/index.html:19
+msgid "Step 3"
+msgstr "Korak 3"
+
+#: lib/bridgedb/templates/index.html:21
+#, python-format
+msgid "Now %s add the bridges to Tor %s"
+msgstr "Sad %s dodajte mostove na Tor %s"
diff --git a/lib/bridgedb/i18n/lv/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/lv/LC_MESSAGES/bridgedb.po
index d611bf1..dea7a31 100644
--- a/lib/bridgedb/i18n/lv/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/lv/LC_MESSAGES/bridgedb.po
@@ -12,7 +12,7 @@ msgstr ""
"POT-Creation-Date: 2013-03-27 21:41+0000\n"
"PO-Revision-Date: 2013-04-29 09:24+0000\n"
"Last-Translator: runasand <runa.sandvik(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language-Team: Latvian (http://www.transifex.com/projects/p/torproject/language/lv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/lib/bridgedb/i18n/ms_MY/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/ms_MY/LC_MESSAGES/bridgedb.po
index 56b8d9c..ced2126 100644
--- a/lib/bridgedb/i18n/ms_MY/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/ms_MY/LC_MESSAGES/bridgedb.po
@@ -1,73 +1,102 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
+# Translations template for BridgeDB.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
-# Weldan Jamili <mweldan(a)gmail.com>, 2012.
+# Translators:
+# shahril <mohd_shahril_96(a)yahoo.com>, 2013
+# Weldan Jamili <mweldan(a)gmail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-01-01 07:48-0800\n"
-"PO-Revision-Date: 2012-05-31 12:46+0000\n"
-"Last-Translator: Weldan Jamili <mweldan(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"POT-Creation-Date: 2013-03-27 21:41+0000\n"
+"PO-Revision-Date: 2013-08-08 03:30+0000\n"
+"Last-Translator: shahril <mohd_shahril_96(a)yahoo.com>\n"
+"Language-Team: Malay (Malaysia) (http://www.transifex.com/projects/p/torproject/language/ms_MY/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
"Language: ms_MY\n"
-"Plural-Forms: nplurals=1; plural=0\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
-#: lib/bridgedb/I18n.py:21
-msgid "Here are your bridge relays: "
-msgstr "Berikut adalah geganti jambatan anda:"
+#: lib/bridgedb/templates/base.html:33
+msgid "What are bridges?"
+msgstr "Apakah itu bridges ?"
-#: lib/bridgedb/I18n.py:23
+#: lib/bridgedb/templates/base.html:34
+#, python-format
msgid ""
-"Bridge relays (or \"bridges\" for short) are Tor relays that aren't listed\n"
-"in the main directory. Since there is no complete public list of them,\n"
-"even if your ISP is filtering connections to all the known Tor relays,\n"
-"they probably won't be able to block all the bridges."
-msgstr "Geganti jambatan (atau \"jambatan\" untuk pendek) geganti Tor yang tidak disenaraikan ⏎\ndalam direktori utama. Memandangkan terdapat tiada senarai lengkap awam mereka, ⏎\nwalaupun jika ISP anda penapisan sambungan kepada semua geganti Tor yang diketahui, ⏎\nmereka mungkin tidak akan mampu untuk menyekat semua jambatan."
+"%s Bridge relays %s are Tor relays that help you circumvent censorship."
+msgstr "%s Bridge relays %s adalah tor relays yang akan membantu kamu menghindari penyaringan."
-#: lib/bridgedb/I18n.py:28
-msgid ""
-"To use the above lines, go to Vidalia's Network settings page, and click\n"
-"\"My ISP blocks connections to the Tor network\". Then add each bridge\n"
-"address one at a time."
-msgstr "Untuk menggunakan talian di atas, pergi ke halaman ini tetapan Rangkaian Vidalia, dan klik ⏎\n\"Blok sambungan ISP Saya rangkaian Tor\". Kemudian tambah jambatan setiap ⏎\nmenyelesaikan satu pada satu-satu masa."
+#: lib/bridgedb/templates/base.html:39
+msgid "I need an alternative way of getting bridges!"
+msgstr "Saya memerlukan cara alternatif untuk mendapatkan bridges!"
-#: lib/bridgedb/I18n.py:32
+#: lib/bridgedb/templates/base.html:40
+#, python-format
msgid ""
-"Configuring more than one bridge address will make your Tor connection\n"
-"more stable, in case some of the bridges become unreachable."
-msgstr "Konfigurasi lebih daripada satu alamat jambatan akan membuat sambungan Tor anda\nlebih stabil, dalam hal jambatan menjadi sukar untuk dicapai."
+"Another way to find public bridge addresses is to send an email (from a %s "
+"or a %s address) to %s with the line 'get bridges' by itself in the body of "
+"the mail."
+msgstr "Satu lagi cara untuk mencari alamat bridges awam adalah untuk menghantar email (dari %s atau alamat %s) ke %s dengan bertulis 'get bridges' dalam badan email tersebut."
+
+#: lib/bridgedb/templates/base.html:48
+msgid "My bridges don't work! I need help!"
+msgstr "Bridges saya tidak berfungsi! Saya perlukan bantuan!"
-#: lib/bridgedb/I18n.py:35
+#: lib/bridgedb/templates/base.html:49
+#, python-format
msgid ""
-"Another way to find public bridge addresses is to send mail to\n"
-"bridges(a)torproject.org with the line \"get bridges\" by itself in the body\n"
-"of the mail. However, so we can make it harder for an attacker to learn\n"
-"lots of bridge addresses, you must send this request from an email address at\n"
-"one of the following domains:"
-msgstr "Satu lagi cara untuk mencari alamat jambatan awam adalah untuk menghantar mel kepada ⏎\nbridges(a)torproject.org dengan garisan \"jambatan\" dengan sendirinya dalam badan ⏎\nmel. Walau bagaimanapun, jadi kita boleh membuat lebih sukar bagi penyerang untuk mempelajari ⏎\nbanyak alamat jambatan, anda mesti menghantar permintaan ini dari alamat e-mel pada ⏎\nsalah satu domain berikut:"
-
-#: lib/bridgedb/I18n.py:41
-msgid "[This is an automated message; please do not reply.]"
-msgstr "[Ini adalah mesej automatik; sila tidak menjawab.]"
-
-#: lib/bridgedb/I18n.py:43
+"If your Tor doesn't work, you should email %s. Try including as much info "
+"about your case as you can, including the list of bridges you used, the "
+"bundle filename/version you used, the messages that Tor gave out, etc."
+msgstr "Jika Tor kamu tidak berfungsi, kamu patut cuba email kepada %s. Cuba masukkan sebanyak mana info yang boleh terhadap permasalahan kamu, termasuk senarai bridges yang kamu guna, dan fail nama bundle dan versi bundle yang kamu guna, dan mesej yang Tor tunjukkan, dan lain-lain."
+
+#: lib/bridgedb/templates/bridges.html:10
msgid ""
-"Another way to find public bridge addresses is to visit\n"
-"https://bridges.torproject.org/. The answers you get from that page\n"
-"will change every few days, so check back periodically if you need more\n"
-"bridge addresses."
-msgstr "Satu lagi cara untuk mencari alamat jambatan awam adalah untuk melawat ⏎\nhttps://bridges.torproject.org/. Jawapan yang anda dapat dari laman utama itu ⏎\nakan berubah setiap beberapa hari, jadi periksa kembali secara berkala jika anda memerlukan lebih banyak ⏎\njambatan alamat."
-
-#: lib/bridgedb/I18n.py:48
-msgid "(no bridges currently available)"
-msgstr "(tiada jambatan yang sedia ada)"
-
-#: lib/bridgedb/I18n.py:50
-msgid "(e-mail requests not currently supported)"
-msgstr "(e-mel meminta tidak disokong pada masa ini)"
+"To use the above lines, go to Vidalia's Network settings page, and click "
+"\"My ISP blocks connections to the Tor network\". Then add each bridge "
+"address one at a time."
+msgstr "Untuk menggunakan bridges di bawah, pergi ke halaman tetapan Jaringan Vidalia, dan klik \"ISP saya menyekat sambungan saya ke dalam jaringan Tor\". Kemudian tambah setiap alamat bridges satu persatu."
+
+#: lib/bridgedb/templates/bridges.html:13
+msgid "No bridges currently available"
+msgstr "Tiada bridges pada masa sekarang."
+
+#: lib/bridgedb/templates/captcha.html:6
+msgid "Upgrade your browser to Firefox"
+msgstr "Menaik taraf firefox anda"
+
+#: lib/bridgedb/templates/captcha.html:8
+msgid "Type the two words"
+msgstr "Tulis dua perkataan itu."
+
+#: lib/bridgedb/templates/index.html:6
+msgid "Step 1"
+msgstr "Langkah 1"
+
+#: lib/bridgedb/templates/index.html:8
+#, python-format
+msgid "Get %s Tor Browser Bundle %s"
+msgstr "Dapatkan %s Tor Browser Bundle %s."
+
+#: lib/bridgedb/templates/index.html:13
+msgid "Step 2"
+msgstr "Langkah 2"
+
+#: lib/bridgedb/templates/index.html:15
+#, python-format
+msgid "Get %s bridges %s"
+msgstr "Dapatkan %s bridges %s"
+
+#: lib/bridgedb/templates/index.html:19
+msgid "Step 3"
+msgstr "Langkah 3"
+
+#: lib/bridgedb/templates/index.html:21
+#, python-format
+msgid "Now %s add the bridges to Tor %s"
+msgstr "Sekarang %s tambah bridges tersebut ke Tor %s"
diff --git a/lib/bridgedb/i18n/nl/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/nl/LC_MESSAGES/bridgedb.po
index 6fbbeba..b6f56c0 100644
--- a/lib/bridgedb/i18n/nl/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/nl/LC_MESSAGES/bridgedb.po
@@ -1,74 +1,104 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
+# Translations template for BridgeDB.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
-# Shondoit Walker <shondoit+transifex(a)gmail.com>, 2011.
-# <therbom(a)gmail.com>, 2012.
+# Adriaan Callaerts <adriaan.callaerts(a)gmail.com>, 2013
+# WMRKameleon <info(a)wmrkameleon.nl>, 2013
+# Shondoit Walker <shondoit(a)gmail.com>, 2011
+# Marco Brohet <therbom(a)gmail.com>, 2012
+# math1985 <transifex(a)matthijsmelissen.nl>, 2013
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-01-01 07:48-0800\n"
-"PO-Revision-Date: 2012-09-20 21:23+0000\n"
-"Last-Translator: therbom <therbom(a)gmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"POT-Creation-Date: 2013-03-27 21:41+0000\n"
+"PO-Revision-Date: 2013-06-21 14:30+0000\n"
+"Last-Translator: math1985 <transifex(a)matthijsmelissen.nl>\n"
+"Language-Team: Dutch (http://www.transifex.com/projects/p/torproject/language/nl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
"Language: nl\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: lib/bridgedb/I18n.py:21
-msgid "Here are your bridge relays: "
-msgstr "Uw bridge-relays:"
+#: lib/bridgedb/templates/base.html:33
+msgid "What are bridges?"
+msgstr "Wat zijn bridges?"
-#: lib/bridgedb/I18n.py:23
+#: lib/bridgedb/templates/base.html:34
+#, python-format
msgid ""
-"Bridge relays (or \"bridges\" for short) are Tor relays that aren't listed\n"
-"in the main directory. Since there is no complete public list of them,\n"
-"even if your ISP is filtering connections to all the known Tor relays,\n"
-"they probably won't be able to block all the bridges."
-msgstr "Bridge-relays (of \"bridges\" in het kort) zijn Tor-relays die niet in de hoofdlijst vermeld zijn. Omdat er geen volledige openbare lijst beschikbaar is, ook al filtert uw provider verbindingen naar alle bekende Tor-relays, kunnen waarschijnlijk niet all bridges worden geblokkerd."
+"%s Bridge relays %s are Tor relays that help you circumvent censorship."
+msgstr "%s Bridge relays %s zijn Tor relays die je in staat stellen censuur te omzeilen."
-#: lib/bridgedb/I18n.py:28
-msgid ""
-"To use the above lines, go to Vidalia's Network settings page, and click\n"
-"\"My ISP blocks connections to the Tor network\". Then add each bridge\n"
-"address one at a time."
-msgstr "Om de bovenstaande regels te gebruiken, gaat u naar de netwerkinstellingen van Vidalia en klikt u op \"Mijn provider blokkeert verbindingen naar het Tor-netwerk\". Daarna voegt u elke bridge toe, één regel per keer."
+#: lib/bridgedb/templates/base.html:39
+msgid "I need an alternative way of getting bridges!"
+msgstr "Ik heb een alternatieve manier nodig om bridges te verkrijgen."
-#: lib/bridgedb/I18n.py:32
+#: lib/bridgedb/templates/base.html:40
+#, python-format
msgid ""
-"Configuring more than one bridge address will make your Tor connection\n"
-"more stable, in case some of the bridges become unreachable."
-msgstr "Het instellen van meerde bridges komt ten goede aan de stabiliteit van uw Tor-verbinding, indien een aantal bridges niet bereikbaar zijn."
+"Another way to find public bridge addresses is to send an email (from a %s "
+"or a %s address) to %s with the line 'get bridges' by itself in the body of "
+"the mail."
+msgstr "Een andere manier om publieke bridges te vinden is om een e-mail te sturen (van een %s of een %s-adres) naar %s met enkel de regel 'get bridges' in de inhoud van de e-mail."
-#: lib/bridgedb/I18n.py:35
+#: lib/bridgedb/templates/base.html:48
+msgid "My bridges don't work! I need help!"
+msgstr "Mijn bridges werken niet! Ik heb hulp nodig!"
+
+#: lib/bridgedb/templates/base.html:49
+#, python-format
msgid ""
-"Another way to find public bridge addresses is to send mail to\n"
-"bridges(a)torproject.org with the line \"get bridges\" by itself in the body\n"
-"of the mail. However, so we can make it harder for an attacker to learn\n"
-"lots of bridge addresses, you must send this request from an email address at\n"
-"one of the following domains:"
-msgstr "Een andere manier om openbare bridge-adressen op te zoeken, is om een e-mail te sturen naar bridges(a)torproject.org met alleen de regel \"get bridges\" daarin. Echter, om het moeilijker te maken aanvallers om veel bridge-adressen te ontdekken, dient u uw verzoek te versturen met een e-mailadres van één van de volgende domeinen:"
-
-#: lib/bridgedb/I18n.py:41
-msgid "[This is an automated message; please do not reply.]"
-msgstr "[Dit is een automatisch bericht, gelieve niet te beantwoorden.]"
-
-#: lib/bridgedb/I18n.py:43
+"If your Tor doesn't work, you should email %s. Try including as much info "
+"about your case as you can, including the list of bridges you used, the "
+"bundle filename/version you used, the messages that Tor gave out, etc."
+msgstr "Als je Tor niet werkt, zou je %s moeten e-mailen. Probeer zo veel mogelijk informatie over uw geval te verzamelen, inclusief de lijst van bridges die u heeft gebruikt, de bestandsnaam en -versie van de bundel die u gebruikt, de berichten die Tor uitgaf, etc."
+
+#: lib/bridgedb/templates/bridges.html:10
msgid ""
-"Another way to find public bridge addresses is to visit\n"
-"https://bridges.torproject.org/. The answers you get from that page\n"
-"will change every few days, so check back periodically if you need more\n"
-"bridge addresses."
-msgstr "Om op een andere manier openbare bridges op te zoeken, gaat u naar https://bridges.torproject.org/. De gegevens op die pagina worden om de paar dagen bijgewerkt, dus wordt het aangeraden regelmatig de pagina te bezoeken voor meer bridges."
-
-#: lib/bridgedb/I18n.py:48
-msgid "(no bridges currently available)"
-msgstr "(momenteel geen bridges beschikbaar)"
-
-#: lib/bridgedb/I18n.py:50
-msgid "(e-mail requests not currently supported)"
-msgstr "(e-mailverzoeken worden momenteel niet ondersteund)"
+"To use the above lines, go to Vidalia's Network settings page, and click "
+"\"My ISP blocks connections to the Tor network\". Then add each bridge "
+"address one at a time."
+msgstr "Om de bovenstaande regels te gebruiken, ga naar Vidalia's Netwerk instellingen pagina en klik op \"Mijn ISP blokkeert verbindingen naar het Tor netwerk\". Voeg daarna elke bridge toe, één regel per keer."
+
+#: lib/bridgedb/templates/bridges.html:13
+msgid "No bridges currently available"
+msgstr "Er zijn momenteel geen bridges beschikbaar."
+
+#: lib/bridgedb/templates/captcha.html:6
+msgid "Upgrade your browser to Firefox"
+msgstr "Upgrade uw browser naar Firefox"
+
+#: lib/bridgedb/templates/captcha.html:8
+msgid "Type the two words"
+msgstr "Typ de twee woorden"
+
+#: lib/bridgedb/templates/index.html:6
+msgid "Step 1"
+msgstr "Stap 1"
+
+#: lib/bridgedb/templates/index.html:8
+#, python-format
+msgid "Get %s Tor Browser Bundle %s"
+msgstr "Download %s Tor Browser Bundle %s"
+
+#: lib/bridgedb/templates/index.html:13
+msgid "Step 2"
+msgstr "Stap 2"
+
+#: lib/bridgedb/templates/index.html:15
+#, python-format
+msgid "Get %s bridges %s"
+msgstr "Download %s bridges %s"
+
+#: lib/bridgedb/templates/index.html:19
+msgid "Step 3"
+msgstr "Stap 3"
+
+#: lib/bridgedb/templates/index.html:21
+#, python-format
+msgid "Now %s add the bridges to Tor %s"
+msgstr "%s Voeg nu de bridges aan Tor toe %s"
diff --git a/lib/bridgedb/i18n/sv/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/sv/LC_MESSAGES/bridgedb.po
index 180bc32..8d4bb80 100644
--- a/lib/bridgedb/i18n/sv/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/sv/LC_MESSAGES/bridgedb.po
@@ -1,73 +1,102 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
+# Translations template for BridgeDB.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
-# <petomatick(a)hotmail.com>, 2011.
+# Translators:
+# Petomatick <petomatick(a)hotmail.com>, 2011
+# WinterFairy <winterfairy(a)riseup.net>, 2013
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-01-01 07:48-0800\n"
-"PO-Revision-Date: 2012-02-14 10:04+0000\n"
-"Last-Translator: Petomatick <petomatick(a)hotmail.com>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"POT-Creation-Date: 2013-03-27 21:41+0000\n"
+"PO-Revision-Date: 2013-06-25 14:00+0000\n"
+"Last-Translator: WinterFairy <winterfairy(a)riseup.net>\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/torproject/language/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
"Language: sv\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: lib/bridgedb/I18n.py:21
-msgid "Here are your bridge relays: "
-msgstr "Här är dina bro reläer:"
+#: lib/bridgedb/templates/base.html:33
+msgid "What are bridges?"
+msgstr "Vad är bryggor?"
-#: lib/bridgedb/I18n.py:23
+#: lib/bridgedb/templates/base.html:34
+#, python-format
msgid ""
-"Bridge relays (or \"bridges\" for short) are Tor relays that aren't listed\n"
-"in the main directory. Since there is no complete public list of them,\n"
-"even if your ISP is filtering connections to all the known Tor relays,\n"
-"they probably won't be able to block all the bridges."
-msgstr "Bridge reläer (eller \"broar\" för kort) är Tor-servrar som inte finns i huvudkatalogen. Eftersom det inte finns någon fullständig offentlig förteckning över dem, även om din ISP filtrerar alla de kända Tor-servrarna, kan de sannolikt inte att kunna blockera alla broar."
+"%s Bridge relays %s are Tor relays that help you circumvent censorship."
+msgstr "%s Bryggreläer %s är Tor reläer som hjälper dig kringå censurering."
-#: lib/bridgedb/I18n.py:28
-msgid ""
-"To use the above lines, go to Vidalia's Network settings page, and click\n"
-"\"My ISP blocks connections to the Tor network\". Then add each bridge\n"
-"address one at a time."
-msgstr "För att använda ovanstående rader, gå till Vidalia nätverksinställningar sidan och klicka på \"Min ISP blockerar anslutningar till Tor-nätverket\". Tillsätt sedan varje bro adress i taget."
+#: lib/bridgedb/templates/base.html:39
+msgid "I need an alternative way of getting bridges!"
+msgstr "Jag behöver ett alternativt sätt att skaffa bryggor på!"
-#: lib/bridgedb/I18n.py:32
+#: lib/bridgedb/templates/base.html:40
+#, python-format
msgid ""
-"Configuring more than one bridge address will make your Tor connection\n"
-"more stable, in case some of the bridges become unreachable."
-msgstr "Konfigurera fler än en bro-adress kommer att göra din Tor-anslutning mer stabil, i det fall att några broar blir onåbara."
+"Another way to find public bridge addresses is to send an email (from a %s "
+"or a %s address) to %s with the line 'get bridges' by itself in the body of "
+"the mail."
+msgstr "Ett annat sätt att hitta publika bryggadresser är genom att skicka ett mail (från en %s eller en %s adress) till %s med raden 'get bridges' ensamt i meddelandetexten."
+
+#: lib/bridgedb/templates/base.html:48
+msgid "My bridges don't work! I need help!"
+msgstr "Mina bryggor fungerar inte! Jag behöver hjälp!"
-#: lib/bridgedb/I18n.py:35
+#: lib/bridgedb/templates/base.html:49
+#, python-format
msgid ""
-"Another way to find public bridge addresses is to send mail to\n"
-"bridges(a)torproject.org with the line \"get bridges\" by itself in the body\n"
-"of the mail. However, so we can make it harder for an attacker to learn\n"
-"lots of bridge addresses, you must send this request from an email address at\n"
-"one of the following domains:"
-msgstr "Ett annat sätt att hitta offentliga bro adresser är att skicka e-post till bridges(a)torproject.org med raden \"get bridges\" av sig själv i kroppen av posten. Men för att göra det svårare för en angripare att lära sig massor av bro-adresser måste du skicka denna begäran från en e-postadress vid ett av följande områden:"
-
-#: lib/bridgedb/I18n.py:41
-msgid "[This is an automated message; please do not reply.]"
-msgstr "[Detta är ett automatiskt meddelande; Var god svara ej]"
-
-#: lib/bridgedb/I18n.py:43
+"If your Tor doesn't work, you should email %s. Try including as much info "
+"about your case as you can, including the list of bridges you used, the "
+"bundle filename/version you used, the messages that Tor gave out, etc."
+msgstr "Om Tor inte fungerar för dig, maila på engelska till %s. Försök att inkludera så mycket information om ditt fall som möjligt, inklusive listan över bryggor du använde, Tor-paketets filnamn/version, meddelandet Tor gav dig, osv."
+
+#: lib/bridgedb/templates/bridges.html:10
msgid ""
-"Another way to find public bridge addresses is to visit\n"
-"https://bridges.torproject.org/. The answers you get from that page\n"
-"will change every few days, so check back periodically if you need more\n"
-"bridge addresses."
-msgstr "Ett annat sätt att hitta offentliga bro-adresser är att besöka https://bridges.torproject.org/. Svaren du får från den sidan kommer att förändras med några dagars mellanrum, så titta in med jämna mellanrum om du behöver mer bro adresser."
-
-#: lib/bridgedb/I18n.py:48
-msgid "(no bridges currently available)"
-msgstr "(Inga broar tillgängliga för närvarande)"
-
-#: lib/bridgedb/I18n.py:50
-msgid "(e-mail requests not currently supported)"
-msgstr "(E-post förfrågningar stöds för närvarande inte)"
+"To use the above lines, go to Vidalia's Network settings page, and click "
+"\"My ISP blocks connections to the Tor network\". Then add each bridge "
+"address one at a time."
+msgstr "För att använda ovanstående rader, gå in i Vidalias nätverksinställningar, och välj \"Min internetleverantör blockerar anslutningar till Tor-nätverket\". Lägg sedan till varje bryggadress en åt gången."
+
+#: lib/bridgedb/templates/bridges.html:13
+msgid "No bridges currently available"
+msgstr "Inga bryggor tillgängliga för närvarande"
+
+#: lib/bridgedb/templates/captcha.html:6
+msgid "Upgrade your browser to Firefox"
+msgstr "Uppgradera din webbläsare till Firefox"
+
+#: lib/bridgedb/templates/captcha.html:8
+msgid "Type the two words"
+msgstr "Skriv in de två orden"
+
+#: lib/bridgedb/templates/index.html:6
+msgid "Step 1"
+msgstr "Steg 1"
+
+#: lib/bridgedb/templates/index.html:8
+#, python-format
+msgid "Get %s Tor Browser Bundle %s"
+msgstr "Skaffa %s Tor Browser Bundle %s"
+
+#: lib/bridgedb/templates/index.html:13
+msgid "Step 2"
+msgstr "Steg 2"
+
+#: lib/bridgedb/templates/index.html:15
+#, python-format
+msgid "Get %s bridges %s"
+msgstr "Skaffa %s bryggor %s"
+
+#: lib/bridgedb/templates/index.html:19
+msgid "Step 3"
+msgstr "Steg 3"
+
+#: lib/bridgedb/templates/index.html:21
+#, python-format
+msgid "Now %s add the bridges to Tor %s"
+msgstr "Lägg nu till %s bryggorna till Tor %s"
diff --git a/lib/bridgedb/i18n/th/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/th/LC_MESSAGES/bridgedb.po
new file mode 100644
index 0000000..a8b6727
--- /dev/null
+++ b/lib/bridgedb/i18n/th/LC_MESSAGES/bridgedb.po
@@ -0,0 +1,101 @@
+# Translations template for BridgeDB.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the BridgeDB project.
+#
+# Translators:
+# Translators:
+# AomNicha <vainilla7(a)gmail.com>, 2013
+msgid ""
+msgstr ""
+"Project-Id-Version: The Tor Project\n"
+"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
+"POT-Creation-Date: 2013-03-27 21:41+0000\n"
+"PO-Revision-Date: 2013-07-27 08:50+0000\n"
+"Last-Translator: AomNicha <vainilla7(a)gmail.com>\n"
+"Language-Team: Thai (http://www.transifex.com/projects/p/torproject/language/th/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+"Language: th\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: lib/bridgedb/templates/base.html:33
+msgid "What are bridges?"
+msgstr "สะพานหมายถึงอะไร"
+
+#: lib/bridgedb/templates/base.html:34
+#, python-format
+msgid ""
+"%s Bridge relays %s are Tor relays that help you circumvent censorship."
+msgstr "%s สะพานรีเลย์ %s คือ Tor รีเลย์ ที่ช่วยให้คุณสามารหลีกหนีการตรวจสอบ"
+
+#: lib/bridgedb/templates/base.html:39
+msgid "I need an alternative way of getting bridges!"
+msgstr "ฉันต้องการทางเลือกอื่นเพื่อเข้าถึงสะพาน"
+
+#: lib/bridgedb/templates/base.html:40
+#, python-format
+msgid ""
+"Another way to find public bridge addresses is to send an email (from a %s "
+"or a %s address) to %s with the line 'get bridges' by itself in the body of "
+"the mail."
+msgstr "อีกหนึ่งช่องทาง สำหรับค้นหาที่อยู่ของสะพานสาธารณะ สามารถทำได้ผ่านการส่งอีเมล (จาก %s หรือ ที่อยู่ %s) ไปสู่ %s ด้วยเส้นทาง \"\n\"การเข้าถึงสะพาน\" ภายในเนื้อหาของอีเมล"
+
+#: lib/bridgedb/templates/base.html:48
+msgid "My bridges don't work! I need help!"
+msgstr "ต้องการความช่วยเหลือ สะพานไม่ทำงาน"
+
+#: lib/bridgedb/templates/base.html:49
+#, python-format
+msgid ""
+"If your Tor doesn't work, you should email %s. Try including as much info "
+"about your case as you can, including the list of bridges you used, the "
+"bundle filename/version you used, the messages that Tor gave out, etc."
+msgstr "ถ้า Tor ไม่ทำงาน ให้คุณส่งอีเมล %s พร้อมแนบข้อมูลเกี่ยวกับสถานการณ์ของคุณ รายชื่อของสะพานที่คุณเคยใช้ บัญชีรายชื่อหรือเวอร์ชั่นที่คุณเคยใช้ ข้อความที่ Tor ส่งถึงคุณ และอื่นๆ ที่จำเป็น"
+
+#: lib/bridgedb/templates/bridges.html:10
+msgid ""
+"To use the above lines, go to Vidalia's Network settings page, and click "
+"\"My ISP blocks connections to the Tor network\". Then add each bridge "
+"address one at a time."
+msgstr " เพื่อใช้งานตามคำแนะนำด้านบน ไปที่การตั้งค่าเครือข่าย Vidalia จากนั้นคลิกที่ \"ไอเอสพีของฉันถูกปิดกั้นไม่ให้เชื่อมต่อกับเครือข่าย\" Tor และกดเพิ่มที่อยู่ของสะพานแต่ละอันลงไป"
+
+#: lib/bridgedb/templates/bridges.html:13
+msgid "No bridges currently available"
+msgstr "ไม่มีสะพานที่ใช้งานได้ในขณะนี้"
+
+#: lib/bridgedb/templates/captcha.html:6
+msgid "Upgrade your browser to Firefox"
+msgstr "ช่วยปรับรุ่นเบราว์เซอร์ของคุณเป็นไฟล์ฟ็อก"
+
+#: lib/bridgedb/templates/captcha.html:8
+msgid "Type the two words"
+msgstr "ให้พิมพ์คำสองคำ"
+
+#: lib/bridgedb/templates/index.html:6
+msgid "Step 1"
+msgstr "ขั้นตอนที่ 1"
+
+#: lib/bridgedb/templates/index.html:8
+#, python-format
+msgid "Get %s Tor Browser Bundle %s"
+msgstr "ได้ %s Tor Browser Bundle %s"
+
+#: lib/bridgedb/templates/index.html:13
+msgid "Step 2"
+msgstr "ขั้นตอนที่ 2"
+
+#: lib/bridgedb/templates/index.html:15
+#, python-format
+msgid "Get %s bridges %s"
+msgstr "ได้ %s สะพาน %s"
+
+#: lib/bridgedb/templates/index.html:19
+msgid "Step 3"
+msgstr "ขั้นตอนที่ 3"
+
+#: lib/bridgedb/templates/index.html:21
+#, python-format
+msgid "Now %s add the bridges to Tor %s"
+msgstr "ขณะนี้ %s ได้เพิ่มสะพานไปที่ Tor %s แล้ว"
diff --git a/lib/bridgedb/i18n/zh_CN/LC_MESSAGES/bridgedb.po b/lib/bridgedb/i18n/zh_CN/LC_MESSAGES/bridgedb.po
index 0abc9be..aec9bc4 100644
--- a/lib/bridgedb/i18n/zh_CN/LC_MESSAGES/bridgedb.po
+++ b/lib/bridgedb/i18n/zh_CN/LC_MESSAGES/bridgedb.po
@@ -3,6 +3,8 @@
# This file is distributed under the same license as the BridgeDB project.
#
# Translators:
+# Translators:
+# simabull tsai, 2013
# simabull tsai, 2013
# simabull tsai, 2013
# Christopher Meng <cickumqt(a)gmail.com>, 2012
@@ -12,9 +14,9 @@ msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
"POT-Creation-Date: 2013-03-27 21:41+0000\n"
-"PO-Revision-Date: 2013-04-30 20:37+0000\n"
+"PO-Revision-Date: 2013-06-28 00:10+0000\n"
"Last-Translator: simabull tsai\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/torproject/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -42,7 +44,7 @@ msgid ""
"Another way to find public bridge addresses is to send an email (from a %s "
"or a %s address) to %s with the line 'get bridges' by itself in the body of "
"the mail."
-msgstr "获取公开的网桥地址还有一种方式:使用 %s 或 %s 邮箱发送电子邮件,并在邮件正文中包含文字“get bridges”。 ( %s )"
+msgstr "获取公开的网桥地址还有一种方式:使用 %s 或 %s 邮箱发送电子邮件至 %s,并在邮件正文中包含文字“get bridges”。 "
#: lib/bridgedb/templates/base.html:48
msgid "My bridges don't work! I need help!"
@@ -61,7 +63,7 @@ msgid ""
"To use the above lines, go to Vidalia's Network settings page, and click "
"\"My ISP blocks connections to the Tor network\". Then add each bridge "
"address one at a time."
-msgstr "如需使用以上地址,请打开 Vidalia 网络设置,选中“我的 ISP 阻挡了对 Tor 网络的连接\",然后依次添加网络地址。"
+msgstr "如需使用以上地址,请打开 Vidalia 网络设置,选中“我的 ISP 阻挡了对 Tor 网络的连接\",然后依次添加网桥地址。"
#: lib/bridgedb/templates/bridges.html:13
msgid "No bridges currently available"
@@ -100,4 +102,4 @@ msgstr "第 3 步"
#: lib/bridgedb/templates/index.html:21
#, python-format
msgid "Now %s add the bridges to Tor %s"
-msgstr "现在可%s 将网桥添加到 Tor %s"
+msgstr "现在 %s 将网桥添加到 Tor %s"
1
0