Main Page | Namespace List | Class List | Directories | File List | Class Members | File Members

canohost.c File Reference

#include "includes.h"
#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "canohost.h"

Go to the source code of this file.

Functions

 RCSID ("$OpenBSD: canohost.c,v 1.48 2005/12/28 22:46:06 stevesk Exp $")
static void check_ip_options (int, char *)
static charget_remote_hostname (int sock, int use_dns)
void ipv64_normalise_mapped (struct sockaddr_storage *addr, socklen_t *len)
const charget_canonical_hostname (int use_dns)
static charget_socket_address (int sock, int remote, int flags)
charget_peer_ipaddr (int sock)
charget_local_ipaddr (int sock)
charget_local_name (int sock)
const charget_remote_ipaddr (void)
const charget_remote_name_or_ip (u_int utmp_len, int use_dns)
static int get_sock_port (int sock, int local)
static int get_port (int local)
int get_peer_port (int sock)
int get_remote_port (void)
int get_local_port (void)


Function Documentation

static void check_ip_options int  ,
char
[static]
 

Definition at line 140 of file canohost.c.

References fatal(), options, and snprintf().

Referenced by get_remote_hostname().

00141 {
00142 #ifdef IP_OPTIONS
00143         u_char options[200];
00144         char text[sizeof(options) * 3 + 1];
00145         socklen_t option_size;
00146         u_int i;
00147         int ipproto;
00148         struct protoent *ip;
00149 
00150         if ((ip = getprotobyname("ip")) != NULL)
00151                 ipproto = ip->p_proto;
00152         else
00153                 ipproto = IPPROTO_IP;
00154         option_size = sizeof(options);
00155         if (getsockopt(sock, ipproto, IP_OPTIONS, options,
00156             &option_size) >= 0 && option_size != 0) {
00157                 text[0] = '\0';
00158                 for (i = 0; i < option_size; i++)
00159                         snprintf(text + i*3, sizeof(text) - i*3,
00160                             " %2.2x", options[i]);
00161                 fatal("Connection from %.100s with IP options:%.800s",
00162                     ipaddr, text);
00163         }
00164 #endif /* IP_OPTIONS */
00165 }

const char* get_canonical_hostname int  use_dns  ) 
 

Definition at line 199 of file canohost.c.

References get_remote_hostname(), host, packet_connection_is_on_socket(), and packet_get_connection_in().

Referenced by allowed_user(), auth_log(), auth_parse_options(), auth_rhosts(), auth_rhosts_rsa(), get_remote_name_or_ip(), getpwnamallow(), hostbased_key_allowed(), and main().

00200 {
00201         char *host;
00202         static char *canonical_host_name = NULL;
00203         static char *remote_ip = NULL;
00204 
00205         /* Check if we have previously retrieved name with same option. */
00206         if (use_dns && canonical_host_name != NULL)
00207                 return canonical_host_name;
00208         if (!use_dns && remote_ip != NULL)
00209                 return remote_ip;
00210 
00211         /* Get the real hostname if socket; otherwise return UNKNOWN. */
00212         if (packet_connection_is_on_socket())
00213                 host = get_remote_hostname(packet_get_connection_in(), use_dns);
00214         else
00215                 host = "UNKNOWN";
00216 
00217         if (use_dns)
00218                 canonical_host_name = host;
00219         else
00220                 remote_ip = host;
00221         return host;
00222 }

char* get_local_ipaddr int  sock  ) 
 

Definition at line 277 of file canohost.c.

References get_socket_address(), NI_NUMERICHOST, and xstrdup().

Referenced by do_setup_env().

00278 {
00279         char *p;
00280 
00281         if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
00282                 return p;
00283         return xstrdup("UNKNOWN");
00284 }

char* get_local_name int  sock  ) 
 

Definition at line 287 of file canohost.c.

References get_socket_address(), and NI_NAMEREQD.

Referenced by main(), and userauth_hostbased().

00288 {
00289         return get_socket_address(sock, 0, NI_NAMEREQD);
00290 }

