struct ub_randstate* ub_initstate(unsigned int seed, struct ub_randstate* from) { struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); if(!s) { log_err("malloc failure in random init"); return NULL; } ub_systemseed(seed); ub_arc4random_stir(s, from); return s; }
/** reseed random generator */ static void ub_arc4random_stir(struct ub_randstate* s, struct ub_randstate* from) { unsigned char rand_buf[SEED_SIZE]; int i; memset(&s->rc4, 0, sizeof(s->rc4)); memset(rand_buf, 0xc, sizeof(rand_buf)); if (from) { for(i=0; i<SEED_SIZE; i++) rand_buf[i] = (unsigned char)ub_random(from); } else { if(!RAND_status()) ub_systemseed((unsigned)getpid()^(unsigned)time(NULL)); if (RAND_bytes(rand_buf, (int)sizeof(rand_buf)) <= 0) { /* very unlikely that this happens, since we seeded * above, if it does; complain and keep going */ log_err("Couldn't obtain random bytes (error %ld)", ERR_get_error()); s->rc4_ready = 256; return; } } RC4_set_key(&s->rc4, SEED_SIZE, rand_buf); /* * Discard early keystream, as per recommendations in: * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps */ for(i = 0; i <= 256; i += sizeof(rand_buf)) RC4(&s->rc4, sizeof(rand_buf), rand_buf, rand_buf); memset(rand_buf, 0, sizeof(rand_buf)); s->rc4_ready = REKEY_BYTES; }
struct daemon* daemon_init(void) { struct daemon* daemon = (struct daemon*)calloc(1, sizeof(struct daemon)); #ifdef USE_WINSOCK int r; WSADATA wsa_data; #endif if(!daemon) return NULL; #ifdef USE_WINSOCK r = WSAStartup(MAKEWORD(2,2), &wsa_data); if(r != 0) { fatal_exit("could not init winsock. WSAStartup: %s", wsa_strerror(r)); } #endif /* USE_WINSOCK */ signal_handling_record(); checklock_start(); #ifdef HAVE_SSL # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS ERR_load_crypto_strings(); # endif #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) ERR_load_SSL_strings(); #endif # ifdef USE_GOST (void)sldns_key_EVP_load_gost_id(); # endif # if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO) OpenSSL_add_all_algorithms(); # else OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); # endif # if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS /* grab the COMP method ptr because openssl leaks it */ comp_meth = (void*)SSL_COMP_get_compression_methods(); # endif # if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) (void)SSL_library_init(); # else (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); # endif # if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) if(!ub_openssl_lock_init()) fatal_exit("could not init openssl locks"); # endif #elif defined(HAVE_NSS) if(NSS_NoDB_Init(NULL) != SECSuccess) fatal_exit("could not init NSS"); #endif /* HAVE_SSL or HAVE_NSS */ #ifdef HAVE_TZSET /* init timezone info while we are not chrooted yet */ tzset(); #endif /* open /dev/random if needed */ ub_systemseed((unsigned)time(NULL)^(unsigned)getpid()^0xe67); daemon->need_to_exit = 0; modstack_init(&daemon->mods); if(!(daemon->env = (struct module_env*)calloc(1, sizeof(*daemon->env)))) { free(daemon); return NULL; } /* init edns_known_options */ if(!edns_known_options_init(daemon->env)) { free(daemon->env); free(daemon); return NULL; } alloc_init(&daemon->superalloc, NULL, 0); daemon->acl = acl_list_create(); if(!daemon->acl) { edns_known_options_delete(daemon->env); free(daemon->env); free(daemon); return NULL; } if(gettimeofday(&daemon->time_boot, NULL) < 0) log_err("gettimeofday: %s", strerror(errno)); daemon->time_last_stat = daemon->time_boot; if((daemon->env->auth_zones = auth_zones_create()) == 0) { acl_list_delete(daemon->acl); edns_known_options_delete(daemon->env); free(daemon->env); free(daemon); return NULL; } return daemon; }