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;
}
Exemple #3
0
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;	
}