int get_local_port void   ) 
 

Definition at line 400 of file canohost.c.

References get_port().

Referenced by do_setup_env().

00401 {
00402         return get_port(1);
00403 }

char* get_peer_ipaddr int  sock  ) 
 

Definition at line 267 of file canohost.c.

References get_socket_address(), NI_NUMERICHOST, and xstrdup().

Referenced by channel_post_x11_listener(), get_remote_ipaddr(), and port_open_helper().

00268 {
00269         char *p;
00270 
00271         if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
00272                 return p;
00273         return xstrdup("UNKNOWN");
00274 }

int get_peer_port int  sock  ) 
 

Definition at line 382 of file canohost.c.

References get_sock_port().

Referenced by channel_post_x11_listener(), and port_open_helper().

00383 {
00384         return get_sock_port(sock, 0);
00385 }

static int get_port int  local  )  [static]
 

Definition at line 368 of file canohost.c.

References get_sock_port(), packet_connection_is_on_socket(), and packet_get_connection_in().

Referenced by get_local_port(), and get_remote_port().

00369 {
00370         /*
00371          * If the connection is not a socket, return 65535.  This is
00372          * intentionally chosen to be an unprivileged port number.
00373          */
00374         if (!packet_connection_is_on_socket())
00375                 return 65535;
00376 
00377         /* Get socket and return the port number. */
00378         return get_sock_port(packet_get_connection_in(), local);
00379 }

static char* get_remote_hostname int  sock,
int  use_dns
[static]
 

Definition at line 30 of file canohost.c.

References AF_INET6, addrinfo::ai_addr, addrinfo::ai_addrlen, addrinfo::ai_next, AI_NUMERICHOST, check_ip_options(), cleanup_exit(), debug(), debug3(), fatal(), freeaddrinfo, getaddrinfo, getnameinfo, ipv64_normalise_mapped(), logit(), name, NI_MAXHOST, NI_NAMEREQD, NI_NUMERICHOST, and xstrdup().

Referenced by get_canonical_hostname().

00031 {
00032         struct sockaddr_storage from;
00033         int i;
00034         socklen_t fromlen;
00035         struct addrinfo hints, *ai, *aitop;
00036         char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
00037 
00038         /* Get IP address of client. */
00039         fromlen = sizeof(from);
00040         memset(&from, 0, sizeof(from));
00041         if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
00042                 debug("getpeername failed: %.100s", strerror(errno));
00043                 cleanup_exit(255);
00044         }
00045 
00046         ipv64_normalise_mapped(&from, &fromlen);
00047 
00048         if (from.ss_family == AF_INET6)
00049                 fromlen = sizeof(struct sockaddr_in6);
00050 
00051         if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
00052             NULL, 0, NI_NUMERICHOST) != 0)
00053                 fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
00054 
00055         if (from.ss_family == AF_INET)
00056                 check_ip_options(sock, ntop);
00057 
00058         if (!use_dns)
00059                 return xstrdup(ntop);
00060 
00061         debug3("Trying to reverse map address %.100s.", ntop);
00062         /* Map the IP address to a host name. */
00063         if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
00064             NULL, 0, NI_NAMEREQD) != 0) {
00065                 /* Host name not found.  Use ip address. */
00066                 return xstrdup(ntop);
00067         }
00068 
00069         /*
00070          * if reverse lookup result looks like a numeric hostname,
00071          * someone is trying to trick us by PTR record like following:
00072          *      1.1.1.10.in-addr.arpa.  IN PTR  2.3.4.5
00073          */
00074         memset(&hints, 0, sizeof(hints));
00075         hints.ai_socktype = SOCK_DGRAM; /*dummy*/
00076         hints.ai_flags = AI_NUMERICHOST;
00077         if (getaddrinfo(name, "0", &hints, &ai) == 0) {
00078                 logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
00079                     name, ntop);
00080                 freeaddrinfo(ai);
00081                 return xstrdup(ntop);
00082         }
00083 
00084         /*
00085          * Convert it to all lowercase (which is expected by the rest
00086          * of this software).
00087          */
00088         for (i = 0; name[i]; i++)
00089                 if (isupper(name[i]))
00090                         name[i] = tolower(name[i]);
00091         /*
00092          * Map it back to an IP address and check that the given
00093          * address actually is an address of this host.  This is
00094          * necessary because anyone with access to a name server can
00095          * define arbitrary names for an IP address. Mapping from
00096          * name to IP address can be trusted better (but can still be
00097          * fooled if the intruder has access to the name server of
00098          * the domain).
00099          */
00100         memset(&hints, 0, sizeof(hints));
00101         hints.ai_family = from.ss_family;
00102         hints.ai_socktype = SOCK_STREAM;
00103         if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
00104                 logit("reverse mapping checking getaddrinfo for %.700s "
00105                     "failed - POSSIBLE BREAK-IN ATTEMPT!", name);
00106                 return xstrdup(ntop);
00107         }
00108         /* Look for the address from the list of addresses. */
00109         for (ai = aitop; ai; ai = ai->ai_next) {
00110                 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
00111                     sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
00112                     (strcmp(ntop, ntop2) == 0))
00113                                 break;
00114         }
00115         freeaddrinfo(aitop);
00116         /* If we reached the end of the list, the address was not there. */
00117         if (!ai) {
00118                 /* Address not found for the host name. */
00119                 logit("Address %.100s maps to %.600s, but this does not "
00120                     "map back to the address - POSSIBLE BREAK-IN ATTEMPT!",
00121                     ntop, name);
00122                 return xstrdup(ntop);
00123         }
00124         return xstrdup(name);
00125 }

