From 40ee114803b2c0f0fcc44fd26106e7834ce0e073 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Jan 2018 12:45:37 +1100 Subject: [PATCH] Extract tor and obfs4proxy executables from the main TorBrowser executable with 7-zip on Windows --- BUILD.md | 7 +++++- install/get-tor-windows.py | 46 ++++++++++++++++------------------ install/onionshare.nsi | 1 + onionshare/common.py | 4 +-- test/test_onionshare_common.py | 6 ++--- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/BUILD.md b/BUILD.md index c9224611..d1fdcb88 100644 --- a/BUILD.md +++ b/BUILD.md @@ -94,11 +94,16 @@ These instructions include adding folders to the path in Windows. To do this, go Download and install the 32-bit [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-US/download/details.aspx?id=48145). I downloaded `vc_redist.x86.exe`. -Download and install the standalone [Windows 10 SDK](https://dev.windows.com/en-us/downloads/windows-10-sdk). Note that you may not need this if you already have Visual Studio. Add the following directories to the path: +Download and install 7-Zip from http://70zip.org/download.html. I downloaded 7z1800.exe. + +Download and install the standalone [Windows 10 SDK](https://dev.windows.com/en-us/downloads/windows-10-sdk). Note that you may not need this if you already have Visual Studio. + +Add the following directories to the path: * `C:\Program Files (x86)\Windows Kits\10\bin\x86` * `C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86` * `C:\Users\user\AppData\Local\Programs\Python\Python35-32\Lib\site-packages\PyQt5\Qt\bin` +* `C:\Program Files (x86)\7-Zip` If you want to build the installer: diff --git a/install/get-tor-windows.py b/install/get-tor-windows.py index 83b8f2b3..4945ce68 100644 --- a/install/get-tor-windows.py +++ b/install/get-tor-windows.py @@ -24,18 +24,17 @@ In order to avoid a Windows gnupg dependency, I manually verify the signature and hard-code the sha256 hash. """ -import inspect, os, sys, hashlib, zipfile, io, shutil +import inspect, os, sys, hashlib, shutil, subprocess import urllib.request def main(): - zip_url = 'https://archive.torproject.org/tor-package-archive/torbrowser/7.0.11/tor-win32-0.3.1.9.zip' - zip_filename = 'tor-win32-0.3.1.9.zip' - expected_zip_sha256 = 'faf28efb606455842bda66ca369287a116b6d6e5ad3720ebed9337da0717f1b4' - + exe_url = 'https://archive.torproject.org/tor-package-archive/torbrowser/7.0.11/torbrowser-install-7.0.11_en-US.exe' + exe_filename = 'torbrowser-install-7.0.11_en-US.exe' + expected_exe_sha256 = 'a033eb9b9ed2ad389169b36a90946a8af8f05bd0c7bbd3e37678041331096624' # Build paths root_path = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) working_path = os.path.join(os.path.join(root_path, 'build'), 'tor') - zip_path = os.path.join(working_path, zip_filename) + exe_path = os.path.join(working_path, exe_filename) dist_path = os.path.join(os.path.join(os.path.join(root_path, 'dist'), 'onionshare'), 'tor') # Make sure the working folder exists @@ -43,36 +42,35 @@ def main(): os.makedirs(working_path) # Make sure the zip is downloaded - if not os.path.exists(zip_path): - print("Downloading {}".format(zip_url)) - response = urllib.request.urlopen(zip_url) - zip_data = response.read() - open(zip_path, 'wb').write(zip_data) - zip_sha256 = hashlib.sha256(zip_data).hexdigest() + if not os.path.exists(exe_path): + print("Downloading {}".format(exe_url)) + response = urllib.request.urlopen(exe_url) + exe_data = response.read() + open(exe_path, 'wb').write(exe_data) + exe_sha256 = hashlib.sha256(exe_data).hexdigest() else: - zip_data = open(zip_path, 'rb').read() - zip_sha256 = hashlib.sha256(zip_data).hexdigest() + exe_data = open(exe_path, 'rb').read() + exe_sha256 = hashlib.sha256(exe_data).hexdigest() # Compare the hash - if zip_sha256 != expected_zip_sha256: + if exe_sha256 != expected_exe_sha256: print("ERROR! The sha256 doesn't match:") - print("expected: {}".format(expected_zip_sha256)) - print(" actual: {}".format(zip_sha256)) + print("expected: {}".format(expected_exe_sha256)) + print(" actual: {}".format(exe_sha256)) sys.exit(-1) - # Extract the zip - z = zipfile.ZipFile(io.BytesIO(zip_data)) - z.extractall(working_path) - - # Delete un-used files - os.remove(os.path.join(os.path.join(working_path, 'Tor'), 'tor-gencert.exe')) + # Extract the bits we need from the exe + cmd = ['7z', 'e', exe_path, 'Browser\TorBrowser\Tor', '-o%s' % os.path.join(working_path, 'Tor')] + cmd2 = ['7z', 'e', exe_path, 'Browser\TorBrowser\Data\Tor\geoip*', '-o%s' % os.path.join(working_path, 'Data')] + subprocess.Popen(cmd).wait() + subprocess.Popen(cmd2).wait() # Copy into dist if os.path.exists(dist_path): shutil.rmtree(dist_path) os.makedirs(dist_path) shutil.copytree( os.path.join(working_path, 'Tor'), os.path.join(dist_path, 'Tor') ) - shutil.copytree( os.path.join(working_path, 'Data'), os.path.join(dist_path, 'Data') ) + shutil.copytree( os.path.join(working_path, 'Data'), os.path.join(dist_path, 'Data', 'Tor') ) if __name__ == '__main__': main() diff --git a/install/onionshare.nsi b/install/onionshare.nsi index 10f459fd..865f5613 100644 --- a/install/onionshare.nsi +++ b/install/onionshare.nsi @@ -209,6 +209,7 @@ Section "install" File "${BINPATH}\tor\Tor\libevent-2-0-5.dll" File "${BINPATH}\tor\Tor\libgcc_s_sjlj-1.dll" File "${BINPATH}\tor\Tor\libssp-0.dll" + File "${BINPATH}\tor\Tor\obfs4proxy.exe" File "${BINPATH}\tor\Tor\ssleay32.dll" File "${BINPATH}\tor\Tor\tor.exe" File "${BINPATH}\tor\Tor\zlib1.dll" diff --git a/onionshare/common.py b/onionshare/common.py index 298dd42b..25b901ee 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -97,10 +97,10 @@ def get_tor_paths(): obfs4proxy_file_path = '/usr/bin/obfs4proxy' elif p == 'Windows': base_path = os.path.join(os.path.dirname(os.path.dirname(get_resource_path(''))), 'tor') - tor_path = os.path.join(os.path.join(base_path, 'Tor'), "tor.exe") + tor_path = os.path.join(os.path.join(base_path, 'Tor'), 'tor.exe') + obfs4proxy_file_path = os.path.join(os.path.join(base_path, 'Tor'), 'obfs4proxy.exe') tor_geo_ip_file_path = os.path.join(os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip') tor_geo_ipv6_file_path = os.path.join(os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip6') - obfs4proxy_file_path = os.path.join(os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'obfs4proxy') elif p == 'Darwin': base_path = os.path.dirname(os.path.dirname(os.path.dirname(get_resource_path('')))) tor_path = os.path.join(base_path, 'Resources', 'Tor', 'tor') diff --git a/test/test_onionshare_common.py b/test/test_onionshare_common.py index 3775951b..f574ad7f 100644 --- a/test/test_onionshare_common.py +++ b/test/test_onionshare_common.py @@ -230,15 +230,15 @@ class TestGetTorPaths: os.path.dirname( common.get_resource_path(''))), 'tor') tor_path = os.path.join( - os.path.join(base_path, 'Tor'), "tor.exe") + os.path.join(base_path, 'Tor'), 'tor.exe') + obfs4proxy_file_path = os.path.join( + os.path.join(base_path, 'Tor'), 'obfs4proxy.exe') tor_geo_ip_file_path = os.path.join( os.path.join( os.path.join(base_path, 'Data'), 'Tor'), 'geoip') tor_geo_ipv6_file_path = os.path.join( os.path.join( os.path.join(base_path, 'Data'), 'Tor'), 'geoip6') - obfs4proxy_file_path = os.path.join( - base_path, 'Data', 'Tor', 'obfs4proxy') assert (common.get_tor_paths() == (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path, obfs4proxy_file_path))