diff --git a/install/build_osx.sh b/install/build_osx.sh index 44883fdf..f6b27d9b 100755 --- a/install/build_osx.sh +++ b/install/build_osx.sh @@ -5,11 +5,12 @@ cd $ROOT # deleting dist echo Deleting dist folder -rm -rf $ROOT/build $ROOT/dist &>/dev/null 2>&1 +rm -rf $ROOT/dist &>/dev/null 2>&1 # build the .app echo Building OnionShare.app pyinstaller $ROOT/install/pyinstaller.spec +python3 $ROOT/install/get-tor-osx.py # create a symlink of onionshare-gui called onionshare, for the CLI version cd $ROOT/dist/OnionShare.app/Contents/MacOS diff --git a/install/get-tor-osx.py b/install/get-tor-osx.py new file mode 100644 index 00000000..fe437669 --- /dev/null +++ b/install/get-tor-osx.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2017 Micah Lee + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" + +""" +This script downloads a pre-built tor binary to bundle with OnionShare. +In order to avoid a Mac gnupg dependency, I manually verify the signature +and hard-code the sha256 hash. +""" + +import inspect, os, sys, hashlib, zipfile, io, shutil, subprocess +import urllib.request + +def main(): + dmg_url = 'https://www.torproject.org/dist/torbrowser/6.5.1/TorBrowser-6.5.1-osx64_en-US.dmg' + dmg_filename = 'TorBrowser-6.5.1-osx64_en-US.dmg' + expected_dmg_sha256 = '4155633dd51db9c805e8a81a9fd180e7235077f15023b5f002648f1c2a8bef92' + + # Build paths + root_path = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) + working_path = os.path.join(root_path, 'build', 'tor') + dmg_tor_path = os.path.join('/Volumes', 'Tor Browser', 'TorBrowser.app', 'Contents') + dmg_path = os.path.join(working_path, dmg_filename) + dist_path = os.path.join(root_path, 'dist', 'OnionShare.app', 'Contents') + + # Make sure the working folder exists + if not os.path.exists(working_path): + os.makedirs(working_path) + + # Make sure the zip is downloaded + if not os.path.exists(dmg_path): + print("Downloading {}".format(dmg_url)) + response = urllib.request.urlopen(dmg_url) + dmg_data = response.read() + open(dmg_path, 'wb').write(dmg_data) + dmg_sha256 = hashlib.sha256(dmg_data).hexdigest() + else: + dmg_data = open(dmg_path, 'rb').read() + dmg_sha256 = hashlib.sha256(dmg_data).hexdigest() + + # Compare the hash + if dmg_sha256 != expected_dmg_sha256: + print("ERROR! The sha256 doesn't match:") + print("expected: {}".format(expected_dmg_sha256)) + print(" actual: {}".format(dmg_sha256)) + sys.exit(-1) + + # Mount the dmg, copy data to the working path + subprocess.call(['hdiutil', 'attach', dmg_path]) + + # Make sure Resources/tor exists before copying files + if os.path.exists(os.path.join(dist_path, 'Resources', 'tor')): + shutil.rmtree(os.path.join(dist_path, 'Resources', 'tor')) + os.makedirs(os.path.join(dist_path, 'Resources', 'tor')) + + # Copy into dist + shutil.copyfile(os.path.join(dmg_tor_path, 'Resources', 'TorBrowser', 'Tor', 'geoip'), os.path.join(dist_path, 'Resources', 'tor', 'geoip')) + shutil.copyfile(os.path.join(dmg_tor_path, 'Resources', 'TorBrowser', 'Tor', 'geoip6'), os.path.join(dist_path, 'Resources', 'tor', 'geoip6')) + shutil.copyfile(os.path.join(dmg_tor_path, 'MacOS', 'Tor', 'tor.real'), os.path.join(dist_path, 'MacOS', 'tor')) + os.chmod(os.path.join(dist_path, 'MacOS', 'tor'), 0o755) + + # Unmount dmg + subprocess.call(['diskutil', 'unmount', '/Volumes/Tor Browser']) + +if __name__ == '__main__': + main() diff --git a/install/pyinstaller.spec b/install/pyinstaller.spec index 14b0d822..0ba359d0 100644 --- a/install/pyinstaller.spec +++ b/install/pyinstaller.spec @@ -13,6 +13,7 @@ a = Analysis( ('../share/license.txt', 'share'), ('../share/version.txt', 'share'), ('../share/wordlist.txt', 'share'), + ('../share/torrc_template', 'share'), ('../share/torrc_template-windows', 'share'), ('../share/images/*', 'share/images'), ('../share/locale/*', 'share/locale'), diff --git a/onionshare/helpers.py b/onionshare/helpers.py index 9bd26f3e..97b4e462 100644 --- a/onionshare/helpers.py +++ b/onionshare/helpers.py @@ -65,8 +65,10 @@ def get_tor_paths(): 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') elif p == 'Darwin': - # TODO: implement - pass + base_path = os.path.dirname(os.path.dirname(os.path.dirname(get_resource_path('')))) + tor_path = os.path.join(base_path, 'MacOS', 'tor') + tor_geo_ip_file_path = os.path.join(base_path, 'Resources', 'tor', 'geoip') + tor_geo_ipv6_file_path = os.path.join(base_path, 'Resources', 'tor', 'geoip6') return (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path) diff --git a/onionshare/onion.py b/onionshare/onion.py index 45dba2f9..7455c3d8 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -192,7 +192,7 @@ class Onion(object): self.c = Controller.from_port(port=self.tor_control_port) self.c.authenticate() else: - elf.c = Controller.from_socket_file(path=self.tor_control_socket) + self.c = Controller.from_socket_file(path=self.tor_control_socket) self.c.authenticate() while True: diff --git a/onionshare/onionshare-gui b/onionshare/onionshare-gui new file mode 120000 index 00000000..5b0d4e42 --- /dev/null +++ b/onionshare/onionshare-gui @@ -0,0 +1 @@ +onionshare-gui \ No newline at end of file