def change_module_node_state(self, module_names, node_name, state):
        """ Method: change module state for node_name if in the node """
        for module_name in module_names:
            is_changed = False
            module_root_xpath = MCS.get_node_root_path(node_name, self)
            if module_root_xpath is not False:
                is_changed = MCS.change_module_node_by_activation(
                    module_root_xpath, module_name, state)
            else:
                self.c.privmsg(
                    self.argument[0].nick, self.prefix +
                    "Not connected on the channel " + node_name + " !")

            if is_changed:
                MCS.append_log(module_name + " on " + node_name +
                               " changed to: " + state + " !")
                self.c.privmsg(
                    self.argument[0].nick, self.prefix + module_name + " on " +
                    node_name + " changed to: " + state + " !")
                if node_name[0] == "#":
                    self.parent.channel_dict[node_name].update_module_list()
                else:
                    self.parent.update_module_list()
            else:
                self.c.privmsg(
                    self.argument[0].nick, self.prefix + module_name +
                    " not changed to: " + state + " !")
Exemple #2
0
def signal_handler(signal_recieved, frame):
    """ Function: handle SIGINT and do a clean stop """
    del signal_recieved, frame
    for server_object in server_dict.values():
        t = threading.Timer(0, server_object.stop)
        t.start()
    time.sleep(1)
    MCS.append_log("Bot stopped")
    sys.exit(0)
