def run(self):
     """
     Copies the firmware image onto the Router, proves if the firmware is in the right file(/tmp/<firmware_name>.bin)
     and does a Sysupgrade.
     """
     network_ctrl = NetworkCtrl(self.router)
     try:
         network_ctrl.connect_with_remote_system()
     except Exception as e:
         logging.warning("%s[-] Couldn't sysupgrade the Router(" + str(self.router.id) + ")",
                         LoggerSetup.get_log_deep(2))
         logging.warning(str(e))
         return
     network_ctrl.remote_system_wget(self.router.firmware.file, '/tmp/', self.web_server_ip)
     # sysupgrade -n <firmware_name> // -n verwirft die letzte firmware
     arg = '-n' if self.n else ''
     if not self.debug:
         logging.debug("%sSysupgrade (this will force a TimeoutError)...", LoggerSetup.get_log_deep(2))
         try:
             network_ctrl.send_command('sysupgrade ' + arg + ' ' + '/tmp/' + self.router.firmware.name)
         except TimeoutError:
             try:
                 Dhclient.update_ip(self.router.vlan_iface_name)
                 self._success_handling()
             except FileExistsError:
                 self._success_handling()
                 pass
             except Exception:
                 self._execption_hanling()
         except Exception:
             self._execption_hanling()
     network_ctrl.exit()
Esempio n. 2
0
    def send_data(self, local_file: str, remote_file: str):
        """
        Sends Data via sftp to the RemoteSystem

        :param local_file: Path to the local file
        :param remote_file: Path on the Router, where the file should be saved
        """
        try:
            # TODO: If sftp is installed on the Router
            '''
            sftp = self.ssh.open_sftp()
            sftp.put(local_file, remote_file)
            sftp.close()
            '''
            command = 'sshpass  -p' + str(self.remote_system.usr_password) + ' scp ' + local_file + ' ' + \
                      str(self.remote_system.usr_name) + '@' + str(self.remote_system.ip) + ':' + remote_file
            os.system(command)

            # TODO: Paramiko_scp have to installed
            '''
            scp = SCPClient(self.ssh.get_transport())
            scp.put(local_file, remote_file)
            '''
            logging.debug("%s[+] Sent data '" + local_file + "' to RemoteSystem '" +
                          str(self.remote_system.usr_name) + "@" + str(self.remote_system.ip) +
                          ":" + remote_file + "'", LoggerSetup.get_log_deep(2))
        except Exception as e:
            logging.error("%s[-] Couldn't send '" + local_file + "' to RemoteSystem '" +
                          str(self.remote_system.usr_name) + "@" + str(self.remote_system.ip) + ":" + remote_file + "'",
                          LoggerSetup.get_log_deep(2))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))
    def test_meshing(self):
        """
        Test:
            1. Router is in normal-mode
            2. Mesh-connections exist
            3. All known Routers that are in normal-mode are connected with the tested Router
        """
        logging.debug("%sTest: Correctness of the Mesh-Connections",
                      LoggerSetup.get_log_deep(1))
        assert self.remote_system.mode == Mode.normal
        logging.debug("%s[" + u"\u2714" + "] Correct Mode",
                      LoggerSetup.get_log_deep(2))
        bat_originators = self.remote_system.bat_originators
        self.assertTrue(
            len(bat_originators) > 0, "No connected Mesh-Nodes exist")
        logging.debug("%s[" + u"\u2714" + "] Connected Mesh-Nodes exist",
                      LoggerSetup.get_log_deep(2))

        my_bat__originators = self.remote_system.bat_originators
        my_bat__originators_macs = [
            originator.mac for originator in my_bat__originators
        ]

        for router in self.all_routers:
            if router.id == self.remote_system.id or router.mode == Mode.configuration:
                continue
            known_router_mac = router.network_interfaces["mesh0"].mac
            cnt = my_bat__originators_macs.count(known_router_mac)
            self.assertTrue(
                cnt >= 1,
                "Not connected with  known Router(" + str(router.id) + ")")
            logging.debug(
                "%s[" + u"\u2713" + "] Connected with known Router(" +
                str(router.id) + ")", LoggerSetup.get_log_deep(2))
    def test_meshing(self):
        """
        Test:
            1. Router is in normal-mode
            2. Mesh-connections exist
            3. All known Routers that are in normal-mode are connected with the tested Router
        """
        logging.debug("%sTest: Correctness of the Mesh-Connections", LoggerSetup.get_log_deep(1))
        assert self.remote_system.mode == Mode.normal
        logging.debug("%s[" + u"\u2714" + "] Correct Mode", LoggerSetup.get_log_deep(2))
        bat_originators = self.remote_system.bat_originators
        self.assertTrue(len(bat_originators) > 0, "No connected Mesh-Nodes exist")
        logging.debug("%s[" + u"\u2714" + "] Connected Mesh-Nodes exist", LoggerSetup.get_log_deep(2))

        my_bat__originators = self.remote_system.bat_originators
        my_bat__originators_macs = [originator.mac for originator in my_bat__originators]

        for router in self.all_routers:
            if router.id == self.remote_system.id or router.mode == Mode.configuration:
                continue
            known_router_mac = router.network_interfaces["mesh0"].mac
            cnt = my_bat__originators_macs.count(known_router_mac)
            self.assertTrue(cnt >= 1, "Not connected with  known Router(" + str(router.id) + ")")
            logging.debug("%s[" + u"\u2713" + "] Connected with known Router(" + str(router.id) + ")",
                          LoggerSetup.get_log_deep(2))
Esempio n. 5
0
    def _execute_test(cls, test: FirmwareTestClass, router: Router, routers: List[Router]) -> TestResult:
        if not isinstance(router, Router):
            raise ValueError("Chosen Router is not a real Router...")
        # proofed: this method runs in other process as the server
        setproctitle(str(router.id) + " - " + str(test))
        logging.debug("%sExecute test " + str(test) + " on Router(" + str(router.id) + ")", LoggerSetup.get_log_deep(2))

        test_suite = defaultTestLoader.loadTestsFromTestCase(test)

        # prepare all test cases
        for test_case in test_suite:
            logging.debug("%sTestCase " + str(test_case), LoggerSetup.get_log_deep(4))
            test_case.prepare(router, routers)

        result = TestResult()

        cls.__setns(router)
        try:

            result = test_suite.run(result)
        except Exception as e:
            logging.error("%sTestCase execution raised an exception", LoggerSetup.get_log_deep(3))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))

            test_obj = test()
            result.addError(test_obj, sys.exc_info())  # add the reason of the exception
        finally:

            # I'm sry for this dirty hack, but if you don't do this you get an
            # "TypeError: cannot serialize '_io.TextIOWrapper' object" because sys.stdout is not serializeable...
            result._original_stdout = None
            result._original_stderr = None

            logging.debug("%sResult from test " + str(result), LoggerSetup.get_log_deep(3))
            return result
