00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "inspircd.h"
00015
00016
00017
00018 class ModuleDenyChannels : public Module
00019 {
00020 private:
00021
00022
00023 ConfigReader *Conf;
00024
00025 public:
00026 ModuleDenyChannels(InspIRCd* Me) : Module(Me)
00027 {
00028
00029 Conf = new ConfigReader(ServerInstance);
00030 Implementation eventlist[] = { I_OnUserPreJoin, I_OnRehash };
00031 ServerInstance->Modules->Attach(eventlist, this, 2);
00032 }
00033
00034 virtual void OnRehash(User* user, const std::string ¶m)
00035 {
00036 delete Conf;
00037 Conf = new ConfigReader(ServerInstance);
00038
00039 for (int i =0; i < Conf->Enumerate("badchan"); i++)
00040 {
00041 std::string name = Conf->ReadValue("badchan","name",i);
00042 std::string redirect = Conf->ReadValue("badchan","redirect",i);
00043
00044 if (!redirect.empty())
00045 {
00046
00047 if (!ServerInstance->IsChannel(redirect.c_str(), ServerInstance->Config->Limits.ChanMax))
00048 {
00049 if (user)
00050 user->WriteServ("NOTICE %s :Invalid badchan redirect '%s'", user->nick.c_str(), redirect.c_str());
00051 throw ModuleException("Invalid badchan redirect, not a channel");
00052 }
00053
00054 for (int j =0; j < Conf->Enumerate("badchan"); j++)
00055 {
00056 if (InspIRCd::Match(redirect, Conf->ReadValue("badchan","name",j)))
00057 {
00058 bool goodchan = false;
00059 for (int k =0; k < Conf->Enumerate("goodchan"); k++)
00060 {
00061 if (InspIRCd::Match(redirect, Conf->ReadValue("goodchan","name",k)))
00062 goodchan = true;
00063 }
00064
00065 if (!goodchan)
00066 {
00067
00068 if (user)
00069 user->WriteServ("NOTICE %s :Badchan %s redirects to badchan %s", user->nick.c_str(), name.c_str(), redirect.c_str());
00070 throw ModuleException("Badchan redirect loop");
00071 }
00072 }
00073 }
00074 }
00075 }
00076 }
00077
00078 virtual ~ModuleDenyChannels()
00079 {
00080 delete Conf;
00081 }
00082
00083 virtual Version GetVersion()
00084 {
00085 return Version("$Id: m_denychans.cpp 10339 2008-08-28 19:57:17Z w00t $", VF_VENDOR,API_VERSION);
00086 }
00087
00088
00089 virtual int OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
00090 {
00091 for (int j =0; j < Conf->Enumerate("badchan"); j++)
00092 {
00093 if (InspIRCd::Match(cname, Conf->ReadValue("badchan","name",j)))
00094 {
00095 if (IS_OPER(user) && Conf->ReadFlag("badchan","allowopers",j))
00096 {
00097 return 0;
00098 }
00099 else
00100 {
00101 std::string reason = Conf->ReadValue("badchan","reason",j);
00102 std::string redirect = Conf->ReadValue("badchan","redirect",j);
00103
00104 for (int i = 0; i < Conf->Enumerate("goodchan"); i++)
00105 {
00106 if (InspIRCd::Match(cname, Conf->ReadValue("goodchan", "name", i)))
00107 {
00108 return 0;
00109 }
00110 }
00111
00112 if (ServerInstance->IsChannel(redirect.c_str(), ServerInstance->Config->Limits.ChanMax))
00113 {
00114
00115 Channel *newchan = ServerInstance->FindChan(redirect);
00116 if ((!newchan) || (!(newchan->IsModeSet('L'))))
00117 {
00118 user->WriteNumeric(926, "%s %s :Channel %s is forbidden, redirecting to %s: %s",user->nick.c_str(),cname,cname,redirect.c_str(), reason.c_str());
00119 Channel::JoinUser(ServerInstance,user,redirect.c_str(),false,"",false,ServerInstance->Time());
00120 return 1;
00121 }
00122 }
00123
00124 user->WriteNumeric(926, "%s %s :Channel %s is forbidden: %s",user->nick.c_str(),cname,cname,reason.c_str());
00125 return 1;
00126 }
00127 }
00128 }
00129 return 0;
00130 }
00131 };
00132
00133 MODULE_INIT(ModuleDenyChannels)