]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_cloaking.cpp
Update wiki links to use HTTPS and point to the correct pages.
[user/henk/code/inspircd.git] / src / modules / m_cloaking.cpp
index 03ea90fbda0e020e17353fb4346c6d30cd98eff9..f4cfdb54f8b07c7186e11f1e5b27b1196a6c5ee5 100644 (file)
@@ -1,16 +1,28 @@
-/*       +------------------------------------+
- *       | Inspire Internet Relay Chat Daemon |
- *       +------------------------------------+
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
  *
- *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
- * See: http://wiki.inspircd.org/Credits
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
+ *   Copyright (C) 2003-2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 John Brooks <john.brooks@dereferenced.net>
+ *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
+ *   Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
  *
- * This program is free but copyrighted software; see
- *         the file COPYING for details.
+ * This file is part of InspIRCd.  InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
  *
- * ---------------------------------------------------
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+
 #include "inspircd.h"
 #include "hash.h"
 
@@ -81,9 +93,13 @@ class CloakUser : public ModeHandler
                /* don't allow this user to spam modechanges */
                if (source == dest)
                        user->CommandFloodPenalty += 5000;
-               
+
                if (adding)
                {
+                       // assume this is more correct
+                       if (user->registered != REG_ALL && user->host != user->dhost)
+                               return MODEACTION_DENY;
+
                        std::string* cloak = ext.get(user);
 
                        if (!cloak)
@@ -106,20 +122,32 @@ class CloakUser : public ModeHandler
                        /* User is removing the mode, so restore their real host
                         * and make it match the displayed one.
                         */
-                       user->ChangeDisplayedHost(user->host.c_str());
                        user->SetMode('x',false);
+                       user->ChangeDisplayedHost(user->host.c_str());
                        return MODEACTION_ALLOW;
                }
        }
 
 };
 
+class CommandCloak : public Command
+{
+ public:
+       CommandCloak(Module* Creator) : Command(Creator, "CLOAK", 1)
+       {
+               flags_needed = 'o';
+               syntax = "<host>";
+       }
+
+       CmdResult Handle(const std::vector<std::string> &parameters, User *user);
+};
 
 class ModuleCloaking : public Module
 {
- private:
+ public:
        CloakUser cu;
        CloakMode mode;
+       CommandCloak ck;
        std::string prefix;
        std::string suffix;
        std::string key;
@@ -127,8 +155,7 @@ class ModuleCloaking : public Module
        const char* xtab[4];
        dynamic_reference<HashProvider> Hash;
 
- public:
-       ModuleCloaking() : cu(this), mode(MODE_OPAQUE), Hash(this, "hash/md5")
+       ModuleCloaking() : cu(this), mode(MODE_OPAQUE), ck(this), Hash(this, "hash/md5")
        {
        }
 
@@ -136,14 +163,12 @@ class ModuleCloaking : public Module
        {
                OnRehash(NULL);
 
-               /* Register it with the core */
-               if (!ServerInstance->Modes->AddMode(&cu))
-                       throw ModuleException("Could not add new modes!");
-
-               ServerInstance->Extensions.Register(&cu.ext);
+               ServerInstance->Modules->AddService(cu);
+               ServerInstance->Modules->AddService(ck);
+               ServerInstance->Modules->AddService(cu.ext);
 
                Implementation eventlist[] = { I_OnRehash, I_OnCheckBan, I_OnUserConnect, I_OnChangeHost };
-               ServerInstance->Modules->Attach(eventlist, this, 4);
+               ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
        }
 
        /** This function takes a domain name string and returns just the last two domain parts,
@@ -189,7 +214,7 @@ class ModuleCloaking : public Module
                input.reserve(key.length() + 3 + item.length());
                input.append(1, id);
                input.append(key);
-               input.append(1, 0); // null does not terminate a C++ string
+               input.append(1, '\0'); // null does not terminate a C++ string
                input.append(item);
 
                std::string rv = Hash->sum(input).substr(0,len);
@@ -247,14 +272,14 @@ class ModuleCloaking : public Module
                        item += *input;
                        if (item.length() > 7)
                        {
-                               hashies.push_back(Hash->sumIV(compatkey, xtab[(compatkey[1]+rounds) % 4], item).substr(0,8));
+                               hashies.push_back(Hash->sumIV(compatkey, xtab[(compatkey[0]+rounds) % 4], item).substr(0,8));
                                item.clear();
                        }
                        rounds++;
                }
                if (!item.empty())
                {
-                       hashies.push_back(Hash->sumIV(compatkey, xtab[(compatkey[1]+rounds) % 4], item).substr(0,8));
+                       hashies.push_back(Hash->sumIV(compatkey, xtab[(compatkey[0]+rounds) % 4], item).substr(0,8));
                }
                /* Stick them all together */
                return irc::stringjoiner(":", hashies, 0, hashies.size() - 1).GetJoined();
@@ -356,7 +381,11 @@ class ModuleCloaking : public Module
        // mode change, we will call SetMode back to true AFTER the host change is done.
        void OnChangeHost(User* u, const std::string& host)
        {
-               u->SetMode('x', false);
+               if(u->IsModeSet('x'))
+               {
+                       u->SetMode('x', false);
+                       u->WriteServ("MODE %s -x", u->nick.c_str());
+               }
        }
 
        ~ModuleCloaking()
@@ -464,25 +493,23 @@ class ModuleCloaking : public Module
                }
        }
 
