ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/contrib/ip_cloaking.c
Revision: 830
Committed: Wed Dec 13 19:47:59 2006 UTC (17 years, 4 months ago) by knight
Content type: text/x-csrc
File size: 14885 byte(s)
Log Message:
- Fix potential core problem in the IP cloaking procedure if a user
  tries to cloak when their host is localhost. The original code was
  in the wrong part of the logic and needed to be before the string to
  array conversion, not after. Though while I do not see why a user
  would wish to cloak themselves or attempt to cloak while being
  user@localhost, this fixes the problem from occuring.


File Contents

# Content
1 /* MODULE CONFIGURATION FOLLOWS -- please read!! */
2
3 /* Change these numbers to something else. Please
4 * make sure that they match on ALL servers
5 * to avoid problems!
6 */
7 #define KEY 23857
8 #define KEY2 38447
9 #define KEY3 64709
10
11 /* END OF MODULE CONFIGURATION */
12
13 /*
14 * ircd-hybrid: an advanced Internet Relay Chat Daemon (ircd).
15 * ip_cloaking.c: Provides hostname (partial) cloaking for clients.
16 *
17 * Copyright (c) 2005 by the past and present ircd coders, and others.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at you option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILILTY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have recieved a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
32 * USA
33 *
34 * $Id: ip_cloaking.c 801 2006-08-30 16:54:25Z adx $
35 */
36
37 /*
38 * Originally re-written from AustNet's VirtualWorld Code.
39 * Virtual World written by Roger 'RogerY' Yerramesetti <rogery@austnet.org>
40 *
41 * Re-written using the crc32 encryption implementation by //ylo based on the original
42 * implementation by Gary S. Brown.
43 *
44 * HiddenHost implementation based on the code from Unreal IRCd by
45 * RaYmAn, NiQuiL, narf, Griever (great thinking) eternal, bball, JK.@ roxnet.org
46 *
47 * Additional ideas and code by ShadowMaster, [-Th3Dud3-] (RageIRCd), Solaris @ Demonkarma.net,
48 * Alan 'knight-' LeVee of the ChatJunkies IRC Network and doughk_ff7.
49 */
50
51 #include "stdinc.h"
52 #include "conf/modules.h"
53 #include "ircd_defs.h"
54 #include "whowas.h"
55 #include "channel.h"
56 #include "channel_mode.h"
57 #include "client.h"
58 #include "common.h"
59 #include "hash.h"
60 #include "ircd.h"
61 #include "numeric.h"
62 #include "server.h"
63 #include "user.h"
64 #include "send.h"
65 #include "userhost.h"
66
67 static unsigned int umode_vhost = 0;
68 static int vhost_ipv6_err;
69 static dlink_node *prev_enter_umode;
70 static dlink_node *prev_umode;
71
72 static void *reset_ipv6err_flag(va_list);
73 static void *h_set_user_mode(va_list);
74
75 INIT_MODULE(ip_cloaking, "$Revision: 33 $")
76 {
77 if (!user_modes['h'])
78 {
79 unsigned int all_umodes = 0, i;
80
81 for (i = 0; i < 128; i++)
82 all_umodes |= user_modes[i];
83
84 for (umode_vhost = 1; umode_vhost && (all_umodes & umode_vhost);
85 umode_vhost <<= 1);
86
87 if (!umode_vhost)
88 {
89 ilog(L_ERROR, "You have more than 32 usermodes, "
90 "IP cloaking not installed");
91 sendto_realops_flags(UMODE_ALL, L_ALL, "You have more than "
92 "32 usermodes, IP cloaking not installed");
93 return;
94 }
95
96 user_modes['h'] = umode_vhost;
97 assemble_umode_buffer();
98 }
99 else
100 {
101 ilog(L_ERROR, "Usermode +h already in use, IP cloaking not installed");
102 sendto_realops_flags(UMODE_ALL, L_ALL, "Usermode +h already in use, "
103 "IP cloaking not installed");
104 return;
105 }
106
107 prev_enter_umode = install_hook(entering_umode_cb, reset_ipv6err_flag);
108 prev_umode = install_hook(umode_cb, h_set_user_mode);
109 }
110
111 CLEANUP_MODULE
112 {
113 if (umode_vhost)
114 {
115 dlink_node *ptr;
116
117 DLINK_FOREACH(ptr, local_client_list.head)
118 {
119 struct Client *cptr = ptr->data;
120 cptr->umodes &= ~umode_vhost;
121 }
122
123 user_modes['h'] = 0;
124 assemble_umode_buffer();
125
126 uninstall_hook(entering_umode_cb, reset_ipv6err_flag);
127 uninstall_hook(umode_cb, h_set_user_mode);
128 }
129 }
130
131 /*
132 * The implementation originally comes from Gary S. Brown. The tables
133 * are a direct transplant of his original concept and have been
134 * changed for randomization purposes. Minor changes were also made
135 * to the crc32-function by //ylo.
136 *
137 * knight-
138 */
139
140 /* =============================================================
141 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
142 * code or tables extracted from it, as desired without restriction.
143 *
144 * First, the polynomial itself and its stable of feedback terms. The
145 * polynomial is:
146 *
147 * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
148 *
149 * Note that we take it "backwards" and put the highest-order term in
150 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
151 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
152 * the MSB being 1.
153 *
154 * Note that the usual hardware shift register implementation, which
155 * is what we're using (we're merely optimizing it by doing eight-bit
156 * chunks at a time) shifts bits into the lowest-order term. In our
157 * implementation, that means shifting towards the right. Why do we
158 * do it this way? Because the calculated CRC must be transmitted in
159 * order from highest-order term to lowest-order term. UARTs transmit
160 * characters in order from LSB to MSB. By storing the CRC this way,
161 * we and it to the UART in the order low-byte to high-byte; the UART
162 * sends each low-bit to high-bit; and the result is transmission bit
163 * by bit from highest-order to lowest-order term without requiring any
164 * bit shuffling on our part. Reception works similarly.
165 *
166 * The feedback term table consists of 256, 32-bit entries. Notes:
167 *
168 * The table can be generated at runtime if desired; code to do so
169 * is shown later. It might not be obvious, but the feedback terms
170 * simply represent the results of eight shift/xor operations for
171 * all combinations of data and CRC register values.
172 *
173 * The values must be right shifted by eight bits by the "updcrc"
174 * logic; the shift must be unsigned (bring in zeroes). On some hardware
175 * you could probably optimize the shift in assembler by using byte-swap
176 * instructions.
177 *
178 * polynomial $edb88320
179 *
180 * --------------------------------------------------------------------
181 */
182
183 static unsigned long crc32_tab[] = {
184 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
185 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
186 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
187 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
188 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
189 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
190 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
191 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
192 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
193 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
194 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
195 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
196 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
197 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
198 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
199 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
200 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
201 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
202 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
203 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
204 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
205 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
206 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
207 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
208 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
209 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
210 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
211 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
212 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
213 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
214 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
215 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
216 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
217 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
218 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
219 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
220 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
221 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
222 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
223 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
224 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
225 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
226 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
227 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
228 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
229 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
230 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
231 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
232 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
233 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
234 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
235 0x2d02ef8dL
236 };
237
238 static unsigned long
239 crc32 (const unsigned char *s, unsigned int len)
240 {
241 unsigned int i;
242 unsigned long crc32val;
243
244 crc32val = 0;
245 for (i = 0; i < len; i++)
246 {
247 crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
248 }
249 return crc32val;
250 }
251
252 /*
253 * str2arr()
254 *
255 * converts IPv4 address segments into arrays
256 * for encryption
257 *
258 * inputs - address parvs, strings and deliminator
259 * outputs - array
260 * side effects - not IPv6 friendly
261 */
262 static int
263 str2arr (char **pparv, char *string, char *delim)
264 {
265 char *tok;
266 int pparc = 0;
267
268 /* Diane had suggested to use this method rather than while() -- knight */
269 for (tok = strtok (string, delim); tok != NULL; tok = strtok (NULL, delim))
270 {
271 pparv[pparc++] = tok;
272 }
273
274 return pparc;
275 }
276
277 /*
278 * make_virthost()
279 *
280 * curr = current hostname/ip
281 * host = current host socket
282 * new = encrypted hostname/ip
283 */
284 static void
285 make_virthost (char *curr, char *host, char *new)
286 {
287 static char mask[HOSTLEN + 1];
288 char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1], s2[HOSTLEN + 1];
289 int parc = 0, parc2 = 0, len = 0;
290 unsigned long hash[8];
291
292 strlcpy(s2, curr, HOSTLEN + 1);
293 strlcpy(s, host, HOSTLEN + 1);
294
295 if (!parc2)
296 return;
297
298 parc = str2arr(parv, s, ".");
299 parc2 = str2arr(parv2, s2, ".");
300
301 hash[0] = ((crc32 (parv[3], strlen (parv[3])) + KEY) ^ KEY2) ^ KEY3;
302 hash[1] = ((KEY2 ^ crc32 (parv[2], strlen (parv[2]))) + KEY3) ^ KEY;
303 hash[2] = ((crc32 (parv[1], strlen (parv[1])) + KEY3) ^ KEY) ^ KEY2;
304 hash[3] = ((KEY3 ^ crc32 (parv[0], strlen (parv[0]))) + KEY2) ^ KEY;
305
306 hash[0] <<= 2;
307 hash[0] >>= 2;
308 hash[0] &= 0x3FFFFFFF;
309 hash[0] &= 0xFFFFFFFF;
310 hash[1] <<= 2;
311 hash[1] >>= 2;
312 hash[1] &= 0x7FFFFFFF;
313 hash[1] &= 0x3FFFFFFF;
314 hash[2] <<= 2;
315 hash[2] >>= 2;
316 hash[2] &= 0x7FFFFFFF;
317 hash[2] &= 0xFFFFFFFF;
318 hash[3] <<= 2;
319 hash[3] >>= 2;
320 hash[3] &= 0x3FFFFFFF;
321 hash[3] &= 0x7FFFFFFF;
322
323 /* IPv4 */
324 if (parc2 == 4 || parc2 < 2)
325 {
326 len = strlen (parv2[3]);
327
328 if (strchr("0123456789", parv2[3][len - 1]) || parc2 < 2)
329 {
330 ircsprintf(mask, "%s.%s.%s.%lx",
331 parv2[parc2 - 4], parv2[parc2 - 3],
332 parv2[parc2 - 2], hash[3]);
333 }
334 else
335 {
336 /* isp.tld */
337 ircsprintf(mask, "%lx-%lx.%s.%s",
338 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
339 }
340 }
341 else
342 {
343 if (parc2 >= 4)
344 {
345 /* isp.sub.tld or district.isp.tld */
346 ircsprintf(mask, "%lx-%lx.%s.%s.%s",
347 hash[3], hash[1], parv2[parc2 - 3], parv2[parc2 - 2],
348 parv2[parc2 - 1]);
349 }
350 else
351 {
352 /* isp.tld */
353 ircsprintf(mask, "%lx-%lx.%s.%s",
354 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
355 }
356
357 if (parc2 >= 5)
358 {
359 /* zone.district.isp.tld or district.isp.sub.tld */
360 ircsprintf(mask, "%lx-%lx.%s.%s.%s.%s",
361 hash[1], hash[0], parv2[parc2 - 4], parv2[parc2 - 3],
362 parv2[parc2 - 2], parv2[parc2 - 1]);
363 }
364 else
365 {
366 /* isp.tld */
367 ircsprintf(mask, "%lx-%lx.%s.%s",
368 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
369 }
370 }
371
372 strlcpy(new, mask, HOSTLEN + 1);
373 }
374
375 /*
376 * set_vhost()
377 *
378 * inputs - pointer to given client to set IP cloak.
379 * outputs - NONE
380 * side effects - NONE
381 */
382 static void
383 set_vhost(struct Client *client_p, struct Client *source_p,
384 struct Client *target_p)
385 {
386 target_p->umodes |= umode_vhost;
387
388 delete_user_host(target_p->username, target_p->host, !MyConnect(target_p));
389 make_virthost(target_p->host, target_p->sockhost, target_p->host);
390 add_user_host(target_p->username, target_p->host, !MyConnect(target_p));
391
392 SetIPSpoof(target_p);
393
394 if (IsClient(target_p))
395 sendto_server(client_p, source_p, NULL, CAP_ENCAP, NOCAPS,
396 ":%s ENCAP * CHGHOST %s %s",
397 me.name, target_p->name, target_p->host);
398
399 sendto_one(target_p, form_str(RPL_HOSTHIDDEN),
400 me.name, target_p->name, target_p->host);
401 }
402
403 static void *
404 reset_ipv6err_flag(va_list args)
405 {
406 struct Client *client_p = va_arg(args, struct Client *);
407 struct Client *source_p = va_arg(args, struct Client *);
408
409 vhost_ipv6_err = NO;
410
411 return pass_callback(prev_enter_umode, client_p, source_p);
412 }
413
414 static void *
415 h_set_user_mode(va_list args)
416 {
417 struct Client *client_p = va_arg(args, struct Client *);
418 struct Client *target_p = va_arg(args, struct Client *);
419 int what = va_arg(args, int);
420 unsigned int flag = va_arg(args, unsigned int);
421
422 if (flag == umode_vhost)
423 {
424 if (what == MODE_ADD)
425 {
426 /* Automatically break if any of these conditions are met. -- knight- */
427 if (!MyConnect(target_p))
428 return NULL;
429
430 if (IsIPSpoof(target_p))
431 return NULL;
432
433 /*
434 * IPv6 could potentially core the server if a user connected via IPv6 sets +h
435 * so we need to check and break before that happens. -- knight-
436 */
437 #ifdef IPV6
438 if (target_p->localClient->aftype == AF_INET6)
439 {
440 if (!vhost_ipv6_err)
441 {
442 sendto_one(target_p, ":%s NOTICE %s :*** Sorry, IP cloaking "
443 "does not support IPv6 users!", me.name, target_p->name);
444 vhost_ipv6_err = YES;
445 }
446 }
447 else
448 #endif
449 set_vhost(client_p, target_p, target_p);
450 }
451
452 return NULL;
453 }
454
455 return pass_callback(prev_umode, client_p, target_p, what, flag);
456 }

Properties

Name Value
svn:eol-style native
svn:keywords "Id Revision"