Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
 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())
Exemplo n.º 5
0
 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())
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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)