-       void OnUserConnect(LocalUser* dest)
+       std::string GenCloak(const irc::sockets::sockaddrs& ip, const std::string& ipstr, const std::string& host)
        {
-               std::string* cloak = cu.ext.get(dest);
-               if (cloak)
-                       return;
-
-               std::string ipstr = dest->GetIPString();
                std::string chost;
 
+               irc::sockets::sockaddrs hostip;
+               bool host_is_ip = irc::sockets::aptosa(host, ip.port(), hostip) && hostip == ip;
+
                switch (mode)
                {
                        case MODE_COMPAT_HOST:
                        {
-                               if (ipstr != dest->host)
+                               if (!host_is_ip)
                                {
-                                       std::string tail = LastTwoDomainParts(dest->host);
+                                       std::string tail = LastTwoDomainParts(host);
 
-                                       /* Generate a cloak using specialized Hash */
-                                       chost = prefix + "-" + Hash->sumIV(compatkey, xtab[(dest->host[0]) % 4], dest->host).substr(0,8) + tail;
+                                       // xtab is not used here due to a bug in 1.2 cloaking
+                                       chost = prefix + "-" + Hash->sumIV(compatkey, "0123456789abcdef", host).substr(0,8) + tail;
 
                                        /* Fix by brain - if the cloaked host is > the max length of a host (64 bytes
                                         * according to the DNS RFC) then they get cloaked as an IP.
@@ -493,26 +520,50 @@ class ModuleCloaking : public Module
                                // fall through to IP cloak
                        }
                        case MODE_COMPAT_IPONLY:
-                               if (dest->client_sa.sa.sa_family == AF_INET6)
+                               if (ip.sa.sa_family == AF_INET6)
                                        chost = CompatCloak6(ipstr.c_str());
                                else
                                        chost = CompatCloak4(ipstr.c_str());
                                break;
                        case MODE_HALF_CLOAK:
                        {
-                               if (ipstr != dest->host)
-                                       chost = prefix + SegmentCloak(dest->host, 1, 6) + LastTwoDomainParts(dest->host);
+                               if (!host_is_ip)
+                                       chost = prefix + SegmentCloak(host, 1, 6) + LastTwoDomainParts(host);
                                if (chost.empty() || chost.length() > 50)
-                                       chost = SegmentIP(dest->client_sa, false);
+                                       chost = SegmentIP(ip, false);
                                break;
                        }
                        case MODE_OPAQUE:
                        default:
-                               chost = SegmentIP(dest->client_sa, true);
+                               chost = SegmentIP(ip, true);
                }
-               cu.ext.set(dest,chost);
+               return chost;
        }
 
+       void OnUserConnect(LocalUser* dest)
+       {
+               std::string* cloak = cu.ext.get(dest);
+               if (cloak)
+                       return;
+
+               cu.ext.set(dest, GenCloak(dest->client_sa, dest->GetIPString(), dest->host));
+       }
 };
 
+CmdResult CommandCloak::Handle(const std::vector<std::string> &parameters, User *user)
+{
+       ModuleCloaking* mod = (ModuleCloaking*)(Module*)creator;
+       irc::sockets::sockaddrs sa;
+       std::string cloak;
+
+       if (irc::sockets::aptosa(parameters[0], 0, sa))
+               cloak = mod->GenCloak(sa, parameters[0], parameters[0]);
+       else
+               cloak = mod->GenCloak(sa, "", parameters[0]);
+
+       user->WriteServ("NOTICE %s :*** Cloak for %s is %s", user->nick.c_str(), parameters[0].c_str(), cloak.c_str());
+
+       return CMD_SUCCESS;
+}
+
 MODULE_INIT(ModuleCloaking)