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); }
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); }