summaryrefslogtreecommitdiff
path: root/random-seed.c
diff options
context:
space:
mode:
Diffstat (limited to 'random-seed.c')
-rw-r--r--random-seed.c109
1 files changed, 61 insertions, 48 deletions
diff --git a/random-seed.c b/random-seed.c
index 6ed971b..53ad8e3 100644
--- a/random-seed.c
+++ b/random-seed.c
@@ -213,7 +213,7 @@ static bool load(FILE *seed_file) {
}
}
- char *nul = memchr(line, '\0', line_length);
+ char *nul = memchr(line, '\0', (size_t)line_length);
if (nul) {
fprintf(stderr, "error parsing seed file: encountered NUL byte in commands line %zu char %zu\n", linenum, nul - line + 1);
credit_entropy = false;
@@ -272,10 +272,11 @@ static bool load(FILE *seed_file) {
}
static bool get_rand_pool(unsigned char *buf) {
- size_t rand_bits_gotten = 0;
- while (rand_bits_gotten < RAND_POOL_SIZE) {
- long this_rand_bits_gotten = random_get(buf + rand_bits_gotten, RAND_POOL_SIZE - rand_bits_gotten, 0);
- if (this_rand_bits_gotten < 0) {
+ size_t rand_bytes_gotten = 0;
+
+ do {
+ long this_rand_bytes_gotten = random_get(buf + rand_bytes_gotten, RAND_POOL_SIZE - rand_bytes_gotten, 0);
+ if (this_rand_bytes_gotten == -1) {
switch (errno) {
case EAGAIN: continue;
case EINTR: return false;
@@ -284,9 +285,10 @@ static bool get_rand_pool(unsigned char *buf) {
exit(1);
}
} else {
- rand_bits_gotten += (size_t)this_rand_bits_gotten;
+ rand_bytes_gotten += (size_t)this_rand_bytes_gotten;
}
- }
+ } while (rand_bytes_gotten < RAND_POOL_SIZE);
+
return true;
}
@@ -301,61 +303,64 @@ static bool save(const char *seed_path, unsigned char *random_buf) {
assert(seed_path);
bool rv = false;
- char *seed_path_tmp = NULL;
- char *seed_name_new = NULL;
- unsigned char my_random_buf[RAND_POOL_SIZE];
- if (!random_buf) {
- if (!get_rand_pool(my_random_buf))
+ unsigned char *random_ptr;
+ if (random_buf) {
+ random_ptr = random_buf;
+ } else {
+ random_ptr = alloca(RAND_POOL_SIZE);
+ if (!get_rand_pool(random_ptr))
return false;
- random_buf = my_random_buf;
}
unsigned char machine_id_digest[HASH_LEN];
- if (!get_machine_id_hash(random_buf, machine_id_digest)) {
+ if (!get_machine_id_hash(random_ptr, machine_id_digest)) {
fputs("cannot obtain machine id, aborting save\n", stderr);
return false;
}
- char machine_id_hash[HASH_LEN*2+1];
- memset(machine_id_hash, 0, HASH_LEN*2);
- mem2hex(machine_id_hash, machine_id_digest, HASH_LEN);
- machine_id_hash[sizeof(machine_id_hash)-1] = '\0';
+ char machine_id_hash[HASH_STR_LEN];
+ mem2hex(machine_id_hash, machine_id_digest, HASH_STR_LEN);
+ machine_id_hash[HASH_STR_LEN-1] = '\0';
int seed_dir_fd = -1;
int seed_fd = -1;
FILE *seed_file = NULL;
- seed_path_tmp = strdup(seed_path);
+ char *seed_path_tmp = strdup(seed_path);
+ const char *seed_dir, *seed_name;
+ char *seed_path_last_slash = strrchr(seed_path_tmp, '/');
+ if (seed_path_last_slash) {
+ *seed_path_last_slash = '\0';
+ seed_dir = seed_path_tmp;
+ seed_name = seed_path_last_slash + 1;
+ } else {
+ free(seed_path_tmp);
+ seed_path_tmp = NULL;
+ seed_dir = ".";
+ seed_name = seed_path;
+ }
+ char *seed_name_new = NULL;
+
+ if (asprintf(&seed_name_new, ".%s.new", seed_name) == -1) {
+ fputs("out of memory\n", stderr);
+ goto out;
+ }
- seed_dir_fd = open(mydirname(seed_path_tmp), O_RDONLY | O_DIRECTORY);
+ seed_dir_fd = open(seed_dir, O_RDONLY | O_DIRECTORY);
if (seed_dir_fd == -1) {
perror("error opening seed directory");
goto out;
}
unsigned char fs_id_digest[HASH_LEN];
- if (!get_fs_id_hash(random_buf, fs_id_digest, seed_dir_fd)) {
+ if (!get_fs_id_hash(random_ptr, fs_id_digest, seed_dir_fd)) {
fputs("cannot obtain machine id, aborting save\n", stderr);
- free(seed_path_tmp);
- return false;
+ goto out;
}
char fs_id_hash[HASH_LEN*2+1];
mem2hex(fs_id_hash, fs_id_digest, HASH_LEN);
fs_id_hash[sizeof(fs_id_hash)-1] = '\0';
- strcpy(seed_path_tmp, seed_path);
- char *seed_name = mybasename(seed_path_tmp);
- size_t seed_name_new_len = strlen(seed_name) + 6;
- seed_name_new = malloc(seed_name_new_len);
- if (!seed_name_new) {
- fputs("out of memory\n", stderr);
- free(seed_path_tmp);
- return false;
- }
- assert(seed_name_new_len < INT_MAX);
- if ((size_t)snprintf(seed_name_new, seed_name_new_len, ".%s.new", seed_name) >= seed_name_new_len)
- abort();
-
seed_fd = openat(seed_dir_fd, seed_name_new, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (seed_fd == -1) {
perror("error opening new seed file");
@@ -367,7 +372,7 @@ static bool save(const char *seed_path, unsigned char *random_buf) {
goto err;
}
- if (fwrite(random_buf, 1, RAND_POOL_SIZE, seed_file) != RAND_POOL_SIZE
+ if (fwrite(random_ptr, 1, RAND_POOL_SIZE, seed_file) != RAND_POOL_SIZE
|| fputs(MAGIC, seed_file) == EOF
|| fputs("machine-id ", seed_file) == EOF
|| fputs(machine_id_hash, seed_file) == EOF
@@ -468,17 +473,22 @@ noreturn static void run(const char *mode, const char *seed_path) {
if (refresh_seed) {
unsigned char random_buf[RAND_POOL_SIZE];
unsigned char *random_ptr = random_buf;
- if (random_get(random_buf, sizeof(random_buf), GRND_NONBLOCK) == -1) {
- if (errno != EAGAIN) {
- perror("getrandom");
- exit(1);
- }
- daemon(0, 1);
- close(0);
- close(1);
- random_ptr = NULL;
+ switch (random_get(random_buf, RAND_POOL_SIZE, GRND_NONBLOCK)) {
+ case RAND_POOL_SIZE:
+ goto save;
+ case -1:
+ if (errno != EAGAIN) {
+ perror("getrandom");
+ exit(1);
+ }
}
- if (!save(seed_path, random_ptr))
+ if (daemon(0, 1) == -1) {
+ perror("error daemonizing, continuing without");
+ }
+ close(0);
+ close(1);
+ random_ptr = NULL;
+save: if (!save(seed_path, random_ptr))
exit_status = 1;
}
exit(exit_status);
@@ -505,7 +515,10 @@ noreturn static void run(const char *mode, const char *seed_path) {
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
- daemon(seed_path[0] != '/', 1);
+ if (daemon(seed_path[0] != '/', 1) == -1) {
+ perror("error daemonizing");
+ exit(1);
+ }
close(0);
close(1);
// don't close stderr because we log there