X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/3d040d098384c48be39e47862d55cac1bc0c578c..7533e17a427d6ae51bba9af028b0d9496f487caf:/src/src/host.c diff --git a/src/src/host.c b/src/src/host.c index 2b09cc260..9c66e9aac 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -2,9 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or directly via the DNS. When IPv6 is supported, getipnodebyname() and @@ -84,13 +85,13 @@ random_number(int limit) if (limit < 1) return 0; if (random_seed == 0) - { - if (f.running_in_test_harness) random_seed = 42; else + if (f.running_in_test_harness) + random_seed = 42; + else { int p = (int)getpid(); random_seed = (int)time(NULL) ^ ((p << 16) | p); } - } random_seed = 1103515245 * random_seed + 12345; return (unsigned int)(random_seed >> 16) % limit; } @@ -363,77 +364,6 @@ while ((name = string_nextinlist(&list, &sep, NULL, 0))) } - - - -/************************************************* -* Extract port from address string * -*************************************************/ - -/* In the spool file, and in the -oMa and -oMi options, a host plus port is -given as an IP address followed by a dot and a port number. This function -decodes this. - -An alternative format for the -oMa and -oMi options is [ip address]:port which -is what Exim 4 uses for output, because it seems to becoming commonly used, -whereas the dot form confuses some programs/people. So we recognize that form -too. - -Argument: - address points to the string; if there is a port, the '.' in the string - is overwritten with zero to terminate the address; if the string - is in the [xxx]:ppp format, the address is shifted left and the - brackets are removed - -Returns: 0 if there is no port, else the port number. If there's a syntax - error, leave the incoming address alone, and return 0. -*/ - -int -host_address_extract_port(uschar *address) -{ -int port = 0; -uschar *endptr; - -/* Handle the "bracketed with colon on the end" format */ - -if (*address == '[') - { - uschar *rb = address + 1; - while (*rb != 0 && *rb != ']') rb++; - if (*rb++ == 0) return 0; /* Missing ]; leave invalid address */ - if (*rb == ':') - { - port = Ustrtol(rb + 1, &endptr, 10); - if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ - } - else if (*rb != 0) return 0; /* Bad syntax; leave invalid address */ - memmove(address, address + 1, rb - address - 2); - rb[-2] = 0; - } - -/* Handle the "dot on the end" format */ - -else - { - int skip = -3; /* Skip 3 dots in IPv4 addresses */ - address--; - while (*(++address) != 0) - { - int ch = *address; - if (ch == ':') skip = 0; /* Skip 0 dots in IPv6 addresses */ - else if (ch == '.' && skip++ >= 0) break; - } - if (*address == 0) return 0; - port = Ustrtol(address + 1, &endptr, 10); - if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ - *address = 0; - } - -return port; -} - - /************************************************* * Get port from a host item's name * *************************************************/ @@ -894,9 +824,9 @@ Returns: pointer to character string */ uschar * -host_ntoa(int type, const void *arg, uschar *buffer, int *portptr) +host_ntoa(int type, const void * arg, uschar * buffer, int * portptr) { -uschar *yield; +uschar * yield; /* The new world. It is annoying that we have to fish out the address from different places in the block, depending on what kind of address it is. It @@ -982,7 +912,7 @@ Returns: the number of ints used */ int -host_aton(const uschar *address, int *bin) +host_aton(const uschar * address, int * bin) { int x[4]; int v4offset = 0; @@ -994,13 +924,10 @@ supported. */ if (Ustrchr(address, ':') != NULL) { - const uschar *p = address; - const uschar *component[8]; + const uschar * p = address; + const uschar * component[8]; BOOL ipv4_ends = FALSE; - int ci = 0; - int nulloffset = 0; - int v6count = 8; - int i; + int ci = 0, nulloffset = 0, v6count = 8, i; /* If the address starts with a colon, it will start with two colons. Just lose the first one, which will leave a null first component. */ @@ -1012,7 +939,7 @@ if (Ustrchr(address, ':') != NULL) overlooked; to guard against that happening again, check here and crash if there are too many components. */ - while (*p != 0 && *p != '%') + while (*p && *p != '%') { int len = Ustrcspn(p, ":%"); if (len == 0) nulloffset = ci; @@ -1717,6 +1644,7 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0))) rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR) { uschar * s = store_get(ssize, GET_TAINTED); /* names are tainted */ + unsigned slen; /* If an overlong response was received, the data will have been truncated and dn_expand may fail. */ @@ -1729,13 +1657,19 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0))) break; } - store_release_above(s + Ustrlen(s) + 1); - if (!s[0]) + store_release_above(s + (slen = Ustrlen(s)) + 1); + if (!*s) { HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an " "empty name: treated as non-existent host name\n"); continue; } + if (Ustrspn(s, letter_digit_hyphen_dot) != slen) + { + HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an " + "illegal name (bad char): treated as non-existent host name\n"); + continue; + } if (!sender_host_name) sender_host_name = s; else *aptr++ = s; while (*s) { *s = tolower(*s); s++; } @@ -2144,11 +2078,11 @@ so we pass that back. */ if (!host->address) { uschar *msg = - #ifndef STAND_ALONE +#ifndef STAND_ALONE !message_id[0] && smtp_in ? string_sprintf("no IP address found for host %s (during %s)", host->name, smtp_get_connection_info()) : - #endif +#endif string_sprintf("no IP address found for host %s", host->name); HDEBUG(D_host_lookup) debug_printf("%s\n", msg);