コード例 #1
0
ファイル: mem.c プロジェクト: ghostflame/ministry
static inline void *__mtype_new_list( MTYPE *mt, int count )
{
	MTBLANK *top, *end;
	uint32_t c, i;

	if( count <= 0 )
		return NULL;

	c = (uint32_t) count;

	lock_mem( mt );

	// get enough
	while( mt->fcount < c )
		__mtype_alloc_free( mt, 0 );

	top = end = mt->flist;

	// run down count - 1 elements
	for( i = c - 1; i > 0; i-- )
		end = end->next;

	// end is now the last in the list we want
	mt->flist   = end->next;
	mt->fcount -= c;

	unlock_mem( mt );

	end->next = NULL;

	return (void *) top;
}
コード例 #2
0
ファイル: mem.c プロジェクト: ghostflame/ministry
static inline void __mtype_free_list( MTYPE *mt, int count, void *first, void *last )
{
	MTBLANK *l = (MTBLANK *) last;

	lock_mem( mt );

	l->next     = mt->flist;
	mt->flist   = first;
	mt->fcount += count;

	unlock_mem( mt );
}
コード例 #3
0
ファイル: mem.c プロジェクト: ghostflame/ministry
static inline void __mtype_free( MTYPE *mt, void *p )
{
	MTBLANK *b = (MTBLANK *) p;

	lock_mem( mt );

	b->next   = mt->flist;
	mt->flist = p;
	++(mt->fcount);

	unlock_mem( mt );
}
コード例 #4
0
ファイル: map_anon.c プロジェクト: jfrazelle/tor
/**
 * Return a new anonymous memory mapping that holds <b>sz</b> bytes.
 *
 * Memory mappings are unlike the results from malloc() in that they are
 * handled separately by the operating system, and as such can have different
 * kernel-level flags set on them.
 *
 * The "flags" argument may be zero or more of ANONMAP_PRIVATE and
 * ANONMAP_NOINHERIT.
 *
 * Memory returned from this function must be released with
 * tor_munmap_anonymous().
 *
 * If <b>inherit_result_out</b> is non-NULL, set it to one of
 * INHERIT_RES_KEEP, INHERIT_RES_DROP, or INHERIT_RES_ZERO, depending on the
 * properties of the returned memory.
 *
 * [Note: OS people use the word "anonymous" here to mean that the memory
 * isn't associated with any file. This has *nothing* to do with the kind of
 * anonymity that Tor is trying to provide.]
 */
