1 /*
2 * ProFTPD - FTP server daemon
3 * Copyright (c) 2003-2021 The ProFTPD Project team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, The ProFTPD Project team and other respective
20 * copyright holders give permission to link this program with OpenSSL, and
21 * distribute the resulting executable, without including the source code for
22 * OpenSSL in the source distribution.
23 */
24
25 /* Network address routines */
26
27 #include "conf.h"
28
29 #if HAVE_NET_IF_H
30 # include <net/if.h>
31 #endif
32 #if HAVE_IFADDRS_H
33 # include <ifaddrs.h>
34 #endif
35
36 /* Define an IPv4 equivalent of the IN6_IS_ADDR_LOOPBACK macro. */
37 #undef IN_IS_ADDR_LOOPBACK
38 #define IN_IS_ADDR_LOOPBACK(a) \
39 ((((unsigned long int) ntohl((a)->s_addr)) & 0xff000000) == 0x7f000000)
40
41 static pr_netaddr_t sess_local_addr;
42 static int have_sess_local_addr = FALSE;
43
44 static pr_netaddr_t sess_remote_addr;
45 static char sess_remote_name[PR_TUNABLE_BUFFER_SIZE];
46 static int have_sess_remote_addr = FALSE;
47
48 /* Do reverse DNS lookups? */
49 static int reverse_dns = 1;
50
51 /* Use IPv6? */
52 #ifdef PR_USE_IPV6
53 static int use_ipv6 = TRUE;
54 #else
55 static int use_ipv6 = FALSE;
56 #endif /* PR_USE_IPV6 */
57
58 static char localaddr_str[PR_TUNABLE_BUFFER_SIZE];
59 static int have_localaddr_str = FALSE;
60
61 static pool *netaddr_pool = NULL;
62 static pr_table_t *netaddr_iptab = NULL;
63 static pr_table_t *netaddr_dnstab = NULL;
64
65 static const char *trace_channel = "dns";
66
67 /* Netaddr cache management */
netaddr_dnscache_get(pool * p,const char * ip_str)68 static array_header *netaddr_dnscache_get(pool *p, const char *ip_str) {
69 array_header *res = NULL;
70
71 if (netaddr_dnstab != NULL) {
72 const void *v;
73
74 v = pr_table_get(netaddr_dnstab, ip_str, NULL);
75 if (v != NULL) {
76 res = (array_header *) v;
77
78 pr_trace_msg(trace_channel, 4,
79 "using %d DNS %s from netaddr DNS cache for IP address '%s'",
80 res->nelts, res->nelts != 1 ? "names" : "name", ip_str);
81
82 if (p) {
83 /* If the caller provided a pool, return a copy of the array. */
84 return copy_array_str(p, res);
85 }
86
87 return res;
88 }
89 }
90
91 pr_trace_msg(trace_channel, 12,
92 "no DNS names found in netaddr DNS cache for IP address '%s'", ip_str);
93 errno = ENOENT;
94 return NULL;
95 }
96
netaddr_dnscache_set(const char * ip_str,const char * dns_name)97 static void netaddr_dnscache_set(const char *ip_str, const char *dns_name) {
98 if (netaddr_dnstab) {
99 void *v = NULL;
100 array_header *res = NULL;
101 int add_list = FALSE;
102
103 res = netaddr_dnscache_get(NULL, ip_str);
104 if (res == NULL) {
105 /* No existing entries for this IP address yet. */
106 res = make_array(netaddr_pool, 1, sizeof(char *));
107 add_list = TRUE;
108
109 } else {
110 register unsigned int i;
111 char **names;
112
113 /* Check for duplicates. */
114 names = res->elts;
115 for (i = 0; i < res->nelts; i++) {
116 if (names[i] != NULL) {
117 if (strcmp(names[i], dns_name) == 0) {
118 pr_trace_msg(trace_channel, 5,
119 "DNS name '%s' for IP address '%s' already stashed in the "
120 "netaddr DNS cache", dns_name, ip_str);
121 return;
122 }
123 }
124 }
125 }
126
127 *((char **) push_array(res)) = pstrdup(netaddr_pool, dns_name);
128 v = res;
129
130 if (add_list) {
131 if (pr_table_add(netaddr_dnstab, pstrdup(netaddr_pool, ip_str), v,
132 sizeof(array_header *)) < 0) {
133 pr_trace_msg(trace_channel, 3,
134 "error adding DNS name '%s' for IP address '%s' to the netaddr "
135 "DNS cache: %s", dns_name, ip_str, strerror(errno));
136
137 } else {
138 pr_trace_msg(trace_channel, 5,
139 "stashed DNS name '%s' for IP address '%s' in the netaddr DNS cache",
140 dns_name, ip_str);
141 }
142
143 } else {
144 pr_trace_msg(trace_channel, 5,
145 "stashed DNS name '%s' for IP address '%s' in the netaddr DNS cache",
146 dns_name, ip_str);
147 }
148 }
149
150 return;
151 }
152
netaddr_ipcache_get(pool * p,const char * name)153 static pr_netaddr_t *netaddr_ipcache_get(pool *p, const char *name) {
154 pr_netaddr_t *res = NULL;
155
156 if (netaddr_iptab != NULL) {
157 const void *v;
158
159 v = pr_table_get(netaddr_iptab, name, NULL);
160 if (v != NULL) {
161 res = (pr_netaddr_t *) v;
162 pr_trace_msg(trace_channel, 4,
163 "using IP address '%s' from netaddr IP cache for name '%s'",
164 pr_netaddr_get_ipstr(res), name);
165
166 /* We return a copy of the cache's netaddr_t, if the caller provided
167 * a pool for duplication.
168 */
169 if (p != NULL) {
170 pr_netaddr_t *dup_res = NULL;
171
172 dup_res = pr_netaddr_dup(p, res);
173 if (dup_res == NULL) {
174 pr_log_debug(DEBUG0, "error duplicating address for name '%s' "
175 "from cache: %s", name, strerror(errno));
176 }
177
178 return dup_res;
179 }
180
181 return res;
182 }
183 }
184
185 pr_trace_msg(trace_channel, 2,
186 "no IP address found in netaddr IP cache for name '%s'", name);
187 errno = ENOENT;
188 return NULL;
189 }
190
netaddr_ipcache_set(const char * name,const pr_netaddr_t * na)191 static int netaddr_ipcache_set(const char *name, const pr_netaddr_t *na) {
192 if (netaddr_iptab != NULL) {
193 int count = 0;
194 void *v = NULL;
195
196 /* We store an internal copy of the netaddr_t in the cache. */
197 v = pr_netaddr_dup(netaddr_pool, na);
198 if (v == NULL) {
199 return -1;
200 }
201
202 count = pr_table_exists(netaddr_iptab, name);
203 if (count <= 0) {
204 if (pr_table_add(netaddr_iptab, pstrdup(netaddr_pool, name), v,
205 sizeof(pr_netaddr_t *)) < 0) {
206 pr_trace_msg(trace_channel, 3,
207 "error adding IP address '%s' for name '%s' to the netaddr "
208 "IP cache: %s", pr_netaddr_get_ipstr(na), name,
209 strerror(errno));
210
211 } else {
212 pr_trace_msg(trace_channel, 5,
213 "stashed IP address '%s' for name '%s' in the netaddr IP cache",
214 pr_netaddr_get_ipstr(v), name);
215 }
216
217 } else {
218 if (pr_table_set(netaddr_iptab, pstrdup(netaddr_pool, name), v,
219 sizeof(pr_netaddr_t *)) < 0) {
220 pr_trace_msg(trace_channel, 3,
221 "error setting IP address '%s' for name '%s' in the netaddr "
222 "IP cache: %s", pr_netaddr_get_ipstr(na), name, strerror(errno));
223 }
224 }
225 }
226
227 return 0;
228 }
229
230 /* Provide replacements for needed functions. */
231
232 #if !defined(HAVE_GETNAMEINFO) || defined(PR_USE_GETNAMEINFO)
pr_getnameinfo(const struct sockaddr * sa,socklen_t salen,char * host,size_t hostlen,char * serv,size_t servlen,int flags)233 int pr_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
234 size_t hostlen, char *serv, size_t servlen, int flags) {
235
236 struct sockaddr_in *sai = (struct sockaddr_in *) sa;
237
238 if (!sai || sai->sin_family != AF_INET)
239 return EAI_FAMILY;
240
241 if (serv != NULL && servlen > (size_t) 1)
242 pr_snprintf(serv, servlen, "%lu", (unsigned long) ntohs(sai->sin_port));
243
244 if (host != NULL && hostlen > (size_t) 1) {
245 struct hostent *he = NULL;
246
247 if ((flags & NI_NUMERICHOST) == 0 &&
248 (he = gethostbyaddr((const char *) &(sai->sin_addr),
249 sizeof(sai->sin_addr), AF_INET)) != NULL &&
250 he->h_name != NULL &&
251 *he->h_name != 0) {
252
253 if (strlen(he->h_name) >= hostlen)
254 goto handle_numeric_ip;
255 sstrncpy(host, he->h_name, hostlen);
256
257 } else {
258 char *ipstr = NULL;
259
260 handle_numeric_ip:
261 ipstr = inet_ntoa(sai->sin_addr);
262 if (ipstr == NULL)
263 return EAI_SYSTEM;
264
265 if (strlen(ipstr) >= hostlen)
266 return EAI_FAIL;
267
268 sstrncpy(host, ipstr, hostlen);
269 }
270 }
271
272 return 0;
273 }
274 #endif /* HAVE_GETNAMEINFO or PR_USE_GETNAMEINFO */
275
276 #if !defined(HAVE_GETADDRINFO) || defined(PR_USE_GETADDRINFO)
pr_getaddrinfo(const char * node,const char * service,const struct addrinfo * hints,struct addrinfo ** res)277 int pr_getaddrinfo(const char *node, const char *service,
278 const struct addrinfo *hints, struct addrinfo **res) {
279 struct addrinfo *ans = NULL;
280 struct sockaddr_in *saddr = NULL;
281 const char *proto_name = "tcp";
282 int socktype = SOCK_STREAM;
283 unsigned short port = 0;
284
285 if (res == NULL) {
286 return EAI_FAIL;
287 }
288
289 *res = NULL;
290
291 ans = malloc(sizeof(struct addrinfo));
292 if (ans == NULL) {
293 return EAI_MEMORY;
294 }
295
296 saddr = malloc(sizeof(struct sockaddr_in));
297 if (saddr == NULL) {
298 free(ans);
299 return EAI_MEMORY;
300 }
301
302 ans->ai_family = AF_INET;
303 ans->ai_addrlen = sizeof *saddr;
304 ans->ai_addr = (struct sockaddr *) saddr;
305 ans->ai_next = NULL;
306 memset(saddr, 0, sizeof(*saddr));
307 saddr->sin_family = AF_INET;
308
309 if (hints != NULL) {
310 struct protoent *pe = NULL;
311
312 if ((pe = getprotobynumber(hints->ai_protocol)) != NULL &&
313 pe->p_name != NULL &&
314 *pe->p_name != 0)
315 proto_name = pe->p_name;
316
317 if (hints->ai_socktype != 0) {
318 socktype = hints->ai_socktype;
319
320 } else if (strncasecmp(proto_name, "udp", 4) == 0) {
321 socktype = SOCK_DGRAM;
322 }
323 }
324
325 if (service != NULL) {
326 struct servent *se = NULL;
327
328 if ((se = getservbyname(service, proto_name)) != NULL &&
329 se->s_port > 0) {
330 port = se->s_port;
331
332 } else if ((port = (unsigned short) strtoul(service, NULL, 0)) <= 0 ||
333 port > 65535) {
334 port = 0;
335 }
336 }
337
338 if (hints != NULL &&
339 (hints->ai_flags & AI_PASSIVE) != 0)
340 saddr->sin_addr.s_addr = htonl(INADDR_ANY);
341
342 if (node != NULL) {
343 struct hostent *he = NULL;
344
345 if ((he = gethostbyname(node)) != NULL &&
346 he->h_addr_list != NULL &&
347 he->h_addr_list[0] != NULL &&
348 he->h_length > 0 &&
349 he->h_length <= (int) sizeof(saddr->sin_addr))
350 memcpy(&saddr->sin_addr, he->h_addr_list[0], he->h_length);
351 }
352
353 ans->ai_socktype = socktype;
354 saddr->sin_port = htons(port);
355 *res = ans;
356
357 return 0;
358 }
359
pr_freeaddrinfo(struct addrinfo * ai)360 void pr_freeaddrinfo(struct addrinfo *ai) {
361 if (ai == NULL) {
362 return;
363 }
364
365 if (ai->ai_addr != NULL) {
366 free(ai->ai_addr);
367 ai->ai_addr = NULL;
368 }
369
370 free(ai);
371 }
372 #endif /* HAVE_GETADDRINFO or PR_USE_GETADDRINFO */
373
374 #if !defined(HAVE_INET_NTOP)
pr_inet_ntop(int af,const void * src,char * dst,size_t len)375 const char *pr_inet_ntop(int af, const void *src, char *dst, size_t len) {
376 char *res;
377
378 if (af != AF_INET) {
379 errno = EAFNOSUPPORT;
380 return NULL;
381 }
382
383 res = inet_ntoa(*((struct in_addr *) src));
384 if (res == NULL)
385 return NULL;
386
387 memcpy(dst, res, len);
388 return dst;
389 }
390 #endif /* !HAVE_INET_NTOP */
391
392 #if !defined(HAVE_INET_PTON)
pr_inet_pton(int af,const char * src,void * dst)393 int pr_inet_pton(int af, const char *src, void *dst) {
394 unsigned long res;
395
396 if (af != AF_INET) {
397 errno = EAFNOSUPPORT;
398 return -1;
399 }
400
401 /* inet_aton(3) would be better. However, it is not ubiquitous. */
402 res = inet_addr(src);
403 if (res == INADDR_NONE ||
404 res == 0)
405 return 0;
406
407 memcpy(dst, &res, sizeof(res));
408 return 1;
409 }
410 #endif /* !HAVE_INET_PTON */
411
get_v4inaddr(const pr_netaddr_t * na)412 static void *get_v4inaddr(const pr_netaddr_t *na) {
413
414 /* This function is specifically for IPv4 clients (when gethostbyname2(2) is
415 * present) that have an IPv4-mapped IPv6 address, when performing reverse
416 * DNS checks. This function is called iff the given netaddr object is
417 * indeed an IPv4-mapped IPv6 address. IPv6 address have 128 bits in their
418 * sin6_addr field. For IPv4-mapped IPv6 addresses, the relevant 32 bits
419 * are the last of those 128 bits (or, alternatively, the last 4 bytes of
420 * those 16 bytes); hence the read of 12 bytes after the start of the
421 * sin6_addr pointer.
422 */
423
424 return (((char *) pr_netaddr_get_inaddr(na)) + 12);
425 }
426
427 /* Validate anything returned from the 'outside', since it's untrusted
428 * information.
429 */
pr_netaddr_validate_dns_str(char * buf)430 char *pr_netaddr_validate_dns_str(char *buf) {
431 char *p;
432
433 if (buf == NULL) {
434 errno = EINVAL;
435 return NULL;
436 }
437
438 /* Validate anything returned from a DNS. */
439 for (p = buf; p && *p; p++) {
440
441 /* Per RFC requirements, these are all that are valid from a DNS. */
442 if (!PR_ISALNUM(*p) &&
443 *p != '.' &&
444 *p != '-'
445 #ifdef PR_USE_IPV6
446 && *p != ':'
447 #endif /* PR_USE_IPV6 */
448 ) {
449
450 /* We set it to _ because we know that's an invalid, yet safe, option
451 * for a DNS entry.
452 */
453 *p = '_';
454 }
455 }
456
457 return buf;
458 }
459
pr_netaddr_set_reverse_dns(int enable)460 int pr_netaddr_set_reverse_dns(int enable) {
461 int old_enable = reverse_dns;
462 reverse_dns = enable;
463 return old_enable;
464 }
465
pr_netaddr_alloc(pool * p)466 pr_netaddr_t *pr_netaddr_alloc(pool *p) {
467 if (!p) {
468 errno = EINVAL;
469 return NULL;
470 }
471
472 return pcalloc(p, sizeof(pr_netaddr_t));
473 }
474
pr_netaddr_clear(pr_netaddr_t * na)475 void pr_netaddr_clear(pr_netaddr_t *na) {
476 if (!na)
477 return;
478
479 memset(na, 0, sizeof(pr_netaddr_t));
480 }
481
pr_netaddr_dup(pool * p,const pr_netaddr_t * na)482 pr_netaddr_t *pr_netaddr_dup(pool *p, const pr_netaddr_t *na) {
483 pr_netaddr_t *dup_na;
484
485 if (p == NULL ||
486 na == NULL) {
487 errno = EINVAL;
488 return NULL;
489 }
490
491 dup_na = pr_netaddr_alloc(p);
492
493 if (pr_netaddr_set_family(dup_na, pr_netaddr_get_family(na)) < 0) {
494 return NULL;
495 }
496
497 pr_netaddr_set_sockaddr(dup_na, pr_netaddr_get_sockaddr(na));
498
499 if (na->na_have_ipstr) {
500 sstrncpy(dup_na->na_ipstr, na->na_ipstr, sizeof(dup_na->na_ipstr));
501 dup_na->na_have_ipstr = 1;
502 }
503
504 if (na->na_have_dnsstr) {
505 sstrncpy(dup_na->na_dnsstr, na->na_dnsstr, sizeof(dup_na->na_dnsstr));
506 dup_na->na_have_dnsstr = 1;
507 }
508
509 return dup_na;
510 }
511
get_addr_by_ip(pool * p,const char * name,array_header ** addrs)512 static pr_netaddr_t *get_addr_by_ip(pool *p, const char *name,
513 array_header **addrs) {
514 struct sockaddr_in v4;
515 pr_netaddr_t *na = NULL;
516 int res;
517
518 #ifdef PR_USE_IPV6
519 if (use_ipv6) {
520 struct sockaddr_in6 v6;
521 memset(&v6, 0, sizeof(v6));
522 v6.sin6_family = AF_INET6;
523
524 # ifdef SIN6_LEN
525 v6.sin6_len = sizeof(struct sockaddr_in6);
526 # endif /* SIN6_LEN */
527
528 res = pr_inet_pton(AF_INET6, name, &v6.sin6_addr);
529 if (res > 0) {
530 na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t));
531 pr_netaddr_set_family(na, AF_INET6);
532 pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v6);
533 if (addrs) {
534 *addrs = NULL;
535 }
536
537 pr_trace_msg(trace_channel, 7, "'%s' resolved to IPv6 address %s", name,
538 pr_netaddr_get_ipstr(na));
539
540 if (netaddr_ipcache_set(name, na) < 0) {
541 pr_trace_msg(trace_channel, 2, "error setting '%s' in cache: %s", name,
542 strerror(errno));
543 }
544
545 if (netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na) < 0) {
546 pr_trace_msg(trace_channel, 2, "error setting '%s' in cache: %s",
547 pr_netaddr_get_ipstr(na), strerror(errno));
548 }
549
550 return na;
551 }
552 }
553 #endif /* PR_USE_IPV6 */
554
555 memset(&v4, 0, sizeof(v4));
556 v4.sin_family = AF_INET;
557
558 # ifdef SIN_LEN
559 v4.sin_len = sizeof(struct sockaddr_in);
560 # endif /* SIN_LEN */
561
562 res = pr_inet_pton(AF_INET, name, &v4.sin_addr);
563 if (res > 0) {
564 na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t));
565 pr_netaddr_set_family(na, AF_INET);
566 pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v4);
567 if (addrs) {
568 *addrs = NULL;
569 }
570
571 pr_trace_msg(trace_channel, 7, "'%s' resolved to IPv4 address %s", name,
572 pr_netaddr_get_ipstr(na));
573
574 if (netaddr_ipcache_set(name, na) < 0) {
575 pr_trace_msg(trace_channel, 2, "error setting '%s' in cache: %s", name,
576 strerror(errno));
577 }
578
579 if (netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na) < 0) {
580 pr_trace_msg(trace_channel, 2, "error setting '%s' in cache: %s",
581 pr_netaddr_get_ipstr(na), strerror(errno));
582 }
583
584 return na;
585 }
586
587 return NULL;
588 }
589
get_addr_by_name(pool * p,const char * name,array_header ** addrs)590 static pr_netaddr_t *get_addr_by_name(pool *p, const char *name,
591 array_header **addrs) {
592 pr_netaddr_t *na = NULL;
593 int res, xerrno;
594 struct addrinfo hints, *info = NULL;
595
596 memset(&hints, 0, sizeof(hints));
597 hints.ai_family = AF_INET;
598 hints.ai_socktype = SOCK_STREAM;
599 hints.ai_protocol = IPPROTO_TCP;
600 info = NULL;
601
602 xerrno = errno;
603 pr_trace_msg(trace_channel, 7,
604 "attempting to resolve '%s' to IPv4 address via DNS", name);
605 errno = xerrno;
606 res = pr_getaddrinfo(name, NULL, &hints, &info);
607 if (res != 0) {
608 xerrno = errno;
609
610 if (res != EAI_SYSTEM) {
611 #ifdef PR_USE_IPV6
612 if (use_ipv6) {
613 pr_trace_msg(trace_channel, 7,
614 "unable to resolve '%s' to an IPv4 address: %s", name,
615 pr_gai_strerror(res));
616
617 memset(&hints, 0, sizeof(hints));
618 hints.ai_family = AF_INET6;
619 hints.ai_socktype = SOCK_STREAM;
620 hints.ai_protocol = IPPROTO_TCP;
621 info = NULL;
622
623 pr_trace_msg(trace_channel, 7,
624 "attempting to resolve '%s' to IPv6 address via DNS", name);
625 errno = xerrno;
626 res = pr_getaddrinfo(name, NULL, &hints, &info);
627 xerrno = errno;
628
629 if (res != 0) {
630 if (res != EAI_SYSTEM) {
631 pr_trace_msg(trace_channel, 5,
632 "unable to resolve '%s' to an IPv6 address: %s", name,
633 pr_gai_strerror(res));
634
635 if (res == EAI_NONAME) {
636 xerrno = ENOENT;
637 # if defined(EAFNOSUPPORT)
638 } else if (res == EAI_FAMILY) {
639 xerrno = EAFNOSUPPORT;
640 # endif /* EAFNOSUPPORT */
641 }
642
643 } else {
644 pr_trace_msg(trace_channel, 1,
645 "IPv6 getaddrinfo '%s' system error: [%d] %s", name,
646 xerrno, strerror(xerrno));
647 }
648 }
649
650 } else {
651 const char *errstr;
652
653 errstr = pr_gai_strerror(res);
654 pr_trace_msg(trace_channel, 1, "IPv4 getaddrinfo '%s' error: %s",
655 name, errstr);
656
657 if (res == EAI_NONAME) {
658 xerrno = ENOENT;
659 # if defined(EAFNOSUPPORT)
660 } else if (res == EAI_FAMILY) {
661 xerrno = EAFNOSUPPORT;
662 # endif /* EAFNOSUPPORT */
663 } else {
664 /* Note that this is a hack, to deal with GNU/Linux custom
665 * gai_strerror(3) values which are not exported in the <netdb.h>
666 * header by default.
667 */
668 if (strcmp(errstr, "Address family for hostname not supported") == 0) {
669 xerrno = EAFNOSUPPORT;
670 }
671 }
672 }
673 #else
674 pr_trace_msg(trace_channel, 1, "IPv4 getaddrinfo '%s' error: %s",
675 name, pr_gai_strerror(res));
676 if (res == EAI_NONAME) {
677 xerrno = ENOENT;
678 # if defined(EAFNOSUPPORT)
679 } else if (res == EAI_FAMILY) {
680 xerrno = EAFNOSUPPORT;
681 # endif /* EAFNOSUPPORT */
682 }
683 #endif /* PR_USE_IPV6 */
684
685 } else {
686 pr_trace_msg(trace_channel, 1,
687 "IPv4 getaddrinfo '%s' system error: [%d] %s", name,
688 xerrno, strerror(xerrno));
689 }
690
691 if (res != 0) {
692 errno = xerrno;
693 return NULL;
694 }
695 }
696
697 if (info != NULL) {
698 na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t));
699
700 /* Copy the first returned addr into na, as the return value. */
701 pr_netaddr_set_family(na, info->ai_family);
702 pr_netaddr_set_sockaddr(na, info->ai_addr);
703
704 pr_trace_msg(trace_channel, 7, "resolved '%s' to %s address %s", name,
705 info->ai_family == AF_INET ? "IPv4" : "IPv6",
706 pr_netaddr_get_ipstr(na));
707
708 if (netaddr_ipcache_set(name, na) < 0) {
709 pr_trace_msg(trace_channel, 2, "error setting '%s' in cache: %s", name,
710 strerror(errno));
711 }
712
713 if (netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na) < 0) {
714 pr_trace_msg(trace_channel, 2, "error setting '%s' in cache: %s",
715 pr_netaddr_get_ipstr(na), strerror(errno));
716 }
717
718 if (addrs != NULL) {
719 struct addrinfo *next_info = NULL;
720
721 /* Copy any other addrs into the list. */
722 if (*addrs == NULL) {
723 *addrs = make_array(p, 0, sizeof(pr_netaddr_t *));
724 }
725
726 next_info = info->ai_next;
727 while (next_info != NULL) {
728 pr_netaddr_t **elt;
729
730 pr_signals_handle();
731 elt = push_array(*addrs);
732
733 *elt = pcalloc(p, sizeof(pr_netaddr_t));
734 pr_netaddr_set_family(*elt, next_info->ai_family);
735 pr_netaddr_set_sockaddr(*elt, next_info->ai_addr);
736
737 pr_trace_msg(trace_channel, 7, "resolved '%s' to %s address %s", name,
738 next_info->ai_family == AF_INET ? "IPv4" : "IPv6",
739 pr_netaddr_get_ipstr(*elt));
740
741 next_info = next_info->ai_next;
742 }
743 }
744
745 pr_freeaddrinfo(info);
746 }
747
748 #ifdef PR_USE_IPV6
749 if (use_ipv6 && addrs) {
750 /* Do the call again, this time for IPv6 addresses.
751 *
752 * We make two separate getaddrinfo(3) calls, rather than one
753 * with a hint of AF_UNSPEC, because of certain bugs where the use
754 * of AF_UNSPEC does not function as advertised. (I suspect this
755 * bug was caused by proftpd's calling pattern, but as I could
756 * not track it down, and as there are reports of AF_UNSPEC not
757 * being as fast as AF_INET/AF_INET6, it just seemed easier to
758 * do it this way.)
759 */
760
761 memset(&hints, 0, sizeof(hints));
762 hints.ai_family = AF_INET6;
763 hints.ai_socktype = SOCK_STREAM;
764 hints.ai_protocol = IPPROTO_TCP;
765 info = NULL;
766
767 pr_trace_msg(trace_channel, 7,
768 "attempting to resolve '%s' to IPv6 address via DNS", name);
769 res = pr_getaddrinfo(name, NULL, &hints, &info);
770 xerrno = errno;
771
772 if (res != 0) {
773 if (res != EAI_SYSTEM) {
774 pr_trace_msg(trace_channel, 1, "IPv6 getaddrinfo '%s' error: %s",
775 name, pr_gai_strerror(res));
776
777 } else {
778 pr_trace_msg(trace_channel, 1,
779 "IPv6 getaddrinfo '%s' system error: [%d] %s", name,
780 xerrno, strerror(xerrno));
781 }
782
783 } else {
784 /* We may have already looked up an IPv6 address as the first
785 * address; we don't want to have duplicate addresses in the
786 * returned list of additional addresses.
787 */
788 if (info != NULL) {
789 struct addrinfo *next_info = NULL;
790
791 /* Copy any other addrs into the list. */
792 if (*addrs == NULL) {
793 *addrs = make_array(p, 0, sizeof(pr_netaddr_t *));
794 }
795
796 /* Note that for this subsequent IPv6 lookup, we need to treat the
797 * first struct addrinfo as an "additional" record, unlike our handling
798 * of IPv4 results. Failure to do so means we might miss some IPv6
799 * addresses; see Bug#4428.
800 */
801 next_info = info;
802 while (next_info != NULL) {
803 pr_netaddr_t **elt;
804
805 pr_signals_handle();
806 elt = push_array(*addrs);
807
808 *elt = pcalloc(p, sizeof(pr_netaddr_t));
809 pr_netaddr_set_family(*elt, next_info->ai_family);
810 pr_netaddr_set_sockaddr(*elt, next_info->ai_addr);
811
812 pr_trace_msg(trace_channel, 7, "resolved '%s' to %s address %s", name,
813 next_info->ai_family == AF_INET ? "IPv4" : "IPv6",
814 pr_netaddr_get_ipstr(*elt));
815
816 next_info = next_info->ai_next;
817 }
818
819 pr_freeaddrinfo(info);
820 }
821 }
822 }
823 #endif /* PR_USE_IPV6 */
824
825 return na;
826 }
827
get_addr_by_device(pool * p,const char * name,array_header ** addrs)828 static pr_netaddr_t *get_addr_by_device(pool *p, const char *name,
829 array_header **addrs) {
830 #ifdef HAVE_GETIFADDRS
831 struct ifaddrs *ifaddr = NULL;
832 pr_netaddr_t *na = NULL;
833 int res, xerrno;
834
835 /* Try to use the given name as a device/interface name, and see if we
836 * can suss out the IP address(es) to use based on that.
837 */
838
839 res = getifaddrs(&ifaddr);
840 if (res < 0) {
841 xerrno = errno;
842
843 pr_trace_msg(trace_channel, 1,
844 "error retrieving interfaces via getifaddrs(3): %s", strerror(xerrno));
845
846 } else {
847 struct ifaddrs *ifa;
848 int found_device = FALSE;
849
850 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
851 pr_signals_handle();
852
853 /* Watch out for null ifa_addr, as when a device does not have
854 * an associated address (e.g. due to not be initialized).
855 */
856 if (ifa->ifa_addr == NULL) {
857 continue;
858 }
859
860 /* We're only looking for addresses, not stats. */
861 if (ifa->ifa_addr->sa_family != AF_INET
862 #ifdef PR_USE_IPV6
863 && ifa->ifa_addr->sa_family != AF_INET6
864 #endif /* PR_USE_IPV6 */
865 ) {
866 continue;
867 }
868
869 if (strcmp(ifa->ifa_name, name) == 0) {
870 if (found_device == FALSE) {
871 na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t));
872
873 pr_netaddr_set_family(na, ifa->ifa_addr->sa_family);
874 pr_netaddr_set_sockaddr(na, ifa->ifa_addr);
875
876 pr_trace_msg(trace_channel, 7,
877 "resolved '%s' to interface with %s address %s", name,
878 ifa->ifa_addr->sa_family == AF_INET ? "IPv4" : "IPv6",
879 pr_netaddr_get_ipstr(na));
880
881 found_device = TRUE;
882
883 /* If the caller did not request additional addresses, then
884 * return now. Otherwise, we keep looking for the other
885 * addresses bound to this interface.
886 */
887 if (addrs == NULL) {
888 break;
889 }
890
891 } else {
892 pr_netaddr_t **elt;
893
894 /* We've already found the first match; this block happens
895 * if the caller wants all of the addresses for this interface.
896 */
897
898 *addrs = make_array(p, 0, sizeof(pr_netaddr_t *));
899 elt = push_array(*addrs);
900
901 *elt = pcalloc(p, sizeof(pr_netaddr_t));
902 pr_netaddr_set_family(*elt, ifa->ifa_addr->sa_family);
903 pr_netaddr_set_sockaddr(*elt, ifa->ifa_addr);
904
905 pr_trace_msg(trace_channel, 7,
906 "resolved '%s' to interface with %s address %s", name,
907 ifa->ifa_addr->sa_family == AF_INET ? "IPv4" : "IPv6",
908 pr_netaddr_get_ipstr(*elt));
909 }
910 }
911 }
912
913 if (ifaddr != NULL) {
914 freeifaddrs(ifaddr);
915 }
916
917 if (found_device) {
918 return na;
919 }
920 }
921
922 errno = ENOENT;
923 #else
924 errno = ENOSYS;
925 #endif /* HAVE_GETIFADDRS */
926
927 return NULL;
928 }
929
pr_netaddr_get_addr2(pool * p,const char * name,array_header ** addrs,unsigned int flags)930 const pr_netaddr_t *pr_netaddr_get_addr2(pool *p, const char *name,
931 array_header **addrs, unsigned int flags) {
932 pr_netaddr_t *na = NULL;
933 int xerrno = ENOENT;
934
935 if (p == NULL ||
936 name == NULL) {
937 errno = EINVAL;
938 return NULL;
939 }
940
941 pr_trace_msg(trace_channel, 10, "resolving name '%s' to IP address",
942 name);
943
944 /* First, check our cache to see if this name has already been
945 * resolved. We only want to use the cache, though, if the caller did not
946 * provide the `addrs' pointer, indicating that the caller wants to know
947 * about any additional addresses for the given name. The netaddr cache
948 * is a simple cache, hidden from callers, and thus is unable to populate
949 * that `addrs' pointer if the name is in the cache.
950 */
951 if (addrs == NULL) {
952 na = netaddr_ipcache_get(p, name);
953 if (na) {
954 return na;
955 }
956 }
957
958 /* Attempt to translate the given name into a pr_netaddr_t using
959 * pr_inet_pton() first.
960 *
961 * First, if IPv6 support is enabled, we try to translate the name using
962 * pr_inet_pton(AF_INET6) on the hopes that the given string is a valid
963 * representation of an IPv6 address. If that fails, or if IPv6 support
964 * is not enabled, we try with pr_inet_pton(AF_INET). If that fails, we
965 * assume that the given name is a DNS name, and we call pr_getaddrinfo().
966 */
967
968 na = get_addr_by_ip(p, name, addrs);
969 xerrno = errno;
970
971 if (na != NULL) {
972 return na;
973 }
974
975 /* If get_addr_by_ip() returns NULL, it means that name does not represent a
976 * valid network address in the specified address family. Usually,
977 * this means that name is actually a DNS name, not an IP address
978 * string. So we treat it as a DNS name, and use getaddrinfo(3) to
979 * resolve that name to its IP address(es) -- unless the EXCL_DNS flag
980 * has been used, indicating that the caller does not want us resolving
981 * DNS names.
982 */
983
984 if (!(flags & PR_NETADDR_GET_ADDR_FL_EXCL_DNS)) {
985 na = get_addr_by_name(p, name, addrs);
986 xerrno = errno;
987
988 if (na != NULL) {
989 return na;
990 }
991 }
992
993 if (flags & PR_NETADDR_GET_ADDR_FL_INCL_DEVICE) {
994 na = get_addr_by_device(p, name, addrs);
995 xerrno = errno;
996
997 if (na != NULL) {
998 return na;
999 }
1000 }
1001
1002 pr_trace_msg(trace_channel, 8, "failed to resolve '%s' to an IP address",
1003 name);
1004 errno = xerrno;
1005 return NULL;
1006 }
1007
pr_netaddr_get_addr(pool * p,const char * name,array_header ** addrs)1008 const pr_netaddr_t *pr_netaddr_get_addr(pool *p, const char *name,
1009 array_header **addrs) {
1010 return pr_netaddr_get_addr2(p, name, addrs, 0);
1011 }
1012
pr_netaddr_get_family(const pr_netaddr_t * na)1013 int pr_netaddr_get_family(const pr_netaddr_t *na) {
1014 if (na == NULL) {
1015 errno = EINVAL;
1016 return -1;
1017 }
1018
1019 return na->na_family;
1020 }
1021
pr_netaddr_set_family(pr_netaddr_t * na,int family)1022 int pr_netaddr_set_family(pr_netaddr_t *na, int family) {
1023 if (!na) {
1024 errno = EINVAL;
1025 return -1;
1026 }
1027
1028 /* Set the family member of the appropriate sockaddr struct. */
1029 switch (family) {
1030 case AF_INET:
1031 na->na_addr.v4.sin_family = AF_INET;
1032 break;
1033
1034 #ifdef PR_USE_IPV6
1035 case AF_INET6:
1036 if (use_ipv6) {
1037 na->na_addr.v6.sin6_family = AF_INET6;
1038 break;
1039 }
1040 #endif /* PR_USE_IPV6 */
1041
1042 default:
1043 #ifdef EAFNOSUPPORT
1044 errno = EAFNOSUPPORT;
1045 #else
1046 errno = EINVAL;
1047 #endif
1048 return -1;
1049 }
1050
1051 na->na_family = family;
1052 return 0;
1053 }
1054
pr_netaddr_get_sockaddr_len(const pr_netaddr_t * na)1055 size_t pr_netaddr_get_sockaddr_len(const pr_netaddr_t *na) {
1056 if (na == NULL) {
1057 errno = EINVAL;
1058 return -1;
1059 }
1060
1061 switch (pr_netaddr_get_family(na)) {
1062 case AF_INET:
1063 return sizeof(struct sockaddr_in);
1064
1065 #ifdef PR_USE_IPV6
1066 case AF_INET6:
1067 if (use_ipv6)
1068 return sizeof(struct sockaddr_in6);
1069 #endif /* PR_USE_IPV6 */
1070 }
1071
1072 errno = EPERM;
1073 return -1;
1074 }
1075
pr_netaddr_get_inaddr_len(const pr_netaddr_t * na)1076 size_t pr_netaddr_get_inaddr_len(const pr_netaddr_t *na) {
1077 if (na == NULL) {
1078 errno = EINVAL;
1079 return -1;
1080 }
1081
1082 switch (pr_netaddr_get_family(na)) {
1083 case AF_INET:
1084 return sizeof(struct in_addr);
1085
1086 #ifdef PR_USE_IPV6
1087 case AF_INET6:
1088 return sizeof(struct in6_addr);
1089 #endif /* PR_USE_IPV6 */
1090 }
1091
1092 errno = EPERM;
1093 return -1;
1094 }
1095
pr_netaddr_get_sockaddr(const pr_netaddr_t * na)1096 struct sockaddr *pr_netaddr_get_sockaddr(const pr_netaddr_t *na) {
1097 if (na == NULL) {
1098 errno = EINVAL;
1099 return NULL;
1100 }
1101
1102 switch (pr_netaddr_get_family(na)) {
1103 case AF_INET:
1104 return (struct sockaddr *) &na->na_addr.v4;
1105
1106 #ifdef PR_USE_IPV6
1107 case AF_INET6:
1108 if (use_ipv6)
1109 return (struct sockaddr *) &na->na_addr.v6;
1110 #endif /* PR_USE_IPV6 */
1111 }
1112
1113 errno = EPERM;
1114 return NULL;
1115 }
1116
pr_netaddr_set_sockaddr(pr_netaddr_t * na,struct sockaddr * addr)1117 int pr_netaddr_set_sockaddr(pr_netaddr_t *na, struct sockaddr *addr) {
1118 if (na == NULL ||
1119 addr == NULL) {
1120 errno = EINVAL;
1121 return -1;
1122 }
1123
1124 memset(&na->na_addr, 0, sizeof(na->na_addr));
1125 switch (na->na_family) {
1126 case AF_INET:
1127 memcpy(&(na->na_addr.v4), addr, sizeof(struct sockaddr_in));
1128 return 0;
1129
1130 #ifdef PR_USE_IPV6
1131 case AF_INET6:
1132 if (use_ipv6) {
1133 memcpy(&(na->na_addr.v6), addr, sizeof(struct sockaddr_in6));
1134 return 0;
1135 }
1136 #endif /* PR_USE_IPV6 */
1137 }
1138
1139 errno = EPERM;
1140 return -1;
1141 }
1142
pr_netaddr_set_sockaddr_any(pr_netaddr_t * na)1143 int pr_netaddr_set_sockaddr_any(pr_netaddr_t *na) {
1144 if (na == NULL) {
1145 errno = EINVAL;
1146 return -1;
1147 }
1148
1149 switch (pr_netaddr_get_family(na)) {
1150 case AF_INET: {
1151 struct in_addr in4addr_any;
1152 in4addr_any.s_addr = htonl(INADDR_ANY);
1153 na->na_addr.v4.sin_family = AF_INET;
1154 #ifdef SIN_LEN
1155 na->na_addr.v4.sin_len = sizeof(struct sockaddr_in);
1156 #endif /* SIN_LEN */
1157 memcpy(&na->na_addr.v4.sin_addr, &in4addr_any, sizeof(struct in_addr));
1158 return 0;
1159 }
1160
1161 #ifdef PR_USE_IPV6
1162 case AF_INET6:
1163 if (use_ipv6) {
1164 na->na_addr.v6.sin6_family = AF_INET6;
1165 #ifdef SIN6_LEN
1166 na->na_addr.v6.sin6_len = sizeof(struct sockaddr_in6);
1167 #endif /* SIN6_LEN */
1168 memcpy(&na->na_addr.v6.sin6_addr, &in6addr_any, sizeof(struct in6_addr));
1169 return 0;
1170 }
1171 #endif /* PR_USE_IPV6 */
1172 }
1173
1174 errno = EPERM;
1175 return -1;
1176 }
1177
pr_netaddr_get_inaddr(const pr_netaddr_t * na)1178 void *pr_netaddr_get_inaddr(const pr_netaddr_t *na) {
1179 if (na == NULL) {
1180 errno = EINVAL;
1181 return NULL;
1182 }
1183
1184 switch (pr_netaddr_get_family(na)) {
1185 case AF_INET:
1186 return (void *) &na->na_addr.v4.sin_addr;
1187
1188 #ifdef PR_USE_IPV6
1189 case AF_INET6:
1190 if (use_ipv6)
1191 return (void *) &na->na_addr.v6.sin6_addr;
1192 #endif /* PR_USE_IPV6 */
1193 }
1194
1195 errno = EPERM;
1196 return NULL;
1197 }
1198
pr_netaddr_get_port(const pr_netaddr_t * na)1199 unsigned int pr_netaddr_get_port(const pr_netaddr_t *na) {
1200 if (!na) {
1201 errno = EINVAL;
1202 return 0;
1203 }
1204
1205 switch (pr_netaddr_get_family(na)) {
1206 case AF_INET:
1207 return na->na_addr.v4.sin_port;
1208
1209 #ifdef PR_USE_IPV6
1210 case AF_INET6:
1211 if (use_ipv6)
1212 return na->na_addr.v6.sin6_port;
1213 #endif /* PR_USE_IPV6 */
1214 }
1215
1216 errno = EPERM;
1217 return 0;
1218 }
1219
pr_netaddr_set_port(pr_netaddr_t * na,unsigned int port)1220 int pr_netaddr_set_port(pr_netaddr_t *na, unsigned int port) {
1221 if (!na) {
1222 errno = EINVAL;
1223 return -1;
1224 }
1225
1226 switch (pr_netaddr_get_family(na)) {
1227 case AF_INET:
1228 na->na_addr.v4.sin_port = port;
1229 return 0;
1230
1231 #ifdef PR_USE_IPV6
1232 case AF_INET6:
1233 if (use_ipv6) {
1234 na->na_addr.v6.sin6_port = port;
1235 return 0;
1236 }
1237 #endif /* PR_USE_IPV6 */
1238 }
1239
1240 errno = EPERM;
1241 return -1;
1242 }
1243
pr_netaddr_set_port2(pr_netaddr_t * na,unsigned int port)1244 int pr_netaddr_set_port2(pr_netaddr_t *na, unsigned int port) {
1245 return pr_netaddr_set_port(na, htons(port));
1246 }
1247
pr_netaddr_cmp(const pr_netaddr_t * na1,const pr_netaddr_t * na2)1248 int pr_netaddr_cmp(const pr_netaddr_t *na1, const pr_netaddr_t *na2) {
1249 pool *tmp_pool = NULL;
1250 pr_netaddr_t *a, *b;
1251 int res;
1252
1253 if (na1 != NULL &&
1254 na2 == NULL) {
1255 return 1;
1256 }
1257
1258 if (na1 == NULL &&
1259 na2 != NULL) {
1260 return -1;
1261 }
1262
1263 if (na1 == NULL &&
1264 na2 == NULL) {
1265 return 0;
1266 }
1267
1268 if (pr_netaddr_get_family(na1) != pr_netaddr_get_family(na2)) {
1269
1270 /* Cannot compare addresses from different families, unless one
1271 * of the netaddrs has an AF_INET family, and the other has an
1272 * AF_INET6 family AND is an IPv4-mapped IPv6 address.
1273 */
1274
1275 if (pr_netaddr_is_v4mappedv6(na1) != TRUE &&
1276 pr_netaddr_is_v4mappedv6(na2) != TRUE) {
1277 errno = EINVAL;
1278 return -1;
1279 }
1280
1281 if (pr_netaddr_is_v4mappedv6(na1) == TRUE) {
1282 tmp_pool = make_sub_pool(permanent_pool);
1283
1284 pr_trace_msg(trace_channel, 5, "addr '%s' is an IPv4-mapped IPv6 address",
1285 pr_netaddr_get_ipstr((pr_netaddr_t *) na1));
1286
1287 /* This case means that na1 is an IPv4-mapped IPv6 address, and
1288 * na2 is an IPv4 address.
1289 */
1290 a = pr_netaddr_v6tov4(tmp_pool, na1);
1291 b = (pr_netaddr_t *) na2;
1292
1293 pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against "
1294 "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(b),
1295 pr_netaddr_get_ipstr(a));
1296
1297 } else if (pr_netaddr_is_v4mappedv6(na2) == TRUE) {
1298 tmp_pool = make_sub_pool(permanent_pool);
1299
1300 pr_trace_msg(trace_channel, 5, "addr '%s' is an IPv4-mapped IPv6 address",
1301 pr_netaddr_get_ipstr((pr_netaddr_t *) na2));
1302
1303 /* This case means that na is an IPv4 address, and na2 is an
1304 * IPv4-mapped IPv6 address.
1305 */
1306 a = (pr_netaddr_t *) na1;
1307 b = pr_netaddr_v6tov4(tmp_pool, na2);
1308
1309 pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against "
1310 "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(a),
1311 pr_netaddr_get_ipstr(b));
1312
1313 } else {
1314 a = (pr_netaddr_t *) na1;
1315 b = (pr_netaddr_t *) na2;
1316 }
1317
1318 } else {
1319 a = (pr_netaddr_t *) na1;
1320 b = (pr_netaddr_t *) na2;
1321 }
1322
1323 switch (pr_netaddr_get_family(a)) {
1324 case AF_INET:
1325 res = memcmp(&a->na_addr.v4.sin_addr, &b->na_addr.v4.sin_addr,
1326 sizeof(struct in_addr));
1327
1328 if (res != 0) {
1329 pr_trace_msg(trace_channel, 4, "addr %s does not match addr %s",
1330 pr_netaddr_get_ipstr(a), pr_netaddr_get_ipstr(b));
1331 }
1332
1333 if (tmp_pool) {
1334 destroy_pool(tmp_pool);
1335 tmp_pool = NULL;
1336 }
1337
1338 return res;
1339
1340 #ifdef PR_USE_IPV6
1341 case AF_INET6:
1342 if (use_ipv6) {
1343 res = memcmp(&a->na_addr.v6.sin6_addr, &b->na_addr.v6.sin6_addr,
1344 sizeof(struct in6_addr));
1345
1346 if (res != 0) {
1347 pr_trace_msg(trace_channel, 4, "addr %s does not match addr %s",
1348 pr_netaddr_get_ipstr(a), pr_netaddr_get_ipstr(b));
1349 }
1350
1351 if (tmp_pool) {
1352 destroy_pool(tmp_pool);
1353 tmp_pool = NULL;
1354 }
1355
1356 return res;
1357 }
1358 #endif /* PR_USE_IPV6 */
1359 }
1360
1361 if (tmp_pool)
1362 destroy_pool(tmp_pool);
1363
1364 errno = EPERM;
1365 return -1;
1366 }
1367
addr_ncmp(const unsigned char * aptr,const unsigned char * bptr,unsigned int masklen)1368 static int addr_ncmp(const unsigned char *aptr, const unsigned char *bptr,
1369 unsigned int masklen) {
1370 unsigned char nbits, nbytes;
1371 int res;
1372
1373 /* These null checks are unlikely to happen. But be prepared, eh? */
1374
1375 if (aptr != NULL &&
1376 bptr == NULL) {
1377 return 1;
1378 }
1379
1380 if (aptr == NULL &&
1381 bptr != NULL) {
1382 return -1;
1383 }
1384
1385 if (aptr == NULL &&
1386 bptr == NULL) {
1387 return 0;
1388 }
1389
1390 nbytes = masklen / 8;
1391 nbits = masklen % 8;
1392
1393 res = memcmp(aptr, bptr, nbytes);
1394 if (res != 0) {
1395 return -1;
1396 }
1397
1398 if (nbits > 0) {
1399 unsigned char abyte, bbyte, mask;
1400
1401 abyte = aptr[nbytes];
1402 bbyte = bptr[nbytes];
1403
1404 mask = (0xff << (8 - nbits)) & 0xff;
1405
1406 if ((abyte & mask) > (bbyte & mask)) {
1407 return 1;
1408 }
1409
1410 if ((abyte & mask) < (bbyte & mask)) {
1411 return -1;
1412 }
1413 }
1414
1415 return 0;
1416 }
1417
pr_netaddr_ncmp(const pr_netaddr_t * na1,const pr_netaddr_t * na2,unsigned int bitlen)1418 int pr_netaddr_ncmp(const pr_netaddr_t *na1, const pr_netaddr_t *na2,
1419 unsigned int bitlen) {
1420 pool *tmp_pool = NULL;
1421 pr_netaddr_t *a, *b;
1422 const unsigned char *in1, *in2;
1423 int res;
1424
1425 if (na1 != NULL &&
1426 na2 == NULL) {
1427 return 1;
1428 }
1429
1430 if (na1 == NULL &&
1431 na2 != NULL) {
1432 return -1;
1433 }
1434
1435 if (na1 == NULL &&
1436 na2 == NULL) {
1437 return 0;
1438 }
1439
1440 if (pr_netaddr_get_family(na1) != pr_netaddr_get_family(na2)) {
1441
1442 /* Cannot compare addresses from different families, unless one
1443 * of the netaddrs has an AF_INET family, and the other has an
1444 * AF_INET6 family AND is an IPv4-mapped IPv6 address.
1445 */
1446
1447 if (pr_netaddr_is_v4mappedv6(na1) != TRUE &&
1448 pr_netaddr_is_v4mappedv6(na2) != TRUE) {
1449 errno = EINVAL;
1450 return -1;
1451 }
1452
1453 if (pr_netaddr_is_v4mappedv6(na1) == TRUE) {
1454 tmp_pool = make_sub_pool(permanent_pool);
1455
1456 /* This case means that na1 is an IPv4-mapped IPv6 address, and
1457 * na2 is an IPv4 address.
1458 */
1459 a = pr_netaddr_v6tov4(tmp_pool, na1);
1460 b = (pr_netaddr_t *) na2;
1461
1462 pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against "
1463 "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(b),
1464 pr_netaddr_get_ipstr(a));
1465
1466 } else if (pr_netaddr_is_v4mappedv6(na2) == TRUE) {
1467 tmp_pool = make_sub_pool(permanent_pool);
1468
1469 /* This case means that na is an IPv4 address, and na2 is an
1470 * IPv4-mapped IPv6 address.
1471 */
1472 a = (pr_netaddr_t *) na1;
1473 b = pr_netaddr_v6tov4(tmp_pool, na2);
1474
1475 pr_trace_msg(trace_channel, 6, "comparing IPv4 address '%s' against "
1476 "IPv4-mapped IPv6 address '%s'", pr_netaddr_get_ipstr(a),
1477 pr_netaddr_get_ipstr(b));
1478
1479 } else {
1480 a = (pr_netaddr_t *) na1;
1481 b = (pr_netaddr_t *) na2;
1482 }
1483
1484 } else {
1485 a = (pr_netaddr_t *) na1;
1486 b = (pr_netaddr_t *) na2;
1487 }
1488
1489 switch (pr_netaddr_get_family(a)) {
1490 case AF_INET: {
1491 /* Make sure that the given number of bits is not more than supported
1492 * for IPv4 addresses (32).
1493 */
1494 if (bitlen > 32) {
1495 errno = EINVAL;
1496 return -1;
1497 }
1498
1499 break;
1500 }
1501
1502 #ifdef PR_USE_IPV6
1503 case AF_INET6: {
1504 if (use_ipv6) {
1505 /* Make sure that the given number of bits is not more than supported
1506 * for IPv6 addresses (128).
1507 */
1508 if (bitlen > 128) {
1509 errno = EINVAL;
1510 return -1;
1511 }
1512
1513 break;
1514 }
1515 }
1516 #endif /* PR_USE_IPV6 */
1517
1518 default:
1519 errno = EPERM;
1520 return -1;
1521 }
1522
1523 /* Retrieve pointers to the contained in_addrs. */
1524 in1 = (const unsigned char *) pr_netaddr_get_inaddr(a);
1525 in2 = (const unsigned char *) pr_netaddr_get_inaddr(b);
1526
1527 res = addr_ncmp(in1, in2, bitlen);
1528
1529 if (tmp_pool) {
1530 destroy_pool(tmp_pool);
1531 }
1532
1533 return res;
1534 }
1535
pr_netaddr_fnmatch(const pr_netaddr_t * na,const char * pattern,int flags)1536 int pr_netaddr_fnmatch(const pr_netaddr_t *na, const char *pattern, int flags) {
1537
1538 /* Note: I'm still not sure why proftpd bundles an fnmatch(3)
1539 * implementation rather than using the system library's implementation.
1540 * Needs looking into.
1541 *
1542 * The FNM_CASEFOLD flag is a GNU extension; perhaps the bundled
1543 * implementation was added to make that flag available on other platforms.
1544 */
1545 int match_flags = PR_FNM_NOESCAPE|PR_FNM_CASEFOLD;
1546
1547 if (na == NULL ||
1548 pattern == NULL) {
1549 errno = EINVAL;
1550 return -1;
1551 }
1552
1553 if (flags & PR_NETADDR_MATCH_DNS) {
1554 const char *dnsstr;
1555
1556 dnsstr = pr_netaddr_get_dnsstr(na);
1557 if (pr_fnmatch(pattern, dnsstr, match_flags) == 0) {
1558 pr_trace_msg(trace_channel, 6, "DNS name '%s' matches pattern '%s'",
1559 dnsstr, pattern);
1560 return TRUE;
1561 }
1562 }
1563
1564 if (flags & PR_NETADDR_MATCH_IP) {
1565 const char *ipstr;
1566
1567 ipstr = pr_netaddr_get_ipstr(na);
1568 if (pr_fnmatch(pattern, ipstr, match_flags) == 0) {
1569 pr_trace_msg(trace_channel, 6, "IP address '%s' matches pattern '%s'",
1570 ipstr, pattern);
1571 return TRUE;
1572 }
1573
1574 /* If the address is an IPv4-mapped IPv6 address, get the IPv4 address
1575 * and try to match that against the configured glob pattern.
1576 */
1577 if (pr_netaddr_is_v4mappedv6(na) == TRUE) {
1578 pool *tmp_pool;
1579 pr_netaddr_t *a;
1580
1581 pr_trace_msg(trace_channel, 5, "addr '%s' is an IPv4-mapped IPv6 address",
1582 ipstr);
1583
1584 tmp_pool = make_sub_pool(permanent_pool);
1585 a = pr_netaddr_v6tov4(tmp_pool, na);
1586
1587 ipstr = pr_netaddr_get_ipstr(a);
1588
1589 if (pr_fnmatch(pattern, ipstr, match_flags) == 0) {
1590 pr_trace_msg(trace_channel, 6, "IP address '%s' matches pattern '%s'",
1591 ipstr, pattern);
1592
1593 destroy_pool(tmp_pool);
1594 return TRUE;
1595 }
1596
1597 destroy_pool(tmp_pool);
1598 }
1599 }
1600
1601 pr_trace_msg(trace_channel, 4, "addr %s does not match pattern '%s'",
1602 pr_netaddr_get_ipstr(na), pattern);
1603 return FALSE;
1604 }
1605
pr_netaddr_get_ipstr(const pr_netaddr_t * na)1606 const char *pr_netaddr_get_ipstr(const pr_netaddr_t *na) {
1607 #ifdef PR_USE_IPV6
1608 char buf[INET6_ADDRSTRLEN];
1609 #else
1610 char buf[INET_ADDRSTRLEN];
1611 #endif /* PR_USE_IPV6 */
1612 int res = 0, xerrno;
1613 pr_netaddr_t *addr;
1614
1615 if (na == NULL) {
1616 errno = EINVAL;
1617 return NULL;
1618 }
1619
1620 /* If this pr_netaddr_t has already been resolved to an IP string, return the
1621 * cached string.
1622 */
1623 if (na->na_have_ipstr) {
1624 return na->na_ipstr;
1625 }
1626
1627 memset(buf, '\0', sizeof(buf));
1628 res = pr_getnameinfo(pr_netaddr_get_sockaddr(na),
1629 pr_netaddr_get_sockaddr_len(na), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
1630 xerrno = errno;
1631
1632 if (res != 0) {
1633 if (res != EAI_SYSTEM) {
1634 pr_log_pri(PR_LOG_WARNING, "getnameinfo error: %s", pr_gai_strerror(res));
1635 errno = EIO;
1636
1637 } else {
1638 pr_log_pri(PR_LOG_WARNING, "getnameinfo system error: [%d] %s",
1639 xerrno, strerror(xerrno));
1640 errno = xerrno;
1641 }
1642
1643 return NULL;
1644 }
1645
1646 #ifdef PR_USE_IPV6
1647 if (use_ipv6 &&
1648 pr_netaddr_get_family(na) == AF_INET6) {
1649 /* The getnameinfo(3) implementation might append the zone ID to an IPv6
1650 * name; we need to trim it off.
1651 */
1652 char *ptr;
1653
1654 ptr = strrchr(buf, '%');
1655 if (ptr != NULL) {
1656 *ptr = '\0';
1657 }
1658 }
1659 #endif /* PR_USE_IPV6 */
1660
1661 /* Copy the string into the pr_netaddr_t cache as well, so we only
1662 * have to do this once for this pr_netaddr_t. But to do this, we need
1663 * let the compiler know that the pr_netaddr_t is not really const at this
1664 * point.
1665 */
1666 addr = (pr_netaddr_t *) na;
1667 memset(addr->na_ipstr, '\0', sizeof(addr->na_ipstr));
1668 sstrncpy(addr->na_ipstr, buf, sizeof(addr->na_ipstr));
1669 addr->na_have_ipstr = TRUE;
1670
1671 return na->na_ipstr;
1672 }
1673
1674 #if defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME2)
netaddr_get_dnsstr_getaddrinfo(const pr_netaddr_t * na,const char * name)1675 static int netaddr_get_dnsstr_getaddrinfo(const pr_netaddr_t *na,
1676 const char *name) {
1677 struct addrinfo hints, *info = NULL;
1678 int family, flags = 0, res = 0, ok = FALSE;
1679 void *inaddr = pr_netaddr_get_inaddr(na);
1680
1681 family = pr_netaddr_get_family(na);
1682 if (pr_netaddr_is_v4mappedv6(na) == TRUE) {
1683 family = AF_INET;
1684 inaddr = get_v4inaddr(na);
1685 }
1686
1687 #ifdef AI_CANONNAME
1688 flags |= AI_CANONNAME;
1689 #endif
1690
1691 #ifdef AI_ALL
1692 flags |= AI_ALL;
1693 #endif
1694
1695 #ifdef AI_V4MAPPED
1696 flags |= AI_V4MAPPED;
1697 #endif
1698
1699 memset(&hints, 0, sizeof(hints));
1700
1701 hints.ai_family = family;
1702 hints.ai_socktype = SOCK_STREAM;
1703 hints.ai_protocol = IPPROTO_TCP;
1704 hints.ai_flags = flags;
1705
1706 res = pr_getaddrinfo(name, NULL, &hints, &info);
1707 if (res != 0) {
1708 int xerrno = errno;
1709
1710 if (res != EAI_SYSTEM) {
1711 pr_trace_msg(trace_channel, 1, "%s getaddrinfo '%s' error: %s",
1712 hints.ai_family == AF_INET ? "IPv4" : "IPv6", name,
1713 pr_gai_strerror(res));
1714
1715 } else {
1716 pr_trace_msg(trace_channel, 1,
1717 "%s getaddrinfo '%s' system error: [%d] %s",
1718 hints.ai_family == AF_INET ? "IPv4" : "IPv6", name, xerrno,
1719 strerror(xerrno));
1720 }
1721
1722 errno = xerrno;
1723 return -1;
1724 }
1725
1726 if (info != NULL) {
1727 #ifdef PR_USE_IPV6
1728 char buf[INET6_ADDRSTRLEN];
1729 #else
1730 char buf[INET_ADDRSTRLEN];
1731 #endif /* PR_USE_IPV6 */
1732 struct addrinfo *ai;
1733 int xerrno;
1734
1735 memset(buf, '\0', sizeof(buf));
1736 res = pr_getnameinfo(info->ai_addr, info->ai_addrlen, buf, sizeof(buf),
1737 NULL, 0, NI_NAMEREQD);
1738 xerrno = errno;
1739
1740 if (res != 0) {
1741 if (res != EAI_SYSTEM) {
1742 pr_trace_msg(trace_channel, 1, "%s getnameinfo error: %s",
1743 hints.ai_family == AF_INET ? "IPv4" : "IPv6", pr_gai_strerror(res));
1744
1745 } else {
1746 pr_trace_msg(trace_channel, 1,
1747 "%s getnameinfo system error: [%d] %s",
1748 hints.ai_family == AF_INET ? "IPv4" : "IPv6", xerrno,
1749 strerror(xerrno));
1750 }
1751
1752 errno = xerrno;
1753 return -1;
1754 }
1755
1756 netaddr_dnscache_set(pr_netaddr_get_ipstr(na), buf);
1757 ok = TRUE;
1758
1759 pr_trace_msg(trace_channel, 10,
1760 "checking addresses associated with host '%s'", buf);
1761
1762 for (ai = info->ai_next; ai; ai = ai->ai_next) {
1763 #ifdef PR_USE_IPV6
1764 char alias[INET6_ADDRSTRLEN];
1765 #else
1766 char alias[INET_ADDRSTRLEN];
1767 #endif /* PR_USE_IPV6 */
1768
1769 switch (ai->ai_family) {
1770 case AF_INET:
1771 if (family == AF_INET) {
1772 if (memcmp(ai->ai_addr, inaddr, ai->ai_addrlen) == 0) {
1773 memset(alias, '\0', sizeof(alias));
1774 res = pr_getnameinfo(ai->ai_addr, ai->ai_addrlen, alias,
1775 sizeof(alias), NULL, 0, NI_NAMEREQD);
1776 if (res == 0) {
1777 pr_trace_msg(trace_channel, 10,
1778 "host '%s' has alias '%s'", buf, alias);
1779 netaddr_ipcache_set(alias, na);
1780 netaddr_dnscache_set(pr_netaddr_get_ipstr(na), alias);
1781 }
1782 }
1783 }
1784 break;
1785
1786 #ifdef PR_USE_IPV6
1787 case AF_INET6:
1788 if (use_ipv6 && family == AF_INET6) {
1789 if (memcmp(ai->ai_addr, inaddr, ai->ai_addrlen) == 0) {
1790 memset(alias, '\0', sizeof(alias));
1791 res = pr_getnameinfo(ai->ai_addr, ai->ai_addrlen, alias,
1792 sizeof(alias), NULL, 0, NI_NAMEREQD);
1793 if (res == 0) {
1794 pr_trace_msg(trace_channel, 10,
1795 "host '%s' has alias '%s'", buf, alias);
1796 netaddr_ipcache_set(alias, na);
1797 netaddr_dnscache_set(pr_netaddr_get_ipstr(na), alias);
1798 }
1799 }
1800 }
1801 break;
1802 #endif /* PR_USE_IPV6 */
1803 }
1804 }
1805
1806 pr_freeaddrinfo(info);
1807 }
1808
1809 return (ok ? 0 : -1);
1810 }
1811 #endif /* HAVE_GETADDRINFO and not HAVE_GETHOSTBYNAME2 */
1812
1813 #ifdef HAVE_GETHOSTBYNAME2
netaddr_get_dnsstr_gethostbyname(const pr_netaddr_t * na,const char * name)1814 static int netaddr_get_dnsstr_gethostbyname(const pr_netaddr_t *na,
1815 const char *name) {
1816 struct hostent *hent = NULL;
1817 int family, ok = FALSE;
1818 void *inaddr;
1819
1820 family = pr_netaddr_get_family(na);
1821 if (family < 0) {
1822 return -1;
1823 }
1824
1825 inaddr = pr_netaddr_get_inaddr(na);
1826
1827 if (pr_netaddr_is_v4mappedv6(na) == TRUE) {
1828 family = AF_INET;
1829 inaddr = get_v4inaddr(na);
1830 }
1831
1832 hent = gethostbyname2(name, family);
1833
1834 if (hent != NULL) {
1835 char **checkaddr;
1836
1837 if (hent->h_name != NULL) {
1838 netaddr_dnscache_set(pr_netaddr_get_ipstr(na), hent->h_name);
1839 }
1840
1841 pr_trace_msg(trace_channel, 10,
1842 "checking addresses associated with host '%s'",
1843 hent->h_name ? hent->h_name : "(null)");
1844
1845 switch (hent->h_addrtype) {
1846 case AF_INET:
1847 if (family == AF_INET) {
1848 for (checkaddr = hent->h_addr_list; *checkaddr; ++checkaddr) {
1849 if (memcmp(*checkaddr, inaddr, hent->h_length) == 0) {
1850 char **alias;
1851
1852 for (alias = hent->h_aliases; *alias; ++alias) {
1853 if (hent->h_name) {
1854 pr_trace_msg(trace_channel, 10,
1855 "host '%s' has alias '%s'", hent->h_name, *alias);
1856 netaddr_ipcache_set(*alias, na);
1857 netaddr_dnscache_set(pr_netaddr_get_ipstr(na), *alias);
1858 }
1859 }
1860
1861 ok = TRUE;
1862 break;
1863 }
1864 }
1865 }
1866 break;
1867
1868 # ifdef PR_USE_IPV6
1869 case AF_INET6:
1870 if (use_ipv6 && family == AF_INET6) {
1871 for (checkaddr = hent->h_addr_list; *checkaddr; ++checkaddr) {
1872 if (memcmp(*checkaddr, inaddr, hent->h_length) == 0) {
1873 char **alias;
1874
1875 for (alias = hent->h_aliases; *alias; ++alias) {
1876 if (hent->h_name) {
1877 pr_trace_msg(trace_channel, 10,
1878 "host '%s' has alias '%s'", hent->h_name, *alias);
1879 netaddr_ipcache_set(*alias, na);
1880 netaddr_dnscache_set(pr_netaddr_get_ipstr(na), *alias);
1881 }
1882 }
1883
1884 ok = TRUE;
1885 break;
1886 }
1887 }
1888 }
1889 break;
1890 # endif /* PR_USE_IPV6 */
1891 }
1892
1893 } else {
1894 pr_log_debug(DEBUG1, "notice: unable to resolve '%s' as %s address: %s",
1895 name, family != AF_INET ? "IPv6" : "IPv4", hstrerror(h_errno));
1896 }
1897
1898 return (ok ? 0 : -1);
1899 }
1900 #endif /* HAVE_GETHOSTBYNAME2 */
1901
1902 /* This differs from pr_netaddr_get_ipstr() in that pr_netaddr_get_ipstr()
1903 * returns a string of the numeric form of the given network address, whereas
1904 * this function returns a string of the DNS name (if present).
1905 */
pr_netaddr_get_dnsstr(const pr_netaddr_t * na)1906 const char *pr_netaddr_get_dnsstr(const pr_netaddr_t *na) {
1907 char dns_buf[1024], *name = NULL;
1908 pr_netaddr_t *addr = NULL, *cache = NULL;
1909
1910 if (na == NULL) {
1911 errno = EINVAL;
1912 return NULL;
1913 }
1914
1915 cache = netaddr_ipcache_get(NULL, pr_netaddr_get_ipstr(na));
1916 if (cache &&
1917 cache->na_have_dnsstr) {
1918 addr = (pr_netaddr_t *) na;
1919 memset(addr->na_dnsstr, '\0', sizeof(addr->na_dnsstr));
1920 sstrncpy(addr->na_dnsstr, cache->na_dnsstr, sizeof(addr->na_dnsstr));
1921 addr->na_have_dnsstr = TRUE;
1922
1923 return na->na_dnsstr;
1924 }
1925
1926 /* If this pr_netaddr_t has already been resolved to an DNS string, return the
1927 * cached string.
1928 */
1929 if (na->na_have_dnsstr) {
1930 return na->na_dnsstr;
1931 }
1932
1933 if (reverse_dns) {
1934 int res = 0;
1935
1936 pr_trace_msg(trace_channel, 3,
1937 "verifying DNS name for IP address %s via reverse DNS lookup",
1938 pr_netaddr_get_ipstr(na));
1939
1940 memset(dns_buf, '\0', sizeof(dns_buf));
1941 res = pr_getnameinfo(pr_netaddr_get_sockaddr(na),
1942 pr_netaddr_get_sockaddr_len(na), dns_buf, sizeof(dns_buf), NULL, 0,
1943 NI_NAMEREQD);
1944 dns_buf[sizeof(dns_buf)-1] = '\0';
1945
1946 if (res == 0) {
1947 /* Some older glibc's getaddrinfo(3) does not appear to handle IPv6
1948 * addresses properly; we thus prefer gethostbyname2(3) on systems
1949 * which have it, for such older systems.
1950 */
1951 #ifdef HAVE_GETHOSTBYNAME2
1952 res = netaddr_get_dnsstr_gethostbyname(na, dns_buf);
1953 #else
1954 res = netaddr_get_dnsstr_getaddrinfo(na, dns_buf);
1955 #endif /* HAVE_GETHOSTBYNAME2 */
1956 if (res == 0) {
1957 name = dns_buf;
1958 pr_trace_msg(trace_channel, 8,
1959 "using DNS name '%s' for IP address '%s'", name,
1960 pr_netaddr_get_ipstr(na));
1961
1962 } else {
1963 name = NULL;
1964 pr_trace_msg(trace_channel, 8,
1965 "unable to verify any DNS names for IP address '%s'",
1966 pr_netaddr_get_ipstr(na));
1967 }
1968 }
1969
1970 } else {
1971 pr_log_debug(DEBUG10,
1972 "UseReverseDNS off, returning IP address instead of DNS name");
1973 }
1974
1975 if (name) {
1976 name = pr_netaddr_validate_dns_str(name);
1977
1978 } else {
1979 name = (char *) pr_netaddr_get_ipstr(na);
1980 }
1981
1982 /* Copy the string into the pr_netaddr_t cache as well, so we only
1983 * have to do this once for this pr_netaddr_t. But to do this, we need
1984 * let the compiler know that the pr_netaddr_t is not really const at this
1985 * point.
1986 */
1987 addr = (pr_netaddr_t *) na;
1988 memset(addr->na_dnsstr, '\0', sizeof(addr->na_dnsstr));
1989 sstrncpy(addr->na_dnsstr, name, sizeof(addr->na_dnsstr));
1990 addr->na_have_dnsstr = TRUE;
1991
1992 /* Update the netaddr object in the cache with the resolved DNS names. */
1993 netaddr_ipcache_set(name, na);
1994 netaddr_ipcache_set(pr_netaddr_get_ipstr(na), na);
1995
1996 return na->na_dnsstr;
1997 }
1998
pr_netaddr_get_dnsstr_list(pool * p,const pr_netaddr_t * na)1999 array_header *pr_netaddr_get_dnsstr_list(pool *p, const pr_netaddr_t *na) {
2000 array_header *res;
2001
2002 if (p == NULL ||
2003 na == NULL) {
2004 errno = EINVAL;
2005 return NULL;
2006 }
2007
2008 if (!reverse_dns) {
2009 /* If UseReverseDNS is off, then we won't have any names that we trust.
2010 * So return an empty list.
2011 */
2012 return make_array(p, 0, sizeof(char *));
2013 }
2014
2015 res = netaddr_dnscache_get(p, pr_netaddr_get_ipstr(na));
2016 if (res == NULL) {
2017 res = make_array(p, 0, sizeof(char *));
2018 }
2019
2020 return res;
2021 }
2022
2023 /* Return the hostname (wrapper for gethostname(2), except returns FQDN). */
pr_netaddr_get_localaddr_str(pool * p)2024 const char *pr_netaddr_get_localaddr_str(pool *p) {
2025 char buf[256];
2026 int res, xerrno;
2027
2028 if (p == NULL) {
2029 errno = EINVAL;
2030 return NULL;
2031 }
2032
2033 if (have_localaddr_str) {
2034 return pr_netaddr_validate_dns_str(pstrdup(p, localaddr_str));
2035 }
2036
2037 memset(buf, '\0', sizeof(buf));
2038 res = gethostname(buf, sizeof(buf)-1);
2039 xerrno = errno;
2040
2041 if (res >= 0) {
2042 struct hostent *host;
2043
2044 buf[sizeof(buf)-1] = '\0';
2045
2046 /* Note: this may need to be gethostbyname2() on systems that provide
2047 * that function, for it is possible that the configured hostname for
2048 * a machine only resolves to an IPv6 address.
2049 */
2050 #ifdef HAVE_GETHOSTBYNAME2
2051 host = gethostbyname2(buf, AF_INET);
2052 if (host == NULL &&
2053 h_errno == HOST_NOT_FOUND) {
2054 # ifdef AF_INET6
2055 host = gethostbyname2(buf, AF_INET6);
2056 # endif /* AF_INET6 */
2057 }
2058 #else
2059 host = gethostbyname(buf);
2060 #endif
2061 if (host != NULL) {
2062 return pr_netaddr_validate_dns_str(pstrdup(p, host->h_name));
2063 }
2064
2065 pr_trace_msg(trace_channel, 14,
2066 "gethostbyname() failed for '%s': %s", buf, hstrerror(h_errno));
2067 return pr_netaddr_validate_dns_str(pstrdup(p, buf));
2068 }
2069
2070 pr_trace_msg(trace_channel, 1, "gethostname(2) error: %s", strerror(xerrno));
2071 errno = xerrno;
2072 return NULL;
2073 }
2074
pr_netaddr_set_localaddr_str(const char * addr_str)2075 int pr_netaddr_set_localaddr_str(const char *addr_str) {
2076 if (addr_str == NULL) {
2077 errno = EINVAL;
2078 return -1;
2079 }
2080
2081 memset(localaddr_str, '\0', sizeof(localaddr_str));
2082 sstrncpy(localaddr_str, addr_str, sizeof(localaddr_str));
2083 have_localaddr_str = TRUE;
2084 return 0;
2085 }
2086
pr_netaddr_is_loopback(const pr_netaddr_t * na)2087 int pr_netaddr_is_loopback(const pr_netaddr_t *na) {
2088 if (na == NULL) {
2089 errno = EINVAL;
2090 return -1;
2091 }
2092
2093 switch (pr_netaddr_get_family(na)) {
2094 case AF_INET:
2095 return IN_IS_ADDR_LOOPBACK(
2096 (struct in_addr *) pr_netaddr_get_inaddr(na));
2097
2098 #ifdef PR_USE_IPV6
2099 case AF_INET6:
2100 if (pr_netaddr_is_v4mappedv6(na) == TRUE) {
2101 pool *tmp_pool;
2102 pr_netaddr_t *v4na;
2103 int res;
2104
2105 tmp_pool = make_sub_pool(permanent_pool);
2106 v4na = pr_netaddr_v6tov4(tmp_pool, na);
2107
2108 res = pr_netaddr_is_loopback(v4na);
2109 destroy_pool(tmp_pool);
2110
2111 return res;
2112 }
2113
2114 /* XXX *sigh* Different platforms implement the IN6_IS_ADDR macros
2115 * differently. For example, on Linux, those macros expect to operate
2116 * on s6_addr32, while on Solaris, the macros operate on struct in6_addr.
2117 * Certain Drafts define the macros to work on struct in6_addr *, as
2118 * Solaris does, so Linux may have it wrong. Tentative research on
2119 * Google shows some BSD netinet6/in6.h headers that define these
2120 * macros in terms of struct in6_addr *, so I'll go with that for now.
2121 * Joy. =P
2122 */
2123 # ifndef LINUX
2124 return IN6_IS_ADDR_LOOPBACK(
2125 (struct in6_addr *) pr_netaddr_get_inaddr(na));
2126 # else
2127 return IN6_IS_ADDR_LOOPBACK(
2128 ((struct in6_addr *) pr_netaddr_get_inaddr(na))->s6_addr32);
2129 # endif
2130 #endif /* PR_USE_IPV6 */
2131 }
2132
2133 return FALSE;
2134 }
2135
2136 /* RFC 1918 addresses:
2137 *
2138 * 10.0.0.0 - 10.255.255.255 (10.0.0.0/8, 24-bit block)
2139 * 172.16.0.0 - 172.31.255.255 (172.16.0.0/12, 20-bit block)
2140 * 192.168.0.0 - 192.168.255.255 (192.168.0.0/16, 16-bit block)
2141 *
2142 */
2143
is_10_xxx_addr(uint32_t addrno)2144 static int is_10_xxx_addr(uint32_t addrno) {
2145 uint32_t rfc1918_addrno;
2146
2147 rfc1918_addrno = htonl(0x0a000000);
2148 return addr_ncmp((const unsigned char *) &addrno,
2149 (const unsigned char *) &rfc1918_addrno, 8);
2150 }
2151
is_172_16_xx_addr(uint32_t addrno)2152 static int is_172_16_xx_addr(uint32_t addrno) {
2153 uint32_t rfc1918_addrno;
2154
2155 rfc1918_addrno = htonl(0xac100000);
2156 return addr_ncmp((const unsigned char *) &addrno,
2157 (const unsigned char *) &rfc1918_addrno, 12);
2158 }
2159
is_192_168_xx_addr(uint32_t addrno)2160 static int is_192_168_xx_addr(uint32_t addrno) {
2161 uint32_t rfc1918_addrno;
2162
2163 rfc1918_addrno = htonl(0xc0a80000);
2164 return addr_ncmp((const unsigned char *) &addrno,
2165 (const unsigned char *) &rfc1918_addrno, 16);
2166 }
2167
pr_netaddr_is_rfc1918(const pr_netaddr_t * na)2168 int pr_netaddr_is_rfc1918(const pr_netaddr_t *na) {
2169 if (na == NULL) {
2170 errno = EINVAL;
2171 return -1;
2172 }
2173
2174 switch (pr_netaddr_get_family(na)) {
2175 case AF_INET: {
2176 uint32_t addrno;
2177
2178 addrno = pr_netaddr_get_addrno(na);
2179 if (is_192_168_xx_addr(addrno) == 0 ||
2180 is_172_16_xx_addr(addrno) == 0 ||
2181 is_10_xxx_addr(addrno) == 0) {
2182 return TRUE;
2183 }
2184 break;
2185 }
2186
2187 #ifdef PR_USE_IPV6
2188 case AF_INET6:
2189 if (pr_netaddr_is_v4mappedv6(na) == TRUE) {
2190 pool *tmp_pool;
2191 pr_netaddr_t *v4na;
2192 int res;
2193
2194 tmp_pool = make_sub_pool(permanent_pool);
2195 v4na = pr_netaddr_v6tov4(tmp_pool, na);
2196
2197 res = pr_netaddr_is_rfc1918(v4na);
2198 destroy_pool(tmp_pool);
2199
2200 return res;
2201 }
2202
2203 /* By definition, an IPv6 address is not an RFC1918-defined address. */
2204 return FALSE;
2205 #endif /* PR_USE_IPV6 */
2206 }
2207
2208 errno = EINVAL;
2209 return FALSE;
2210 }
2211
2212 /* A slightly naughty function that should go away. It relies too much on
2213 * knowledge of the internal structures of struct in_addr, struct in6_addr.
2214 */
pr_netaddr_get_addrno(const pr_netaddr_t * na)2215 uint32_t pr_netaddr_get_addrno(const pr_netaddr_t *na) {
2216 if (na == NULL) {
2217 errno = EINVAL;
2218 return 0;
2219 }
2220
2221 switch (pr_netaddr_get_family(na)) {
2222 case AF_INET:
2223 return (uint32_t) na->na_addr.v4.sin_addr.s_addr;
2224
2225 #ifdef PR_USE_IPV6
2226 case AF_INET6: {
2227
2228 /* Linux defines s6_addr32 in its netinet/in.h header.
2229 * FreeBSD defines s6_addr32 in KAME's netinet6/in6.h header.
2230 * Solaris defines s6_addr32 in its netinet/in.h header, but only
2231 * for kernel builds.
2232 */
2233 #if 0
2234 int *addrs = ((struct sockaddr_in6 *) pr_netaddr_get_inaddr(na))->s6_addr32;
2235 return addrs[0];
2236 #else
2237 errno = ENOENT;
2238 return 0;
2239 #endif
2240 }
2241 #endif /* PR_USE_IPV6 */
2242 }
2243
2244 errno = EPERM;
2245 return 0;
2246 }
2247
pr_netaddr_is_v4(const char * name)2248 int pr_netaddr_is_v4(const char *name) {
2249 int res;
2250 struct sockaddr_in v4;
2251
2252 if (name == NULL) {
2253 errno = EINVAL;
2254 return -1;
2255 }
2256
2257 memset(&v4, 0, sizeof(v4));
2258 v4.sin_family = AF_INET;
2259
2260 # ifdef SIN_LEN
2261 v4.sin_len = sizeof(struct sockaddr_in);
2262 # endif /* SIN_LEN */
2263
2264 res = pr_inet_pton(AF_INET, name, &v4.sin_addr);
2265 if (res > 0) {
2266 return TRUE;
2267 }
2268
2269 return FALSE;
2270 }
2271
pr_netaddr_is_v6(const char * name)2272 int pr_netaddr_is_v6(const char *name) {
2273 if (name == NULL) {
2274 errno = EINVAL;
2275 return -1;
2276 }
2277
2278 #ifdef PR_USE_IPV6
2279 if (use_ipv6) {
2280 int res;
2281 struct sockaddr_in6 v6;
2282
2283 memset(&v6, 0, sizeof(v6));
2284 v6.sin6_family = AF_INET6;
2285
2286 # ifdef SIN6_LEN
2287 v6.sin6_len = sizeof(struct sockaddr_in6);
2288 # endif /* SIN6_LEN */
2289
2290 res = pr_inet_pton(AF_INET6, name, &v6.sin6_addr);
2291 if (res > 0) {
2292 return TRUE;
2293 }
2294 }
2295
2296 return FALSE;
2297 #else
2298 return FALSE;
2299 #endif /* !PR_USE_IPV6 */
2300 }
2301
pr_netaddr_is_v4mappedv6(const pr_netaddr_t * na)2302 int pr_netaddr_is_v4mappedv6(const pr_netaddr_t *na) {
2303 if (!na) {
2304 errno = EINVAL;
2305 return -1;
2306 }
2307
2308 switch (pr_netaddr_get_family(na)) {
2309 case AF_INET:
2310
2311 /* This function tests only IPv6 addresses, not IPv4 addresses. */
2312 errno = EINVAL;
2313 return -1;
2314
2315 #ifdef PR_USE_IPV6
2316 case AF_INET6: {
2317 int res;
2318
2319 if (!use_ipv6) {
2320 errno = EINVAL;
2321 return -1;
2322 }
2323
2324 # ifndef LINUX
2325 res = IN6_IS_ADDR_V4MAPPED(
2326 (struct in6_addr *) pr_netaddr_get_inaddr(na));
2327 # else
2328 res = IN6_IS_ADDR_V4MAPPED(
2329 ((struct in6_addr *) pr_netaddr_get_inaddr(na))->s6_addr32);
2330 # endif
2331
2332 if (res != TRUE) {
2333 errno = EINVAL;
2334 }
2335
2336 return res;
2337 }
2338 #endif /* PR_USE_IPV6 */
2339 }
2340
2341 errno = EPERM;
2342 return -1;
2343 }
2344
pr_netaddr_v6tov4(pool * p,const pr_netaddr_t * na)2345 pr_netaddr_t *pr_netaddr_v6tov4(pool *p, const pr_netaddr_t *na) {
2346 pr_netaddr_t *res;
2347
2348 if (p == NULL ||
2349 na == NULL) {
2350 errno = EINVAL;
2351 return NULL;
2352 }
2353
2354 if (pr_netaddr_is_v4mappedv6(na) != TRUE) {
2355 errno = EPERM;
2356 return NULL;
2357 }
2358
2359 res = pr_netaddr_alloc(p);
2360 pr_netaddr_set_family(res, AF_INET);
2361 pr_netaddr_set_port(res, pr_netaddr_get_port(na));
2362 memcpy(&res->na_addr.v4.sin_addr, get_v4inaddr(na), sizeof(struct in_addr));
2363
2364 return res;
2365 }
2366
pr_netaddr_v4tov6(pool * p,const pr_netaddr_t * na)2367 pr_netaddr_t *pr_netaddr_v4tov6(pool *p, const pr_netaddr_t *na) {
2368 pr_netaddr_t *res;
2369
2370 if (p == NULL ||
2371 na == NULL) {
2372 errno = EINVAL;
2373 return NULL;
2374 }
2375
2376 if (pr_netaddr_get_family(na) != AF_INET) {
2377 errno = EPERM;
2378 return NULL;
2379 }
2380
2381 #ifdef PR_USE_IPV6
2382 res = (pr_netaddr_t *) pr_netaddr_get_addr(p,
2383 pstrcat(p, "::ffff:", pr_netaddr_get_ipstr(na), NULL), NULL);
2384 if (res != NULL) {
2385 pr_netaddr_set_port(res, pr_netaddr_get_port(na));
2386 }
2387
2388 #else
2389 errno = EPERM;
2390 res = NULL;
2391 #endif /* PR_USE_IPV6 */
2392
2393 return res;
2394 }
2395
pr_netaddr_get_sess_local_addr(void)2396 const pr_netaddr_t *pr_netaddr_get_sess_local_addr(void) {
2397 if (have_sess_local_addr) {
2398 return &sess_local_addr;
2399 }
2400
2401 errno = ENOENT;
2402 return NULL;
2403 }
2404
pr_netaddr_get_sess_remote_addr(void)2405 const pr_netaddr_t *pr_netaddr_get_sess_remote_addr(void) {
2406 if (have_sess_remote_addr) {
2407 return &sess_remote_addr;
2408 }
2409
2410 errno = ENOENT;
2411 return NULL;
2412 }
2413
pr_netaddr_get_sess_remote_name(void)2414 const char *pr_netaddr_get_sess_remote_name(void) {
2415 if (have_sess_remote_addr) {
2416 return sess_remote_name;
2417 }
2418
2419 errno = ENOENT;
2420 return NULL;
2421 }
2422
pr_netaddr_set_sess_addrs(void)2423 void pr_netaddr_set_sess_addrs(void) {
2424 memset(&sess_local_addr, 0, sizeof(sess_local_addr));
2425 pr_netaddr_set_family(&sess_local_addr,
2426 pr_netaddr_get_family(session.c->local_addr));
2427 pr_netaddr_set_sockaddr(&sess_local_addr,
2428 pr_netaddr_get_sockaddr(session.c->local_addr));
2429 have_sess_local_addr = TRUE;
2430
2431 memset(&sess_remote_addr, 0, sizeof(sess_remote_addr));
2432 pr_netaddr_set_family(&sess_remote_addr,
2433 pr_netaddr_get_family(session.c->remote_addr));
2434 pr_netaddr_set_sockaddr(&sess_remote_addr,
2435 pr_netaddr_get_sockaddr(session.c->remote_addr));
2436
2437 memset(sess_remote_name, '\0', sizeof(sess_remote_name));
2438 sstrncpy(sess_remote_name, session.c->remote_name, sizeof(sess_remote_name));
2439 have_sess_remote_addr = TRUE;
2440 }
2441
pr_netaddr_use_ipv6(void)2442 unsigned char pr_netaddr_use_ipv6(void) {
2443 if (use_ipv6)
2444 return TRUE;
2445
2446 return FALSE;
2447 }
2448
pr_netaddr_disable_ipv6(void)2449 void pr_netaddr_disable_ipv6(void) {
2450 #ifdef PR_USE_IPV6
2451 use_ipv6 = 0;
2452 #endif /* PR_USE_IPV6 */
2453 }
2454
pr_netaddr_enable_ipv6(void)2455 void pr_netaddr_enable_ipv6(void) {
2456 #ifdef PR_USE_IPV6
2457 use_ipv6 = 1;
2458 #endif /* PR_USE_IPV6 */
2459 }
2460
pr_netaddr_clear_cache(void)2461 void pr_netaddr_clear_cache(void) {
2462 if (netaddr_iptab) {
2463 pr_trace_msg(trace_channel, 5, "emptying netaddr IP cache");
2464 (void) pr_table_empty(netaddr_iptab);
2465 (void) pr_table_free(netaddr_iptab);
2466
2467 /* Allocate a fresh table. */
2468 netaddr_iptab = pr_table_alloc(netaddr_pool, 0);
2469 }
2470
2471 if (netaddr_dnstab) {
2472 pr_trace_msg(trace_channel, 5, "emptying netaddr DNS cache");
2473 (void) pr_table_empty(netaddr_dnstab);
2474 (void) pr_table_free(netaddr_dnstab);
2475
2476 /* Allocate a fresh table. */
2477 netaddr_dnstab = pr_table_alloc(netaddr_pool, 0);
2478 }
2479 }
2480
pr_netaddr_clear_dnscache(const char * ip_str)2481 void pr_netaddr_clear_dnscache(const char *ip_str) {
2482 if (netaddr_dnstab != NULL) {
2483 (void) pr_table_remove(netaddr_dnstab, ip_str, NULL);
2484 }
2485 }
2486
pr_netaddr_clear_ipcache(const char * name)2487 void pr_netaddr_clear_ipcache(const char *name) {
2488 if (netaddr_iptab != NULL) {
2489 (void) pr_table_remove(netaddr_iptab, name, NULL);
2490 }
2491 }
2492
init_netaddr(void)2493 void init_netaddr(void) {
2494 if (netaddr_pool) {
2495 pr_netaddr_clear_cache();
2496 destroy_pool(netaddr_pool);
2497 netaddr_pool = NULL;
2498 }
2499
2500 netaddr_pool = make_sub_pool(permanent_pool);
2501 pr_pool_tag(netaddr_pool, "Netaddr API");
2502
2503 netaddr_iptab = pr_table_alloc(netaddr_pool, 0);
2504 netaddr_dnstab = pr_table_alloc(netaddr_pool, 0);
2505 }
2506