Пример #1
0
 def get_psk(self, code, interface):
     LoggerGui.debug("Attempting to get PSK")  # Don't log code
     CliMain.create_temp_config_file()
     self.wpa_supplicant = WpaSupplicant()
     self.wpa_supplicant.add_status_change_listener(self.wpa_status_changed)
     self.wpa_supplicant.get_psk(constants.PATH_CONF_CONNECT_TMP, interface,
                                 code)
Пример #2
0
 def get_key(self):
     LoggerCli.info("Getting key")
     wii_u_interface = Args.args.wii_u_interface
     try:
         InterfaceUtil.get_mac(wii_u_interface)
     except ValueError:
         LoggerCli.throw(Exception("Invalid interface selected."))
     if len(Args.args.wps_pin) != 4:
         LoggerCli.throw(Exception("WPS PIN should be 4 digits"))
     self.prompt_unmanaged(wii_u_interface)
     self.create_temp_config_file()
     self.wpa_supplicant = WpaSupplicant()
     self.wpa_supplicant.get_psk(constants.PATH_CONF_CONNECT_TMP,
                                 wii_u_interface, Args.args.wps_pin)
     self.wpa_supplicant.add_status_change_listener(self.status_changed_key)
     self.getting_key = True
     while self.getting_key:
         time.sleep(1)
Пример #3
0
 def run_server(self):
     LoggerCli.info("Starting server")
     normal_interface = Args.args.normal_interface
     wii_u_interface = Args.args.wii_u_interface
     self.check_interfaces(normal_interface, wii_u_interface)
     self.prompt_unmanaged(wii_u_interface)
     self.wpa_supplicant = WpaSupplicant()
     self.wpa_supplicant.connect(constants.PATH_CONF_CONNECT,
                                 wii_u_interface)
     self.wpa_supplicant.add_status_change_listener(self.status_changed)
     InterfaceUtil.dhclient(wii_u_interface)
     InterfaceUtil.set_metric(normal_interface, 0)
     InterfaceUtil.set_metric(wii_u_interface, 1)
     self.drc_sim_c = DrcSimC()
     self.drc_sim_c.set_region(Args.args.region)
     self.drc_sim_c.add_status_change_listener(
         self.drc_sim_c_status_changed)
     self.drc_sim_c.start()
     while self.drc_sim_c.running:
         time.sleep(1)
Пример #4
0
 def start_server(self, event=None):
     """
     Try to start wpa_supplicant and connect to a Wii U.
     :param event: Determines if this was a user initiated start.
     :return: None
     """
     if event:
         LoggerGui.debug("User clicked start server button")
     LoggerGui.debug("Start server called")
     if self.label_backend_status["text"] != DrcSimC.STOPPED and \
             (self.label_wpa_status["text"] not in (WpaSupplicant.DISCONNECTED, WpaSupplicant.TERMINATED)):
         messagebox.showerror("Running", "Server is already running")
         return
     if not os.path.exists(constants.PATH_CONF_CONNECT):
         messagebox.showerror(
             "Auth Error",
             "No auth details found. Use the \"Get Key\" tab to pair with a Wii U."
         )
         self.activate()
         return
     self.normal_interface = self.dropdown_normal_interface.get()
     self.wii_u_interface = self.dropdown_wiiu_interface.get()
     if not self.normal_interface or not self.wii_u_interface:
         messagebox.showerror("Interface Error",
                              "Two interfaces need to be selected.")
         self.activate()
         return
     if self.normal_interface == self.wii_u_interface:
         messagebox.showerror(
             "Interface Error",
             "The selected normal and Wii U interfaces must be different.")
         self.activate()
         return
     try:
         InterfaceUtil.get_mac(self.normal_interface)
         InterfaceUtil.get_mac(self.wii_u_interface)
     except ValueError:
         messagebox.showerror(
             "Interface Error",
             "The selected Interface is no longer available.")
         self.activate()
         return
     if InterfaceUtil.is_managed_by_network_manager(self.wii_u_interface):
         set_unmanaged = messagebox.askokcancel(
             "Managed Interface",
             "This interface is managed by Network Manager. To use it with DRC Sim it needs "
             "to be set to unmanaged. Network Manager will not be able to control the interface"
             " after this.\nSet %s to unmanaged?" % self.wii_u_interface)
         if set_unmanaged:
             InterfaceUtil.set_unmanaged_by_network_manager(
                 self.wii_u_interface)
         else:
             messagebox.showerror(
                 "Managed Interface",
                 "Selected Wii U interface is managed by Network Manager.")
             self.activate()
             return
     LoggerGui.debug("Starting wpa supplicant")
     self.wpa_supplicant = WpaSupplicant()
     self.wpa_supplicant.add_status_change_listener(self.wpa_status_changed)
     self.wpa_supplicant.connect(constants.PATH_CONF_CONNECT,
                                 self.wii_u_interface)
     self.label_backend_status.config(text="WAITING")
