diff svr-kex.c @ 986:8d0c33e8ddab coverity

merge
author Matt Johnston <matt@ucc.asn.au>
date Sun, 04 Jan 2015 22:33:12 +0800
parents 2b62f26cf808
children aaf576b27a10
line wrap: on
line diff
--- a/svr-kex.c	Tue Oct 21 22:34:20 2014 +0800
+++ b/svr-kex.c	Sun Jan 04 22:33:12 2015 +0800
@@ -84,7 +84,28 @@
 	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);
+	int dirfd = open(dir, O_RDONLY);
+
+	if (dirfd != -1) {
+		if (fsync(dirfd) != 0) {
+			TRACE(("fsync of directory %s failed: %s", dir, strerror(errno)))
+		}
+		m_close(dirfd);
+	} else {
+		TRACE(("error opening directory %s for fsync: %s", dir, strerror(errno)))
+	}
+
+	free(fn_dir);
+#endif
+}
+
 static void svr_ensure_hostkey() {
 
 	const char* fn = NULL;
@@ -142,6 +163,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) {