/*
 * 
 * canohost.c
 * 
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * 
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * 
 * Created: Sun Jul  2 17:52:22 1995 ylo
 * 
 * Functions for returning the canonical host name of the remote site.
 * 
 */

#include "includes.h"
RCSID("$Id: canohost.c,v 1.6 1999/12/18 09:57:40 damien Exp $");

#include "packet.h"
#include "xmalloc.h"
#include "ssh.h"

/*
 * Return the canonical name of the host at the other end of the socket. The
 * caller should free the returned string with xfree.
 */

char *
get_remote_hostname(int socket)
{
	struct sockaddr_in from;
	int fromlen, i;
	struct hostent *hp;
	char name[MAXHOSTNAMELEN];

	/* Get IP address of client. */
	fromlen = sizeof(from);
	memset(&from, 0, sizeof(from));
	if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) {
		debug("getpeername failed: %.100s", strerror(errno));
		fatal_cleanup();
	}
	/* Map the IP address to a host name. */
	hp = gethostbyaddr((char *) &from.sin_addr, sizeof(struct in_addr),
			   from.sin_family);
	if (hp) {
		/* Got host name, find canonic host name. */
		if (strchr(hp->h_name, '.') != 0)
			strlcpy(name, hp->h_name, sizeof(name));
		else if (hp->h_aliases != 0
			 && hp->h_aliases[0] != 0
			 && strchr(hp->h_aliases[0], '.') != 0)
			strlcpy(name, hp->h_aliases[0], sizeof(name));
		else
			strlcpy(name, hp->h_name, sizeof(name));

		/*
		 * Convert it to all lowercase (which is expected by the rest
		 * of this software).
		 */
		for (i = 0; name[i]; i++)
			if (isupper(name[i]))
				name[i] = tolower(name[i]);

		/*
		 * Map it back to an IP address and check that the given
		 * address actually is an address of this host.  This is
		 * necessary because anyone with access to a name server can
		 * define arbitrary names for an IP address. Mapping from
		 * name to IP address can be trusted better (but can still be
		 * fooled if the intruder has access to the name server of
		 * the domain).
		 */
		hp = gethostbyname(name);
		if (!hp) {
			log("reverse mapping checking gethostbyname for %.700s failed - POSSIBLE BREAKIN ATTEMPT!", name);
			strlcpy(name, inet_ntoa(from.sin_addr), sizeof name);
			goto check_ip_options;
		}
		/* Look for the address from the list of addresses. */
		for (i = 0; hp->h_addr_list[i]; i++)
			if (memcmp(hp->h_addr_list[i], &from.sin_addr, sizeof(from.sin_addr))
			    == 0)
				break;
		/*
		 * If we reached the end of the list, the address was not
		 * there.
		 */
		if (!hp->h_addr_list[i]) {
			/* Address not found for the host name. */
			log("Address %.100s maps to %.600s, but this does not map back to the address - POSSIBLE BREAKIN ATTEMPT!",
			    inet_ntoa(from.sin_addr), name);
			strlcpy(name, inet_ntoa(from.sin_addr), sizeof name);
			goto check_ip_options;
		}
		/* Address was found for the host name.  We accept the host name. */
	} else {
		/* Host name not found.  Use ascii representation of the address. */
		strlcpy(name, inet_ntoa(from.sin_addr), sizeof name);
		log("Could not reverse map address %.100s.", name);
	}

