diff --git a/src/cfgfile.c b/src/cfgfile.c index 41359bd6..dce09ae9 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -664,6 +664,15 @@ listener_t *config_clear_listener(listener_t *listener) return next; } +static void config_clear_prng_seed(prng_seed_config_t *seed) +{ + while (seed) { + prng_seed_config_t *next = seed->next; + if (seed->filename) xmlFree(seed->filename); + seed = next; + } +} + void config_clear(ice_config_t *c) { mount_proxy *mount, @@ -729,6 +738,8 @@ void config_clear(ice_config_t *c) refobject_unref(c->reportxml_db); + config_clear_prng_seed(c->prng_seed); + memset(c, 0, sizeof(ice_config_t)); } @@ -2525,6 +2536,38 @@ static void _parse_security(xmlDocPtr doc, } } while((node = node->next)); node = oldnode; + } else if (xmlStrcmp(node->name, XMLSTR("prng-seed")) == 0) { + tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (tmp) { + prng_seed_config_t *seed = calloc(1, sizeof(prng_seed_config_t)); + seed->filename = tmp; + seed->type = PRNG_SEED_TYPE_READ_ONCE; + seed->size = -1; + + tmp = (char *)xmlGetProp(node, XMLSTR("type")); + if (tmp) { + if (strcmp(tmp, "read-once") == 0) { + seed->type = PRNG_SEED_TYPE_READ_ONCE; + } else if (strcmp(tmp, "read-write") == 0) { + seed->type = PRNG_SEED_TYPE_READ_WRITE; + } else if (strcmp(tmp, "device") == 0) { + seed->type = PRNG_SEED_TYPE_DEVICE; + } else { + ICECAST_LOG_WARN("Unknown type for : %s", tmp); + } + xmlFree(tmp); + } + + tmp = (char *)xmlGetProp(node, XMLSTR("size")); + if (tmp) { + seed->size = atoi(tmp); + xmlFree(tmp); + } + + if (configuration->prng_seed) + seed->next = configuration->prng_seed; + configuration->prng_seed = seed; + } } } while ((node = node->next)); } diff --git a/src/cfgfile.h b/src/cfgfile.h index 3d383a60..8167275a 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -201,6 +201,20 @@ typedef struct { relay_config_upstream_t upstream_default; } relay_config_t; +typedef enum { + PRNG_SEED_TYPE_READ_ONCE, + PRNG_SEED_TYPE_READ_WRITE, + PRNG_SEED_TYPE_DEVICE +} prng_seed_type_t; + +typedef struct prng_seed_config_tag prng_seed_config_t; +struct prng_seed_config_tag { + char *filename; + prng_seed_type_t type; + ssize_t size; + prng_seed_config_t *next; +}; + struct ice_config_tag { char *config_filename; @@ -259,6 +273,7 @@ struct ice_config_tag { char *allowfile; char *webroot_dir; char *adminroot_dir; + prng_seed_config_t *prng_seed; resource_t *resources; reportxml_database_t *reportxml_db; diff --git a/src/main.c b/src/main.c index f121da54..69d96a0a 100644 --- a/src/main.c +++ b/src/main.c @@ -176,6 +176,7 @@ static void shutdown_subsystems(void) connection_shutdown(); tls_shutdown(); + prng_deconfigure(); config_shutdown(); resolver_shutdown(); sock_shutdown(); diff --git a/src/prng.c b/src/prng.c index 859ab725..e51d822c 100644 --- a/src/prng.c +++ b/src/prng.c @@ -24,6 +24,7 @@ #include "prng.h" #include "digest.h" +#include "cfgfile.h" #include "logging.h" #define CATMODULE "prng" @@ -95,10 +96,34 @@ void prng_shutdown(void) void prng_configure(ice_config_t *config) { + prng_seed_config_t *seed = config->prng_seed; + if (!initialized) return; - // no-op at the moment. + while (seed) { + prng_read_file(seed->filename, seed->size); + seed = seed->next; + } +} + +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) { + prng_write_file(seed->filename, seed->size); + } + seed = seed->next; + } + config_release_config(); } void prng_write(const void *buffer, size_t len) diff --git a/src/prng.h b/src/prng.h index d79057c4..a462cb2a 100644 --- a/src/prng.h +++ b/src/prng.h @@ -14,6 +14,7 @@ void prng_initialize(void); void prng_shutdown(void); void prng_configure(ice_config_t *config); +void prng_deconfigure(void); void prng_write(const void *buffer, size_t len); ssize_t prng_read(void *buffer, size_t len);