mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-06-23 06:25:24 +00:00
156 lines
4.1 KiB
C
156 lines
4.1 KiB
C
/* Icecast
|
|
*
|
|
* This program is distributed under the GNU General Public License, version 2.
|
|
* A copy of this license is included with this source.
|
|
*
|
|
* Copyright 2020, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
|
|
*
|
|
* The SHA3 implementation is based on rhash:
|
|
* 2013 by Aleksey Kravchenko <rhash.admin@gmail.com>
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#ifdef HAVE_UNAME
|
|
#include <sys/utsname.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_OPENSSL
|
|
#include <openssl/rand.h>
|
|
#include <openssl/err.h>
|
|
#endif
|
|
|
|
#include <igloo/prng.h>
|
|
|
|
#include "prng.h"
|
|
#include "global.h"
|
|
#include "cfgfile.h"
|
|
|
|
#include "logging.h"
|
|
#define CATMODULE "prng"
|
|
|
|
#define BLOCK_LENGTH (512/8)
|
|
|
|
#define SEEDING_FACTOR 128
|
|
#define SEEDING_MAX_BEFORE_RESEED 32768
|
|
|
|
static int initialized = 0;
|
|
|
|
static void prng_initial_seed(void)
|
|
{
|
|
#ifdef HAVE_OPENSSL
|
|
char buffer[1024];
|
|
const char *filename;
|
|
#endif
|
|
|
|
#ifdef HAVE_OPENSSL
|
|
filename = RAND_file_name(buffer, sizeof(buffer));
|
|
if (filename)
|
|
RAND_load_file(filename, -1);
|
|
ERR_get_error(); // clear error if any
|
|
#endif
|
|
}
|
|
|
|
static void prng_cross_seed(void)
|
|
{
|
|
char buffer[1024];
|
|
ssize_t len;
|
|
|
|
#ifdef HAVE_OPENSSL
|
|
if (RAND_bytes((unsigned char*)buffer, sizeof(buffer)) == 1) {
|
|
igloo_prng_write(igloo_instance, buffer, sizeof(buffer), -1, igloo_PRNG_FLAG_NONE);
|
|
} else {
|
|
ERR_get_error(); // clear error
|
|
}
|
|
len = igloo_prng_read(igloo_instance, buffer, sizeof(buffer), igloo_PRNG_FLAG_NONE);
|
|
if (len > 0)
|
|
RAND_add(buffer, len, len/10.);
|
|
#endif
|
|
}
|
|
|
|
static void prng_read_seeds(prng_seed_config_t *seed, int configure_time)
|
|
{
|
|
while (seed) {
|
|
switch (seed->type) {
|
|
case PRNG_SEED_TYPE_READ_ONCE:
|
|
case PRNG_SEED_TYPE_READ_WRITE:
|
|
if (configure_time)
|
|
igloo_prng_read_file(igloo_instance, seed->filename, seed->size, -1, igloo_PRNG_FLAG_NONE);
|
|
break;
|
|
case PRNG_SEED_TYPE_DEVICE:
|
|
igloo_prng_read_file(igloo_instance, seed->filename, seed->size, -1, igloo_PRNG_FLAG_NONE);
|
|
break;
|
|
case PRNG_SEED_TYPE_STATIC:
|
|
igloo_prng_write(igloo_instance, seed->filename, strlen(seed->filename), -1, igloo_PRNG_FLAG_NONE);
|
|
break;
|
|
case PRNG_SEED_TYPE_PROFILE:
|
|
if (strcmp(seed->filename, "linux") == 0) {
|
|
igloo_prng_read_file(igloo_instance, "/proc/sys/kernel/random/uuid", -1, -1, igloo_PRNG_FLAG_NONE);
|
|
}
|
|
if (strcmp(seed->filename, "linux") == 0 || strcmp(seed->filename, "bsd") == 0) {
|
|
igloo_prng_read_file(igloo_instance, "/dev/urandom", 64, -1, igloo_PRNG_FLAG_NONE);
|
|
}
|
|
break;
|
|
}
|
|
seed = seed->next;
|
|
}
|
|
}
|
|
|
|
void prng_initialize(void)
|
|
{
|
|
if (initialized)
|
|
return;
|
|
|
|
initialized = 1;
|
|
prng_initial_seed();
|
|
prng_cross_seed();
|
|
}
|
|
|
|
void prng_shutdown(void)
|
|
{
|
|
if (!initialized)
|
|
return;
|
|
|
|
initialized = 0;
|
|
}
|
|
|
|
void prng_configure(ice_config_t *config)
|
|
{
|
|
if (!initialized)
|
|
return;
|
|
|
|
igloo_prng_write(igloo_instance, config->location, strlen(config->location), -1, igloo_PRNG_FLAG_NONE);
|
|
igloo_prng_write(igloo_instance, config->admin, strlen(config->admin), -1, igloo_PRNG_FLAG_NONE);
|
|
igloo_prng_write(igloo_instance, config->hostname, strlen(config->hostname), -1, igloo_PRNG_FLAG_NONE);
|
|
igloo_prng_write(igloo_instance, config, sizeof(*config), -1, igloo_PRNG_FLAG_NONE);
|
|
prng_read_seeds(config->prng_seed, 1);
|
|
prng_cross_seed();
|
|
}
|
|
|
|
void prng_deconfigure(void)
|
|
{
|
|
ice_config_t *config;
|
|
prng_seed_config_t *seed;
|
|
|
|
if (!initialized)
|
|
return;
|
|
|
|
config = config_get_config();
|
|
seed = config->prng_seed;
|
|
while (seed) {
|
|
if (seed->type == PRNG_SEED_TYPE_READ_WRITE) {
|
|
igloo_prng_write_file(igloo_instance, seed->filename, seed->size, igloo_PRNG_FLAG_NONE);
|
|
}
|
|
seed = seed->next;
|
|
}
|
|
config_release_config();
|
|
}
|