Beispiel #1
0
class KlineCommand(Command):
    def __init__(self):
        self.banList = CaseInsensitiveDictionary()

    def onUse(self, user, data):
        if "reason" in data:
            self.banList[data["mask"]] = {
                "setter": user.prefix(),
                "created": epoch(now()),
                "duration": data["duration"],
                "reason": data["reason"]
            }
            user.sendMessage(
                "NOTICE",
                ":*** K:Line added on {}, to expire in {} seconds".format(
                    data["mask"], data["duration"]))
            now_banned = {}
            for nick, u in self.ircd.users.iteritems():
                if u.server == self.ircd.name:
                    result = self.match_kline(u)
                    if result:
                        now_banned[nick] = result
            for uid, reason in now_banned.iteritems():
                udata = self.ircd.users[uid]
                udata.sendMessage(
                    "NOTICE",
                    ":{}".format(self.ircd.servconfig["client_ban_msg"]))
                udata.disconnect("K:Lined: {}".format(reason))
        else:
            del self.banList[data["mask"]]
            user.sendMessage("NOTICE",
                             ":*** K:Line removed on {}".format(data["mask"]))

    def processParams(self, user, params):
        if user.registered > 0:
            user.sendMessage(irc.ERR_NOTREGISTERED, "KLINE",
                             ":You have not registered")
            return {}
        if "o" not in user.mode:
            user.sendMessage(
                irc.ERR_NOPRIVILEGES,
                ":Permission denied - You do not have the correct operator privileges"
            )
            return {}
        if not params:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE",
                             ":Not enough parameters")
            return {}
        banmask = params[0]
        if banmask in self.ircd.users:
            banmask = "{}@{}".format(user.username, user.hostname)
        elif "@" not in banmask:
            banmask = "*@{}".format(banmask)
        self.expire_klines()
        if banmask[0] == "-":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE",
                                 ":Not enough parameters")
                return {}
            if banmask not in self.banList:
                user.sendMessage(
                    "NOTICE",
                    ":*** K:line for {} does not currently exist; check /stats K for a list of active k:lines"
                    .format(banmask))
                return {}
            return {"user": user, "mask": banmask}
        if len(params) < 3 or not params[2]:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE",
                             ":Not enough parameters")
            return {}
        if banmask[0] == "+":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE",
                                 ":Not enough parameters")
                return {}
        if banmask in self.banList:
            user.sendMessage(
                "NOTICE",
                ":*** There's already a k:line set on {}!  Check /stats K for a list of active k:lines."
                .format(banmask))
            return {}
        return {
            "user": user,
            "mask": banmask,
            "duration": parse_duration(params[1]),
            "reason": " ".join(params[2:])
        }

    def statsList(self, user, statsType):
        if statsType != "K":
            return
        self.expire_klines()
        for mask, linedata in self.banList.iteritems():
            user.sendMessage(
                irc.RPL_STATSKLINE,
                ":{} {} {} {} :{}".format(mask, linedata["created"],
                                          linedata["duration"],
                                          linedata["setter"],
                                          linedata["reason"]))

    def register_check(self, user):
        result = self.match_kline(user)
        if not result:
            if result == None:
                return True
            return "again"
        user.sendMessage("NOTICE",
                         ":{}".format(self.ircd.servconfig["client_ban_msg"]))
        user.sendMessage("ERROR",
                         ":Closing Link: {} [K:Lined: {}]".format(
                             user.hostname, result),
                         to=None,
                         prefix=None)
        return False

    def match_kline(self, user):
        if "o" in user.mode:
            return None  # don't allow bans to affect opers
        if user.server != self.ircd.name:
            return None  # only match users on this server
        if "except_line" not in user.cache:
            if "kline_match" in user.cache:
                return user.cache["kline_match"]
            # Determine whether the user matches
            self.expire_klines()
            match_against = irc_lower("{}@{}".format(user.username,
                                                     user.hostname))
            for mask, linedata in self.banList.iteritems():
                if fnmatch(match_against, mask):
                    user.cache["kline_match"] = linedata["reason"]
                    return ""
            match_against = irc_lower("{}@{}".format(user.username, user.ip))
            for mask in self.banList.iterkeys(
            ):  # we just removed expired lines
                if fnmatch(match_against, mask):
                    user.cache["kline_match"] = linedata["reason"]
                    return ""
            return None
        else:
            if user.cache["except_line"]:
                return None
            if "kline_match" in user.cache:
                return user.cache["kline_match"]
            self.expire_klines()
            match_against = irc_lower("{}@{}".format(user.username,
                                                     user.hostname))
            for mask, linedata in self.banList.iteritems():
                if fnmatch(match_against, mask):
                    return linedata["reason"]
            match_against = irc_lower("{}@{}".format(user.username, user.ip))
            for mask in self.banList.iterkeys(
            ):  # we just removed expired lines
                if fnmatch(match_against, mask):
                    return linedata["reason"]
            return None

    def expire_klines(self):
        current_time = epoch(now())
        expired = []
        for mask, linedata in self.banList.iteritems():
            if linedata["duration"] and current_time > linedata[
                    "created"] + linedata["duration"]:
                expired.append(mask)
        for mask in expired:
            del self.banList[mask]
