+ /*
+ * If we have a host key, verify_host_key will return 0 or 2.
+ * If we don't have one, it'll return 1.
+ */
+ return verify_host_key(hostname, port, keytype, "") != 1;
+}
+
+void store_host_key(const char *hostname, int port,
+ const char *keytype, const char *key)
+{
+ FILE *rfp, *wfp;
+ char *newtext, *line;
+ int headerlen;
+ char *filename, *tmpfilename;
+
+ /*
+ * Open both the old file and a new file.
+ */
+ tmpfilename = make_filename(INDEX_HOSTKEYS_TMP, NULL);
+ wfp = fopen(tmpfilename, "w");
+ if (!wfp && errno == ENOENT) {
+ char *dir;
+
+ dir = make_filename(INDEX_DIR, NULL);
+ if (mkdir(dir, 0700) < 0) {
+ nonfatal("Unable to store host key: mkdir(\"%s\") "
+ "returned '%s'", dir, strerror(errno));
+ sfree(dir);
+ sfree(tmpfilename);
+ return;
+ }
+ sfree(dir);
+
+ wfp = fopen(tmpfilename, "w");
+ }
+ if (!wfp) {
+ nonfatal("Unable to store host key: open(\"%s\") "
+ "returned '%s'", tmpfilename, strerror(errno));
+ sfree(tmpfilename);
+ return;
+ }
+ filename = make_filename(INDEX_HOSTKEYS, NULL);
+ rfp = fopen(filename, "r");
+
+ newtext = dupprintf("%s@%d:%s %s\n", keytype, port, hostname, key);
+ headerlen = 1 + strcspn(newtext, " "); /* count the space too */
+
+ /*
+ * Copy all lines from the old file to the new one that _don't_
+ * involve the same host key identifier as the one we're adding.
+ */
+ if (rfp) {
+ while ( (line = fgetline(rfp)) ) {
+ if (strncmp(line, newtext, headerlen))
+ fputs(line, wfp);
+ sfree(line);
+ }
+ fclose(rfp);
+ }
+
+ /*
+ * Now add the new line at the end.
+ */
+ fputs(newtext, wfp);
+
+ fclose(wfp);
+
+ if (rename(tmpfilename, filename) < 0) {
+ nonfatal("Unable to store host key: rename(\"%s\",\"%s\")"
+ " returned '%s'", tmpfilename, filename,
+ strerror(errno));
+ }
+
+ sfree(tmpfilename);
+ sfree(filename);
+ sfree(newtext);