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

CloakUser Class Reference

Handles user mode +x. More...

Inheritance diagram for CloakUser:

Inheritance graph
[legend]
Collaboration diagram for CloakUser:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 CloakUser (InspIRCd *Instance, Module *Source, Module *Hash)
ModeAction OnModeChange (userrec *source, userrec *dest, chanrec *channel, std::string &parameter, bool adding)
std::string Cloak4 (const char *ip)
std::string Cloak6 (const char *ip)
void DoRehash ()

Private Member Functions

std::string LastTwoDomainParts (const std::string &host)
 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.

Private Attributes

std::string prefix
 Mode prefix, or 0.
unsigned int key1
unsigned int key2
unsigned int key3
unsigned int key4
bool ipalways
ModuleSender
ModuleHashProvider
const char * xtab [4]

Detailed Description

Handles user mode +x.

Definition at line 25 of file m_cloaking.cpp.


Constructor & Destructor Documentation

CloakUser::CloakUser InspIRCd Instance,
Module Source,
Module Hash
[inline]
 

Definition at line 69 of file m_cloaking.cpp.

00069                                                                     : ModeHandler(Instance, 'x', 0, 0, false, MODETYPE_USER, false), Sender(Source), HashProvider(Hash)
00070         {
00071         }


Member Function Documentation

std::string CloakUser::Cloak4 const char *  ip  )  [inline]
 

Definition at line 185 of file m_cloaking.cpp.

References irc::sepstream::GetToken(), HashProvider, key1, key2, key3, key4, Sender, and xtab.

Referenced by Cloak6(), and OnModeChange().

00186         {
00187                 unsigned int iv[] = { key1, key2, key3, key4 };
00188                 irc::sepstream seps(ip, '.');
00189                 std::string ra[4];;
00190                 std::string octet[4];
00191                 int i[4];
00192 
00193                 for (int j = 0; j < 4; j++)
00194                 {
00195                         seps.GetToken(octet[j]);
00196                         i[j] = atoi(octet[j].c_str());
00197                 }
00198 
00199                 octet[3] = octet[0] + "." + octet[1] + "." + octet[2] + "." + octet[3];
00200                 octet[2] = octet[0] + "." + octet[1] + "." + octet[2];
00201                 octet[1] = octet[0] + "." + octet[1];
00202 
00203                 /* Reset the Hash module and send it our IV */
00204                 HashResetRequest(Sender, HashProvider).Send();
00205                 HashKeyRequest(Sender, HashProvider, iv).Send();
00206 
00207                 /* Send the Hash module a different hex table for each octet group's Hash sum */
00208                 for (int k = 0; k < 4; k++)
00209                 {
00210                         HashHexRequest(Sender, HashProvider, xtab[(iv[k]+i[k]) % 4]).Send();
00211                         ra[k] = std::string(HashSumRequest(Sender, HashProvider, octet[k]).Send()).substr(0,6);
00212                 }
00213                 /* Stick them all together */
00214                 return std::string().append(ra[0]).append(".").append(ra[1]).append(".").append(ra[2]).append(".").append(ra[3]);
00215         }

std::string CloakUser::Cloak6 const char *  ip  )  [inline]
 

Definition at line 217 of file m_cloaking.cpp.

References Cloak4(), HashProvider, key1, key2, key3, key4, Sender, and xtab.

Referenced by OnModeChange().

