00001
00002
00003
00004
00005
00006
00007 #define KEY 23857
00008 #define KEY2 38447
00009 #define KEY3 64709
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "stdinc.h"
00052 #include "whowas.h"
00053 #include "channel_mode.h"
00054 #include "client.h"
00055 #include "common.h"
00056 #include "hash.h"
00057 #include "hook.h"
00058 #include "irc_string.h"
00059 #include "ircd.h"
00060 #include "ircd_defs.h"
00061 #include "numeric.h"
00062 #include "s_serv.h"
00063 #include "s_user.h"
00064 #include "send.h"
00065 #include "s_conf.h"
00066 #include "modules.h"
00067 #include "memory.h"
00068 #include "s_log.h"
00069 #include "sprintf_irc.h"
00070
00071 static unsigned int umode_vhost = 0;
00072 static int vhost_ipv6_err;
00073 static dlink_node *prev_enter_umode;
00074 static dlink_node *prev_umode;
00075
00076 const char *_version = "$Revision: 698 $";
00077
00078 static void *reset_ipv6err_flag(va_list);
00079 static void *h_set_user_mode(va_list);
00080
00081 void _modinit(void)
00082 {
00083 if (!user_modes['h'])
00084 {
00085 unsigned int all_umodes = 0, i;
00086
00087 for (i = 0; i < 128; i++)
00088 all_umodes |= user_modes[i];
00089
00090 for (umode_vhost = 1; umode_vhost && (all_umodes & umode_vhost);
00091 umode_vhost <<= 1);
00092
00093 if (!umode_vhost)
00094 {
00095 ilog(L_ERROR, "You have more than 32 usermodes, "
00096 "IP cloaking not installed");
00097 sendto_realops_flags(UMODE_ALL, L_ALL, "You have more than "
00098 "32 usermodes, IP cloaking not installed");
00099 return;
00100 }
00101
00102 user_modes['h'] = umode_vhost;
00103 assemble_umode_buffer();
00104 }
00105 else
00106 {
00107 ilog(L_ERROR, "Usermode +h already in use, IP cloaking not installed");
00108 sendto_realops_flags(UMODE_ALL, L_ALL, "Usermode +h already in use, "
00109 "IP cloaking not installed");
00110 return;
00111 }
00112
00113 prev_enter_umode = install_hook(entering_umode_cb, reset_ipv6err_flag);
00114 prev_umode = install_hook(umode_cb, h_set_user_mode);
00115 }
00116
00117 void _moddeinit(void)
00118 {
00119 if (umode_vhost)
00120 {
00121 dlink_node *ptr;
00122
00123 DLINK_FOREACH(ptr, local_client_list.head)
00124 {
00125 struct Client *cptr = ptr->data;
00126 cptr->umodes &= ~umode_vhost;
00127 }
00128
00129 user_modes['h'] = 0;
00130 assemble_umode_buffer();
00131
00132 uninstall_hook(entering_umode_cb, reset_ipv6err_flag);
00133 uninstall_hook(umode_cb, h_set_user_mode);
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 static unsigned long crc32_tab[] = {
00190 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
00191 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
00192 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
00193 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
00194 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
00195 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
00196 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
00197 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
00198 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
00199 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
00200 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
00201 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
00202 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
00203 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
00204 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
00205 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
00206 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
00207 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
00208 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
00209 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
00210 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
00211 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
00212 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
00213 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
00214 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
00215 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
00216 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
00217 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
00218 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
00219 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
00220 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
00221 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
00222 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
00223 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
00224 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
00225 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
00226 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
00227 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
00228 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
00229 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
00230 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
00231 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
00232 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
00233 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
00234 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
00235 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
00236 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
00237 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
00238 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
00239 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
00240 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
00241 0x2d02ef8dL
00242 };
00243
00244 static unsigned long
00245 crc32 (const unsigned char *s, unsigned int len)
00246 {
00247 unsigned int i;
00248 unsigned long crc32val;
00249
00250 crc32val = 0;
00251 for (i = 0; i < len; i++)
00252 {
00253 crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
00254 }
00255 return crc32val;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 static int
00269 str2arr (char **pparv, char *string, char *delim)
00270 {
00271 char *tok;
00272 int pparc = 0;
00273
00274
00275 for (tok = strtok (string, delim); tok != NULL; tok = strtok (NULL, delim))
00276 {
00277 pparv[pparc++] = tok;
00278 }
00279
00280 return pparc;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290 static void
00291 make_virthost (char *curr, char *host, char *new)
00292 {
00293 static char mask[HOSTLEN + 1];
00294 char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1], s2[HOSTLEN + 1];
00295 int parc = 0, parc2 = 0, len = 0;
00296 unsigned long hash[8];
00297
00298 strlcpy(s2, curr, HOSTLEN + 1);
00299 strlcpy(s, host, HOSTLEN + 1);
00300
00301 parc = str2arr(parv, s, ".");
00302 parc2 = str2arr(parv2, s2, ".");
00303
00304 if (!parc2)
00305 return;
00306
00307 hash[0] = ((crc32 (parv[3], strlen (parv[3])) + KEY) ^ KEY2) ^ KEY3;
00308 hash[1] = ((KEY2 ^ crc32 (parv[2], strlen (parv[2]))) + KEY3) ^ KEY;
00309 hash[2] = ((crc32 (parv[1], strlen (parv[1])) + KEY3) ^ KEY) ^ KEY2;
00310 hash[3] = ((KEY3 ^ crc32 (parv[0], strlen (parv[0]))) + KEY2) ^ KEY;
00311
00312 hash[0] <<= 2;
00313 hash[0] >>= 2;
00314 hash[0] &= 0x3FFFFFFF;
00315 hash[0] &= 0xFFFFFFFF;
00316 hash[1] <<= 2;
00317 hash[1] >>= 2;
00318 hash[1] &= 0x7FFFFFFF;
00319 hash[1] &= 0x3FFFFFFF;
00320 hash[2] <<= 2;
00321 hash[2] >>= 2;
00322 hash[2] &= 0x7FFFFFFF;
00323 hash[2] &= 0xFFFFFFFF;
00324 hash[3] <<= 2;
00325 hash[3] >>= 2;
00326 hash[3] &= 0x3FFFFFFF;
00327 hash[3] &= 0x7FFFFFFF;
00328
00329
00330 if (parc2 == 4 || parc2 < 2)
00331 {
00332 len = strlen (parv2[3]);
00333
00334 if (strchr("0123456789", parv2[3][len - 1]) || parc2 < 2)
00335 {
00336 ircsprintf(mask, "%s.%s.%s.%lx",
00337 parv2[parc2 - 4], parv2[parc2 - 3],
00338 parv2[parc2 - 2], hash[3]);
00339 }
00340 else
00341 {
00342
00343 ircsprintf(mask, "%lx-%lx.%s.%s",
00344 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
00345 }
00346 }
00347 else
00348 {
00349 if (parc2 >= 4)
00350 {
00351
00352 ircsprintf(mask, "%lx-%lx.%s.%s.%s",
00353 hash[3], hash[1], parv2[parc2 - 3], parv2[parc2 - 2],
00354 parv2[parc2 - 1]);
00355 }
00356 else
00357 {
00358
00359 ircsprintf(mask, "%lx-%lx.%s.%s",
00360 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
00361 }
00362
00363 if (parc2 >= 5)
00364 {
00365
00366 ircsprintf(mask, "%lx-%lx.%s.%s.%s.%s",
00367 hash[1], hash[0], parv2[parc2 - 4], parv2[parc2 - 3],
00368 parv2[parc2 - 2], parv2[parc2 - 1]);
00369 }
00370 else
00371 {
00372
00373 ircsprintf(mask, "%lx-%lx.%s.%s",
00374 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
00375 }
00376 }
00377
00378 strlcpy(new, mask, HOSTLEN + 1);
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388 static void
00389 set_vhost(struct Client *client_p, struct Client *source_p,
00390 struct Client *target_p)
00391 {
00392 target_p->umodes |= umode_vhost;
00393 SetIPSpoof(target_p);
00394 make_virthost(target_p->host, target_p->sockhost, target_p->host);
00395
00396 if (IsClient(target_p))
00397 sendto_server(client_p, source_p, NULL, CAP_ENCAP, NOCAPS, LL_ICLIENT,
00398 ":%s ENCAP * CHGHOST %s %s",
00399 me.name, target_p->name, target_p->host);
00400
00401 sendto_one(target_p, form_str(RPL_HOSTHIDDEN),
00402 me.name, target_p->name, target_p->host);
00403 }
00404
00405 static void *
00406 reset_ipv6err_flag(va_list args)
00407 {
00408 struct Client *client_p = va_arg(args, struct Client *);
00409 struct Client *source_p = va_arg(args, struct Client *);
00410
00411 vhost_ipv6_err = NO;
00412
00413 return pass_callback(prev_enter_umode, client_p, source_p);
00414 }
00415
00416 static void *
00417 h_set_user_mode(va_list args)
00418 {
00419 struct Client *client_p = va_arg(args, struct Client *);
00420 struct Client *target_p = va_arg(args, struct Client *);
00421 int what = va_arg(args, int);
00422 unsigned int flag = va_arg(args, unsigned int);
00423
00424 if (flag == umode_vhost)
00425 {
00426 if (what == MODE_ADD)
00427 {
00428
00429 if (!MyConnect(target_p))
00430 return NULL;
00431
00432 if (IsIPSpoof(target_p))
00433 return NULL;
00434
00435
00436
00437
00438
00439 #ifdef IPV6
00440 if (target_p->localClient->aftype == AF_INET6)
00441 {
00442 if (!vhost_ipv6_err)
00443 {
00444 sendto_one(target_p, ":%s NOTICE %s :*** Sorry, IP cloaking "
00445 "does not support IPv6 users!", me.name, target_p->name);
00446 vhost_ipv6_err = YES;
00447 }
00448 }
00449 else
00450 #endif
00451 set_vhost(client_p, target_p, target_p);
00452 }
00453
00454 return NULL;
00455 }
00456
00457 return pass_callback(prev_umode, client_p, target_p, what, flag);
00458 }