Esempio n. 6
0
    def delete_interface(self, close_ipdb: bool = False):
        """
        Removes the virtual interface

        :param close_ipdb: If also the IPDB should be closed.
        """
        logging.debug("%sDelete VLAN Interface ...",
                      LoggerSetup.get_log_deep(2))
        try:
            self.ipdb.interfaces[self.vlan_iface_name].remove().commit()
            if close_ipdb:
                self.ipdb.release()
            logging.debug(
                "%s[+] Interface(" + self.vlan_iface_name +
                ") successfully deleted", LoggerSetup.get_log_deep(3))
        except KeyError:
            logging.debug(
                "%s[+] Interface(" + self.vlan_iface_name +
                ") is already deleted", LoggerSetup.get_log_deep(3))
            return
        except Exception as e:
            logging.debug(
                "%s[-] Interface(" + self.vlan_iface_name +
                ") couldn't be deleted. Try 'ip link delete <vlan_name>'",
                LoggerSetup.get_log_deep(3))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))
Esempio n. 7
0
 def test_connection(self):
     """
     Test:
         1. Google or FreiFunk is reachable via a Ping
     """
     logging.debug("%sTest: Existence of an Internet-Connection",
                   LoggerSetup.get_log_deep(1))
     assert self.remote_system.mode == Mode.normal
     logging.debug("%s[" + u"\u2714" + "] Correct Mode",
                   LoggerSetup.get_log_deep(2))
     network_ctrl = NetworkCtrl(self.remote_system)
     network_ctrl.connect_with_remote_system()
     ping_result1 = network_ctrl.send_command(
         "ping -c 5 8.8.8.8 | grep received")
     ping_result2 = network_ctrl.send_command(
         "ping -c 5 freifunk.net | grep received")
     self.assertTrue(
         self._ping_successful(ping_result1[0])
         or self._ping_successful(ping_result2[0]),
         "No Internet-Connection")
     logging.debug(
         "%s[" + u"\u2714" +
         "] At least one Ping was successful => An Internet-Connection exist",
         LoggerSetup.get_log_deep(2))
     network_ctrl.exit()
Esempio n. 8
0
    def create_interface(self):
        """
         Creates a virtual interface on a existing interface (like eth0)
        """
        logging.debug("%sCreate VLAN Interface ...", LoggerSetup.get_log_deep(2))
        try:
            # Get the real link interface
            link_iface = self.ipdb.interfaces[self.link_iface_name]

            # Create a Vlan
            iface = self.ipdb.create(kind="vlan", ifname=self.vlan_iface_name, link=link_iface,
                                     vlan_id=self.vlan_iface_id).commit()
            # Try to assign an IP via dhclient
            # IP 169.254.235.157/16 is returned when static is expected
            if (not self._wait_for_ip_assignment()) or (self.ipdb_get_ip("169.254.235.157") == ""):
                # Otherwise add a static IP
                iface.add_ip(self._get_matching_ip(str(self.remote_system.ip)), self.remote_system.ip_mask).commit()
            iface.mtu = 1400

            logging.debug("%s[+] " + self.vlan_iface_name + " created with: Link=" + self.link_iface_name +
                          ", VLAN_ID=" + str(self.vlan_iface_id) + ", IP=" + self.ipdb_get_ip(),
                          LoggerSetup.get_log_deep(3))
        except Exception as e:
            logging.debug("%s[-] " + self.vlan_iface_name + " couldn't be created", LoggerSetup.get_log_deep(3))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))
 def run(self):
     """
     Copies the firmware image onto the Router, proves if the firmware is in the right file(/tmp/<firmware_name>.bin)
     and does a Sysupgrade.
     :return:
     """
     network_ctrl = NetworkCtrl(self.router)
     try:
         network_ctrl.connect_with_remote_system()
     except Exception as e:
         logging.warning("[-] Couldn't sysupgrade the Router(" + str(self.router.id) + ")")
         logging.warning(str(e))
         return
     network_ctrl.remote_system_wget(self.router.firmware.file, '/tmp/', self.web_server_ip)
     # sysupgrade -n <firmware_name> // -n verwirft die letzte firmware
     arg = '-n' if self.n else ''
     if not self.debug:
         logging.debug("sysupgrade ...")
         try:
             network_ctrl.send_command('sysupgrade ' + arg + ' ' + '/tmp/' + self.router.firmware.name)
         except TimeoutError:
             logging.info("%s[+] Router was set into normal mode", LoggerSetup.get_log_deep(2))
             self.router.mode = Mode.configuration
             if Dhclient.update_ip(self.router.vlan_iface_name) == 1:
                 self.router.mode = Mode.unknown
                 logging.error("%s[-] Something went wrong. Use command 'online -r " + str(self.router.id) + "'",
                               LoggerSetup.get_log_deep(2))
         except Exception as e:
             self.router.mode = Mode.unknown
             logging.error("[-] Something went wrong. Use command 'online -r " + str(self.router.id) + "'")
             logging.error(str(e))
     network_ctrl.exit()
Esempio n. 10
0
    def send_command(self, command: str, timeout: int = 90) -> List:
        """
        Sends the given command via SSH to the RemoteSystem.

        :param command: Like 'ping 8.8.8.8'
        :param timeout: Timeout in seconds
        :return: The output of the command inside a list. Each output-line is a list-element
        :exception TimeoutError: If the timeout-limit is reached
        :exception Exception: If sending the command fails
        """
        try:
            stdin, stdout, stderr = self.ssh.exec_command(command,
                                                          timeout=timeout)
            output = stdout.readlines()
            logging.debug(
                "%s[+] Sent the command (" + command + ") to the RemoteSystem",
                LoggerSetup.get_log_deep(3))
            return output
        except (PipeTimeout, socket.timeout):
            logging.warning("%s[!] Timeout: No response from RemoteSystem",
                            LoggerSetup.get_log_deep(3))
            raise TimeoutError
        except Exception as e:
            logging.error("%s[-] Couldn't send the command (" + command + ")",
                          LoggerSetup.get_log_deep(3))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))
            raise e
