#include "includes.h"
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <stddef.h>
+
+#include <netinet/in.h>
+
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>
#include "pathnames.h"
#include "log.h"
-RCSID("$Id$");
-
/* Number of bytes we write out */
#define OUTPUT_SEED_SIZE 48
unsigned short tcp_port, char *socket_path)
{
int fd, addr_len, rval, errors;
- char msg[2];
+ u_char msg[2];
struct sockaddr_storage addr;
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;
if (socket_path != NULL &&
strlen(socket_path) >= sizeof(addr_un->sun_path))
fatal("Random pool path is too long");
- if (len > 255)
- fatal("Too many bytes to read from PRNGD");
+ if (len <= 0 || len > 255)
+ fatal("Too many bytes (%d) to read from PRNGD", len);
memset(&addr, '\0', sizeof(addr));
goto done;
}
- if (atomicio(read, fd, buf, len) != len) {
+ if (atomicio(read, fd, buf, len) != (size_t)len) {
if (errno == EPIPE && errors < 10) {
close(fd);
errors++;
debug3("Time elapsed: %d msec", msec_elapsed);
if (waitpid(pid, &status, 0) == -1) {
- error("Couldn't wait for child '%s' completion: %s",
- src->cmdstring, strerror(errno));
+ error("Couldn't wait for child '%s' completion: %s",
+ src->cmdstring, strerror(errno));
return 0.0;
}
/* Try to ensure that the parent directory is there */
snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
_PATH_SSH_USER_DIR);
- mkdir(filename, 0700);
+ if (mkdir(filename, 0700) < 0 && errno != EEXIST)
+ fatal("mkdir %.200s: %s", filename, strerror(errno));
snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
SSH_PRNG_SEED_FILE);
save_errno = errno;
unlink(tmpseed);
fatal("problem renaming PRNG seedfile from %.100s "
- "to %.100s (%.100s)", tmpseed, filename,
+ "to %.100s (%.100s)", tmpseed, filename,
strerror(save_errno));
}
}
}
num_cmds = 64;
- entcmd = xmalloc(num_cmds * sizeof(entropy_cmd_t));
- memset(entcmd, '\0', num_cmds * sizeof(entropy_cmd_t));
+ entcmd = xcalloc(num_cmds, sizeof(entropy_cmd_t));
/* Read in file */
cur_cmd = linenum = 0;
*/
if (cur_cmd == num_cmds) {
num_cmds *= 2;
- entcmd = xrealloc(entcmd, num_cmds *
+ entcmd = xrealloc(entcmd, num_cmds,
sizeof(entropy_cmd_t));
}
}
memset(&entcmd[cur_cmd], '\0', sizeof(entropy_cmd_t));
/* trim to size */
- entropy_cmds = xrealloc(entcmd, (cur_cmd + 1) *
+ entropy_cmds = xrealloc(entcmd, (cur_cmd + 1),
sizeof(entropy_cmd_t));
debug("Loaded %d entropy commands from %.100s", cur_cmd,
cmdfilename);
+ fclose(f);
return cur_cmd < MIN_ENTROPY_SOURCES ? -1 : 0;
}
return ret == bytes ? 0 : 1;
}
+
+/*
+ * We may attempt to re-seed during mkstemp if we are using the one in the
+ * compat library (via mkstemp -> _gettemp -> arc4random -> seed_rng) so we
+ * need our own seed_rng(). We must also check that we have enough entropy.
+ */
+void
+seed_rng(void)
+{
+ if (!RAND_status())
+ fatal("Not enough entropy in RNG");
+}