Пример #5
0
class FrameRunServer(FrameTab):
    def __init__(self, master=None, **kw):
        """
        GUI tab that handles interface and region selection and starting the server.
        :param master: root window
        :param kw: args
        """
        FrameTab.__init__(self, master, **kw)
        self.wii_u_interface = None
        self.normal_interface = None
        self.drc_sim_c = None
        self.wpa_supplicant = None
        LoggerGui.extra("Initializing FrameRunServer")
        # Create Widgets
        self.label_wpa = Label(self, text="Wii U Connection:")
        self.label_backend = Label(self, text="Server Status:")
        self.label_wpa_status = Label(self)
        self.label_backend_status = Label(self)
        self.button_start = Button(self, text="Start")
        self.button_stop = Button(self, text="Stop")
        self.label_wiiu_interface = Label(self, text="Wii U Interface")
        self.label_normal_interface = Label(self, text="Normal Interface")
        self.dropdown_wiiu_interface = Combobox(self, state="readonly")
        self.dropdown_normal_interface = Combobox(self, state="readonly")
        self.label_interface_info = Label(self)
        self.label_region = Label(self, text="Region")
        self.dropdown_region = Combobox(self, state="readonly")
        # Events
        self.button_start.bind("<Button-1>", self.start_server)
        self.button_stop.bind("<Button-1>", self.stop_server)
        # Position widgets
        self.label_wpa.grid(column=0, row=0, sticky="e")
        self.label_backend.grid(column=0, row=1, sticky="e")
        self.label_wpa_status.grid(column=1, row=0, sticky="w")
        self.label_backend_status.grid(column=1, row=1, sticky="w")
        self.label_wiiu_interface.grid(column=0, row=2)
        self.label_normal_interface.grid(column=0, row=3)
        self.dropdown_wiiu_interface.grid(column=1, row=2, columnspan=2)
        self.dropdown_normal_interface.grid(column=1, row=3, columnspan=2)
        self.label_region.grid(column=0, row=4)
        self.dropdown_region.grid(column=1, row=4, columnspan=2)
        self.button_start.grid(column=1, row=5)
        self.button_stop.grid(column=2, row=5)
        self.label_interface_info.grid(column=0, row=6, columnspan=3)
        LoggerGui.extra("Initialized FrameRunServer")

    def start_server(self, event=None):
        """
        Try to start wpa_supplicant and connect to a Wii U.
        :param event: Determines if this was a user initiated start.
        :return: None
        """
        if event:
            LoggerGui.debug("User clicked start server button")
        LoggerGui.debug("Start server called")
        if self.label_backend_status["text"] != DrcSimC.STOPPED and \
                (self.label_wpa_status["text"] not in (WpaSupplicant.DISCONNECTED, WpaSupplicant.TERMINATED)):
            messagebox.showerror("Running", "Server is already running")
            return
        if not os.path.exists(constants.PATH_CONF_CONNECT):
            messagebox.showerror(
                "Auth Error",
                "No auth details found. Use the \"Get Key\" tab to pair with a Wii U."
            )
            self.activate()
            return
        self.normal_interface = self.dropdown_normal_interface.get()
        self.wii_u_interface = self.dropdown_wiiu_interface.get()
        if not self.normal_interface or not self.wii_u_interface:
            messagebox.showerror("Interface Error",
                                 "Two interfaces need to be selected.")
            self.activate()
            return
        if self.normal_interface == self.wii_u_interface:
            messagebox.showerror(
                "Interface Error",
                "The selected normal and Wii U interfaces must be different.")
            self.activate()
            return
        try:
            InterfaceUtil.get_mac(self.normal_interface)
            InterfaceUtil.get_mac(self.wii_u_interface)
        except ValueError:
            messagebox.showerror(
                "Interface Error",
                "The selected Interface is no longer available.")
            self.activate()
            return
        if InterfaceUtil.is_managed_by_network_manager(self.wii_u_interface):
            set_unmanaged = messagebox.askokcancel(
                "Managed Interface",
                "This interface is managed by Network Manager. To use it with DRC Sim it needs "
                "to be set to unmanaged. Network Manager will not be able to control the interface"
                " after this.\nSet %s to unmanaged?" % self.wii_u_interface)
            if set_unmanaged:
                InterfaceUtil.set_unmanaged_by_network_manager(
                    self.wii_u_interface)
            else:
                messagebox.showerror(
                    "Managed Interface",
                    "Selected Wii U interface is managed by Network Manager.")
                self.activate()
                return
        LoggerGui.debug("Starting wpa supplicant")
        self.wpa_supplicant = WpaSupplicant()
        self.wpa_supplicant.add_status_change_listener(self.wpa_status_changed)
        self.wpa_supplicant.connect(constants.PATH_CONF_CONNECT,
                                    self.wii_u_interface)
        self.label_backend_status.config(text="WAITING")

    def wpa_status_changed(self, status):
        """
        Handles wpa status changes. Initializes backend server if a connection is made.
        :param status: status message
        :return: None
        """
        LoggerGui.debug("Wpa changed status to %s", status)
        self.label_wpa_status.config(text=status)
        if status == WpaSupplicant.CONNECTED:
            LoggerGui.debug("Routing")
            InterfaceUtil.dhclient(self.wii_u_interface)
            InterfaceUtil.set_metric(self.normal_interface, 0)
            InterfaceUtil.set_metric(self.wii_u_interface, 1)
            LoggerGui.debug("Starting backend")
            self.drc_sim_c = DrcSimC()
            self.drc_sim_c.add_status_change_listener(
                self.backend_status_changed)
            self.drc_sim_c.set_region(self.dropdown_region.get())
            self.drc_sim_c.start()
            self.label_interface_info.config(
                text="Server IP: " +
                InterfaceUtil.get_ip(self.normal_interface) + "\n" +
                os.uname()[1])
        elif status in (WpaSupplicant.DISCONNECTED, WpaSupplicant.TERMINATED):
            self.stop_server()
        elif status == WpaSupplicant.NOT_FOUND:
            self.stop_server()
            messagebox.showerror("Scan Error", "No Wii U found.")
        elif status == WpaSupplicant.FAILED_START:
            self.stop_server()
            messagebox.showerror(
                "Cannot Connect",
                "Failed to start wpa_supplicant_drc. This could mean there is a "
                "configuration error or wpa_supplicant_drc is not installed. "
                "Check %s for details." % constants.PATH_LOG_WPA)

    def backend_status_changed(self, status):
        """
        Handles backend status changes.
        :param status: status message
        :return: None
        """
        LoggerGui.debug("Backend status changed to %s", status)
        self.label_backend_status.config(text=status)
        if status == DrcSimC.STOPPED:
            self.stop_server()

    def stop_server(self, event=None):
        """
        Stops active threads.
        :param event: Determines if this is a user initiated stop
        :return: None
        """
        if event:
            LoggerGui.debug("User clicked stop server button")
        LoggerGui.debug("Stop server called")
        if event and (self.label_wpa_status["text"]
                      in (WpaSupplicant.DISCONNECTED, WpaSupplicant.TERMINATED)
                      and self.label_backend_status["text"]
                      == DrcSimC.STOPPED):
            messagebox.showerror("Stop", "Server is not running.")
            return
        if self.drc_sim_c:
            self.drc_sim_c.stop()
            self.drc_sim_c = None
        if self.wpa_supplicant:
            self.wpa_supplicant.stop()
            self.wpa_supplicant = None
        self.activate()

    def activate(self):
        """
        Initializes the frame.
        :return: None
        """
        LoggerGui.debug("FrameRunServer activated")
        self.dropdown_wiiu_interface[
            "values"] = InterfaceUtil.get_wiiu_compatible_interfaces()
        self.dropdown_normal_interface[
            "values"] = InterfaceUtil.get_all_interfaces()
        self.dropdown_region["values"] = ["NONE", "NA"]
        self.label_wpa_status["text"] = self.wpa_supplicant.get_status() \
            if self.wpa_supplicant and self.wpa_supplicant.get_status() else WpaSupplicant.DISCONNECTED
        self.label_backend_status["text"] = self.drc_sim_c.get_status() \
            if self.drc_sim_c and self.drc_sim_c.get_status() else DrcSimC.STOPPED
        self.button_start.config(state="normal")
        self.button_stop.config(state="normal")
        self.label_interface_info.config(text="")

    def deactivate(self):
        """
        De-initializes the frame.
        :return: None
        """
        LoggerGui.debug("FrameRunServer deactivated")
        self.stop_server()

    def kill_other_tabs(self):
        return True