Beispiel #2
0
class ShunCommand(Command):
    def __init__(self):
        self.shunList = CaseInsensitiveDictionary()
    
    def onUse(self, user, data):
        if "reason" in data:
            self.shunList[data["mask"]] = {
                "setter": user.nickname,
                "created": epoch(now()),
                "duration": data["duration"],
                "reason": data["reason"]
            }
            user.sendMessage("NOTICE", ":*** Shun set on {}, to expire in {} seconds".format(data["mask"], data["duration"]))
        else:
            del self.shunList[data["mask"]]
            user.sendMessage("NOTICE", ":*** Shun removed on {}".format(data["mask"]))
        for udata in self.ircd.users.itervalues():
            if self.match_shun(udata):
                udata.cache["shunned"] = True
            else:
                udata.cache["shunned"] = False
    
    def processParams(self, user, params):
        if user.registered > 0:
            user.sendMessage(irc.ERR_NOTREGISTERED, "SHUN", ":You have not registered")
            return {}
        if "o" not in user.mode:
            user.sendMessage(irc.ERR_NOPRIVILEGES, ":Permission denied - You do not have the correct operator privileges")
            return {}
        if not params:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN", ":Not enough parameters")
            return {}
        banmask = params[0]
        if banmask in self.ircd.users:
            udata = self.ircd.users[banmask]
            banmask = "{}@{}".format(udata.username, udata.hostname)
        elif "@" not in banmask:
            banmask = "*@{}".format(banmask)
        self.expire_shuns()
        if banmask[0] == "-":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN", ":Not enough parameters")
                return {}
            if banmask not in self.shunList:
                user.sendMessage("NOTICE", ":*** Shun {} not found; check /stats S for a list of active shuns.".format(banmask))
                return {}
            return {
                "user": user,
                "mask": banmask
            }
        if len(params) < 3 or not params[2]:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN", ":Not enough parameters")
            return {}
        if banmask[0] == "+":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN", ":Not enough parameters")
                return {}
        if banmask in self.shunList:
            user.sendMessage("NOTICE", ":*** Shun {} is already set!  Check /stats S for a list of active shuns.".format(banmask))
            return {}
        return {
            "user": user,
            "mask": banmask,
            "duration": parse_duration(params[1]),
            "reason": " ".join(params[2:])
        }
    
    def statsList(self, user, statsType):
        if statsType != "S":
            return
        self.expire_shuns()
        for mask, linedata in self.shunList.iteritems():
            user.sendMessage(irc.RPL_STATSSHUN, "{} {} {} {} :{}".format(mask, linedata["created"], linedata["duration"], linedata["setter"], linedata["reason"]))
    
    def check_register(self, user):
        reason = self.match_shun(user)
        if reason:
            user.cache["shunned"] = True
        elif reason == None:
            user.cache["shunned"] = False
        else:
            return "again"
        return True
    
    def reassign_shun(self, user):
        reason = self.match_shun(user)
        if reason:
            user.cache["shunned"] = True
        else:
            user.cache["shunned"] = False
        return None # the xline_rematch hook shouldn't automatically operate on these, so let's make it not.
    
    def match_shun(self, user):
        self.expire_shuns()
        if "except_line" in user.cache:
            if user.cache["except_line"]:
                return None
            matchMask = "{}@{}".format(user.username, user.hostname)
            for mask, linedata in self.shunList.iteritems():
                if fnmatch(matchMask, mask):
                    return linedata["reason"]
            matchMask = "{}@{}".format(user.username, user.ip)
            for mask, linedata in self.shunList.iteritems():
                if fnmatch(matchMask, mask):
                    return linedata["reason"]
            return None
        elif "shunned" in user.cache:
            if user.cache["shunned"]:
                return "Shunned"
            return None
        else:
            matchMask = "{}@{}".format(user.username, user.hostname)
            for mask in self.shunList.iterkeys():
                if fnmatch(matchMask, mask):
                    user.cache["shunned"] = True
                    return ""
            matchMask = "{}@{}".format(user.username, user.ip)
            for mask in self.shunList.iterkeys():
                if fnmatch(matchMask, mask):
                    user.cache["shunned"] = True
                    return ""
            user.cache["shunned"] = False
            return None
    
    def expire_shuns(self):
        current_time = epoch(now())
        expired = []
        for mask, linedata in self.shunList.iteritems():
            if linedata["duration"] and current_time > linedata["created"] + linedata["duration"]:
                expired.append(mask)
        for mask in expired:
            del self.shunList[mask]
    
    def check_command(self, user, command, data):
        if "shunned" not in user.cache or not user.cache["shunned"]:
            return data
        if command not in self.ircd.servconfig["shun_command_list"]:
            return {}
        return data
