/* 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