From ac5d17cbdb046b38673b25b599f141b43cd9d78b Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sat, 26 Feb 2022 14:30:14 +0000 Subject: [PATCH] Cleanup: Migrated to libigloo's PRNG --- src/cfgfile.c | 12 +-- src/prng.c | 236 ++++---------------------------------------------- src/prng.h | 7 -- src/slave.c | 12 +-- src/yp.c | 5 +- 5 files changed, 27 insertions(+), 245 deletions(-) diff --git a/src/cfgfile.c b/src/cfgfile.c index 272ce316..bd286448 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -1405,18 +1405,10 @@ static void _parse_root(xmlDocPtr doc, configuration->port = 8000; if (!configuration->prng_seed) { - configuration->config_problems |= CONFIG_PROBLEM_PRNG; #ifndef _WIN32 - configuration->prng_seed = calloc(1, sizeof(prng_seed_config_t)); - if (configuration->prng_seed) { - configuration->prng_seed->filename = (char*)xmlStrdup(XMLSTR("linux")); // the linux profile is also fine on BSD. - configuration->prng_seed->type = PRNG_SEED_TYPE_PROFILE; - configuration->prng_seed->size = -1; - ICECAST_LOG_WARN("Warning, no PRNG seed configured, using default profile \"linux\"."); - } else { - ICECAST_LOG_ERROR("No PRNG seed configured and unable to add one. PRNG is insecure."); - } + ICECAST_LOG_WARN("Warning, no PRNG seed configured, falling back to libigloo defaults."); #else + configuration->config_problems |= CONFIG_PROBLEM_PRNG; ICECAST_LOG_ERROR("No PRNG seed configured and unable to add one. PRNG is insecure."); #endif } diff --git a/src/prng.c b/src/prng.c index 716f30a4..b2a80b04 100644 --- a/src/prng.c +++ b/src/prng.c @@ -28,10 +28,13 @@ #include #endif +#include + #include "common/thread/thread.h" #include "common/timing/timing.h" #include "prng.h" +#include "global.h" #include "digest.h" #include "cfgfile.h" @@ -44,46 +47,14 @@ #define SEEDING_MAX_BEFORE_RESEED 32768 static int initialized = 0; -static mutex_t digest_a_lock; -static mutex_t digest_b_lock; -static digest_t * digest_a; // protected by digest_a_lock -static digest_t * digest_b; // protected by digest_b_lock -static size_t before_reseed; // protected by digest_a_lock static void prng_initial_seed(void) { - struct { - int debian; - uint64_t t; -#ifdef HAVE_UNAME - struct utsname utsname; -#endif -#ifdef HAVE_SETUID - uid_t uid; - pid_t pid; - pid_t ppid; -#endif - } seed; #ifdef HAVE_OPENSSL char buffer[1024]; const char *filename; #endif - memset(&seed, 0, sizeof(seed)); - - seed.debian = 4; - seed.t = timing_get_time(); -#ifdef HAVE_UNAME - uname(&seed.utsname); -#endif -#ifdef HAVE_SETUID - seed.uid = getuid(); - seed.pid = getpid(); - seed.ppid = getppid(); -#endif - - prng_write(&seed, sizeof(seed)); - #ifdef HAVE_OPENSSL filename = RAND_file_name(buffer, sizeof(buffer)); if (filename) @@ -99,11 +70,11 @@ static void prng_cross_seed(void) #ifdef HAVE_OPENSSL if (RAND_bytes((unsigned char*)buffer, sizeof(buffer)) == 1) { - prng_write(buffer, sizeof(buffer)); + igloo_prng_write(igloo_instance, buffer, sizeof(buffer), -1, igloo_PRNG_FLAG_NONE); } else { ERR_get_error(); // clear error } - len = prng_read(buffer, sizeof(buffer)); + len = igloo_prng_read(igloo_instance, buffer, sizeof(buffer), igloo_PRNG_FLAG_NONE); if (len > 0) RAND_add(buffer, len, len/10.); #endif @@ -116,24 +87,20 @@ static void prng_read_seeds(prng_seed_config_t *seed, int configure_time) case PRNG_SEED_TYPE_READ_ONCE: case PRNG_SEED_TYPE_READ_WRITE: if (configure_time) - prng_read_file(seed->filename, seed->size); + igloo_prng_read_file(igloo_instance, seed->filename, seed->size, -1, igloo_PRNG_FLAG_NONE); break; case PRNG_SEED_TYPE_DEVICE: - prng_read_file(seed->filename, seed->size); + igloo_prng_read_file(igloo_instance, seed->filename, seed->size, -1, igloo_PRNG_FLAG_NONE); break; case PRNG_SEED_TYPE_STATIC: - prng_write(seed->filename, strlen(seed->filename)); + 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) { - if (configure_time) { - prng_read_file("/proc/sys/kernel/random/boot_id", -1); - prng_read_file("/etc/machine-id", -1); - } - prng_read_file("/proc/sys/kernel/random/uuid", -1); + 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) { - prng_read_file("/dev/urandom", 64); + igloo_prng_read_file(igloo_instance, "/dev/urandom", 64, -1, igloo_PRNG_FLAG_NONE); } break; } @@ -146,10 +113,6 @@ void prng_initialize(void) if (initialized) return; - thread_mutex_create(&digest_a_lock); - thread_mutex_create(&digest_b_lock); - digest_a = digest_new(DIGEST_ALGO_SHA3_512); - digest_b = digest_new(DIGEST_ALGO_SHA3_512); initialized = 1; prng_initial_seed(); prng_cross_seed(); @@ -160,11 +123,6 @@ void prng_shutdown(void) if (!initialized) return; - refobject_unref(digest_b); - refobject_unref(digest_a); - thread_mutex_destroy(&digest_b_lock); - thread_mutex_destroy(&digest_a_lock); - initialized = 0; } @@ -173,10 +131,10 @@ void prng_configure(ice_config_t *config) if (!initialized) return; - prng_write(config->location, strlen(config->location)); - prng_write(config->admin, strlen(config->admin)); - prng_write(config->hostname, strlen(config->hostname)); - prng_write(config, sizeof(*config)); + 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(); } @@ -193,173 +151,9 @@ void prng_deconfigure(void) seed = config->prng_seed; while (seed) { if (seed->type == PRNG_SEED_TYPE_READ_WRITE) { - prng_write_file(seed->filename, seed->size); + igloo_prng_write_file(igloo_instance, seed->filename, seed->size, igloo_PRNG_FLAG_NONE); } seed = seed->next; } config_release_config(); } - -void prng_auto_reseed(void) -{ - int need_seeding; - ice_config_t *config; - - thread_mutex_lock(&digest_a_lock); - need_seeding = before_reseed == 0; - thread_mutex_unlock(&digest_a_lock); - - if (!need_seeding) - return; - - config = config_get_config(); - prng_read_seeds(config->prng_seed, 0); - config_release_config(); - prng_cross_seed(); -} - -void prng_write(const void *buffer, size_t len) -{ - if (!initialized) - return; - - thread_mutex_lock(&digest_a_lock); - digest_write(digest_a, buffer, len); - digest_write(digest_a, &len, sizeof(len)); - before_reseed += len * SEEDING_FACTOR; - if (before_reseed > SEEDING_MAX_BEFORE_RESEED) - before_reseed = SEEDING_MAX_BEFORE_RESEED; - thread_mutex_unlock(&digest_a_lock); -} - -static ssize_t prng_read_block(void *froma, void *buffer, size_t len) -{ - char fromb[BLOCK_LENGTH]; - - digest_write(digest_b, froma, BLOCK_LENGTH); - - if (digest_read(digest_b, fromb, sizeof(fromb)) != sizeof(fromb)) - return -1; - - refobject_unref(digest_b); - digest_b = digest_new(DIGEST_ALGO_SHA3_512); - digest_write(digest_b, fromb, sizeof(fromb)); - digest_write(digest_b, &len, sizeof(len)); - - if (len > sizeof(fromb)) - len = sizeof(fromb); - - memcpy(buffer, fromb, len); - - return len; -} - -ssize_t prng_read(void *buffer, size_t len) -{ - digest_t *copy; - char froma[BLOCK_LENGTH]; - size_t ret = 0; - ssize_t res; - - if (!initialized) - return -1; - - thread_mutex_lock(&digest_a_lock); - digest_write(digest_a, &len, sizeof(len)); - copy = digest_copy(digest_a); - if (before_reseed > len) { - before_reseed -= len; - } else { - before_reseed = 0; - } - thread_mutex_unlock(&digest_a_lock); - - if (!copy) - return -1; - - if (digest_read(copy, froma, sizeof(froma)) != sizeof(froma)) - return -1; - - refobject_unref(copy); - - thread_mutex_lock(&digest_b_lock); - while (ret < len) { - res = prng_read_block(froma, buffer + ret, len - ret); - if (res < 0) { - thread_mutex_unlock(&digest_b_lock); - return -1; - } - ret += res; - } - thread_mutex_unlock(&digest_b_lock); - - return ret; -} - -int prng_write_file(const char *filename, ssize_t len) -{ - char buffer[BLOCK_LENGTH*16]; - size_t done = 0; - FILE *file; - - if (len < 0) - len = 1024; - - file = fopen(filename, "wb"); - if (!file) - return -1; - - while (done < (size_t)len) { - size_t todo = (size_t)len < sizeof(buffer) ? (size_t)len : sizeof(buffer); - ssize_t res = prng_read(buffer, todo); - if (res < 1) { - fclose(file); - return -1; - } - - if (fwrite(buffer, 1, res, file) != (size_t)res) { - fclose(file); - return -1; - } - - done += res; - } - - fclose(file); - return 0; -} - -int prng_read_file(const char *filename, ssize_t len) -{ - char buffer[BLOCK_LENGTH*16]; - size_t done = 0; - int fh; - - if (len < 0 || len > 1048576) - len = 1048576; - -#ifdef O_CLOEXEC - fh = open(filename, O_RDONLY|O_CLOEXEC, 0); -#else - fh = open(filename, O_RDONLY, 0); -#endif - if (fh < 0) - return -1; - - while (done < (size_t)len) { - size_t todo = (size_t)len < sizeof(buffer) ? (size_t)len : sizeof(buffer); - size_t res = read(fh, buffer, todo); - - if (res < 1) { - close(fh); - return 0; - } - - prng_write(buffer, res); - - done += res; - } - - close(fh); - return 0; -} diff --git a/src/prng.h b/src/prng.h index 958d5d22..e2e9201a 100644 --- a/src/prng.h +++ b/src/prng.h @@ -15,12 +15,5 @@ void prng_initialize(void); void prng_shutdown(void); void prng_configure(ice_config_t *config); void prng_deconfigure(void); -void prng_auto_reseed(void); - -void prng_write(const void *buffer, size_t len); -ssize_t prng_read(void *buffer, size_t len); - -int prng_write_file(const char *filename, ssize_t len); -int prng_read_file(const char *filename, ssize_t len); #endif diff --git a/src/slave.c b/src/slave.c index a5ac06a4..0564eec9 100644 --- a/src/slave.c +++ b/src/slave.c @@ -38,6 +38,9 @@ #include "compat.h" #include + +#include + #include "common/thread/thread.h" #include "common/avl/avl.h" #include "common/net/sock.h" @@ -54,7 +57,6 @@ #include "logging.h" #include "source.h" #include "format.h" -#include "prng.h" #define CATMODULE "slave" @@ -313,7 +315,7 @@ static client_t *open_relay_connection (relay_t *relay, relay_config_upstream_t ICECAST_LOG_ERROR("Header read failed for %s (%s:%d%s)", relay->config->localmount, server, port, mount); break; } - prng_write(header, strlen(header)); + igloo_prng_write(igloo_instance, header, strlen(header), -1, igloo_PRNG_FLAG_NONE); parser = httpp_create_parser(); httpp_initialize (parser, NULL); if (! httpp_parse_response (parser, header, strlen(header), relay->config->localmount)) @@ -801,7 +803,7 @@ static int update_from_master(ice_config_t *config) size_t len = strlen(buf); if (!len) break; - prng_write(buf, len); + igloo_prng_write(igloo_instance, buf, len, -1, igloo_PRNG_FLAG_NONE); } while (sock_read_line(mastersock, buf, sizeof(buf))) { size_t len = strlen(buf); @@ -810,7 +812,7 @@ static int update_from_master(ice_config_t *config) if (!len) continue; - prng_write(buf, len); + igloo_prng_write(igloo_instance, buf, len, -1, igloo_PRNG_FLAG_NONE); ICECAST_LOG_DEBUG("read %d from master \"%s\"", count++, buf); xmlURIPtr parsed_uri = xmlParseURI(buf); @@ -916,7 +918,7 @@ static void *_slave_thread(void *arg) global_unlock(); thread_sleep(1000000); - prng_auto_reseed(); + igloo_prng_auto_reseed(igloo_instance, igloo_PRNG_FLAG_NONE); thread_mutex_lock(&_slave_mutex); if (slave_running == 0) { thread_mutex_unlock(&_slave_mutex); diff --git a/src/yp.c b/src/yp.c index 7248a255..106f34bf 100644 --- a/src/yp.c +++ b/src/yp.c @@ -20,6 +20,8 @@ #include #include +#include + #include "common/thread/thread.h" #include "yp.h" @@ -30,7 +32,6 @@ #include "cfgfile.h" #include "stats.h" #include "listensocket.h" -#include "prng.h" #ifdef WIN32 #define snprintf _snprintf @@ -112,7 +113,7 @@ static size_t handle_returned_header (void *ptr, size_t size, size_t nmemb, void ypdata_t *yp = stream; size_t bytes = size * nmemb; - prng_write(ptr, bytes); + igloo_prng_write(igloo_instance, ptr, bytes, -1, igloo_PRNG_FLAG_NONE); /* ICECAST_LOG_DEBUG("header from YP is \"%.*s\"", bytes, ptr); */ if (strncasecmp (ptr, "YPResponse: 1", 13) == 0)