X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_cloaking.cpp;h=f729943b41b067748e3ee9af88b8a040ee64f892;hb=02c6ce1ad09a7471a6b03dc00bac4b843d157489;hp=ffa1890076aebc6932705e123a19400bc1c648ba;hpb=93b0dec6654e1b8249c7b01a4820d861f9bac149;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index ffa189007..f729943b4 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -2,25 +2,19 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. - * E-mail: - * - * - * - * Written by Craig Edwards, Craig McLure, and others. + * InspIRCd: (C) 2002-2007 InspIRCd Development Team + * See: http://www.inspircd.org/wiki/index.php/Credits + * * This program is free but copyrighted software; see * the file COPYING for details. * * --------------------------------------------------- */ -#include "inspircd_config.h" -#include "configreader.h" #include "inspircd.h" #include "users.h" #include "channels.h" #include "modules.h" - #include "m_hash.h" /* $ModDesc: Provides masking of user hostnames */ @@ -41,6 +35,37 @@ class CloakUser : public ModeHandler unsigned int key4; Module* Sender; Module* HashProvider; + + /** This function takes a domain name string and returns just the last two domain parts, + * or the last domain part if only two are available. Failing that it just returns what it was given. + * + * For example, if it is passed "svn.inspircd.org" it will return ".inspircd.org". + * If it is passed "brainbox.winbot.co.uk" it will return ".co.uk", + * and if it is passed "localhost.localdomain" it will return ".localdomain". + * + * This is used to ensure a significant part of the host is always cloaked (see Bug #216) + */ + std::string LastTwoDomainParts(const std::string &host) + { + int dots = 0; + std::string::size_type splitdot = host.length(); + + for (std::string::size_type x = host.length() - 1; x; --x) + { + if (host[x] == '.') + { + splitdot = x; + dots++; + } + if (dots >= 3) + break; + } + + if (splitdot == host.length()) + return host; + else + return host.substr(splitdot); + } public: CloakUser(InspIRCd* Instance, Module* Source, Module* Hash) : ModeHandler(Instance, 'x', 0, 0, false, MODETYPE_USER, false), Sender(Source), HashProvider(Hash) @@ -49,8 +74,7 @@ class CloakUser : public ModeHandler ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding) { - /* Only opers can change other users modes */ - if ((source != dest) && (!*source->oper)) + if (source != dest) return MODEACTION_DENY; /* For remote clients, we dont take any action, we just allow it. @@ -84,9 +108,8 @@ class CloakUser : public ModeHandler */ unsigned int iv[] = { key1, key2, key3, key4 }; - std::string a = (n1 ? n1 : n2); + std::string a = LastTwoDomainParts(dest->host); std::string b; - insp_inaddr testaddr; /** Reset the Hash module, and send it our IV and hex table */ HashResetRequest(Sender, HashProvider).Send(); @@ -101,16 +124,28 @@ class CloakUser : public ModeHandler * Their ISP shouldnt go to town on subdomains, or they shouldnt have a kiddie * vhost. */ - - if ((insp_aton(dest->host,&testaddr) < 1) && (hostcloak.length() <= 64)) - { - // if they have a hostname, make something appropriate +#ifdef IPV6 + in6_addr testaddr; + in_addr testaddr2; + if ((dest->GetProtocolFamily() == AF_INET6) && (inet_pton(AF_INET6,dest->host,&testaddr) < 1) && (hostcloak.length() <= 64)) + /* Invalid ipv6 address, and ipv6 user (resolved host) */ + b = hostcloak; + else if ((dest->GetProtocolFamily() == AF_INET) && (inet_aton(dest->host,&testaddr2) < 1) && (hostcloak.length() <= 64)) + /* Invalid ipv4 address, and ipv4 user (resolved host) */ b = hostcloak; - } else - { - b = ((b.find(':') == std::string::npos) ? Cloak4(dest->host) : Cloak6(dest->host)); - } + /* Valid ipv6 or ipv4 address (not resolved) ipv4 or ipv6 user */ + b = ((!strchr(dest->host,':')) ? Cloak4(dest->host) : Cloak6(dest->host)); +#else + in_addr testaddr; + if ((inet_aton(dest->host,&testaddr) < 1) && (hostcloak.length() <= 64)) + /* Invalid ipv4 address, and ipv4 user (resolved host) */ + b = hostcloak; + else + /* Valid ipv4 address (not resolved) ipv4 user */ + b = Cloak4(dest->host); +#endif + dest->ChangeDisplayedHost(b.c_str()); } @@ -168,9 +203,14 @@ class CloakUser : public ModeHandler std::string Cloak6(const char* ip) { + /* Theyre using 4in6 (YUCK). Translate as ipv4 cloak */ + if (!strncmp(ip, "0::ffff:", 8)) + return Cloak4(ip + 8); + + /* If we get here, yes it really is an ipv6 ip */ unsigned int iv[] = { key1, key2, key3, key4 }; std::vector hashies; - std::string item = ""; + std::string item; int rounds = 0; /* Reset the Hash module and send it our IV */ @@ -180,12 +220,12 @@ class CloakUser : public ModeHandler for (const char* input = ip; *input; input++) { item += *input; - if (item.length() > 5) + if (item.length() > 7) { /* Send the Hash module a different hex table for each octet group's Hash sum */ HashHexRequest(Sender, HashProvider, xtab[(key1+rounds) % 4]).Send(); - hashies.push_back(std::string(HashSumRequest(Sender, HashProvider, item).Send()).substr(0,10)); - item = ""; + hashies.push_back(std::string(HashSumRequest(Sender, HashProvider, item).Send()).substr(0,8)); + item.clear(); } rounds++; } @@ -193,8 +233,8 @@ class CloakUser : public ModeHandler { /* Send the Hash module a different hex table for each octet group's Hash sum */ HashHexRequest(Sender, HashProvider, xtab[(key1+rounds) % 4]).Send(); - hashies.push_back(std::string(HashSumRequest(Sender, HashProvider, item).Send()).substr(0,10)); - item = ""; + hashies.push_back(std::string(HashSumRequest(Sender, HashProvider, item).Send()).substr(0,8)); + item.clear(); } /* Stick them all together */ return irc::stringjoiner(":", hashies, 0, hashies.size() - 1).GetJoined(); @@ -228,9 +268,11 @@ class ModuleCloaking : public Module public: ModuleCloaking(InspIRCd* Me) - : Module::Module(Me) + : Module(Me) { - /* Attempt to locate the Hash service provider, bail if we can't find it */ + ServerInstance->UseInterface("HashRequest"); + + /* Attempt to locate the md5 service provider, bail if we can't find it */ HashModule = ServerInstance->FindModule("m_md5.so"); if (!HashModule) throw ModuleException("Can't find m_md5.so. Please load m_md5.so before m_cloaking.so."); @@ -239,15 +281,17 @@ class ModuleCloaking : public Module cu = new CloakUser(ServerInstance, this, HashModule); /* Register it with the core */ - ServerInstance->AddMode(cu, 'x'); + if (!ServerInstance->AddMode(cu, 'x')) + throw ModuleException("Could not add new modes!"); - OnRehash(""); + OnRehash(NULL,""); } virtual ~ModuleCloaking() { ServerInstance->Modes->DelMode(cu); DELETE(cu); + ServerInstance->DoneWithInterface("HashRequest"); } virtual Version GetVersion() @@ -257,7 +301,7 @@ class ModuleCloaking : public Module return Version(1,1,0,2,VF_COMMON|VF_VENDOR,API_VERSION); } - virtual void OnRehash(const std::string ¶meter) + virtual void OnRehash(userrec* user, const std::string ¶meter) { cu->DoRehash(); } @@ -289,7 +333,7 @@ class ModuleCloakingFactory : public ModuleFactory }; -extern "C" void * init_module( void ) +extern "C" DllExport void * init_module( void ) { return new ModuleCloakingFactory; }