async def run(reactor, cfg, tor, beta, alpha, use_clearnet, system_keychain, no_extract, no_launch): # NOTE the middle cert changed on April 10 or thereabouts; # still need to confirm this is legitimate? chain = [ ssl.Certificate.loadPEM( pkg_resources.resource_string('carml', 'keys/torproject.pem')), ssl.Certificate.loadPEM( pkg_resources.resource_string('carml', 'keys/digicert-sha2.pem')), ssl.Certificate.loadPEM( pkg_resources.resource_string('carml', 'keys/digicert-root-ca.pem')), ] cf = VerifyCertChainContextFactory(chain) if use_clearnet: print( util.colors.red('WARNING') + ': downloading over plain Internet (not via Tor).') agent = Agent(reactor, contextFactory=cf) else: agent = tor.web_agent() # see onion.torproject.org to verify this is "www.torproject.org" equiv uri = b'http://expyuzz4wqqyqhjn.onion/projects/torbrowser/RecommendedTBBVersions' data = BytesIO() print(u'Getting recommended versions from "{}".'.format( uri.decode('ascii'))) try: await download(agent, uri, data) except Exception as e: if hasattr(value, 'reasons'): msg = ''.join([str(r.value.args[-1]) for r in fail.value.reasons]) raise RuntimeError(msg) raise # valid platforms from check.torproject.org can be one of: # 'Linux', 'MacOS' or 'Windows' plat = platform.system().lower() arch = platform.uname()[-2] plat_to_tor = dict(linux='Linux', darwin='MacOS', windows='Win') if plat not in plat_to_tor: print('Unknown platform "%s".' % plat) raise RuntimeError('Unknown platform "%s".' % plat) tor_plat = plat_to_tor[plat] data_bytes = data.getvalue() try: versions = json.loads(data_bytes.decode('utf8')) except: print('Error getting versions; invalid JSON:') print(data_bytes) raise RuntimeError('Invalid JSON:\n{}'.format(data_bytes)) alpha_re = re.compile(r'[0-9]*.[0-9]*a[0-9]-(Windows|MacOS|Linux)') beta_re = re.compile(r'[0-9]*.[0-9]*b[0-9]-(Windows|MacOS|Linux)') hardened_re = re.compile(r'(.*)-hardened-(.*)') print(util.wrap(', '.join(versions), 60, ' ')) alphas = [x for x in versions if alpha_re.match(x)] betas = [x for x in versions if beta_re.match(x)] hardened = [x for x in versions if hardened_re.match(x)] others = set(versions).difference(alphas, betas, hardened) if alpha: versions = alphas elif beta: versions = betas else: versions = others if alphas and not alpha: print( util.colors.yellow( "Note: there are alpha versions available; use --alpha to download." )) if betas and not beta: print( util.colors.yellow( "Note: there are beta versions available; use --beta to download." )) if hardened: print( util.colors.yellow( "Note: there are hardened versions available but we don't support downloading them yet." )) target_version = None for v in versions: if v.endswith(tor_plat): target_version = v[:v.rfind('-')] if target_version is None: print("Can't find a version to download") print(" My platform is: %s (%s)" % (plat, plat_to_tor[plat])) print(" Potential versions are: %s" % ', '.join(versions)) if beta: print("(Try without --beta)") elif alpha: print("(Try without --alpha)") raise RuntimeError("Nothing to download found.") # download the signature, then browser-bundle (if they don't # already exist locally). sig_fname, dist_fname = get_download_urls(plat, arch, target_version) for to_download in [sig_fname, dist_fname]: # this will 302 to the right spot, but goes to clearweb (dist.torproject.org) instead of onion service... # uri = u'http://expyuzz4wqqyqhjn.onion/dist/torbrowser/{}/{}'.format(target_version, to_download).encode('ascii') # see onion.torproject.org to verify this is "dist.torproject.org" equiv uri = u'http://rqef5a5mebgq46y5.onion/torbrowser/{}/{}'.format( target_version, to_download).encode('ascii') if os.path.exists(to_download): print( util.colors.red(to_download) + ': already exists, so not downloading.') else: try: with open(to_download, 'wb') as f: print('Downloading "%s" from:\n %s' % (to_download, uri.decode('ascii'))) await download(agent, uri, f) except Exception as e: print('removing "%s"...' % to_download) os.unlink(to_download) raise # ensure the signature matches if verify_signature(sig_fname, system_gpg=system_keychain): print(util.colors.green("Signature is good.")) if no_extract: print("Download and signature check of the Tor Browser Bundle") print("has SUCCEEDED.\n") print("It is here: %s\n" % os.path.realpath(dist_fname)) extraction_instructions(dist_fname) print("and then:") else: try: extract_7zip(dist_fname) print("Tor Browser Bundle downloaded and extracted.") except ImportError: msg = 'You need "backports.lzma" installed to do 7zip extraction.' print(util.colors.red('Error: ') + msg, isError=True) extraction_instructions(dist_fname) # running instructions lang = dist_fname[-12:-7] tbb_path = './tor-browser_%s/Browser/start-tor-browser' % lang if no_launch: print("To run: %s" % tbb_path) else: print("running: %s" % tbb_path) os.execl(tbb_path, tbb_path) else: print( util.colors.bold( 'Deleting tarball; signature verification failed.')) # XXX probably want an option to NOT do this ("for expert use" ...?) os.unlink(dist_fname) print('...however signature file is being kept for reference (%s).' % sig_fname)
def print_help_for(sub): desc = util.wrap(sub.help_text, 60, ' ') print(desc) for line in sub.options_class().getUsage().split('\n'): print(' ', line)
def run(self, options, mainoptions, connection): # NOTE the middle cert changed on April 10 or thereabouts; # still need to confirm this is legitimate? chain = [ssl.Certificate.loadPEM(pkg_resources.resource_string('carml', 'keys/torproject.pem')), ssl.Certificate.loadPEM(pkg_resources.resource_string('carml', 'keys/digicert-sha2.pem')), ssl.Certificate.loadPEM(pkg_resources.resource_string('carml', 'keys/digicert-root-ca.pem')), ] cf = VerifyCertChainContextFactory(chain) error_wrapper = None if options['use-clearnet']: print(util.colors.red('WARNING') + ': downloading over plain Internet (not via Tor).') agent = Agent(reactor, contextFactory=cf) else: try: import txsocksx.http conn = "tcp:127.0.0.1:9050" tor_ep = endpoints.clientFromString(reactor, conn) agent = txsocksx.http.SOCKS5Agent(reactor, proxyEndpoint=tor_ep, contextFactory=cf) def nicer_error(fail): if fail.trap(error.ConnectError): m = fail.getErrorMessage() raise RuntimeError("Couldn't contact Tor on SOCKS5 (via \"%s\"): %s" % (conn, m)) return fail error_wrapper = nicer_error except ImportError: raise RuntimeError('You need "txsocksx" installed to download via Tor.') uri = 'https://www.torproject.org/projects/torbrowser/RecommendedTBBVersions' data = StringIO() print('Getting recommended versions from "%s".' % uri) d = download(agent, uri, data) def ssl_errors(fail): if hasattr(fail.value, 'reasons'): msg = '' for r in fail.value.reasons: msg += str(r.value.args[-1]) raise RuntimeError(msg) return fail d.addErrback(ssl_errors) if error_wrapper is not None: d.addErrback(error_wrapper) yield d # valid platforms from check.torproject.org can be one of: # 'Linux', 'MacOS' or 'Windows' plat = platform.system().lower() arch = platform.uname()[-2] plat_to_tor = dict(linux='Linux', darwin='MacOS', windows='Win') if plat not in plat_to_tor: print('Unknown platform "%s".' % plat) raise RuntimeError('Unknown platform "%s".' % plat) tor_plat = plat_to_tor[plat] try: versions = json.loads(data.getvalue()) except: print('Error getting versions; invalid JSON:') print(data.getvalue()) raise RuntimeError('Invalid JSON:\n%s' % data.getvalue()) alpha_re = re.compile(r'[0-9]*.[0-9]*a[0-9]-(Windows|MacOS|Linux)') beta_re = re.compile(r'[0-9]*.[0-9]*b[0-9]-(Windows|MacOS|Linux)') print(util.wrap(', '.join(versions), 60, ' ')) alphas = filter(lambda x: alpha_re.match(x), versions) betas = filter(lambda x: beta_re.match(x), versions) others = set(versions).difference(alphas, betas) if options['alpha']: versions = alphas elif options['beta']: versions = betas else: versions = others if alphas: print(util.colors.yellow("Note: there are alpha versions available; use --alpha to download.")) if betas: print(util.colors.yellow("Note: there are beta versions available; use --beta to download.")) target_version = None for v in versions: if v.endswith(tor_plat): target_version = v[:v.rfind('-')] if target_version is None: print("Can't find a version to download") print(" My platform is: %s (%s)" % (plat, plat_to_tor[plat])) print(" Potential versions are: %s" % ', '.join(versions)) if options['beta']: print("(Try without --beta)") elif options['alpha']: print("(Try without --alpha)") raise RuntimeError("Nothing to download found.") # download the signature, then browser-bundle (if they don't # already exist locally). sig_fname, dist_fname = get_download_urls(plat, arch, target_version) for to_download in [sig_fname, dist_fname]: uri = bytes('https://www.torproject.org/dist/torbrowser/%s/%s' % (target_version, to_download)) if os.path.exists(to_download): print(util.colors.red(to_download) + ': already exists, so not downloading.') else: def cleanup(failure, fname): print('removing "%s"...' % fname) os.unlink(fname) return failure f = open(to_download, 'w') print('Downloading "%s".' % to_download) d = download(agent, uri, f) d.addErrback(cleanup, to_download) yield d f.close() # ensure the signature matches if verify_signature(sig_fname, system_gpg=bool(options['system-keychain'])): print(util.colors.green("Signature is good.")) if options['no-extract']: print("Download and signature check of the Tor Browser Bundle") print("has SUCCEEDED.\n") print("It is here: %s\n" % os.path.realpath(dist_fname)) extraction_instructions(dist_fname) print("and then:") else: try: extract_7zip(dist_fname) print("Tor Browser Bundle downloaded and extracted.") except ImportError: msg = 'You need "backports.lzma" installed to do 7zip extraction.' print(util.colors.red('Error: ') + msg, isError=True) extraction_instructions(dist_fname) print("To run:") # running instructions lang = dist_fname[-12:-7] print(" ./tor-browser_%s/Browser/start-tor-browser" % lang) else: print(util.colors.bold('Deleting tarball; signature verification failed.')) os.unlink(dist_fname) print('...however signature file is being kept for reference (%s).' % sig_fname)
def circuit_built(self, circuit): print(string_for_circuit(self.state, circuit)) if self.show_flags: flagslist = ['%s=%s' % x for x in circuit.flags.items()] flags = wrap(' '.join(flagslist), 72, ' ') print(colors.cyan(' Flags:'), flags.lstrip())
def print_help_for(sub): desc = util.wrap(sub.help_text, 60, " ") print(desc) for line in sub.options_class().getUsage().split("\n"): print(" ", line)
async def run(reactor, cfg, tor, beta, alpha, use_clearnet, system_keychain, no_extract, no_launch): # NOTE the middle cert changed on April 10 or thereabouts; # still need to confirm this is legitimate? chain = [ssl.Certificate.loadPEM(pkg_resources.resource_string('carml', 'keys/torproject.pem')), ssl.Certificate.loadPEM(pkg_resources.resource_string('carml', 'keys/digicert-sha2.pem')), ssl.Certificate.loadPEM(pkg_resources.resource_string('carml', 'keys/digicert-root-ca.pem')), ] cf = VerifyCertChainContextFactory(chain) if use_clearnet: print(util.colors.red('WARNING') + ': downloading over plain Internet (not via Tor).') agent = Agent(reactor, contextFactory=cf) else: agent = tor.web_agent() # see onion.torproject.org to verify this is "www.torproject.org" equiv uri = b'http://expyuzz4wqqyqhjn.onion/projects/torbrowser/RecommendedTBBVersions' data = BytesIO() print(u'Getting recommended versions from "{}".'.format(uri.decode('ascii'))) try: await download(agent, uri, data) except Exception as e: if hasattr(value, 'reasons'): msg = ''.join([str(r.value.args[-1]) for r in fail.value.reasons]) raise RuntimeError(msg) raise # valid platforms from check.torproject.org can be one of: # 'Linux', 'MacOS' or 'Windows' plat = platform.system().lower() arch = platform.uname()[-2] plat_to_tor = dict(linux='Linux', darwin='MacOS', windows='Win') if plat not in plat_to_tor: print('Unknown platform "%s".' % plat) raise RuntimeError('Unknown platform "%s".' % plat) tor_plat = plat_to_tor[plat] data_bytes = data.getvalue() try: versions = json.loads(data_bytes.decode('utf8')) except: print('Error getting versions; invalid JSON:') print(data_bytes) raise RuntimeError('Invalid JSON:\n{}'.format(data_bytes)) alpha_re = re.compile(r'[0-9]*.[0-9]*a[0-9]-(Windows|MacOS|Linux)') beta_re = re.compile(r'[0-9]*.[0-9]*b[0-9]-(Windows|MacOS|Linux)') hardened_re = re.compile(r'(.*)-hardened-(.*)') print(util.wrap(', '.join(versions), 60, ' ')) alphas = [x for x in versions if alpha_re.match(x)] betas = [x for x in versions if beta_re.match(x)] hardened = [x for x in versions if hardened_re.match(x)] others = set(versions).difference(alphas, betas, hardened) if alpha: versions = alphas elif beta: versions = betas else: versions = others if alphas and not alpha: print(util.colors.yellow("Note: there are alpha versions available; use --alpha to download.")) if betas and not beta: print(util.colors.yellow("Note: there are beta versions available; use --beta to download.")) if hardened: print(util.colors.yellow("Note: there are hardened versions available but we don't support downloading them yet.")) target_version = None for v in versions: if v.endswith(tor_plat): target_version = v[:v.rfind('-')] if target_version is None: print("Can't find a version to download") print(" My platform is: %s (%s)" % (plat, plat_to_tor[plat])) print(" Potential versions are: %s" % ', '.join(versions)) if beta: print("(Try without --beta)") elif alpha: print("(Try without --alpha)") raise RuntimeError("Nothing to download found.") # download the signature, then browser-bundle (if they don't # already exist locally). sig_fname, dist_fname = get_download_urls(plat, arch, target_version) for to_download in [sig_fname, dist_fname]: # this will 302 to the right spot, but goes to clearweb (dist.torproject.org) instead of onion service... # uri = u'http://expyuzz4wqqyqhjn.onion/dist/torbrowser/{}/{}'.format(target_version, to_download).encode('ascii') # see onion.torproject.org to verify this is "dist.torproject.org" equiv uri = u'http://rqef5a5mebgq46y5.onion/torbrowser/{}/{}'.format(target_version, to_download).encode('ascii') if os.path.exists(to_download): print(util.colors.red(to_download) + ': already exists, so not downloading.') else: try: with open(to_download, 'wb') as f: print('Downloading "%s" from:\n %s' % (to_download, uri.decode('ascii'))) await download(agent, uri, f) except Exception as e: print('removing "%s"...' % to_download) os.unlink(to_download) raise # ensure the signature matches if verify_signature(sig_fname, system_gpg=system_keychain): print(util.colors.green("Signature is good.")) if no_extract: print("Download and signature check of the Tor Browser Bundle") print("has SUCCEEDED.\n") print("It is here: %s\n" % os.path.realpath(dist_fname)) extraction_instructions(dist_fname) print("and then:") else: try: extract_7zip(dist_fname) print("Tor Browser Bundle downloaded and extracted.") except ImportError: msg = 'You need "backports.lzma" installed to do 7zip extraction.' print(util.colors.red('Error: ') + msg, isError=True) extraction_instructions(dist_fname) # running instructions lang = dist_fname[-12:-7] tbb_path = './tor-browser_%s/Browser/start-tor-browser' % lang if no_launch: print("To run: %s" % tbb_path) else: print("running: %s" % tbb_path) os.execl(tbb_path, tbb_path) else: print(util.colors.bold('Deleting tarball; signature verification failed.')) # XXX probably want an option to NOT do this ("for expert use" ...?) os.unlink(dist_fname) print('...however signature file is being kept for reference (%s).' % sig_fname)