| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssh/src/canohost.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /* $OpenBSD: canohost.c,v 1.73 2016/03/07 19:02:43 djm Exp $ */ | - | ||||||||||||
| 2 | /* | - | ||||||||||||
| 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | - | ||||||||||||
| 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | - | ||||||||||||
| 5 | * All rights reserved | - | ||||||||||||
| 6 | * Functions for returning the canonical host name of the remote site. | - | ||||||||||||
| 7 | * | - | ||||||||||||
| 8 | * As far as I am concerned, the code I have written for this software | - | ||||||||||||
| 9 | * can be used freely for any purpose. Any derived versions of this | - | ||||||||||||
| 10 | * software must be clearly marked as such, and if the derived work is | - | ||||||||||||
| 11 | * incompatible with the protocol description in the RFC file, it must be | - | ||||||||||||
| 12 | * called by a name other than "ssh" or "Secure Shell". | - | ||||||||||||
| 13 | */ | - | ||||||||||||
| 14 | - | |||||||||||||
| 15 | #include "includes.h" | - | ||||||||||||
| 16 | - | |||||||||||||
| 17 | #include <sys/types.h> | - | ||||||||||||
| 18 | #include <sys/socket.h> | - | ||||||||||||
| 19 | #include <sys/un.h> | - | ||||||||||||
| 20 | - | |||||||||||||
| 21 | #include <netinet/in.h> | - | ||||||||||||
| 22 | #include <arpa/inet.h> | - | ||||||||||||
| 23 | - | |||||||||||||
| 24 | #include <errno.h> | - | ||||||||||||
| 25 | #include <netdb.h> | - | ||||||||||||
| 26 | #include <stdio.h> | - | ||||||||||||
| 27 | #include <stdlib.h> | - | ||||||||||||
| 28 | #include <string.h> | - | ||||||||||||
| 29 | #include <stdarg.h> | - | ||||||||||||
| 30 | #include <unistd.h> | - | ||||||||||||
| 31 | - | |||||||||||||
| 32 | #include "xmalloc.h" | - | ||||||||||||
| 33 | #include "packet.h" | - | ||||||||||||
| 34 | #include "log.h" | - | ||||||||||||
| 35 | #include "canohost.h" | - | ||||||||||||
| 36 | #include "misc.h" | - | ||||||||||||
| 37 | - | |||||||||||||
| 38 | void | - | ||||||||||||
| 39 | ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) | - | ||||||||||||
| 40 | { | - | ||||||||||||
| 41 | struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; | - | ||||||||||||
| 42 | struct sockaddr_in *a4 = (struct sockaddr_in *)addr; | - | ||||||||||||
| 43 | struct in_addr inaddr; | - | ||||||||||||
| 44 | u_int16_t port; | - | ||||||||||||
| 45 | - | |||||||||||||
| 46 | if (addr->ss_family != AF_INET6 ||
| 0 | ||||||||||||
| 47 | !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
| 0 | ||||||||||||
| 48 | return; never executed: return; | 0 | ||||||||||||
| 49 | - | |||||||||||||
| 50 | debug3("Normalising mapped IPv4 in IPv6 address"); | - | ||||||||||||
| 51 | - | |||||||||||||
| 52 | memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); | - | ||||||||||||
| 53 | port = a6->sin6_port; | - | ||||||||||||
| 54 | - | |||||||||||||
| 55 | memset(a4, 0, sizeof(*a4)); | - | ||||||||||||
| 56 | - | |||||||||||||
| 57 | a4->sin_family = AF_INET; | - | ||||||||||||
| 58 | *len = sizeof(*a4); | - | ||||||||||||
| 59 | memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr)); | - | ||||||||||||
| 60 | a4->sin_port = port; | - | ||||||||||||
| 61 | } never executed: end of block | 0 | ||||||||||||
| 62 | - | |||||||||||||
| 63 | /* | - | ||||||||||||
| 64 | * Returns the local/remote IP-address/hostname of socket as a string. | - | ||||||||||||
| 65 | * The returned string must be freed. | - | ||||||||||||
| 66 | */ | - | ||||||||||||
| 67 | static char * | - | ||||||||||||
| 68 | get_socket_address(int sock, int remote, int flags) | - | ||||||||||||
| 69 | { | - | ||||||||||||
| 70 | struct sockaddr_storage addr; | - | ||||||||||||
| 71 | socklen_t addrlen; | - | ||||||||||||
| 72 | char ntop[NI_MAXHOST]; | - | ||||||||||||
| 73 | int r; | - | ||||||||||||
| 74 | - | |||||||||||||
| 75 | /* Get IP address of client. */ | - | ||||||||||||
| 76 | addrlen = sizeof(addr); | - | ||||||||||||
| 77 | memset(&addr, 0, sizeof(addr)); | - | ||||||||||||
| 78 | - | |||||||||||||
| 79 | if (remote) {
| 0 | ||||||||||||
| 80 | if (getpeername(sock, (struct sockaddr *)&addr, &addrlen) != 0)
| 0 | ||||||||||||
| 81 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
| 82 | } else { never executed: end of block | 0 | ||||||||||||
| 83 | if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) != 0)
| 0 | ||||||||||||
| 84 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
| 85 | } never executed: end of block | 0 | ||||||||||||
| 86 | - | |||||||||||||
| 87 | /* Work around Linux IPv6 weirdness */ | - | ||||||||||||
| 88 | if (addr.ss_family == AF_INET6) {
| 0 | ||||||||||||
| 89 | addrlen = sizeof(struct sockaddr_in6); | - | ||||||||||||
| 90 | ipv64_normalise_mapped(&addr, &addrlen); | - | ||||||||||||
| 91 | } never executed: end of block | 0 | ||||||||||||
| 92 | - | |||||||||||||
| 93 | switch (addr.ss_family) { | - | ||||||||||||
| 94 | case AF_INET: never executed: case 2 : | 0 | ||||||||||||
| 95 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||
| 96 | /* Get the address in ascii. */ | - | ||||||||||||
| 97 | if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
| 0 | ||||||||||||
| 98 | sizeof(ntop), NULL, 0, flags)) != 0) {
| 0 | ||||||||||||
| 99 | error("%s: getnameinfo %d failed: %s", __func__, | - | ||||||||||||
| 100 | flags, ssh_gai_strerror(r)); | - | ||||||||||||
| 101 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
| 102 | } | - | ||||||||||||
| 103 | return xstrdup(ntop); never executed: return xstrdup(ntop); | 0 | ||||||||||||
| 104 | case AF_UNIX: never executed: case 1 : | 0 | ||||||||||||
| 105 | /* Get the Unix domain socket path. */ | - | ||||||||||||
| 106 | return xstrdup(((struct sockaddr_un *)&addr)->sun_path); never executed: return xstrdup(((struct sockaddr_un *)&addr)->sun_path); | 0 | ||||||||||||
| 107 | default: never executed: default: | 0 | ||||||||||||
| 108 | /* We can't look up remote Unix domain sockets. */ | - | ||||||||||||
| 109 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
| 110 | } | - | ||||||||||||
| 111 | } | - | ||||||||||||
| 112 | - | |||||||||||||
| 113 | char * | - | ||||||||||||
| 114 | get_peer_ipaddr(int sock) | - | ||||||||||||
| 115 | { | - | ||||||||||||
| 116 | char *p; | - | ||||||||||||
| 117 | - | |||||||||||||
| 118 | if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
| 0 | ||||||||||||
| 119 | return p; never executed: return p; | 0 | ||||||||||||
| 120 | return xstrdup("UNKNOWN"); never executed: return xstrdup("UNKNOWN"); | 0 | ||||||||||||
| 121 | } | - | ||||||||||||
| 122 | - | |||||||||||||
| 123 | char * | - | ||||||||||||
| 124 | get_local_ipaddr(int sock) | - | ||||||||||||
| 125 | { | - | ||||||||||||
| 126 | char *p; | - | ||||||||||||
| 127 | - | |||||||||||||
| 128 | if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
| 0 | ||||||||||||
| 129 | return p; never executed: return p; | 0 | ||||||||||||
| 130 | return xstrdup("UNKNOWN"); never executed: return xstrdup("UNKNOWN"); | 0 | ||||||||||||
| 131 | } | - | ||||||||||||
| 132 | - | |||||||||||||
| 133 | char * | - | ||||||||||||
| 134 | get_local_name(int fd) | - | ||||||||||||
| 135 | { | - | ||||||||||||
| 136 | char *host, myname[NI_MAXHOST]; | - | ||||||||||||
| 137 | - | |||||||||||||
| 138 | /* Assume we were passed a socket */ | - | ||||||||||||
| 139 | if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL)
| 0 | ||||||||||||
| 140 | return host; never executed: return host; | 0 | ||||||||||||
| 141 | - | |||||||||||||
| 142 | /* Handle the case where we were passed a pipe */ | - | ||||||||||||
| 143 | if (gethostname(myname, sizeof(myname)) == -1) {
| 0 | ||||||||||||
| 144 | verbose("%s: gethostname: %s", __func__, strerror(errno)); | - | ||||||||||||
| 145 | host = xstrdup("UNKNOWN"); | - | ||||||||||||
| 146 | } else { never executed: end of block | 0 | ||||||||||||
| 147 | host = xstrdup(myname); | - | ||||||||||||
| 148 | } never executed: end of block | 0 | ||||||||||||
| 149 | - | |||||||||||||
| 150 | return host; never executed: return host; | 0 | ||||||||||||
| 151 | } | - | ||||||||||||
| 152 | - | |||||||||||||
| 153 | /* Returns the local/remote port for the socket. */ | - | ||||||||||||
| 154 | - | |||||||||||||
| 155 | static int | - | ||||||||||||
| 156 | get_sock_port(int sock, int local) | - | ||||||||||||
| 157 | { | - | ||||||||||||
| 158 | struct sockaddr_storage from; | - | ||||||||||||
| 159 | socklen_t fromlen; | - | ||||||||||||
| 160 | char strport[NI_MAXSERV]; | - | ||||||||||||
| 161 | int r; | - | ||||||||||||
| 162 | - | |||||||||||||
| 163 | /* Get IP address of client. */ | - | ||||||||||||
| 164 | fromlen = sizeof(from); | - | ||||||||||||
| 165 | memset(&from, 0, sizeof(from)); | - | ||||||||||||
| 166 | if (local) {
| 0 | ||||||||||||
| 167 | if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) {
| 0 | ||||||||||||
| 168 | error("getsockname failed: %.100s", strerror(errno)); | - | ||||||||||||
| 169 | return 0; never executed: return 0; | 0 | ||||||||||||
| 170 | } | - | ||||||||||||
| 171 | } else { never executed: end of block | 0 | ||||||||||||
| 172 | if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
| 0 | ||||||||||||
| 173 | debug("getpeername failed: %.100s", strerror(errno)); | - | ||||||||||||
| 174 | return -1; never executed: return -1; | 0 | ||||||||||||
| 175 | } | - | ||||||||||||
| 176 | } never executed: end of block | 0 | ||||||||||||
| 177 | - | |||||||||||||
| 178 | /* Work around Linux IPv6 weirdness */ | - | ||||||||||||
| 179 | if (from.ss_family == AF_INET6)
| 0 | ||||||||||||
| 180 | fromlen = sizeof(struct sockaddr_in6); never executed: fromlen = sizeof(struct sockaddr_in6); | 0 | ||||||||||||
| 181 | - | |||||||||||||
| 182 | /* Non-inet sockets don't have a port number. */ | - | ||||||||||||
| 183 | if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
| 0 | ||||||||||||
| 184 | return 0; never executed: return 0; | 0 | ||||||||||||
| 185 | - | |||||||||||||
| 186 | /* Return port number. */ | - | ||||||||||||
| 187 | if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
| 0 | ||||||||||||
| 188 | strport, sizeof(strport), NI_NUMERICSERV)) != 0)
| 0 | ||||||||||||
| 189 | fatal("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__, never executed: fatal("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__, ssh_gai_strerror(r)); | 0 | ||||||||||||
| 190 | ssh_gai_strerror(r)); never executed: fatal("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__, ssh_gai_strerror(r)); | 0 | ||||||||||||
| 191 | return atoi(strport); never executed: return atoi(strport); | 0 | ||||||||||||
| 192 | } | - | ||||||||||||
| 193 | - | |||||||||||||
| 194 | int | - | ||||||||||||
| 195 | get_peer_port(int sock) | - | ||||||||||||
| 196 | { | - | ||||||||||||
| 197 | return get_sock_port(sock, 0); never executed: return get_sock_port(sock, 0); | 0 | ||||||||||||
| 198 | } | - | ||||||||||||
| 199 | - | |||||||||||||
| 200 | int | - | ||||||||||||
| 201 | get_local_port(int sock) | - | ||||||||||||
| 202 | { | - | ||||||||||||
| 203 | return get_sock_port(sock, 1); never executed: return get_sock_port(sock, 1); | 0 | ||||||||||||
| 204 | } | - | ||||||||||||
| Source code | Switch to Preprocessed file |