diff --git a/Makefile b/Makefile index 01dab0d..4570785 100644 --- a/Makefile +++ b/Makefile @@ -37,19 +37,20 @@ activitypub.o: activitypub.c xs.h xs_json.h xs_curl.h xs_mime.h \ xs_openssl.h xs_regex.h xs_time.h xs_set.h snac.h data.o: data.c xs.h xs_io.h xs_json.h xs_openssl.h xs_glob.h xs_set.h \ xs_time.h snac.h -format.o: format.c xs.h xs_regex.h snac.h +format.o: format.c xs.h xs_regex.h xs_mime.h snac.h html.o: html.c xs.h xs_io.h xs_json.h xs_regex.h xs_set.h xs_openssl.h \ xs_time.h xs_mime.h snac.h http.o: http.c xs.h xs_io.h xs_openssl.h xs_curl.h xs_time.h xs_json.h \ snac.h httpd.o: httpd.c xs.h xs_io.h xs_json.h xs_socket.h xs_httpd.h xs_mime.h \ - xs_time.h snac.h + xs_time.h xs_openssl.h snac.h main.o: main.c xs.h xs_io.h xs_json.h snac.h mastoapi.o: mastoapi.c xs.h xs_openssl.h xs_json.h xs_io.h xs_time.h \ - xs_glob.h xs_set.h snac.h + xs_glob.h xs_set.h xs_random.h snac.h snac.o: snac.c xs.h xs_io.h xs_unicode.h xs_json.h xs_curl.h xs_openssl.h \ xs_socket.h xs_httpd.h xs_mime.h xs_regex.h xs_set.h xs_time.h xs_glob.h \ - snac.h + xs_random.h snac.h upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h -utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h snac.h +utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \ + xs_random.h snac.h webfinger.o: webfinger.c xs.h xs_json.h xs_curl.h snac.h diff --git a/mastoapi.c b/mastoapi.c index f30971e..a76a6ab 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -10,6 +10,7 @@ #include "xs_time.h" #include "xs_glob.h" #include "xs_set.h" +#include "xs_random.h" #include "snac.h" @@ -17,19 +18,8 @@ static xs_str *random_str(void) /* just what is says in the tin */ { unsigned int data[4] = {0}; - FILE *f; - - if ((f = fopen("/dev/random", "r")) != NULL) { - fread(data, sizeof(data), 1, f); - fclose(f); - } - else { - data[0] = random() % 0xffffffff; - data[1] = random() % 0xffffffff; - data[2] = random() % 0xffffffff; - data[3] = random() % 0xffffffff; - } + xs_rnd_buf(data, sizeof(data)); return xs_hex_enc((char *)data, sizeof(data)); } diff --git a/snac.c b/snac.c index 722af62..691c2e2 100644 --- a/snac.c +++ b/snac.c @@ -16,6 +16,7 @@ #include "xs_set.h" #include "xs_time.h" #include "xs_glob.h" +#include "xs_random.h" #include "snac.h" @@ -122,7 +123,9 @@ xs_str *hash_password(const char *uid, const char *passwd, const char *nonce) xs *hash; if (nonce == NULL) { - d_nonce = xs_fmt("%08x", random()); + unsigned int r; + xs_rnd_buf(&r, sizeof(r)); + d_nonce = xs_fmt("%08x", r); nonce = d_nonce; } diff --git a/utils.c b/utils.c index 1c03fee..f5b02ae 100644 --- a/utils.c +++ b/utils.c @@ -6,6 +6,7 @@ #include "xs_json.h" #include "xs_time.h" #include "xs_openssl.h" +#include "xs_random.h" #include "snac.h" @@ -204,10 +205,7 @@ void new_password(const char *uid, d_char **clear_pwd, d_char **hashed_pwd) { int rndbuf[3]; - srandom(time(NULL) ^ getpid()); - rndbuf[0] = random() & 0xffffffff; - rndbuf[1] = random() & 0xffffffff; - rndbuf[2] = random() & 0xffffffff; + xs_rnd_buf(rndbuf, sizeof(rndbuf)); *clear_pwd = xs_base64_enc((char *)rndbuf, sizeof(rndbuf)); *hashed_pwd = hash_password(uid, *clear_pwd, NULL); diff --git a/xs_random.h b/xs_random.h new file mode 100644 index 0000000..3566827 --- /dev/null +++ b/xs_random.h @@ -0,0 +1,87 @@ +/* copyright (c) 2022 - 2023 grunfink / MIT license */ + +#ifndef _XS_RANDOM_H + +#define _XS_RANDOM_H + +unsigned int xs_rnd_int32_d(unsigned int *seed); +void *xs_rnd_buf(void *buf, int size); + +#ifdef XS_IMPLEMENTATION + +#include +#include +#include +#include + +unsigned int xs_rnd_int32_d(unsigned int *seed) +/* returns a deterministic random integer. If seed is NULL, uses a static one */ +{ + static unsigned int s = 0; + + if (seed == NULL) + seed = &s; + + if (*seed == 0) { + struct timeval tv; + + gettimeofday(&tv, NULL); + *seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); + } + + /* Linear congruential generator by Numerical Recipes */ + *seed = (*seed * 1664525) + 1013904223; + + return *seed; +} + + +void *xs_rnd_buf(void *buf, int size) +/* fills buf with random data */ +{ +#ifdef __OpenBSD__ + + /* available since OpenBSD 2.2 */ + arc4random_buf(buf, size); + +#else + + FILE *f; + int done = 0; + + if ((f = fopen("/dev/urandom", "r")) != NULL) { + /* fill with great random data from the system */ + if (fread(buf, size, 1, f) == 1) + done = 1; + + fclose(f); + } + + if (!done) { + /* fill the buffer with poor quality, deterministic data */ + unsigned int s = 0; + unsigned char *p = (unsigned char *)buf; + int n = size / sizeof(s); + + /* fill with full integers */ + while (n--) { + xs_rnd_int32_d(&s); + p = memcpy(p, &s, sizeof(s)) + sizeof(s); + } + + if ((n = size % sizeof(s))) { + /* fill the remaining */ + xs_rnd_int32_d(&s); + memcpy(p, &s, n); + } + } + +#endif /* __OpenBSD__ */ + + return buf; +} + + +#endif /* XS_IMPLEMENTATION */ + +#endif /* XS_RANDOM_H */ diff --git a/xs_version.h b/xs_version.h index 7a793d1..b589fed 100644 --- a/xs_version.h +++ b/xs_version.h @@ -1 +1 @@ -/* 3588cbb7859917f1c5965254f8a53c3349c773ea */ +/* 5c255b45c8cd5d6c01c983b03e635936db12da03 */