00218         {
00219                 /* Theyre using 4in6 (YUCK). Translate as ipv4 cloak */
00220                 if (!strncmp(ip, "0::ffff:", 8))
00221                         return Cloak4(ip + 8);
00222 
00223                 /* If we get here, yes it really is an ipv6 ip */
00224                 unsigned int iv[] = { key1, key2, key3, key4 };
00225                 std::vector<std::string> hashies;
00226                 std::string item;
00227                 int rounds = 0;
00228 
00229                 /* Reset the Hash module and send it our IV */
00230                 HashResetRequest(Sender, HashProvider).Send();
00231                 HashKeyRequest(Sender, HashProvider, iv).Send();
00232 
00233                 for (const char* input = ip; *input; input++)
00234                 {
00235                         item += *input;
00236                         if (item.length() > 7)
00237                         {
00238                                 /* Send the Hash module a different hex table for each octet group's Hash sum */
00239                                 HashHexRequest(Sender, HashProvider, xtab[(key1+rounds) % 4]).Send();
00240                                 hashies.push_back(std::string(HashSumRequest(Sender, HashProvider, item).Send()).substr(0,8));
00241                                 item.clear();
00242                         }
00243                         rounds++;
00244                 }
00245                 if (!item.empty())
00246                 {
00247                         /* Send the Hash module a different hex table for each octet group's Hash sum */
00248                         HashHexRequest(Sender, HashProvider, xtab[(key1+rounds) % 4]).Send();
00249                         hashies.push_back(std::string(HashSumRequest(Sender, HashProvider, item).Send()).substr(0,8));
00250                         item.clear();
00251                 }
00252                 /* Stick them all together */
00253                 return irc::stringjoiner(":", hashies, 0, hashies.size() - 1).GetJoined();
00254         }

void CloakUser::DoRehash  )  [inline]
 

Definition at line 256 of file m_cloaking.cpp.

References Conf, InspIRCd::Config, ipalways, key1, key2, key3, key4, ServerConfig::Network, prefix, ConfigReader::ReadFlag(), ConfigReader::ReadInteger(), ConfigReader::ReadValue(), ModeHandler::ServerInstance, and xtab.

Referenced by ModuleCloaking::OnRehash().

00257         {
00258                 ConfigReader Conf(ServerInstance);
00259                 bool lowercase;
00260 
00261                 key1 = key2 = key3 = key4 = 0;
00262                 key1 = Conf.ReadInteger("cloak","key1",0,true);
00263                 key2 = Conf.ReadInteger("cloak","key2",0,true);
00264                 key3 = Conf.ReadInteger("cloak","key3",0,true);
00265                 key4 = Conf.ReadInteger("cloak","key4",0,true);
00266                 prefix = Conf.ReadValue("cloak","prefix",0);
00267                 ipalways = Conf.ReadFlag("cloak", "ipalways", 0);
00268                 lowercase = Conf.ReadFlag("cloak", "lowercase", 0);
00269                 
00270                 if (!lowercase)
00271                 {
00272                         xtab[0] = "F92E45D871BCA630";
00273                         xtab[1] = "A1B9D80C72E653F4";
00274                         xtab[2] = "1ABC078934DEF562";
00275                         xtab[3] = "ABCDEF5678901234";
00276                 }
00277                 else
00278                 {
00279                         xtab[0] = "f92e45d871bca630";
00280                         xtab[1] = "a1b9d80c72e653f4";
00281                         xtab[2] = "1abc078934def562";
00282                         xtab[3] = "abcdef5678901234";
00283                 }
00284 
00285                 if (prefix.empty())
00286                         prefix = ServerInstance->Config->Network;
00287 
00288                 if (!key1 || !key2 || !key3 || !key4)
00289                 {
00290                         std::string detail;
00291                         if (!key1)
00292                                 detail = "<cloak:key1> is not valid, it may be set to a too high/low value, or it may not exist.";
00293                         else if (!key2)
00294                                 detail = "<cloak:key2> is not valid, it may be set to a too high/low value, or it may not exist.";
00295                         else if (!key3)
00296                                 detail = "<cloak:key3> is not valid, it may be set to a too high/low value, or it may not exist.";
00297                         else if (!key4)
00298                                 detail = "<cloak:key4> is not valid, it may be set to a too high/low value, or it may not exist.";
00299 
00300                         throw ModuleException("You have not defined cloak keys for m_cloaking!!! THIS IS INSECURE AND SHOULD BE CHECKED! - " + detail);
00301                 }
00302         }

std::string CloakUser::LastTwoDomainParts const std::string host  )  [inline, private]
 

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)

Definition at line 46 of file m_cloaking.cpp.

Referenced by OnModeChange().