check_ip_options:

	/*
	 * If IP options are supported, make sure there are none (log and
	 * disconnect them if any are found).  Basically we are worried about
	 * source routing; it can be used to pretend you are somebody
	 * (ip-address) you are not. That itself may be "almost acceptable"
	 * under certain circumstances, but rhosts autentication is useless
	 * if source routing is accepted. Notice also that if we just dropped
	 * source routing here, the other side could use IP spoofing to do
	 * rest of the interaction and could still bypass security.  So we
	 * exit here if we detect any IP options.
	 */
	{
		unsigned char options[200], *ucp;
		char text[1024], *cp;
		int option_size, ipproto;
		struct protoent *ip;

		if ((ip = getprotobyname("ip")) != NULL)
			ipproto = ip->p_proto;
		else
			ipproto = IPPROTO_IP;
		option_size = sizeof(options);
		if (getsockopt(0, ipproto, IP_OPTIONS, (char *) options,
			       &option_size) >= 0 && option_size != 0) {
			cp = text;
			/* Note: "text" buffer must be at least 3x as big as options. */
			for (ucp = options; option_size > 0; ucp++, option_size--, cp += 3)
				sprintf(cp, " %2.2x", *ucp);
			log("Connection from %.100s with IP options:%.800s",
			    inet_ntoa(from.sin_addr), text);
			packet_disconnect("Connection from %.100s with IP options:%.800s",
					  inet_ntoa(from.sin_addr), text);
		}
	}

	return xstrdup(name);
}

static char *canonical_host_name = NULL;
static char *canonical_host_ip = NULL;

/* Returns 1 if remote host is connected via socket, 0 if not. */

int
peer_connection_is_on_socket()
{
	struct sockaddr_in from;
	int fromlen;
	int in = packet_get_connection_in();
	int out = packet_get_connection_out();

	/* filedescriptors in and out are the same, so it's a socket */
	if (in == out)
		return 1;
	fromlen = sizeof(from);
	memset(&from, 0, sizeof(from));
	if (getpeername(in, (struct sockaddr *) & from, &fromlen) < 0)
		return 0;
	if (from.sin_family != AF_INET)
		return 0;

	return 1;
}

/*
 * Return the canonical name of the host in the other side of the current
 * connection.  The host name is cached, so it is efficient to call this
 * several times.
 */

const char *
get_canonical_hostname()
{
	/* Check if we have previously retrieved this same name. */
	if (canonical_host_name != NULL)
		return canonical_host_name;

	/* Get the real hostname if socket; otherwise return UNKNOWN. */
	if (peer_connection_is_on_socket())
		canonical_host_name = get_remote_hostname(packet_get_connection_in());
	else
		canonical_host_name = xstrdup("UNKNOWN");

	return canonical_host_name;
}

/*
 * Returns the IP-address of the remote host as a string.  The returned
 * string need not be freed.
 */

const char *
get_remote_ipaddr()
{
	struct sockaddr_in from;
	int fromlen, socket;

	/* Check whether we have chached the name. */
	if (canonical_host_ip != NULL)
		return canonical_host_ip;

	/* If not a socket, return UNKNOWN. */
	if (!peer_connection_is_on_socket()) {
		canonical_host_ip = xstrdup("UNKNOWN");
		return canonical_host_ip;
	}
	/* Get client socket. */
	socket = packet_get_connection_in();

	/* Get IP address of client. */
	fromlen = sizeof(from);
	memset(&from, 0, sizeof(from));
	if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) {
		debug("getpeername failed: %.100s", strerror(errno));
		fatal_cleanup();
	}
	/* Get the IP address in ascii. */
	canonical_host_ip = xstrdup(inet_ntoa(from.sin_addr));

	/* Return ip address string. */
	return canonical_host_ip;
}

/* Returns the port of the peer of the socket. */

int 
get_peer_port(int sock)
{
	struct sockaddr_in from;
	int fromlen;

	/* Get IP address of client. */
	fromlen = sizeof(from);
	memset(&from, 0, sizeof(from));
	if (getpeername(sock, (struct sockaddr *) & from, &fromlen) < 0) {
		debug("getpeername failed: %.100s", strerror(errno));
		fatal_cleanup();
	}
	/* Return port number. */
	return ntohs(from.sin_port);
}

/* Returns the port number of the remote host.  */

int 
get_remote_port()
{
	int socket;

	/*
	 * If the connection is not a socket, return 65535.  This is
	 * intentionally chosen to be an unprivileged port number.
	 */
	if (!peer_connection_is_on_socket())
		return 65535;

	/* Get client socket. */
	socket = packet_get_connection_in();

	/* Get and return the peer port number. */
	return get_peer_port(socket);
}