Exemple #3
0
 def _main(self):
     """ Method: module loop waiting for module event """
     MCS.append_log("Module Started")
     try:
         while self.is_running:
             self.callEvent.wait()
             if self.is_running:
                 blacklisted = MCS.recursively_scan_node_info(
                     self.path, "blacklisted", "mask", self.argument[0],
                     True)
                 if self.parent.blacklist is False or blacklisted is None or blacklisted is False:
                     MCS.append_log(self.name + " called by " +
                                    self.argument[0] + " with: " +
                                    self.argument[1])
                     self.call_handle()
                 else:
                     MCS.append_log(self.name + " called by blacklisted " +
                                    self.argument[0] + "with: " +
                                    self.argument[1])
             self.callEvent.clear()
     except Exception as e:
         MCS.append_log(
             "{:.100s} Need to reboot... Exception: {:.100s}".format(
                 self.name, str(e)))
         traceback.print_exc()
         print("[" + self.name + "] rebooting...")
         self.parent.restart_module(self.__class__.__name__)
     return
 def disconnect_chan(self, channel_name):
     """ Method: disconnect the bot from a chan """
     if channel_name in self.parent.channel_dict:
         MCS.append_log(self.parent.nickname + " disconnected from: " +
                        channel_name)
         chan_xpath_expr = "/botConf/server[@url='" + self.parent.url + "']/salon[@name='" + channel_name + "']"
         chan_node = MCS.botConfObject.xpath(chan_xpath_expr)[0]
         chan_node.getparent().remove(chan_node)
         self.parent.part_chan(channel_name)
     else:
         self.c.privmsg(
             self.argument[0].nick, self.prefix +
             "Not connected on the channel " + channel_name + " !")
 def connect_chan(self, channel_name):
     """ Method: connect the bot to a new chan """
     if channel_name in self.parent.channel_dict:
         self.c.privmsg(
             self.argument[0].nick,
             self.prefix + "Already on the channel " + channel_name + " !")
     else:
         new_channel_node = MCS.get_new_channel_node(channel_name)
         MCS.botConfObject.xpath("server[@url='" + self.parent.url +
                                 "'] ")[0].append(new_channel_node)
         MCS.append_log(self.parent.nickname + " connected to: " +
                        channel_name)
         self.parent.join_chan(new_channel_node)
    def update_conf(self, range_name):
        real_node = MCS.get_first_real_root(self.parent.url, range_name)[0]

        if MCS.node_depth(real_node) == 0:
            self.c.privmsg(self.argument[0].nick,
                           self.prefix + "Not working for now !")
        elif MCS.node_depth(real_node) == 1:
            self.parent.update_server_node()
            self.c.privmsg(self.argument[0].nick,
                           self.prefix + "Server updated !")
        elif MCS.node_depth(real_node) == 2:
            self.parent.channel_dict[range_name].update_server_node()
            self.c.privmsg(self.argument[0].nick,
                           self.prefix + "Channel updated !")
    def sender_relative_admin_power(self, range_name):
        root_path = MCS.get_node_root_path(range_name, self)
        sender_node = MCS.recursively_scan_node_info(root_path, "admin",
                                                     "mask", self.argument[0],
                                                     False)
        is_bot_admin = sender_node is not False and sender_node is not None

        if is_bot_admin:
            # remove 1 in depth because of the <admin> depth
            if MCS.range_depth(range_name) > MCS.node_depth(sender_node) - 1:
                return -1
            else:
                return int(sender_node.get("level"))
        else:
            return 5
    def execute_admin_order(self, msg):
        """ Method: execute when the module event is raised and every prerequist are met """
        splited_msg = msg.split(" ")
        splited_msg = [argument for argument in splited_msg if argument != ""]

        if msg.startswith("!admin connect") and self.command_checker(
                splited_msg, 3, "!admin connect <channel>"):
            self.connect_chan(splited_msg[2])

        elif msg.startswith("!admin disconnect") and self.command_checker(
                splited_msg, 3, "!admin disconnect <channel>"):
            self.disconnect_chan(splited_msg[2])

        elif msg.startswith("!admin start") and self.command_checker(
                splited_msg, -4, "!admin start <module> <channel>"):
            self.change_module_node_state(splited_msg[2:-1], splited_msg[-1],
                                          "true")

        elif msg.startswith("!admin stop") and self.command_checker(
                splited_msg, -4, "!admin stop <module> <channel>"):
            self.change_module_node_state(splited_msg[2:-1], splited_msg[-1],
                                          "false")

        elif msg.startswith("!admin edit") and self.command_checker(
                splited_msg, -4,
                "!admin edit <info> [attr=value attr2=value2...] <range>"):
            self.edit_recursive_node(splited_msg[2], splited_msg[-1],
                                     splited_msg[3:-1])

        elif msg.startswith("!admin saveConf") and self.command_checker(
                splited_msg, 3, "!admin saveConf <xml_file>"):
            MCS.set_save_conf(splited_msg[2])

        elif msg.startswith("!admin list") and self.command_checker(
                splited_msg, 4, "!admin list <info> <range>"):
            self.list_info(splited_msg[2], splited_msg[3])

        elif msg.startswith("!admin dump") and self.command_checker(
                splited_msg, 2, "!admin dump"):
            self.dump_xml()

        elif msg.startswith("!admin reload") and self.command_checker(
                splited_msg, 3, "!admin reload <range>"):
            self.update_conf(splited_msg[2])

        return
Exemple #9
0
    def _main(self):
        """ Method: module loop waiting for module event """
        MCS.append_log("Module Started")
        try:
            # Load TCL part
            self.tcl_interpreter = tkinter.Tcl()
            for script in self.load_list:
                self.tcl_interpreter.eval("source {:.50s}/{:.50s}".format(
                    "modules/" + self.__class__.__name__, script))
        except Exception as e:
            MCS.append_log(
                "{:.100s} Need to reboot... Exception: {:.100s}".format(
                    self.name, str(e)))
            traceback.print_exc()
            print("[" + self.name + "] Can't Load source !")

        super(TclModule, self)._main()
        return
    def _main(self):
        """ Method: module loop waiting for module event"""

        MCS.append_log("Module Started")
        try:
            while self.is_running:
                self.callEvent.wait()
                self.analyse_sender_permission()
                self.callEvent.clear()
            return
        except Exception as e:
            MCS.append_log(
                "{:.100s} Need to reboot... Exception: {:.100s}".format(
                    self.name, str(e)))
            traceback.print_exc()
            print("[" + self.name + "] rebooting...")
            self.parent.restart_admin_module()
        return
