/[svn]/ircd-hybrid-7.2/contrib/ip_cloaking.c
ViewVC logotype

Annotation of /ircd-hybrid-7.2/contrib/ip_cloaking.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 698 - (hide annotations)
Thu Jun 22 09:34:55 2006 UTC (13 years, 4 months ago) by michael
File MIME type: text/x-chdr
File size: 14802 byte(s)
- Fixed core in make_virthost() with host names that doesn't have a dot
  in it.  Reported by CoolCold

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     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 michael 698 if (!parc2)
305     return;
306    
307 adx 30 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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26