Esempio n. 11
0
    def __init__(self, ipdb: IPDB, nsp_name: str):
        """
        Creats a namespace for a specific vlan_iface

        :param nsp_name:
        :param ipdb: IPDB is a transactional database, containing records, representing network stack objects.
                    Any change in the database is not reflected immidiately in OS, but waits until commit() is called.
        """
        logging.debug("%sCreate Namespace ...", LoggerSetup.get_log_deep(2))
        self.ipdb = ipdb if ipdb else IPDB()
        self.ipdb_netns = None
        self.nsp_name = nsp_name
        try:
            self.ipdb_netns = IPDB(nl=NetNS(nsp_name))
            self.ipdb_netns.interfaces['lo'].up().commit()
            logging.debug(
                "%s[+] Namespace(" + nsp_name + ") successfully created",
                LoggerSetup.get_log_deep(3))
            # self.encapsulate_interface()
        except Exception as e:
            logging.debug("%s[-] Couldn't create Namespace(" + nsp_name + ")",
                          LoggerSetup.get_log_deep(3))
            for tb in traceback.format_tb(sys.exc_info()[2]):
                logging.error("%s" + tb, LoggerSetup.get_log_deep(3))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))
            self.remove()
    def _wca_setup_wizard(self, config):
        """
        Starts the WebConfigurationAssist and
        sets the values provided by the wizard-mode (in the WebConfiguration).

        :param config: {node_name, mesh_vpn, limit_bandwidth, show_location, latitude, longitude, altitude, contact,...}
        """
        try:
            # remote_sytem has to be a router object
            wca = WebConfigurationAssist(config, self.router)
            wca.setup_wizard()
            wca.exit()
        except Exception as e:
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))
            raise e
        # The Router should reboot
        logging.info("%sWait until Router rebooted (90sec) ...", LoggerSetup.get_log_deep(2))
        time.sleep(90)

        try:
            Dhclient.update_ip(self.router.vlan_iface_name)
            self._success_handling()
        except FileExistsError:
            self._success_handling()
        except Exception:
            self._exception_handling()
Esempio n. 13
0
    def run(self):
        """
        Runs new thread and gets the information from the Router via ssh
        """
        logging.info(
            "%sUpdate the Infos of the Router(" + str(self.router.id) +
            ") ...", LoggerSetup.get_log_deep(1))
        try:
            self.network_ctrl.connect_with_remote_system()

            # Model
            self.router.model = self._get_router_model()
            # MAC
            self.router.mac = self._get_router_mac()
            # SSID
            self.router.ssid = self._get_router_ssid()
            # NetworkInterfaces
            self.router.interfaces = self._get_router_network_interfaces()
            # CPUProcesses
            self.router.cpu_processes = self._get_router_cpu_process()
            # RAM
            self.router.ram = self._get_router_mem_ram()
            # Sockets
            self.router.sockets = self._get_router_sockets()
            logging.debug("%s[+] Infos updated", LoggerSetup.get_log_deep(2))
        except Exception as e:
            logging.warning("%s[-] Couldn't update all Infos",
                            LoggerSetup.get_log_deep(2))
            logging.error(str(e))
            for tb in traceback.format_tb(sys.exc_info()[2]):
                logging.error("%s" + tb, LoggerSetup.get_log_deep(3))
        finally:
            self.network_ctrl.exit()
Esempio n. 14
0
    def _wait_for_job_done(cls, job: RemoteSystemJob, remote_sys: RemoteSystem, done_event: DoneEvent) -> None:
        """
        Wait 2 minutes until the job is done.
        Handles the result from the job with the job.prepare(data) method.
        Triggers the next job/test.

        :param job: job to execute
        :param remote_sys: the RemoteSystem
        :param done_event: event which will be triggered when the task is finished
        """
        async_result = cls._task_pool.apply_async(func=cls._execute_job, args=(job, remote_sys, cls._routers))
        try:
            result = async_result.get(120)  # wait 2 minutes or raise an TimeoutError
            logging.debug("%sJob done " + str(job), LoggerSetup.get_log_deep(1))
            logging.debug("%sAt Router(" + str(remote_sys.id) + ")", LoggerSetup.get_log_deep(2))
            job.post_process(result, cls)

        except Exception as e:
                logging.error("%sTask raised an exception: " + str(e), LoggerSetup.get_log_deep(1))
                cls._task_errors.append((remote_sys.id, sys.exc_info()))
        finally:
            cls.set_running_task(remote_sys, None)
            # start next test in the queue
            done_event.set()
            cls.__start_task(remote_sys, None)
Esempio n. 15
0
    def send_data(self, local_file: str, remote_file: str):
        """
        Sends Data via sftp to the RemoteSystem

        :param local_file: Path to the local file
        :param remote_file: Path on the Router, where the file should be saved
        """
        try:
            # TODO: If sftp is installed on the Router
            '''
            sftp = self.ssh.open_sftp()
            sftp.put(local_file, remote_file)
            sftp.close()
            '''
            command = 'sshpass  -p' + str(self.remote_system.usr_password) + ' scp ' + local_file + ' ' + \
                      str(self.remote_system.usr_name) + '@' + str(self.remote_system.ip) + ':' + remote_file
            os.system(command)

            # TODO: Paramiko_scp have to installed
            '''
            scp = SCPClient(self.ssh.get_transport())
            scp.put(local_file, remote_file)
            '''
            logging.debug(
                "%s[+] Sent data '" + local_file + "' to RemoteSystem '" +
                str(self.remote_system.usr_name) + "@" +
                str(self.remote_system.ip) + ":" + remote_file + "'",
                LoggerSetup.get_log_deep(2))
        except Exception as e:
            logging.error(
                "%s[-] Couldn't send '" + local_file + "' to RemoteSystem '" +
                str(self.remote_system.usr_name) + "@" +
                str(self.remote_system.ip) + ":" + remote_file + "'",
                LoggerSetup.get_log_deep(2))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))