00047         {
00048                 int dots = 0;
00049                 std::string::size_type splitdot = host.length();
00050 
00051                 for (std::string::size_type x = host.length() - 1; x; --x)
00052                 {
00053                         if (host[x] == '.')
00054                         {
00055                                 splitdot = x;
00056                                 dots++;
00057                         }
00058                         if (dots >= 3)
00059                                 break;
00060                 }
00061 
00062                 if (splitdot == host.length())
00063                         return host;
00064                 else
00065                         return host.substr(splitdot);
00066         }

ModeAction CloakUser::OnModeChange userrec source,
userrec dest,
chanrec channel,
std::string parameter,
bool  adding
[inline, virtual]
 

Reset the Hash module, and send it our IV and hex table

Reimplemented from ModeHandler.

Definition at line 73 of file m_cloaking.cpp.

References userrec::ChangeDisplayedHost(), Cloak4(), Cloak6(), userrec::GetIPString(), userrec::GetProtocolFamily(), HashProvider, connection::host, ipalways, IS_LOCAL, userrec::IsModeSet(), key1, key2, key3, key4, LastTwoDomainParts(), MODEACTION_ALLOW, MODEACTION_DENY, prefix, Sender, userrec::SetMode(), and xtab.

00074         {
00075                 if (source != dest)
00076                         return MODEACTION_DENY;
00077 
00078                 /* For remote clients, we dont take any action, we just allow it.
00079                  * The local server where they are will set their cloak instead.
00080                  */
00081                 if (!IS_LOCAL(dest))
00082                         return MODEACTION_ALLOW;
00083 
00084                 if (adding)
00085                 {
00086                         if(!dest->IsModeSet('x'))
00087                         {
00088                                 /* The mode is being turned on - so attempt to
00089                                  * allocate the user a cloaked host using a non-reversible
00090                                  * algorithm (its simple, but its non-reversible so the
00091                                  * simplicity doesnt really matter). This algorithm
00092                                  * will not work if the user has only one level of domain
00093                                  * naming in their hostname (e.g. if they are on a lan or
00094                                  * are connecting via localhost) -- this doesnt matter much.
00095                                  */
00096 
00097                                 char* n1 = strchr(dest->host,'.');
00098                                 char* n2 = strchr(dest->host,':');
00099                         
00100                                 if (n1 || n2)
00101                                 {
00102                                         unsigned int iv[] = { key1, key2, key3, key4 };
00103                                         std::string a = LastTwoDomainParts(dest->host);
00104                                         std::string b;
00105 
00106                                         /* InspIRCd users have two hostnames; A displayed
00107                                          * hostname which can be modified by modules (e.g.
00108                                          * to create vhosts, implement chghost, etc) and a
00109                                          * 'real' hostname which you shouldnt write to.
00110                                          */
00111 
00112                                         /* 2008/08/18: add <cloak:ipalways> which always cloaks
00113                                          * the IP, for anonymity. --nenolod
00114                                          */
00115                                         if (!ipalways)
00116                                         {
00118                                                 HashResetRequest(Sender, HashProvider).Send();
00119                                                 HashKeyRequest(Sender, HashProvider, iv).Send();
00120                                                 HashHexRequest(Sender, HashProvider, xtab[(*dest->host) % 4]);
00121 
00122                                                 /* Generate a cloak using specialized Hash */
00123                                                 std::string hostcloak = prefix + "-" + std::string(HashSumRequest(Sender, HashProvider, dest->host).Send()).substr(0,8) + a;
00124 
00125                                                 /* Fix by brain - if the cloaked host is > the max length of a host (64 bytes
00126                                                  * according to the DNS RFC) then tough titty, they get cloaked as an IP. 
00127                                                  * Their ISP shouldnt go to town on subdomains, or they shouldnt have a kiddie
00128                                                  * vhost.
00129                                                  */
00130 #ifdef IPV6
00131                                                 in6_addr testaddr;
00132                                                 in_addr testaddr2;
00133                                                 if ((dest->GetProtocolFamily() == AF_INET6) && (inet_pton(AF_INET6,dest->host,&testaddr) < 1) && (hostcloak.length() <= 64))
00134                                                         /* Invalid ipv6 address, and ipv6 user (resolved host) */
00135                                                         b = hostcloak;
00136                                                 else if ((dest->GetProtocolFamily() == AF_INET) && (inet_aton(dest->host,&testaddr2) < 1) && (hostcloak.length() <= 64))
00137                                                         /* Invalid ipv4 address, and ipv4 user (resolved host) */
00138                                                         b = hostcloak;
00139                                                 else
00140                                                         /* Valid ipv6 or ipv4 address (not resolved) ipv4 or ipv6 user */
00141                                                         b = ((!strchr(dest->host,':')) ? Cloak4(dest->host) : Cloak6(dest->host));
00142 #else
00143                                                 in_addr testaddr;
00144                                                 if ((inet_aton(dest->host,&testaddr) < 1) && (hostcloak.length() <= 64))
00145                                                         /* Invalid ipv4 address, and ipv4 user (resolved host) */
00146                                                         b = hostcloak;
00147                                                 else
00148                                                         /* Valid ipv4 address (not resolved) ipv4 user */
00149                                                         b = Cloak4(dest->host);
00150 #endif
00151                                         }
00152                                         else
00153                                         {
00154 #ifdef IPV6
00155                                                 if (dest->GetProtocolFamily() == AF_INET6)
00156                                                         b = Cloak6(dest->GetIPString());
00157 #endif
00158                                                 if (dest->GetProtocolFamily() == AF_INET)
00159                                                         b = Cloak4(dest->GetIPString());
00160                                         }
00161 
00162                                         dest->ChangeDisplayedHost(b.c_str());
00163                                 }
00164                                 
00165                                 dest->SetMode('x',true);
00166                                 return MODEACTION_ALLOW;
00167                         }
00168                 }
00169                 else
00170                 {
00171                         if (dest->IsModeSet('x'))
00172                         {
00173                                 /* User is removing the mode, so just restore their real host
00174                                  * and make it match the displayed one.
00175                                  */
00176                                 dest->ChangeDisplayedHost(dest->host);
00177                                 dest->SetMode('x',false);
00178                                 return MODEACTION_ALLOW;
00179                         }
00180                 }
00181 
00182                 return MODEACTION_DENY;
00183         }


