def checkUnset(self, channel, param): actionExtban = "" validParams = [] for fullBanmask in param.split(","): banmask = fullBanmask if ";" in banmask: actionExtban, banmask = banmask.split(";", 1) # We don't care about the rest of actionExtban here if ":" in banmask and ("@" not in banmask or banmask.find(":") < banmask.find("@")): validParams.append(fullBanmask) continue # Just allow this; the other checks will be managed by checking whether the parameter is actually set on the channel # If there's no matching extban, make sure the ident and host are given if "!" not in banmask: fullBanmask += "!*@*" elif "@" not in banmask: fullBanmask += "@*" # Make ban unsetting case-insensitive lowerBanmask = ircLower(fullBanmask) for existingParamData in channel.modes["b"]: if ircLower(existingParamData[0]) == lowerBanmask: validParams.append(existingParamData[0]) break else: validParams.append(fullBanmask) return validParams
def matchHostmask(self, user, banmask): banmask = ircLower(banmask) userMask = ircLower(user.hostmask()) if fnmatchcase(userMask, banmask): return True userMask = ircLower(user.hostmaskWithRealHost()) if fnmatchcase(userMask, banmask): return True userMask = ircLower(user.hostmaskWithIP()) return fnmatchcase(userMask, banmask)
def checkUserMatch(self, user, mask, data): exceptMask = ircLower(mask) userMask = ircLower("{}@{}".format(user.ident, user.host())) if fnmatchcase(userMask, exceptMask): return True userMask = ircLower("{}@{}".format(user.ident, user.realHost)) if fnmatchcase(userMask, exceptMask): return True userMask = ircLower("{}@{}".format(user.ident, user.ip)) if fnmatchcase(userMask, exceptMask): return True return False
def addUserToWhowas(self, user, reason): if not user.isRegistered(): # user never registered a nick, so no whowas entry to add return lowerNick = ircLower(user.nick) allWhowas = self.ircd.storage["whowas"] if lowerNick in allWhowas: whowasEntries = allWhowas[lowerNick] else: whowasEntries = [] serverName = self.ircd.name if user.uuid[:3] != self.ircd.serverID: serverName = self.ircd.servers[user.uuid[:3]].name whowasEntries.append({ "nick": user.nick, "ident": user.ident, "host": user.host(), "gecos": user.gecos, "server": serverName, "when": timestamp(now()) }) whowasEntries = self.removeOldEntries(whowasEntries) if whowasEntries: allWhowas[lowerNick] = whowasEntries elif lowerNick in allWhowas: del allWhowas[lowerNick]
def checkSet(self, user, param): noticeTypes = ircLower(param).split(",") badTypes = [] for noticeType in noticeTypes: if not self.ircd.runActionUntilTrue("servernoticetype", user, noticeType): user.sendMessage(irc.ERR_INVALIDSNOTYPE, noticeType, "Invalid server notice type") badTypes.append(noticeType) for noticeType in badTypes: noticeTypes.remove(noticeType) return noticeTypes
def parseParams(self, user, params, prefix, tags): if not params: user.sendSingleError("WhowasCmd", irc.ERR_NEEDMOREPARAMS, "WHOWAS", "Not enough parameters") return None lowerParam = ircLower(params[0]) if lowerParam not in self.ircd.storage["whowas"]: user.sendSingleError("WhowasNick", irc.ERR_WASNOSUCHNICK, params[0], "There was no such nickname") return None return {"nick": lowerParam, "param": params[0]}
def parseParams(self, user, params, prefix, tags): if len(params) < 2: user.sendSingleError("SQuitParams", irc.ERR_NEEDMOREPARAMS, "SQUIT", "Not enough parameters") return None source = self.ircd.serverID if params[0] not in self.ircd.serverNames: if ircLower(params[0]) == ircLower(self.ircd.name): user.sendSingleError( "SQuitTarget", irc.ERR_NOSUCHSERVER, self.ircd.name, "You can't unlink this server from itself") return None user.sendSingleError("SQuitTarget", irc.ERR_NOSUCHSERVER, params[0], "No such server") return None return { "source": source, "target": self.ircd.servers[self.ircd.serverNames[params[0]]], "reason": params[1] }
def parseParams(self, user, params, prefix, tags): if not params: user.sendSingleError("WhowasCmd", irc.ERR_NEEDMOREPARAMS, "WHOWAS", "Not enough parameters") return None lowerParam = ircLower(params[0]) if lowerParam not in self.ircd.storage["whowas"]: user.sendSingleError("WhowasNick", irc.ERR_WASNOSUCHNICK, params[0], "There was no such nickname") return None return { "nick": lowerParam, "param": params[0] }
def parseParams(self, user, params, prefix, tags): if not params: return {} channels = [] wildcardNames = [] for name in params[0].split(","): if "*" not in name and "?" not in name: if name in self.ircd.channels: channels.append(self.ircd.channels[name]) else: wildcardNames.append(ircLower(name)) for lowerName, channel in self.ircd.channels.iteritems(): for wildcardName in wildcardNames: if fnmatchcase(lowerName, wildcardName): channels.append(channel) break return {"channels": channels}
def parseParams(self, user, params, prefix, tags): if not params: return {} channels = [] wildcardNames = [] for name in params[0].split(","): if "*" not in name and "?" not in name: if name in self.ircd.channels: channels.append(self.ircd.channels[name]) else: wildcardNames.append(ircLower(name)) for lowerName, channel in self.ircd.channels.iteritems(): for wildcardName in wildcardNames: if fnmatchcase(lowerName, wildcardName): channels.append(channel) break return { "channels": channels }
def normalizeMask(self, mask): return ircLower(mask)
def checkUserMatch(self, user, mask, data): if data and "newnick" in data: return fnmatchcase(ircLower(data["newnick"]), ircLower(mask)) return fnmatchcase(ircLower(user.nick), ircLower(mask))
def checkUnset(self, user, param): return ircLower(param).split(",")
def execute(self, user, data): configuredOpers = self.ircd.config.get("opers", {}) username = data["username"] if username not in configuredOpers: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad username") return True operData = configuredOpers[username] if "password" not in operData: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad password") return True password = data["password"] if "hash" in operData: compareFunc = "compare-{}".format(operData["hash"]) if compareFunc not in self.ircd.functionCache: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad password") return True passwordMatch = self.ircd.functionCache[compareFunc](password, operData["password"]) else: passwordMatch = (password == operData["password"]) if not passwordMatch: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad password") return True if "host" in operData: hosts = ircLower(operData["host"]).split(" ") for operHost in hosts: userHost = ircLower("{}@{}".format(user.ident, user.host())) if fnmatchcase(userHost, operHost): break userHost = ircLower("{}@{}".format(user.ident, user.realHost)) if fnmatchcase(userHost, operHost): break userHost = ircLower("{}@{}".format(user.ident, user.ip)) if fnmatchcase(userHost, operHost): break else: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad host") return True if self.ircd.runActionUntilFalse("opercheck", user, username, password, operData): # Allow other modules to implement additional checks user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") if "error" in operData: self.reportOper(user, operData["error"]) else: self.reportOper(user, "Failed additional oper checks") return True user.setModes([(True, "o", None)], self.ircd.serverID) user.sendMessage(irc.RPL_YOUREOPER, "You are now an IRC operator") self.reportOper(user, None) vhost = None if "vhost" in operData: vhost = operData["vhost"] operPermissions = set() configuredOperTypes = self.ircd.config["oper_types"] if "types" in operData: for operType in operData["types"]: operPermissions.update(configuredOperTypes[operType]) if "group" in operData: groupData = self.ircd.config["oper_groups"][operData["group"]] if not vhost and "vhost" in groupData: vhost = groupData["vhost"] if "types" in groupData: for operType in groupData["types"]: operPermissions.update(configuredOperTypes[operType]) user.cache["oper-permissions"] = operPermissions if vhost: user.changeHost("oper", vhost) self.ircd.broadcastToServers(None, "OPER", user.uuid, *operPermissions, prefix=self.ircd.serverID) return True
def checkModePermission(self, user, settingUser, adding, param): if adding: if self.ircd.runActionUntilValue("userhasoperpermission", user, "servernotice-{}".format(ircLower(param)), users=[user]): return True user.sendMessage(irc.ERR_NOPRIVILEGES, "Permission denied - You do not have the correct operator privileges") return False return None
def denyMetadataSet(self, key): if ircLower(key) == "away": return False return None
def denyMetadataSet(self, key): if ircLower(key) == "account": return False return None
def execute(self, user, data): configuredOpers = self.ircd.config.get("opers", {}) username = data["username"] if username not in configuredOpers: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad username") return True operData = configuredOpers[username] if "password" not in operData: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad password") return True password = data["password"] if "hash" in operData: compareFunc = "compare-{}".format(operData["hash"]) if compareFunc not in self.ircd.functionCache: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad password") return True passwordMatch = self.ircd.functionCache[compareFunc]( password, operData["password"]) else: passwordMatch = (password == operData["password"]) if not passwordMatch: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad password") return True if "host" in operData: hosts = ircLower(operData["host"]).split(" ") for operHost in hosts: userHost = ircLower("{}@{}".format(user.ident, user.host())) if fnmatchcase(userHost, operHost): break userHost = ircLower("{}@{}".format(user.ident, user.realHost)) if fnmatchcase(userHost, operHost): break userHost = ircLower("{}@{}".format(user.ident, user.ip)) if fnmatchcase(userHost, operHost): break else: user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") self.reportOper(user, "Bad host") return True if self.ircd.runActionUntilFalse( "opercheck", user, username, password, operData ): # Allow other modules to implement additional checks user.sendMessage(irc.ERR_NOOPERHOST, "Invalid oper credentials") if "error" in operData: self.reportOper(user, operData["error"]) else: self.reportOper(user, "Failed additional oper checks") return True user.setModes([(True, "o", None)], self.ircd.serverID) user.sendMessage(irc.RPL_YOUREOPER, "You are now an IRC operator") self.reportOper(user, None) vhost = None if "vhost" in operData: vhost = operData["vhost"] operPermissions = set() configuredOperTypes = self.ircd.config["oper_types"] if "types" in operData: for operType in operData["types"]: operPermissions.update(configuredOperTypes[operType]) if "group" in operData: groupData = self.ircd.config["oper_groups"][operData["group"]] if not vhost and "vhost" in groupData: vhost = groupData["vhost"] if "types" in groupData: for operType in groupData["types"]: operPermissions.update(configuredOperTypes[operType]) user.cache["oper-permissions"] = operPermissions if vhost: user.changeHost("oper", vhost) self.ircd.broadcastToServers(None, "OPER", user.uuid, *operPermissions, prefix=self.ircd.serverID) return True