Changeset c39cd8e for lib/misc.c
- Timestamp:
- 2017-04-02T18:50:49Z (8 years ago)
- Children:
- df67b48
- Parents:
- 262a82b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/misc.c
r262a82b rc39cd8e 549 549 } 550 550 551 /* From OpenSSH 7.4p1 canohost.c" */ 552 char *reverse_lookup(const struct sockaddr *from_, const socklen_t fromlen_) 553 { 554 struct sockaddr_storage from; 555 socklen_t fromlen; 556 struct addrinfo hints, *ai, *aitop; 557 char name[NI_MAXHOST], ntop2[NI_MAXHOST]; 558 char ntop[INET6_ADDRSTRLEN]; 559 560 fromlen = sizeof(from); 561 memset(&from, 0, sizeof(from)); 562 memcpy(&from, from_, fromlen_); 563 ipv64_normalise_mapped(&from, &fromlen); 564 if (from.ss_family == AF_INET6) { 565 fromlen = sizeof(struct sockaddr_in6); 566 } 567 568 if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), 569 NULL, 0, NI_NUMERICHOST) != 0) { 570 return NULL; 571 } 572 573 /* Map the IP address to a host name. */ 574 if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), 575 NULL, 0, NI_NAMEREQD) != 0) { 576 /* Host name not found. Use ip address. */ 577 return g_strdup(ntop); 578 } 579 580 /* 581 * if reverse lookup result looks like a numeric hostname, 582 * someone is trying to trick us by PTR record like following: 583 * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 584 */ 585 memset(&hints, 0, sizeof(hints)); 586 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 587 hints.ai_flags = AI_NUMERICHOST; 588 if (getaddrinfo(name, NULL, &hints, &ai) == 0) { 589 freeaddrinfo(ai); 590 return g_strdup(ntop); 591 } 592 593 /* Names are stored in lowercase. */ 594 char *tolower = g_utf8_strdown(name, -1); 595 g_snprintf(name, sizeof(name), "%s", tolower); 596 g_free(tolower); 597 598 /* 599 * Map it back to an IP address and check that the given 600 * address actually is an address of this host. This is 601 * necessary because anyone with access to a name server can 602 * define arbitrary names for an IP address. Mapping from 603 * name to IP address can be trusted better (but can still be 604 * fooled if the intruder has access to the name server of 605 * the domain). 606 */ 607 memset(&hints, 0, sizeof(hints)); 608 hints.ai_family = from.ss_family; 609 hints.ai_socktype = SOCK_STREAM; 610 if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { 611 return g_strdup(ntop); 612 } 613 /* Look for the address from the list of addresses. */ 614 for (ai = aitop; ai; ai = ai->ai_next) { 615 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, 616 sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && 617 (strcmp(ntop, ntop2) == 0)) 618 break; 619 } 620 freeaddrinfo(aitop); 621 /* If we reached the end of the list, the address was not there. */ 622 if (ai == NULL) { 623 /* Address not found for the host name. */ 624 return g_strdup(ntop); 625 } 626 return g_strdup(name); 627 } 628 629 void 630 ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) 631 { 632 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; 633 struct sockaddr_in *a4 = (struct sockaddr_in *)addr; 634 struct in_addr inaddr; 635 u_int16_t port; 636 637 if (addr->ss_family != AF_INET6 || 638 !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr)) 639 return; 640 641 memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); 642 port = a6->sin6_port; 643 644 memset(a4, 0, sizeof(*a4)); 645 646 a4->sin_family = AF_INET; 647 *len = sizeof(*a4); 648 memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr)); 649 a4->sin_port = port; 650 } 651 551 652 char *word_wrap(const char *msg, int line_len) 552 653 {
Note: See TracChangeset
for help on using the changeset viewer.