Esempio n. 16
0
    def _wait_for_job_done(cls, job: RemoteSystemJob, remote_sys: RemoteSystem,
                           done_event: DoneEvent) -> None:
        """
        Wait 5 minutes until the job is done.
        Handles the result from the job with the job.prepare(data) method.
        Triggers the next job/test.

        :param job: job to execute
        :param remote_sys: the RemoteSystem
        """
        async_result = cls._task_pool.apply_async(func=cls._execute_job,
                                                  args=(job, remote_sys))
        result = async_result.get(
            300)  # wait 5 minutes or raise an TimeoutError
        logging.debug("%sJob done " + str(job), LoggerSetup.get_log_deep(1))
        logging.debug("%sAt Router(" + str(remote_sys.id) + ")",
                      LoggerSetup.get_log_deep(2))
        try:
            exception = None  # task.exception() # TODO #105
            if exception is not None:
                logging.error("%sTask raised an exception: " + str(exception),
                              LoggerSetup.get_log_deep(1))
            else:
                job.post_process(result, cls)

        finally:
            cls.set_running_task(remote_sys, None)
            # start next test in the queue
            done_event.set()
            cls.__start_task(remote_sys, None)
Esempio n. 17
0
    def delete_interface(self, close_ipdb: bool = False):
        """
        Removes the virtual interface.

        :param close_ipdb: If also the IPDB should be closed
        """
        logging.debug("%sDelete VLAN Interface ...", LoggerSetup.get_log_deep(2))
        try:
            self.ipdb.interfaces[self.vlan_iface_name].remove().commit()
            if close_ipdb:
                self.ipdb.release()
            logging.debug(
                "%s[+] Interface(" + self.vlan_iface_name + ") successfully deleted", LoggerSetup.get_log_deep(3)
            )
        except KeyError:
            logging.debug(
                "%s[+] Interface(" + self.vlan_iface_name + ") is already deleted", LoggerSetup.get_log_deep(3)
            )
            return
        except Exception as e:
            logging.error(
                "%s[-] Interface(" + self.vlan_iface_name + ") couldn't be deleted. Try 'ip link delete <vlan_name>'",
                LoggerSetup.get_log_deep(3),
            )
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))
Esempio n. 18
0
    def remote_system_wget(self, file: str, remote_path: str,
                           web_server_ip: str):
        """
        The RemoteSystem downloads the file from the PI and stores it at remote_file.
        Therefore this function starts a webserver in a new thread.

        :param file: Like '/root/TestFramework/firmware/.../<firmware>.bin'
        :param remote_path: Like '/tmp/'
        :param web_server_ip: IP-address of the PI
        """
        webserver = WebServer()
        try:
            logging.debug(
                "%sForce the Router to download Data from the own WebServer ...",
                LoggerSetup.get_log_deep(2))
            webserver.start()
            # Proves first if file already exists
            self.send_command('test -f /' + remote_path + '/' +
                              file.split('/')[-1] + ' || wget http://' +
                              web_server_ip + ':' +
                              str(WebServer.PORT_WEBSERVER) +
                              file.replace(WebServer.BASE_DIR, '') + ' -P ' +
                              remote_path)
        except Exception as e:
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))
        finally:
            webserver.join()
Esempio n. 19
0
    def set_new_ip(self,
                   dhcp: bool,
                   iface_name: str,
                   new_ip: str = None,
                   new_ip_mask: int = None):
        """
        Sets the IP either given by 'new_ip'-parameter or via dhclient.

        :param dhcp: should a dhclient be used?
        :param iface_name:
        :param new_ip:
        :param new_ip_mask:
        :return: the new IP with the format ip/mask
        """
        iface_ip = None
        if dhcp:
            try:
                self._wait_for_ip_assignment(iface_name)
                iface_ip = self._get_ip(iface_name)
                logging.debug(
                    "%s[+] New IP " + iface_ip + " for " + iface_name +
                    " by dhcp", LoggerSetup.get_log_deep(2))
            except TimeoutError:
                logging.debug(
                    "%s[-] Couldn't get a new IP for " + iface_name +
                    " by dhcp", LoggerSetup.get_log_deep(2))
        else:
            iface_ip = new_ip + "/" + str(new_ip_mask)
            logging.debug("%s[+] New IP " + iface_ip + " for " + iface_name,
                          LoggerSetup.get_log_deep(2))
        return iface_ip
 def test_availability(self):
     """
     Test:
         1. Router is in configuration-mode
         2. All necessary network-interfaces exist
     """
     necessary_network_interfaces = ["br-setup", "eth1", "lo"]
     logging.debug(
         "%sTest: Following Network-Interfaces have to exist in config-mode: "
         + str(necessary_network_interfaces), LoggerSetup.get_log_deep(1))
     assert self.remote_system.mode == Mode.configuration
     logging.debug("%s[" + u"\u2714" + "] Correct Mode",
                   LoggerSetup.get_log_deep(2))
     existing_network_interfaces = self.remote_system.network_interfaces.values(
     )
     existing_network_interfaces = [
         interface.name for interface in existing_network_interfaces
     ]
     common_network_interfaces = list(
         set(necessary_network_interfaces)
         & set(existing_network_interfaces))
     self.assertTrue(
         len(common_network_interfaces) >=
         len(necessary_network_interfaces),
         "Some Network-Interfaces are missing")
     logging.debug(
         "%s[" + u"\u2714" + "] All specified Network-Interfaces exist",
         LoggerSetup.get_log_deep(2))
