ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/contrib/ip_cloaking.c
Revision: 885
Committed: Wed Oct 31 18:09:24 2007 UTC (16 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 14757 byte(s)
Log Message:
- Removed LazyLinks in 7.2 to stop people from asking why we keep
  broken code for half a decade. LL will be implemented in a smarter
  fashion in due time

File Contents

# User Rev Content
1 adx 30 /* 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 knight 31 * $Id$
35 adx 30 */
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 knight 31 const char *_version = "$Revision$";
77 adx 30
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 michael 885 unsigned long crc32val = 0;
249 adx 30
250     for (i = 0; i < len; i++)
251     crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
252 michael 885
253 adx 30 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     static 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 michael 698 if (!parc2)
303     return;
304    
305 adx 30 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 michael 885 sendto_server(client_p, NULL, CAP_ENCAP, NOCAPS,
396 adx 30 ":%s ENCAP * CHGHOST %s %s",
397     me.name, target_p->name, target_p->host);
398    
399 michael 885 sendto_one(target_p, form_str(RPL_HOSTHIDDEN),
400     me.name, target_p->name, target_p->host);
401 adx 30 }
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