Beispiel #3
0
class KlineCommand(Command):
    def __init__(self):
        self.banList = CaseInsensitiveDictionary()
    
    def onUse(self, user, data):
        if "reason" in data:
            self.banList[data["mask"]] = {
                "setter": user.prefix(),
                "created": epoch(now()),
                "duration": data["duration"],
                "reason": data["reason"]
            }
            user.sendMessage("NOTICE", ":*** K:Line added on {}, to expire in {} seconds".format(data["mask"], data["duration"]))
            now_banned = {}
            for nick, u in self.ircd.users.iteritems():
                if u.server == self.ircd.name:
                    result = self.match_kline(u)
                    if result:
                        now_banned[nick] = result
            for uid, reason in now_banned.iteritems():
                udata = self.ircd.users[uid]
                udata.sendMessage("NOTICE", ":{}".format(self.ircd.servconfig["client_ban_msg"]))
                udata.disconnect("K:Lined: {}".format(reason))
        else:
            del self.banList[data["mask"]]
            user.sendMessage("NOTICE", ":*** K:Line removed on {}".format(data["mask"]))
    
    def processParams(self, user, params):
        if user.registered > 0:
            user.sendMessage(irc.ERR_NOTREGISTERED, "KLINE", ":You have not registered")
            return {}
        if "o" not in user.mode:
            user.sendMessage(irc.ERR_NOPRIVILEGES, ":Permission denied - You do not have the correct operator privileges")
            return {}
        if not params:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE", ":Not enough parameters")
            return {}
        banmask = params[0]
        if banmask in self.ircd.users:
            banmask = "{}@{}".format(user.username, user.hostname)
        elif "@" not in banmask:
            banmask = "*@{}".format(banmask)
        self.expire_klines()
        if banmask[0] == "-":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE", ":Not enough parameters")
                return {}
            if banmask not in self.banList:
                user.sendMessage("NOTICE", ":*** K:line for {} does not currently exist; check /stats K for a list of active k:lines".format(banmask))
                return {}
            return {
                "user": user,
                "mask": banmask
            }
        if len(params) < 3 or not params[2]:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE", ":Not enough parameters")
            return {}
        if banmask[0] == "+":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "KLINE", ":Not enough parameters")
                return {}
        if banmask in self.banList:
            user.sendMessage("NOTICE", ":*** There's already a k:line set on {}!  Check /stats K for a list of active k:lines.".format(banmask))
            return {}
        return {
            "user": user,
            "mask": banmask,
            "duration": parse_duration(params[1]),
            "reason": " ".join(params[2:])
        }
    
    def statsList(self, user, statsType):
        if statsType != "K":
            return
        self.expire_klines()
        for mask, linedata in self.banList.iteritems():
            user.sendMessage(irc.RPL_STATSKLINE, ":{} {} {} {} :{}".format(mask, linedata["created"], linedata["duration"], linedata["setter"], linedata["reason"]))
    
    def register_check(self, user):
        result = self.match_kline(user)
        if not result:
            if result == None:
                return True
            return "again"
        user.sendMessage("NOTICE", ":{}".format(self.ircd.servconfig["client_ban_msg"]))
        user.sendMessage("ERROR", ":Closing Link: {} [K:Lined: {}]".format(user.hostname, result), to=None, prefix=None)
        return False
    
    def match_kline(self, user):
        if "o" in user.mode:
            return None # don't allow bans to affect opers
        if user.server != self.ircd.name:
            return None # only match users on this server
        if "except_line" not in user.cache:
            if "kline_match" in user.cache:
                return user.cache["kline_match"]
            # Determine whether the user matches
            self.expire_klines()
            match_against = irc_lower("{}@{}".format(user.username, user.hostname))
            for mask, linedata in self.banList.iteritems():
                if fnmatch(match_against, mask):
                    user.cache["kline_match"] = linedata["reason"]
                    return ""
            match_against = irc_lower("{}@{}".format(user.username, user.ip))
            for mask in self.banList.iterkeys(): # we just removed expired lines
                if fnmatch(match_against, mask):
                    user.cache["kline_match"] = linedata["reason"]
                    return ""
            return None
        else:
            if user.cache["except_line"]:
                return None
            if "kline_match" in user.cache:
                return user.cache["kline_match"]
            self.expire_klines()
            match_against = irc_lower("{}@{}".format(user.username, user.hostname))
            for mask, linedata in self.banList.iteritems():
                if fnmatch(match_against, mask):
                    return linedata["reason"]
            match_against = irc_lower("{}@{}".format(user.username, user.ip))
            for mask in self.banList.iterkeys(): # we just removed expired lines
                if fnmatch(match_against, mask):
                    return linedata["reason"]
            return None
    
    def expire_klines(self):
        current_time = epoch(now())
        expired = []
        for mask, linedata in self.banList.iteritems():
            if linedata["duration"] and current_time > linedata["created"] + linedata["duration"]:
                expired.append(mask)
        for mask in expired:
            del self.banList[mask]
