00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "includes.h"
00015 RCSID("$OpenBSD: canohost.c,v 1.48 2005/12/28 22:46:06 stevesk Exp $");
00016
00017 #include "packet.h"
00018 #include "xmalloc.h"
00019 #include "log.h"
00020 #include "canohost.h"
00021
00022 static void check_ip_options(int, char *);
00023
00024
00025
00026
00027
00028
00029 static char *
00030 get_remote_hostname(int sock, int use_dns)
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
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
00063 if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
00064 NULL, 0, NI_NAMEREQD) != 0) {
00065
00066 return xstrdup(ntop);
00067 }
00068
00069
00070
00071
00072
00073
00074 memset(&hints, 0, sizeof(hints));
00075 hints.ai_socktype = SOCK_DGRAM;
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
00086
00087
00088 for (i = 0; name[i]; i++)
00089 if (isupper(name[i]))
00090 name[i] = tolower(name[i]);
00091
00092
00093
00094
00095
00096
00097
00098
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
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
00117 if (!ai) {
00118
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 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 static void
00140 check_ip_options(int sock, char *ipaddr)
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
00165 }
00166
00167 void
00168 ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
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 }
00191
00192
00193
00194
00195
00196
00197
00198 const char *
00199 get_canonical_hostname(int use_dns)
00200 {
00201 char *host;
00202 static char *canonical_host_name = NULL;
00203 static char *remote_ip = NULL;
00204
00205
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
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 }
00223
00224
00225
00226
00227
00228 static char *
00229 get_socket_address(int sock, int remote, int flags)
00230 {
00231 struct sockaddr_storage addr;
00232 socklen_t addrlen;
00233 char ntop[NI_MAXHOST];
00234 int r;
00235
00236
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
00251 if (addr.ss_family == AF_INET6)
00252 addrlen = sizeof(struct sockaddr_in6);
00253
00254 ipv64_normalise_mapped(&addr, &addrlen);
00255
00256
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 }
00265
00266 char *
00267 get_peer_ipaddr(int sock)
00268 {
00269 char *p;
00270
00271 if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
00272 return p;
00273 return xstrdup("UNKNOWN");
00274 }
00275
00276 char *
00277 get_local_ipaddr(int sock)
00278 {
00279 char *p;
00280
00281 if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
00282 return p;
00283 return xstrdup("UNKNOWN");
00284 }
00285
00286 char *
00287 get_local_name(int sock)
00288 {
00289 return get_socket_address(sock, 0, NI_NAMEREQD);
00290 }
00291
00292
00293
00294
00295
00296
00297 const char *
00298 get_remote_ipaddr(void)
00299 {
00300 static char *canonical_host_ip = NULL;
00301
00302
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
00311 canonical_host_ip = xstrdup("UNKNOWN");
00312 }
00313 }
00314 return canonical_host_ip;
00315 }
00316
00317 const char *
00318 get_remote_name_or_ip(u_int utmp_len, int use_dns)
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 }
00327
00328
00329
00330 static int
00331 get_sock_port(int sock, int local)
00332 {
00333 struct sockaddr_storage from;
00334 socklen_t fromlen;
00335 char strport[NI_MAXSERV];
00336 int r;
00337
00338
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
00354 if (from.ss_family == AF_INET6)
00355 fromlen = sizeof(struct sockaddr_in6);
00356
00357
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 }
00364
00365
00366
00367 static int
00368 get_port(int local)
00369 {
00370
00371
00372
00373
00374 if (!packet_connection_is_on_socket())
00375 return 65535;
00376
00377
00378 return get_sock_port(packet_get_connection_in(), local);
00379 }
00380
00381 int
00382 get_peer_port(int sock)
00383 {
00384 return get_sock_port(sock, 0);
00385 }
00386
00387 int
00388 get_remote_port(void)
00389 {
00390 static int port = -1;
00391
00392
00393 if (port == -1)
00394 port = get_port(0);
00395
00396 return port;
00397 }
00398
00399 int
00400 get_local_port(void)
00401 {
00402 return get_port(1);
00403 }