void *
tor_mmap_anonymous(size_t sz, unsigned flags,
                   inherit_res_t *inherit_result_out)
{
  void *ptr;
  inherit_res_t itmp=0;
  if (inherit_result_out == NULL) {
    inherit_result_out = &itmp;
  }
  *inherit_result_out = INHERIT_RES_KEEP;

#if defined(_WIN32)
  HANDLE mapping = CreateFileMapping(INVALID_HANDLE_VALUE,
                                     NULL, /*attributes*/
                                     PAGE_READWRITE,
                                     HIGH_SIZE_T_BYTES(sz),
                                     sz & 0xffffffff,
                                     NULL /* name */);
  raw_assert(mapping != NULL);
  ptr = MapViewOfFile(mapping, FILE_MAP_WRITE,
                      0, 0, /* Offset */
                      0 /* Extend to end of mapping */);
  raw_assert(ptr);
  CloseHandle(mapping); /* mapped view holds a reference */
#elif defined(HAVE_SYS_MMAN_H)
  ptr = mmap(NULL, sz,
             PROT_READ|PROT_WRITE,
             MAP_ANON|MAP_PRIVATE,
             -1, 0);
  raw_assert(ptr != MAP_FAILED);
  raw_assert(ptr != NULL);
#else
  ptr = tor_malloc_zero(sz);
#endif

  if (flags & ANONMAP_PRIVATE) {
    int lock_result = lock_mem(ptr, sz);
    raw_assert(lock_result == 0);
    int nodump_result = nodump_mem(ptr, sz);
    raw_assert(nodump_result == 0);
  }

  if (flags & ANONMAP_NOINHERIT) {
    int noinherit_result = noinherit_mem(ptr, sz, inherit_result_out);
    raw_assert(noinherit_result == 0);
  }

  return ptr;
}
コード例 #5
0
ファイル: mem.c プロジェクト: ghostflame/ministry
static inline void *__mtype_new( MTYPE *mt )
{
	MTBLANK *b;

	lock_mem( mt );

	if( !mt->fcount )
		__mtype_alloc_free( mt, 0 );

	b = mt->flist;
	mt->flist = b->next;

	--(mt->fcount);

	unlock_mem( mt );

	b->next = NULL;

	return (void *) b;
}
コード例 #6
0
ファイル: stats.c プロジェクト: ant1441/ministry
IOBUF *stats_report_mtype( char *name, MTYPE *mt, time_t ts, IOBUF *b )
{
	char *prfx = ctl->stats->self->prefix;
	uint32_t freec, alloc;
	uint64_t bytes;

	// grab some stats under lock
	// we CANNOT bprintf under lock because
	// one of the reported types is buffers
	lock_mem( mt );

	bytes = (uint64_t) mt->alloc_sz * (uint64_t) mt->total;
	alloc = mt->total;
	freec = mt->fcount;

	unlock_mem( mt );

	// and report them
	bprintf( "mem.%s.free %u",  name, freec );
	bprintf( "mem.%s.alloc %u", name, alloc );
	bprintf( "mem.%s.kb %lu",   name, bytes / 1024 );

	return b;
}
コード例 #7
0
int main(int argc, char *argv[])
{
	unsigned char bytes[4096];
	int c;
	bool do_not_fork = false, log_console = false, log_syslog = false;
	char *log_logfile = NULL;
	char *bytes_file = NULL;
	int verbose = 0;
	char server_type[128];
	bool show_bps = false;
	libusb_context *ctx = NULL;
	libusb_device_handle *handle = NULL;
	std::string username, password;
	std::vector<std::string> hosts;
	int log_level = LOG_INFO;

	fprintf(stderr, "eb_server_Araneus_Alea v" VERSION ", (C) 2009-2015 by [email protected]\n");

	while((c = getopt(argc, argv, "I:hSX:P:o:L:l:snv")) != -1)
	{
		switch(c)
		{
			case 'I':
				hosts.push_back(optarg);
				break;

			case 'S':
				show_bps = true;
				break;

			case 'X':
				get_auth_from_file(optarg, username, password);
				break;

			case 'P':
				pid_file = optarg;
				break;

			case 'v':
				verbose++;
				break;

			case 'o':
				bytes_file = optarg;
				break;

			case 's':
				log_syslog = true;
				break;

			case 'L':
				log_level = atoi(optarg);
				break;

			case 'l':
				log_logfile = optarg;
				break;

			case 'n':
				do_not_fork = true;
				log_console = true;
				break;

			case 'h':
				help();
				return 0;

			default:
				help();
				return 1;
		}
	}

	if (!hosts.empty() && (username.length() == 0 || password.length() == 0))
		error_exit("please select a file with authentication parameters (username + password) using the -X switch");

	if (hosts.empty() && !bytes_file)
		error_exit("no host to connect to or file to write to given");

	(void)umask(0177);
	no_core();

	lock_mem(bytes, sizeof bytes);

	set_logging_parameters(log_console, log_logfile, log_syslog, log_level);

	if(libusb_init(&ctx) < 0)
		error_exit("Error initialising Araneus Alea");

	libusb_set_debug(ctx, 3);

	handle = libusb_open_device_with_vid_pid(ctx,USB_VENDOR_ARANEUS,USB_ARANEUS_PRODUCT_ALEA);

	if (!handle)
		error_exit("No Alea device found");

	if(libusb_claim_interface(handle, 0) < 0){
        	error_exit("Cannot Claim Interface");
	}

	snprintf(server_type, sizeof server_type, "eb_server_Araneus_Alea v" VERSION);

	if (!do_not_fork)
	{
		if (daemon(0, 0) == -1)
			error_exit("fork failed");
	}

	write_pid(pid_file);

	protocol *p = NULL;
	if (!hosts.empty())
		p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO);

	signal(SIGPIPE, SIG_IGN);
	signal(SIGTERM, sig_handler);
	signal(SIGINT , sig_handler);
	signal(SIGQUIT, sig_handler);

	init_showbps();
	set_showbps_start_ts();

	for(;!do_exit;)
	{
        	if (libusb_bulk_transfer(handle, (1 | LIBUSB_ENDPOINT_IN), (unsigned char *)bytes, sizeof bytes, &c, TIMEOUT) < 0)
			error_exit("Failed to retrieve random bytes from device %x", c);

		////////

		if (show_bps)
			update_showbps(sizeof bytes);

		if (bytes_file)
			emit_buffer_to_file(bytes_file, bytes, sizeof bytes);

		if (!hosts.empty() && p -> message_transmit_entropy_data(bytes, sizeof bytes, &do_exit) == -1)
		{
			dolog(LOG_INFO, "connection closed");

			p -> drop();
		}

		set_showbps_start_ts();
	}

	delete p;

	memset(bytes, 0x00, sizeof bytes);

	unlink(pid_file);

	return 0;
}
コード例 #8
0
void main_loop(std::vector<std::string> * hosts, char *bytes_file, char show_bps, std::string username, std::string password, const char *cdevice)
{
	int n_to_do, bits_out=0, loop;
	char *dummy;
	static short psl=0, psr=0; /* previous samples */
	static char a=1; /* alternater */
	unsigned char byte_out=0;
	int input_buffer_size;
	char *input_buffer;
	snd_pcm_t *chandle;
	snd_pcm_format_t format;
	int err;
	unsigned char bytes[4096]; // 4096 * 8: 9992, must be less then 9999
	int bytes_out = 0;

	char server_type[128];
	snprintf(server_type, sizeof server_type, "eb_server_audio v" VERSION " %s", cdevice);

	protocol *p = NULL;
	if (!hosts -> empty())
		p = new protocol(hosts, username, password, true, server_type, DEFAULT_COMM_TO);

	lock_mem(bytes, sizeof bytes);

	recover_sound_dev(&chandle, false, cdevice, &format);

	init_showbps();
	set_showbps_start_ts();
	for(;!do_exit;)
	{
		char got_any = 0;

		input_buffer_size = snd_pcm_frames_to_bytes(chandle, DEFAULT_SAMPLE_RATE * 2);

		input_buffer = reinterpret_cast<char *>(malloc_locked(input_buffer_size));
		if (!input_buffer)
			error_exit("problem allocating %d bytes of memory", input_buffer_size);

		/* Discard the first data read */
		/* it often contains weird looking data - probably a click from */
		/* driver loading / card initialisation */
		snd_pcm_sframes_t garbage_frames_read = snd_pcm_readi(chandle, input_buffer, DEFAULT_SAMPLE_RATE);
		/* Make sure we aren't hitting a disconnect/suspend case */
		if (garbage_frames_read < 0)
		{
			dolog(LOG_INFO, "snd_pcm_readi: failed retrieving audio", snd_strerror(garbage_frames_read)); // FIXME

			if ((err = snd_pcm_recover(chandle, garbage_frames_read, 0)) < 0)
			{
				dolog(LOG_INFO, "snd_pcm_recover fail : %s", snd_strerror(err));

				dolog(LOG_INFO, "Failure retrieving sound from soundcard, re-opening device");

				recover_sound_dev(&chandle, true, cdevice, &format);
			}
		}

		/* Read a buffer of audio */
		n_to_do = DEFAULT_SAMPLE_RATE * 2;
		dummy = input_buffer;
		while (n_to_do > 0 && !do_exit)
		{
			snd_pcm_sframes_t frames_read = snd_pcm_readi(chandle, dummy, n_to_do);
			/* Make	sure we	aren't hitting a disconnect/suspend case */
			if (frames_read < 0)
				frames_read = snd_pcm_recover(chandle, frames_read, 0);
			/* Nope, something else is wrong. Bail.	*/
			if (frames_read == -1) 
			{
				if ((err = snd_pcm_recover(chandle, frames_read, 0)) < 0)
				{
					dolog(LOG_INFO, "snd_pcm_recover fail : %s", snd_strerror(err));

					dolog(LOG_INFO, "Failure retrieving sound from soundcard, re-opening device");

					recover_sound_dev(&chandle, true, cdevice, &format);
				}
			}
			else
			{
				n_to_do -= frames_read;
				dummy += frames_read;	
			}
		}

		/* de-biase the data */
		for(loop=0; loop<(DEFAULT_SAMPLE_RATE * 2/*16bits*/ * 2/*stereo*/ * 2) && !do_exit; loop+=8)
		{
			int w1, w2, w3, w4, o1, o2;

			if (format == SND_PCM_FORMAT_S16_BE)
			{
				w1 = (input_buffer[loop+0]<<8) + input_buffer[loop+1];
				w2 = (input_buffer[loop+2]<<8) + input_buffer[loop+3];
				w3 = (input_buffer[loop+4]<<8) + input_buffer[loop+5];
				w4 = (input_buffer[loop+6]<<8) + input_buffer[loop+7];
			}
			else
			{
				w1 = (input_buffer[loop+1]<<8) + input_buffer[loop+0];
				w2 = (input_buffer[loop+3]<<8) + input_buffer[loop+2];
				w3 = (input_buffer[loop+5]<<8) + input_buffer[loop+4];
				w4 = (input_buffer[loop+7]<<8) + input_buffer[loop+6];
			}

			/* Determine order of channels for each sample, subtract previous sample
			 * to compensate for unbalanced audio devices */
			o1 = order(w1-psl, w2-psr);
			o2 = order(w3-psl, w4-psr);
			if (a > 0)
			{
				psl = w3;
				psr = w4;
			}
			else
			{
				psl = w1;
				psr = w2;
			}

			/* If both samples have the same order, there is bias in the samples, so we
			 * discard them; if both channels are equal on either sample, we discard
			 * them too; additionally, alternate the sample we'll use next (even more
			 * bias removal) */
			if (o1 == o2 || o1 < 0 || o2 < 0)
			{
				a = -a;
			}
			else
			{
				/* We've got a random bit; the bit is either the order from the first or
				 * the second sample, determined by the alternator 'a' */
				char bit = (a > 0) ? o1 : o2;

				byte_out <<= 1;
				byte_out += bit;

				bits_out++;

				got_any = 1;

				if (bits_out>=8)
				{
					bytes[bytes_out++] = byte_out;

					if (bytes_out == sizeof bytes)
					{
						if (show_bps)
							update_showbps(sizeof bytes);

						if (bytes_file)
							emit_buffer_to_file(bytes_file, bytes, bytes_out);

						if (p && p -> message_transmit_entropy_data(bytes, bytes_out) == -1)
						{
							dolog(LOG_INFO, "connection closed");
							p -> drop();
						}

						set_showbps_start_ts();

						bytes_out = 0;
					}

					bits_out = 0;
				}
			}
		}

		if (!got_any)
			dolog(LOG_WARNING, "no bits in audio-stream, please make sure the recording channel is not muted");

		free_locked(input_buffer, input_buffer_size);
	}

	unlock_mem(bytes, sizeof bytes);

	if (!do_exit)
		snd_pcm_close(chandle);

	delete p;
}
コード例 #9
0
int main(int argc, char *argv[])
{
	unsigned char bytes[4096];
	unsigned char cur_byte = 0;
	int bits = 0;
	int c;
	bool do_not_fork = false, log_console = false, log_syslog = false;
	char *log_logfile = NULL;
	char *bytes_file = NULL;
	bool show_bps = false;
	std::string username, password;
	std::vector<std::string> hosts;
	int log_level = LOG_INFO;

	fprintf(stderr, "%s, (C) 2009-2015 by [email protected]\n", server_type);

	while((c = getopt(argc, argv, "hX:P:So:I:L:l:sn")) != -1)
	{
		switch(c)
		{
			case 'X':
				get_auth_from_file(optarg, username, password);
				break;

			case 'P':
				pid_file = optarg;
				break;

			case 'S':
				show_bps = true;
				break;

			case 'o':
				bytes_file = optarg;
				break;

			case 'I':
				hosts.push_back(optarg);
				break;

			case 's':
				log_syslog = true;
				break;

			case 'L':
				log_level = atoi(optarg);
				break;

			case 'l':
				log_logfile = optarg;
				break;

			case 'n':
				do_not_fork = true;
				log_console = true;
				break;

			case 'h':
				help();
				return 0;

			default:
				help();
				return 1;
		}
	}

	if (!hosts.empty() && (username.length() == 0 || password.length() == 0))
		error_exit("please select a file with authentication parameters (username + password) using the -X switch");

	if (hosts.empty() && !bytes_file)
		error_exit("no host to connect to or file to write to given");

	(void)umask(0177);
	no_core();
	lock_mem(bytes, sizeof bytes);

	set_logging_parameters(log_console, log_logfile, log_syslog, log_level);

	if (!do_not_fork && !show_bps)
	{
		if (daemon(0, 0) == -1)
			error_exit("fork failed");
	}

	write_pid(pid_file);

	protocol *p = NULL;
	if (!hosts.empty())
		p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO);

	signal(SIGPIPE, SIG_IGN);
	signal(SIGTERM, sig_handler);
	signal(SIGINT , sig_handler);
	signal(SIGQUIT, sig_handler);

	struct libusb_device **devs = NULL;
	libusb_device_handle **devhs;
	int index = 0, n = 0, use_n = 0;

	if (libusb_init(NULL) < 0)
		error_exit("cannot init libusb");

	if (libusb_get_device_list(NULL, &devs) < 0)
		error_exit("cannot retrieve usb devicelist");

	while(devs[n] != NULL) { n++; }

	dolog(LOG_INFO, "Found %d devices", n);

	devhs = (libusb_device_handle **)malloc(sizeof(libusb_device_handle *) * n);
	for(index=0; index<n; index++)
	{
		uint8_t bus_nr = libusb_get_bus_number(devs[index]);
		uint8_t dev_nr = libusb_get_device_address(devs[index]);
		struct libusb_device_descriptor desc;
		libusb_get_device_descriptor(devs[index], &desc);

		dolog(LOG_INFO, "Opening device %d: %d/%d %04x:%04x", index, bus_nr, dev_nr, desc.idVendor, desc.idProduct);

		if (desc.idVendor == 0x1d6b) // ignore
			continue;

		if (libusb_open(devs[index], &devhs[use_n++]) != 0)
			error_exit("error getting usb handle");
	}

	dolog(LOG_INFO, "Using %d devices", use_n);
	if (use_n == 0)
		error_exit("no devices found which can be used");

	init_showbps();
	set_showbps_start_ts();

	int dev_index = 0;
	for(;!do_exit;)
	{
		// gather random data
		double t1 = gen_entropy_data(devhs[dev_index]), t2 = gen_entropy_data(devhs[dev_index]);

		if (++dev_index >= use_n)
			dev_index = 0;

		if (t1 == t2)
			continue;

		cur_byte <<= 1;
		if (t1 > t2)
			cur_byte |= 1;

		if (++bits == 8)
		{
			bytes[index++] = cur_byte;
			bits = 0;

			if (index == sizeof bytes)
			{
				if (show_bps)
					update_showbps(sizeof bytes);

				if (bytes_file)
					emit_buffer_to_file(bytes_file, bytes, index);

				if (p && p -> message_transmit_entropy_data(bytes, index, &do_exit) == -1)
				{
					dolog(LOG_INFO, "connection closed");
					p -> drop();
				}

				set_showbps_start_ts();

				index = 0; // skip header
			}
		}
	}

	memset(bytes, 0x00, sizeof bytes);

	for(index=0; index<n; index++)
		libusb_close(devhs[index]);

	libusb_free_device_list(devs, 1);

	libusb_exit(NULL);

	free(devhs);

	unlink(pid_file);

	return 0;
}
コード例 #10
0
int main(int argc, char *argv[])
{
	unsigned char bytes[4096];
	int bits = 0, index = 0;
	int c;
	bool do_not_fork = false, log_console = false, log_syslog = false;
	char *log_logfile = NULL;
	char *bytes_file = NULL;
	bool show_bps = false;
	std::string username, password;
	std::vector<std::string> hosts;
	int log_level = LOG_INFO;

	fprintf(stderr, "%s, (C) 2009-2015 by [email protected]\n", server_type);

	while((c = getopt(argc, argv, "I:hX:P:So:L:l:sn")) != -1)
	{
		switch(c)
		{
			case 'X':
				get_auth_from_file(optarg, username, password);
				break;

			case 'P':
				pid_file = optarg;
				break;

			case 'S':
				show_bps = true;
				break;

			case 'o':
				bytes_file = optarg;
				break;

			case 'I':
				hosts.push_back(optarg);
				break;

			case 's':
				log_syslog = true;
				break;

			case 'L':
				log_level = atoi(optarg);
				break;

			case 'l':
				log_logfile = optarg;
				break;

			case 'n':
				do_not_fork = true;
				log_console = true;
				break;

			case 'h':
				help();
				return 0;

			default:
				help();
				return 1;
		}
	}

	if (!hosts.empty() && (username.length() == 0 || password.length() == 0))
		error_exit("please select a file with authentication parameters (username + password) using the -X switch");

	if (hosts.empty() && !bytes_file)
		error_exit("no host to connect to or file to write to given");

	(void)umask(0177);
	no_core();
	lock_mem(bytes, sizeof bytes);

	set_logging_parameters(log_console, log_logfile, log_syslog, log_level);

	if (!do_not_fork && !show_bps)
	{
		if (daemon(0, 0) == -1)
			error_exit("fork failed");
	}

	write_pid(pid_file);

	signal(SIGPIPE, SIG_IGN);
	signal(SIGTERM, sig_handler);
	signal(SIGINT , sig_handler);
	signal(SIGQUIT, sig_handler);

	protocol *p = NULL;
	if (!hosts.empty())
		p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO);

	int slp = get_clock_res();
	dolog(LOG_INFO, "resolution of clock is %dns", slp);

	init_showbps();
	set_showbps_start_ts();

	unsigned char cur_byte = 0;
	int equal_cnt = 0;
	for(;!do_exit;)
	{
		// gather random data
		double t1 = gen_entropy_data(slp), t2 = gen_entropy_data(slp);

		if (t1 == t2)
		{
			equal_cnt++;

			if (equal_cnt > 5 && slp < 1000)
			{
				dolog(LOG_DEBUG, "increasing sleep to %dns", slp);

				slp++;
			}

			continue;
		}
		equal_cnt = 0;

		cur_byte <<= 1;
		if (t1 >= t2)
			cur_byte |= 1;

		if (++bits == 8)
		{
			bytes[index++] = cur_byte;
			bits = 0;

			if (index == sizeof bytes)
			{
				if (show_bps)
					update_showbps(sizeof bytes);

				if (bytes_file)
					emit_buffer_to_file(bytes_file, bytes, index);

				if (p && p -> message_transmit_entropy_data(bytes, index, &do_exit) == -1)
				{
					dolog(LOG_INFO, "connection closed");

					p -> drop();
				}

				set_showbps_start_ts();

				index = 0; // skip header
			}
		}
	}

	memset(bytes, 0x00, sizeof bytes);
	unlink(pid_file);

	delete p;

	return 0;
}
コード例 #11
0
int main(int argc, char *argv[])
{
	unsigned char bytes[BLOCK_SIZE];
	int read_fd = -1;
	int c;
	bool do_not_fork = false, log_console = false, log_syslog = false;
	char *log_logfile = NULL;
	char *device = NULL;
	char *serial = NULL;
	char *bytes_file = NULL;
	bool show_bps = false;
	std::string username, password;
	std::vector<std::string> hosts;
	int log_level = LOG_INFO;

	fprintf(stderr, "%s, (C) 2009-2015 by [email protected]\n", server_type);

	while((c = getopt(argc, argv, "hSX:P:o:p:I:d:L:l:sn")) != -1)
	{
		switch(c)
		{
			case 'S':
				show_bps = true;
				break;

			case 'X':
				get_auth_from_file(optarg, username, password);
				break;

			case 'P':
				pid_file = optarg;
				break;

			case 'o':
				bytes_file = optarg;
				break;

			case 'p':
				serial = optarg;
				break;

			case 'I':
				hosts.push_back(optarg);
				break;

			case 'd':
				device = optarg;
				break;

			case 's':
				log_syslog = true;
				break;

			case 'L':
				log_level = atoi(optarg);
				break;

			case 'l':
				log_logfile = optarg;
				break;

			case 'n':
				do_not_fork = true;
				log_console = true;
				break;

			case 'h':
				help();
				return 0;

			default:
				help();
				return 1;
		}
	}

	if (!hosts.empty() && (username.length() == 0 || password.length() == 0))
		error_exit("please select a file with authentication parameters (username + password) using the -X switch");

	if (hosts.empty() && !bytes_file)
		error_exit("no host to connect to or file to write to given");

	set_logging_parameters(log_console, log_logfile, log_syslog, log_level);

	if (device)
		read_fd = open(device, O_RDONLY);
	if (read_fd == -1)
		error_exit("error opening %s", device);

	if (serial)
		set_serial_parameters(read_fd, serial);

	(void)umask(0177);
	no_core();
	lock_mem(bytes, sizeof bytes);

	if (!do_not_fork)
	{
		if (daemon(0, 0) == -1)
			error_exit("fork failed");
	}

	protocol *p = NULL;
	if (!hosts.empty())
		p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO);

	write_pid(pid_file);

	signal(SIGPIPE, SIG_IGN);
	signal(SIGTERM, sig_handler);
	signal(SIGINT , sig_handler);
	signal(SIGQUIT, sig_handler);

	init_showbps();
	set_showbps_start_ts();
	for(;!do_exit;)
	{
		if (READ(read_fd, bytes, BLOCK_SIZE, &do_exit) != BLOCK_SIZE)
			error_exit("error reading from input");

		if (show_bps)
			update_showbps(BLOCK_SIZE);

		if (bytes_file)
			emit_buffer_to_file(bytes_file, bytes, BLOCK_SIZE);

		if (p && p -> message_transmit_entropy_data(bytes, BLOCK_SIZE, &do_exit) == -1)
		{
			dolog(LOG_INFO, "connection closed");
			p -> drop();
		}

		set_showbps_start_ts();
	}

	memset(bytes, 0x00, sizeof bytes);
	unlink(pid_file);

	delete p;

	return 0;
}
コード例 #12
0
int main(int argc, char *argv[])
{
	int dev_random_fd = open(DEV_RANDOM, O_RDWR);
	const int max_bits_in_kernel_rng = kernel_rng_get_max_entropy_count();
	const int write_threshold = kernel_rng_get_write_threshold();
	int c;
	bool do_not_fork = false, log_console = false, log_syslog = false;
	char *log_logfile = NULL;
	std::string username, password;
	int interval = -1;
	std::vector<std::string> hosts;
	int log_level = LOG_INFO;

	printf("eb_client_linux_kernel v" VERSION ", (C) 2009-2017 by [email protected]\n");

	while((c = getopt(argc, argv, "b:hX:P:I:L:l:sn")) != -1)
	{
		switch(c)
		{
			case 'b':
				interval = atof(optarg);
				if (interval < 1)
					error_exit("Interval must be > 0");
				break;

			case 'X':
				get_auth_from_file(optarg, username, password);
				break;

			case 'P':
				pid_file = optarg;
				break;

			case 'I':
				hosts.push_back(optarg);
				break;

			case 's':
				log_syslog = true;
				break;

			case 'L':
				log_level = atoi(optarg);
				break;

			case 'l':
				log_logfile = optarg;
				break;

			case 'n':
				do_not_fork = true;
				log_console = true;
				break;

			default:
				help();
				return 1;
		}
	}

	if (username.length() == 0 || password.length() == 0)
		error_exit("please select a file with authentication parameters (username + password) using the -X switch");

	if (hosts.empty())
		error_exit("no host to connect to selected");

	set_logging_parameters(log_console, log_logfile, log_syslog, log_level);

	if (!do_not_fork)
	{
		if (daemon(0, 0) == -1)
			error_exit("fork failed");
	}

	protocol *p = new protocol(&hosts, username, password, false, client_type, DEFAULT_COMM_TO);

	(void)umask(0177);
	no_core();

	write_pid(pid_file);

	signal(SIGPIPE, SIG_IGN);
	signal(SIGTERM, sig_handler);
	signal(SIGINT , sig_handler);
	signal(SIGQUIT, sig_handler);

	dolog(LOG_INFO, "started with %d bits in kernel rng", kernel_rng_get_entropy_count());

	if (dev_random_fd == -1)
		error_exit("failed to open %s", DEV_RANDOM);

	bit_count_estimator bce(BCE_SHANNON);

	for(;!do_exit;)
	{
		struct timeval tv, *ptv = NULL;

		if (interval > 0) {
			tv.tv_sec = interval / 1000;
			tv.tv_usec = int(interval * 1000) % 1000;
			ptv = &tv;
		}

		// wait for /dev/random te become writable which means the entropy-
		// level dropped below a certain threshold
		fd_set write_fd;
		FD_ZERO(&write_fd);
		FD_SET(dev_random_fd, &write_fd);

		dolog(LOG_DEBUG, "wait for low-event");
		for(;!do_exit;)
		{
			int rc = select(dev_random_fd + 1, NULL, &write_fd, NULL, ptv);
printf("%d\n", rc);
			if (rc >= 0)
				break;

			if (errno != EINTR && errno != EAGAIN)
				error_exit("Select error: %m");
		}

		if (do_exit)
			break;

		int n_bits_in_kernel_rng = kernel_rng_get_entropy_count();
		dolog(LOG_DEBUG, "kernel rng bit count: %d", n_bits_in_kernel_rng);

		if (n_bits_in_kernel_rng < write_threshold)
		{
			/* find out how many bits to add */
			int n_bits_to_get = max_bits_in_kernel_rng - n_bits_in_kernel_rng;
			if (n_bits_to_get <= 0)
			{
				dolog(LOG_DEBUG, "number of bits to get <= 0: %d", n_bits_to_get);
				continue;
			}
			if (n_bits_to_get > 9999)
				n_bits_to_get = 9999;
			if (n_bits_to_get < 8)
				n_bits_to_get = 8;

			dolog(LOG_INFO, "%d bits left (%d max), will get %d bits", n_bits_in_kernel_rng, max_bits_in_kernel_rng, n_bits_to_get);

			int n_bytes_to_get = (n_bits_to_get + 7) / 8;

			unsigned char *buffer = static_cast<unsigned char *>(malloc(n_bytes_to_get));
			if (!buffer)
				error_exit("out of memory allocating %d bytes", n_bytes_to_get);
			lock_mem(buffer, n_bytes_to_get);

			int n_bytes = p -> request_bytes(buffer, n_bits_to_get, false, &do_exit);
			if (do_exit)
				break;

			int is_n_bits = bce.get_bit_count(reinterpret_cast<unsigned char *>(buffer), n_bytes);

			int rc = kernel_rng_add_entropy(reinterpret_cast<unsigned char *>(buffer), n_bytes, is_n_bits);
			if (rc == -1)
				error_exit("error submiting entropy data to kernel");

			dolog(LOG_DEBUG, "new entropy count: %d", kernel_rng_get_entropy_count());

			memset(buffer, 0x00, n_bytes_to_get);
			unlock_mem(buffer, n_bytes_to_get);
			free(buffer);
		}
	}

	unlink(pid_file);

	delete p;

	return 0;
}