]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_cloaking.cpp
764937d345ea8df9d8aec3fb950a2bd966ba2bad
[user/henk/code/inspircd.git] / src / modules / m_cloaking.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 // Hostname cloaking (+x mode) module for inspircd.
18 // version 1.0.0.1 by brain (C. J. Edwards) Mar 2004.
19 //
20 // When loaded this module will automatically set the
21 // +x mode on all connecting clients.
22 //
23 // Setting +x on a client causes the module to change the
24 // dhost entry (displayed host) for each user who has the
25 // mode, cloaking their host. Unlike unreal, the algorithm
26 // is non-reversible as uncloaked hosts are passed along
27 // the server->server link, and all encoding of hosts is
28 // done locally on the server by this module.
29
30 #include <stdio.h>
31 #include "users.h"
32 #include "channels.h"
33 #include "modules.h"
34
35 /* $ModDesc: Provides masking of user hostnames */
36
37 class ModuleCloaking : public Module
38 {
39  private:
40
41          Server *Srv;
42          
43  public:
44         ModuleCloaking()
45         {
46                 // We must create an instance of the Server class to work with
47                 Srv = new Server;
48                 
49                 // we must create a new mode. Set the parameters so the
50                 // mode doesn't require oper, and is a client usermode
51                 // with no parameters (actually, you cant have params for a umode!)
52                 if (!Srv->AddExtendedMode('x',MT_CLIENT,false,0,0))
53                 {
54                         // we couldn't claim mode x... possibly anther module has it,
55                         // this might become likely to happen if there are a lot of 3rd
56                         // party modules around in the future -- any 3rd party modules
57                         // SHOULD implement a system of configurable mode letters (e.g.
58                         // from a config file)
59                         Srv->Log(DEFAULT,"*** m_cloaking: ERROR, failed to allocate user mode +x!");
60                         printf("Could not claim usermode +x for this module!");
61                         return;
62                 }
63         }
64         
65         virtual ~ModuleCloaking()
66         {
67                 // not really neccessary, but free it anyway
68                 delete Srv;
69         }
70         
71         virtual Version GetVersion()
72         {
73                 // returns the version number of the module to be
74                 // listed in /MODULES
75                 return Version(1,0,0,1,VF_STATIC|VF_VENDOR);
76         }
77         
78         virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
79         {
80                 // this method is called for any extended mode character.
81                 // all module modes for all modules pass through here
82                 // (unless another module further up the chain claims them)
83                 // so we must be VERY careful to only act upon modes which
84                 // we have claimed ourselves. This is a feature to allow
85                 // modules to 'spy' on extended mode activity if they so wish.
86                 if ((modechar == 'x') && (type == MT_CLIENT))
87                 {
88                         // OnExtendedMode gives us a void* as the target, we must cast
89                         // it into a userrec* or a chanrec* depending on the value of
90                         // the 'type' parameter (MT_CLIENT or MT_CHANNEL)
91                         userrec* dest = (userrec*)target;
92                         
93                         // we've now determined that this is our mode character...
94                         // is the user adding the mode to their list or removing it?
95                         if (mode_on)
96                         {
97                                 // the mode is being turned on - so attempt to
98                                 // allocate the user a cloaked host using a non-reversible
99                                 // algorithm (its simple, but its non-reversible so the
100                                 // simplicity doesnt really matter). This algorithm
101                                 // will not work if the user has only one level of domain
102                                 // naming in their hostname (e.g. if they are on a lan or
103                                 // are connecting via localhost) -- this doesnt matter much.
104                                 if (strchr(dest->host,'.'))
105                                 {
106                                         // in inspircd users have two hostnames. A displayed
107                                         // hostname which can be modified by modules (e.g.
108                                         // to create vhosts, implement chghost, etc) and a
109                                         // 'real' hostname which you shouldnt write to.
110                                         std::string a = strstr(dest->host,".");
111                                         char ra[64];
112                                         long seed,s2;
113                                         memcpy(&seed,dest->host,sizeof(long));
114                                         memcpy(&s2,a.c_str(),sizeof(long));
115                                         sprintf(ra,"%.8X",seed*s2*strlen(dest->host));
116                                         std::string b = Srv->GetNetworkName() + "-" + ra + a;
117                                         Srv->Log(DEBUG,"cloak: allocated "+b);
118                                         Srv->ChangeHost(dest,b);
119                                 }
120                         }
121                         else
122                         {
123                                 // user is removing the mode, so just restore their real host
124                                 // and make it match the displayed one.
125                                 Srv->ChangeHost(dest,dest->host);
126                         }
127                         // this mode IS ours, and we have handled it. If we chose not to handle it,
128                         // for example the user cannot cloak as they have a vhost or such, then
129                         // we could return 0 here instead of 1 and the core would not send the mode
130                         // change to the user.
131                         return 1;
132                 }
133                 else
134                 {
135                         // this mode isn't ours, we have to bail and return 0 to not handle it.
136                         return 0;
137                 }
138         }
139
140         virtual void OnUserConnect(userrec* user)
141         {
142                 // Heres the weird bit. When a user connects we must set +x on them, so
143                 // we're going to use the SendMode method of the Server class to send
144                 // the mode to the client. This is basically the same as sending an
145                 // SAMODE in unreal. Note that to the user it will appear as if they set
146                 // the mode on themselves.
147                 
148                 char* modes[2];                 // only two parameters
149                 modes[0] = user->nick;          // first parameter is the nick
150                 modes[1] = "+x";                // second parameter is the mode
151                 Srv->SendMode(modes,2,user);    // send these, forming the command "MODE <nick> +x"
152         }
153
154 };
155
156 // stuff down here is the module-factory stuff. For basic modules you can ignore this.
157
158 class ModuleCloakingFactory : public ModuleFactory
159 {
160  public:
161         ModuleCloakingFactory()
162         {
163         }
164         
165         ~ModuleCloakingFactory()
166         {
167         }
168         
169         virtual Module * CreateModule()
170         {
171                 return new ModuleCloaking;
172         }
173         
174 };
175
176
177 extern "C" void * init_module( void )
178 {
179         return new ModuleCloakingFactory;
180 }
181