Esempio n. 21
0
    def create_interface(self):
        """
        Creates a 'veth'-interface.
        """
        logging.debug("%sCreate Veth Interface ...",
                      LoggerSetup.get_log_deep(2))
        try:
            self.ipdb.create(kind='veth',
                             ifname=self.veth_iface_name1,
                             peer=self.veth_iface_name2).commit()
            self.ipdb.interfaces[self.veth_iface_name1].up().commit()
            # veth0
            if self.veth_iface_ip1:
                iface = self.ipdb.interfaces[self.veth_iface_name1]
                iface.add_ip(self.veth_iface_ip1,
                             self.veth_iface_ip_mask1).commit()
            # veth1
            if self.veth_iface_ip2:
                iface = self.ipdb.interfaces[self.veth_iface_name2]
                iface.add_ip(self.veth_iface_ip2,
                             self.veth_iface_ip_mask2).commit()

            logging.debug(
                "%s[+] " + self.veth_iface_name1 +
                " <=> " + self.veth_iface_name2 + " created",
                LoggerSetup.get_log_deep(3))
        except Exception as e:
            logging.debug(
                "%s[-] " + self.veth_iface_name1 + self.veth_iface_name2 +
                " couldn't be created", LoggerSetup.get_log_deep(3))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))
Esempio n. 22
0
    def create_interface(self):
        """
         Creates a virtual interface on an existing interface (like eth0).
        """
        logging.debug("%sCreate VLAN Interface ...", LoggerSetup.get_log_deep(2))
        try:
            # Get the real link interface
            link_iface = self.ipdb.interfaces[self.link_iface_name]

            # Create a Vlan
            iface = self.ipdb.create(kind="vlan", ifname=self.vlan_iface_name, link=link_iface,
                                     vlan_id=self.vlan_iface_id).commit()
            # Try to assign an IP via dhclient
            # IP 169.254.235.157/16 is returned when static is expected
            if (not self._wait_for_ip_assignment()) or (self.ipdb_get_ip("169.254.235.157") == ""):
                # Otherwise add a static IP
                iface.add_ip(self._get_matching_ip(str(self.remote_system.ip)), self.remote_system.ip_mask).commit()
            iface.mtu = 1400

            logging.debug("%s[+] " + self.vlan_iface_name + " created with: Link=" + self.link_iface_name +
                          ", VLAN_ID=" + str(self.vlan_iface_id) + ", IP=" + self.ipdb_get_ip("169.254.235.157"),
                          LoggerSetup.get_log_deep(3))
        except Exception as e:
            logging.error("%s[-] " + self.vlan_iface_name + " couldn't be created", LoggerSetup.get_log_deep(3))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))
    def _wca_setup_wizard(self, config):
        """
        Starts the WebConfigurationAssist and
        sets the values provided by the wizard-mode (in the WebConfiguration).

        :param config: {node_name, mesh_vpn, limit_bandwidth, show_location, latitude, longitude, altitude, contact,...}
        """
        try:
            # remote_sytem has to be a router object
            wca = WebConfigurationAssist(config, self.router)
            wca.setup_wizard()
            wca.exit()
        except Exception as e:
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))
            raise e
        # The Router should reboot
        logging.info("%sWait until Router rebooted (90sec) ...",
                     LoggerSetup.get_log_deep(2))
        time.sleep(90)

        try:
            Dhclient.update_ip(self.router.vlan_iface_name)
            self._success_handling()
        except FileExistsError:
            self._success_handling()
        except Exception:
            self._exception_handling()
Esempio n. 24
0
    def import_firmwares(self, release_model: str):
        """
        Imports the stored Firmwares, so the firmware_handler can use them.
        :param release_model: stable, beta, experimental
        """
        path = FIRMWARE_PATH + '/' + release_model + '/' + self.UPDATE_TYPE + '/'
        logging.debug("%sImport Firmwares from '" + path + "'", LoggerSetup.get_log_deep(2))
        count = 0

        try:
            files = os.listdir(path)
        except Exception:
            logging.debug("%sNo Firmwares available for import at path '" + path + "'", LoggerSetup.get_log_deep(3))
            return

        for firmware_name in files:
            try:
                freifunk_verein = firmware_name.split('-')[1]
                firmware_version = firmware_name.split('-')[2]
                file = path + firmware_name
                url = self.url + '/' + release_model + '/' + self.UPDATE_TYPE + '/' + firmware_name
                self.firmwares.append(Firmware(firmware_name, firmware_version, freifunk_verein,
                                               release_model, file, url))
                count += 1
            except Exception:
                logging.warning("%s[-] Couldn't import " + firmware_name, LoggerSetup.get_log_deep(3))
                continue
        logging.debug("%s" + str(count) + " Firmwares imported", LoggerSetup.get_log_deep(3))
Esempio n. 25
0
    def run(self):
        """
        Runs new thread and gets the information from the Router via ssh.
        """
        logging.info("%sUpdate the Infos of the Router(" + str(self.router.id) + ") ...", LoggerSetup.get_log_deep(1))
        try:
            self.network_ctrl.connect_with_remote_system()

            # Model
            self.router.model = self._get_router_model()
            # MAC
            self.router.mac = self._get_router_mac()
            # NetworkInterfaces
            self.router.network_interfaces = self._get_router_network_interfaces()
            # CPUProcesses
            self.router.cpu_processes = self._get_router_cpu_process()
            # RAM
            self.router.ram = self._get_router_mem_ram()
            # Sockets
            self.router.sockets = self._get_router_sockets()
            # UCI
            self.router.uci = self._get_router_uci()
            # Bat Originators
            self.router.bat_originators = self._get_bat_originator()
            logging.info("%s[+] Infos updated", LoggerSetup.get_log_deep(2))
        except Exception as e:
            logging.error("%s[-] Couldn't update all Infos", LoggerSetup.get_log_deep(2))
            logging.error(str(e))
            for tb in traceback.format_tb(sys.exc_info()[2]):
                logging.error("%s" + tb, LoggerSetup.get_log_deep(3))
        finally:
            self.network_ctrl.exit()
Esempio n. 26
0
 def join(self):
     logging.info("%sStop WebServer ...", LoggerSetup.get_log_deep(1))
     time.sleep(2)
     try:
         self.httpd.shutdown()
         logging.debug("%s[+] WebServer successfully stoped", LoggerSetup.get_log_deep(2))
     except Exception as e:
         logging.debug("%s[-] WebServer couldn't stoped", LoggerSetup.get_log_deep(2))
         logging.error("%s" + str(e), LoggerSetup.get_log_deep(1))
