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