import pickle
import json
import re
+import gettext
+import gpg
-try:
- import gpg
- gpgme_support = True
-except ImportError:
- gpgme_support = False
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-SHARE = os.getenv('TBL_SHARE', sys.prefix+'/share/torbrowser-launcher')
+SHARE = os.getenv('TBL_SHARE', sys.prefix + '/share') + '/torbrowser-launcher'
-import gettext
gettext.install('torbrowser-launcher')
-from twisted.internet import gtk2reactor
-gtk2reactor.install()
-
# We're looking for output which:
#
# 1. The first portion must be `[GNUPG:] IMPORT_OK`
# 2. The second must be an integer between [0, 15], inclusive
# 3. The third must be an uppercased hex-encoded 160-bit fingerprint
gnupg_import_ok_pattern = re.compile(
- "(\[GNUPG\:\]) (IMPORT_OK) ([0-9]|[1]?[0-5]) ([A-F0-9]{40})")
-
+ b"(\[GNUPG\:\]) (IMPORT_OK) ([0-9]|[1]?[0-5]) ([A-F0-9]{40})")
-class Common:
+class Common(object):
def __init__(self, tbl_version):
self.tbl_version = tbl_version
# initialize the app
- self.default_mirror = 'https://www.torproject.org/dist/'
+ self.default_mirror = 'https://dist.torproject.org/'
self.discover_arch_lang()
self.build_paths()
for d in self.paths['dirs']:
self.mkdir(self.paths['tbb']['dir'])
self.init_gnupg()
- # allow buttons to have icons
- try:
- gtk_settings = gtk.settings_get_default()
- gtk_settings.props.gtk_button_images = True
- except:
- pass
-
# discover the architecture and language
def discover_arch_lang(self):
# figure out the architecture
self.architecture = 'x86_64' if '64' in platform.architecture()[0] else 'i686'
# figure out the language
- available_languages = ['en-US', 'ar', 'de', 'es-ES', 'fa', 'fr', 'it', 'ko', 'nl', 'pl', 'pt-PT', 'ru', 'vi', 'zh-CN']
- default_locale = locale.getlocale(locale.LC_MESSAGES)[0]
+ available_languages = ['ar', 'ca', 'da', 'de', 'en-US', 'es-ES', 'fa', 'fr', 'ga-IE', 'he', 'id', 'is', 'it', 'ja', 'ko', 'nb-NO', 'nl', 'pl', 'pt-BR', 'ru', 'sv-SE', 'tr', 'vi', 'zh-CN', 'zh-TW']
+
+ # a list of manually configured language fallback overriding
+ language_overrides = {
+ 'zh-HK': 'zh-TW',
+ }
+
+ default_locale = locale.getlocale()[0]
if default_locale is None:
self.language = 'en-US'
else:
self.language = default_locale.replace('_', '-')
+ if self.language in language_overrides:
+ self.language = language_overrides[self.language]
if self.language not in available_languages:
self.language = self.language.split('-')[0]
if self.language not in available_languages:
if self.language not in available_languages:
self.language = 'en-US'
+ # get value of environment variable, if it is not set return the default value
+ @staticmethod
+ def get_env(var_name, default_value):
+ value = os.getenv(var_name)
+ if not value:
+ value = default_value
+ return value
+
# build all relevant paths
def build_paths(self, tbb_version=None):
homedir = os.getenv('HOME')
homedir = '/tmp/.torbrowser-'+os.getenv('USER')
if not os.path.exists(homedir):
try:
- os.mkdir(homedir, 0700)
+ os.mkdir(homedir, 0o700)
except:
self.set_gui('error', _("Error creating {0}").format(homedir), [], False)
if not os.access(homedir, os.W_OK):
self.set_gui('error', _("{0} is not writable").format(homedir), [], False)
- tbb_config = '{0}/.config/torbrowser'.format(homedir)
- tbb_cache = '{0}/.cache/torbrowser'.format(homedir)
- tbb_local = '{0}/.local/share/torbrowser'.format(homedir)
+ tbb_config = '{0}/torbrowser'.format(self.get_env('XDG_CONFIG_HOME', '{0}/.config'.format(homedir)))
+ tbb_cache = '{0}/torbrowser'.format(self.get_env('XDG_CACHE_HOME', '{0}/.cache'.format(homedir)))
+ tbb_local = '{0}/torbrowser'.format(self.get_env('XDG_DATA_HOME', '{0}/.local/share'.format(homedir)))
old_tbb_data = '{0}/.torbrowser'.format(homedir)
if tbb_version:
language = 'en-US'
else:
language = self.language
- tarball_filename = 'tor-browser-'+arch+'-'+tbb_version+'_'+language+'.tar.xz'
+ tarball_filename = 'tor-browser-' + arch + '-' + tbb_version + '_' + language + '.tar.xz'
# tarball
- self.paths['tarball_url'] = '{0}torbrowser/'+tbb_version+'/'+tarball_filename
- self.paths['tarball_file'] = tbb_cache+'/download/'+tarball_filename
+ self.paths['tarball_url'] = '{0}torbrowser/' + tbb_version + '/' + tarball_filename
+ self.paths['tarball_file'] = tbb_cache + '/download/' + tarball_filename
self.paths['tarball_filename'] = tarball_filename
# sig
- self.paths['sig_url'] = '{0}torbrowser/'+tbb_version+'/'+tarball_filename+'.asc'
- self.paths['sig_file'] = tbb_cache+'/download/'+tarball_filename+'.asc'
- self.paths['sig_filename'] = tarball_filename+'.asc'
+ self.paths['sig_url'] = '{0}torbrowser/' + tbb_version + '/' + tarball_filename + '.asc'
+ self.paths['sig_file'] = tbb_cache + '/download/' + tarball_filename + '.asc'
+ self.paths['sig_filename'] = tarball_filename + '.asc'
else:
self.paths = {
'dirs': {
'tbl_bin': sys.argv[0],
'icon_file': os.path.join(os.path.dirname(SHARE), 'pixmaps/torbrowser.png'),
'torproject_pem': os.path.join(SHARE, 'torproject.pem'),
- 'keyserver_ca': os.path.join(SHARE, 'sks-keyservers.netCA.pem'),
'signing_keys': {
'tor_browser_developers': os.path.join(SHARE, 'tor-browser-developers.asc')
},
'mirrors_txt': [os.path.join(SHARE, 'mirrors.txt'),
- tbb_config+'/mirrors.txt'],
- 'modem_sound': os.path.join(SHARE, 'modem.ogg'),
- 'download_dir': tbb_cache+'/download',
- 'gnupg_homedir': tbb_local+'/gnupg_homedir',
- 'settings_file': tbb_config+'/settings.json',
- 'settings_file_pickle': tbb_config+'/settings',
+ tbb_config + '/mirrors.txt'],
+ 'download_dir': tbb_cache + '/download',
+ 'gnupg_homedir': tbb_local + '/gnupg_homedir',
+ 'settings_file': tbb_config + '/settings.json',
+ 'settings_file_pickle': tbb_config + '/settings',
'version_check_url': 'https://aus1.torproject.org/torbrowser/update_3/release/Linux_x86_64-gcc3/x/en-US',
- 'version_check_file': tbb_cache+'/download/release.xml',
+ 'version_check_file': tbb_cache + '/download/release.xml',
'tbb': {
- 'changelog': tbb_local+'/tbb/'+self.architecture+'/tor-browser_'+self.language+'/Browser/TorBrowser/Docs/ChangeLog.txt',
- 'dir': tbb_local+'/tbb/'+self.architecture,
- 'dir_tbb': tbb_local+'/tbb/'+self.architecture+'/tor-browser_'+self.language,
- 'start': tbb_local+'/tbb/'+self.architecture+'/tor-browser_'+self.language+'/start-tor-browser.desktop',
+ 'changelog': tbb_local + '/tbb/' + self.architecture + '/tor-browser_' +
+ self.language + '/Browser/TorBrowser/Docs/ChangeLog.txt',
+ 'dir': tbb_local + '/tbb/' + self.architecture,
+ 'dir_tbb': tbb_local + '/tbb/' + self.architecture + '/tor-browser_' + self.language,
+ 'start': tbb_local + '/tbb/' + self.architecture + '/tor-browser_' +
+ self.language + '/start-tor-browser.desktop'
},
}
def mkdir(path):
try:
if not os.path.exists(path):
- os.makedirs(path, 0700)
+ os.makedirs(path, 0o700)
return True
except:
- print _("Cannot create directory {0}").format(path)
+ print(_("Cannot create directory {0}").format(path))
return False
if not os.access(path, os.W_OK):
- print _("{0} is not writable").format(path)
+ print(_("{0} is not writable").format(path))
return False
return True
# if gnupg_homedir isn't set up, set it up
def init_gnupg(self):
if not os.path.exists(self.paths['gnupg_homedir']):
- print _('Creating GnuPG homedir'), self.paths['gnupg_homedir']
+ print(_('Creating GnuPG homedir'), self.paths['gnupg_homedir'])
self.mkdir(self.paths['gnupg_homedir'])
self.import_keys()
else:
print('Refreshing local keyring...')
- p = subprocess.Popen(['/usr/bin/gpg', '--status-fd', '2',
+ p = subprocess.Popen(['/usr/bin/gpg2', '--status-fd', '2',
'--homedir', self.paths['gnupg_homedir'],
- '--keyserver', 'hkps://hkps.pool.sks-keyservers.net',
- '--keyserver-options', 'ca-cert-file=' + self.paths['keyserver_ca']
- + ',include-revoked,no-honor-keyserver-url,no-honor-pka-record',
+ '--keyserver', 'hkps://keys.openpgp.org',
'--refresh-keys'], stderr=subprocess.PIPE)
p.wait()
if match and match.group(2) == 'IMPORT_OK':
fingerprint = str(match.group(4))
if match.group(3) == '0':
- print('Keyring refreshed successfully...\n No key updates for key: ' + fingerprint)
+ print('Keyring refreshed successfully...')
+ print(' No key updates for key: ' + fingerprint)
elif match.group(3) == '4':
- print('Keyring refreshed successfully...\n New signatures for key: ' + fingerprint)
+ print('Keyring refreshed successfully...')
+ print(' New signatures for key: ' + fingerprint)
else:
print('Keyring refreshed successfully...')
:returns: ``True`` if the key is now within the keyring (or was
previously and hasn't changed). ``False`` otherwise.
"""
- if gpgme_support:
- with gpg.Context() as c:
- c.set_engine_info(gpg.constants.protocol.OpenPGP, home_dir=self.paths['gnupg_homedir'])
-
- impkey = self.paths['signing_keys'][key]
- try:
- c.op_import(gpg.Data(file=impkey))
- except:
- return False
+ with gpg.Context() as c:
+ c.set_engine_info(gpg.constants.protocol.OpenPGP, home_dir=self.paths['gnupg_homedir'])
+
+ impkey = self.paths['signing_keys'][key]
+ try:
+ c.op_import(gpg.Data(file=impkey))
+ except:
+ return False
+ else:
+ result = c.op_import_result()
+ if result and self.fingerprints[key] in result.imports[0].fpr:
+ return True
else:
- result = c.op_import_result()
- if result and self.fingerprints[key] in result.imports[0].fpr:
- return True
- else:
- return False
- else:
- success = False
-
- p = subprocess.Popen(['/usr/bin/gpg', '--status-fd', '2',
- '--homedir', self.paths['gnupg_homedir'],
- '--import', self.paths['signing_keys'][key]],
- stderr=subprocess.PIPE)
- p.wait()
-
- for output in p.stderr.readlines():
- match = gnupg_import_ok_pattern.match(output)
- if match:
- if match.group().find(self.fingerprints[key]) >= 0:
- success = True
- break
-
- return success
+ return False
# import gpg keys
def import_keys(self):
:returns: ``True`` if all keys were successfully imported; ``False``
otherwise.
"""
- keys = ['tor_browser_developers',]
+ keys = ['tor_browser_developers', ]
all_imports_succeeded = True
for key in keys:
imported = self.import_key_and_check_status(key)
if not imported:
- print _('Could not import key with fingerprint: %s.'
- % self.fingerprints[key])
+ print(_('Could not import key with fingerprint: %s.'
+ % self.fingerprints[key]))
all_imports_succeeded = False
if not all_imports_succeeded:
- print _('Not all keys were imported successfully!')
+ print(_('Not all keys were imported successfully!'))
- self.refresh_keyring()
return all_imports_succeeded
# load mirrors
'tbl_version': self.tbl_version,
'installed': False,
'download_over_tor': False,
- 'modem_sound': False,
- 'tor_socks_address': 'tcp:127.0.0.1:9050',
+ 'tor_socks_address': '127.0.0.1:9050',
'mirror': self.default_mirror,
'force_en-US': False,
}
settings[setting] = default_settings[setting]
resave = True
+ # make sure tor_socks_address doesn't start with 'tcp:'
+ if settings['tor_socks_address'].startswith('tcp:'):
+ settings['tor_socks_address'] = settings['tor_socks_address'][4:]
+ resave = True
+
# make sure the version is current
if settings['tbl_version'] != self.tbl_version:
settings['tbl_version'] = self.tbl_version