Esempio n. 27
0
 def run(self):
     logging.info(
         "%sStart WebServer on port " + str(WebServer.PORT_WEBSERVER) +
         " ...", LoggerSetup.get_log_deep(1))
     try:
         self.httpd.serve_forever()
     except Exception as e:
         logging.debug("%s[-] WebServer couldn't get started",
                       LoggerSetup.get_log_deep(2))
         raise e
 def _success_handling(self):
     """
     Sets the Router in config-mode.
     """
     if self.n:
         logging.info("%s[+]Router was set into config mode", LoggerSetup.get_log_deep(2))
         self.router.mode = Mode.configuration
     else:
         logging.info("%s[+]Router was set into normal mode", LoggerSetup.get_log_deep(2))
         self.router.mode = Mode.normal
Esempio n. 29
0
 def join(self):
     logging.info("%sStop WebServer ...", LoggerSetup.get_log_deep(1))
     time.sleep(2)
     try:
         self.httpd.shutdown()
         logging.debug("%s[+] WebServer successfully stoped",
                       LoggerSetup.get_log_deep(2))
     except Exception as e:
         logging.debug("%s[-] WebServer couldn't stoped",
                       LoggerSetup.get_log_deep(2))
         logging.error("%s" + str(e), LoggerSetup.get_log_deep(1))
 def test_meshing(self):
     """
     Test:
         1. Router is in normal-mode
         2. Mesh-connections exist
     """
     logging.debug("%sTest: Existence of Mesh-Connections", LoggerSetup.get_log_deep(1))
     assert self.remote_system.mode == Mode.normal
     logging.debug("%s[" + u"\u2714" + "] Correct Mode", LoggerSetup.get_log_deep(2))
     bat_originators = self.remote_system.bat_originators
     self.assertTrue(len(bat_originators) > 0, "No connected Mesh-Nodes exist")
     logging.debug("%s[" + u"\u2714" + "] Connected Mesh-Nodes exist", LoggerSetup.get_log_deep(2))
Esempio n. 31
0
 def _success_handling(self):
     """
     Sets the Router in config-mode.
     """
     if self.n:
         logging.info("%s[+]Router was set into config mode",
                      LoggerSetup.get_log_deep(2))
         self.router.mode = Mode.configuration
     else:
         logging.info("%s[+]Router was set into normal mode",
                      LoggerSetup.get_log_deep(2))
         self.router.mode = Mode.normal
Esempio n. 32
0
 def run(self):
     """
     Uses the Dhlcient to get an IP from a given Router and tries to connect to.
     """
     logging.info("%sCheck if Router is online ...", LoggerSetup.get_log_deep(1))
     try:
         Dhclient.update_ip(self.router.vlan_iface_name)
         self._test_connection()
     except FileExistsError:
         self._test_connection()
     except Exception:
         logging.debug("%s[*] Try again in a minute", LoggerSetup.get_log_deep(2))
     return
Esempio n. 33
0
 def _create_path(self, path: str):
     """
     Creates directories if necessary
     :param path:
     """
     try:
         logging.debug("%sCreate path " + path + " ...", LoggerSetup.get_log_deep(3))
         os.makedirs(path)
         logging.debug("%s[+] Path successfully created", LoggerSetup.get_log_deep(4))
     except OSError as exception:
         if exception.errno != errno.EEXIST:
             raise
         logging.debug("%s[+] Path allready exists", LoggerSetup.get_log_deep(4))
    def test_log_level_tab(self):
        """
        Test log level tab
        :return: Test results
        """
        LoggerSetup.setup(10)

        logging.info("%sInfo deep 2", LoggerSetup.get_log_deep(2))
        logging.info("%sInfo deep 3 with - as char", LoggerSetup.get_log_deep(3, '-'))

        self.assertEqual(True, LoggerSetup.is_setup_loaded())

        LoggerSetup.shutdown()
Esempio n. 35
0
    def _create_path(self, path: str):
        """
        Creates directories if necessary.

        :param path: Path where the firmware-image should be stored on the device
        """
        try:
            logging.debug("%sCreate path " + path + " ...", LoggerSetup.get_log_deep(4))
            os.makedirs(path)
            logging.debug("%s[+] Path successfully created", LoggerSetup.get_log_deep(5))
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise e
            logging.debug("%s[+] Path allready exists", LoggerSetup.get_log_deep(5))
Esempio n. 36
0
 def run(self):
     """
     Runs new thread and trys to send a command via ssh to reboot the Router.
     """
     logging.info("%sReboot the Router(" + str(self.router.id) + ") ...", LoggerSetup.get_log_deep(1))
     network_ctrl = NetworkCtrl(self.router)
     try:
         network_ctrl.connect_with_remote_system()
     except Exception as e:
         logging.error("%s[-] Couldn't reboot Router(" + str(self.router.id) + ")", LoggerSetup.get_log_deep(2))
         logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))
         network_ctrl.exit()
         return
     # Reboot Router into configuration-mode
     if self.configmode:
         if self.router.mode == Mode.configuration:
             logging.info("%s[+] Router is already in " + str(Mode.configuration), LoggerSetup.get_log_deep(2))
             network_ctrl.exit()
             return
         try:
             network_ctrl.send_command("uci set 'gluon-setup-mode.@setup_mode[0].enabled=1'")
             network_ctrl.send_command("uci commit")
             network_ctrl.send_command("reboot")
             logging.info("%sWait until Router rebooted (60sec) ...", LoggerSetup.get_log_deep(2))
             time.sleep(60)
             Dhclient.update_ip(self.router.vlan_iface_name)
             self._success_handling()
         except FileExistsError:
             self._success_handling()
             pass
         except Exception as e:
             self._execption_hanling()
     # Reboot Router into normal-mode
     else:
         if self.router.mode == Mode.normal:
             logging.info("%s[+] Router is already in " + str(Mode.normal), LoggerSetup.get_log_deep(2))
             network_ctrl.exit()
             return
         try:
             network_ctrl.send_command("reboot")
             logging.info("%sWait until Router rebooted (90sec) ...", LoggerSetup.get_log_deep(2))
             time.sleep(90)
             Dhclient.update_ip(self.router.vlan_iface_name)
             self._success_handling()
         except FileExistsError:
             self._success_handling()
             pass
         except Exception as e:
             self._execption_hanling()
     network_ctrl.exit()
