1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-05 07:53:13 +02:00
Files
unrealircd/src/cloak.c
T
griever 67059bd3ae Changed the way ipv4 IPs are cloaked, you now need to crack all three
cloak keys to break ipv4 IPs. ip6 ips and hostnames are too ambiguous to
be susceptable.

#define COMPAT_BETA4_KEYS undoes this fix, and is required for ipv4 bans
to be interoperable between pre-beta4 and post-beta4 servers. This should
be defined on all win32 compiles at least until the first rc or final for
3.2
2001-11-28 20:39:20 +00:00

298 lines
11 KiB
C

/************************************************************************
* Unreal Internet Relay Chat Daemon, src/cloak.c
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
#ifdef lint
static char sccxid[] = "@(#)cloak.c 9.00 7/12/99 UnrealIRCd";
#endif
*/
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "ircsprintf.h"
#include "channel.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "h.h"
#undef KEY
#undef KEY2
#undef KEY3
#define KEY CLOAK_KEY1
#define KEY2 CLOAK_KEY2
#define KEY3 CLOAK_KEY3
#define POW_8 256L
#define POW_16 65536L
#define POW_32 4294967296L
/* The implementation here was originally done by Gary S. Brown. I have
borrowed the tables directly, and made some minor changes to the
crc32-function (including changing the interface). //ylo */
/* ============================================================= */
/* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
/* code or tables extracted from it, as desired without restriction. */
/* */
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* 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 */
/* */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
/* polynomial $edb88320 */
/* */
/* -------------------------------------------------------------------- */
static unsigned long crc32_tab[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
/* Return a 32-bit CRC of the contents of the buffer. */
unsigned long crc32(const unsigned char *s, unsigned int len)
{
unsigned int i;
unsigned long crc32val;
crc32val = 0;
for (i = 0; i < len; i ++)
{
crc32val =
crc32_tab[(crc32val ^ s[i]) & 0xff] ^
(crc32val >> 8);
}
return crc32val;
}
char *hidehost(char *host)
{
static char cloaked[512];
static char h1[512];
static char h2[4][4];
static char h3[300];
unsigned long l[8];
int i;
char *p;
/* Find out what kind of host we're dealing with here */
/* IPv6 ? */
if (strchr(host, ':'))
{
/* Do IPv6 cloaking here */
/* FIXME: what the hell to do with :FFFF:192.168.1.5?
*/
/*
* a:b:c:d:e:f:g:h
*
* crc(a.b.c.d)
* crc(a.b.c.d.e.f.g)
* crc(a.b.c.d.e.f.g.h)
*/
sscanf(host, "%x:%x:%x:%x:%x:%x:%x:%x",
&l[0], &l[1], &l[2], &l[3],
&l[4], &l[5], &l[6], &l[7]);
ircsprintf(h3, "%x:%x:%x:%x",
l[0], l[1], l[2], l[3]);
l[0] = crc32(h3, strlen(h3));
ircsprintf(h3, "%x:%x:%x:%x:%x:%x:%x",
l[0], l[1], l[2], l[3],
l[4], l[5], l[6]);
l[1] = crc32(h3, strlen(h3));
l[2] = crc32(host, strlen(host));
for (i = 0; i <= 2; i++)
{
l[i] = ((l[i] + KEY2) ^ KEY) ^ KEY3;
l[i] <<= 2; l[i] >>= 2;
}
ircsprintf(cloaked, "%x:%x:%x:IP",
l[2], l[1], l[0]);
return cloaked;
}
/* Is this a IPv4 IP? */
for (p = host; *p; p++)
{
if (!isdigit(*p) && !(*p == '.'))
{
break;
}
}
if (!(*p))
{
/* Do IPv4 cloaking here */
strcpy(h1, host);
i = 0;
for (i = 0, p = strtok(h1, "."); p && (i <= 3); p = strtok(NULL, "."), i++)
{
strncpy(h2[i], p, 4);
}
#ifndef COMPAT_BETA4_KEYS
ircsprintf(h3, "%s.%s", h2[0], h2[1]);
l[0] = ((crc32(h3, strlen(h3)) + KEY) ^ KEY2) ^ KEY3;
ircsprintf(h3, "%s.%s.%s", h2[0], h2[1], h2[2]);
l[1] = ((KEY2 + crc32(h3, strlen(h3))) ^ KEY3) ^ KEY;
l[4] = crc32(host, strlen(host));
l[2] = ((l[4] + KEY3) ^ KEY)^ KEY2;
#else
ircsprintf(h3, "%s.%s", h2[0], h2[1]);
l[0] = ((crc32(h3, strlen(h3)) + KEY2) ^ KEY) ^ KEY3;
ircsprintf(h3, "%s.%s.%s", h2[0], h2[1], h2[2]);
l[1] = ((KEY2 + crc32(h3, strlen(h3))) ^ KEY3) ^ KEY;
l[4] = crc32(host, strlen(host));
l[2] = ((l[4] + KEY) ^ KEY3)^ KEY2;
#endif
l[2] <<= 2; l[2] >>= 2;
l[0] <<= 1; l[0] >>= 1;
ircsprintf(cloaked, "%X.%X.%X.IP", l[2], l[1], l[0]);
return cloaked;
}
else
{
/* Normal host cloaking here
*
* Find first .<alpha>
*/
for (p = host; *p; p++)
{
if (*p == '.')
{
if (isalpha(*(p + 1)))
break;
}
}
l[0] = ((crc32(host, strlen(host)) + KEY2) ^ KEY)^ KEY3;
l[0] <<= 2;
l[0] >>= 2;
p++;
if (*p)
sprintf(cloaked, "%s-%X.%s", hidden_host,
l[0], p);
else
sprintf(cloaked, "%s-%X", hidden_host, l[0]);
return cloaked;
}
/* Couldn't cloak, -WTF? */
return NULL;
}
/* Regular user host */
/* mode = 0, just use strncpyzt, 1 = Realloc new and return new pointer */
char *make_virthost(char *curr, char *new, int mode)
{
char *mask;
char *x;
int i;
if (curr == NULL)
return (char *)NULL;
mask = hidehost(curr);
if (mode == 0)
{
strncpyzt(new, mask, HOSTLEN); /* */
return NULL;
}
i = strlen(mask) + 1;
if (new)
MyFree(new);
x = MyMalloc(i);
strcpy(x, mask);
return x;
}