]> jfr.im git - irc/evilnet/x3.git/blame - src/hosthiding.c
Minor typo in previous commit where returning 0 when it should have been 1 from opser...
[irc/evilnet/x3.git] / src / hosthiding.c
CommitLineData
37ef8ee3 1/* hosthiding.c - Host hiding
2 * Copyright 2000-2006 X3 Development Team
3 *
4 * This file is part of x3.
5 *
6 * x3 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
348683aa 8 * the Free Software Foundation; either version 3 of the License, or
37ef8ee3 9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with srvx; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 */
20
21#include "conf.h"
22#include "common.h"
23#include "hash.h"
24#include "hosthiding.h"
25
26 /* The implementation here was originally done by Gary S. Brown. I have
27 borrowed the tables directly, and made some minor changes to the
28 crc32-function (including changing the interface). //ylo */
29
30 /* ====================================================================== */
31 /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
32 /* code or tables extracted from it, as desired without restriction. */
33 /* */
34 /* First, the polynomial itself and its table of feedback terms. The */
35 /* polynomial is */
36 /* 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 */
37 /* */
38 /* Note that we take it "backwards" and put the highest-order term in */
39 /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
40 /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
41 /* the MSB being 1. */
42 /* */
43 /* Note that the usual hardware shift register implementation, which */
44 /* is what we're using (we're merely optimizing it by doing eight-bit */
45 /* chunks at a time) shifts bits into the lowest-order term. In our */
46 /* implementation, that means shifting towards the right. Why do we */
47 /* do it this way? Because the calculated CRC must be transmitted in */
48 /* order from highest-order term to lowest-order term. UARTs transmit */
49 /* characters in order from LSB to MSB. By storing the CRC this way, */
50 /* we hand it to the UART in the order low-byte to high-byte; the UART */
51 /* sends each low-bit to hight-bit; and the result is transmission bit */
52 /* by bit from highest- to lowest-order term without requiring any bit */
53 /* shuffling on our part. Reception works similarly. */
54 /* */
55 /* The feedback terms table consists of 256, 32-bit entries. Notes: */
56 /* */
57 /* The table can be generated at runtime if desired; code to do so */
58 /* is shown later. It might not be obvious, but the feedback */
59 /* terms simply represent the results of eight shift/xor opera- */
60 /* tions for all combinations of data and CRC register values. */
61 /* */
62 /* The values must be right-shifted by eight bits by the "updcrc" */
63 /* logic; the shift must be unsigned (bring in zeroes). On some */
64 /* hardware you could probably optimize the shift in assembler by */
65 /* using byte-swap instructions. */
66 /* polynomial $edb88320 */
67 /* */
68 /* -------------------------------------------------------------------- */
69
f16ad9e7 70/* Set only once */
71static int KEY;
72static int KEY2;
73static int KEY3;
74
37ef8ee3 75static unsigned long crc32_tab[] = {
76 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
77 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
78 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
79 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
80 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
81 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
82 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
83 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
84 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
85 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
86 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
87 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
88 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
89 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
90 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
91 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
92 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
93 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
94 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
95 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
96 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
97 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
98 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
99 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
100 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
101 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
102 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
103 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
104 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
105 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
106 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
107 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
108 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
109 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
110 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
111 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
112 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
113 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
114 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
115 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
116 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
117 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
118 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
119 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
120 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
121 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
122 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
123 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
124 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
125 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
126 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
127 0x2d02ef8dL
128};
129
130/* Return a 32-bit CRC of the contents of the buffer. */
37ef8ee3 131unsigned long
132crc32 (const unsigned char *s, unsigned int len)
133{
134 unsigned int i;
135 unsigned long crc32val;
136
137 crc32val = 0;
138 for (i = 0; i < len; i++) {
68b75482 139 crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
37ef8ee3 140 }
141 return crc32val;
142}
143
144
145int
146str2arr (char **pparv, char *string, char *delim)
147{
148 char *tok;
149 int pparc = 0;
150
151 tok = (char *) strtok (string, delim);
152 while (tok != NULL) {
68b75482 153 pparv[pparc++] = tok;
154 tok = (char *) strtok (NULL, delim);
37ef8ee3 155 }
156
157 return pparc;
158}
159
f16ad9e7 160int
161check_keys()
162{
163 char *data;
164
165 if (!KEY) {
166 data = conf_get_data("server/key1", RECDB_QSTRING);
167 KEY = data ? atoi(data) : 45432;
168 }
169
170 if (!KEY2) {
171 data = conf_get_data("server/key2", RECDB_QSTRING);
172 KEY2 = data ? atoi(data) : 76934;
173 }
174
175 if (!KEY3) {
176 data = conf_get_data("server/key3", RECDB_QSTRING);
177 KEY3 = data ? atoi(data) : 98336;
178 }
179
180 return 0;
181}
182
37ef8ee3 183void
184make_virthost (char *curr, char *host, char *virt)
185{
186 static char mask[HOSTLEN + 1];
187 char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1], s2[HOSTLEN + 2];
188 int parc = 0, parc2 = 0, len = 0;
189 unsigned int hash[8];
190
191 if ((strlen(host) < 3) || (strlen(curr) < 3))
192 return;
193
194 strncpy (s, curr, HOSTLEN);
195 strncpy (s2, host, HOSTLEN);
196
197 parc = str2arr (parv, s, ".");
198 parc2 = str2arr (parv2, s2, ".");
199
f16ad9e7 200 check_keys();
201
37ef8ee3 202 hash[0] = ((crc32 ((unsigned char *)parv[3], strlen (parv[3])) + KEY2) ^ KEY) ^ KEY3;
203 hash[1] = ((crc32 ((unsigned char *)parv[2], strlen (parv[2])) + KEY2) ^ KEY) ^ KEY3;
204
205 hash[0] <<= 2;
206 hash[0] >>= 2;
207
208 hash[1] <<= 2;
209 hash[1] >>= 2;
210
211 if (parc2 == 4) {
212 len = strlen (parv2[3]);
213 if (strchr ("0123456789", parv2[3][len - 1])) {
214 hash[2] = ((crc32 ((unsigned char *)parv[1], strlen (parv[1])) + KEY2) ^ KEY) ^ KEY3;
215
216 hash[2] <<= 2;
217 hash[2] >>= 2;
218
219 snprintf(mask, HOSTLEN, "%x.%x.%x.IP", hash[0], hash[1], hash[2]);
220 } else {
221 snprintf(mask, HOSTLEN, "%x.%x.%s.%s.%s",
222 hash[0], hash[1], parv2[parc2 - 3], parv2[parc2 - 2],
223 parv2[parc2 - 1]);
224 }
225 } else {
226 if (parc2 >= 4) {
227 snprintf(mask, HOSTLEN, "%x.%x.%s.%s.%s",
228 hash[0], hash[1], parv2[parc2 - 3], parv2[parc2 - 2],
229 parv2[parc2 - 1]);
85e88703 230 } else if (parc2 >= 3) {
37ef8ee3 231 snprintf(mask, HOSTLEN, "%x.%x.%s.%s",
232 hash[0], hash[1], parv2[parc2 - 2],
233 parv2[parc2 - 1]);
85e88703 234 } else if (parc2 >= 2) {
235 snprintf(mask, HOSTLEN, "%x.%x.%s",
236 hash[0], hash[1], parv2[parc2 - 1]);
237 } else {
238 snprintf(mask, HOSTLEN, "%x.%x",
239 hash[0], hash[1]);
37ef8ee3 240 }
241 }
242 safestrncpy (virt, mask, HOSTLEN);
243 return;
244}
245
246void
247make_virtip (char *curr, char *host, char *virt)
248{
249 static char mask[HOSTLEN + 1];
250 char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1], s2[HOSTLEN + 2];
251 int parc = 0, parc2 = 0, len = 0;
252 unsigned int hash[8];
253
254 if ((strlen(host) < 3) || (strlen(curr) < 3))
255 return;
256
257 strncpy (s, curr, HOSTLEN);
258 strncpy (s2, host, HOSTLEN);
259
260 parc = str2arr (parv, s, ".");
261 parc2 = str2arr (parv2, s2, ".");
262
f16ad9e7 263 check_keys();
264
37ef8ee3 265 hash[0] = ((crc32 ((unsigned char *)parv[3], strlen (parv[3])) + KEY2) ^ KEY) ^ KEY3;
266 hash[1] = ((crc32 ((unsigned char *)parv[2], strlen (parv[2])) + KEY2) ^ KEY) ^ KEY3;
267
268 hash[0] <<= 2;
269 hash[0] >>= 2;
270
271 hash[1] <<= 2;
272 hash[1] >>= 2;
273
274 len = strlen (parv2[3]);
275 if (strchr ("0123456789", parv2[3][len - 1])) {
276 hash[2] = ((crc32 ((unsigned char *)parv[1], strlen (parv[1])) + KEY2) ^ KEY) ^ KEY3;
277
278 hash[2] <<= 2;
279 hash[2] >>= 2;
280
281 snprintf(mask, HOSTLEN, "%x.%x.%x.IP", hash[0], hash[1], hash[2]);
282 } else {
283 snprintf(mask, HOSTLEN, "%x.%x.%s.%s.%s",
284 hash[0], hash[1], parv2[parc2 - 3], parv2[parc2 - 2],
285 parv2[parc2 - 1]);
286 }
287
288 safestrncpy(virt, mask, SOCKIPLEN + 30);
289 return;
290}
291
68b75482 292void
293make_ipv6virthost (char *curr, char *host, char *new)
294{
295 static char mask[HOSTLEN + 1];
296 char *parv[HOSTLEN + 1], *parv2[HOSTLEN + 1], s[HOSTLEN + 1],
297 s2[HOSTLEN + 2], s3[HOSTLEN + 2];
298 int parc = 0, parc2 = 0;
299 unsigned int hash[8];
300
56958740 301 if ((strlen(host) < 3) || (strlen(curr) < 3))
302 return;
303
68b75482 304 strncpy (s, curr, HOSTLEN);
305 strncpy (s2, host, HOSTLEN);
306
307 ip62arr (s, s3);
308
309 parc = str2arr (parv, s3, ":");
310 parc2 = str2arr (parv2, s2, ".");
311
f16ad9e7 312 check_keys();
313
68b75482 314 hash[0] = ((crc32 ((unsigned char *)parv[0], strlen (parv[0])) + KEY2) ^ KEY) ^ KEY3;
315 hash[1] = ((crc32 ((unsigned char *)parv[1], strlen (parv[1])) + KEY2) ^ KEY) ^ KEY3;
316
317 hash[0] <<= 2;
318 hash[0] >>= 2;
319
320 hash[1] <<= 2;
321 hash[1] >>= 2;
322
323 if (parc2 >= 2) {
324 snprintf(mask, HOSTLEN, "%x.%x.%s.%s.%s",
325 hash[0], hash[1], parv2[parc2 - 3], parv2[parc2 - 2],
326 parv2[parc2 - 1]);
327 } else {
328 hash[2] = ((crc32 ((unsigned char *)parv[2], strlen (parv[2])) + KEY2) ^ KEY) ^ KEY3;
329 hash[3] = ((crc32 ((unsigned char *)parv[3], strlen (parv[3])) + KEY2) ^ KEY) ^ KEY3;
330 hash[4] = ((crc32 ((unsigned char *)parv[4], strlen (parv[4])) + KEY2) ^ KEY) ^ KEY3;
331 hash[5] = ((crc32 ((unsigned char *)parv[5], strlen (parv[5])) + KEY2) ^ KEY) ^ KEY3;
332 hash[6] = ((crc32 ((unsigned char *)parv[6], strlen (parv[6])) + KEY2) ^ KEY) ^ KEY3;
333 hash[7] = ((crc32 ((unsigned char *)parv[7], strlen (parv[7])) + KEY2) ^ KEY) ^ KEY3;
334
335 hash[2] <<= 2;
336 hash[2] >>= 2;
337
338 hash[3] <<= 2;
339 hash[3] >>= 2;
340
341 hash[4] <<= 2;
342 hash[4] >>= 2;
343
344 hash[5] <<= 2;
345 hash[5] >>= 2;
346
347 hash[6] <<= 2;
348 hash[6] >>= 2;
349
350 hash[7] <<= 2;
351 hash[7] >>= 2;
352
353 snprintf(mask, HOSTLEN, "%x:%x:%x:%x:%x:%x:%x:%x",
354 hash[0] / 10000, hash[1] / 10000, hash[2] / 10000,
355 hash[3] / 10000, hash[4] / 10000, hash[5] / 10000,
356 hash[6] / 10000, hash[7] / 10000);
357 }
358
359 strncpy (new, mask, HOSTLEN);
360 return;
361}
362
363void
364ip62arr (char *string, char *dest)
365{
366 char fields[8][5], temp[HOSTLEN + 1];
367 char *pointer = string;
368 int numberOfColons = 0, i = 0, j = 0, k = 0;
369 int length = strlen (string), missing = 8;
370
371 while ((*pointer++)) {
372 if ((*pointer) == ':')
373 numberOfColons++;
374 }
375
376 memset (fields, 0, sizeof (fields));
377
378 for (i = 0; i < length + 1; i++) {
379 if (string[i] == ':') {
380 k = 0;
381 j++;
382 if (string[i + 1] == ':') {
383 if (string[i + 2] == '\0') {
384 missing = 9 - numberOfColons;
385 } else {
386 missing = 8 - numberOfColons;
387 }
388
389 while (missing > 0) {
390 fields[j][0] = '0';
391 j++;
392 missing--;
393 }
394 j--;
395 }
396 } else {
397 fields[j][k++] = string[i];
398 }
399 }
400
401 strcpy (temp, fields[0]);
402 strcat (temp, ":");
403 for (i = 1; i < 8; i++) {
404 strcat (temp, fields[i]);
405 if (i != 7)
406 strcat (temp, ":");
407 }
408 strcpy (dest, temp);
409}