Exemple #11
0
def main():
    """ Function: Main function of the bot. first one to call """
    start_time = datetime.datetime.now()
    if len(sys.argv) != 2:
        print("Usage: <configurationFile>")
        sys.exit(1)

    MCS.botConfObject = parse_conf(os.path.abspath(os.curdir) + "/" + sys.argv[1])
    MCS.append_log("------------------------------------------------------------")
    MCS.append_log("Bot started at: " + str(start_time))
    MCS.append_log("Configuration loaded")
    for server in MCS.botConfObject.xpath("/botConf/server"):

        server_object = core.ServerWorker.Worker(server)
        server_dict.update({server.get("url"): server_object})
        server_object.run()

    MCS.append_log("Server(s) launched")
    signal.pause()
Exemple #12
0
    def on_welcome(self, c, e):
        print(e.arguments[0])
        self.c = c
        self.admin_module_object.run(c)

        self.c.privmsg("Themis", u"IDENTIFY " + self.password)
        is_obfuscating = MCS.get_node_attr_to_bool(self.server_node,
                                                   "obfuscate")
        if is_obfuscating:
            c.mode(self.nickname, "+x")
        else:
            c.mode(self.nickname, "-x")
        c.mode(self.nickname, "+B")
        print("[" + self.url + "] identified as " + self.nickname +
              " and as a bot")

        for channel in self.server_node.xpath("salon"):
            self.join_chan(channel)
    def list_info(self, info_name, node_name):
        node_root_xpath = MCS.get_node_root_path(node_name, self)

        if info_name == "admin":
            if node_root_xpath is False:
                self.c.privmsg(self.argument[0].nick,
                               self.prefix + "No conf for " + node_name + " !")
            else:
                node_root_xpath = node_root_xpath + "/admin"
                node_list = MCS.botConfObject.xpath(node_root_xpath)
                if len(node_list) > 0:
                    for node in node_list:
                        self.c.privmsg(
                            self.argument[0].nick,
                            "[" + self.name + "] Admin: " + node.get("mask") +
                            " is level: " + node.get("level"))

        elif info_name == "module":
            if node_name.lower() == "installed":
                module_set = set([
                    name for name in os.listdir("modules")
                    if os.path.isdir(os.path.join("modules", name))
                    and name[0] is not "_"
                ])
                self.c.privmsg(
                    self.argument[0].nick, self.prefix +
                    "Modules installed: " + ", ".join(module_set))
            elif node_root_xpath is False:
                self.c.privmsg(self.argument[0].nick,
                               self.prefix + "No conf for " + node_name + " !")
            else:
                node_root_xpath = node_root_xpath + "/module"
                node_list = MCS.botConfObject.xpath(node_root_xpath)
                if len(node_list) > 0:
                    for node in node_list:
                        self.c.privmsg(
                            self.argument[0].nick,
                            "[" + self.name + "] Module: " + node.get("name") +
                            " is at state: " + node.get("activated"))
        else:
            self.c.privmsg(self.argument[0].nick,
                           self.prefix + "Info: " + info_name + " unknown !")
            return
    def analyse_sender_permission(self):
        """analyse_sender_permission"""

        splited_msg = self.argument[1].split()
        splited_msg = [argument for argument in splited_msg if argument != ""]
        node_name = splited_msg[-1]

        off_admin = False
        if node_name[0] != "#":
            node_name = self.parent.url
        else:
            try:
                off_admin = self.parent.channels[node_name].is_oper(
                    self.argument[0].nick)
            except KeyError:
                pass

        base_node = MCS.get_first_real_root(self.parent.url, node_name)
        root_node_path = MCS.botConfObject.getpath(base_node[0])

        admin_node = MCS.recursively_scan_node_info(root_node_path, "admin",
                                                    "mask", self.argument[0],
                                                    False)

        is_bot_admin = admin_node is not False and admin_node is not None
        is_off_admin_and_used = off_admin is True and self.parent.channel_dict[
            node_name].useoffadmin is True
        if is_off_admin_and_used or is_bot_admin:
            MCS.append_log(self.argument[0] + " call: " + self.argument[1])
            self.execute_admin_order(self.argument[1])
        else:
            MCS.append_log(self.argument[0] + " tried to call: " +
                           self.argument[1] + " but wasn't admin")
            self.c.privmsg(
                self.argument[0].nick, self.prefix + self.argument[0] +
                " is not admin from " + node_name + " or upper!")