Beispiel #4
0
class ShunCommand(Command):
    def __init__(self):
        self.shunList = CaseInsensitiveDictionary()

    def onUse(self, user, data):
        if "reason" in data:
            self.shunList[data["mask"]] = {
                "setter": user.nickname,
                "created": epoch(now()),
                "duration": data["duration"],
                "reason": data["reason"]
            }
            user.sendMessage(
                "NOTICE",
                ":*** Shun set on {}, to expire in {} seconds".format(
                    data["mask"], data["duration"]))
        else:
            del self.shunList[data["mask"]]
            user.sendMessage("NOTICE",
                             ":*** Shun removed on {}".format(data["mask"]))
        for udata in self.ircd.users.itervalues():
            if self.match_shun(udata):
                udata.cache["shunned"] = True
            else:
                udata.cache["shunned"] = False

    def processParams(self, user, params):
        if user.registered > 0:
            user.sendMessage(irc.ERR_NOTREGISTERED, "SHUN",
                             ":You have not registered")
            return {}
        if "o" not in user.mode:
            user.sendMessage(
                irc.ERR_NOPRIVILEGES,
                ":Permission denied - You do not have the correct operator privileges"
            )
            return {}
        if not params:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN",
                             ":Not enough parameters")
            return {}
        banmask = params[0]
        if banmask in self.ircd.users:
            udata = self.ircd.users[banmask]
            banmask = "{}@{}".format(udata.username, udata.hostname)
        elif "@" not in banmask:
            banmask = "*@{}".format(banmask)
        self.expire_shuns()
        if banmask[0] == "-":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN",
                                 ":Not enough parameters")
                return {}
            if banmask not in self.shunList:
                user.sendMessage(
                    "NOTICE",
                    ":*** Shun {} not found; check /stats S for a list of active shuns."
                    .format(banmask))
                return {}
            return {"user": user, "mask": banmask}
        if len(params) < 3 or not params[2]:
            user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN",
                             ":Not enough parameters")
            return {}
        if banmask[0] == "+":
            banmask = banmask[1:]
            if not banmask:
                user.sendMessage(irc.ERR_NEEDMOREPARAMS, "SHUN",
                                 ":Not enough parameters")
                return {}
        if banmask in self.shunList:
            user.sendMessage(
                "NOTICE",
                ":*** Shun {} is already set!  Check /stats S for a list of active shuns."
                .format(banmask))
            return {}
        return {
            "user": user,
            "mask": banmask,
            "duration": parse_duration(params[1]),
            "reason": " ".join(params[2:])
        }

    def statsList(self, user, statsType):
        if statsType != "S":
            return
        self.expire_shuns()
        for mask, linedata in self.shunList.iteritems():
            user.sendMessage(
                irc.RPL_STATSSHUN,
                "{} {} {} {} :{}".format(mask, linedata["created"],
                                         linedata["duration"],
                                         linedata["setter"],
                                         linedata["reason"]))

    def check_register(self, user):
        reason = self.match_shun(user)
        if reason:
            user.cache["shunned"] = True
        elif reason == None:
            user.cache["shunned"] = False
        else:
            return "again"
        return True

    def reassign_shun(self, user):
        reason = self.match_shun(user)
        if reason:
            user.cache["shunned"] = True
        else:
            user.cache["shunned"] = False
        return None  # the xline_rematch hook shouldn't automatically operate on these, so let's make it not.

    def match_shun(self, user):
        self.expire_shuns()
        if "except_line" in user.cache:
            if user.cache["except_line"]:
                return None
            matchMask = "{}@{}".format(user.username, user.hostname)
            for mask, linedata in self.shunList.iteritems():
                if fnmatch(matchMask, mask):
                    return linedata["reason"]
            matchMask = "{}@{}".format(user.username, user.ip)
            for mask, linedata in self.shunList.iteritems():
                if fnmatch(matchMask, mask):
                    return linedata["reason"]
            return None
        elif "shunned" in user.cache:
            if user.cache["shunned"]:
                return "Shunned"
            return None
        else:
            matchMask = "{}@{}".format(user.username, user.hostname)
            for mask in self.shunList.iterkeys():
                if fnmatch(matchMask, mask):
                    user.cache["shunned"] = True
                    return ""
            matchMask = "{}@{}".format(user.username, user.ip)
            for mask in self.shunList.iterkeys():
                if fnmatch(matchMask, mask):
                    user.cache["shunned"] = True
                    return ""
            user.cache["shunned"] = False
            return None

    def expire_shuns(self):
        current_time = epoch(now())
        expired = []
        for mask, linedata in self.shunList.iteritems():
            if linedata["duration"] and current_time > linedata[
                    "created"] + linedata["duration"]:
                expired.append(mask)
        for mask in expired:
            del self.shunList[mask]

    def check_command(self, user, command, data):
        if "shunned" not in user.cache or not user.cache["shunned"]:
            return data
        if command not in self.ircd.servconfig["shun_command_list"]:
            return {}
        return data