def generate(): chunk_size = 102400 # 100kb fp = open(zip_filename, 'rb') done = False canceled = False while not done: chunk = fp.read(chunk_size) if chunk == '': done = True else: try: yield chunk # tell GUI the progress downloaded_bytes = fp.tell() percent = (1.0 * downloaded_bytes / zip_filesize) * 100 # suppress stdout platform on OSX (#203) if helpers.get_platform() != 'Darwin': sys.stdout.write("\r{0:s}, {1:.2f}% ".format( helpers.human_readable_filesize(downloaded_bytes), percent)) sys.stdout.flush() add_request(REQUEST_PROGRESS, path, { 'id': download_id, 'bytes': downloaded_bytes }) except: # looks like the download was canceled done = True canceled = True # tell the GUI the download has canceled add_request(REQUEST_CANCELED, path, {'id': download_id}) fp.close() if helpers.get_platform() != 'Darwin': sys.stdout.write("\n") # download is finished, close the server if not stay_open and not canceled: print strings._("closing_automatically") if shutdown_func is None: raise RuntimeError('Not running with the Werkzeug Server') shutdown_func()
def tails_root(): # if running in Tails and as root, do only the things that require root if helpers.get_platform() == 'Tails' and helpers.is_root(): parser = argparse.ArgumentParser() parser.add_argument('port', nargs=1, help=strings._("help_tails_port")) args = parser.parse_args() try: port = int(args.port[0]) except ValueError: sys.stderr.write('{0}\n'.format(strings._("error_tails_invalid_port"))) sys.exit(-1) # open hole in firewall subprocess.call(['/sbin/iptables', '-I', 'OUTPUT', '-o', 'lo', '-p', 'tcp', '--dport', str(port), '-j', 'ACCEPT']) # start hidden service app = OnionShare() app.choose_port() app.port = port app.start_hidden_service(False, True) sys.stdout.write(app.onion_host) sys.stdout.flush() # close hole in firewall on shutdown import signal def handler(signum = None, frame = None): subprocess.call(['/sbin/iptables', '-D', 'OUTPUT', '-o', 'lo', '-p', 'tcp', '--dport', str(port), '-j', 'ACCEPT']) sys.exit() for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]: signal.signal(sig, handler) # stay open until killed while True: time.sleep(1)
def load_strings(default="en"): """ Loads translated strings and fallback to English if the translation does not exist. """ global strings p = helpers.get_platform() # find locale dir if p == 'Linux': locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale') elif p == 'Darwin': locale_dir = os.path.join(helpers.osx_resources_dir, 'locale') else: locale_dir = os.path.join(os.path.dirname(helpers.get_onionshare_dir()), 'locale') # load all translations translations = {} for filename in os.listdir(locale_dir): abs_filename = os.path.join(locale_dir, filename) lang, ext = os.path.splitext(filename) if abs_filename.endswith('.json'): translations[lang] = json.loads(open(abs_filename).read()) strings = translations[default] lc, enc = locale.getdefaultlocale() if lc: lang = lc[:2] if lang in translations: # if a string doesn't exist, fallback to English for key in translations[default]: if key in translations[lang]: strings[key] = translations[lang][key]
def load_strings(default="en"): global strings p = helpers.get_platform() # find locale dir if p == 'Linux' or p == 'Tails': locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale') elif p == 'Darwin': locale_dir = os.path.join(helpers.osx_resources_dir, 'locale') else: locale_dir = os.path.join( os.path.dirname(helpers.get_onionshare_dir()), 'locale') # load all translations translated = {} for filename in os.listdir(locale_dir): abs_filename = os.path.join(locale_dir, filename) lang, ext = os.path.splitext(filename) if abs_filename.endswith('.json'): translated[lang] = json.loads(open(abs_filename).read()) strings = translated[default] lc, enc = locale.getdefaultlocale() if lc: lang = lc[:2] if lang in translated: # if a string doesn't exist, fallback to English for key in translated[default]: if key in translated[lang]: strings[key] = translated[lang][key]
def start(self, port): """ Start a hidden service on port 80, pointing to the given port, and return the onion hostname. """ print strings._("connecting_ctrlport").format(int(port)) if self.supports_ephemeral: print strings._('using_ephemeral') res = self.c.create_ephemeral_hidden_service( {80: port}, await_publication=False) self.service_id = res.content()[0][2].split('=')[1] onion_host = res.content()[0][2].split('=')[1] + '.onion' return onion_host else: # come up with a hidden service directory name if helpers.get_platform() == 'Windows': self.hidserv_dir = tempfile.mkdtemp() self.hidserv_dir = self.hidserv_dir.replace('\\', '/') else: path = '/tmp/onionshare' try: if not os.path.exists(path): os.makedirs(path, 0700) except: raise HSDirError( strings._("error_hs_dir_cannot_create").format(path)) if not os.access(path, os.W_OK): raise HSDirError( strings._("error_hs_dir_not_writable").format(path)) self.hidserv_dir = tempfile.mkdtemp(dir=path) self.cleanup_filenames.append(self.hidserv_dir) # set up hidden service hsdic = self.c.get_conf_map('HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } if self.hidserv_dir in hsdic.get('HiddenServiceDir', []): # Maybe a stale service with the wrong local port dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir) del hsdic['HiddenServiceDir'][dropme] del hsdic['HiddenServicePort'][dropme] hsdic['HiddenServiceDir'] = hsdic.get('HiddenServiceDir', []) + [self.hidserv_dir] hsdic['HiddenServicePort'] = hsdic.get( 'HiddenServicePort', []) + ['80 127.0.0.1:{0:d}'.format(port)] self.c.set_options(self._hsdic2list(hsdic)) # figure out the .onion hostname hostname_file = '{0:s}/hostname'.format(self.hidserv_dir) onion_host = open(hostname_file, 'r').read().strip() return onion_host
def generate(): chunk_size = 102400 # 100kb fp = open(zip_filename, 'rb') done = False canceled = False while not done: chunk = fp.read(chunk_size) if chunk == '': done = True else: try: yield chunk # tell GUI the progress downloaded_bytes = fp.tell() percent = (1.0 * downloaded_bytes / zip_filesize) * 100 # suppress stdout platform on OSX (#203) if helpers.get_platform() != 'Darwin': sys.stdout.write( "\r{0:s}, {1:.2f}% ".format(helpers.human_readable_filesize(downloaded_bytes), percent)) sys.stdout.flush() add_request(REQUEST_PROGRESS, path, {'id': download_id, 'bytes': downloaded_bytes}) except: # looks like the download was canceled done = True canceled = True # tell the GUI the download has canceled add_request(REQUEST_CANCELED, path, {'id': download_id}) fp.close() if helpers.get_platform() != 'Darwin': sys.stdout.write("\n") # download is finished, close the server if not stay_open and not canceled: print strings._("closing_automatically") if shutdown_func is None: raise RuntimeError('Not running with the Werkzeug Server') shutdown_func()
def stop(port): # to stop flask, load http://127.0.0.1:<port>/<shutdown_slug>/shutdown if helpers.get_platform() == 'Tails': # in Tails everything is proxies over Tor, so we need to get lower level # to connect not over the proxy import socket s = socket.socket() s.connect(('127.0.0.1', port)) s.sendall('GET /{0}/shutdown HTTP/1.1\r\n\r\n'.format(shutdown_slug)) else: urllib2.urlopen('http://127.0.0.1:{0}/{1}/shutdown'.format(port, shutdown_slug)).read()
def wait_for_hs(self): if self.local_only: return True print strings._('wait_for_hs') ready = False while not ready: try: sys.stdout.write('{0:s} '.format( strings._('wait_for_hs_trying'))) sys.stdout.flush() if helpers.get_platform() == 'Tails': # in Tails everything is proxies over Tor already # so no need to set the socks5 proxy urllib2.urlopen('http://{0:s}'.format(self.onion_host)) else: tor_exists = False tor_socks_ports = [9050, 9150] for tor_socks_port in tor_socks_ports: try: s = socks.socksocket() s.setproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', tor_socks_port) s.connect((self.onion_host, 80)) s.close() tor_exists = True break except socks.ProxyConnectionError: pass if not tor_exists: raise NoTor( strings._("cant_connect_socksport").format( tor_socks_ports)) ready = True sys.stdout.write('{0:s}\n'.format( strings._('wait_for_hs_yup'))) except socks.SOCKS5Error: # non-Tails error sys.stdout.write('{0:s}\n'.format( strings._('wait_for_hs_nope'))) sys.stdout.flush() except urllib2.HTTPError: # Tails error sys.stdout.write('{0:s}\n'.format( strings._('wait_for_hs_nope'))) sys.stdout.flush() except httplib.BadStatusLine: # Tails (with bridge) error sys.stdout.write('{0:s}\n'.format( strings._('wait_for_hs_nope'))) sys.stdout.flush() except KeyboardInterrupt: return False return True
def stop(port): # to stop flask, load http://127.0.0.1:<port>/<shutdown_slug>/shutdown if helpers.get_platform() == 'Tails': # in Tails everything is proxies over Tor, so we need to get lower level # to connect not over the proxy import socket s = socket.socket() s.connect(('127.0.0.1', port)) s.sendall('GET /{0}/shutdown HTTP/1.1\r\n\r\n'.format(shutdown_slug)) else: urllib2.urlopen('http://127.0.0.1:{0}/{1}/shutdown'.format( port, shutdown_slug)).read()
def start(self, port): """ Start a hidden service on port 80, pointing to the given port, and return the onion hostname. """ print strings._("connecting_ctrlport").format(int(port)) if self.supports_ephemeral: print strings._('using_ephemeral') res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication = False) self.service_id = res.content()[0][2].split('=')[1] onion_host = res.content()[0][2].split('=')[1] + '.onion' return onion_host else: # come up with a hidden service directory name if helpers.get_platform() == 'Windows': self.hidserv_dir = tempfile.mkdtemp() self.hidserv_dir = self.hidserv_dir.replace('\\', '/') else: path = '/tmp/onionshare' try: if not os.path.exists(path): os.makedirs(path, 0700) except: raise HSDirError(strings._("error_hs_dir_cannot_create").format(path)) if not os.access(path, os.W_OK): raise HSDirError(strings._("error_hs_dir_not_writable").format(path)) self.hidserv_dir = tempfile.mkdtemp(dir=path) self.cleanup_filenames.append(self.hidserv_dir) # set up hidden service hsdic = self.c.get_conf_map('HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } if self.hidserv_dir in hsdic.get('HiddenServiceDir', []): # Maybe a stale service with the wrong local port dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir) del hsdic['HiddenServiceDir'][dropme] del hsdic['HiddenServicePort'][dropme] hsdic['HiddenServiceDir'] = hsdic.get('HiddenServiceDir', [])+[self.hidserv_dir] hsdic['HiddenServicePort'] = hsdic.get('HiddenServicePort', [])+[ '80 127.0.0.1:{0:d}'.format(port)] self.c.set_options(self._hsdic2list(hsdic)) # figure out the .onion hostname hostname_file = '{0:s}/hostname'.format(self.hidserv_dir) onion_host = open(hostname_file, 'r').read().strip() return onion_host
def start_hidden_service(self, gui=False, tails_root=False): if not self.port: self.choose_port() if helpers.get_platform() == 'Tails' and not tails_root: # in Tails, start the hidden service in a root process if gui: args = ['/usr/bin/gksudo', '-D', 'OnionShare', '--', '/usr/bin/onionshare'] else: args = ['/usr/bin/sudo', '--', '/usr/bin/onionshare'] p = subprocess.Popen(args+[str(self.port)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout = p.stdout.read(22) # .onion URLs are 22 chars long if stdout: self.onion_host = stdout else: if p.poll() == -1: raise TailsError(o.stderr.read()) else: raise TailsError(strings._("error_tails_unknown_root")) else: if self.local_only: self.onion_host = '127.0.0.1:{0}'.format(self.port) else: # come up with a hidden service directory name hidserv_dir = '{0}/onionshare_{1}'.format(helpers.get_tmp_dir(), helpers.random_string(8)) self.cleanup_filenames.append(hidserv_dir) # connect to the tor controlport controller = False tor_control_ports = [9051, 9151] for tor_control_port in tor_control_ports: try: controller = Controller.from_port(port=tor_control_port) break except SocketError: pass if not controller: raise NoTor(strings._("cant_connect_ctrlport").format(tor_control_ports)) controller.authenticate() # set up hidden service controller.set_options([ ('HiddenServiceDir', hidserv_dir), ('HiddenServicePort', '80 127.0.0.1:{0}'.format(self.port)) ]) # figure out the .onion hostname hostname_file = '{0}/hostname'.format(hidserv_dir) self.onion_host = open(hostname_file, 'r').read().strip()
def start(self, port): """ Start a hidden service on port 80, pointing to the given port, and return the onion hostname. """ print strings._("connecting_ctrlport").format(int(port)) if self.supports_ephemeral: print strings._('using_ephemeral') res = self.c.create_ephemeral_hidden_service( {80: port}, await_publication=True) self.service_id = res.content()[0][2].split('=')[1] onion_host = res.content()[0][2].split('=')[1] + '.onion' return onion_host else: # come up with a hidden service directory name if helpers.get_platform() == 'Windows': path = '{0:s}/onionshare'.format(os.environ['Temp'].replace( '\\', '/')) else: path = '/tmp/onionshare' try: if not os.path.exists(path): os.makedirs(path, 0700) except: raise HSDirError( strings._("error_hs_dir_cannot_create").format(path)) if not os.access(path, os.W_OK): raise HSDirError( strings._("error_hs_dir_not_writable").format(path)) self.hidserv_dir = tempfile.mkdtemp(dir=path) self.cleanup_filenames.append(self.hidserv_dir) # set up hidden service hs_conf = self.c.get_hidden_service_conf() if self.hidserv_dir in hs_conf: del hs_conf[self.hidserv_dir] hs_conf[self.hidserv_dir] = { 'HiddenServicePort': [(80, '127.0.0.1', port)] } self.c.set_hidden_service_conf(hs_conf) # figure out the .onion hostname hostname_file = '{0:s}/hostname'.format(self.hidserv_dir) onion_host = open(hostname_file, 'r').read().strip() return onion_host
def tails_root(): # if running in Tails and as root, do only the things that require root if helpers.get_platform() == 'Tails' and helpers.is_root(): parser = argparse.ArgumentParser() parser.add_argument('port', nargs=1, help=strings._("help_tails_port")) args = parser.parse_args() try: port = int(args.port[0]) except ValueError: sys.stderr.write('{0}\n'.format( strings._("error_tails_invalid_port"))) sys.exit(-1) # open hole in firewall subprocess.call([ '/sbin/iptables', '-I', 'OUTPUT', '-o', 'lo', '-p', 'tcp', '--dport', str(port), '-j', 'ACCEPT' ]) # start hidden service app = OnionShare() app.choose_port() app.port = port app.start_hidden_service(False, True) sys.stdout.write(app.onion_host) sys.stdout.flush() # close hole in firewall on shutdown import signal def handler(signum=None, frame=None): subprocess.call([ '/sbin/iptables', '-D', 'OUTPUT', '-o', 'lo', '-p', 'tcp', '--dport', str(port), '-j', 'ACCEPT' ]) sys.exit() for sig in [ signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT ]: signal.signal(sig, handler) # stay open until killed while True: time.sleep(1)
def wait_for_hs(self): if self.local_only: return True print strings._('wait_for_hs') ready = False while not ready: try: sys.stdout.write('{0} '.format(strings._('wait_for_hs_trying'))) sys.stdout.flush() if helpers.get_platform() == 'Tails': # in Tails everything is proxies over Tor already # so no need to set the socks5 proxy urllib2.urlopen('http://{0}'.format(self.onion_host)) else: tor_exists = False tor_socks_ports = [9050, 9150] for tor_socks_port in tor_socks_ports: try: s = socks.socksocket() s.setproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', tor_socks_port) s.connect((self.onion_host, 80)) s.close() tor_exists = True break except socks.ProxyConnectionError: pass if not tor_exists: raise NoTor(strings._("cant_connect_socksport").format(tor_socks_ports)) ready = True sys.stdout.write('{0}\n'.format(strings._('wait_for_hs_yup'))) except socks.SOCKS5Error: # non-Tails error sys.stdout.write('{0}\n'.format(strings._('wait_for_hs_nope'))) sys.stdout.flush() except urllib2.HTTPError: # Tails error sys.stdout.write('{0}\n'.format(strings._('wait_for_hs_nope'))) sys.stdout.flush() except KeyboardInterrupt: return False return True
def start(self, port): """ Start a hidden service on port 80, pointing to the given port, and return the onion hostname. """ print strings._("connecting_ctrlport").format(int(port)) if self.supports_ephemeral: print strings._("using_ephemeral") res = self.c.create_ephemeral_hidden_service({80: port}, await_publication=True) self.service_id = res.content()[0][2].split("=")[1] onion_host = res.content()[0][2].split("=")[1] + ".onion" return onion_host else: # come up with a hidden service directory name if helpers.get_platform() == "Windows": path = "{0:s}/onionshare".format(os.environ["Temp"].replace("\\", "/")) else: path = "/tmp/onionshare" try: if not os.path.exists(path): os.makedirs(path, 0700) except: raise HSDirError(strings._("error_hs_dir_cannot_create").format(path)) if not os.access(path, os.W_OK): raise HSDirError(strings._("error_hs_dir_not_writable").format(path)) self.hidserv_dir = tempfile.mkdtemp(dir=path) self.cleanup_filenames.append(self.hidserv_dir) # set up hidden service hs_conf = self.c.get_hidden_service_conf() if self.hidserv_dir in hs_conf: del hs_conf[self.hidserv_dir] hs_conf[self.hidserv_dir] = {"HiddenServicePort": [(80, "127.0.0.1", port)]} self.c.set_hidden_service_conf(hs_conf) # figure out the .onion hostname hostname_file = "{0:s}/hostname".format(self.hidserv_dir) onion_host = open(hostname_file, "r").read().strip() return onion_host
def start_hidden_service(self, gui=False, tails_root=False): if not self.port: self.choose_port() if helpers.get_platform() == 'Tails' and not tails_root: # in Tails, start the hidden service in a root process if gui: args = ['/usr/bin/gksudo', '-D', 'OnionShare', '--', '/usr/bin/onionshare'] else: args = ['/usr/bin/sudo', '--', '/usr/bin/onionshare'] print "Executing: {0}".format(args+[str(self.port)]) p = subprocess.Popen(args+[str(self.port)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout = p.stdout.read(22) # .onion URLs are 22 chars long if stdout: self.onion_host = stdout print 'Got onion_host: {0}'.format(self.onion_host) else: if p.poll() == -1: raise TailsError(o.stderr.read()) else: raise TailsError(strings._("error_tails_unknown_root")) else: if self.local_only: self.onion_host = '127.0.0.1:{0}'.format(self.port) else: # come up with a hidden service directory name if helpers.get_platform() == 'Tails': # need to create HS directory in /var/lib/tor because of AppArmor rules included in Tails self.hidserv_dir = tempfile.mkdtemp(dir='/var/lib/tor') # change owner to debian-tor import pwd import grp uid = pwd.getpwnam("debian-tor").pw_uid gid = grp.getgrnam("debian-tor").gr_gid os.chown(self.hidserv_dir, uid, gid) else: self.hidserv_dir = tempfile.mkdtemp() self.cleanup_filenames.append(self.hidserv_dir) # connect to the tor controlport self.controller = None tor_control_ports = [9051, 9151] for tor_control_port in tor_control_ports: try: self.controller = Controller.from_port(port=tor_control_port) break except SocketError: pass if not self.controller: raise NoTor(strings._("cant_connect_ctrlport").format(tor_control_ports)) self.controller.authenticate() # set up hidden service if helpers.get_platform() == 'Windows': self.hidserv_dir = self.hidserv_dir.replace('\\', '/') hsdic = self.controller.get_conf_map('HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } if self.hidserv_dir in hsdic.get('HiddenServiceDir', []): # Maybe a stale service with the wrong local port dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir) del hsdic['HiddenServiceDir'][dropme] del hsdic['HiddenServicePort'][dropme] hsdic['HiddenServiceDir'] = hsdic.get('HiddenServiceDir', [])+[self.hidserv_dir] hsdic['HiddenServicePort'] = hsdic.get('HiddenServicePort', [])+[ '80 127.0.0.1:{0}'.format(self.port)] self.controller.set_options(hsdic2list(hsdic)) # figure out the .onion hostname hostname_file = '{0}/hostname'.format(self.hidserv_dir) self.onion_host = open(hostname_file, 'r').read().strip()
def main(cwd=None): """ The main() function implements all of the logic that the command-line version of onionshare uses. """ strings.load_strings() # onionshare CLI in OSX needs to change current working directory (#132) if helpers.get_platform() == 'Darwin': if cwd: os.chdir(cwd) # parse arguments parser = argparse.ArgumentParser() parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only")) parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open")) parser.add_argument('--transparent', action='store_true', dest='transparent_torification', help=strings._("help_transparent_torification")) parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug")) parser.add_argument('filename', metavar='filename', nargs='+', help=strings._('help_filename')) args = parser.parse_args() filenames = args.filename for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) local_only = bool(args.local_only) debug = bool(args.debug) stay_open = bool(args.stay_open) transparent_torification = bool(args.transparent_torification) # validation valid = True for filename in filenames: if not os.path.exists(filename): print(strings._("not_a_file").format(filename)) valid = False if not valid: sys.exit() # start the onionshare app try: app = OnionShare(debug, local_only, stay_open, transparent_torification) app.choose_port() app.start_hidden_service() except hs.NoTor as e: sys.exit(e.args[0]) except hs.HSDirError as e: sys.exit(e.args[0]) # prepare files to share print strings._("preparing_files") web.set_file_info(filenames) app.cleanup_filenames.append(web.zip_filename) # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb print '' print strings._("large_filesize") print '' # start onionshare service in new thread t = threading.Thread(target=web.start, args=(app.port, app.stay_open, app.transparent_torification)) t.daemon = True t.start() try: # Trap Ctrl-C # wait for hs, only if using old version of tor if not app.local_only: ready = app.hs.wait_for_hs(app.onion_host) if not ready: sys.exit() print strings._("give_this_url") print 'http://{0:s}/{1:s}'.format(app.onion_host, web.slug) print '' print strings._("ctrlc_to_stop") # wait for app to close while t.is_alive(): # t.join() can't catch KeyboardInterrupt in such as Ubuntu t.join(0.5) except KeyboardInterrupt: web.stop(app.port) finally: # shutdown app.cleanup()
def start_hidden_service(self, gui=False, tails_root=False): if not self.port: self.choose_port() if helpers.get_platform() == 'Tails' and not tails_root: # in Tails, start the hidden service in a root process if gui: args = [ '/usr/bin/gksudo', '-D', 'OnionShare', '--', '/usr/bin/onionshare' ] else: args = ['/usr/bin/sudo', '--', '/usr/bin/onionshare'] p = subprocess.Popen(args + [str(self.port)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout = p.stdout.read(22) # .onion URLs are 22 chars long if stdout: self.onion_host = stdout else: if p.poll() == -1: raise TailsError(o.stderr.read()) else: raise TailsError(strings._("error_tails_unknown_root")) else: if self.local_only: self.onion_host = '127.0.0.1:{0}'.format(self.port) else: # come up with a hidden service directory name hidserv_dir = '{0}/onionshare_{1}'.format( helpers.get_tmp_dir(), helpers.random_string(8)) self.cleanup_filenames.append(hidserv_dir) # connect to the tor controlport controller = False tor_control_ports = [9051, 9151] for tor_control_port in tor_control_ports: try: controller = Controller.from_port( port=tor_control_port) break except SocketError: pass if not controller: raise NoTor( strings._("cant_connect_ctrlport").format( tor_control_ports)) controller.authenticate() # set up hidden service controller.set_options([ ('HiddenServiceDir', hidserv_dir), ('HiddenServicePort', '80 127.0.0.1:{0}'.format(self.port)) ]) # figure out the .onion hostname hostname_file = '{0}/hostname'.format(hidserv_dir) self.onion_host = open(hostname_file, 'r').read().strip()
def main(cwd=None): """ The main() function implements all of the logic that the command-line version of onionshare uses. """ strings.load_strings() # onionshare CLI in OSX needs to change current working directory (#132) if helpers.get_platform() == 'Darwin': if cwd: os.chdir(cwd) # parse arguments parser = argparse.ArgumentParser() parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only")) parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open")) parser.add_argument('--transparent', action='store_true', dest='transparent_torification', help=strings._("help_transparent_torification")) parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug")) parser.add_argument('filename', metavar='filename', nargs='+', help=strings._('help_filename')) args = parser.parse_args() filenames = args.filename for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) local_only = bool(args.local_only) debug = bool(args.debug) stay_open = bool(args.stay_open) transparent_torification = bool(args.transparent_torification) # validation valid = True for filename in filenames: if not os.path.exists(filename): print(strings._("not_a_file").format(filename)) valid = False if not valid: sys.exit() # start the onionshare app try: app = OnionShare(debug, local_only, stay_open, transparent_torification) app.choose_port() app.start_hidden_service() except hs.NoTor as e: sys.exit(e.args[0]) except hs.HSDirError as e: sys.exit(e.args[0]) # prepare files to share print strings._("preparing_files") web.set_file_info(filenames) app.cleanup_filenames.append(web.zip_filename) # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb print '' print strings._("large_filesize") print '' # start onionshare service in new thread t = threading.Thread(target=web.start, args=(app.port, app.stay_open, app.transparent_torification)) t.daemon = True t.start() try: # Trap Ctrl-C # wait for hs, only if using old version of tor if not app.hs.supports_ephemeral: if not app.local_only: ready = app.hs.wait_for_hs(app.onion_host) if not ready: sys.exit() print strings._("give_this_url") print 'http://{0:s}/{1:s}'.format(app.onion_host, web.slug) print '' print strings._("ctrlc_to_stop") # wait for app to close while t.is_alive(): # t.join() can't catch KeyboardInterrupt in such as Ubuntu t.join(0.5) except KeyboardInterrupt: web.stop(app.port) finally: # shutdown app.cleanup()
def start_hidden_service(self, gui=False, tails_root=False): if not self.port: self.choose_port() if helpers.get_platform() == 'Tails' and not tails_root: # in Tails, start the hidden service in a root process if gui: args = [ '/usr/bin/gksudo', '-D', 'OnionShare', '--', '/usr/bin/onionshare' ] else: args = ['/usr/bin/sudo', '--', '/usr/bin/onionshare'] print "Executing: {0}".format(args + [str(self.port)]) p = subprocess.Popen(args + [str(self.port)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout = p.stdout.read(22) # .onion URLs are 22 chars long if stdout: self.onion_host = stdout print 'Got onion_host: {0}'.format(self.onion_host) else: if p.poll() == -1: raise TailsError(o.stderr.read()) else: raise TailsError(strings._("error_tails_unknown_root")) else: if self.local_only: self.onion_host = '127.0.0.1:{0}'.format(self.port) else: # come up with a hidden service directory name if helpers.get_platform() == 'Tails': # need to create HS directory in /var/lib/tor because of AppArmor rules included in Tails self.hidserv_dir = tempfile.mkdtemp(dir='/var/lib/tor') # change owner to debian-tor import pwd import grp uid = pwd.getpwnam("debian-tor").pw_uid gid = grp.getgrnam("debian-tor").gr_gid os.chown(self.hidserv_dir, uid, gid) else: self.hidserv_dir = tempfile.mkdtemp() self.cleanup_filenames.append(self.hidserv_dir) # connect to the tor controlport self.controller = None tor_control_ports = [9051, 9151] for tor_control_port in tor_control_ports: try: self.controller = Controller.from_port( port=tor_control_port) break except SocketError: pass if not self.controller: raise NoTor( strings._("cant_connect_ctrlport").format( tor_control_ports)) self.controller.authenticate() # set up hidden service if helpers.get_platform() == 'Windows': self.hidserv_dir = self.hidserv_dir.replace('\\', '/') hsdic = self.controller.get_conf_map( 'HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } if self.hidserv_dir in hsdic.get('HiddenServiceDir', []): # Maybe a stale service with the wrong local port dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir) del hsdic['HiddenServiceDir'][dropme] del hsdic['HiddenServicePort'][dropme] hsdic['HiddenServiceDir'] = hsdic.get('HiddenServiceDir', []) + [self.hidserv_dir] hsdic['HiddenServicePort'] = hsdic.get( 'HiddenServicePort', []) + ['80 127.0.0.1:{0}'.format(self.port)] self.controller.set_options(hsdic2list(hsdic)) # figure out the .onion hostname hostname_file = '{0}/hostname'.format(self.hidserv_dir) self.onion_host = open(hostname_file, 'r').read().strip()
def __init__(self): self.lastPos = None self.last_interaction = datetime.datetime.now() self.platform = helpers.get_platform() self.m = PyMouse()