1 /*
2 * misc.c Various miscellaneous functions.
3 *
4 * Version: $Id: 9dbb73a5992d36cd7e931304460484bc75e0cc70 $
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 * Copyright 2000,2006 The FreeRADIUS server project
21 */
22
23 RCSID("$Id: 9dbb73a5992d36cd7e931304460484bc75e0cc70 $")
24
25 #include <freeradius-devel/libradius.h>
26
27 #include <ctype.h>
28 #include <sys/file.h>
29 #include <fcntl.h>
30 #include <grp.h>
31 #include <pwd.h>
32 #include <sys/uio.h>
33
34 #ifdef HAVE_DIRENT_H
35 #include <dirent.h>
36
37 /*
38 * Some versions of Linux don't have closefrom(), but they will
39 * have /proc.
40 *
41 * BSD systems will generally have closefrom(), but not proc.
42 *
43 * OSX doesn't have closefrom() or /proc/self/fd, but it does
44 * have /dev/fd
45 */
46 #ifdef __linux__
47 #define CLOSEFROM_DIR "/proc/self/fd"
48 #elif defined(__APPLE__)
49 #define CLOSEFROM_DIR "/dev/fd"
50 #else
51 #undef HAVE_DIRENT_H
52 #endif
53
54 #endif
55
56 #define FR_PUT_LE16(a, val)\
57 do {\
58 a[1] = ((uint16_t) (val)) >> 8;\
59 a[0] = ((uint16_t) (val)) & 0xff;\
60 } while (0)
61
62 bool fr_dns_lookups = false; /* IP -> hostname lookups? */
63 bool fr_hostname_lookups = true; /* hostname -> IP lookups? */
64 int fr_debug_lvl = 0;
65
66 static char const *months[] = {
67 "jan", "feb", "mar", "apr", "may", "jun",
68 "jul", "aug", "sep", "oct", "nov", "dec" };
69
70 fr_thread_local_setup(char *, fr_inet_ntop_buffer) /* macro */
71
72 typedef struct fr_talloc_link {
73 bool armed;
74 TALLOC_CTX *child;
75 } fr_talloc_link_t;
76
77 /** Sets a signal handler using sigaction if available, else signal
78 *
79 * @param sig to set handler for.
80 * @param func handler to set.
81 */
82 DIAG_OPTIONAL
83 DIAG_OFF(disabled-macro-expansion)
fr_set_signal(int sig,sig_t func)84 int fr_set_signal(int sig, sig_t func)
85 {
86 #ifdef HAVE_SIGACTION
87 struct sigaction act;
88
89 memset(&act, 0, sizeof(act));
90 act.sa_flags = 0;
91 sigemptyset(&act.sa_mask);
92 act.sa_handler = func;
93
94 if (sigaction(sig, &act, NULL) < 0) {
95 fr_strerror_printf("Failed setting signal %i handler via sigaction(): %s", sig, fr_syserror(errno));
96 return -1;
97 }
98 #else
99 if (signal(sig, func) < 0) {
100 fr_strerror_printf("Failed setting signal %i handler via signal(): %s", sig, fr_syserror(errno));
101 return -1;
102 }
103 #endif
104 return 0;
105 }
106 DIAG_ON(disabled-macro-expansion)
107
108 /** Uninstall a signal for a specific handler
109 *
110 * man sigaction says these are fine to call from a signal handler.
111 *
112 * @param sig SIGNAL
113 */
114 DIAG_OPTIONAL
115 DIAG_OFF(disabled-macro-expansion)
fr_unset_signal(int sig)116 int fr_unset_signal(int sig)
117 {
118 #ifdef HAVE_SIGACTION
119 struct sigaction act;
120
121 memset(&act, 0, sizeof(act));
122 act.sa_flags = 0;
123 sigemptyset(&act.sa_mask);
124 act.sa_handler = SIG_DFL;
125
126 return sigaction(sig, &act, NULL);
127 #else
128 return signal(sig, SIG_DFL);
129 #endif
130 }
131 DIAG_ON(disabled-macro-expansion)
132
_fr_trigger_talloc_ctx_free(fr_talloc_link_t * trigger)133 static int _fr_trigger_talloc_ctx_free(fr_talloc_link_t *trigger)
134 {
135 if (trigger->armed) talloc_free(trigger->child);
136
137 return 0;
138 }
139
_fr_disarm_talloc_ctx_free(bool ** armed)140 static int _fr_disarm_talloc_ctx_free(bool **armed)
141 {
142 **armed = false;
143 return 0;
144 }
145
146 /** Link a parent and a child context, so the child is freed before the parent
147 *
148 * @note This is not thread safe. Do not free parent before threads are joined, do not call from a child thread.
149 * @note It's OK to free the child before threads are joined, but this will leak memory until the parent is freed.
150 *
151 * @param parent who's fate the child should share.
152 * @param child bound to parent's lifecycle.
153 * @return 0 on success -1 on failure.
154 */
fr_link_talloc_ctx_free(TALLOC_CTX * parent,TALLOC_CTX * child)155 int fr_link_talloc_ctx_free(TALLOC_CTX *parent, TALLOC_CTX *child)
156 {
157 fr_talloc_link_t *trigger;
158 bool **disarm;
159
160 trigger = talloc(parent, fr_talloc_link_t);
161 if (!trigger) return -1;
162
163 disarm = talloc(child, bool *);
164 if (!disarm) {
165 talloc_free(trigger);
166 return -1;
167 }
168
169 trigger->child = child;
170 trigger->armed = true;
171 *disarm = &trigger->armed;
172
173 talloc_set_destructor(trigger, _fr_trigger_talloc_ctx_free);
174 talloc_set_destructor(disarm, _fr_disarm_talloc_ctx_free);
175
176 return 0;
177 }
178
179 /*
180 * Explicitly cleanup the memory allocated to the error inet_ntop
181 * buffer.
182 */
_fr_inet_ntop_free(void * arg)183 static void _fr_inet_ntop_free(void *arg)
184 {
185 free(arg);
186 }
187
188 /** Wrapper around inet_ntop, prints IPv4/IPv6 addresses
189 *
190 * inet_ntop requires the caller pass in a buffer for the address.
191 * This would be annoying and cumbersome, seeing as quite often the ASCII
192 * address is only used for logging output.
193 *
194 * So as with lib/log.c use TLS to allocate thread specific buffers, and
195 * write the IP address there instead.
196 *
197 * @param af address family, either AF_INET or AF_INET6.
198 * @param src pointer to network address structure.
199 * @return NULL on error, else pointer to ASCII buffer containing text version of address.
200 */
fr_inet_ntop(int af,void const * src)201 char const *fr_inet_ntop(int af, void const *src)
202 {
203 char *buffer;
204
205 if (!src) {
206 return NULL;
207 }
208
209 buffer = fr_thread_local_init(fr_inet_ntop_buffer, _fr_inet_ntop_free);
210 if (!buffer) {
211 int ret;
212
213 /*
214 * malloc is thread safe, talloc is not
215 */
216 buffer = malloc(sizeof(char) * INET6_ADDRSTRLEN);
217 if (!buffer) {
218 fr_perror("Failed allocating memory for inet_ntop buffer");
219 return NULL;
220 }
221
222 ret = fr_thread_local_set(fr_inet_ntop_buffer, buffer);
223 if (ret != 0) {
224 fr_perror("Failed setting up TLS for inet_ntop buffer: %s", fr_syserror(ret));
225 free(buffer);
226 return NULL;
227 }
228 }
229 buffer[0] = '\0';
230
231 return inet_ntop(af, src, buffer, INET6_ADDRSTRLEN);
232 }
233
234 /*
235 * Return an IP address in standard dot notation
236 *
237 * FIXME: DELETE THIS
238 */
ip_ntoa(char * buffer,uint32_t ipaddr)239 char const *ip_ntoa(char *buffer, uint32_t ipaddr)
240 {
241 ipaddr = ntohl(ipaddr);
242
243 sprintf(buffer, "%d.%d.%d.%d",
244 (ipaddr >> 24) & 0xff,
245 (ipaddr >> 16) & 0xff,
246 (ipaddr >> 8) & 0xff,
247 (ipaddr ) & 0xff);
248 return buffer;
249 }
250
251 /*
252 * Parse decimal digits until we run out of decimal digits.
253 */
ip_octet_from_str(char const * str,uint32_t * poctet)254 static int ip_octet_from_str(char const *str, uint32_t *poctet)
255 {
256 uint32_t octet;
257 char const *p = str;
258
259 if ((*p < '0') || (*p > '9')) {
260 return -1;
261 }
262
263 octet = 0;
264
265 while ((*p >= '0') && (*p <= '9')) {
266 octet *= 10;
267 octet += *p - '0';
268 p++;
269
270 if (octet > 255) return -1;
271 }
272
273
274 *poctet = octet;
275 return p - str;
276 }
277
ip_prefix_from_str(char const * str,uint32_t * paddr)278 static int ip_prefix_from_str(char const *str, uint32_t *paddr)
279 {
280 int shift, length;
281 uint32_t octet;
282 uint32_t addr;
283 char const *p = str;
284
285 addr = 0;
286
287 for (shift = 24; shift >= 0; shift -= 8) {
288 length = ip_octet_from_str(p, &octet);
289 if (length <= 0) return -1;
290
291 addr |= octet << shift;
292 p += length;
293
294 /*
295 * EOS or / means we're done.
296 */
297 if (!*p || (*p == '/')) break;
298
299 /*
300 * We require dots between octets.
301 */
302 if (*p != '.') return -1;
303 p++;
304 }
305
306 *paddr = htonl(addr);
307 return p - str;
308 }
309
310
311 /**
312 * Parse an IPv4 address, IPv4 prefix in presentation format (and others), or
313 * a hostname.
314 *
315 * @param out Where to write the ip address value.
316 * @param value to parse, may be dotted quad [+ prefix], or integer, or octal number, or '*' (INADDR_ANY), or a hostname.
317 * @param inlen Length of value, if value is \0 terminated inlen may be -1.
318 * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
319 * @param fallback to IPv6 resolution if no A records can be found.
320 * @return 0 if ip address was parsed successfully, else -1 on error.
321 */
fr_pton4(fr_ipaddr_t * out,char const * value,ssize_t inlen,bool resolve,bool fallback)322 int fr_pton4(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, bool fallback)
323 {
324 char *p;
325 unsigned int mask;
326 char *eptr;
327
328 /* Dotted quad + / + [0-9]{1,2} or a hostname (RFC1035 2.3.4 Size limits) */
329 char buffer[256];
330
331 /*
332 * Copy to intermediary buffer if we were given a length
333 */
334 if (inlen >= 0) {
335 if (inlen >= (ssize_t)sizeof(buffer)) {
336 fr_strerror_printf("Invalid IPv4 address string \"%s\"", value);
337 return -1;
338 }
339 memcpy(buffer, value, inlen);
340 buffer[inlen] = '\0';
341 value = buffer;
342 }
343
344 p = strchr(value, '/');
345
346 /*
347 * 192.0.2.2 is parsed as if it was /32
348 */
349 if (!p) {
350 out->prefix = 32;
351 out->af = AF_INET;
352
353 /*
354 * Allow '*' as the wildcard address usually 0.0.0.0
355 */
356 if ((value[0] == '*') && (value[1] == '\0')) {
357 out->ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
358
359 /*
360 * Convert things which are obviously integers to IP addresses
361 *
362 * We assume the number is the bigendian representation of the
363 * IP address.
364 */
365 } else if (is_integer(value) || ((value[0] == '0') && (value[1] == 'x'))) {
366 out->ipaddr.ip4addr.s_addr = htonl(strtoul(value, NULL, 0));
367
368 } else if (!resolve) {
369 if (inet_pton(AF_INET, value, &out->ipaddr.ip4addr.s_addr) <= 0) {
370 fr_strerror_printf("Failed to parse IPv4 addreess string \"%s\"", value);
371 return -1;
372 }
373 } else if (ip_hton(out, AF_INET, value, fallback) < 0) return -1;
374
375 return 0;
376 }
377
378 /*
379 * Copy the IP portion into a temporary buffer if we haven't already.
380 */
381 if (inlen < 0) memcpy(buffer, value, p - value);
382 buffer[p - value] = '\0';
383
384 if (ip_prefix_from_str(buffer, &out->ipaddr.ip4addr.s_addr) <= 0) {
385 fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
386 return -1;
387 }
388
389 mask = strtoul(p + 1, &eptr, 10);
390 if (mask > 32) {
391 fr_strerror_printf("Invalid IPv4 mask length \"%s\". Should be between 0-32", p);
392 return -1;
393 }
394
395 if (eptr[0] != '\0') {
396 fr_strerror_printf("Failed to parse IPv4 address string \"%s\", "
397 "got garbage after mask length \"%s\"", value, eptr);
398 return -1;
399 }
400
401 if (mask < 32) {
402 out->ipaddr.ip4addr = fr_inaddr_mask(&out->ipaddr.ip4addr, mask);
403 }
404
405 out->prefix = (uint8_t) mask;
406 out->af = AF_INET;
407
408 return 0;
409 }
410
411 /**
412 * Parse an IPv6 address or IPv6 prefix in presentation format (and others),
413 * or a hostname.
414 *
415 * @param out Where to write the ip address value.
416 * @param value to parse.
417 * @param inlen Length of value, if value is \0 terminated inlen may be -1.
418 * @param resolve If true and value doesn't look like an IP address, try and resolve value as a hostname.
419 * @param fallback to IPv4 resolution if no AAAA records can be found.
420 * @return 0 if ip address was parsed successfully, else -1 on error.
421 */
fr_pton6(fr_ipaddr_t * out,char const * value,ssize_t inlen,bool resolve,bool fallback)422 int fr_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, bool fallback)
423 {
424 char const *p;
425 unsigned int prefix;
426 char *eptr;
427
428 /* IPv6 + / + [0-9]{1,3} or a hostname (RFC1035 2.3.4 Size limits) */
429 char buffer[256];
430
431 /*
432 * Copy to intermediary buffer if we were given a length
433 */
434 if (inlen >= 0) {
435 if (inlen >= (ssize_t)sizeof(buffer)) {
436 fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
437 return -1;
438 }
439 memcpy(buffer, value, inlen);
440 buffer[inlen] = '\0';
441 value = buffer;
442 }
443
444 p = strchr(value, '/');
445 if (!p) {
446 out->prefix = 128;
447 out->af = AF_INET6;
448
449 /*
450 * Allow '*' as the wildcard address
451 */
452 if ((value[0] == '*') && (value[1] == '\0')) {
453 memset(out->ipaddr.ip6addr.s6_addr, 0, sizeof(out->ipaddr.ip6addr.s6_addr));
454 } else if (!resolve) {
455 if (inet_pton(AF_INET6, value, out->ipaddr.ip6addr.s6_addr) <= 0) {
456 fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
457 return -1;
458 }
459 } else if (ip_hton(out, AF_INET6, value, fallback) < 0) return -1;
460
461 return 0;
462 }
463
464 if ((p - value) >= INET6_ADDRSTRLEN) {
465 fr_strerror_printf("Invalid IPv6 address string \"%s\"", value);
466 return -1;
467 }
468
469 /*
470 * Copy string to temporary buffer if we didn't do it earlier
471 */
472 if (inlen < 0) memcpy(buffer, value, p - value);
473 buffer[p - value] = '\0';
474
475 if (!resolve) {
476 if (inet_pton(AF_INET6, buffer, out->ipaddr.ip6addr.s6_addr) <= 0) {
477 fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
478 return -1;
479 }
480 } else if (ip_hton(out, AF_INET6, buffer, fallback) < 0) return -1;
481
482 prefix = strtoul(p + 1, &eptr, 10);
483 if (prefix > 128) {
484 fr_strerror_printf("Invalid IPv6 mask length \"%s\". Should be between 0-128", p);
485 return -1;
486 }
487 if (eptr[0] != '\0') {
488 fr_strerror_printf("Failed to parse IPv6 address string \"%s\", "
489 "got garbage after mask length \"%s\"", value, eptr);
490 return -1;
491 }
492
493 if (prefix < 128) {
494 struct in6_addr addr;
495
496 addr = fr_in6addr_mask(&out->ipaddr.ip6addr, prefix);
497 memcpy(out->ipaddr.ip6addr.s6_addr, addr.s6_addr, sizeof(out->ipaddr.ip6addr.s6_addr));
498 }
499
500 out->prefix = (uint8_t) prefix;
501 out->af = AF_INET6;
502
503 return 0;
504 }
505
506 /** Simple wrapper to decide whether an IP value is v4 or v6 and call the appropriate parser.
507 *
508 * @param[out] out Where to write the ip address value.
509 * @param[in] value to parse.
510 * @param[in] inlen Length of value, if value is \0 terminated inlen may be -1.
511 * @param[in] resolve If true and value doesn't look like an IP address, try and resolve value as a
512 * hostname.
513 * @param[in] af If the address type is not obvious from the format, and resolve is true, the DNS
514 * record (A or AAAA) we require. Also controls which parser we pass the address to if
515 * we have no idea what it is.
516 * @return
517 * - 0 if ip address was parsed successfully.
518 * - -1 on failure.
519 */
fr_pton(fr_ipaddr_t * out,char const * value,ssize_t inlen,int af,bool resolve)520 int fr_pton(fr_ipaddr_t *out, char const *value, ssize_t inlen, int af, bool resolve)
521 {
522 size_t len, i;
523 bool hostname = true;
524 bool ipv4 = true;
525 bool ipv6 = true;
526
527 len = (inlen >= 0) ? (size_t)inlen : strlen(value);
528
529 for (i = 0; i < len; i++) {
530 /*
531 * These are valid for IPv4, IPv6, and host names.
532 */
533 if ((value[i] >= '0') && (value[i] <= '9')) {
534 continue;
535 }
536
537 /*
538 * These are invalid for IPv4, but OK for IPv6
539 * and host names.
540 */
541 if ((value[i] >= 'a') && (value[i] <= 'f')) {
542 ipv4 = false;
543 continue;
544 }
545
546 /*
547 * These are invalid for IPv4, but OK for IPv6
548 * and host names.
549 */
550 if ((value[i] >= 'A') && (value[i] <= 'F')) {
551 ipv4 = false;
552 continue;
553 }
554
555 /*
556 * This is only valid for IPv6 addresses.
557 */
558 if (value[i] == ':') {
559 ipv4 = false;
560 hostname = false;
561 continue;
562 }
563
564 /*
565 * Valid for IPv4 and host names, not for IPv6.
566 */
567 if (value[i] == '.') {
568 ipv6 = false;
569 continue;
570 }
571
572 /*
573 * Netmasks are allowed by us, and MUST come at
574 * the end of the address.
575 */
576 if (value[i] == '/') {
577 break;
578 }
579
580 /*
581 * Any characters other than what are checked for
582 * above can't be IPv4 or IPv6 addresses.
583 */
584 ipv4 = false;
585 ipv6 = false;
586 }
587
588 /*
589 * It's not an IPv4 or IPv6 address. It MUST be a host
590 * name.
591 */
592 if (!ipv4 && !ipv6) {
593 /*
594 * Not an IPv4 or IPv6 address, and we weren't
595 * asked to do DNS resolution, we can't do it.
596 */
597 if (!resolve) {
598 fr_strerror_printf("Not IPv4/6 address, and asked not to resolve");
599 return -1;
600 }
601
602 /*
603 * It's not a hostname, either, so bail out
604 * early.
605 */
606 if (!hostname) {
607 fr_strerror_printf("Invalid address");
608 return -1;
609 }
610 }
611
612 /*
613 * The name has a ':' in it. Therefore it must be an
614 * IPv6 address. Error out if the caller specified IPv4.
615 * Otherwise, force IPv6.
616 */
617 if (ipv6 && !hostname) {
618 if (af == AF_INET) {
619 fr_strerror_printf("Invalid address");
620 return -1;
621 }
622
623 af = AF_INET6;
624 }
625
626 /*
627 * Use whatever the caller specified, OR what we
628 * insinuated above from looking at the name string.
629 */
630 switch (af) {
631 case AF_UNSPEC:
632 return fr_pton4(out, value, inlen, resolve, true);
633
634 case AF_INET:
635 return fr_pton4(out, value, inlen, resolve, false);
636
637 case AF_INET6:
638 return fr_pton6(out, value, inlen, resolve, false);
639
640 default:
641 break;
642 }
643
644 /*
645 * No idea what it is...
646 */
647 fr_strerror_printf("Invalid address family %i", af);
648 return -1;
649 }
650
651 /** Parses IPv4/6 address + port, to fr_ipaddr_t and integer
652 *
653 * @param[out] out Where to write the ip address value.
654 * @param[out] port_out Where to write the port (0 if no port found).
655 * @param[in] value to parse.
656 * @param[in] inlen Length of value, if value is \0 terminated inlen may be -1.
657 * @param[in] af If the address type is not obvious from the format, and resolve is true, the DNS
658 * record (A or AAAA) we require. Also controls which parser we pass the address to if
659 * we have no idea what it is.
660 * @param[in] resolve If true and value doesn't look like an IP address, try and resolve value as a
661 * hostname.
662 */
fr_pton_port(fr_ipaddr_t * out,uint16_t * port_out,char const * value,ssize_t inlen,int af,bool resolve)663 int fr_pton_port(fr_ipaddr_t *out, uint16_t *port_out, char const *value, ssize_t inlen, int af, bool resolve)
664 {
665 char const *p = value, *q;
666 char *end;
667 unsigned long port;
668 char buffer[6];
669 size_t len;
670
671 *port_out = 0;
672
673 len = (inlen >= 0) ? (size_t)inlen : strlen(value);
674
675 if (*p == '[') {
676 if (!(q = memchr(p + 1, ']', len - 1))) {
677 fr_strerror_printf("Missing closing ']' for IPv6 address");
678 return -1;
679 }
680
681 /*
682 * inet_pton doesn't like the address being wrapped in []
683 */
684 if (fr_pton6(out, p + 1, (q - p) - 1, false, false) < 0) return -1;
685
686 if (q[1] == ':') {
687 q++;
688 goto do_port;
689 }
690
691 return 0;
692 }
693
694 /*
695 * Host, IPv4 or IPv6 with no port
696 */
697 q = memchr(p, ':', len);
698 if (!q) return fr_pton(out, p, len, af, resolve);
699
700 /*
701 * IPv4 or host, with port
702 */
703 if (fr_pton(out, p, (q - p), af, resolve) < 0) return -1;
704
705 do_port:
706 /*
707 * Valid ports are a maximum of 5 digits, so if the
708 * input length indicates there are more than 5 chars
709 * after the ':' then there's an issue.
710 */
711 if (len > (size_t) ((q + sizeof(buffer)) - value)) {
712 error:
713 fr_strerror_printf("IP string contains trailing garbage after port delimiter");
714 return -1;
715 }
716
717 p = q + 1; /* Move to first digit */
718
719 strlcpy(buffer, p, (len - (p - value)) + 1);
720 port = strtoul(buffer, &end, 10);
721 if (*end != '\0') goto error; /* Trailing garbage after integer */
722
723 if ((port > UINT16_MAX) || (port == 0)) {
724 fr_strerror_printf("Port %lu outside valid port range 1-" STRINGIFY(UINT16_MAX), port);
725 return -1;
726 }
727 *port_out = port;
728
729 return 0;
730 }
731
fr_ntop(char * out,size_t outlen,fr_ipaddr_t const * addr)732 int fr_ntop(char *out, size_t outlen, fr_ipaddr_t const *addr)
733 {
734 char buffer[INET6_ADDRSTRLEN];
735
736 if (inet_ntop(addr->af, &(addr->ipaddr), buffer, sizeof(buffer)) == NULL) return -1;
737
738 return snprintf(out, outlen, "%s/%i", buffer, addr->prefix);
739 }
740
741 /*
742 * cppcheck apparently can't pick this up from the system headers.
743 */
744 #ifdef CPPCHECK
745 #define F_WRLCK
746 #endif
747
748 /*
749 * Internal wrapper for locking, to minimize the number of ifdef's
750 *
751 * Use fcntl or error
752 */
rad_lockfd(int fd,int lock_len)753 int rad_lockfd(int fd, int lock_len)
754 {
755 #ifdef F_WRLCK
756 struct flock fl;
757
758 fl.l_start = 0;
759 fl.l_len = lock_len;
760 fl.l_pid = getpid();
761 fl.l_type = F_WRLCK;
762 fl.l_whence = SEEK_CUR;
763
764 return fcntl(fd, F_SETLKW, (void *)&fl);
765 #else
766 #error "missing definition for F_WRLCK, all file locks will fail"
767
768 return -1;
769 #endif
770 }
771
772 /*
773 * Internal wrapper for locking, to minimize the number of ifdef's
774 *
775 * Lock an fd, prefer lockf() over flock()
776 * Nonblocking version.
777 */
rad_lockfd_nonblock(int fd,int lock_len)778 int rad_lockfd_nonblock(int fd, int lock_len)
779 {
780 #ifdef F_WRLCK
781 struct flock fl;
782
783 fl.l_start = 0;
784 fl.l_len = lock_len;
785 fl.l_pid = getpid();
786 fl.l_type = F_WRLCK;
787 fl.l_whence = SEEK_CUR;
788
789 return fcntl(fd, F_SETLK, (void *)&fl);
790 #else
791 #error "missing definition for F_WRLCK, all file locks will fail"
792
793 return -1;
794 #endif
795 }
796
797 /*
798 * Internal wrapper for unlocking, to minimize the number of ifdef's
799 * in the source.
800 *
801 * Unlock an fd, prefer lockf() over flock()
802 */
rad_unlockfd(int fd,int lock_len)803 int rad_unlockfd(int fd, int lock_len)
804 {
805 #ifdef F_WRLCK
806 struct flock fl;
807
808 fl.l_start = 0;
809 fl.l_len = lock_len;
810 fl.l_pid = getpid();
811 fl.l_type = F_UNLCK;
812 fl.l_whence = SEEK_CUR;
813
814 return fcntl(fd, F_SETLK, (void *)&fl);
815 #else
816 #error "missing definition for F_WRLCK, all file locks will fail"
817
818 return -1;
819 #endif
820 }
821
822 /*
823 * Return an interface-id in standard colon notation
824 */
ifid_ntoa(char * buffer,size_t size,uint8_t const * ifid)825 char *ifid_ntoa(char *buffer, size_t size, uint8_t const *ifid)
826 {
827 snprintf(buffer, size, "%x:%x:%x:%x",
828 (ifid[0] << 8) + ifid[1], (ifid[2] << 8) + ifid[3],
829 (ifid[4] << 8) + ifid[5], (ifid[6] << 8) + ifid[7]);
830 return buffer;
831 }
832
833
834 /*
835 * Return an interface-id from
836 * one supplied in standard colon notation.
837 */
ifid_aton(char const * ifid_str,uint8_t * ifid)838 uint8_t *ifid_aton(char const *ifid_str, uint8_t *ifid)
839 {
840 static char const xdigits[] = "0123456789abcdef";
841 char const *p, *pch;
842 int num_id = 0, val = 0, idx = 0;
843
844 for (p = ifid_str; ; ++p) {
845 if (*p == ':' || *p == '\0') {
846 if (num_id <= 0)
847 return NULL;
848
849 /*
850 * Drop 'val' into the array.
851 */
852 ifid[idx] = (val >> 8) & 0xff;
853 ifid[idx + 1] = val & 0xff;
854 if (*p == '\0') {
855 /*
856 * Must have all entries before
857 * end of the string.
858 */
859 if (idx != 6)
860 return NULL;
861 break;
862 }
863 val = 0;
864 num_id = 0;
865 if ((idx += 2) > 6)
866 return NULL;
867 } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
868 if (++num_id > 4)
869 return NULL;
870 /*
871 * Dumb version of 'scanf'
872 */
873 val <<= 4;
874 val |= (pch - xdigits);
875 } else
876 return NULL;
877 }
878 return ifid;
879 }
880
881
882 #ifndef HAVE_INET_PTON
inet_pton4(char const * src,struct in_addr * dst)883 static int inet_pton4(char const *src, struct in_addr *dst)
884 {
885 int octet;
886 unsigned int num;
887 char const *p, *off;
888 uint8_t tmp[4];
889 static char const digits[] = "0123456789";
890
891 octet = 0;
892 p = src;
893 while (1) {
894 num = 0;
895 while (*p && ((off = strchr(digits, *p)) != NULL)) {
896 num *= 10;
897 num += (off - digits);
898
899 if (num > 255) return 0;
900
901 p++;
902 }
903 if (!*p) break;
904
905 /*
906 * Not a digit, MUST be a dot, else we
907 * die.
908 */
909 if (*p != '.') {
910 return 0;
911 }
912
913 tmp[octet++] = num;
914 p++;
915 }
916
917 /*
918 * End of the string. At the fourth
919 * octet is OK, anything else is an
920 * error.
921 */
922 if (octet != 3) {
923 return 0;
924 }
925 tmp[3] = num;
926
927 memcpy(dst, &tmp, sizeof(tmp));
928 return 1;
929 }
930
931
932 #ifdef HAVE_STRUCT_SOCKADDR_IN6
933 /** Convert presentation level address to network order binary form
934 *
935 * @note Does not touch dst unless it's returning 1.
936 * @note :: in a full address is silently ignored.
937 * @note Inspired by Mark Andrews.
938 * @author Paul Vixie, 1996.
939 *
940 * @param src presentation level address.
941 * @param dst where to write output address.
942 * @return 1 if `src' is a valid [RFC1884 2.2] address, else 0.
943 */
inet_pton6(char const * src,unsigned char * dst)944 static int inet_pton6(char const *src, unsigned char *dst)
945 {
946 static char const xdigits_l[] = "0123456789abcdef",
947 xdigits_u[] = "0123456789ABCDEF";
948 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
949 char const *xdigits, *curtok;
950 int ch, saw_xdigit;
951 u_int val;
952
953 memset((tp = tmp), 0, IN6ADDRSZ);
954 endp = tp + IN6ADDRSZ;
955 colonp = NULL;
956 /* Leading :: requires some special handling. */
957 if (*src == ':')
958 if (*++src != ':')
959 return (0);
960 curtok = src;
961 saw_xdigit = 0;
962 val = 0;
963 while ((ch = *src++) != '\0') {
964 char const *pch;
965
966 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
967 pch = strchr((xdigits = xdigits_u), ch);
968 if (pch != NULL) {
969 val <<= 4;
970 val |= (pch - xdigits);
971 if (val > 0xffff)
972 return (0);
973 saw_xdigit = 1;
974 continue;
975 }
976 if (ch == ':') {
977 curtok = src;
978 if (!saw_xdigit) {
979 if (colonp)
980 return (0);
981 colonp = tp;
982 continue;
983 }
984 if (tp + INT16SZ > endp)
985 return (0);
986 *tp++ = (u_char) (val >> 8) & 0xff;
987 *tp++ = (u_char) val & 0xff;
988 saw_xdigit = 0;
989 val = 0;
990 continue;
991 }
992 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
993 inet_pton4(curtok, (struct in_addr *) tp) > 0) {
994 tp += INADDRSZ;
995 saw_xdigit = 0;
996 break; /* '\0' was seen by inet_pton4(). */
997 }
998 return (0);
999 }
1000 if (saw_xdigit) {
1001 if (tp + INT16SZ > endp)
1002 return (0);
1003 *tp++ = (u_char) (val >> 8) & 0xff;
1004 *tp++ = (u_char) val & 0xff;
1005 }
1006 if (colonp != NULL) {
1007 /*
1008 * Since some memmove()'s erroneously fail to handle
1009 * overlapping regions, we'll do the shift by hand.
1010 */
1011 int const n = tp - colonp;
1012 int i;
1013
1014 for (i = 1; i <= n; i++) {
1015 endp[- i] = colonp[n - i];
1016 colonp[n - i] = 0;
1017 }
1018 tp = endp;
1019 }
1020 if (tp != endp)
1021 return (0);
1022 /* bcopy(tmp, dst, IN6ADDRSZ); */
1023 memcpy(dst, tmp, IN6ADDRSZ);
1024 return (1);
1025 }
1026 #endif
1027
1028 /*
1029 * Utility function, so that the rest of the server doesn't
1030 * have ifdef's around IPv6 support
1031 */
inet_pton(int af,char const * src,void * dst)1032 int inet_pton(int af, char const *src, void *dst)
1033 {
1034 if (af == AF_INET) {
1035 return inet_pton4(src, dst);
1036 }
1037 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1038
1039 if (af == AF_INET6) {
1040 return inet_pton6(src, dst);
1041 }
1042 #endif
1043
1044 return -1;
1045 }
1046 #endif
1047
1048 #ifndef HAVE_INET_NTOP
1049 /*
1050 * Utility function, so that the rest of the server doesn't
1051 * have ifdef's around IPv6 support
1052 */
inet_ntop(int af,void const * src,char * dst,size_t cnt)1053 char const *inet_ntop(int af, void const *src, char *dst, size_t cnt)
1054 {
1055 if (af == AF_INET) {
1056 uint8_t const *ipaddr = src;
1057
1058 if (cnt <= INET_ADDRSTRLEN) return NULL;
1059
1060 snprintf(dst, cnt, "%d.%d.%d.%d",
1061 ipaddr[0], ipaddr[1],
1062 ipaddr[2], ipaddr[3]);
1063 return dst;
1064 }
1065
1066 /*
1067 * If the system doesn't define this, we define it
1068 * in missing.h
1069 */
1070 if (af == AF_INET6) {
1071 struct in6_addr const *ipaddr = src;
1072
1073 if (cnt <= INET6_ADDRSTRLEN) return NULL;
1074
1075 snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x",
1076 (ipaddr->s6_addr[0] << 8) | ipaddr->s6_addr[1],
1077 (ipaddr->s6_addr[2] << 8) | ipaddr->s6_addr[3],
1078 (ipaddr->s6_addr[4] << 8) | ipaddr->s6_addr[5],
1079 (ipaddr->s6_addr[6] << 8) | ipaddr->s6_addr[7],
1080 (ipaddr->s6_addr[8] << 8) | ipaddr->s6_addr[9],
1081 (ipaddr->s6_addr[10] << 8) | ipaddr->s6_addr[11],
1082 (ipaddr->s6_addr[12] << 8) | ipaddr->s6_addr[13],
1083 (ipaddr->s6_addr[14] << 8) | ipaddr->s6_addr[15]);
1084 return dst;
1085 }
1086
1087 return NULL; /* don't support IPv6 */
1088 }
1089 #endif
1090
1091 /** Wrappers for IPv4/IPv6 host to IP address lookup
1092 *
1093 * This function returns only one IP address, of the specified address family,
1094 * or the first address (of whatever family), if AF_UNSPEC is used.
1095 *
1096 * If fallback is specified and af is AF_INET, but no AF_INET records were
1097 * found and a record for AF_INET6 exists that record will be returned.
1098 *
1099 * If fallback is specified and af is AF_INET6, and a record with AF_INET4 exists
1100 * that record will be returned instead.
1101 *
1102 * @param out Where to write result.
1103 * @param af To search for in preference.
1104 * @param hostname to search for.
1105 * @param fallback to the other adress family, if no records matching af, found.
1106 * @return 0 on success, else -1 on failure.
1107 */
ip_hton(fr_ipaddr_t * out,int af,char const * hostname,bool fallback)1108 int ip_hton(fr_ipaddr_t *out, int af, char const *hostname, bool fallback)
1109 {
1110 int rcode;
1111 struct addrinfo hints, *ai = NULL, *alt = NULL, *res = NULL;
1112
1113 /*
1114 * Avoid malloc for IP addresses. This helps us debug
1115 * memory errors when using talloc.
1116 */
1117 #ifdef TALLOC_DEBUG
1118 if (true) {
1119 #else
1120 if (!fr_hostname_lookups) {
1121 #endif
1122 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1123 if (af == AF_UNSPEC) {
1124 char const *p;
1125
1126 for (p = hostname; *p != '\0'; p++) {
1127 if ((*p == ':') ||
1128 (*p == '[') ||
1129 (*p == ']')) {
1130 af = AF_INET6;
1131 break;
1132 }
1133 }
1134 }
1135 #endif
1136
1137 if (af == AF_UNSPEC) af = AF_INET;
1138
1139 if (!inet_pton(af, hostname, &(out->ipaddr))) return -1;
1140
1141 out->af = af;
1142 return 0;
1143 }
1144
1145 memset(&hints, 0, sizeof(hints));
1146
1147 /*
1148 * If we're falling back we need both IPv4 and IPv6 records
1149 */
1150 if (fallback) {
1151 hints.ai_family = AF_UNSPEC;
1152 } else {
1153 hints.ai_family = af;
1154 }
1155
1156 if ((rcode = getaddrinfo(hostname, NULL, &hints, &res)) != 0) {
1157 switch (af) {
1158 default:
1159 case AF_UNSPEC:
1160 fr_strerror_printf("Failed resolving \"%s\" to IP address: %s",
1161 hostname, gai_strerror(rcode));
1162 return -1;
1163
1164 case AF_INET:
1165 fr_strerror_printf("Failed resolving \"%s\" to IPv4 address: %s",
1166 hostname, gai_strerror(rcode));
1167 return -1;
1168
1169 case AF_INET6:
1170 fr_strerror_printf("Failed resolving \"%s\" to IPv6 address: %s",
1171 hostname, gai_strerror(rcode));
1172 return -1;
1173 }
1174 }
1175
1176 for (ai = res; ai; ai = ai->ai_next) {
1177 if ((af == ai->ai_family) || (af == AF_UNSPEC)) break;
1178 if (!alt && fallback && ((ai->ai_family == AF_INET) || (ai->ai_family == AF_INET6))) alt = ai;
1179 }
1180
1181 if (!ai) ai = alt;
1182 if (!ai) {
1183 fr_strerror_printf("ip_hton failed to find requested information for host %.100s", hostname);
1184 freeaddrinfo(res);
1185 return -1;
1186 }
1187
1188 rcode = fr_sockaddr2ipaddr((struct sockaddr_storage *)ai->ai_addr,
1189 ai->ai_addrlen, out, NULL);
1190 freeaddrinfo(res);
1191 if (!rcode) {
1192 fr_strerror_printf("Failed converting sockaddr to ipaddr");
1193 return -1;
1194 }
1195
1196 return 0;
1197 }
1198
1199 /*
1200 * Look IP addresses up, and print names (depending on DNS config)
1201 */
1202 char const *ip_ntoh(fr_ipaddr_t const *src, char *dst, size_t cnt)
1203 {
1204 struct sockaddr_storage ss;
1205 int error;
1206 socklen_t salen;
1207
1208 /*
1209 * No DNS lookups
1210 */
1211 if (!fr_dns_lookups) {
1212 return inet_ntop(src->af, &(src->ipaddr), dst, cnt);
1213 }
1214
1215 if (!fr_ipaddr2sockaddr(src, 0, &ss, &salen)) {
1216 return NULL;
1217 }
1218
1219 if ((error = getnameinfo((struct sockaddr *)&ss, salen, dst, cnt, NULL, 0,
1220 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
1221 fr_strerror_printf("ip_ntoh: %s", gai_strerror(error));
1222 return NULL;
1223 }
1224 return dst;
1225 }
1226
1227 /** Mask off a portion of an IPv4 address
1228 *
1229 * @param ipaddr to mask.
1230 * @param prefix Number of contiguous bits to mask.
1231 * @return an ipv4 address with the host portion zeroed out.
1232 */
1233 struct in_addr fr_inaddr_mask(struct in_addr const *ipaddr, uint8_t prefix)
1234 {
1235 uint32_t ret;
1236
1237 if (prefix > 32) prefix = 32;
1238
1239 /* Short circuit */
1240 if (prefix == 32) return *ipaddr;
1241
1242 if (prefix == 0) ret = 0;
1243 else ret = htonl(~((0x00000001UL << (32 - prefix)) - 1)) & ipaddr->s_addr;
1244
1245 return (*(struct in_addr *)&ret);
1246 }
1247
1248 /** Mask off a portion of an IPv6 address
1249 *
1250 * @param ipaddr to mask.
1251 * @param prefix Number of contiguous bits to mask.
1252 * @return an ipv6 address with the host portion zeroed out.
1253 */
1254 struct in6_addr fr_in6addr_mask(struct in6_addr const *ipaddr, uint8_t prefix)
1255 {
1256 uint64_t const *p = (uint64_t const *) ipaddr;
1257 uint64_t ret[2], *o = ret;
1258
1259 if (prefix > 128) prefix = 128;
1260
1261 /* Short circuit */
1262 if (prefix == 128) return *ipaddr;
1263
1264 if (prefix >= 64) {
1265 prefix -= 64;
1266 *o++ = 0xffffffffffffffffULL & *p++; /* lhs portion masked */
1267 } else {
1268 ret[1] = 0; /* rhs portion zeroed */
1269 }
1270
1271 /* Max left shift is 63 else we get overflow */
1272 if (prefix > 0) {
1273 *o = htonll(~((uint64_t)(0x0000000000000001ULL << (64 - prefix)) - 1)) & *p;
1274 } else {
1275 *o = 0;
1276 }
1277
1278 return *(struct in6_addr *) &ret;
1279 }
1280
1281 /** Zeroes out the host portion of an fr_ipaddr_t
1282 *
1283 * @param[in,out] addr to mask
1284 * @param[in] prefix Length of the network portion.
1285 */
1286 void fr_ipaddr_mask(fr_ipaddr_t *addr, uint8_t prefix)
1287 {
1288
1289 switch (addr->af) {
1290 case AF_INET:
1291 addr->ipaddr.ip4addr = fr_inaddr_mask(&addr->ipaddr.ip4addr, prefix);
1292 break;
1293
1294 case AF_INET6:
1295 addr->ipaddr.ip6addr = fr_in6addr_mask(&addr->ipaddr.ip6addr, prefix);
1296 break;
1297
1298 default:
1299 return;
1300 }
1301 addr->prefix = prefix;
1302 }
1303
1304 static char const hextab[] = "0123456789abcdef";
1305
1306 /** Convert hex strings to binary data
1307 *
1308 * @param bin Buffer to write output to.
1309 * @param outlen length of output buffer (or length of input string / 2).
1310 * @param hex input string.
1311 * @param inlen length of the input string
1312 * @return length of data written to buffer.
1313 */
1314 size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
1315 {
1316 size_t i;
1317 size_t len;
1318 char *c1, *c2;
1319
1320 /*
1321 * Smartly truncate output, caller should check number of bytes
1322 * written.
1323 */
1324 len = inlen >> 1;
1325 if (len > outlen) len = outlen;
1326
1327 for (i = 0; i < len; i++) {
1328 if(!(c1 = memchr(hextab, tolower((int) hex[i << 1]), sizeof(hextab))) ||
1329 !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), sizeof(hextab))))
1330 break;
1331 bin[i] = ((c1-hextab)<<4) + (c2-hextab);
1332 }
1333
1334 return i;
1335 }
1336
1337 /** Convert binary data to a hex string
1338 *
1339 * Ascii encoded hex string will not be prefixed with '0x'
1340 *
1341 * @warning If the output buffer isn't long enough, we have a buffer overflow.
1342 *
1343 * @param[out] hex Buffer to write hex output.
1344 * @param[in] bin input.
1345 * @param[in] inlen of bin input.
1346 * @return length of data written to buffer.
1347 */
1348 size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen)
1349 {
1350 size_t i;
1351
1352 for (i = 0; i < inlen; i++) {
1353 hex[0] = hextab[((*bin) >> 4) & 0x0f];
1354 hex[1] = hextab[*bin & 0x0f];
1355 hex += 2;
1356 bin++;
1357 }
1358
1359 *hex = '\0';
1360 return inlen * 2;
1361 }
1362
1363 /** Convert binary data to a hex string
1364 *
1365 * Ascii encoded hex string will not be prefixed with '0x'
1366 *
1367 * @param[in] ctx to alloc buffer in.
1368 * @param[in] bin input.
1369 * @param[in] inlen of bin input.
1370 * @return length of data written to buffer.
1371 */
1372 char *fr_abin2hex(TALLOC_CTX *ctx, uint8_t const *bin, size_t inlen)
1373 {
1374 char *buff;
1375
1376 buff = talloc_array(ctx, char, (inlen << 2));
1377 if (!buff) return NULL;
1378
1379 fr_bin2hex(buff, bin, inlen);
1380
1381 return buff;
1382 }
1383
1384 /** Consume the integer (or hex) portion of a value string
1385 *
1386 * @param value string to parse.
1387 * @param end pointer to the first non numeric char.
1388 * @return integer value.
1389 */
1390 uint32_t fr_strtoul(char const *value, char **end)
1391 {
1392 if ((value[0] == '0') && (value[1] == 'x')) {
1393 return strtoul(value, end, 16);
1394 }
1395
1396 return strtoul(value, end, 10);
1397 }
1398
1399 /** Check whether the string is all whitespace
1400 *
1401 * @return true if the entirety of the string is whitespace, else false.
1402 */
1403 bool is_whitespace(char const *value)
1404 {
1405 do {
1406 if (!isspace(*value)) return false;
1407 value++;
1408 } while (*value);
1409
1410 return true;
1411 }
1412
1413 /** Check whether the string is made up of printable UTF8 chars
1414 *
1415 * @param value to check.
1416 * @param len of value.
1417 *
1418 * @return
1419 * - true if the string is printable.
1420 * - false if the string contains non printable chars
1421 */
1422 bool is_printable(void const *value, size_t len)
1423 {
1424 uint8_t const *p = value;
1425 int clen;
1426 size_t i;
1427
1428 for (i = 0; i < len; i++) {
1429 clen = fr_utf8_char(p, len - i);
1430 if (clen == 0) return false;
1431 i += (size_t)clen;
1432 p += clen;
1433 }
1434 return true;
1435 }
1436
1437 /** Check whether the string is all numbers
1438 *
1439 * @return true if the entirety of the string is all numbers, else false.
1440 */
1441 bool is_integer(char const *value)
1442 {
1443 #ifndef __clang_analyzer__
1444 do {
1445 if (!isdigit(*value)) return false;
1446 value++;
1447 } while (*value);
1448
1449 /*
1450 * Clang analyzer complains about the above line: "Branch
1451 * depends on a garbage value", even though that's
1452 * clearly not true. And, it doesn't complain about the
1453 * other functions doing similar things.
1454 */
1455 #else
1456 if (!isdigit(*value)) return false;
1457 #endif
1458
1459 return true;
1460 }
1461
1462 /** Check whether the string is allzeros
1463 *
1464 * @return true if the entirety of the string is all zeros, else false.
1465 */
1466 bool is_zero(char const *value)
1467 {
1468 do {
1469 if (*value != '0') return false;
1470 value++;
1471 } while (*value);
1472
1473 return true;
1474 }
1475
1476 /*
1477 * So we don't have ifdef's in the rest of the code
1478 */
1479 #ifndef HAVE_CLOSEFROM
1480 int closefrom(int fd)
1481 {
1482 int i;
1483 int maxfd = 256;
1484 #ifdef HAVE_DIRENT_H
1485 DIR *dir;
1486 #endif
1487
1488 #ifdef F_CLOSEM
1489 if (fcntl(fd, F_CLOSEM) == 0) {
1490 return 0;
1491 }
1492 #endif
1493
1494 #ifdef F_MAXFD
1495 maxfd = fcntl(fd, F_F_MAXFD);
1496 if (maxfd >= 0) goto do_close;
1497 #endif
1498
1499 #ifdef _SC_OPEN_MAX
1500 maxfd = sysconf(_SC_OPEN_MAX);
1501 if (maxfd < 0) {
1502 maxfd = 256;
1503 }
1504 #endif
1505
1506 #ifdef HAVE_DIRENT_H
1507 /*
1508 * Use /proc/self/fd directory if it exists.
1509 */
1510 dir = opendir(CLOSEFROM_DIR);
1511 if (dir != NULL) {
1512 long my_fd;
1513 char *endp;
1514 struct dirent *dp;
1515
1516 while ((dp = readdir(dir)) != NULL) {
1517 my_fd = strtol(dp->d_name, &endp, 10);
1518 if (my_fd <= 0) continue;
1519
1520 if (*endp) continue;
1521
1522 if (my_fd == dirfd(dir)) continue;
1523
1524 if ((my_fd >= fd) && (my_fd <= maxfd)) {
1525 (void) close((int) my_fd);
1526 }
1527 }
1528 (void) closedir(dir);
1529 return 0;
1530 }
1531 #endif
1532
1533 #ifdef F_MAXFD
1534 do_close:
1535 #endif
1536
1537 if (fd > maxfd) return 0;
1538
1539 /*
1540 * FIXME: return EINTR?
1541 */
1542 for (i = fd; i < maxfd; i++) {
1543 close(i);
1544 }
1545
1546 return 0;
1547 }
1548 #endif
1549
1550 int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
1551 {
1552 if (a->af < b->af) return -1;
1553 if (a->af > b->af) return +1;
1554
1555 if (a->prefix < b->prefix) return -1;
1556 if (a->prefix > b->prefix) return +1;
1557
1558 switch (a->af) {
1559 case AF_INET:
1560 return memcmp(&a->ipaddr.ip4addr,
1561 &b->ipaddr.ip4addr,
1562 sizeof(a->ipaddr.ip4addr));
1563
1564 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1565 case AF_INET6:
1566 if (a->scope < b->scope) return -1;
1567 if (a->scope > b->scope) return +1;
1568
1569 return memcmp(&a->ipaddr.ip6addr,
1570 &b->ipaddr.ip6addr,
1571 sizeof(a->ipaddr.ip6addr));
1572 #endif
1573
1574 default:
1575 break;
1576 }
1577
1578 return -1;
1579 }
1580
1581 int fr_ipaddr2sockaddr(fr_ipaddr_t const *ipaddr, uint16_t port,
1582 struct sockaddr_storage *sa, socklen_t *salen)
1583 {
1584 memset(sa, 0, sizeof(*sa));
1585
1586 if (ipaddr->af == AF_INET) {
1587 struct sockaddr_in s4;
1588
1589 *salen = sizeof(s4);
1590
1591 memset(&s4, 0, sizeof(s4));
1592 s4.sin_family = AF_INET;
1593 s4.sin_addr = ipaddr->ipaddr.ip4addr;
1594 s4.sin_port = htons(port);
1595 memset(sa, 0, sizeof(*sa));
1596 memcpy(sa, &s4, sizeof(s4));
1597
1598 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1599 } else if (ipaddr->af == AF_INET6) {
1600 struct sockaddr_in6 s6;
1601
1602 *salen = sizeof(s6);
1603
1604 memset(&s6, 0, sizeof(s6));
1605 s6.sin6_family = AF_INET6;
1606 s6.sin6_addr = ipaddr->ipaddr.ip6addr;
1607 s6.sin6_port = htons(port);
1608 s6.sin6_scope_id = ipaddr->scope;
1609 memset(sa, 0, sizeof(*sa));
1610 memcpy(sa, &s6, sizeof(s6));
1611 #endif
1612 } else {
1613 return 0;
1614 }
1615
1616 return 1;
1617 }
1618
1619
1620 int fr_sockaddr2ipaddr(struct sockaddr_storage const *sa, socklen_t salen,
1621 fr_ipaddr_t *ipaddr, uint16_t *port)
1622 {
1623 memset(ipaddr, 0, sizeof(*ipaddr));
1624
1625 if (sa->ss_family == AF_INET) {
1626 struct sockaddr_in s4;
1627
1628 if (salen < sizeof(s4)) {
1629 fr_strerror_printf("IPv4 address is too small");
1630 return 0;
1631 }
1632
1633 memcpy(&s4, sa, sizeof(s4));
1634 ipaddr->af = AF_INET;
1635 ipaddr->prefix = 32;
1636 ipaddr->ipaddr.ip4addr = s4.sin_addr;
1637 if (port) *port = ntohs(s4.sin_port);
1638
1639 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1640 } else if (sa->ss_family == AF_INET6) {
1641 struct sockaddr_in6 s6;
1642
1643 if (salen < sizeof(s6)) {
1644 fr_strerror_printf("IPv6 address is too small");
1645 return 0;
1646 }
1647
1648 memcpy(&s6, sa, sizeof(s6));
1649 ipaddr->af = AF_INET6;
1650 ipaddr->prefix = 128;
1651 ipaddr->ipaddr.ip6addr = s6.sin6_addr;
1652 if (port) *port = ntohs(s6.sin6_port);
1653 ipaddr->scope = s6.sin6_scope_id;
1654 #endif
1655
1656 } else {
1657 fr_strerror_printf("Unsupported address famility %d",
1658 sa->ss_family);
1659 return 0;
1660 }
1661
1662 return 1;
1663 }
1664
1665 #ifdef O_NONBLOCK
1666 /** Set O_NONBLOCK on a socket
1667 *
1668 * @note O_NONBLOCK is POSIX.
1669 *
1670 * @param fd to set nonblocking flag on.
1671 * @return flags set on the socket, or -1 on error.
1672 */
1673 int fr_nonblock(int fd)
1674 {
1675 int flags;
1676
1677 flags = fcntl(fd, F_GETFL, NULL);
1678 if (flags < 0) {
1679 fr_strerror_printf("Failure getting socket flags: %s", fr_syserror(errno));
1680 return -1;
1681 }
1682
1683 flags |= O_NONBLOCK;
1684 if (fcntl(fd, F_SETFL, flags) < 0) {
1685 fr_strerror_printf("Failure setting socket flags: %s", fr_syserror(errno));
1686 return -1;
1687 }
1688
1689 return flags;
1690 }
1691
1692 /** Unset O_NONBLOCK on a socket
1693 *
1694 * @note O_NONBLOCK is POSIX.
1695 *
1696 * @param fd to set nonblocking flag on.
1697 * @return flags set on the socket, or -1 on error.
1698 */
1699 int fr_blocking(int fd)
1700 {
1701 int flags;
1702
1703 flags = fcntl(fd, F_GETFL, NULL);
1704 if (flags < 0) {
1705 fr_strerror_printf("Failure getting socket flags: %s", fr_syserror(errno));
1706 return -1;
1707 }
1708
1709 flags ^= O_NONBLOCK;
1710 if (fcntl(fd, F_SETFL, flags) < 0) {
1711 fr_strerror_printf("Failure setting socket flags: %s", fr_syserror(errno));
1712 return -1;
1713 }
1714
1715 return flags;
1716 }
1717 #else
1718 int fr_nonblock(UNUSED int fd)
1719 {
1720 fr_strerror_printf("Non blocking sockets are not supported");
1721 return -1;
1722 }
1723 int fr_blocking(UNUSED int fd)
1724 {
1725 fr_strerror_printf("Non blocking sockets are not supported");
1726 return -1;
1727 }
1728 #endif
1729
1730 /** Write out a vector to a file descriptor
1731 *
1732 * Wraps writev, calling it as necessary. If timeout is not NULL,
1733 * timeout is applied to each call that returns EAGAIN or EWOULDBLOCK
1734 *
1735 * @note Should only be used on nonblocking file descriptors.
1736 * @note Socket should likely be closed on timeout.
1737 * @note iovec may be modified in such a way that it's not re-usable.
1738 * @note Leaves errno set to the last error that ocurred.
1739 *
1740 * @param fd to write to.
1741 * @param vector to write.
1742 * @param iovcnt number of elements in iovec.
1743 * @param timeout how long to wait for fd to become writeable before timing out.
1744 * @return number of bytes written, -1 on error.
1745 */
1746 ssize_t fr_writev(int fd, struct iovec vector[], int iovcnt, struct timeval *timeout)
1747 {
1748 struct iovec *vector_p = vector;
1749 ssize_t total = 0;
1750
1751 while (iovcnt > 0) {
1752 ssize_t wrote;
1753
1754 wrote = writev(fd, vector_p, iovcnt);
1755 if (wrote > 0) {
1756 total += wrote;
1757 while (wrote > 0) {
1758 /*
1759 * An entire vector element was written
1760 */
1761 if (wrote >= (ssize_t)vector_p->iov_len) {
1762 iovcnt--;
1763 wrote -= vector_p->iov_len;
1764 vector_p++;
1765 continue;
1766 }
1767
1768 /*
1769 * Partial vector element was written
1770 */
1771 vector_p->iov_len -= wrote;
1772 vector_p->iov_base = ((char *)vector_p->iov_base) + wrote;
1773 break;
1774 }
1775 continue;
1776 } else if (wrote == 0) return total;
1777
1778 switch (errno) {
1779 /* Write operation would block, use select() to implement a timeout */
1780 #if EWOULDBLOCK != EAGAIN
1781 case EWOULDBLOCK:
1782 case EAGAIN:
1783 #else
1784 case EAGAIN:
1785 #endif
1786 {
1787 int ret;
1788 fd_set write_set;
1789
1790 FD_ZERO(&write_set);
1791 FD_SET(fd, &write_set);
1792
1793 /* Don't let signals mess up the select */
1794 do {
1795 ret = select(fd + 1, NULL, &write_set, NULL, timeout);
1796 } while ((ret == -1) && (errno == EINTR));
1797
1798 /* Select returned 0 which means it reached the timeout */
1799 if (ret == 0) {
1800 fr_strerror_printf("Write timed out");
1801 return -1;
1802 }
1803
1804 /* Other select error */
1805 if (ret < 0) {
1806 fr_strerror_printf("Failed waiting on socket: %s", fr_syserror(errno));
1807 return -1;
1808 }
1809
1810 /* select said a file descriptor was ready for writing */
1811 if (!fr_assert(FD_ISSET(fd, &write_set))) return -1;
1812
1813 break;
1814 }
1815
1816 default:
1817 return -1;
1818 }
1819 }
1820
1821 return total;
1822 }
1823
1824 /** Convert UTF8 string to UCS2 encoding
1825 *
1826 * @note Borrowed from src/crypto/ms_funcs.c of wpa_supplicant project (http://hostap.epitest.fi/wpa_supplicant/)
1827 *
1828 * @param[out] out Where to write the ucs2 string.
1829 * @param[in] outlen Size of output buffer.
1830 * @param[in] in UTF8 string to convert.
1831 * @param[in] inlen length of UTF8 string.
1832 * @return the size of the UCS2 string written to the output buffer (in bytes).
1833 */
1834 ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
1835 {
1836 size_t i;
1837 uint8_t *start = out;
1838
1839 for (i = 0; i < inlen; i++) {
1840 uint8_t c, c2, c3;
1841
1842 c = in[i];
1843 if ((size_t)(out - start) >= outlen) {
1844 /* input too long */
1845 return -1;
1846 }
1847
1848 /* One-byte encoding */
1849 if (c <= 0x7f) {
1850 FR_PUT_LE16(out, c);
1851 out += 2;
1852 continue;
1853 } else if ((i == (inlen - 1)) || ((size_t)(out - start) >= (outlen - 1))) {
1854 /* Incomplete surrogate */
1855 return -1;
1856 }
1857
1858 c2 = in[++i];
1859 /* Two-byte encoding */
1860 if ((c & 0xe0) == 0xc0) {
1861 FR_PUT_LE16(out, ((c & 0x1f) << 6) | (c2 & 0x3f));
1862 out += 2;
1863 continue;
1864 }
1865 if ((i == inlen) || ((size_t)(out - start) >= (outlen - 1))) {
1866 /* Incomplete surrogate */
1867 return -1;
1868 }
1869
1870 /* Three-byte encoding */
1871 c3 = in[++i];
1872 FR_PUT_LE16(out, ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));
1873 out += 2;
1874 }
1875
1876 return out - start;
1877 }
1878
1879 /** Write 128bit unsigned integer to buffer
1880 *
1881 * @author Alexey Frunze
1882 *
1883 * @param out where to write result to.
1884 * @param outlen size of out.
1885 * @param num 128 bit integer.
1886 */
1887 size_t fr_prints_uint128(char *out, size_t outlen, uint128_t const num)
1888 {
1889 char buff[128 / 3 + 1 + 1];
1890 uint64_t n[2];
1891 char *p = buff;
1892 int i;
1893 #ifdef FR_LITTLE_ENDIAN
1894 const size_t l = 0;
1895 const size_t h = 1;
1896 #else
1897 const size_t l = 1;
1898 const size_t h = 0;
1899 #endif
1900
1901 memset(buff, '0', sizeof(buff) - 1);
1902 buff[sizeof(buff) - 1] = '\0';
1903
1904 memcpy(n, &num, sizeof(n));
1905
1906 for (i = 0; i < 128; i++) {
1907 ssize_t j;
1908 int carry;
1909
1910 carry = (n[h] >= 0x8000000000000000);
1911
1912 // Shift n[] left, doubling it
1913 n[h] = ((n[h] << 1) & 0xffffffffffffffff) + (n[l] >= 0x8000000000000000);
1914 n[l] = ((n[l] << 1) & 0xffffffffffffffff);
1915
1916 // Add s[] to itself in decimal, doubling it
1917 for (j = sizeof(buff) - 2; j >= 0; j--) {
1918 buff[j] += buff[j] - '0' + carry;
1919 carry = (buff[j] > '9');
1920 if (carry) {
1921 buff[j] -= 10;
1922 }
1923 }
1924 }
1925
1926 while ((*p == '0') && (p < &buff[sizeof(buff) - 2])) {
1927 p++;
1928 }
1929
1930 return strlcpy(out, p, outlen);
1931 }
1932
1933 /*
1934 * Sort of strtok/strsep function.
1935 */
1936 static char *mystrtok(char **ptr, char const *sep)
1937 {
1938 char *res;
1939
1940 if (**ptr == 0) {
1941 return NULL;
1942 }
1943
1944 while (**ptr && strchr(sep, **ptr)) {
1945 (*ptr)++;
1946 }
1947 if (**ptr == 0) {
1948 return NULL;
1949 }
1950
1951 res = *ptr;
1952 while (**ptr && strchr(sep, **ptr) == NULL) {
1953 (*ptr)++;
1954 }
1955
1956 if (**ptr != 0) {
1957 *(*ptr)++ = 0;
1958 }
1959 return res;
1960 }
1961
1962 /** Convert string in various formats to a time_t
1963 *
1964 * @param date_str input date string.
1965 * @param date time_t to write result to.
1966 * @return 0 on success or -1 on error.
1967 */
1968 int fr_get_time(char const *date_str, time_t *date)
1969 {
1970 int i, j;
1971 time_t t;
1972 struct tm *tm, s_tm;
1973 char buf[64];
1974 char *p;
1975 char *f[4];
1976 char *tail = NULL;
1977
1978 /*
1979 * Test for unix timestamp date
1980 */
1981 *date = strtoul(date_str, &tail, 10);
1982 if (*tail == '\0') {
1983 return 0;
1984 }
1985
1986 tm = &s_tm;
1987 memset(tm, 0, sizeof(*tm));
1988 tm->tm_isdst = -1; /* don't know, and don't care about DST */
1989
1990 strlcpy(buf, date_str, sizeof(buf));
1991
1992 p = buf;
1993 f[0] = mystrtok(&p, " \t");
1994 f[1] = mystrtok(&p, " \t");
1995 f[2] = mystrtok(&p, " \t");
1996 f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */
1997 if (!f[0] || !f[1] || !f[2]) return -1;
1998
1999 /*
2000 * The time has a colon, where nothing else does.
2001 * So if we find it, bubble it to the back of the list.
2002 */
2003 if (f[3]) {
2004 for (i = 0; i < 3; i++) {
2005 if (strchr(f[i], ':')) {
2006 p = f[3];
2007 f[3] = f[i];
2008 f[i] = p;
2009 break;
2010 }
2011 }
2012 }
2013
2014 /*
2015 * The month is text, which allows us to find it easily.
2016 */
2017 tm->tm_mon = 12;
2018 for (i = 0; i < 3; i++) {
2019 if (isalpha( (int) *f[i])) {
2020 /*
2021 * Bubble the month to the front of the list
2022 */
2023 p = f[0];
2024 f[0] = f[i];
2025 f[i] = p;
2026
2027 for (j = 0; j < 12; j++) {
2028 if (strncasecmp(months[j], f[0], 3) == 0) {
2029 tm->tm_mon = j;
2030 break;
2031 }
2032 }
2033 }
2034 }
2035
2036 /* month not found? */
2037 if (tm->tm_mon == 12) return -1;
2038
2039 /*
2040 * The year may be in f[1], or in f[2]
2041 */
2042 tm->tm_year = atoi(f[1]);
2043 tm->tm_mday = atoi(f[2]);
2044
2045 if (tm->tm_year >= 1900) {
2046 tm->tm_year -= 1900;
2047
2048 } else {
2049 /*
2050 * We can't use 2-digit years any more, they make it
2051 * impossible to tell what's the day, and what's the year.
2052 */
2053 if (tm->tm_mday < 1900) return -1;
2054
2055 /*
2056 * Swap the year and the day.
2057 */
2058 i = tm->tm_year;
2059 tm->tm_year = tm->tm_mday - 1900;
2060 tm->tm_mday = i;
2061 }
2062
2063 /*
2064 * If the day is out of range, die.
2065 */
2066 if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {
2067 return -1;
2068 }
2069
2070 /*
2071 * There may be %H:%M:%S. Parse it in a hacky way.
2072 */
2073 if (f[3]) {
2074 f[0] = f[3]; /* HH */
2075 f[1] = strchr(f[0], ':'); /* find : separator */
2076 if (!f[1]) return -1;
2077
2078 *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
2079
2080 f[2] = strchr(f[1], ':'); /* find : separator */
2081 if (f[2]) {
2082 *(f[2]++) = '\0'; /* nuke it, and point to SS */
2083 tm->tm_sec = atoi(f[2]);
2084 } /* else leave it as zero */
2085
2086 tm->tm_hour = atoi(f[0]);
2087 tm->tm_min = atoi(f[1]);
2088 }
2089
2090 /*
2091 * Returns -1 on error.
2092 */
2093 t = mktime(tm);
2094 if (t == (time_t) -1) return -1;
2095
2096 *date = t;
2097
2098 return 0;
2099 }
2100
2101 /** Compares two pointers
2102 *
2103 * @param a first pointer to compare.
2104 * @param b second pointer to compare.
2105 * @return -1 if a < b, +1 if b > a, or 0 if both equal.
2106 */
2107 int8_t fr_pointer_cmp(void const *a, void const *b)
2108 {
2109 if (a < b) return -1;
2110 if (a == b) return 0;
2111
2112 return 1;
2113 }
2114
2115 static int _quick_partition(void const *to_sort[], int min, int max, fr_cmp_t cmp) {
2116 void const *pivot = to_sort[min];
2117 int i = min;
2118 int j = max + 1;
2119 void const *tmp;
2120
2121 for (;;) {
2122 do ++i; while((cmp(to_sort[i], pivot) <= 0) && i <= max);
2123 do --j; while(cmp(to_sort[j], pivot) > 0);
2124
2125 if (i >= j) break;
2126
2127 tmp = to_sort[i];
2128 to_sort[i] = to_sort[j];
2129 to_sort[j] = tmp;
2130 }
2131
2132 tmp = to_sort[min];
2133 to_sort[min] = to_sort[j];
2134 to_sort[j] = tmp;
2135
2136 return j;
2137 }
2138
2139 /** Quick sort an array of pointers using a comparator
2140 *
2141 * @param to_sort array of pointers to sort.
2142 * @param min_idx the lowest index (usually 0).
2143 * @param max_idx the highest index (usually length of array - 1).
2144 * @param cmp the comparison function to use to sort the array elements.
2145 */
2146 void fr_quick_sort(void const *to_sort[], int min_idx, int max_idx, fr_cmp_t cmp)
2147 {
2148 int part;
2149
2150 if (min_idx >= max_idx) return;
2151
2152 part = _quick_partition(to_sort, min_idx, max_idx, cmp);
2153 fr_quick_sort(to_sort, min_idx, part - 1, cmp);
2154 fr_quick_sort(to_sort, part + 1, max_idx, cmp);
2155 }
2156
2157 #define USEC 1000000
2158
2159 /** Convert a time specified in milliseconds to a timeval
2160 *
2161 * @param[out] out Where to write the result.
2162 * @param[in] ms To convert to a timeval struct.
2163 */
2164 void fr_timeval_from_ms(struct timeval *out, uint64_t ms)
2165 {
2166 out->tv_sec = ms / 1000;
2167 out->tv_usec = (ms % 1000) * 1000;
2168 }
2169
2170 /** Convert a time specified in microseconds to a timeval
2171 *
2172 * @param[out] out Where to write the result.
2173 * @param[in] usec To convert to a timeval struct.
2174 */
2175 void fr_timeval_from_usec(struct timeval *out, uint64_t usec)
2176 {
2177 out->tv_sec = usec / USEC;
2178 out->tv_usec = usec % USEC;
2179 }
2180
2181 #ifdef TALLOC_DEBUG
2182 void fr_talloc_verify_cb(UNUSED const void *ptr, UNUSED int depth,
2183 UNUSED int max_depth, UNUSED int is_ref,
2184 UNUSED void *private_data)
2185 {
2186 /* do nothing */
2187 }
2188 #endif
2189