def restart(): """Tell the Onionr daemon to restart.""" if platform.system() == 'Windows': logger.warn('Cannot restart Onionr on Windows. Run stop and manually restart.', terminal=True) return logger.info('Restarting Onionr', terminal=True) # On platforms where we can, fork out to prevent locking try: pid = os.fork() if pid != 0: return except (AttributeError, OSError): logger.warn('Could not fork on restart') with open(filepaths.restarting_indicator, 'w') as f: f.write('t') daemonlaunch.kill_daemon() while localcommand.local_command('ping', max_wait=8) == 'pong!': time.sleep(0.3) time.sleep(15) while (os.path.exists(filepaths.private_API_host_file) or (os.path.exists(filepaths.daemon_mark_file))): time.sleep(1) cleanup.delete_run_files() subprocess.Popen([SCRIPT_NAME, 'start'])
def test_delete_run_files(self): for x in run_file_paths: with open(x, 'w') as f: f.write("") self.assertTrue(_run_paths_exist()) delete_run_files() self.assertFalse(_run_paths_exist())
def restart(): logger.info('Restarting Onionr', terminal=True) # On platforms where we can, fork out to prevent locking try: pid = os.fork() if pid != 0: return except (AttributeError, OSError) as e: if platform.platform() != 'Windows': logger.warn('Could not fork on restart') daemonlaunch.kill_daemon() while localcommand.local_command('ping', maxWait=8) == 'pong!': time.sleep(0.3) time.sleep(15) while os.path.exists(filepaths.private_API_host_file) or os.path.exists( filepaths.daemon_mark_file): time.sleep(1) cleanup.delete_run_files() subprocess.Popen([SCRIPT_NAME, 'start'])
def _setup_online_mode(use_existing_tor: bool, net: NetController, security_level: int): if config.get('transports.tor', True): # If we are using tor, check if we are using an existing tor instance # if we are, we need to create an onion service on it and set attrs on our NetController # if not, we need to tell netcontroller to start one if use_existing_tor: try: os.mkdir(filepaths.tor_hs_loc) except FileExistsError: pass net.socksPort = config.get('tor.existing_socks_port') try: net.myID = create_onion_service(port=net.apiServerIP + ':' + str(net.hsPort))[0] except IncorrectPassword: # Exit if we cannot connect to the existing Tor instance logger.error('Invalid Tor control password', terminal=True) localcommand.local_command('shutdown') cleanup.delete_run_files() sys.exit(1) if not net.myID.endswith('.onion'): net.myID += '.onion' with open(filepaths.tor_hs_address_file, 'w') as tor_file: tor_file.write(net.myID) else: logger.info('Tor is starting...', terminal=True) if not net.startTor(): # Exit if we cannot start Tor. localcommand.local_command('shutdown') cleanup.delete_run_files() sys.exit(1) if len(net.myID) > 0 and security_level == 0: logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID)) else: logger.debug('.onion service disabled')
def daemon(): """Start Onionr's primary threads for communicator, API server, node, and LAN.""" def _handle_sig_term(signum, frame): pid = str(os.getpid()) main_pid = localcommand.local_command('/getpid') #logger.info(main_pid, terminal=True) if main_pid and main_pid == pid: logger.info( f"Received sigterm, shutting down gracefully. PID: {pid}", terminal=True) localcommand.local_command('/shutdownclean') else: logger.info( f"Recieved sigterm in child process or fork, exiting. PID: {pid}") sys.exit(0) signal.signal(signal.SIGTERM, _handle_sig_term) # Determine if Onionr is in offline mode. # When offline, Onionr can only use LAN and disk transport offline_mode = config.get('general.offline_mode', False) if not hastor.has_tor(): offline_mode = True logger.error("Tor is not present in system path or Onionr directory", terminal=True) # Create shared objects shared_state = toomanyobjs.TooMany() # Add DeadSimpleKV for quasi-global variables (ephemeral key-value) shared_state.get(DeadSimpleKV) # Initialize the quasi-global variables setup_kv(shared_state.get(DeadSimpleKV)) shared_state.get(daemoneventsapi.DaemonEventsBP) Thread(target=shared_state.get(apiservers.ClientAPI).start, daemon=True, name='client HTTP API').start() if not offline_mode: Thread(target=shared_state.get(apiservers.PublicAPI).start, daemon=True, name='public HTTP API').start() # Init run time tester # (ensures Onionr is running right, for testing purposes) # Run time tests are not normally run shared_state.get(runtests.OnionrRunTestManager) # Create singleton shared_state.get(serializeddata.SerializedData) shared_state.share_object() # share the parent object to the threads show_logo() # since we randomize loopback API server hostname to protect against attacks, # we have to wait for it to become set apiHost = '' if not offline_mode: apiHost = get_api_host_until_available() net = NetController(config.get('client.public.port', 59497), apiServerIP=apiHost) shared_state.add(net) shared_state.get(onionrstatistics.tor.TorStats) security_level = config.get('general.security_level', 1) use_existing_tor = config.get('tor.use_existing_tor', False) if not offline_mode: # we need to setup tor for use _setup_online_mode(use_existing_tor, net, security_level) _show_info_messages() logger.info( "Onionr daemon is running under " + str(os.getpid()), terminal=True) events.event('init', threaded=False) events.event('daemon_start') if config.get('transports.lan', True): if not onionrvalues.IS_QUBES: Thread(target=LANServer(shared_state).start_server, daemon=True).start() LANManager(shared_state).start() else: logger.warn('LAN not supported on Qubes', terminal=True) if config.get('transports.sneakernet', True): Thread(target=sneakernet_import_thread, daemon=True).start() Thread(target=statistics_reporter, args=[shared_state], daemon=True).start() shared_state.get(DeadSimpleKV).put( 'proxyPort', net.socksPort) spawn_client_threads(shared_state) clean_blocks_not_meeting_pow(shared_state) communicator.startCommunicator(shared_state) clean_ephemeral_services() if not offline_mode and not use_existing_tor: net.killTor() else: try: os.remove(filepaths.tor_hs_address_file) except FileNotFoundError: pass better_sleep(5) cleanup.delete_run_files() if security_level >= 2: filenuke.nuke.clean_tree(identifyhome.identify_home())
def daemon(): ''' Starts the Onionr communication daemon ''' if not hastor.has_tor(): logger.error("Tor is not present in system path or Onionr directory", terminal=True) cleanup.delete_run_files() sys.exit(1) # remove runcheck if it exists if os.path.isfile(filepaths.run_check_file): logger.debug( 'Runcheck file found on daemon start, deleting in advance.') os.remove(filepaths.run_check_file) # Create shared objects shared_state = toomanyobjs.TooMany() Thread(target=shared_state.get(apiservers.ClientAPI).start, daemon=True, name='client HTTP API').start() Thread(target=shared_state.get(apiservers.PublicAPI).start, daemon=True, name='public HTTP API').start() # Init run time tester (ensures Onionr is running right, for testing purposes) shared_state.get(runtests.OnionrRunTestManager) shared_state.get(serializeddata.SerializedData) shared_state.share_object() # share the parent object to the threads apiHost = '' while apiHost == '': try: with open(filepaths.public_API_host_file, 'r') as hostFile: apiHost = hostFile.read() except FileNotFoundError: pass time.sleep(0.5) logger.raw('', terminal=True) # print nice header thing :) if config.get('general.display_header', True): logoheader.header() version.version(verbosity=5, function=logger.info) logger.debug('Python version %s' % platform.python_version()) if onionrvalues.DEVELOPMENT_MODE: logger.warn('Development mode enabled', timestamp=False, terminal=True) net = NetController(config.get('client.public.port', 59497), apiServerIP=apiHost) shared_state.add(net) logger.info('Tor is starting...', terminal=True) if not net.startTor(): localcommand.local_command('shutdown') cleanup.delete_run_files() sys.exit(1) if len(net.myID) > 0 and config.get('general.security_level', 1) == 0: logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID)) else: logger.debug('.onion service disabled') logger.info( 'Using public key: %s' % (logger.colors.underline + getourkeypair.get_keypair()[0][:52])) try: time.sleep(1) except KeyboardInterrupt: pass events.event('init', threaded=False) events.event('daemon_start') communicator.startCommunicator(shared_state) localcommand.local_command('shutdown') net.killTor() try: time.sleep( 5 ) # Time to allow threads to finish, if not any "daemon" threads will be slaughtered http://docs.python.org/library/threading.html#threading.Thread.daemon except KeyboardInterrupt: pass cleanup.delete_run_files()
def daemon(): """Start Onionr's primary threads for communicator, API server, node, and LAN.""" # Determine if Onionr is in offline mode. # When offline, Onionr can only use LAN and disk transport offline_mode = config.get('general.offline_mode', False) if not hastor.has_tor(): offline_mode = True logger.error("Tor is not present in system path or Onionr directory", terminal=True) # remove runcheck if it exists if os.path.isfile(filepaths.run_check_file): logger.debug('Runcheck file found on daemon start, deleting.') os.remove(filepaths.run_check_file) # Create shared objects shared_state = toomanyobjs.TooMany() # Add DeadSimpleKV for quasi-global variables (ephemeral key-value) shared_state.get(DeadSimpleKV) # Initialize the quasi-global variables setup_kv(shared_state.get(DeadSimpleKV)) spawn_client_threads(shared_state) shared_state.get(daemoneventsapi.DaemonEventsBP) Thread(target=shared_state.get(apiservers.ClientAPI).start, daemon=True, name='client HTTP API').start() if not offline_mode: Thread(target=shared_state.get(apiservers.PublicAPI).start, daemon=True, name='public HTTP API').start() # Init run time tester # (ensures Onionr is running right, for testing purposes) # Run time tests are not normally run shared_state.get(runtests.OnionrRunTestManager) # Create singleton shared_state.get(serializeddata.SerializedData) shared_state.share_object() # share the parent object to the threads show_logo() # since we randomize loopback API server hostname to protect against attacks, # we have to wait for it to become set apiHost = '' if not offline_mode: apiHost = get_api_host_until_available() net = NetController(config.get('client.public.port', 59497), apiServerIP=apiHost) shared_state.add(net) shared_state.get(onionrstatistics.tor.TorStats) security_level = config.get('general.security_level', 1) use_existing_tor = config.get('tor.use_existing_tor', False) if not offline_mode: # we need to setup tor for use _setup_online_mode(use_existing_tor, net, security_level) _show_info_messages() events.event('init', threaded=False) events.event('daemon_start') if config.get('transports.lan', True): Thread(target=LANServer(shared_state).start_server, daemon=True).start() LANManager(shared_state).start() if config.get('transports.sneakernet', True): Thread(target=sneakernet_import_thread, daemon=True).start() Thread(target=statistics_reporter, args=[shared_state], daemon=True).start() communicator.startCommunicator(shared_state) clean_ephemeral_services() if not offline_mode and not use_existing_tor: net.killTor() else: try: os.remove(filepaths.tor_hs_address_file) except FileNotFoundError: pass better_sleep(5) cleanup.delete_run_files() if security_level >= 2: filenuke.nuke.clean_tree(identifyhome.identify_home())