Exemple #15
0
 def stop(self):
     MCS.append_log("Module Stopped")
     self.is_running = False
     self.callEvent.set()
    def edit_recursive_node(self, info, range_name, attr_list_text):

        is_changed = False

        root_path = MCS.get_node_root_path(range_name, self)
        if root_path is False:
            self.c.privmsg(
                self.argument[0].nick,
                self.prefix + "Can't access range: " + range_name + " !")
            return

        # We already know that the sender is an admin, but is it a upper range admin ?

        sender_level = self.sender_relative_admin_power(range_name)

        try:
            attr_dict = dict([i.split("=") for i in attr_list_text])
        except ValueError:
            self.c.privmsg(
                self.argument[0].nick,
                self.prefix + "Attribute wrongly formated: <attr=value> !")
            return

        is_valid = True

        if info.lower() == "blacklisted":
            if not "mask" in attr_dict:
                is_valid = False
                self.c.privmsg(self.argument[0].nick,
                               self.prefix + "You need to specify a mask!")
            if is_valid == True:
                new_node = MCS.get_new_node("blacklisted", attr_dict,
                                            ["mask", "remove"])
                etree.dump(new_node)
                is_changed = MCS.merge_node(new_node, root_path,
                                            ["mask", attr_dict["mask"]],
                                            {"remove": "true"})
        elif info.lower() == "admin":
            if not "mask" in attr_dict:
                is_valid = False
                self.c.privmsg(self.argument[0].nick,
                               self.prefix + "You need to specify a mask!")
            if not "level" in attr_dict:
                is_valid = False
                self.c.privmsg(self.argument[0].nick,
                               self.prefix + "You need to specify a level!")

            if not attr_dict["level"].isnumeric():
                self.c.privmsg(self.argument[0].nick,
                               self.prefix + "level is not a number!")
                is_valid = False
            if sender_level >= 0 and int(attr_dict["level"]) > sender_level:
                self.c.privmsg(
                    self.argument[0].nick, self.prefix +
                    "new admin can't be higher than you: {:d}".format(
                        sender_level))
                is_valid = False

            if is_valid == True:
                new_node = MCS.get_new_node("admin", attr_dict,
                                            ["mask", "level", "remove"])
                is_changed = MCS.merge_node(new_node, root_path,
                                            ["mask", attr_dict["mask"]], {
                                                "remove": "true",
                                                "level": "0"
                                            })
        elif info.lower() == "channel":
            if not "name" in attr_dict:
                is_valid = False
                self.c.privmsg(self.argument[0].nick,
                               self.prefix + "You need to specify a name!")

            if is_valid == True:
                new_node = MCS.get_new_node(
                    "salon", attr_dict, ["name", "blacklist", "useoffadmin"])
                is_changed = MCS.merge_node(new_node, root_path,
                                            ["name", attr_dict["name"]], {})

        else:
            self.c.privmsg(self.argument[0].nick,
                           self.prefix + "{:.50s} unknown".format(info))

        if is_changed:
            MCS.append_log("{:.50s} edited in {:.50s}".format(
                info, range_name))
            self.c.privmsg(
                self.argument[0].nick, self.prefix +
                "{:.50s} edited in {:.50s}".format(info, range_name))
        else:
            self.c.privmsg(
                self.argument[0].nick, self.prefix +
                "{:.50s} not edited in {:.50s}".format(info, range_name))
Exemple #17
0
 def on_kick(self, c, e):
     MCS.append_log(self.url + " : kicked from " + e.target + " by " +
                    e.source)
     self.c.join(e.target)
     del c
Exemple #18
0
 def stop(self):
     for channel_object in self.channel_dict.values():
         channel_object.stop()
     MCS.append_log(self.url + " stopped")
     self.die()
Exemple #19
0
 def run(self):
     MCS.append_log(self.url + " started")
     self.thread.start()