Пример #6
0
class CliMain:
    def __init__(self):
        self.getting_key = False
        self.drc_sim_c = None
        self.wpa_supplicant = None

    def start(self):
        if Args.args.run_server:
            self.run_server()
        elif Args.args.get_key:
            self.get_key()
        else:
            self.stop()

    def stop(self):
        LoggerCli.info("Stopping")
        ProcessUtil.call(["killall", "dhclient"])
        self.getting_key = False
        if self.drc_sim_c:
            self.drc_sim_c.stop()
        if self.wpa_supplicant:
            self.wpa_supplicant.stop()

    def run_server(self):
        LoggerCli.info("Starting server")
        normal_interface = Args.args.normal_interface
        wii_u_interface = Args.args.wii_u_interface
        self.check_interfaces(normal_interface, wii_u_interface)
        self.prompt_unmanaged(wii_u_interface)
        self.wpa_supplicant = WpaSupplicant()
        self.wpa_supplicant.connect(constants.PATH_CONF_CONNECT,
                                    wii_u_interface)
        self.wpa_supplicant.add_status_change_listener(self.status_changed)
        InterfaceUtil.dhclient(wii_u_interface)
        InterfaceUtil.set_metric(normal_interface, 0)
        InterfaceUtil.set_metric(wii_u_interface, 1)
        self.drc_sim_c = DrcSimC()
        self.drc_sim_c.set_region(Args.args.region)
        self.drc_sim_c.add_status_change_listener(
            self.drc_sim_c_status_changed)
        self.drc_sim_c.start()
        while self.drc_sim_c.running:
            time.sleep(1)

    def drc_sim_c_status_changed(self, status):
        if status == DrcSimC.STOPPED:
            self.stop()

    @staticmethod
    def check_interfaces(normal_interface, wii_u_interface):
        if normal_interface == wii_u_interface:
            LoggerCli.throw(
                Exception(
                    "The Wii U and normal interfaces cannot be the same."))
        try:
            InterfaceUtil.get_mac(normal_interface)
            InterfaceUtil.get_mac(wii_u_interface)
        except ValueError:
            LoggerCli.throw(Exception("Invalid interface selected."))

    def status_changed(self, status):
        LoggerCli.info("Connection status changed to %s.", status)
        if status in (WpaSupplicant.TERMINATED, WpaSupplicant.NOT_FOUND,
                      WpaSupplicant.DISCONNECTED, WpaSupplicant.FAILED_START):
            self.stop()

    def status_changed_key(self, status):
        LoggerCli.info("Connection status changed to %s.", status)
        if status == WpaSupplicant.DISCONNECTED:
            LoggerCli.info("Successfully received PSK from the Wii U.")
            self.stop()
        elif status in (WpaSupplicant.TERMINATED, WpaSupplicant.NOT_FOUND,
                        WpaSupplicant.FAILED_START):
            self.stop()

    def get_key(self):
        LoggerCli.info("Getting key")
        wii_u_interface = Args.args.wii_u_interface
        try:
            InterfaceUtil.get_mac(wii_u_interface)
        except ValueError:
            LoggerCli.throw(Exception("Invalid interface selected."))
        if len(Args.args.wps_pin) != 4:
            LoggerCli.throw(Exception("WPS PIN should be 4 digits"))
        self.prompt_unmanaged(wii_u_interface)
        self.create_temp_config_file()
        self.wpa_supplicant = WpaSupplicant()
        self.wpa_supplicant.get_psk(constants.PATH_CONF_CONNECT_TMP,
                                    wii_u_interface, Args.args.wps_pin)
        self.wpa_supplicant.add_status_change_listener(self.status_changed_key)
        self.getting_key = True
        while self.getting_key:
            time.sleep(1)

    @staticmethod
    def prompt_unmanaged(interface):
        if not InterfaceUtil.is_managed_by_network_manager(interface):
            return
        LoggerCli.info(
            "The interface \"%s\" is managed by Network Manager. It must be set to "
            "unmanaged to function with DRC Sim. Network manager will not be able to "
            "use this interface after it is set to unmanaged.", interface)
        response = input("Set %s as unmanaged? (y/n)" % interface)
        LoggerCli.debug(response)
        if response in ("y", "yes", "Y", "Yes", "YES"):
            InterfaceUtil.set_unmanaged_by_network_manager(interface)
        else:
            LoggerCli.throw(
                Exception("Interface is managed by Network Manager."))

    @classmethod
    def create_temp_config_file(cls):
        if not os.path.exists(constants.PATH_TMP):
            os.mkdir(constants.PATH_TMP)
        tmp_conf = open(constants.PATH_CONF_CONNECT_TMP, "w")
        tmp_conf.write(Resource("config/get_psk.conf").resource)
        tmp_conf.close()
