options.user_hostfile);
user_hostfile);
check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key){	Key *file_key;	char *ip = NULL;	char hostline[1000], *hostp;	HostStatus host_status;	HostStatus ip_status;	int local = 0, host_ip_differ = 0;	char ntop[NI_MAXHOST];	/*	 * Force accepting of the host key for loopback/localhost. The	 * problem is that if the home directory is NFS-mounted to multiple	 * machines, localhost will refer to a different machine in each of	 * them, and the user will get bogus HOST_CHANGED warnings.  This	 * essentially disables host authentication for localhost; however,	 * this is probably not a real problem.	 */	switch (hostaddr->sa_family) {	case AF_INET:		local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;		break;	case AF_INET6:		local = IN6_IS_ADDR_LOOPBACK(&(((struct sockaddr_in6 *)hostaddr)->sin6_addr));		break;	default:		local = 0;		break;	}	if (local) {		debug("Forcing accepting of host key for loopback/localhost.");		return;	}	/*	 * Turn off check_host_ip for proxy connects, since	 * we don't have the remote ip-address	 */	if (options.proxy_command != NULL && options.check_host_ip)		options.check_host_ip = 0;	if (options.check_host_ip) {		if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop),		    NULL, 0, NI_NUMERICHOST) != 0)			fatal("check_host_key: getnameinfo failed");		ip = xstrdup(ntop);	}	/*	 * Store the host key from the known host file in here so that we can	 * compare it with the key for the IP address.	 */	file_key = key_new(host_key->type);	/*	 * Check if the host key is present in the user\'s list of known	 * hosts or in the systemwide list.	 */	host_status = check_host_in_hostfile(options.user_hostfile, host, host_key, file_key);	if (host_status == HOST_NEW)		host_status = check_host_in_hostfile(options.system_hostfile, host, host_key, file_key);	/*	 * Also perform check for the ip address, skip the check if we are	 * localhost or the hostname was an ip address to begin with	 */	if (options.check_host_ip && !local && strcmp(host, ip)) {		Key *ip_key = key_new(host_key->type);		ip_status = check_host_in_hostfile(options.user_hostfile, ip, host_key, ip_key);		if (ip_status == HOST_NEW)			ip_status = check_host_in_hostfile(options.system_hostfile, ip, host_key, ip_key);		if (host_status == HOST_CHANGED &&		    (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))			host_ip_differ = 1;		key_free(ip_key);	} else		ip_status = host_status;	key_free(file_key);	switch (host_status) {	case HOST_OK:		/* The host is known and the key matches. */		debug("Host '%.200s' is known and matches the host key.", host);		if (options.check_host_ip) {			if (ip_status == HOST_NEW) {				if (!add_host_to_hostfile(options.user_hostfile, ip, host_key))					log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",					    ip, options.user_hostfile);				else					log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.",					    ip);			} else if (ip_status != HOST_OK)				log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'",				    host, ip);		}		break;	case HOST_NEW:		/* The host is new. */		if (options.strict_host_key_checking == 1) {			/* User has requested strict host key checking.  We will not add the host key			   automatically.  The only alternative left is to abort. */			fatal("No host key is known for %.200s and you have requested strict checking.", host);		} else if (options.strict_host_key_checking == 2) {			/* The default */			char prompt[1024];			char *fp = key_fingerprint(host_key);			snprintf(prompt, sizeof(prompt),			    "The authenticity of host '%.200s' can't be established.\n"			    "Key fingerprint is %s.\n"			    "Are you sure you want to continue connecting (yes/no)? ",			    host, fp);			if (!read_yes_or_no(prompt, -1))				fatal("Aborted by user!\n");		}		if (options.check_host_ip && ip_status == HOST_NEW && strcmp(host, ip)) {			snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);			hostp = hostline;		} else			hostp = host;		/* If not in strict mode, add the key automatically to the local known_hosts file. */		if (!add_host_to_hostfile(options.user_hostfile, hostp, host_key))			log("Failed to add the host to the list of known hosts (%.500s).",			    options.user_hostfile);		else			log("Warning: Permanently added '%.200s' to the list of known hosts.",			    hostp);		break;	case HOST_CHANGED:		if (options.check_host_ip && host_ip_differ) {			char *msg;			if (ip_status == HOST_NEW)				msg = "is unknown";			else if (ip_status == HOST_OK)				msg = "is unchanged";			else				msg = "has a different value";			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");			error("The host key for %s has changed,", host);			error("and the key for the according IP address %s", ip);			error("%s. This could either mean that", msg);			error("DNS SPOOFING is happening or the IP address for the host");			error("and its host key have changed at the same time");		}		/* The host key has changed. */		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 host key has just been changed.");		error("Please contact your system administrator.");		error("Add correct host key in %.100s to get rid of this message.",		      options.user_hostfile);		/*		 * If strict host key checking is in use, the user will have		 * to edit the key manually and we can only abort.		 */		if (options.strict_host_key_checking)			fatal("Host key for %.200s has changed and you have requested strict checking.", host);		/*		 * If strict host key checking has not been requested, allow		 * the connection but without password authentication or		 * agent forwarding.		 */		if (options.password_authentication) {			error("Password authentication is disabled to avoid trojan horses.");			options.password_authentication = 0;		}		if (options.forward_agent) {			error("Agent forwarding is disabled to avoid trojan horses.");			options.forward_agent = 0;		}		/*		 * XXX Should permit the user to change to use the new id.		 * This could be done by converting the host key to an		 * identifying sentence, tell that the host identifies itself		 * by that sentence, and ask the user if he/she whishes to		 * accept the authentication.		 */		break;	}	if (options.check_host_ip)		xfree(ip);}