void
prng_write_seedfile(void)
{
	int fd, save_errno;
	unsigned char seed[SEED_FILE_SIZE];
	char filename[MAXPATHLEN], tmpseed[MAXPATHLEN];
	struct passwd *pw;
	mode_t old_umask;

	pw = getpwuid(getuid());
	if (pw == NULL)
		fatal("Couldn't get password entry for current user "
		    "(%li): %s", (long int)getuid(), strerror(errno));

	/* Try to ensure that the parent directory is there */
	snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
	    _PATH_SSH_USER_DIR);
	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);

	strlcpy(tmpseed, filename, sizeof(tmpseed));
	if (strlcat(tmpseed, ".XXXXXXXXXX", sizeof(tmpseed)) >=
	    sizeof(tmpseed))
		fatal("PRNG seed filename too long");

	if (RAND_bytes(seed, sizeof(seed)) <= 0)
		fatal("PRNG seed extraction failed");

	/* Don't care if the seed doesn't exist */
	prng_check_seedfile(filename);

	old_umask = umask(0177);

	if ((fd = mkstemp(tmpseed)) == -1) {
		debug("WARNING: couldn't make temporary PRNG seedfile %.100s "
		    "(%.100s)", tmpseed, strerror(errno));
	} else {
		debug("writing PRNG seed to file %.100s", tmpseed);
		if (atomicio(vwrite, fd, &seed, sizeof(seed)) < sizeof(seed)) {
			save_errno = errno;
			close(fd);
			unlink(tmpseed);
			fatal("problem writing PRNG seedfile %.100s "
			    "(%.100s)", filename, strerror(save_errno));
		}
		close(fd);
		debug("moving temporary PRNG seed to file %.100s", filename);
		if (rename(tmpseed, filename) == -1) {
			save_errno = errno;
			unlink(tmpseed);
			fatal("problem renaming PRNG seedfile from %.100s "
			    "to %.100s (%.100s)", tmpseed, filename,
			    strerror(save_errno));
		}
	}
	umask(old_umask);
}
示例#2
0
void
prng_write_seedfile(void)
{
	int fd;
	unsigned char seed[SEED_FILE_SIZE];
	char filename[MAXPATHLEN];
	struct passwd *pw;

	pw = getpwuid(getuid());
	if (pw == NULL)
		fatal("Couldn't get password entry for current user "
		    "(%i): %s", getuid(), strerror(errno));

	/* 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);

	snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
	    SSH_PRNG_SEED_FILE);

	debug("writing PRNG seed to file %.100s", filename);

	if (RAND_bytes(seed, sizeof(seed)) <= 0)
		fatal("PRNG seed extration failed");

	/* Don't care if the seed doesn't exist */
	prng_check_seedfile(filename);

	if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) {
		debug("WARNING: couldn't access PRNG seedfile %.100s "
		    "(%.100s)", filename, strerror(errno));
	} else {
		if (atomicio(write, fd, &seed, sizeof(seed)) < sizeof(seed))
			fatal("problem writing PRNG seedfile %.100s "
			    "(%.100s)", filename, strerror(errno));
		close(fd);
	}
}
void
prng_read_seedfile(void)
{
	int fd;
	char seed[SEED_FILE_SIZE], filename[MAXPATHLEN];
	struct passwd *pw;

	pw = getpwuid(getuid());
	if (pw == NULL)
		fatal("Couldn't get password entry for current user "
		    "(%li): %s", (long int)getuid(), strerror(errno));

	snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
		SSH_PRNG_SEED_FILE);

	debug("loading PRNG seed from file %.100s", filename);

	if (!prng_check_seedfile(filename)) {
		verbose("Random seed file not found or invalid, ignoring.");
		return;
	}

	/* open the file and read in the seed */
	fd = open(filename, O_RDONLY);
	if (fd == -1)
		fatal("could not open PRNG seedfile %.100s (%.100s)",
		    filename, strerror(errno));

	if (atomicio(read, fd, &seed, sizeof(seed)) < sizeof(seed)) {
		verbose("invalid or short read from PRNG seedfile "
		    "%.100s - ignoring", filename);
		memset(seed, '\0', sizeof(seed));
	}
	close(fd);

	/* stir in the seed, with estimated entropy zero */
	RAND_add(&seed, sizeof(seed), 0.0);
}