Пример #7
0
class FrameGetKey(FrameTab):
    def __init__(self, master=None, **kw):
        FrameTab.__init__(self, master, **kw)
        self.wpa_supplicant = None
        self.getting_psk = False
        # Widgets
        button_size = 50
        # Spade
        self.button_spade = Button(self, width=button_size, height=button_size)
        self.button_spade.image = self.get_image("image/spade.gif",
                                                 button_size, button_size)
        self.button_spade.config(image=self.button_spade.image)
        self.button_spade.number = 0
        # Heart
        self.button_heart = Button(self, width=button_size, height=button_size)
        self.button_heart.image = self.get_image("image/heart.gif",
                                                 button_size, button_size)
        self.button_heart.config(image=self.button_heart.image)
        self.button_heart.number = 1
        # Diamond
        self.button_diamond = Button(self,
                                     width=button_size,
                                     height=button_size)
        self.button_diamond.image = self.get_image("image/diamond.gif",
                                                   button_size, button_size)
        self.button_diamond.config(image=self.button_diamond.image)
        self.button_diamond.number = 2
        # Clover
        self.button_clover = Button(self,
                                    width=button_size,
                                    height=button_size)
        self.button_clover.image = self.get_image("image/clover.gif",
                                                  button_size, button_size)
        self.button_clover.config(image=self.button_clover.image)
        self.button_clover.number = 3
        # Delete
        self.button_delete = Button(self, text="Delete")
        # Code
        self.entry_pair_code = Entry(self, state="readonly")
        # Status Message
        self.status_message = Label(self, state="readonly")
        # interface dropdown
        self.dropdown_wii_u = Combobox(self, state="readonly")
        # Events
        self.button_spade.bind("<Button-1>", self.button_clicked)
        self.button_heart.bind("<Button-1>", self.button_clicked)
        self.button_diamond.bind("<Button-1>", self.button_clicked)
        self.button_clover.bind("<Button-1>", self.button_clicked)
        self.button_delete.bind("<Button-1>", self.button_delete_clicked)
        # Grid
        self.button_spade.grid(column=0, row=0)
        self.button_heart.grid(column=1, row=0)
        self.button_diamond.grid(column=2, row=0)
        self.button_clover.grid(column=3, row=0)
        self.button_delete.grid(column=4, row=0)
        self.entry_pair_code.grid(column=0, row=1, columnspan=5)
        self.status_message.grid(column=0, row=3, columnspan=5)
        self.dropdown_wii_u.grid(column=0, row=2, columnspan=5)

    # noinspection PyUnusedLocal
    def button_delete_clicked(self, event):
        self.set_code_text(
            self.entry_pair_code.get()[:len(self.entry_pair_code.get()) - 1])

    def button_clicked(self, event):
        if self.getting_psk:
            messagebox.showerror("Running",
                                 "A pairing attempt is already im progress.")
            return
        number = str(event.widget.number)
        LoggerGui.debug(
            "A suit button was clicked"
        )  # Don't log numbers as the code can be derived from that
        code = self.entry_pair_code.get()
        code += number
        self.set_code_text(code)
        wii_u_interface = self.dropdown_wii_u.get()
        if not wii_u_interface:
            messagebox.showerror("No Interface",
                                 "An interface must be selected.")
            self.activate()
            return
        try:
            InterfaceUtil.get_mac(wii_u_interface)
        except ValueError:
            messagebox.showerror(
                "Interface Error",
                "The selected Interface is no longer available.")
            self.activate()
            return
        if InterfaceUtil.is_managed_by_network_manager(wii_u_interface):
            set_unmanaged = messagebox.askokcancel(
                "Managed Interface",
                "This interface is managed by Network Manager. To use it with DRC Sim it needs "
                "to be set to unmanaged. Network Manager will not be able to control the interface"
                " after this.\nSet %s to unmanaged?" % wii_u_interface)
            if set_unmanaged:
                InterfaceUtil.set_unmanaged_by_network_manager(wii_u_interface)
            else:
                messagebox.showerror(
                    "Managed Interface",
                    "Selected Wii U interface is managed by Network Manager.")
                self.activate()
                return
        if len(code) == 4:
            self.getting_psk = True
            self.set_code_text("")
            self.get_psk(code, wii_u_interface)

    def get_psk(self, code, interface):
        LoggerGui.debug("Attempting to get PSK")  # Don't log code
        CliMain.create_temp_config_file()
        self.wpa_supplicant = WpaSupplicant()
        self.wpa_supplicant.add_status_change_listener(self.wpa_status_changed)
        self.wpa_supplicant.get_psk(constants.PATH_CONF_CONNECT_TMP, interface,
                                    code)

    def wpa_status_changed(self, status):
        LoggerGui.debug("Wpa status changed to %s", status)
        if status == WpaSupplicant.NOT_FOUND:
            self.deactivate()
            self.activate()
            messagebox.showerror("Scan", "No Wii U found.")
        elif status == WpaSupplicant.TERMINATED:
            self.deactivate()
            self.activate()
            messagebox.showerror(
                "Auth Fail", "Could not authenticate. Check the entered PIN.")
        elif status == WpaSupplicant.FAILED_START:
            self.deactivate()
            self.activate()
            messagebox.showerror("Error", "An unexpected error occurred.")
        elif status == WpaSupplicant.DISCONNECTED:
            self.deactivate()
            self.activate()
            messagebox.showerror("Auth Saved",
                                 "Successfully paired with Wii U.")
        elif status == WpaSupplicant.SCANNING:
            self.status_message["text"] = "Scanning"
        elif status == WpaSupplicant.CONNECTING:
            self.status_message["text"] = "Connecting"

    def activate(self):
        LoggerGui.debug("FrameTab activate called")
        self.getting_psk = False
        self.set_code_text("")
        if not self.wpa_supplicant or not self.wpa_supplicant.get_status():
            self.status_message["text"] = ""
        self.dropdown_wii_u[
            "values"] = InterfaceUtil.get_wiiu_compatible_interfaces()

    def deactivate(self):
        LoggerGui.debug("FrameTab deactivate called")
        self.status_message["text"] = ""
        self.getting_psk = False
        if self.wpa_supplicant:
            self.wpa_supplicant.stop()
            self.wpa_supplicant = None

    @staticmethod
    def get_image(location, width, height):
        image = PhotoImage(data=Resource(location).resource)
        orig_width = image.width()
        orig_height = image.height()
        image = image.zoom(width, height)
        image = image.subsample(orig_width, orig_height)
        return image

    def set_code_text(self, text):
        self.entry_pair_code.config(state="normal")
        self.entry_pair_code.delete(0, END)
        self.entry_pair_code.insert(0, text)
        self.entry_pair_code.config(state="readonly")

    def kill_other_tabs(self):
        return True