--- parser3/src/classes/math.C 2009/01/23 03:45:18 1.54 +++ parser3/src/classes/math.C 2009/01/25 01:58:17 1.55 @@ -8,7 +8,7 @@ Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o. */ -static const char * const IDENT_MATH_C="$Date: 2009/01/23 03:45:18 $"; +static const char * const IDENT_MATH_C="$Date: 2009/01/25 01:58:17 $"; #include "pa_vmethod_frame.h" #include "pa_common.h" @@ -16,7 +16,7 @@ static const char * const IDENT_MATH_C=" #include "pa_vmath.h" #include "pa_request.h" #include "pa_md5.h" -#include "pa_threads.h" +#include "pa_random.h" #ifdef WIN32 # define _WIN32_WINNT 0x400 @@ -50,119 +50,8 @@ public: // Methoded DECLARE_CLASS_VAR(math, 0 /*fictive*/, new MMath); -#ifdef WIN32 -class Random_provider { - HCRYPTPROV fhProv; - - void acquire() { - SYNCHRONIZED; - - if(fhProv) - return; - - if(!CryptAcquireContext(&fhProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - throw Exception(0, - 0, - "CryptAcquireContext failed"); - } - void release() { - if(fhProv) - CryptReleaseContext(fhProv, 0); - } - -public: - Random_provider(): fhProv(0) {} - ~Random_provider() { release(); } - void generate(void *buffer, size_t size) { - acquire(); - - if(!CryptGenRandom(fhProv, size, (BYTE*)buffer)) - throw Exception(0, - 0, - "CryptGenRandom failed"); - } -} - random_provider; - -#else - -/// from gen_uuid.c -static int get_random_fd(void) -{ - struct timeval tv; - static int fd = -2; - int i; - - if (fd == -2) { - gettimeofday(&tv, 0); - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) - fd = open("/dev/random", O_RDONLY | O_NONBLOCK); - srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); - } - /* Crank the random number generator a few times */ - gettimeofday(&tv, 0); - for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) - rand(); - return fd; -} - - -/* - * Generate a series of random bytes. Use /dev/urandom if possible, - * and if not, use srandom/random. - */ -static void get_random_bytes(void *buf, int nbytes) -{ - int i, fd = get_random_fd(); - int lose_counter = 0; - char *cp = (char *) buf; - - if (fd >= 0) { - while (nbytes > 0) { - i = read(fd, cp, nbytes); - if (i <= 0) { - if (lose_counter++ > 16) - break; - continue; - } - nbytes -= i; - cp += i; - lose_counter = 0; - } - } - - /* XXX put something better here if no /dev/random! */ - for (i = 0; i < nbytes; i++) - *cp++ = rand() & 0xFF; - return; -} - - -#endif - - -// helpers - -static void random(void *buffer, size_t size) { -#ifdef WIN32 - random_provider.generate(buffer, size); -#else - get_random_bytes(buffer, size); -#endif -} - - // methods -#define MAX_UINT 0xFFFFFFFFu - -static inline int _random(uint top) { - uint raw; - random(&raw, sizeof(raw)); - return int(double(raw) / MAX_UINT * top ); -} - static void _random(Request& r, MethodParams& params) { double top=params.as_double(0, "range must be expression", r); if(top<=0 || top>MAX_UINT) @@ -425,9 +314,10 @@ static void _sha1(Request& r, MethodPara if(!SHA1Result(&c)) throw Exception (PARSER_RUNTIME, 0, "Can not compute SHA1"); - size_t sha1_bufsize=40+/*for zero-teminator*/+1/*for faulty snprintfs*/; - char *sha1_cstr=new(PointerFreeGC) char[sha1_bufsize]; - snprintf(sha1_cstr, sha1_bufsize, + const size_t bufsize=40+/*zero-teminator*/+1/*for faulty snprintfs*/; + char* cstr=new(PointerFreeGC) char[bufsize]; + + snprintf(cstr, bufsize, "%08x%08x%08x%08x%08x", c.Message_Digest[0], c.Message_Digest[1], @@ -435,51 +325,23 @@ static void _sha1(Request& r, MethodPara c.Message_Digest[3], c.Message_Digest[4]); - r.write_pass_lang(*new String(sha1_cstr)); + r.write_pass_lang(*new String(cstr)); } - -/// to hell with extra bytes on 64bit platforms -struct uuid { - unsigned int time_low; - unsigned short time_mid; - unsigned short time_hi_and_version; - unsigned short clock_seq; - unsigned char node[6]; -}; static void _uuid(Request& r, MethodParams& /*params*/) { + uuid uuid=get_uuid(); + + const size_t bufsize=36+1/*zero-teminator*/+1/*for faulty snprintfs*/; + char* cstr=new(PointerFreeGC) char[bufsize]; - // random - struct uuid uuid; - random(&uuid, sizeof(uuid)); - - // http://www.opengroup.org/onlinepubs/9629399/apdxa.htm#tagtcjh_35 - // ~ - // version = DCE Security version, with embedded POSIX UIDs. - // variant = DCE - // - // DCE=Distributed Computing Environment - // http://www.opengroup.org/dce/ - // - // they say this influences comparison&such, - // but could not figure out how, hence structure layout specified strictly - // anyhow, uuidgen on Win32 yield those values - // - // xxxxxxxx-xxxx-4xxx-{8,9,A,B}xxx-xxxxxxxxxxxx - uuid.clock_seq = (uuid.clock_seq & 0x3FFF) | 0x8000; - uuid.time_hi_and_version = (uuid.time_hi_and_version & 0x0FFF) | 0x4000; - - // format - const int uuid_cstr_bufsize=36+1/*for zero-teminator*/+1/*for faulty snprintfs*/; - char *uuid_cstr=new(PointerFreeGC) char[uuid_cstr_bufsize]; - snprintf(uuid_cstr, uuid_cstr_bufsize, - "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, - uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, - uuid.node[0], uuid.node[1], uuid.node[2], - uuid.node[3], uuid.node[4], uuid.node[5]); + snprintf(cstr, bufsize, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, + uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, + uuid.node[0], uuid.node[1], uuid.node[2], + uuid.node[3], uuid.node[4], uuid.node[5]); - r.write_pass_lang(*new String(uuid_cstr)); + r.write_pass_lang(*new String(cstr)); } static void _uid64(Request& r, MethodParams& /*params*/) {