The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

m_hostchange.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 #include "inspircd.h"
00015 
00016 /* $ModDesc: Provides masking of user hostnames in a different way to m_cloaking */
00017 
00020 class Host : public classbase
00021 {
00022  public:
00023         std::string action;
00024         std::string newhost;
00025         std::string ports;
00026 };
00027 
00028 typedef std::map<std::string,Host*> hostchanges_t;
00029 
00030 class ModuleHostChange : public Module
00031 {
00032  private:
00033         hostchanges_t hostchanges;
00034         std::string MySuffix;
00035         std::string MyPrefix;
00036         std::string MySeparator;
00037 
00038  public:
00039         ModuleHostChange(InspIRCd* Me)
00040                 : Module(Me)
00041         {
00042                 OnRehash(NULL,"");
00043                 Implementation eventlist[] = { I_OnRehash, I_OnUserConnect };
00044                 ServerInstance->Modules->Attach(eventlist, this, 2);
00045         }
00046 
00047         virtual ~ModuleHostChange()
00048         {
00049                 for (hostchanges_t::iterator i = hostchanges.begin(); i != hostchanges.end(); i++)
00050                 {
00051                         delete i->second;
00052                 }
00053                 hostchanges.clear();
00054         }
00055 
00056         void Prioritize()
00057         {
00058                 Module* cloak = ServerInstance->Modules->Find("m_cloaking.so");
00059                 ServerInstance->Modules->SetPriority(this, I_OnUserConnect, PRIO_AFTER, &cloak);
00060         }
00061 
00062 
00063         virtual void OnRehash(User* user, const std::string &parameter)
00064         {
00065                 ConfigReader Conf(ServerInstance);
00066                 MySuffix = Conf.ReadValue("host","suffix",0);
00067                 MyPrefix = Conf.ReadValue("host","prefix","",0);
00068                 MySeparator = Conf.ReadValue("host","separator",".",0);
00069                 for (hostchanges_t::iterator i = hostchanges.begin(); i != hostchanges.end(); i++)
00070                 {
00071                         delete i->second;
00072                 }
00073                 hostchanges.clear();
00074                 for (int index = 0; index < Conf.Enumerate("hostchange"); index++)
00075                 {
00076                         std::string mask = Conf.ReadValue("hostchange", "mask", index);
00077                         std::string ports = Conf.ReadValue("hosthange", "ports", index);
00078                         std::string action = Conf.ReadValue("hostchange", "action", index);
00079                         std::string newhost = Conf.ReadValue("hostchange", "value", index);
00080                         Host* x = new Host;
00081                         x->action = action;
00082                         x->ports = ports;
00083                         x->newhost = newhost;
00084                         hostchanges[mask] = x;
00085                 }
00086         }
00087 
00088         virtual Version GetVersion()
00089         {
00090                 // returns the version number of the module to be
00091                 // listed in /MODULES
00092                 return Version("$Id: m_hostchange.cpp 10291 2008-08-25 20:35:51Z w00t $", VF_VENDOR, API_VERSION);
00093         }
00094 
00095         virtual void OnUserConnect(User* user)
00096         {
00097                 for (hostchanges_t::iterator i = hostchanges.begin(); i != hostchanges.end(); i++)
00098                 {
00099                         if (((InspIRCd::MatchCIDR(user->MakeHost(), i->first)) || (InspIRCd::MatchCIDR(user->MakeHostIP(), i->first))))
00100                         {
00101                                 Host* h = i->second;
00102 
00103                                 if (!h->ports.empty())
00104                                 {
00105                                         irc::portparser portrange(h->ports, false);
00106                                         long portno = -1;
00107                                         bool foundany = false;
00108 
00109                                         while ((portno = portrange.GetToken()))
00110                                                 if (portno == user->GetPort())
00111                                                         foundany = true;
00112 
00113                                         if (!foundany)
00114                                                 continue;
00115                                 }
00116 
00117                                 // host of new user matches a hostchange tag's mask
00118                                 std::string newhost;
00119                                 if (h->action == "set")
00120                                 {
00121                                         newhost = h->newhost;
00122                                 }
00123                                 else if (h->action == "suffix")
00124                                 {
00125                                         newhost = MySuffix;
00126                                 }
00127                                 else if (h->action == "addnick")
00128                                 {
00129                                         // first take their nick and strip out non-dns, leaving just [A-Z0-9\-]
00130                                         std::string complete;
00131                                         std::string old = user->nick;
00132                                         for (unsigned int j = 0; j < old.length(); j++)
00133                                         {
00134                                                 if  (((old[j] >= 'A') && (old[j] <= 'Z')) ||
00135                                                     ((old[j] >= 'a') && (old[j] <= 'z')) ||
00136                                                     ((old[j] >= '0') && (old[j] <= '9')) ||
00137                                                     (old[j] == '-'))
00138                                                 {
00139                                                         complete = complete + old[j];
00140                                                 }
00141                                         }
00142                                         if (complete.empty())
00143                                                 complete = "i-have-a-lame-nick";
00144 
00145                                         if (!MyPrefix.empty())
00146                                                 newhost = MyPrefix + MySeparator + complete;
00147                                         else
00148                                                 newhost = complete + MySeparator + MySuffix;
00149                                 }
00150                                 if (!newhost.empty())
00151                                 {
00152                                         user->WriteServ("NOTICE "+std::string(user->nick)+" :Setting your virtual host: " + newhost);
00153                                         if (!user->ChangeDisplayedHost(newhost.c_str()))
00154                                                 user->WriteServ("NOTICE "+std::string(user->nick)+" :Could not set your virtual host: " + newhost);
00155                                         return;
00156                                 }
00157                         }
00158                 }
00159         }
00160 };
00161 
00162 MODULE_INIT(ModuleHostChange)