Revert "Rename authorized_identity in authenticated_identity for clarity sake."
[platform/upstream/dbus.git] / dbus / dbus-sysdeps.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps.c Wrappers around system/libc features shared between UNIX and Windows (internal to D-Bus implementation)
3  * 
4  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-sysdeps.h"
28 #include "dbus-threads.h"
29 #include "dbus-protocol.h"
30 #include "dbus-string.h"
31 #include "dbus-list.h"
32
33 /* NOTE: If you include any unix/windows-specific headers here, you are probably doing something
34  * wrong and should be putting some code in dbus-sysdeps-unix.c or dbus-sysdeps-win.c.
35  *
36  * These are the standard ANSI C headers...
37  */
38 #if HAVE_LOCALE_H
39 #include <locale.h>
40 #endif
41 #include <stdlib.h>
42 #include <string.h>
43 #include <stdio.h>
44
45 #ifdef HAVE_ERRNO_H
46 #include <errno.h>
47 #endif
48
49 #ifdef DBUS_WIN
50   #include <stdlib.h>
51 #elif (defined __APPLE__)
52 # include <crt_externs.h>
53 # define environ (*_NSGetEnviron())
54 #else
55 extern char **environ;
56 #endif
57
58 /**
59  * @defgroup DBusSysdeps Internal system-dependent API
60  * @ingroup DBusInternals
61  * @brief Internal system-dependent API available on UNIX and Windows
62  *
63  * The system-dependent API has a dual purpose. First, it encapsulates
64  * all usage of operating system APIs for ease of auditing and to
65  * avoid cluttering the rest of the code with bizarre OS quirks and
66  * headers. Second, it abstracts different operating system APIs for
67  * portability.
68  * 
69  * @{
70  */
71
72 /**
73  * Aborts the program with SIGABRT (dumping core).
74  */
75 void
76 _dbus_abort (void)
77 {
78   const char *s;
79   
80   _dbus_print_backtrace ();
81   
82   s = _dbus_getenv ("DBUS_BLOCK_ON_ABORT");
83   if (s && *s)
84     {
85       /* don't use _dbus_warn here since it can _dbus_abort() */
86       fprintf (stderr, "  Process %lu sleeping for gdb attach\n", _dbus_pid_for_log ());
87       _dbus_sleep_milliseconds (1000 * 180);
88     }
89   
90   abort ();
91   _dbus_exit (1); /* in case someone manages to ignore SIGABRT ? */
92 }
93
94 /**
95  * Wrapper for setenv(). If the value is #NULL, unsets
96  * the environment variable.
97  *
98  * There is an unfixable memleak in that it is unsafe to
99  * free memory malloced for use with setenv. This is because
100  * we can not rely on internal implementation details of
101  * the underlying libc library.
102  *
103  * @param varname name of environment variable
104  * @param value value of environment variable
105  * @returns #TRUE on success.
106  */
107 dbus_bool_t
108 _dbus_setenv (const char *varname,
109               const char *value)
110 {
111   _dbus_assert (varname != NULL);
112   
113   if (value == NULL)
114     {
115 #ifdef HAVE_UNSETENV
116       unsetenv (varname);
117       return TRUE;
118 #else
119       char *putenv_value;
120       size_t len;
121
122       len = strlen (varname);
123
124       /* Use system malloc to avoid memleaks that dbus_malloc
125        * will get upset about.
126        */
127       
128       putenv_value = malloc (len + 2);
129       if (putenv_value == NULL)
130         return FALSE;
131
132       strcpy (putenv_value, varname);
133 #if defined(DBUS_WIN)
134       strcat (putenv_value, "=");
135 #endif
136       
137       return (putenv (putenv_value) == 0);
138 #endif
139     }
140   else
141     {
142 #ifdef HAVE_SETENV
143       return (setenv (varname, value, TRUE) == 0);
144 #else
145       char *putenv_value;
146       size_t len;
147       size_t varname_len;
148       size_t value_len;
149
150       varname_len = strlen (varname);
151       value_len = strlen (value);
152       
153       len = varname_len + value_len + 1 /* '=' */ ;
154
155       /* Use system malloc to avoid memleaks that dbus_malloc
156        * will get upset about.
157        */
158       
159       putenv_value = malloc (len + 1);
160       if (putenv_value == NULL)
161         return FALSE;
162
163       strcpy (putenv_value, varname);
164       strcpy (putenv_value + varname_len, "=");
165       strcpy (putenv_value + varname_len + 1, value);
166       
167       return (putenv (putenv_value) == 0);
168 #endif
169     }
170 }
171
172 /**
173  * Wrapper for getenv().
174  *
175  * @param varname name of environment variable
176  * @returns value of environment variable or #NULL if unset
177  */
178 const char*
179 _dbus_getenv (const char *varname)
180 {  
181   /* Don't respect any environment variables if the current process is
182    * setuid.  This is the equivalent of glibc's __secure_getenv().
183    */
184   if (_dbus_check_setuid ())
185     return NULL;
186   return getenv (varname);
187 }
188
189 /**
190  * Wrapper for clearenv().
191  *
192  * @returns #TRUE on success.
193  */
194 dbus_bool_t
195 _dbus_clearenv (void)
196 {
197   dbus_bool_t rc = TRUE;
198
199 #ifdef HAVE_CLEARENV
200   if (clearenv () != 0)
201      rc = FALSE;
202 #else
203
204   if (environ != NULL)
205     environ[0] = NULL;
206 #endif
207
208   return rc;
209 }
210
211 /**
212  * Split paths into a list of char strings
213  * 
214  * @param dirs string with pathes 
215  * @param suffix string concated to each path in dirs
216  * @param dir_list contains a list of splitted pathes
217  * return #TRUE is pathes could be splittes,#FALSE in oom case 
218  */
219 dbus_bool_t
220 _dbus_split_paths_and_append (DBusString *dirs, 
221                               const char *suffix, 
222                               DBusList  **dir_list)
223 {
224    int start;
225    int i;
226    int len;
227    char *cpath;
228    DBusString file_suffix;
229
230    start = 0;
231    i = 0;
232
233    _dbus_string_init_const (&file_suffix, suffix);
234
235    len = _dbus_string_get_length (dirs);
236
237    while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
238      {
239        DBusString path;
240
241        if (!_dbus_string_init (&path))
242           goto oom;
243
244        if (!_dbus_string_copy_len (dirs,
245                                    start,
246                                    i - start,
247                                    &path,
248                                    0))
249           {
250             _dbus_string_free (&path);
251             goto oom;
252           }
253
254         _dbus_string_chop_white (&path);
255
256         /* check for an empty path */
257         if (_dbus_string_get_length (&path) == 0)
258           goto next;
259
260         if (!_dbus_concat_dir_and_file (&path,
261                                         &file_suffix))
262           {
263             _dbus_string_free (&path);
264             goto oom;
265           }
266
267         if (!_dbus_string_copy_data(&path, &cpath))
268           {
269             _dbus_string_free (&path);
270             goto oom;
271           }
272
273         if (!_dbus_list_append (dir_list, cpath))
274           {
275             _dbus_string_free (&path);              
276             dbus_free (cpath);
277             goto oom;
278           }
279
280        next:
281         _dbus_string_free (&path);
282         start = i + 1;
283     } 
284       
285   if (start != len)
286     { 
287       DBusString path;
288
289       if (!_dbus_string_init (&path))
290         goto oom;
291
292       if (!_dbus_string_copy_len (dirs,
293                                   start,
294                                   len - start,
295                                   &path,
296                                   0))
297         {
298           _dbus_string_free (&path);
299           goto oom;
300         }
301
302       if (!_dbus_concat_dir_and_file (&path,
303                                       &file_suffix))
304         {
305           _dbus_string_free (&path);
306           goto oom;
307         }
308
309       if (!_dbus_string_copy_data(&path, &cpath))
310         {
311           _dbus_string_free (&path);
312           goto oom;
313         }
314
315       if (!_dbus_list_append (dir_list, cpath))
316         {
317           _dbus_string_free (&path);              
318           dbus_free (cpath);
319           goto oom;
320         }
321
322       _dbus_string_free (&path); 
323     }
324
325   return TRUE;
326
327  oom:
328   _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); 
329   _dbus_list_clear (dir_list);
330   return FALSE;
331 }
332
333 /** @} */
334
335 /**
336  * @addtogroup DBusString
337  *
338  * @{
339  */
340 /**
341  * Appends an integer to a DBusString.
342  * 
343  * @param str the string
344  * @param value the integer value
345  * @returns #FALSE if not enough memory or other failure.
346  */
347 dbus_bool_t
348 _dbus_string_append_int (DBusString *str,
349                          long        value)
350 {
351   /* this calculation is from comp.lang.c faq */
352 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)  /* +1 for '-' */
353   int orig_len;
354   int i;
355   char *buf;
356   
357   orig_len = _dbus_string_get_length (str);
358
359   if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
360     return FALSE;
361
362   buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
363
364   snprintf (buf, MAX_LONG_LEN, "%ld", value);
365
366   i = 0;
367   while (*buf)
368     {
369       ++buf;
370       ++i;
371     }
372   
373   _dbus_string_shorten (str, MAX_LONG_LEN - i);
374   
375   return TRUE;
376 }
377
378 /**
379  * Appends an unsigned integer to a DBusString.
380  * 
381  * @param str the string
382  * @param value the integer value
383  * @returns #FALSE if not enough memory or other failure.
384  */
385 dbus_bool_t
386 _dbus_string_append_uint (DBusString    *str,
387                           unsigned long  value)
388 {
389   /* this is wrong, but definitely on the high side. */
390 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
391   int orig_len;
392   int i;
393   char *buf;
394   
395   orig_len = _dbus_string_get_length (str);
396
397   if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
398     return FALSE;
399
400   buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
401
402   snprintf (buf, MAX_ULONG_LEN, "%lu", value);
403
404   i = 0;
405   while (*buf)
406     {
407       ++buf;
408       ++i;
409     }
410   
411   _dbus_string_shorten (str, MAX_ULONG_LEN - i);
412   
413   return TRUE;
414 }
415
416 /**
417  * Parses an integer contained in a DBusString. Either return parameter
418  * may be #NULL if you aren't interested in it. The integer is parsed
419  * and stored in value_return. Return parameters are not initialized
420  * if the function returns #FALSE.
421  *
422  * @param str the string
423  * @param start the byte index of the start of the integer
424  * @param value_return return location of the integer value or #NULL
425  * @param end_return return location of the end of the integer, or #NULL
426  * @returns #TRUE on success
427  */
428 dbus_bool_t
429 _dbus_string_parse_int (const DBusString *str,
430                         int               start,
431                         long             *value_return,
432                         int              *end_return)
433 {
434   long v;
435   const char *p;
436   char *end;
437
438   p = _dbus_string_get_const_data_len (str, start,
439                                        _dbus_string_get_length (str) - start);
440
441   end = NULL;
442   _dbus_set_errno_to_zero ();
443   v = strtol (p, &end, 0);
444   if (end == NULL || end == p || errno != 0)
445     return FALSE;
446
447   if (value_return)
448     *value_return = v;
449   if (end_return)
450     *end_return = start + (end - p);
451
452   return TRUE;
453 }
454
455 /**
456  * Parses an unsigned integer contained in a DBusString. Either return
457  * parameter may be #NULL if you aren't interested in it. The integer
458  * is parsed and stored in value_return. Return parameters are not
459  * initialized if the function returns #FALSE.
460  *
461  * @param str the string
462  * @param start the byte index of the start of the integer
463  * @param value_return return location of the integer value or #NULL
464  * @param end_return return location of the end of the integer, or #NULL
465  * @returns #TRUE on success
466  */
467 dbus_bool_t
468 _dbus_string_parse_uint (const DBusString *str,
469                          int               start,
470                          unsigned long    *value_return,
471                          int              *end_return)
472 {
473   unsigned long v;
474   const char *p;
475   char *end;
476
477   p = _dbus_string_get_const_data_len (str, start,
478                                        _dbus_string_get_length (str) - start);
479
480   end = NULL;
481   _dbus_set_errno_to_zero ();
482   v = strtoul (p, &end, 0);
483   if (end == NULL || end == p || errno != 0)
484     return FALSE;
485
486   if (value_return)
487     *value_return = v;
488   if (end_return)
489     *end_return = start + (end - p);
490
491   return TRUE;
492 }
493
494 /** @} */ /* DBusString group */
495
496 /**
497  * @addtogroup DBusInternalsUtils
498  * @{
499  */
500
501 void
502 _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
503                                           int   n_bytes)
504 {
505   long tv_usec;
506   int i;
507   
508   /* fall back to pseudorandom */
509   _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
510                  n_bytes);
511   
512   _dbus_get_real_time (NULL, &tv_usec);
513   srand (tv_usec);
514   
515   i = 0;
516   while (i < n_bytes)
517     {
518       double r;
519       unsigned int b;
520           
521       r = rand ();
522       b = (r / (double) RAND_MAX) * 255.0;
523
524       buffer[i] = b;
525
526       ++i;
527     }
528 }
529
530 /**
531  * Fills n_bytes of the given buffer with random bytes.
532  *
533  * @param buffer an allocated buffer
534  * @param n_bytes the number of bytes in buffer to write to
535  */
536 void
537 _dbus_generate_random_bytes_buffer (char *buffer,
538                                     int   n_bytes)
539 {
540   DBusString str;
541
542   if (!_dbus_string_init (&str))
543     {
544       _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
545       return;
546     }
547
548   if (!_dbus_generate_random_bytes (&str, n_bytes))
549     {
550       _dbus_string_free (&str);
551       _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
552       return;
553     }
554
555   _dbus_string_copy_to_buffer (&str, buffer, n_bytes);
556
557   _dbus_string_free (&str);
558 }
559
560 /**
561  * Generates the given number of random bytes, where the bytes are
562  * chosen from the alphanumeric ASCII subset.
563  *
564  * @param str the string
565  * @param n_bytes the number of random ASCII bytes to append to string
566  * @returns #TRUE on success, #FALSE if no memory or other failure
567  */
568 dbus_bool_t
569 _dbus_generate_random_ascii (DBusString *str,
570                              int         n_bytes)
571 {
572   static const char letters[] =
573     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
574   int i;
575   int len;
576   
577   if (!_dbus_generate_random_bytes (str, n_bytes))
578     return FALSE;
579   
580   len = _dbus_string_get_length (str);
581   i = len - n_bytes;
582   while (i < len)
583     {
584       _dbus_string_set_byte (str, i,
585                              letters[_dbus_string_get_byte (str, i) %
586                                      (sizeof (letters) - 1)]);
587
588       ++i;
589     }
590
591   _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
592                                              n_bytes));
593
594   return TRUE;
595 }
596
597 /**
598  * Converts a UNIX errno, or Windows errno or WinSock error value into
599  * a #DBusError name.
600  *
601  * @todo should cover more errnos, specifically those
602  * from open().
603  * 
604  * @param error_number the errno.
605  * @returns an error name
606  */
607 const char*
608 _dbus_error_from_errno (int error_number)
609 {
610   switch (error_number)
611     {
612     case 0:
613       return DBUS_ERROR_FAILED;
614       
615 #ifdef EPROTONOSUPPORT
616     case EPROTONOSUPPORT:
617       return DBUS_ERROR_NOT_SUPPORTED;
618 #elif defined(WSAEPROTONOSUPPORT)
619     case WSAEPROTONOSUPPORT:
620       return DBUS_ERROR_NOT_SUPPORTED;
621 #endif
622 #ifdef EAFNOSUPPORT
623     case EAFNOSUPPORT:
624       return DBUS_ERROR_NOT_SUPPORTED;
625 #elif defined(WSAEAFNOSUPPORT)
626     case WSAEAFNOSUPPORT:
627       return DBUS_ERROR_NOT_SUPPORTED;
628 #endif
629 #ifdef ENFILE
630     case ENFILE:
631       return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
632 #endif
633 #ifdef EMFILE
634     case EMFILE:
635       return DBUS_ERROR_LIMITS_EXCEEDED;
636 #endif
637 #ifdef EACCES
638     case EACCES:
639       return DBUS_ERROR_ACCESS_DENIED;
640 #endif
641 #ifdef EPERM
642     case EPERM:
643       return DBUS_ERROR_ACCESS_DENIED;
644 #endif
645 #ifdef ENOBUFS
646     case ENOBUFS:
647       return DBUS_ERROR_NO_MEMORY;
648 #endif
649 #ifdef ENOMEM
650     case ENOMEM:
651       return DBUS_ERROR_NO_MEMORY;
652 #endif
653 #ifdef ECONNREFUSED
654     case ECONNREFUSED:
655       return DBUS_ERROR_NO_SERVER;
656 #elif defined(WSAECONNREFUSED)
657     case WSAECONNREFUSED:
658       return DBUS_ERROR_NO_SERVER;
659 #endif
660 #ifdef ETIMEDOUT
661     case ETIMEDOUT:
662       return DBUS_ERROR_TIMEOUT;
663 #elif defined(WSAETIMEDOUT)
664     case WSAETIMEDOUT:
665       return DBUS_ERROR_TIMEOUT;
666 #endif
667 #ifdef ENETUNREACH
668     case ENETUNREACH:
669       return DBUS_ERROR_NO_NETWORK;
670 #elif defined(WSAENETUNREACH)
671     case WSAENETUNREACH:
672       return DBUS_ERROR_NO_NETWORK;
673 #endif
674 #ifdef EADDRINUSE
675     case EADDRINUSE:
676       return DBUS_ERROR_ADDRESS_IN_USE;
677 #elif defined(WSAEADDRINUSE)
678     case WSAEADDRINUSE:
679       return DBUS_ERROR_ADDRESS_IN_USE;
680 #endif
681 #ifdef EEXIST
682     case EEXIST:
683       return DBUS_ERROR_FILE_EXISTS;
684 #endif
685 #ifdef ENOENT
686     case ENOENT:
687       return DBUS_ERROR_FILE_NOT_FOUND;
688 #endif
689     }
690
691   return DBUS_ERROR_FAILED;
692 }
693
694 /**
695  * Converts the current system errno value into a #DBusError name.
696  *
697  * @returns an error name
698  */
699 const char*
700 _dbus_error_from_system_errno (void)
701 {
702   return _dbus_error_from_errno (errno);
703 }
704
705 /**
706  * Assign 0 to the global errno variable
707  */
708 void
709 _dbus_set_errno_to_zero (void)
710 {
711 #ifdef DBUS_WINCE
712   SetLastError (0);
713 #else
714   errno = 0;
715 #endif
716 }
717
718 /**
719  * See if errno is set
720  * @returns #TRUE if errno is not 0
721  */
722 dbus_bool_t
723 _dbus_get_is_errno_nonzero (void)
724 {
725   return errno != 0;
726 }
727
728 /**
729  * See if errno is ENOMEM
730  * @returns #TRUE if errno == ENOMEM
731  */
732 dbus_bool_t
733 _dbus_get_is_errno_enomem (void)
734 {
735   return errno == ENOMEM;
736 }
737
738 /**
739  * See if errno is EINTR
740  * @returns #TRUE if errno == EINTR
741  */
742 dbus_bool_t
743 _dbus_get_is_errno_eintr (void)
744 {
745   return errno == EINTR;
746 }
747
748 /**
749  * See if errno is EPIPE
750  * @returns #TRUE if errno == EPIPE
751  */
752 dbus_bool_t
753 _dbus_get_is_errno_epipe (void)
754 {
755   return errno == EPIPE;
756 }
757
758 /**
759  * Get error message from errno
760  * @returns _dbus_strerror(errno)
761  */
762 const char*
763 _dbus_strerror_from_errno (void)
764 {
765   return _dbus_strerror (errno);
766 }
767
768 /** @} end of sysdeps */
769
770 /* tests in dbus-sysdeps-util.c */