summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-02-16 13:02:45 +1100
committerDamien Miller <djm@mindrot.org>2005-02-16 13:02:45 +1100
commited462d9a4557a400266c43d13fd6fa0ec8c7d9ea (patch)
tree3fff6ff14fa9a83cd1fab9f493cd3d4690bbae1e
parent66df70c97d189fb8bdf35a66b42f62bcc0a6e4da (diff)
write seed to temporary file and atomically rename into place; ok dtucker@
-rw-r--r--ChangeLog6
-rw-r--r--ssh-rand-helper.c38
2 files changed, 34 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index e076fc66..9c14c6ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+20050216
+ - (djm) write seed to temporary file and atomically rename into place;
+ ok dtucker@
+
20050215
- (dtucker) [config.sh.in] Collect oslevel -r too.
- (dtucker) [README.platform auth.c configure.ac loginrec.c
@@ -2131,4 +2135,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
-$Id: ChangeLog,v 1.3653 2005/02/15 11:19:28 dtucker Exp $
+$Id: ChangeLog,v 1.3654 2005/02/16 02:02:45 djm Exp $
diff --git a/ssh-rand-helper.c b/ssh-rand-helper.c
index 7cd081fa..6412d44e 100644
--- a/ssh-rand-helper.c
+++ b/ssh-rand-helper.c
@@ -39,7 +39,7 @@
#include "pathnames.h"
#include "log.h"
-RCSID("$Id: ssh-rand-helper.c,v 1.20 2004/12/20 01:05:08 dtucker Exp $");
+RCSID("$Id: ssh-rand-helper.c,v 1.21 2005/02/16 02:02:45 djm Exp $");
/* Number of bytes we write out */
#define OUTPUT_SEED_SIZE 48
@@ -550,10 +550,11 @@ prng_check_seedfile(char *filename)
void
prng_write_seedfile(void)
{
- int fd;
+ int fd, save_errno;
unsigned char seed[SEED_FILE_SIZE];
- char filename[MAXPATHLEN];
+ char filename[MAXPATHLEN], tmpseed[MAXPATHLEN];
struct passwd *pw;
+ mode_t old_umask;
pw = getpwuid(getuid());
if (pw == NULL)
@@ -568,7 +569,10 @@ prng_write_seedfile(void)
snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
SSH_PRNG_SEED_FILE);
- debug("writing PRNG seed to file %.100s", filename);
+ 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");
@@ -576,15 +580,31 @@ prng_write_seedfile(void)
/* 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));
+ old_umask = umask(0177);
+
+ if ((fd = mkstemp(tmpseed)) == -1) {
+ debug("WARNING: couldn't make temporary PRNG seedfile %.100s "
+ "(%.100s)", tmpseed, strerror(errno));
} else {
- if (atomicio(vwrite, fd, &seed, sizeof(seed)) < sizeof(seed))
+ 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(errno));
+ "(%.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