Member Data Documentation

Module* CloakUser::HashProvider [private]
 

Definition at line 34 of file m_cloaking.cpp.

Referenced by Cloak4(), Cloak6(), and OnModeChange().

bool CloakUser::ipalways [private]
 

Definition at line 32 of file m_cloaking.cpp.

Referenced by DoRehash(), and OnModeChange().

unsigned int CloakUser::key1 [private]
 

Definition at line 28 of file m_cloaking.cpp.

Referenced by Cloak4(), Cloak6(), DoRehash(), and OnModeChange().

unsigned int CloakUser::key2 [private]
 

Definition at line 29 of file m_cloaking.cpp.

Referenced by Cloak4(), Cloak6(), DoRehash(), and OnModeChange().

unsigned int CloakUser::key3 [private]
 

Definition at line 30 of file m_cloaking.cpp.

Referenced by Cloak4(), Cloak6(), DoRehash(), and OnModeChange().

unsigned int CloakUser::key4 [private]
 

Definition at line 31 of file m_cloaking.cpp.

Referenced by Cloak4(), Cloak6(), DoRehash(), and OnModeChange().

std::string CloakUser::prefix [private]
 

Mode prefix, or 0.

Reimplemented from ModeHandler.

Definition at line 27 of file m_cloaking.cpp.

Referenced by DoRehash(), and OnModeChange().

Module* CloakUser::Sender [private]
 

Definition at line 33 of file m_cloaking.cpp.

Referenced by Cloak4(), Cloak6(), and OnModeChange().

const char* CloakUser::xtab[4] [private]
 

Definition at line 35 of file m_cloaking.cpp.

Referenced by Cloak4(), Cloak6(), DoRehash(), and OnModeChange().


The documentation for this class was generated from the following file: