Ejemplo n.º 1
0
    def test_lan_learn(self):
        if onionrvalues.IS_QUBES:
            logger.info('Cannot run LAN tests on Qubes')
            return
        test_ip = '192.168.1.30'
        def multicast():
            port = 1349
            MULTICAST_TTL = 3
            ips = '-'.join([test_ip]) + f'-{port}'

            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
            sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
            sock.sendto(f"onionr-{ips}".encode('utf-8'), (MCAST_GRP, MCAST_PORT))
            bettersleep.better_sleep(1)
            try:
                sock.shutdown(SHUT_RDWR)
            except OSError:
                pass
            sock.close()
        test_list = [test_ip]

        Thread(target=learn_services, daemon=True).start()
        bettersleep.better_sleep(3)
        multicast()
        self.assertIn(test_ip, test_list)
Ejemplo n.º 2
0
 def test_block_list(self):
     block_list = BlockList()
     self.assertEqual(len(block_list.get()), 0)
     bl = insert('test')
     bettersleep.better_sleep(0.8)
     self.assertIn(bl, block_list.get())
     bl2 = insert('test2')
     bettersleep.better_sleep(0.8)
     self.assertIn(bl2, block_list.get())
     self.assertIn(bl, block_list.get())
Ejemplo n.º 3
0
        def multicast():
            port = 1349
            MULTICAST_TTL = 3
            ips = '-'.join([test_ip]) + f'-{port}'

            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
            sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
            sock.sendto(f"onionr-{ips}".encode('utf-8'), (MCAST_GRP, MCAST_PORT))
            bettersleep.better_sleep(1)
            try:
                sock.shutdown(SHUT_RDWR)
            except OSError:
                pass
            sock.close()
Ejemplo n.º 4
0
def advertise_service(specific_ips=None):
    # regarding socket.IP_MULTICAST_TTL
    # ---------------------------------
    # for all packets sent, after three hops on the network the packet will not
    # be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
    MULTICAST_TTL = 3

    ips = best_ip

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
    while True:
        sock.sendto(f"onionr-{ips}".encode('utf-8'), (MCAST_GRP, MCAST_PORT))
        better_sleep(ANNOUNCE_LOOP_SLEEP)
Ejemplo n.º 5
0
    def test_lan_broadcast(self):
        test_ip = '192.168.1.30'
        if onionrvalues.IS_QUBES:
            logger.info('Cannot run LAN tests on Qubes')
            return

        def multicast():
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                 socket.IPPROTO_UDP)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            if IS_ALL_GROUPS:
                # on this port, receives ALL multicast groups
                sock.bind(('', MCAST_PORT))
            else:
                # on this port, listen ONLY to MCAST_GRP
                sock.bind((MCAST_GRP, MCAST_PORT))
            mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP),
                               socket.INADDR_ANY)

            sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

            service_ips = sock.recv(200).decode('utf-8')
            if not service_ips: raise ValueError

            self.assertIn('onionr', service_ips)
            self.assertEqual(
                len(
                    set(
                        set(service_ips.replace('onionr', '').split('-'))
                        ^ set(lan_ips))), 1)
            for x in set(
                    set(service_ips.replace('onionr', '').split('-'))
                    ^ set(lan_ips)):
                self.assertEqual('', x)

            try:
                sock.shutdown(SHUT_RDWR)
            except OSError:
                pass
            sock.close()

        test_list = [test_ip]

        Thread(target=advertise_service, daemon=True).start()
        bettersleep.better_sleep(1)
        multicast()
Ejemplo n.º 6
0
def statistics_reporter(shared_state):
    server = config.get('statistics.server', '')
    if not config.get('statistics.i_dont_want_privacy', False) or \
            not server:
        return

    def compile_data():
        return {
            'time': epoch.get_epoch(),
            'adders': get_transports(),
            'peers':
            shared_state.get_by_string('DeadSimpleKV').get('onlinePeers')
        }

    while True:
        better_sleep(5)
        data = compile_data()
        basicrequests.do_post_request(f'http://{server}/sendstats/' +
                                      get_transports()[0],
                                      data=json.dumps(data))
Ejemplo n.º 7
0
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())
Ejemplo n.º 8
0
 def _show_lan_bind(port):
     better_sleep(1)
     if self.server.started and port == self.server.server_port:
         logger.info(f'Serving to LAN on {self.host}:{self.port}',
                     terminal=True)
Ejemplo n.º 9
0
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())