+
+static int
+show_key_from_file(const char *file, const char *host, int keytype)
+{
+ Key *found;
+ char *fp;
+ int line, ret;
+
+ found = key_new(keytype);
+ if ((ret = lookup_key_in_hostfile_by_type(file, host,
+ keytype, found, &line))) {
+ fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+ logit("WARNING: %s key found for host %s\n"
+ "in %s:%d\n"
+ "%s key fingerprint %s.",
+ key_type(found), host, file, line,
+ key_type(found), fp);
+ xfree(fp);
+ }
+ key_free(found);
+ return (ret);
+}
+
+/* print all known host keys for a given host, but skip keys of given type */
+static int
+show_other_keys(const char *host, Key *key)
+{
+ int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, -1};
+ int i, found = 0;
+
+ for (i = 0; type[i] != -1; i++) {
+ if (type[i] == key->type)
+ continue;
+ if (type[i] != KEY_RSA1 &&
+ show_key_from_file(options.user_hostfile2, host, type[i])) {
+ found = 1;
+ continue;
+ }
+ if (type[i] != KEY_RSA1 &&
+ show_key_from_file(options.system_hostfile2, host, type[i])) {
+ found = 1;
+ continue;
+ }
+ if (show_key_from_file(options.user_hostfile, host, type[i])) {
+ found = 1;
+ continue;
+ }
+ if (show_key_from_file(options.system_hostfile, host, type[i])) {
+ found = 1;
+ continue;
+ }
+ debug2("no key of type %d for host %s", type[i], host);
+ }
+ return (found);
+}
+
+static void
+warn_changed_key(Key *host_key)
+{
+ char *fp;
+ const char *type = key_type(host_key);
+
+ fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
+
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
+ error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
+ error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
+ error("It is also possible that the %s host key has just been changed.", type);
+ error("The fingerprint for the %s key sent by the remote host is\n%s.",
+ type, fp);
+ error("Please contact your system administrator.");
+
+ xfree(fp);
+}
+
+/*
+ * Execute a local command
+ */
+int
+ssh_local_cmd(const char *args)
+{
+ char *shell;
+ pid_t pid;
+ int status;
+
+ if (!options.permit_local_command ||
+ args == NULL || !*args)
+ return (1);
+
+ if ((shell = getenv("SHELL")) == NULL)
+ shell = _PATH_BSHELL;
+
+ pid = fork();
+ if (pid == 0) {
+ debug3("Executing %s -c \"%s\"", shell, args);
+ execl(shell, shell, "-c", args, (char *)NULL);
+ error("Couldn't execute %s -c \"%s\": %s",
+ shell, args, strerror(errno));
+ _exit(1);
+ } else if (pid == -1)
+ fatal("fork failed: %.100s", strerror(errno));
+ while (waitpid(pid, &status, 0) == -1)
+ if (errno != EINTR)
+ fatal("Couldn't wait for child: %s", strerror(errno));
+
+ if (!WIFEXITED(status))
+ return (1);
+
+ return (WEXITSTATUS(status));
+}