]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_cgiirc.cpp
Fix some of the include guard names (requested by SaberUK)
[user/henk/code/inspircd.git] / src / modules / m_cgiirc.cpp
index 49a96c42d90878d8e0c661fa284f528af244600e..a5144e36d0cd7f5994be1bdfd8e92ee700dbc316 100644 (file)
@@ -2,7 +2,7 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
  * See: http://wiki.inspircd.org/Credits
  *
  * This program is free but copyrighted software; see
@@ -53,16 +53,16 @@ typedef std::vector<CGIhost> CGIHostlist;
  */
 class CommandWebirc : public Command
 {
-       bool notify;
  public:
+       bool notify;
        StringExtItem realhost;
        StringExtItem realip;
        LocalStringExt webirc_hostname;
        LocalStringExt webirc_ip;
 
        CGIHostlist Hosts;
-       CommandWebirc(Module* Creator, bool bnotify)
-               : Command(Creator, "WEBIRC", 4), notify(bnotify),
+       CommandWebirc(Module* Creator)
+               : Command(Creator, "WEBIRC", 4),
                  realhost("cgiirc_realhost", Creator), realip("cgiirc_realip", Creator),
                  webirc_hostname("cgiirc_webirc_hostname", Creator), webirc_ip("cgiirc_webirc_ip", Creator)
                {
@@ -102,26 +102,30 @@ class CommandWebirc : public Command
 class CGIResolver : public Resolver
 {
        std::string typ;
-       int theirfd;
-       LocalUser* them;
+       std::string theiruid;
+       LocalIntExt& waiting;
        bool notify;
  public:
-       CGIResolver(Module* me, bool NotifyOpers, const std::string &source, bool forward, LocalUser* u, int userfd, const std::string &type, bool &cached)
-               : Resolver(source, forward ? DNS_QUERY_A : DNS_QUERY_PTR4, cached, me), typ(type), theirfd(userfd), them(u), notify(NotifyOpers) { }
+       CGIResolver(Module* me, bool NotifyOpers, const std::string &source, bool forward, LocalUser* u,
+                       const std::string &type, bool &cached, LocalIntExt& ext)
+               : Resolver(source, forward ? DNS_QUERY_A : DNS_QUERY_PTR4, cached, me), typ(type), theiruid(u->uuid),
+               waiting(ext), notify(NotifyOpers)
+       {
+       }
 
        virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
        {
                /* Check the user still exists */
-               if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
+               User* them = ServerInstance->FindUUID(theiruid);
+               if (them)
                {
                        if (notify)
                                ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", them->nick.c_str(), them->host.c_str(), result.c_str(), typ.c_str());
 
-                       them->host.assign(result,0, 64);
-                       them->dhost.assign(result, 0, 64);
-                       if (querytype)
-                               them->SetClientIP(result.c_str());
-                       them->ident.assign("~cgiirc", 0, 8);
+                       if (result.length() > 64)
+                               return;
+                       them->host = result;
+                       them->dhost = result;
                        them->InvalidateCache();
                        them->CheckLines(true);
                }
@@ -129,7 +133,8 @@ class CGIResolver : public Resolver
 
        virtual void OnError(ResolverError e, const std::string &errormessage)
        {
-               if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
+               User* them = ServerInstance->FindUUID(theiruid);
+               if (them)
                {
                        if (notify)
                                ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but their host can't be resolved from their %s!", them->nick.c_str(), them->host.c_str(), typ.c_str());
@@ -138,15 +143,25 @@ class CGIResolver : public Resolver
 
        virtual ~CGIResolver()
        {
+               User* them = ServerInstance->FindUUID(theiruid);
+               if (!them)
+                       return;
+               int count = waiting.get(them);
+               if (count)
+                       waiting.set(them, count - 1);
        }
 };
 
 class ModuleCgiIRC : public Module
 {
        CommandWebirc cmd;
-       bool NotifyOpers;
+       LocalIntExt waiting;
 public:
-       ModuleCgiIRC() : cmd(this, NotifyOpers)
+       ModuleCgiIRC() : cmd(this), waiting("cgiirc-delay", this)
+       {
+       }
+
+       void init()
        {
                OnRehash(NULL);
                ServerInstance->AddCommand(&cmd);
@@ -155,31 +170,31 @@ public:
                ServerInstance->Extensions.Register(&cmd.webirc_hostname);
                ServerInstance->Extensions.Register(&cmd.webirc_ip);
 
-               Implementation eventlist[] = { I_OnRehash, I_OnUserRegister, I_OnSyncUser, I_OnDecodeMetaData, I_OnUserDisconnect, I_OnUserConnect };
-               ServerInstance->Modules->Attach(eventlist, this, 6);
+               Implementation eventlist[] = { I_OnRehash, I_OnUserRegister, I_OnCheckReady, I_OnUserConnect };
+               ServerInstance->Modules->Attach(eventlist, this, 4);
        }
 
-
-       virtual void Prioritize()
+       void Prioritize()
        {
                ServerInstance->Modules->SetPriority(this, I_OnUserConnect, PRIORITY_FIRST);
+               Module* umodes = ServerInstance->Modules->Find("m_conn_umodes.so");
+               ServerInstance->Modules->SetPriority(this, I_OnUserConnect, PRIORITY_BEFORE, &umodes);
        }
 
-       virtual void OnRehash(User* user)
+       void OnRehash(User* user)
        {
-               ConfigReader Conf;
                cmd.Hosts.clear();
 
-               NotifyOpers = Conf.ReadFlag("cgiirc", "opernotice", 0); // If we send an oper notice when a CGI:IRC has their host changed.
-
-               if(Conf.GetError() == CONF_VALUE_NOT_FOUND)
-                       NotifyOpers = true;
+               // Do we send an oper notice when a CGI:IRC has their host changed?
+               cmd.notify = ServerInstance->Config->ConfValue("cgiirc")->getBool("opernotice", true);
 
-               for(int i = 0; i < Conf.Enumerate("cgihost"); i++)
+               ConfigTagList tags = ServerInstance->Config->ConfTags("cgihost");
+               for (ConfigIter i = tags.first; i != tags.second; ++i)
                {
-                       std::string hostmask = Conf.ReadValue("cgihost", "mask", i); // An allowed CGI:IRC host
-                       std::string type = Conf.ReadValue("cgihost", "type", i); // What type of user-munging we do on this host.
-                       std::string password = Conf.ReadValue("cgihost", "password", i);
+                       ConfigTag* tag = i->second;
+                       std::string hostmask = tag->getString("mask"); // An allowed CGI:IRC host
+                       std::string type = tag->getString("type"); // What type of user-munging we do on this host.
+                       std::string password = tag->getString("password");
 
                        if(hostmask.length())
                        {
@@ -214,7 +229,14 @@ public:
                }
        }
 
-       virtual ModResult OnUserRegister(LocalUser* user)
+       ModResult OnCheckReady(LocalUser *user)
+       {
+               if (waiting.get(user))
+                       return MOD_RES_DENY;
+               return MOD_RES_PASSTHRU;
+       }
+
+       ModResult OnUserRegister(LocalUser* user)
        {
                for(CGIHostlist::iterator iter = cmd.Hosts.begin(); iter != cmd.Hosts.end(); iter++)
                {
@@ -257,24 +279,23 @@ public:
        {
                std::string *webirc_hostname = cmd.webirc_hostname.get(user);
                std::string *webirc_ip = cmd.webirc_ip.get(user);
-               if (webirc_hostname)
-               {
-                       user->host.assign(*webirc_hostname, 0, 64);
-                       user->dhost.assign(*webirc_hostname, 0, 64);
-                       user->InvalidateCache();
-                       cmd.webirc_hostname.unset(user);
-               }
-               if (webirc_ip)
-               {
-                       ServerInstance->Users->RemoveCloneCounts(user);
-                       user->SetClientIP(webirc_ip->c_str());
-                       user->InvalidateCache();
-                       cmd.webirc_ip.unset(user);
-                       ServerInstance->Users->AddLocalClone(user);
-                       ServerInstance->Users->AddGlobalClone(user);
-                       user->CheckClass();
-                       user->CheckLines(true);
-               }
+               if (!webirc_ip)
+                       return;
+               ServerInstance->Users->RemoveCloneCounts(user);
+               user->SetClientIP(webirc_ip->c_str());
+               user->InvalidateCache();
+               if (webirc_hostname && webirc_hostname->length() < 64)
+                       user->host = user->dhost = *webirc_hostname;
+               else
+                       user->host = user->dhost = user->GetIPString();
+               user->InvalidateCache();
+               ServerInstance->Users->AddLocalClone(user);
+               ServerInstance->Users->AddGlobalClone(user);
+               user->SetClass();
+               user->CheckClass();
+               user->CheckLines(true);
+               cmd.webirc_ip.unset(user);
+               cmd.webirc_hostname.unset(user);
        }
 
        bool CheckPass(LocalUser* user)
@@ -283,38 +304,28 @@ public:
                {
                        cmd.realhost.set(user, user->host);
                        cmd.realip.set(user, user->GetIPString());
-                       user->host.assign(user->password, 0, 64);
-                       user->dhost.assign(user->password, 0, 64);
+                       user->host = user->password;
+                       user->dhost = user->password;
                        user->InvalidateCache();
 
-                       bool valid = false;
                        ServerInstance->Users->RemoveCloneCounts(user);
-                       valid = user->SetClientIP(user->password.c_str());
+                       user->SetClientIP(user->password.c_str());
                        ServerInstance->Users->AddLocalClone(user);
                        ServerInstance->Users->AddGlobalClone(user);
+                       user->SetClass();
                        user->CheckClass();
 
-                       if (valid)
+                       try
                        {
-                               /* We were given a IP in the password, we don't do DNS so they get this is as their host as well. */
-                               if(NotifyOpers)
-                                       ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from PASS", user->nick.c_str(), user->host.c_str(), user->password.c_str());
+                               bool cached;
+                               CGIResolver* r = new CGIResolver(this, cmd.notify, user->password, false, user, "PASS", cached, waiting);
+                               ServerInstance->AddResolver(r, cached);
+                               waiting.set(user, waiting.get(user) + 1);
                        }
-                       else
+                       catch (...)
                        {
-                               /* We got as resolved hostname in the password. */
-                               try
-                               {
-
-                                       bool cached;
-                                       CGIResolver* r = new CGIResolver(this, NotifyOpers, user->password, false, user, user->GetFd(), "PASS", cached);
-                                       ServerInstance->AddResolver(r, cached);
-                               }
-                               catch (...)
-                               {
-                                       if (NotifyOpers)
-                                               ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but I could not resolve their hostname!", user->nick.c_str(), user->host.c_str());
-                               }
+                               if (cmd.notify)
+                                       ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but I could not resolve their hostname!", user->nick.c_str(), user->host.c_str());
                        }
 
                        user->password.clear();
@@ -350,6 +361,7 @@ public:
                user->SetClientIP(newipstr);
                ServerInstance->Users->AddLocalClone(user);
                ServerInstance->Users->AddGlobalClone(user);
+               user->SetClass();
                user->CheckClass();
                user->host = newipstr;
                user->dhost = newipstr;
@@ -358,14 +370,15 @@ public:
                {
 
                        bool cached;
-                       CGIResolver* r = new CGIResolver(this, NotifyOpers, newipstr, false, user, user->GetFd(), "IDENT", cached);
+                       CGIResolver* r = new CGIResolver(this, cmd.notify, newipstr, false, user, "IDENT", cached, waiting);
                        ServerInstance->AddResolver(r, cached);
+                       waiting.set(user, waiting.get(user) + 1);
                }
                catch (...)
                {
                        user->InvalidateCache();
 
-                       if(NotifyOpers)
+                       if(cmd.notify)
                                 ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but I could not resolve their hostname!", user->nick.c_str(), user->host.c_str());
                }
 
@@ -374,7 +387,7 @@ public:
 
        bool IsValidHost(const std::string &host)
        {
-               if(!host.size())
+               if(!host.size() || host.size() > 64)
                        return false;
 
                for(unsigned int i = 0; i < host.size(); i++)