+ char *ret = smalloc(512);
+ int size = 512, len = 0;
+ while (fgets(ret + len, size - len, fp)) {
+ len += strlen(ret + len);
+ if (ret[len-1] == '\n')
+ break; /* got a newline, we're done */
+ size = len + 512;
+ ret = srealloc(ret, size);
+ }
+ if (len == 0) { /* first fgets returned NULL */
+ sfree(ret);
+ return NULL;
+ }
+ ret[len] = '\0';
+ return ret;
+}
+
+/*
+ * Lines in the host keys file are of the form
+ *
+ * type@port:hostname keydata
+ *
+ * e.g.
+ *
+ * rsa@22:foovax.example.org 0x23,0x293487364395345345....2343
+ */
+int verify_host_key(const char *hostname, int port,
+ const char *keytype, const char *key)
+{
+ FILE *fp;
+ char filename[FILENAME_MAX];
+ char *line;
+ int ret;
+
+ make_filename(filename, INDEX_HOSTKEYS);
+ fp = fopen(filename, "r");
+ if (!fp)
+ return 1; /* key does not exist */
+
+ ret = 1;
+ while ( (line = fgetline(fp)) ) {
+ int i;
+ char *p = line;
+ char porttext[20];
+
+ line[strcspn(line, "\n")] = '\0'; /* strip trailing newline */
+
+ i = strlen(keytype);
+ if (strncmp(p, keytype, i))
+ goto done;
+ p += i;
+
+ if (*p != '@')
+ goto done;
+ p++;
+
+ sprintf(porttext, "%d", port);
+ i = strlen(porttext);
+ if (strncmp(p, porttext, i))
+ goto done;
+ p += i;
+
+ if (*p != ':')
+ goto done;
+ p++;
+
+ i = strlen(hostname);
+ if (strncmp(p, hostname, i))
+ goto done;
+ p += i;
+
+ if (*p != ' ')
+ goto done;
+ p++;
+
+ /*
+ * Found the key. Now just work out whether it's the right
+ * one or not.
+ */
+ if (!strcmp(p, key))
+ ret = 0; /* key matched OK */
+ else
+ ret = 2; /* key mismatch */
+
+ done:
+ sfree(line);
+ if (ret != 1)
+ break;
+ }
+
+ return ret;
+}
+
+void store_host_key(const char *hostname, int port,
+ const char *keytype, const char *key)
+{
+ FILE *fp;
+ int fd;
+ char filename[FILENAME_MAX];
+
+ make_filename(filename, INDEX_HOSTKEYS);
+ fd = open(filename, O_CREAT | O_APPEND | O_RDWR, 0600);
+ if (fd < 0) {
+ char dir[FILENAME_MAX];
+
+ make_filename(dir, INDEX_DIR);
+ mkdir(dir, 0700);
+ fd = open(filename, O_CREAT | O_APPEND | O_RDWR, 0600);
+ }
+ if (fd < 0) {
+ perror(filename);
+ exit(1);
+ }
+ fp = fdopen(fd, "a");
+ fprintf(fp, "%s@%d:%s %s\n", keytype, port, hostname, key);
+ fclose(fp);