Assume password src encoding is UTF8 and convert it to UCS2 before hashing with MD4
[freeradius.git] / src / lib / misc.c
1 /*
2  * misc.c       Various miscellaneous functions.
3  *
4  * Version:     $Id$
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$")
24
25 #include        <freeradius-devel/libradius.h>
26
27 #include        <ctype.h>
28 #include        <sys/file.h>
29 #include        <fcntl.h>
30 #include        <signal.h>
31
32 #define FR_PUT_LE16(a, val)\
33         do {\
34                 a[1] = ((uint16_t) (val)) >> 8;\
35                 a[0] = ((uint16_t) (val)) & 0xff;\
36         } while (0)
37
38 static int      fr_debugger_present = -1;
39
40 int     fr_dns_lookups = 0;
41 int     fr_debug_flag = 0;
42
43 fr_thread_local_setup(char *, fr_inet_ntop_buffer);     /* macro */
44
45 /** Allocates a new talloc context from the root autofree context
46  *
47  * @param signum signal raised.
48  */
49 static void _sigtrap_handler(UNUSED int signum)
50 {
51     fr_debugger_present = 0;
52     signal(SIGTRAP, SIG_DFL);
53 }
54
55 /** Break in GDB (if were running under GDB)
56  *
57  * If the server is running under GDB this will raise a SIGTRAP which
58  * will pause the running process.
59  *
60  * If the server is not running under GDB then this will do nothing.
61  */
62 void fr_debug_break(void)
63 {
64     if (fr_debugger_present == -1) {
65         fr_debugger_present = 0;
66         signal(SIGTRAP, _sigtrap_handler);
67         raise(SIGTRAP);
68     } else if (fr_debugger_present == 1) {
69         raise(SIGTRAP);
70     }
71 }
72
73 /*
74  *      Return an IP address in standard dot notation
75  *
76  *      FIXME: DELETE THIS
77  */
78 char const *ip_ntoa(char *buffer, uint32_t ipaddr)
79 {
80         ipaddr = ntohl(ipaddr);
81
82         sprintf(buffer, "%d.%d.%d.%d",
83                 (ipaddr >> 24) & 0xff,
84                 (ipaddr >> 16) & 0xff,
85                 (ipaddr >>  8) & 0xff,
86                 (ipaddr      ) & 0xff);
87         return buffer;
88 }
89
90 /*
91  *      Internal wrapper for locking, to minimize the number of ifdef's
92  *
93  *      Use fcntl or error
94  */
95 int rad_lockfd(int fd, int lock_len)
96 {
97 #ifdef F_WRLCK
98         struct flock fl;
99
100         fl.l_start = 0;
101         fl.l_len = lock_len;
102         fl.l_pid = getpid();
103         fl.l_type = F_WRLCK;
104         fl.l_whence = SEEK_CUR;
105
106         return fcntl(fd, F_SETLKW, (void *)&fl);
107 #else
108 #error "missing definition for F_WRLCK, all file locks will fail"
109
110         return -1;
111 #endif
112 }
113
114 /*
115  *      Internal wrapper for locking, to minimize the number of ifdef's
116  *
117  *      Lock an fd, prefer lockf() over flock()
118  *      Nonblocking version.
119  */
120 int rad_lockfd_nonblock(int fd, int lock_len)
121 {
122 #ifdef F_WRLCK
123         struct flock fl;
124
125         fl.l_start = 0;
126         fl.l_len = lock_len;
127         fl.l_pid = getpid();
128         fl.l_type = F_WRLCK;
129         fl.l_whence = SEEK_CUR;
130
131         return fcntl(fd, F_SETLK, (void *)&fl);
132 #else
133 #error "missing definition for F_WRLCK, all file locks will fail"
134
135         return -1;
136 #endif
137 }
138
139 /*
140  *      Internal wrapper for unlocking, to minimize the number of ifdef's
141  *      in the source.
142  *
143  *      Unlock an fd, prefer lockf() over flock()
144  */
145 int rad_unlockfd(int fd, int lock_len)
146 {
147 #ifdef F_WRLCK
148         struct flock fl;
149
150         fl.l_start = 0;
151         fl.l_len = lock_len;
152         fl.l_pid = getpid();
153         fl.l_type = F_WRLCK;
154         fl.l_whence = SEEK_CUR;
155
156         return fcntl(fd, F_UNLCK, (void *)&fl);
157 #else
158 #error "missing definition for F_WRLCK, all file locks will fail"
159
160         return -1;
161 #endif
162 }
163
164 /*
165  *      Return an interface-id in standard colon notation
166  */
167 char *ifid_ntoa(char *buffer, size_t size, uint8_t const *ifid)
168 {
169         snprintf(buffer, size, "%x:%x:%x:%x",
170                  (ifid[0] << 8) + ifid[1], (ifid[2] << 8) + ifid[3],
171                  (ifid[4] << 8) + ifid[5], (ifid[6] << 8) + ifid[7]);
172         return buffer;
173 }
174
175
176 /*
177  *      Return an interface-id from
178  *      one supplied in standard colon notation.
179  */
180 uint8_t *ifid_aton(char const *ifid_str, uint8_t *ifid)
181 {
182         static char const xdigits[] = "0123456789abcdef";
183         char const *p, *pch;
184         int num_id = 0, val = 0, idx = 0;
185
186         for (p = ifid_str; ; ++p) {
187                 if (*p == ':' || *p == '\0') {
188                         if (num_id <= 0)
189                                 return NULL;
190
191                         /*
192                          *      Drop 'val' into the array.
193                          */
194                         ifid[idx] = (val >> 8) & 0xff;
195                         ifid[idx + 1] = val & 0xff;
196                         if (*p == '\0') {
197                                 /*
198                                  *      Must have all entries before
199                                  *      end of the string.
200                                  */
201                                 if (idx != 6)
202                                         return NULL;
203                                 break;
204                         }
205                         val = 0;
206                         num_id = 0;
207                         if ((idx += 2) > 6)
208                                 return NULL;
209                 } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
210                         if (++num_id > 4)
211                                 return NULL;
212                         /*
213                          *      Dumb version of 'scanf'
214                          */
215                         val <<= 4;
216                         val |= (pch - xdigits);
217                 } else
218                         return NULL;
219         }
220         return ifid;
221 }
222
223
224 #ifndef HAVE_INET_PTON
225 static int inet_pton4(char const *src, struct in_addr *dst)
226 {
227         int octet;
228         unsigned int num;
229         char const *p, *off;
230         uint8_t tmp[4];
231         static char const digits[] = "0123456789";
232
233         octet = 0;
234         p = src;
235         while (1) {
236                 num = 0;
237                 while (*p && ((off = strchr(digits, *p)) != NULL)) {
238                         num *= 10;
239                         num += (off - digits);
240
241                         if (num > 255) return 0;
242
243                         p++;
244                 }
245                 if (!*p) break;
246
247                 /*
248                  *      Not a digit, MUST be a dot, else we
249                  *      die.
250                  */
251                 if (*p != '.') {
252                         return 0;
253                 }
254
255                 tmp[octet++] = num;
256                 p++;
257         }
258
259         /*
260          *      End of the string.  At the fourth
261          *      octet is OK, anything else is an
262          *      error.
263          */
264         if (octet != 3) {
265                 return 0;
266         }
267         tmp[3] = num;
268
269         memcpy(dst, &tmp, sizeof(tmp));
270         return 1;
271 }
272
273
274 #ifdef HAVE_STRUCT_SOCKADDR_IN6
275 /* int
276  * inet_pton6(src, dst)
277  *      convert presentation level address to network order binary form.
278  * return:
279  *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
280  * notice:
281  *      (1) does not touch `dst' unless it's returning 1.
282  *      (2) :: in a full address is silently ignored.
283  * credit:
284  *      inspired by Mark Andrews.
285  * author:
286  *      Paul Vixie, 1996.
287  */
288 static int
289 inet_pton6(char const *src, unsigned char *dst)
290 {
291         static char const xdigits_l[] = "0123456789abcdef",
292                           xdigits_u[] = "0123456789ABCDEF";
293         u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
294         char const *xdigits, *curtok;
295         int ch, saw_xdigit;
296         u_int val;
297
298         memset((tp = tmp), 0, IN6ADDRSZ);
299         endp = tp + IN6ADDRSZ;
300         colonp = NULL;
301         /* Leading :: requires some special handling. */
302         if (*src == ':')
303                 if (*++src != ':')
304                         return (0);
305         curtok = src;
306         saw_xdigit = 0;
307         val = 0;
308         while ((ch = *src++) != '\0') {
309                 char const *pch;
310
311                 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
312                         pch = strchr((xdigits = xdigits_u), ch);
313                 if (pch != NULL) {
314                         val <<= 4;
315                         val |= (pch - xdigits);
316                         if (val > 0xffff)
317                                 return (0);
318                         saw_xdigit = 1;
319                         continue;
320                 }
321                 if (ch == ':') {
322                         curtok = src;
323                         if (!saw_xdigit) {
324                                 if (colonp)
325                                         return (0);
326                                 colonp = tp;
327                                 continue;
328                         }
329                         if (tp + INT16SZ > endp)
330                                 return (0);
331                         *tp++ = (u_char) (val >> 8) & 0xff;
332                         *tp++ = (u_char) val & 0xff;
333                         saw_xdigit = 0;
334                         val = 0;
335                         continue;
336                 }
337                 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
338                     inet_pton4(curtok, (struct in_addr *) tp) > 0) {
339                         tp += INADDRSZ;
340                         saw_xdigit = 0;
341                         break;  /* '\0' was seen by inet_pton4(). */
342                 }
343                 return (0);
344         }
345         if (saw_xdigit) {
346                 if (tp + INT16SZ > endp)
347                         return (0);
348                 *tp++ = (u_char) (val >> 8) & 0xff;
349                 *tp++ = (u_char) val & 0xff;
350         }
351         if (colonp != NULL) {
352                 /*
353                  * Since some memmove()'s erroneously fail to handle
354                  * overlapping regions, we'll do the shift by hand.
355                  */
356                 int const n = tp - colonp;
357                 int i;
358
359                 for (i = 1; i <= n; i++) {
360                         endp[- i] = colonp[n - i];
361                         colonp[n - i] = 0;
362                 }
363                 tp = endp;
364         }
365         if (tp != endp)
366                 return (0);
367         /* bcopy(tmp, dst, IN6ADDRSZ); */
368         memcpy(dst, tmp, IN6ADDRSZ);
369         return (1);
370 }
371 #endif
372
373 /*
374  *      Utility function, so that the rest of the server doesn't
375  *      have ifdef's around IPv6 support
376  */
377 int inet_pton(int af, char const *src, void *dst)
378 {
379         if (af == AF_INET) {
380                 return inet_pton4(src, dst);
381         }
382 #ifdef HAVE_STRUCT_SOCKADDR_IN6
383
384         if (af == AF_INET6) {
385                 return inet_pton6(src, dst);
386         }
387 #endif
388
389         return -1;
390 }
391 #endif
392
393
394 #ifndef HAVE_INET_NTOP
395 /*
396  *      Utility function, so that the rest of the server doesn't
397  *      have ifdef's around IPv6 support
398  */
399 char const *inet_ntop(int af, void const *src, char *dst, size_t cnt)
400 {
401         if (af == AF_INET) {
402                 uint8_t const *ipaddr = src;
403
404                 if (cnt <= INET_ADDRSTRLEN) return NULL;
405
406                 snprintf(dst, cnt, "%d.%d.%d.%d",
407                          ipaddr[0], ipaddr[1],
408                          ipaddr[2], ipaddr[3]);
409                 return dst;
410         }
411
412         /*
413          *      If the system doesn't define this, we define it
414          *      in missing.h
415          */
416         if (af == AF_INET6) {
417                 struct const in6_addr *ipaddr = src;
418
419                 if (cnt <= INET6_ADDRSTRLEN) return NULL;
420
421                 snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x",
422                          (ipaddr->s6_addr[0] << 8) | ipaddr->s6_addr[1],
423                          (ipaddr->s6_addr[2] << 8) | ipaddr->s6_addr[3],
424                          (ipaddr->s6_addr[4] << 8) | ipaddr->s6_addr[5],
425                          (ipaddr->s6_addr[6] << 8) | ipaddr->s6_addr[7],
426                          (ipaddr->s6_addr[8] << 8) | ipaddr->s6_addr[9],
427                          (ipaddr->s6_addr[10] << 8) | ipaddr->s6_addr[11],
428                          (ipaddr->s6_addr[12] << 8) | ipaddr->s6_addr[13],
429                          (ipaddr->s6_addr[14] << 8) | ipaddr->s6_addr[15]);
430                 return dst;
431         }
432
433         return NULL;            /* don't support IPv6 */
434 }
435 #endif
436
437
438 /*
439  *      Wrappers for IPv4/IPv6 host to IP address lookup.
440  *      This API returns only one IP address, of the specified
441  *      address family, or the first address (of whatever family),
442  *      if AF_UNSPEC is used.
443  */
444 int ip_hton(char const *src, int af, fr_ipaddr_t *dst)
445 {
446         int rcode;
447         struct addrinfo hints, *ai = NULL, *res = NULL;
448
449         memset(&hints, 0, sizeof(hints));
450         hints.ai_family = af;
451
452         if ((rcode = getaddrinfo(src, NULL, &hints, &res)) != 0) {
453                 fr_strerror_printf("ip_hton: %s", gai_strerror(rcode));
454                 return -1;
455         }
456
457         for (ai = res; ai; ai = ai->ai_next) {
458                 if ((af == ai->ai_family) || (af == AF_UNSPEC))
459                         break;
460         }
461
462         if (!ai) {
463                 fr_strerror_printf("ip_hton failed to find requested information for host %.100s", src);
464                 freeaddrinfo(ai);
465                 return -1;
466         }
467
468         rcode = fr_sockaddr2ipaddr((struct sockaddr_storage *)ai->ai_addr,
469                                    ai->ai_addrlen, dst, NULL);
470         freeaddrinfo(ai);
471         if (!rcode) return -1;
472
473         return 0;
474 }
475
476 /*
477  *      Look IP addresses up, and print names (depending on DNS config)
478  */
479 char const *ip_ntoh(fr_ipaddr_t const *src, char *dst, size_t cnt)
480 {
481         struct sockaddr_storage ss;
482         int error;
483         socklen_t salen;
484
485         /*
486          *      No DNS lookups
487          */
488         if (!fr_dns_lookups) {
489                 return inet_ntop(src->af, &(src->ipaddr), dst, cnt);
490         }
491
492         if (!fr_ipaddr2sockaddr(src, 0, &ss, &salen)) {
493                 return NULL;
494         }
495
496         if ((error = getnameinfo((struct sockaddr *)&ss, salen, dst, cnt, NULL, 0,
497                                  NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
498                 fr_strerror_printf("ip_ntoh: %s", gai_strerror(error));
499                 return NULL;
500         }
501         return dst;
502 }
503
504
505 static char const *hextab = "0123456789abcdef";
506
507 /** Convert hex strings to binary data
508  *
509  * @param bin Buffer to write output to.
510  * @param hex input string.
511  * @param outlen length of output buffer (or length of input string / 2).
512  * @return length of data written to buffer.
513  */
514 size_t fr_hex2bin(uint8_t *bin, char const *hex, size_t outlen)
515 {
516         size_t i;
517         char *c1, *c2;
518
519         for (i = 0; i < outlen; i++) {
520                 if(!(c1 = memchr(hextab, tolower((int) hex[i << 1]), 16)) ||
521                    !(c2 = memchr(hextab, tolower((int) hex[(i << 1) + 1]), 16)))
522                         break;
523                  bin[i] = ((c1-hextab)<<4) + (c2-hextab);
524         }
525
526         return i;
527 }
528
529
530 /** Convert binary data to a hex string
531  *
532  * Ascii encoded hex string will not be prefixed with '0x'
533  *
534  * @warning If the output buffer isn't long enough, we have a buffer overflow.
535  *
536  * @param[out] hex Buffer to write hex output.
537  * @param[in] bin input.
538  * @param[in] inlen of bin input.
539  * @return length of data written to buffer.
540  */
541 size_t fr_bin2hex(char *hex, uint8_t const *bin, size_t inlen)
542 {
543         size_t i;
544
545         for (i = 0; i < inlen; i++) {
546                 hex[0] = hextab[((*bin) >> 4) & 0x0f];
547                 hex[1] = hextab[*bin & 0x0f];
548                 hex += 2;
549                 bin++;
550         }
551
552         *hex = '\0';
553         return inlen * 2;
554 }
555
556
557 /*
558  *      So we don't have ifdef's in the rest of the code
559  */
560 #ifndef HAVE_CLOSEFROM
561 int closefrom(int fd)
562 {
563         int i;
564         int maxfd = 256;
565
566 #ifdef _SC_OPEN_MAX
567         maxfd = sysconf(_SC_OPEN_MAX);
568         if (maxfd < 0) {
569           maxfd = 256;
570         }
571 #endif
572
573         if (fd > maxfd) return 0;
574
575         /*
576          *      FIXME: return EINTR?
577          *
578          *      Use F_CLOSEM?
579          */
580         for (i = fd; i < maxfd; i++) {
581                 close(i);
582         }
583
584         return 0;
585 }
586 #endif
587
588 int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
589 {
590         if (a->af < b->af) return -1;
591         if (a->af > b->af) return +1;
592
593         switch (a->af) {
594         case AF_INET:
595                 return memcmp(&a->ipaddr.ip4addr,
596                               &b->ipaddr.ip4addr,
597                               sizeof(a->ipaddr.ip4addr));
598                 break;
599
600 #ifdef HAVE_STRUCT_SOCKADDR_IN6
601         case AF_INET6:
602                 if (a->scope < b->scope) return -1;
603                 if (a->scope > b->scope) return +1;
604
605                 return memcmp(&a->ipaddr.ip6addr,
606                               &b->ipaddr.ip6addr,
607                               sizeof(a->ipaddr.ip6addr));
608                 break;
609 #endif
610
611         default:
612                 break;
613         }
614
615         return -1;
616 }
617
618 int fr_ipaddr2sockaddr(fr_ipaddr_t const *ipaddr, int port,
619                        struct sockaddr_storage *sa, socklen_t *salen)
620 {
621         if (ipaddr->af == AF_INET) {
622                 struct sockaddr_in s4;
623
624                 *salen = sizeof(s4);
625
626                 memset(&s4, 0, sizeof(s4));
627                 s4.sin_family = AF_INET;
628                 s4.sin_addr = ipaddr->ipaddr.ip4addr;
629                 s4.sin_port = htons(port);
630                 memset(sa, 0, sizeof(*sa));
631                 memcpy(sa, &s4, sizeof(s4));
632
633 #ifdef HAVE_STRUCT_SOCKADDR_IN6
634         } else if (ipaddr->af == AF_INET6) {
635                 struct sockaddr_in6 s6;
636
637                 *salen = sizeof(s6);
638
639                 memset(&s6, 0, sizeof(s6));
640                 s6.sin6_family = AF_INET6;
641                 s6.sin6_addr = ipaddr->ipaddr.ip6addr;
642                 s6.sin6_port = htons(port);
643                 s6.sin6_scope_id = ipaddr->scope;
644                 memset(sa, 0, sizeof(*sa));
645                 memcpy(sa, &s6, sizeof(s6));
646 #endif
647         } else {
648                 return 0;
649         }
650
651         return 1;
652 }
653
654
655 int fr_sockaddr2ipaddr(struct sockaddr_storage const *sa, socklen_t salen,
656                        fr_ipaddr_t *ipaddr, int *port)
657 {
658         if (sa->ss_family == AF_INET) {
659                 struct sockaddr_in      s4;
660
661                 if (salen < sizeof(s4)) {
662                         fr_strerror_printf("IPv4 address is too small");
663                         return 0;
664                 }
665
666                 memcpy(&s4, sa, sizeof(s4));
667                 ipaddr->af = AF_INET;
668                 ipaddr->ipaddr.ip4addr = s4.sin_addr;
669                 if (port) *port = ntohs(s4.sin_port);
670
671 #ifdef HAVE_STRUCT_SOCKADDR_IN6
672         } else if (sa->ss_family == AF_INET6) {
673                 struct sockaddr_in6     s6;
674
675                 if (salen < sizeof(s6)) {
676                         fr_strerror_printf("IPv6 address is too small");
677                         return 0;
678                 }
679
680                 memcpy(&s6, sa, sizeof(s6));
681                 ipaddr->af = AF_INET6;
682                 ipaddr->ipaddr.ip6addr = s6.sin6_addr;
683                 if (port) *port = ntohs(s6.sin6_port);
684                 ipaddr->scope = s6.sin6_scope_id;
685 #endif
686
687         } else {
688                 fr_strerror_printf("Unsupported address famility %d",
689                                    sa->ss_family);
690                 return 0;
691         }
692
693         return 1;
694 }
695
696 /** Convert UTF8 string to UCS2 encoding
697  *
698  * @note Borrowed from src/crypto/ms_funcs.c of wpa_supplicant project (http://hostap.epitest.fi/wpa_supplicant/)
699  *
700  * @param[out] out Where to write the ucs2 string.
701  * @param[in] outlen Size of output buffer.
702  * @param[in] in UTF8 string to convert.
703  * @param[in] inlen length of UTF8 string.
704  * @return the size of the UCS2 string written to the output buffer (in bytes).
705  */
706 ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
707 {
708         size_t i;
709         uint8_t *start = out;
710
711         for (i = 0; i < inlen; i++) {
712                 uint8_t c, c2, c3;
713
714                 c = in[i];
715                 if ((size_t)(out - start) >= outlen) {
716                         /* input too long */
717                         return -1;
718                 }
719
720                 /* One-byte encoding */
721                 if (c <= 0x7f) {
722                         FR_PUT_LE16(out, c);
723                         out += 2;
724                         continue;
725                 } else if ((i == (inlen - 1)) || ((size_t)(out - start) >= (outlen - 1))) {
726                         /* Incomplete surrogate */
727                         return -1;
728                 }
729
730                 c2 = in[++i];
731                 /* Two-byte encoding */
732                 if ((c & 0xe0) == 0xc0) {
733                         FR_PUT_LE16(out, ((c & 0x1f) << 6) | (c2 & 0x3f));
734                         out += 2;
735                         continue;
736                 }
737                 if ((i == inlen) || ((size_t)(out - start) >= (outlen - 1))) {
738                         /* Incomplete surrogate */
739                         return -1;
740                 }
741
742                 /* Three-byte encoding */
743                 c3 = in[++i];
744                 FR_PUT_LE16(out, ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));
745                 out += 2;
746         }
747
748         return out - start;
749 }
750