const char* get_remote_ipaddr void   ) 
 

Definition at line 298 of file canohost.c.

References cleanup_exit(), get_peer_ipaddr(), packet_connection_is_on_socket(), packet_get_connection_in(), and xstrdup().

Referenced by allowed_user(), auth_log(), auth_parse_options(), auth_rhosts(), auth_root_allowed(), do_setup_env(), do_ssh1_kex(), get_remote_name_or_ip(), getpwnamallow(), grace_alarm_handler(), hostbased_key_allowed(), packet_read_poll_seqnr(), packet_read_seqnr(), process_input(), ssh1_session_key(), and sshd_exchange_identification().

00299 {
00300         static char *canonical_host_ip = NULL;
00301 
00302         /* Check whether we have cached the ipaddr. */
00303         if (canonical_host_ip == NULL) {
00304                 if (packet_connection_is_on_socket()) {
00305                         canonical_host_ip =
00306                             get_peer_ipaddr(packet_get_connection_in());
00307                         if (canonical_host_ip == NULL)
00308                                 cleanup_exit(255);
00309                 } else {
00310                         /* If not on socket, return UNKNOWN. */
00311                         canonical_host_ip = xstrdup("UNKNOWN");
00312                 }
00313         }
00314         return canonical_host_ip;
00315 }

const char* get_remote_name_or_ip u_int  utmp_len,
int  use_dns
 

Definition at line 318 of file canohost.c.

References get_canonical_hostname(), and get_remote_ipaddr().

Referenced by do_child(), do_login(), and mm_record_login().

00319 {
00320         static const char *remote = "";
00321         if (utmp_len > 0)
00322                 remote = get_canonical_hostname(use_dns);
00323         if (utmp_len == 0 || strlen(remote) > utmp_len)
00324                 remote = get_remote_ipaddr();
00325         return remote;
00326 }

int get_remote_port void   ) 
 

Definition at line 388 of file canohost.c.

References get_port().

Referenced by auth_log(), do_setup_env(), and main().

00389 {
00390         static int port = -1;
00391 
00392         /* Cache to avoid getpeername() on a dead connection */
00393         if (port == -1)
00394                 port = get_port(0);
00395 
00396         return port;
00397 }

static int get_sock_port int  sock,
int  local
[static]
 

Definition at line 331 of file canohost.c.

