ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/contrib/ip_cloaking.c
Revision: 1155
Committed: Tue Aug 9 20:27:45 2011 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/contrib/ip_cloaking.c
File size: 14739 byte(s)
Log Message:
- recreate "trunk"

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 char *s, unsigned int len)
246 {
247 unsigned int i;
248 unsigned long crc32val = 0;
249
250 for (i = 0; i < len; i++)
251 crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
252
253 return crc32val;
254 }
255
256 /*
257 * str2arr()
258 *
259 * converts IPv4 address segments into arrays
260 * for encryption
261 *
262 * inputs - address parvs, strings and deliminator
263 * outputs - array
264 * side effects - not IPv6 friendly
265 */
266 static int
267 str2arr (char **pparv, char *string, char *delim)
268 {
269 char *tok;
270 int pparc = 0;
271
272 /* Diane had suggested to use this method rather than while() -- knight */
273 for (tok = strtok (string, delim); tok != NULL; tok = strtok (NULL, delim))
274 {
275 pparv[pparc++] = tok;
276 }
277
278 return pparc;
279 }
280
281 /*
282 * make_virthost()
283 *
284 * curr = current hostname/ip
285 * host = current host socket
286 * new = encrypted hostname/ip
287 */
288 static void
289 make_virthost(char *curr, char *host, char *new)
290 {
291 char mask[HOSTLEN + 1];
292 char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1], s2[HOSTLEN + 1];
293 int parc = 0, parc2 = 0, len = 0;
294 unsigned long hash[8];
295
296 strlcpy(s2, curr, HOSTLEN + 1);
297 strlcpy(s, host, HOSTLEN + 1);
298
299 parc = str2arr(parv, s, ".");
300 parc2 = str2arr(parv2, s2, ".");
301
302 if (!parc2)
303 return;
304
305 hash[0] = ((crc32 (parv[3], strlen (parv[3])) + KEY) ^ KEY2) ^ KEY3;
306 hash[1] = ((KEY2 ^ crc32 (parv[2], strlen (parv[2]))) + KEY3) ^ KEY;
307 hash[2] = ((crc32 (parv[1], strlen (parv[1])) + KEY3) ^ KEY) ^ KEY2;
308 hash[3] = ((KEY3 ^ crc32 (parv[0], strlen (parv[0]))) + KEY2) ^ KEY;
309
310 hash[0] <<= 2;
311 hash[0] >>= 2;
312 hash[0] &= 0x3FFFFFFF;
313 hash[0] &= 0xFFFFFFFF;
314 hash[1] <<= 2;
315 hash[1] >>= 2;
316 hash[1] &= 0x7FFFFFFF;
317 hash[1] &= 0x3FFFFFFF;
318 hash[2] <<= 2;
319 hash[2] >>= 2;
320 hash[2] &= 0x7FFFFFFF;
321 hash[2] &= 0xFFFFFFFF;
322 hash[3] <<= 2;
323 hash[3] >>= 2;
324 hash[3] &= 0x3FFFFFFF;
325 hash[3] &= 0x7FFFFFFF;
326
327 /* IPv4 */
328 if (parc2 == 4 || parc2 < 2)
329 {
330 len = strlen (parv2[3]);
331
332 if (strchr("0123456789", parv2[3][len - 1]) || parc2 < 2)
333 {
334 ircsprintf(mask, "%s.%s.%s.%lx",
335 parv2[parc2 - 4], parv2[parc2 - 3],
336 parv2[parc2 - 2], hash[3]);
337 }
338 else
339 {
340 /* isp.tld */
341 ircsprintf(mask, "%lx-%lx.%s.%s",
342 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
343 }
344 }
345 else
346 {
347 if (parc2 >= 4)
348 {
349 /* isp.sub.tld or district.isp.tld */
350 ircsprintf(mask, "%lx-%lx.%s.%s.%s",
351 hash[3], hash[1], parv2[parc2 - 3], parv2[parc2 - 2],
352 parv2[parc2 - 1]);
353 }
354 else
355 {
356 /* isp.tld */
357 ircsprintf(mask, "%lx-%lx.%s.%s",
358 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
359 }
360
361 if (parc2 >= 5)
362 {
363 /* zone.district.isp.tld or district.isp.sub.tld */
364 ircsprintf(mask, "%lx-%lx.%s.%s.%s.%s",
365 hash[1], hash[0], parv2[parc2 - 4], parv2[parc2 - 3],
366 parv2[parc2 - 2], parv2[parc2 - 1]);
367 }
368 else
369 {
370 /* isp.tld */
371 ircsprintf(mask, "%lx-%lx.%s.%s",
372 hash[0], hash[3], parv2[parc2 - 2], parv2[parc2 - 1]);
373 }
374 }
375
376 strlcpy(new, mask, HOSTLEN + 1);
377 }
378
379 /*
380 * set_vhost()
381 *
382 * inputs - pointer to given client to set IP cloak.
383 * outputs - NONE
384 * side effects - NONE
385 */
386 static void
387 set_vhost(struct Client *client_p, struct Client *source_p,
388 struct Client *target_p)
389 {
390 target_p->umodes |= umode_vhost;
391 SetIPSpoof(target_p);
392 make_virthost(target_p->host, target_p->sockhost, target_p->host);
393
394 if (IsClient(target_p))
395 sendto_server(client_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