Esempio n. 37
0
    def test_log_level_tab(self):
        """
        Test log level tab
        :return: Test results
        """
        LoggerSetup.setup(10)

        logging.info("%sInfo deep 2", LoggerSetup.get_log_deep(2))
        logging.info("%sInfo deep 3 with - as char",
                     LoggerSetup.get_log_deep(3, '-'))

        self.assertEqual(True, LoggerSetup.is_setup_loaded())

        LoggerSetup.shutdown()
Esempio n. 38
0
    def _wait_for_test_done(cls, test: FirmwareTestClass, router: Router, done_event: DoneEvent) -> None:
        """
        Wait 2 minutes until the test is done.
        Handles the result from the tests.
        Triggers the next job/test.

        :param test: test to execute
        :param router: the Router
        :param done_event: event which will be triggered when the task is finished
        """
        logging.debug("%sWait for test" + str(test), LoggerSetup.get_log_deep(2))
        try:
            async_result = cls._task_pool.apply_async(func=cls._execute_test, args=(test, router, cls._routers))
            result = async_result.get(120)  # wait 2 minutes or raise an TimeoutError
            logging.debug("%sTest done " + str(test), LoggerSetup.get_log_deep(1))
            logging.debug("%sFrom Router(" + str(router.id) + ")", LoggerSetup.get_log_deep(2))

            cls._test_results.append((router.id, str(test), result))

            try:
                length = len(cls._test_results)
                t = cls._test_results[(length - 1)]
                cls.write_in_db(str(length), t)
            except Exception as e:
                logging.error("Error at write test results into DB: {0}".format(e))

        except Exception as e:
            logging.error("%sTest raised an Exception: " + str(e), LoggerSetup.get_log_deep(1))

            result = TestResult()
            result._original_stdout = None
            result._original_stderr = None

            cls._test_results.append((router.id, str(test), result))
            cls._task_errors.append((router.id, sys.exc_info()))

            try:
                length = len(cls._test_results)
                t = cls._test_results[(length - 1)]
                cls.write_in_db(str(length), t)
            except Exception as e:
                logging.error("Error at write test results into DB: {0}".format(e))

        finally:
            cls.set_running_task(router, None)
            # logging.debug(str(cls._test_results))
            # start next test in the queue
            done_event.set()
            cls.__start_task(router, None)
Esempio n. 39
0
    def _execute_job(cls, job: RemoteSystemJob, remote_sys: RemoteSystem, routers: List[Router]) -> {}:
        logging.debug("%sExecute job " + str(job) + " on Router(" + str(remote_sys.id) + ")",
                      LoggerSetup.get_log_deep(2))
        setproctitle(str(remote_sys.id) + " - " + str(job))
        job.prepare(remote_sys, routers)

        cls.__setns(remote_sys)
        result = None
        try:
            result = job.run()
        except Exception as e:
            logging.error("%sError while execute job " + str(job), LoggerSetup.get_log_deep(1))
            logging.error("%s" + str(e), LoggerSetup.get_log_deep(2))

        return result
Esempio n. 40
0
 def connect_with_remote_system(self):
     """
     Connects to the remote_system via SSH(Paramiko).
     Ignores a missing signatur.
     """
     logging.info("%sConnect with RemoteSystem ...", LoggerSetup.get_log_deep(1))
     try:
         self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         self.ssh.connect(str(self.remote_system.ip), port=22,
                          username=str(self.remote_system.usr_name),
                          password=str(self.remote_system.usr_password))
         logging.debug("%s[+] Successfully connected", LoggerSetup.get_log_deep(2))
     except Exception as e:
         logging.error("%s[-] Couldn't connect", LoggerSetup.get_log_deep(2))
         raise e
Esempio n. 41
0
    def update_ip(interface: str, timeout: int = 20) -> int:
        """
        Uses 'Popen' to start a dhclient in new process, for a given interface.

        :param interface: interface name
        :param timeout: time until break
        :return: 0 = no error; 1 = error; 2 = a dhclient is already running
        """
        try:
            logging.debug("%sUpdate IP via dhclient ...",
                          LoggerSetup.get_log_deep(2))
            process = Popen(['dhclient', interface], stdout=PIPE, stderr=PIPE)
            stdout, stderr = process.communicate()
            while Dhclient.get_ip(interface) is None:
                time.sleep(0.5)
                if timeout <= 0:
                    return TimeoutError
                timeout -= 1

            if "File exists" in str(stderr):
                return 2
            elif stderr.decode('utf-8') != "":
                return 1
            return 0
        except KeyboardInterrupt:
            return 3
        except Exception as e:
            raise e
 def _execption_hanling(self):
     """
     Sets the Router in unknown-mode.
     """
     logging.error("%s[-] Something went wrong. Use command 'online -r " + str(self.router.id) + "'",
                   LoggerSetup.get_log_deep(2))
     self.router.mode = Mode.unknown
Esempio n. 43
0
 def _success_handling(self):
     """
     Sets the Router in config/normal-mode depending on given mode.
     """
     mode = Mode.configuration if self.configmode else Mode.normal
     logging.debug("%s[+] Router was set into " + str(mode), LoggerSetup.get_log_deep(2))
     self.router.mode = mode
Esempio n. 44
0
    def check_hash(self, excep_hash: str) -> bool:
        """
        Checks whether the excepted Hash equals the actual Hash of the Firmware.

        :param excep_hash:
        :return:
        """
        logging.debug("%sCheck Hash of the Firmware(" + self.name + ") ...", LoggerSetup.get_log_deep(3))
        self.calc_hash()
        if self.hash == excep_hash:
            logging.debug("%s[+] The Hash is correct", LoggerSetup.get_log_deep(4))
            return True
        logging.debug("%s[-] The Hash is incorrect", LoggerSetup.get_log_deep(4))
        logging.debug("%sHash of the Firmware: " + self.hash, LoggerSetup.get_log_deep(4))
        logging.debug("%sExcepted Hash: " + excep_hash, LoggerSetup.get_log_deep(4))
        return False
