ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/contrib/ip_cloaking.c
Revision: 698
Committed: Thu Jun 22 09:34:55 2006 UTC (17 years, 9 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/contrib/ip_cloaking.c
File size: 14802 byte(s)
Log Message:
- Fixed core in make_virthost() with host names that doesn't have a dot
  in it.  Reported by CoolCold

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

Properties

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