/*
MurkMUD++ - A Windows compatible, C++ compatible Merc 2.2 Mud.
\author Jon A. Lambert
\date 08/30/2006
\version 1.4
\remarks
This source code copyright (C) 2005, 2006 by Jon A. Lambert
All rights reserved.
Use governed by the MurkMUD++ public license found in license.murk++
*/
#include "os.hpp"
// replacement or substitute for itoa
std::string itoa(int value, int base) {
std::string buf;
if (base < 2 || base > 16)
return buf;
int quotient = value;
do {
buf += "0123456789abcdef"[ std::abs( quotient % base ) ];
quotient /= base;
} while ( quotient );
if ( value < 0 && base == 10)
buf += '-';
std::reverse( buf.begin(), buf.end() );
return buf;
}
#ifdef WIN32 /* Windows portability */
/*
Not implemented in windows, although all the structural support is
found in winsock.h
\author Jon A. Lambert
\remarks
This version has millisecond granularity.
*/
void gettimeofday (struct timeval *tp, struct timezone *tzp)
{
tp->tv_sec = std::time (NULL);
tp->tv_usec = (GetTickCount () % 1000) * 1000;
}
/*-------------------------------------------------------------------*/
/*
Crypt is from Andy Tanenbaum's book "Computer Networks", rewritten in C.
\author Andy Tanenbaum
\remarks
This does generate the exact same password string as glibc and newlib
so your files containg passwords are portable. I am not sure about
FreeBSD.
*/
/*
Copyright (c) 1987,1997, Prentice Hall
All rights reserved.
Redistribution and use of the MINIX operating system in source and
binary forms, with or without modification, are permitted provided
that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Prentice Hall nor the names of the software
authors or contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND
CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
struct block {
unsigned char b_data[64];
};
struct ordering {
unsigned char o_data[64];
};
static struct block key;
static struct ordering InitialTr = {
{58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}
};
static struct ordering FinalTr = {
{40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}
};
static struct ordering swap = {
{33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
};
static struct ordering KeyTr1 = {
{57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}
};
static struct ordering KeyTr2 = {
{14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}
};
static struct ordering etr = {
{32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}
};
static struct ordering ptr = {
{16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}
};
static unsigned char s_boxes[8][64] = {
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
},
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
},
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
},
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
},
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
},
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
},
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
},
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
},
};
static int rots[] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
};
static void transpose (struct block *data, struct ordering *t, int n)
{
struct block x;
x = *data;
while (n-- > 0) {
data->b_data[n] = x.b_data[t->o_data[n] - 1];
}
}
static void rotate (struct block *key)
{
register unsigned char *p = key->b_data;
register unsigned char *ep = &(key->b_data[55]);
int data0 = key->b_data[0], data28 = key->b_data[28];
while (p++ < ep)
*(p - 1) = *p;
key->b_data[27] = (char) data0;
key->b_data[55] = (char) data28;
}
static struct ordering *EP = &etr;
static void f (int i, struct block *key, struct block *a, struct block *x)
{
struct block e, ikey, y;
int k;
register unsigned char *p, *q, *r;
e = *a;
transpose (&e, EP, 48);
for (k = rots[i]; k; k--)
rotate (key);
ikey = *key;
transpose (&ikey, &KeyTr2, 48);
p = &(y.b_data[48]);
q = &(e.b_data[48]);
r = &(ikey.b_data[48]);
while (p > y.b_data) {
*--p = *--q ^ *--r;
}
q = x->b_data;
for (k = 0; k < 8; k++) {
register int xb, r;
r = *p++ << 5;
r += *p++ << 3;
r += *p++ << 2;
r += *p++ << 1;
r += *p++;
r += *p++ << 4;
xb = s_boxes[k][r];
*q++ = (char) (xb >> 3) & 1;
*q++ = (char) (xb >> 2) & 1;
*q++ = (char) (xb >> 1) & 1;
*q++ = (char) (xb & 1);
}
transpose (x, &ptr, 32);
}
void definekey (char *k)
{
key = *((struct block *) k);
transpose (&key, &KeyTr1, 56);
}
void encrypt (char *blck, int edflag)
{
register struct block *p = (struct block *) blck;
register int i;
transpose (p, &InitialTr, 64);
for (i = 15; i >= 0; i--) {
int j = edflag ? i : 15 - i;
register int k;
struct block b, x;
b = *p;
for (k = 31; k >= 0; k--) {
p->b_data[k] = b.b_data[k + 32];
}
f (j, &key, p, &x);
for (k = 31; k >= 0; k--) {
p->b_data[k + 32] = b.b_data[k] ^ x.b_data[k];
}
}
transpose (p, &swap, 64);
transpose (p, &FinalTr, 64);
}
char *crypt (char *pw, const char *salt)
{
char pwb[66];
static char result[16];
register char *p = pwb;
struct ordering new_etr;
register int i;
while (*pw && p < &pwb[64]) {
register int j = 7;
while (j--) {
*p++ = (*pw >> j) & 01;
}
pw++;
*p++ = 0;
}
while (p < &pwb[64])
*p++ = 0;
definekey (p = pwb);
while (p < &pwb[66])
*p++ = 0;
new_etr = etr;
EP = &new_etr;
for (i = 0; i < 2; i++) {
register char c = *salt++;
register int j;
result[i] = c;
if (c > 'Z')
c -= 6 + 7 + '.'; /* c was a lower case letter */
else if (c > '9')
c -= 7 + '.'; /* c was upper case letter */
else
c -= '.'; /* c was digit, '.' or '/'. */
/* now, 0 <= c <= 63 */
for (j = 0; j < 6; j++) {
if ((c >> j) & 01) {
int t = 6 * i + j;
int temp = new_etr.o_data[t];
new_etr.o_data[t] = new_etr.o_data[t + 24];
new_etr.o_data[t + 24] = (char) temp;
}
}
}
if (result[1] == 0)
result[1] = result[0];
for (i = 0; i < 25; i++)
encrypt (pwb, 0);
EP = &etr;
p = pwb;
pw = result + 2;
while (p < &pwb[66]) {
register int c = 0;
register int j = 6;
while (j--) {
c <<= 1;
c |= *p++;
}
c += '.'; /* becomes >= '.' */
if (c > '9')
c += 7; /* not in [./0-9], becomes upper */
if (c > 'Z')
c += 6; /* not in [A-Z], becomes lower */
*pw++ = (char) c;
}
*pw = 0;
return result;
}
#endif // WIN32