1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-06-16 06:15:24 +00:00

Feature: Added PRNG

This commit is contained in:
Philipp Schafft 2020-10-21 21:09:52 +00:00
parent 2b9edf6fd1
commit 70419a33b5
5 changed files with 269 additions and 0 deletions

View File

@ -29,6 +29,7 @@ noinst_HEADERS = \
yp.h \
md5.h \
digest.h \
prng.h \
matchfile.h \
tls.h \
refobject.h \
@ -79,6 +80,7 @@ icecast_SOURCES = \
resourcematch.c \
md5.c \
digest.c \
prng.c \
matchfile.c \
tls.c \
refobject.c \

View File

@ -45,6 +45,7 @@
#include "main.h"
#include "slave.h"
#include "xslt.h"
#include "prng.h"
#define CATMODULE "CONFIG"
#define CONFIG_DEFAULT_LOCATION "Earth"
@ -765,6 +766,7 @@ void config_reread_config(void)
config_set_config(&new_config);
config = config_get_config_unlocked();
restart_logging(config);
prng_configure(config);
main_config_reload(config);
connection_reread_config(config);
yp_recheck_config(config);

View File

@ -79,6 +79,7 @@
#include "event.h"
#include "listensocket.h"
#include "fastevent.h"
#include "prng.h"
#include <libxml/xmlmemory.h>
@ -144,6 +145,7 @@ static void initialize_subsystems(void)
{
log_initialize();
thread_initialize();
prng_initialize();
global_initialize();
#ifndef FASTEVENT_ENABLED
fastevent_initialize();
@ -181,6 +183,7 @@ static void shutdown_subsystems(void)
refobject_unref(fastevent_reg);
fastevent_shutdown();
#endif
prng_shutdown();
global_shutdown();
thread_shutdown();
@ -576,6 +579,7 @@ int main(int argc, char **argv)
char filename[512] = "";
#endif
char pbuf[1024];
ice_config_t *config;
/* parse the '-c icecast.xml' option
** only, so that we can read a configfile
@ -644,6 +648,10 @@ int main(int argc, char **argv)
return 1;
}
config = config_get_config();
prng_configure(config);
config_release_config();
stats_initialize(); /* We have to do this later on because of threading */
fserve_initialize(); /* This too */

233
src/prng.c Normal file
View File

@ -0,0 +1,233 @@
/* 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 <string.h>
#include <stdio.h>
#ifdef HAVE_UNAME
#include <sys/utsname.h>
#endif
#include "common/thread/thread.h"
#include "prng.h"
#include "digest.h"
#include "logging.h"
#define CATMODULE "prng"
#define BLOCK_LENGTH (512/8)
static int initialized = 0;
static mutex_t digest_a_lock;
static mutex_t digest_b_lock;
static digest_t * digest_a;
static digest_t * digest_b;
static void prng_initial_seed(void)
{
struct {
int debian;
time_t t;
#ifdef HAVE_UNAME
struct utsname utsname;
#endif
#ifdef HAVE_SETUID
uid_t uid;
pid_t pid;
pid_t ppid;
#endif
} seed;
seed.debian = 4;
seed.t = time(NULL);
#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));
}
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();
}
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;
}
void prng_configure(ice_config_t *config)
{
if (!initialized)
return;
// no-op at the moment.
}
void prng_write(const void *buffer, size_t len)
{
if (!initialized)
return;
thread_mutex_lock(&digest_a_lock);
digest_write(digest_a, buffer, len);
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);
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_a_lock);
return -1;
}
ret += res;
}
thread_mutex_unlock(&digest_a_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;
FILE *file;
if (len < 0 || len > 1048576)
len = 1048576;
file = fopen(filename, "rb");
if (!file)
return -1;
while (done < (size_t)len) {
size_t todo = (size_t)len < sizeof(buffer) ? (size_t)len : sizeof(buffer);
size_t res = fread(buffer, 1, todo, file);
if (res < 1) {
fclose(file);
return 0;
}
prng_write(buffer, res);
done += res;
}
fclose(file);
return 0;
}

24
src/prng.h Normal file
View File

@ -0,0 +1,24 @@
/* 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>
*/
#ifndef __PRNG_H__
#define __PRNG_H__
#include "icecasttypes.h"
void prng_initialize(void);
void prng_shutdown(void);
void prng_configure(ice_config_t *config);
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