changeset 982:fd2e8bbb0333

Make sure hostkeys are flushed to disk to avoid empty files if the power fails. Based on patch from Peter Korsgaard
author Matt Johnston <matt@ucc.asn.au>
date Sat, 08 Nov 2014 22:15:16 +0800
parents b2fc6607b530
children 2b62f26cf808
files gensignkey.c svr-kex.c
diffstat 2 files changed, 23 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/gensignkey.c	Thu Oct 23 22:09:46 2014 +0800
+++ b/gensignkey.c	Sat Nov 08 22:15:16 2014 +0800
@@ -41,6 +41,7 @@
 
 out:
 	if (fd >= 0) {
+		fsync(fd);
 		m_close(fd);
 	}
 	return ret;
--- a/svr-kex.c	Thu Oct 23 22:09:46 2014 +0800
+++ b/svr-kex.c	Sat Nov 08 22:15:16 2014 +0800
@@ -84,7 +84,25 @@
 	TRACE(("leave recv_msg_kexdh_init"))
 }
 
+
 #ifdef DROPBEAR_DELAY_HOSTKEY
+
+static void fsync_parent_dir(const char* fn) {
+#ifdef HAVE_LIBGEN_H
+	char *fn_dir = m_strdup(fn);
+	char *dir = dirname(fn_dir);
+	/* some OSes need the fd to be writable for fsync */
+	int dirfd = open(dir, O_RDWR);
+
+	if (dirfd != -1) {
+		fsync(dirfd);
+		m_close(dirfd);
+	}
+
+	free(fn_dir);
+#endif
+}
+
 static void svr_ensure_hostkey() {
 
 	const char* fn = NULL;
@@ -142,6 +160,10 @@
 		}
 	}
 
+	/* ensure directory update is flushed to disk, otherwise we can end up
+	with zero-byte hostkey files if the power goes off */
+	fsync_parent_dir(fn);
+
 	ret = readhostkey(fn, svr_opts.hostkey, &type);
 
 	if (ret == DROPBEAR_SUCCESS) {