The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
misc.c
Go to the documentation of this file.
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /** Various miscellaneous utility functions
18  *
19  * @file src/lib/util/misc.c
20  *
21  * @copyright 2000,2006 The FreeRADIUS server project
22  */
23 RCSID("$Id: b20d703963b162c9196c6958a732aa2950b29658 $")
24 
25 #include <freeradius-devel/util/dbuff.h>
26 #include <freeradius-devel/util/sbuff.h>
27 #include <freeradius-devel/util/syserror.h>
28 
29 #include <fcntl.h>
30 #include <grp.h>
31 #include <pwd.h>
32 #include <sys/file.h>
33 #include <sys/stat.h>
34 #include <sys/uio.h>
35 
36 #define FR_PUT_LE16(a, val)\
37  do {\
38  a[1] = ((uint16_t) (val)) >> 8;\
39  a[0] = ((uint16_t) (val)) & 0xff;\
40  } while (0)
41 
42 /** Sets a signal handler using sigaction if available, else signal
43  *
44  * @param sig to set handler for.
45  * @param func handler to set.
46  */
47 int fr_set_signal(int sig, sig_t func)
48 {
49 #ifdef HAVE_SIGACTION
50  struct sigaction act;
51 
52  memset(&act, 0, sizeof(act));
53  act.sa_flags = 0;
54  sigemptyset(&act.sa_mask);
55  act.sa_handler = func;
56 
57  if (sigaction(sig, &act, NULL) < 0) {
58  fr_strerror_printf("Failed setting signal %i handler via sigaction(): %s", sig, fr_syserror(errno));
59  return -1;
60  }
61 #else
62  if (signal(sig, func) < 0) {
63  fr_strerror_printf("Failed setting signal %i handler via signal(): %s", sig, fr_syserror(errno));
64  return -1;
65  }
66 #endif
67  return 0;
68 }
69 
70 /** Uninstall a signal for a specific handler
71  *
72  * man sigaction says these are fine to call from a signal handler.
73  *
74  * @param sig SIGNAL
75  */
76 int fr_unset_signal(int sig)
77 {
78 #ifdef HAVE_SIGACTION
79  struct sigaction act;
80 
81  memset(&act, 0, sizeof(act));
82  act.sa_flags = 0;
83  sigemptyset(&act.sa_mask);
84  act.sa_handler = SIG_DFL;
85 
86  return sigaction(sig, &act, NULL);
87 #else
88  return signal(sig, SIG_DFL);
89 #endif
90 }
91 
92 #ifndef F_WRLCK
93 #error "missing definition for F_WRLCK, all file locks will fail"
94 #endif
95 
96 /*
97  * cppcheck apparently can't pick this up from the system headers.
98  */
99 #ifdef CPPCHECK
100 #define F_WRLCK
101 #endif
102 
103 static int rad_lock(int fd, int lock_len, int cmd, int type)
104 {
105  struct flock fl;
106 
107  fl.l_start = 0;
108  fl.l_len = lock_len;
109  fl.l_pid = getpid();
110  fl.l_type = type;
111  fl.l_whence = SEEK_CUR;
112 
113  return fcntl(fd, cmd, (void *)&fl);
114 }
115 
116 /*
117  * Internal wrapper for locking, to minimize the number of ifdef's
118  */
119 int rad_lockfd(int fd, int lock_len)
120 {
121  return rad_lock(fd, lock_len, F_SETLKW, F_WRLCK);
122 }
123 
124 /*
125  * Internal wrapper for locking, to minimize the number of ifdef's
126  *
127  * Nonblocking version.
128  */
129 int rad_lockfd_nonblock(int fd, int lock_len)
130 {
131  /*
132  * Note that there's no "W" on SETLK
133  */
134  return rad_lock(fd, lock_len, F_SETLK, F_WRLCK);
135 }
136 
137 /*
138  * Internal wrapper for unlocking, to minimize the number of ifdef's
139  * in the source.
140  */
141 int rad_unlockfd(int fd, int lock_len)
142 {
143  /*
144  * Note UNLOCK.
145  */
146  return rad_lock(fd, lock_len, F_SETLK, F_UNLCK);
147 }
148 
149 /** Consume the integer (or hex) portion of a value string
150  *
151  * Allows integer or hex representations of integers (but not octal,
152  * as octal is deemed to be confusing).
153  *
154  * @param[out] out Result of parsing string as unsigned 64bit integer.
155  * @param[out] end pointer to the first non numeric char.
156  * @param[in] value string to parse.
157  *
158  * @return integer value.
159  */
160 int fr_strtoull(uint64_t *out, char **end, char const *value)
161 {
162  errno = 0; /* Explicitly clear errors, as glibc appears not to do this */
163 
164  if ((value[0] == '0') && (value[1] == 'x')) {
165  *out = strtoull(value, end, 16);
166  if (errno == ERANGE) {
167  error:
168  fr_strerror_printf("Unsigned integer value \"%s\" too large, would overflow", value);
169  return -1;
170  }
171  return 0;
172  }
173 
174  *out = strtoull(value, end, 10);
175  if (errno == ERANGE) goto error;
176  return 0;
177 }
178 
179 /** Consume the integer (or hex) portion of a value string
180  *
181  * Allows integer or hex representations of integers (but not octal,
182  * as octal is deemed to be confusing).
183  *
184  * @note Check for overflow with errno == ERANGE.
185  *
186  * @param[out] out Result of parsing string as signed 64bit integer.
187  * @param[out] end pointer to the first non numeric char.
188  * @param[in] value string to parse.
189  * @return integer value.
190  */
191 int fr_strtoll(int64_t *out, char **end, char const *value)
192 {
193  errno = 0; /* Explicitly clear errors, as glibc appears not to do this */
194 
195  if ((value[0] == '0') && (value[1] == 'x')) {
196  *out = strtoll(value, end, 16);
197  if (errno == ERANGE) {
198  error:
199  fr_strerror_printf("Signed integer value \"%s\" too large, would overflow", value);
200  return -1;
201  }
202  return 0;
203  }
204 
205  *out = strtoll(value, end, 10);
206  if (errno == ERANGE) goto error;
207  return 0;
208 }
209 
210 /** Trim whitespace from the end of a string
211  *
212  */
213 char *fr_trim(char const *str, size_t size)
214 {
215  char *q;
216 
217  if (!str || !size) return NULL;
218 
219  memcpy(&q, &str, sizeof(q));
220  for (q = q + size; q > str && isspace((uint8_t) *q); q--);
221 
222  return q;
223 }
224 
225 char *fr_tolower(char *str)
226 {
227  char *p;
228 
229  for (p = str; *p != '\0'; p++) *p = tolower(*p);
230 
231  return str;
232 }
233 
234 #ifdef O_NONBLOCK
235 /** Set O_NONBLOCK on a socket
236  *
237  * @note O_NONBLOCK is POSIX.
238  *
239  * @param fd to set nonblocking flag on.
240  * @return
241  * - Flags set on the socket.
242  * - -1 on failure.
243  */
244 int fr_nonblock(int fd)
245 {
246  int flags;
247 
248  flags = fcntl(fd, F_GETFL, NULL);
249  if (flags < 0) {
250  fr_strerror_printf("Failed getting socket flags: %s", fr_syserror(errno));
251  return -1;
252  }
253 
254  flags |= O_NONBLOCK;
255  if (fcntl(fd, F_SETFL, flags) < 0) {
256  fr_strerror_printf("Failed setting socket flags: %s", fr_syserror(errno));
257  return -1;
258  }
259 
260  return flags;
261 }
262 
263 /** Unset O_NONBLOCK on a socket
264  *
265  * @note O_NONBLOCK is POSIX.
266  *
267  * @param fd to set nonblocking flag on.
268  * @return
269  * - Flags set on the socket.
270  * - -1 on failure.
271  */
272 int fr_blocking(int fd)
273 {
274  int flags;
275 
276  flags = fcntl(fd, F_GETFL, NULL);
277  if (flags < 0) {
278  fr_strerror_printf("Failed getting socket flags: %s", fr_syserror(errno));
279  return -1;
280  }
281 
282  if (!(flags & O_NONBLOCK)) return flags;
283 
284  flags ^= O_NONBLOCK;
285  if (fcntl(fd, F_SETFL, flags) < 0) {
286  fr_strerror_printf("Failed setting socket flags: %s", fr_syserror(errno));
287  return -1;
288  }
289 
290  return flags;
291 }
292 #else
293 int fr_nonblock(UNUSED int fd)
294 {
295  fr_strerror_const("Non blocking sockets are not supported");
296  return -1;
297 }
298 int fr_blocking(UNUSED int fd)
299 {
300  fr_strerror_const("Non blocking sockets are not supported");
301  return -1;
302 }
303 #endif
304 
305 /** Convert UTF8 string to UCS2 encoding
306  *
307  * @note Borrowed from src/crypto/ms_funcs.c of wpa_supplicant project (http://hostap.epitest.fi/wpa_supplicant/)
308  *
309  * @param[out] out Where to write the ucs2 string.
310  * @param[in] outlen Size of output buffer.
311  * @param[in] in UTF8 string to convert.
312  * @param[in] inlen length of UTF8 string.
313  * @return the size of the UCS2 string written to the output buffer (in bytes).
314  */
315 ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
316 {
317  size_t i;
318  uint8_t *start = out;
319 
320  for (i = 0; i < inlen; i++) {
321  uint8_t c, c2, c3;
322 
323  c = in[i];
324  if ((size_t)(out - start) >= outlen) {
325  /* input too long */
326  return -1;
327  }
328 
329  /* One-byte encoding */
330  if (c <= 0x7f) {
331  out[0] = (uint8_t)c;
332  out[1] = 0;
333  out += 2;
334  continue;
335  } else if ((i == (inlen - 1)) || ((size_t)(out - start) >= (outlen - 1))) {
336  /* Incomplete surrogate */
337  return -1;
338  }
339 
340  c2 = in[++i];
341  /* Two-byte encoding */
342  if ((c & 0xe0) == 0xc0) {
343  FR_PUT_LE16(out, ((c & 0x1f) << 6) | (c2 & 0x3f));
344  out += 2;
345  continue;
346  }
347  if ((i == inlen) || ((size_t)(out - start) >= (outlen - 1))) {
348  /* Incomplete surrogate */
349  return -1;
350  }
351 
352  /* Three-byte encoding */
353  c3 = in[++i];
354  FR_PUT_LE16(out, ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f));
355  out += 2;
356  }
357 
358  return out - start;
359 }
360 
361 /** Write 128bit unsigned integer to buffer
362  *
363  * @author Alexey Frunze
364  *
365  * @param out where to write result to.
366  * @param outlen size of out.
367  * @param num 128 bit integer.
368  */
369 size_t fr_snprint_uint128(char *out, size_t outlen, uint128_t const num)
370 {
371  char buff[] = "00000000000000000000000000000000000000000000";
372  uint64_t n[2];
373  char *p = buff;
374  int i;
375 #ifndef WORDS_BIGENDIAN
376  size_t const l = 0;
377  size_t const h = 1;
378 #else
379  size_t const l = 1;
380  size_t const h = 0;
381 #endif
382 
383  memcpy(n, &num, sizeof(n));
384 
385  for (i = 0; i < 128; i++) {
386  ssize_t j;
387  int carry;
388 
389  carry = (n[h] >= 0x8000000000000000);
390 
391  // Shift n[] left, doubling it
392  n[h] = ((n[h] << 1) & 0xffffffffffffffff) + (n[l] >= 0x8000000000000000);
393  n[l] = ((n[l] << 1) & 0xffffffffffffffff);
394 
395  // Add s[] to itself in float, doubling it
396  for (j = sizeof(buff) - 2; j >= 0; j--) {
397  buff[j] += buff[j] - '0' + carry;
398  carry = (buff[j] > '9');
399  if (carry) buff[j] -= 10;
400  }
401  }
402 
403  while ((*p == '0') && (p < &buff[sizeof(buff) - 2])) p++;
404 
405  return strlcpy(out, p, outlen);
406 }
407 
408 /** Compares two pointers
409  *
410  * @param a first pointer to compare.
411  * @param b second pointer to compare.
412  * @return
413  * - -1 if a < b.
414  * - +1 if b > a.
415  * - 0 if both equal.
416  */
417 int8_t fr_pointer_cmp(void const *a, void const *b)
418 {
419  return CMP(a, b);
420 }
421 
422 /** Quick sort an array of pointers using a comparator
423  *
424  * @param to_sort array of pointers to sort.
425  * @param start the lowest index (usually 0).
426  * @param end the length of the array.
427  * @param cmp the comparison function to use to sort the array elements.
428  */
429 void fr_quick_sort(void const *to_sort[], int start, int end, fr_cmp_t cmp)
430 {
431  int i, pi;
432  void const *pivot;
433 
434  if (start >= end) return;
435 
436 #define SWAP(_a, _b) \
437  do { \
438  void const *_tmp = to_sort[_a]; \
439  to_sort[_a] = to_sort[_b]; \
440  to_sort[_b] = _tmp; \
441  } while (0)
442 
443  pivot = to_sort[end];
444  for (pi = start, i = start; i < end; i++) {
445  if (cmp(to_sort[i], pivot) < 0) {
446  SWAP(i , pi);
447  pi++;
448  }
449  }
450  SWAP(end, pi);
451 
452  fr_quick_sort(to_sort, start, pi - 1, cmp);
453  fr_quick_sort(to_sort, pi + 1, end, cmp);
454 }
455 
456 #ifdef TALLOC_DEBUG
457 void fr_talloc_verify_cb(UNUSED const void *ptr, UNUSED int depth,
458  UNUSED int max_depth, UNUSED int is_ref,
459  UNUSED void *private_data)
460 {
461  /* do nothing */
462 }
463 #endif
464 
465 
466 /** Do a comparison of two authentication digests by comparing the FULL data.
467  *
468  * Otherwise, the server can be subject to timing attacks.
469  *
470  * http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf
471  */
472 int fr_digest_cmp(uint8_t const *a, uint8_t const *b, size_t length)
473 {
474  int result = 0;
475  size_t i;
476 
477  for (i = 0; i < length; i++) result |= a[i] ^ b[i];
478 
479  return result; /* 0 is OK, !0 is !OK, just like memcmp */
480 }
int n
Definition: acutest.h:577
#define RCSID(id)
Definition: build.h:481
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition: build.h:110
#define UNUSED
Definition: build.h:313
static fr_slen_t in
Definition: dict.h:821
Test enumeration values.
Definition: dict_test.h:92
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
unsigned long int size_t
Definition: merged_model.c:25
static uint8_t depth(fr_minmax_heap_index_t i)
Definition: minmax_heap.c:83
void fr_quick_sort(void const *to_sort[], int start, int end, fr_cmp_t cmp)
Quick sort an array of pointers using a comparator.
Definition: misc.c:429
int fr_unset_signal(int sig)
Uninstall a signal for a specific handler.
Definition: misc.c:76
char * fr_trim(char const *str, size_t size)
Trim whitespace from the end of a string.
Definition: misc.c:213
int fr_strtoull(uint64_t *out, char **end, char const *value)
Consume the integer (or hex) portion of a value string.
Definition: misc.c:160
int fr_set_signal(int sig, sig_t func)
Sets a signal handler using sigaction if available, else signal.
Definition: misc.c:47
#define FR_PUT_LE16(a, val)
Definition: misc.c:36
int rad_unlockfd(int fd, int lock_len)
Definition: misc.c:141
int fr_nonblock(UNUSED int fd)
Definition: misc.c:293
char * fr_tolower(char *str)
Definition: misc.c:225
#define SWAP(_a, _b)
ssize_t fr_utf8_to_ucs2(uint8_t *out, size_t outlen, char const *in, size_t inlen)
Convert UTF8 string to UCS2 encoding.
Definition: misc.c:315
int fr_strtoll(int64_t *out, char **end, char const *value)
Consume the integer (or hex) portion of a value string.
Definition: misc.c:191
int8_t fr_pointer_cmp(void const *a, void const *b)
Compares two pointers.
Definition: misc.c:417
static int rad_lock(int fd, int lock_len, int cmd, int type)
Definition: misc.c:103
int rad_lockfd(int fd, int lock_len)
Definition: misc.c:119
int rad_lockfd_nonblock(int fd, int lock_len)
Definition: misc.c:129
int fr_blocking(UNUSED int fd)
Definition: misc.c:298
size_t fr_snprint_uint128(char *out, size_t outlen, uint128_t const num)
Write 128bit unsigned integer to buffer.
Definition: misc.c:369
int fr_digest_cmp(uint8_t const *a, uint8_t const *b, size_t length)
Do a comparison of two authentication digests by comparing the FULL data.
Definition: misc.c:472
int8_t(* fr_cmp_t)(void const *a, void const *b)
Definition: misc.h:38
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
fr_aka_sim_id_type_t type
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:34
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define fr_strerror_const(_msg)
Definition: strerror.h:223
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:997
static size_t char ** out
Definition: value.h:997