References AF_INET6, debug(), EAI_SYSTEM, error(), fatal(), gai_strerror, getnameinfo, NI_MAXSERV, and NI_NUMERICSERV.

Referenced by get_peer_port(), and get_port().

00332 {
00333         struct sockaddr_storage from;
00334         socklen_t fromlen;
00335         char strport[NI_MAXSERV];
00336         int r;
00337 
00338         /* Get IP address of client. */
00339         fromlen = sizeof(from);
00340         memset(&from, 0, sizeof(from));
00341         if (local) {
00342                 if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) {
00343                         error("getsockname failed: %.100s", strerror(errno));
00344                         return 0;
00345                 }
00346         } else {
00347                 if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
00348                         debug("getpeername failed: %.100s", strerror(errno));
00349                         return -1;
00350                 }
00351         }
00352 
00353         /* Work around Linux IPv6 weirdness */
00354         if (from.ss_family == AF_INET6)
00355                 fromlen = sizeof(struct sockaddr_in6);
00356 
00357         /* Return port number. */
00358         if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
00359             strport, sizeof(strport), NI_NUMERICSERV)) != 0)
00360                 fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s",
00361                     r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
00362         return atoi(strport);
00363 }

static char* get_socket_address int  sock,
int  remote,
int  flags
[static]
 

Definition at line 229 of file canohost.c.

References AF_INET6, EAI_SYSTEM, error(), gai_strerror, getnameinfo, ipv64_normalise_mapped(), NI_MAXHOST, and xstrdup().

Referenced by get_local_ipaddr(), get_local_name(), and get_peer_ipaddr().

00230 {
00231         struct sockaddr_storage addr;
00232         socklen_t addrlen;
00233         char ntop[NI_MAXHOST];
00234         int r;
00235 
00236         /* Get IP address of client. */
00237         addrlen = sizeof(addr);
00238         memset(&addr, 0, sizeof(addr));
00239 
00240         if (remote) {
00241                 if (getpeername(sock, (struct sockaddr *)&addr, &addrlen)
00242                     < 0)
00243                         return NULL;
00244         } else {
00245                 if (getsockname(sock, (struct sockaddr *)&addr, &addrlen)
00246                     < 0)
00247                         return NULL;
00248         }
00249 
00250         /* Work around Linux IPv6 weirdness */
00251         if (addr.ss_family == AF_INET6)
00252                 addrlen = sizeof(struct sockaddr_in6);
00253 
00254         ipv64_normalise_mapped(&addr, &addrlen);
00255 
00256         /* Get the address in ascii. */
00257         if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
00258             sizeof(ntop), NULL, 0, flags)) != 0) {
00259                 error("get_socket_address: getnameinfo %d failed: %s", flags,
00260                     r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
00261                 return NULL;
00262         }
00263         return xstrdup(ntop);
00264 }

void ipv64_normalise_mapped struct sockaddr_storage addr,
socklen_t *  len
 

Definition at line 168 of file canohost.c.

References AF_INET6, debug3(), IN6_IS_ADDR_V4MAPPED, sockaddr_in6::sin6_addr, and sockaddr_in6::sin6_port.

Referenced by get_remote_hostname(), and get_socket_address().

00169 {
00170         struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
00171         struct sockaddr_in *a4 = (struct sockaddr_in *)addr;
00172         struct in_addr inaddr;
00173         u_int16_t port;
00174 
00175         if (addr->ss_family != AF_INET6 ||
00176             !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
00177                 return;
00178 
00179         debug3("Normalising mapped IPv4 in IPv6 address");
00180 
00181         memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
00182         port = a6->sin6_port;
00183 
00184         memset(addr, 0, sizeof(*a4));
00185 
00186         a4->sin_family = AF_INET;
00187         *len = sizeof(*a4);
00188         memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));
00189         a4->sin_port = port;
00190 }

RCSID "$OpenBSD: canohost.  c,
v 1.48 2005/12/28 22:46:06 stevesk Exp $" 
 


© sourcejam.com 2005-2008