ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/contrib/ip_cloaking.c
Revision: 76
Committed: Tue Oct 4 19:38:49 2005 UTC (20 years, 10 months ago) by adx
Content type: text/x-csrc
File size: 14674 byte(s)
Log Message:
- fixed contrib #includes

File Contents

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

Properties

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