Esempio n. 45
0
    def setup_expert_private_wlan(self):
        """
        Extend your private network by bridging the WAN interface with a seperate WLAN

        Info:
            private WLAN:   [checkbox]
                ssid:           [text]
                ssid key:       [text]
            submit:         [button]
        """
        logging.debug("%sSetup 'Private WLAN' ...", LoggerSetup.get_log_deep(2))
        self.browser.get('http://' + self.router.ip + '/cgi-bin/luci/admin/privatewifi/')

        private_wlan_field_id = "cbid.wifi.1.enabled"
        ssid_field_id = "cbid.wifi.1.ssid"
        ssid_key_field_id = "cbid.wifi.1.key"
        safe_button_xpath = "//*[@class='cbi-button cbi-button-save']"

        private_wlan_field_element = self._get_element_by_id(private_wlan_field_id)
        safe_button_element = self._get_element_by_xpath(safe_button_xpath)

        # The checkboxes are set to 'display = none' via css.
        # Because selenium can't see them we have to set the checkboxes to 'display = inline'
        self.browser.execute_script("arguments[0].style.display = 'inline';", private_wlan_field_element)

        self._click_checkbox(private_wlan_field_element, self.config['private_wlan'])
        if self.config['private_wlan']:
            ssid_field_element = self._get_element_by_id(ssid_field_id)
            ssid_key_field_element = self._get_element_by_id(ssid_key_field_id)
            ssid_field_element.clear()
            ssid_field_element.send_keys(self.config['ssid'])
            ssid_key_field_element.clear()
            ssid_key_field_element.send_keys(self.config['ssid_key'])

        safe_button_element.click()
 def _exception_handling(self):
     """
     Sets the Router in unknown-mode.
     """
     logging.warning("%s[!] Couldn't get a new IP for Router(" + str(self.router.id) + ")",
                     LoggerSetup.get_log_deep(2))
     self.router.mode = Mode.unknown
 def test_accessibility_of_expert(self):
     """
     Test:
         1. Router is in configuration-mode
         2. The page-source of the expert-page doesn't contain "Not Found" => expert-page exist
     """
     logging.debug("%sTest: Accessibility of the WebInterface: Expert-Page", LoggerSetup.get_log_deep(1))
     assert self.remote_system.mode == Mode.configuration
     logging.debug("%s[" + u"\u2714" + "] Correct Mode", LoggerSetup.get_log_deep(2))
     pre_command = ['ip', 'netns', 'exec', self.remote_system.namespace_name]
     browser = WebdriverPhantomjsExtended(pre_command=pre_command)
     browser.get(self.remote_system.ip)
     browser.get('http://' + self.remote_system.ip + '/cgi-bin/luci/admin/')
     self.assertTrue("Not Found" not in browser.page_source, "The Expert-Page isn't accessible")
     logging.debug("%s[" + u"\u2714" + "] The Expert-Page is accessible", LoggerSetup.get_log_deep(2))
     browser.close()
Esempio n. 48
0
 def remove(self):
     """
     Removes the Namespace and all included Network-Interfaces.
     """
     logging.debug("%sDelete Namespace ...", LoggerSetup.get_log_deep(2))
     try:
         netns.remove(self.nsp_name)
         self.ipdb_netns.release()
         logging.debug("%s[+] Namespace(" + self.nsp_name + ") successfully deleted", LoggerSetup.get_log_deep(3))
     except Exception as e:
         if re.match("\[Errno 2\]*", str(e)):
             logging.debug("%s[+] Namespace(" + self.nsp_name + ") is already deleted", LoggerSetup.get_log_deep(3))
             return
         logging.error("%s[-] Namespace(" + self.nsp_name +
                       ") couldn't be deleted. Try 'ip netns delete <namespace_name>'", LoggerSetup.get_log_deep(3))
         logging.error("%s" + str(e), LoggerSetup.get_log_deep(3))
Esempio n. 49
0
    def get_stored_firmware(self, router_model: str) -> Firmware:
        """
        Returns the matching Firmware, if stored in the list 'self.firmwares'.

        :param router_model: Like 'TP-LINK TL-WR841N/ND v9'
        :return: Firmware-Obj
        """
        router_model_name, router_model_version = self._parse_router_model(router_model)
        parsed_router_model = router_model_name + "-" + router_model_version
        for firmware in self.firmwares:
            if parsed_router_model in firmware.name:
                logging.info("%s[+] The Firmware is up to date", LoggerSetup.get_log_deep(2))
                return firmware
        logging.info("%s[-] Couldn't found a matching Firmware to Router(" + router_model + ")",
                     LoggerSetup.get_log_deep(2))
        return None
Esempio n. 50
0
    def setup_expert_mesh_vpn(self):
        """
        Sets the given mesh-vpn configuration

        Info:
            security mode:  [radiobutton]
            perform. mode:  [radiobutton]

            submit:         [button]
        """
        logging.debug("%sSetup 'Mesh VPN' ...", LoggerSetup.get_log_deep(3))
        self.browser.get('http://' + self.router.ip +
                         '/cgi-bin/luci/admin/mesh_vpn_fastd/')

        security_mode_field_id = "cbid.mesh_vpn.1.mode1"
        performance_mode_field_id = "cbid.mesh_vpn.1.mode2"
        safe_button_xpath = "//*[@class='cbi-button cbi-button-save']"

        security_mode_field_element = self._get_element_by_id(
            security_mode_field_id)
        performance_mode_field_element = self._get_element_by_id(
            performance_mode_field_id)
        safe_button_element = self._get_element_by_xpath(safe_button_xpath)

        self._click_checkbox(security_mode_field_element,
                             self.config['security_mode'])
        self._click_checkbox(performance_mode_field_element,
                             self.config['performance_mode'])
        safe_button_element.click()
Esempio n. 51
0
 def _parse_router_model(self, router_model: str):
     """
     Transform a str like "TP-LINK TL-WR841N/ND v9" into "tp-link-tl-wr841n-nd-v9"
     :param router_model:
     :return: router_model_name and router_model_version
     """
     logging.debug("Parse RouterModel ...", LoggerSetup.get_log_deep(2))
     tmp = router_model.split(' v')
     router_model_name = tmp[0]
     router_model_version = 'v' + tmp[1]
     router_model_name = router_model_name.lower()
     # replace all symbols with a minus
     router_model_name = re.sub(r'(?:[^\w])', '-', router_model_name)
     logging.debug("%s'" + router_model + "' into '" + router_model_name + " " + router_model_version + "'",
                   LoggerSetup.get_log_deep(3))
     return [router_model_name, router_model_version]