[tor-commits] [gettor/master] Moved files

ilv at torproject.org ilv at torproject.org
Tue Sep 22 23:39:13 UTC 2015


commit 01ad4b154f6d361b94a4286a697d7879ce460234
Author: ilv <ilv at users.noreply.github.com>
Date:   Thu Feb 5 17:17:29 2015 -0300

    Moved files
---
 bundles2drive.py      |  340 -------------------------------------------------
 bundles2dropbox.py    |  249 ------------------------------------
 drive.cfg             |    9 --
 drive.links           |   25 ----
 dropbox.cfg           |    8 --
 providers/drive.links |   25 ++++
 6 files changed, 25 insertions(+), 631 deletions(-)

diff --git a/bundles2drive.py b/bundles2drive.py
deleted file mode 100644
index 8c329bf..0000000
--- a/bundles2drive.py
+++ /dev/null
@@ -1,340 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# This file is part of GetTor, a Tor Browser distribution system.
-#
-# :authors: poly <poly at darkdepths.net>
-#           Israel Leiva <ilv at riseup.net>
-#           see also AUTHORS file
-#
-# :copyright:   (c) 2008-2014, The Tor Project, Inc.
-#               (c) 2014, Poly
-#               (c) 2014, Israel Leiva
-#
-# :license: This is Free Software. See LICENSE for license information.
-
-import re
-import os
-import gnupg
-import hashlib
-import ConfigParser
-import gettor.core
-
-#import google drive libs
-import httplib2
-from apiclient.discovery import build
-from apiclient.http import MediaFileUpload
-from apiclient import errors
-from oauth2client.client import FlowExchangeError
-from oauth2client.client import OAuth2WebServerFlow
-from oauth2client.client import Credentials
-
-
-def valid_format(file, osys):
-    """Check for valid bundle format
-
-    Check if the given file has a valid bundle format
-    (e.g. tor-browser-linux32-3.6.2_es-ES.tar.xz)
-
-    :param: file (string) the name of the file.
-    :param: osys (string) the OS.
-
-    :return: (boolean) true if the bundle format is valid, false otherwise.
-
-    """
-    if(osys == 'windows'):
-        m = re.search(
-            'torbrowser-install-\d\.\d\.\d_\w\w(-\w\w)?\.exe',
-            file)
-    elif(osys == 'linux'):
-        m = re.search(
-            'tor-browser-linux\d\d-\d\.\d\.\d_(\w\w)(-\w\w)?\.tar\.xz',
-            file)
-    elif(osys == 'osx'):
-        m = re.search(
-            'TorBrowser-\d\.\d\.\d-osx\d\d_(\w\w)(-\w\w)?\.dmg',     
-            file)
-    if m:
-        return True
-    else:
-        return False
-
-
-def get_bundle_info(file, osys):
-    """Get the os, arch and lc from a bundle string.
-
-    :param: file (string) the name of the file.
-    :param: osys (string) the OS.
-
-    :raise: ValueError if the bundle doesn't have a valid bundle format.
-
-    :return: (list) the os, arch and lc.
-
-    """
-    if(osys == 'windows'):
-        m = re.search(
-            'torbrowser-install-\d\.\d\.\d_(\w\w)(-\w\w)?\.exe',
-            file)
-        if m:
-            lc = m.group(1)
-            return 'windows', '32/64', lc
-        else:
-            raise ValueError("Invalid bundle format %s" % file)
-    elif(osys == 'linux'):
-        m = re.search(
-            'tor-browser-linux(\d\d)-\d\.\d\.\d_(\w\w)(-\w\w)?\.tar\.xz',
-            file)
-        if m:
-            arch = m.group(1)
-            lc = m.group(2)
-            return 'linux', arch, lc
-        else:
-            raise ValueError("Invalid bundle format %s" % file)
-    elif(osys == 'osx'):
-        m = re.search(
-            'TorBrowser-\d\.\d\.\d-osx(\d\d)_(\w\w)(-\w\w)?\.dmg',
-            file)
-        if m:
-            os = 'osx'
-            arch = m.group(1)
-            lc = m.group(2)
-            return 'osx', arch, lc
-        else:
-            raise ValueError("Invalid bundle format %s" % file)
-
-
-def get_file_sha256(file):
-    """Get the sha256 of a file.
-
-    :param: file (string) the path of the file.
-
-    :return: (string) the sha256 hash.
-
-    """
-    # as seen on the internetz
-    BLOCKSIZE = 65536
-    hasher = hashlib.sha256()
-    with open(file, 'rb') as afile:
-        buf = afile.read(BLOCKSIZE)
-        while len(buf) > 0:
-            hasher.update(buf)
-            buf = afile.read(BLOCKSIZE)
-    return hasher.hexdigest()
-
-
-def upload_files(client, basedir):
-    """Upload files to Google Drive.
-
-    Looks for tor browser files inside basedir.
-
-    :param: basedir (string) path of the folder with the files to be
-            uploaded.
-    :param: client (object) Google Drive object.
-
-    :raise: UploadError if something goes wrong while uploading the
-            files to Google Drive. All files are uploaded to '/'.
-
-    :return: (dict) the names of the uploaded files as the keys,
-             and file id as the value
-
-    """
-    files = []
-
-    p = re.compile('.*\.tar.xz$')
-    for name in os.listdir(basedir):
-        path = os.path.abspath(os.path.join(basedir, name))
-        if os.path.isfile(path) and p.match(path)\
-        and valid_format(name, 'linux'):
-            files.append(name)
-
-    p = re.compile('.*\.exe$')
-    for name in os.listdir(basedir):
-        path = os.path.abspath(os.path.join(basedir, name))
-        if os.path.isfile(path) and p.match(path)\
-        and valid_format(name, 'windows'):
-            files.append(name)
-
-    p = re.compile('.*\.dmg$')
-    for name in os.listdir(basedir):
-        path = os.path.abspath(os.path.join(basedir, name))
-        if os.path.isfile(path) and p.match(path)\
-        and valid_format(name, 'osx'):
-            files.append(name)
-
-    # dictionary to store file names and IDs
-    files_dict = dict()
-
-    for file in files:
-        asc = "%s.asc" % file
-        abs_file = os.path.abspath(os.path.join(basedir, file))
-        abs_asc = os.path.abspath(os.path.join(basedir, asc))
-
-        if not os.path.isfile(abs_asc):
-            # there are some .mar files that don't have .asc, don't upload it
-            continue
-
-        # upload tor browser installer
-        file_body = MediaFileUpload(abs_file, resumable=True)
-        body = {
-          'title': file
-        }
-        print "Uploading '%s'..." % file
-        try:
-            file_data = drive_service.files().insert(body=body, media_body=file_body).execute()
-        except errors.HttpError, e:
-            print str(e)
-
-        # upload signature
-        asc_body = MediaFileUpload(abs_asc, resumable=True)
-        asc_head = {
-           'title': "%s.asc" % file
-        }
-        print "Uploading '%s'..." % asc
-        try:
-            asc_data = drive_service.files().insert(body=asc_head, media_body=asc_body).execute()
-        except errors.HttpError, e:
-            print str(e)
-
-        # add filenames and file id to dict
-        files_dict[file] = file_data['id']
-        files_dict[asc]  = asc_data['id']
-
-    return files_dict
-
-def share_file(service, file_id):
-    """Make files public
-
-    For a given file-id, sets role 'reader' to 'anyone'. Returns public
-    link to file.
-
-    :param: file_id (string)
-    
-    :return: (string) url to shared file
-   
-    """
-    permission = {
-         'type': "anyone",
-         'role': "reader",
-         'withLink': True
-    }
-    
-    try:
-        service.permissions().insert(
-               fileId=file_id, body=permission).execute()
-    except errors.HttpError, error:
-           print('An error occured while sharing: %s' % file_id)
-
-    try:
-        file = service.files().get(fileId=file_id).execute()
-    except errors.HttpError, error:
-           print('Error occured while fetch public link for file: %s' % file_id)
-
-    print("Uploaded to %s" % file['webContentLink'])
-    return file['webContentLink']
-
-
-if __name__ == '__main__':
-    config = ConfigParser.ConfigParser()
-    config.read('drive.cfg')
-
-    client_id = config.get('app', 'client-id')
-    app_secret = config.get('app', 'secret')
-    refresh_token = config.get('app', 'refresh_token')
-    upload_dir = config.get('general', 'upload_dir')
-
-    # important: this key must be the one that signed the packages
-    tbb_key = config.get('general', 'tbb_key')
-
-    # requests full access to drive account
-    OAUTH_SCOPE = 'https://www.googleapis.com/auth/drive'
-    REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
-
-    print "Authenticating..."
-
-    flow = OAuth2WebServerFlow(client_id, app_secret, OAUTH_SCOPE,
-                           redirect_uri=REDIRECT_URI)
-
-    # If no valid token found, need to prompt user.
-    # this should only occur once
-    if not refresh_token:
-       flow.params['access_type'] = 'offline'
-       flow.params['approval_prompt'] = 'force'
-       authorize_url = flow.step1_get_authorize_url()
-       print 'Go to the following link in your browser: ' + authorize_url
-       code = raw_input('Enter verification code: ').strip()
-       try:
-           credentials = flow.step2_exchange(code)
-       except FlowExchangeError as e:
-           print str(e)
-
-       # oauth2 credentials instance must be stored as json string
-       config.set('app', 'refresh_token', credentials.to_json())
-       with open('drive.cfg', 'wb') as configfile:
-            config.write(configfile)
-    else:
-       # we already have a valid token
-       credentials = Credentials.new_from_json(refresh_token)
-
-    # authenticate with oauth2
-    http = httplib2.Http()
-    http = credentials.authorize(http)
-
-    # initialize drive instance
-    drive_service = build('drive', 'v2', http=http)
-
-
-    # import key fingerprint
-    gpg = gnupg.GPG()
-    key_data = open(tbb_key).read()
-    import_result = gpg.import_keys(key_data)
-    fp = import_result.results[0]['fingerprint']
-
-    # make groups of four characters to make fingerprint more readable
-    # e.g. 123A 456B 789C 012D 345E 678F 901G 234H 567I 890J
-    readable = ' '.join(fp[i:i+4] for i in xrange(0, len(fp), 4))
-
-    try:
-        uploaded_files = upload_files(drive_service, upload_dir)
-        # use default config
-        core = gettor.core.Core('/home/gettor/core.cfg')
-
-        # erase old links
-        core.create_links_file('Drive', readable)
-
-        # recognize file OS by its extension
-        p1 = re.compile('.*\.tar.xz$')
-        p2 = re.compile('.*\.exe$')
-        p3 = re.compile('.*\.dmg$')
-        p4 = re.compile('.*\.asc$')
-
-        for file in uploaded_files.keys():
-            # only run for tor browser installers
-            if p4.match(file):
-               continue
-            asc = "%s.asc" % file
-            abs_file = os.path.abspath(os.path.join(upload_dir, file))
-            abs_asc = os.path.abspath(os.path.join(upload_dir, asc))
-
-            sha_file = get_file_sha256(abs_file)
-
-            # build links
-            link_file = share_file(drive_service,
-                                   uploaded_files[file])
-            link_asc  = share_file(drive_service,
-                                   uploaded_files["%s.asc" % file])
-
-            if p1.match(file):
-                osys, arch, lc = get_bundle_info(file, 'linux')
-            elif p2.match(file):
-                osys, arch, lc = get_bundle_info(file, 'windows')
-            elif p3.match(file):
-                osys, arch, lc = get_bundle_info(file, 'osx')
-
-            link = "Package (%s-bit): %s\nASC signature (%s-bit): %s\n"\
-                   "Package SHA256 checksum (%s-bit): %s\n" %\
-                   (arch, link_file, arch, link_asc,
-                    arch, sha_file)
-
-            # note that you should only upload bundles for supported locales
-            core.add_link('Drive', osys, lc, link)
-    except (ValueError, RuntimeError) as e:
-        print str(e)
diff --git a/bundles2dropbox.py b/bundles2dropbox.py
deleted file mode 100644
index a1328d8..0000000
--- a/bundles2dropbox.py
+++ /dev/null
@@ -1,249 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# This file is part of GetTor, a Tor Browser distribution system.
-#
-# :authors: Israel Leiva <ilv at riseup.net>
-#           see also AUTHORS file
-#
-# :copyright:   (c) 2008-2014, The Tor Project, Inc.
-#               (c) 2014, Israel Leiva
-#
-# :license: This is Free Software. See LICENSE for license information.
-
-import re
-import os
-import gnupg
-import hashlib
-import ConfigParser
-
-import dropbox
-import gettor.core
-
-def valid_format(file, osys):
-    """Check for valid bundle format
-
-    Check if the given file has a valid bundle format
-    (e.g. tor-browser-linux32-3.6.2_es-ES.tar.xz)
-
-    :param: file (string) the name of the file.
-    :param: osys (string) the OS.
-
-    :return: (boolean) true if the bundle format is valid, false otherwise.
-
-    """
-    if(osys == 'windows'):
-        m = re.search(
-            'torbrowser-install-\d\.\d\.\d_\w\w(-\w\w)?\.exe',
-            file)
-    elif(osys == 'linux'):
-        m = re.search(
-            'tor-browser-linux\d\d-\d\.\d\.\d_(\w\w)(-\w\w)?\.tar\.xz',
-            file)
-    elif(osys == 'osx'):
-        m = re.search(
-            'TorBrowser-\d\.\d\.\d-osx\d\d_(\w\w)(-\w\w)?\.dmg',     
-            file)
-    if m:
-        return True
-    else:
-        return False
-
-
-def get_bundle_info(file, osys):
-    """Get the os, arch and lc from a bundle string.
-
-    :param: file (string) the name of the file.
-    :param: osys (string) the OS.
-
-    :raise: ValueError if the bundle doesn't have a valid bundle format.
-
-    :return: (list) the os, arch and lc.
-
-    """
-    if(osys == 'windows'):
-        m = re.search(
-            'torbrowser-install-\d\.\d\.\d_(\w\w)(-\w\w)?\.exe',
-            file)
-        if m:
-            lc = m.group(1)
-            return 'windows', '32/64', lc
-        else:
-            raise ValueError("Invalid bundle format %s" % file)
-    elif(osys == 'linux'):
-        m = re.search(
-            'tor-browser-linux(\d\d)-\d\.\d\.\d_(\w\w)(-\w\w)?\.tar\.xz',
-            file)
-        if m:
-            arch = m.group(1)
-            lc = m.group(2)
-            return 'linux', arch, lc
-        else:
-            raise ValueError("Invalid bundle format %s" % file)
-    elif(osys == 'osx'):
-        m = re.search(
-            'TorBrowser-\d\.\d\.\d-osx(\d\d)_(\w\w)(-\w\w)?\.dmg',
-            file)
-        if m:
-            os = 'osx'
-            arch = m.group(1)
-            lc = m.group(2)
-            return 'osx', arch, lc
-        else:
-            raise ValueError("Invalid bundle format %s" % file)
-
-
-def get_file_sha256(file):
-    """Get the sha256 of a file.
-
-    :param: file (string) the path of the file.
-
-    :return: (string) the sha256 hash.
-
-    """
-    # as seen on the internetz
-    BLOCKSIZE = 65536
-    hasher = hashlib.sha256()
-    with open(file, 'rb') as afile:
-        buf = afile.read(BLOCKSIZE)
-        while len(buf) > 0:
-            hasher.update(buf)
-            buf = afile.read(BLOCKSIZE)
-    return hasher.hexdigest()
-
-
-def upload_files(basedir, client):
-    """Upload files to Dropbox.
-
-    Looks for files ending with 'tar.xz' inside basedir.
-
-    :param: basedir (string) path of the folder with the files to be
-            uploaded.
-    :param: client (object) DropboxClient object.
-
-    :raise: ValueError if the .xz file doesn't have an .asc file.
-    :raise: UploadError if something goes wrong while uploading the
-            files to Dropbox. All files are uploaded to '/'.
-
-    :return: (list) the names of the uploaded files.
-
-    """
-    files = []
-
-    p = re.compile('.*\.tar.xz$')
-    for name in os.listdir(basedir):
-        path = os.path.abspath(os.path.join(basedir, name))
-        if os.path.isfile(path) and p.match(path)\
-        and valid_format(name, 'linux'):
-            files.append(name)
-
-    p = re.compile('.*\.exe$')
-    for name in os.listdir(basedir):
-        path = os.path.abspath(os.path.join(basedir, name))
-        if os.path.isfile(path) and p.match(path)\
-        and valid_format(name, 'windows'):
-            files.append(name)
-
-    p = re.compile('.*\.dmg$')
-    for name in os.listdir(basedir):
-        path = os.path.abspath(os.path.join(basedir, name))
-        if os.path.isfile(path) and p.match(path)\
-        and valid_format(name, 'osx'):
-            files.append(name)
-
-    for file in files:
-        asc = "%s.asc" % file
-        abs_file = os.path.abspath(os.path.join(basedir, file))
-        abs_asc = os.path.abspath(os.path.join(basedir, asc))
-
-        if not os.path.isfile(abs_asc):
-            # there are some .mar files that don't have .asc, don't upload it
-            continue
-
-        # chunk upload for big files
-        to_upload = open(abs_file, 'rb')
-        size = os.path.getsize(abs_file)
-        uploader = client.get_chunked_uploader(to_upload, size)
-        while uploader.offset < size:
-            try:
-                upload = uploader.upload_chunked()
-            except dropbox.rest.ErrorResponse, e:
-                print("An error ocurred while uploading %s: %s" % abs_file, e)
-        uploader.finish(file)
-        print "Uploading %s" % file
-
-        # this should be small, upload it simple
-        to_upload_asc = open(abs_asc, 'rb')
-        response = client.put_file(asc, to_upload_asc)
-        print "Uploading %s" % asc
-
-    return files
-
-if __name__ == '__main__':
-    config = ConfigParser.ConfigParser()
-    config.read('dropbox.cfg')
-
-    app_key = config.get('app', 'key')
-    app_secret = config.get('app', 'secret')
-    access_token = config.get('app', 'access_token')
-    upload_dir = config.get('general', 'upload_dir')
-
-    # important: this key must be the one that signed the packages
-    tbb_key = config.get('general', 'tbb_key')
-
-    client = dropbox.client.DropboxClient(access_token)
-
-    # import key fingerprint
-    gpg = gnupg.GPG()
-    key_data = open(tbb_key).read()
-    import_result = gpg.import_keys(key_data)
-    fp = import_result.results[0]['fingerprint']
-
-    # make groups of four characters to make fingerprint more readable
-    # e.g. 123A 456B 789C 012D 345E 678F 901G 234H 567I 890J
-    readable = ' '.join(fp[i:i+4] for i in xrange(0, len(fp), 4))
-
-    try:
-        uploaded_files = upload_files(upload_dir, client)
-        # use default config
-        core = gettor.core.Core('/home/gettor/core.cfg')
-
-        # erase old links
-        core.create_links_file('Dropbox', readable)
-
-        # recognize file OS by its extension
-        p1 = re.compile('.*\.tar.xz$')
-        p2 = re.compile('.*\.exe$')
-        p3 = re.compile('.*\.dmg$')
-
-        for file in uploaded_files:
-            # build file names
-            asc = "%s.asc" % file
-            abs_file = os.path.abspath(os.path.join(upload_dir, file))
-            abs_asc = os.path.abspath(os.path.join(upload_dir, asc))
-
-            sha_file = get_file_sha256(abs_file)
-
-            # build links
-            link_file = client.share(file, short_url=False)
-            # if someone finds how to do this with the API, please tell me!
-            link_file[u'url'] = link_file[u'url'].replace('?dl=0', '?dl=1')
-            link_asc = client.share(asc, short_url=False)
-            link_asc[u'url'] = link_asc[u'url'].replace('?dl=0', '?dl=1')
-            if p1.match(file):
-                osys, arch, lc = get_bundle_info(file, 'linux')
-            elif p2.match(file):
-                osys, arch, lc = get_bundle_info(file, 'windows')
-            elif p3.match(file):
-                osys, arch, lc = get_bundle_info(file, 'osx')
-
-            link = "Package (%s-bit): %s\nASC signature (%s-bit): %s\n"\
-                   "Package SHA256 checksum (%s-bit): %s\n" %\
-                   (arch, link_file[u'url'], arch, link_asc[u'url'],
-                    arch, sha_file)
-
-            # note that you should only upload bundles for supported locales
-            core.add_link('Dropbox', osys, lc, link)
-    except (ValueError, RuntimeError) as e:
-        print str(e)
-    except dropbox.rest.ErrorResponse as e:
-        print str(e)
diff --git a/drive.cfg b/drive.cfg
deleted file mode 100644
index b400af0..0000000
--- a/drive.cfg
+++ /dev/null
@@ -1,9 +0,0 @@
-[general]
-upload_dir = upload
-tbb_key = tbb-key.asc
-
-[app]
-client-id = 
-secret = 
-refresh_token = 
-
diff --git a/drive.links b/drive.links
deleted file mode 100644
index 5f4fa89..0000000
--- a/drive.links
+++ /dev/null
@@ -1,25 +0,0 @@
-[provider]
-name = Drive
-
-[key]
-fingerprint = A3C4 F0F9 79CA A22C DBA8 F512 EE8C BC9E 886D DD89
-
-[linux]
-en = Package (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjNTJPanBRekI5Slk&export=download
-	ASC signature (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjTXVONkhvZ1VRY2c&export=download
-	Package SHA256 checksum (32-bit): 03a4ecab9ffb4b579c9d03a0f800d9bcd4446b49eff21eb3e1db255fa9d9b930,
-	Package (64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjbXp2MUh5RmxTa28&export=download
-	ASC signature (64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjNTVZVnJUTnNCOEk&export=download
-	Package SHA256 checksum (64-bit): 03a4ecab9ffb4b579c9d03a0f800d9bcd4446b49eff21eb3e1db255fa9d9b930
-	
-
-[windows]
-en = Package (32/64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjakM4a21iRlQzQVE&export=download
-	ASC signature (32/64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjZy1FLVpTLW9INFU&export=download
-	Package SHA256 checksum (32/64-bit): 21e54d964366e8a67f379ed402007f59cb3aebfddbc3a30dacc3ac64171145a6
-
-[osx]
-en = Package (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjenRobzJtcWw0UnM&export=download
-	ASC signature (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjZ0R4Z0I1ZlBRUHc&export=download
-	Package SHA256 checksum (32-bit): dd86727270ba236d85673194782b4cc9860bd886e4abdf2dfc6d716dabddb68f
-
diff --git a/dropbox.cfg b/dropbox.cfg
deleted file mode 100644
index a29989c..0000000
--- a/dropbox.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-[general]
-upload_dir: upload
-tbb_key: tbb-key.asc
-
-[app]
-key: suchkey
-secret: suchsecret
-access_token: suchtoken
\ No newline at end of file
diff --git a/providers/drive.links b/providers/drive.links
new file mode 100644
index 0000000..5f4fa89
--- /dev/null
+++ b/providers/drive.links
@@ -0,0 +1,25 @@
+[provider]
+name = Drive
+
+[key]
+fingerprint = A3C4 F0F9 79CA A22C DBA8 F512 EE8C BC9E 886D DD89
+
+[linux]
+en = Package (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjNTJPanBRekI5Slk&export=download
+	ASC signature (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjTXVONkhvZ1VRY2c&export=download
+	Package SHA256 checksum (32-bit): 03a4ecab9ffb4b579c9d03a0f800d9bcd4446b49eff21eb3e1db255fa9d9b930,
+	Package (64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjbXp2MUh5RmxTa28&export=download
+	ASC signature (64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjNTVZVnJUTnNCOEk&export=download
+	Package SHA256 checksum (64-bit): 03a4ecab9ffb4b579c9d03a0f800d9bcd4446b49eff21eb3e1db255fa9d9b930
+	
+
+[windows]
+en = Package (32/64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjakM4a21iRlQzQVE&export=download
+	ASC signature (32/64-bit): https://docs.google.com/uc?id=0B7humfJYX-LjZy1FLVpTLW9INFU&export=download
+	Package SHA256 checksum (32/64-bit): 21e54d964366e8a67f379ed402007f59cb3aebfddbc3a30dacc3ac64171145a6
+
+[osx]
+en = Package (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjenRobzJtcWw0UnM&export=download
+	ASC signature (32-bit): https://docs.google.com/uc?id=0B7humfJYX-LjZ0R4Z0I1ZlBRUHc&export=download
+	Package SHA256 checksum (32-bit): dd86727270ba236d85673194782b4cc9860bd886e4abdf2dfc6d716dabddb68f
+





More information about the tor-commits mailing list