Imported Upstream version 2.66.6
[platform/upstream/glib.git] / gio / gdbusdaemon.c
1 #include "config.h"
2
3 #include <string.h>
4 #include <stdlib.h>
5
6 #include <gstdio.h>
7 #include <gio/gio.h>
8 #include <gio/gunixsocketaddress.h>
9 #include "gdbusdaemon.h"
10 #include "glibintl.h"
11
12 #include "gdbus-daemon-generated.h"
13
14 #define DBUS_SERVICE_NAME  "org.freedesktop.DBus"
15
16 /* Owner flags */
17 #define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
18 #define DBUS_NAME_FLAG_REPLACE_EXISTING  0x2 /**< Request to replace the current primary owner */
19 #define DBUS_NAME_FLAG_DO_NOT_QUEUE      0x4 /**< If we can not become the primary owner do not place us in the queue */
20
21 /* Replies to request for a name */
22 #define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER  1 /**< Service has become the primary owner of the requested name */
23 #define DBUS_REQUEST_NAME_REPLY_IN_QUEUE       2 /**< Service could not become the primary owner and has been placed in the queue */
24 #define DBUS_REQUEST_NAME_REPLY_EXISTS         3 /**< Service is already in the queue */
25 #define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER  4 /**< Service is already the primary owner */
26
27 /* Replies to releasing a name */
28 #define DBUS_RELEASE_NAME_REPLY_RELEASED        1 /**< Service was released from the given name */
29 #define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT    2 /**< The given name does not exist on the bus */
30 #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER       3 /**< Service is not an owner of the given name */
31
32 /* Replies to service starts */
33 #define DBUS_START_REPLY_SUCCESS         1 /**< Service was auto started */
34 #define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */
35
36 #define IDLE_TIMEOUT_MSEC 3000
37
38 struct _GDBusDaemon
39 {
40   _GFreedesktopDBusSkeleton parent_instance;
41
42   gchar *address;
43   guint timeout;
44   gchar *tmpdir;
45   GDBusServer *server;
46   gchar *guid;
47   GHashTable *clients;
48   GHashTable *names;
49   guint32 next_major_id;
50   guint32 next_minor_id;
51 };
52
53 struct _GDBusDaemonClass
54 {
55   _GFreedesktopDBusSkeletonClass parent_class;
56 };
57
58 enum {
59   PROP_0,
60   PROP_ADDRESS,
61 };
62
63 enum
64 {
65   SIGNAL_IDLE_TIMEOUT,
66   NR_SIGNALS
67 };
68
69 static guint g_dbus_daemon_signals[NR_SIGNALS];
70
71
72 static void initable_iface_init      (GInitableIface         *initable_iface);
73 static void g_dbus_daemon_iface_init (_GFreedesktopDBusIface *iface);
74
75 #define g_dbus_daemon_get_type _g_dbus_daemon_get_type
76 G_DEFINE_TYPE_WITH_CODE (GDBusDaemon, g_dbus_daemon, _G_TYPE_FREEDESKTOP_DBUS_SKELETON,
77                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
78                          G_IMPLEMENT_INTERFACE (_G_TYPE_FREEDESKTOP_DBUS, g_dbus_daemon_iface_init))
79
80 typedef struct {
81   GDBusDaemon *daemon;
82   char *id;
83   GDBusConnection *connection;
84   GList *matches;
85 } Client;
86
87 typedef struct {
88   Client *client;
89   guint32 flags;
90 } NameOwner;
91
92 typedef struct {
93   int refcount;
94
95   char *name;
96   GDBusDaemon *daemon;
97
98   NameOwner *owner;
99   GList *queue;
100 } Name;
101
102 enum {
103   MATCH_ELEMENT_TYPE,
104   MATCH_ELEMENT_SENDER,
105   MATCH_ELEMENT_INTERFACE,
106   MATCH_ELEMENT_MEMBER,
107   MATCH_ELEMENT_PATH,
108   MATCH_ELEMENT_PATH_NAMESPACE,
109   MATCH_ELEMENT_DESTINATION,
110   MATCH_ELEMENT_ARG0NAMESPACE,
111   MATCH_ELEMENT_EAVESDROP,
112   MATCH_ELEMENT_ARGN,
113   MATCH_ELEMENT_ARGNPATH,
114 };
115
116 typedef struct {
117   guint16 type;
118   guint16 arg;
119   char *value;
120 } MatchElement;
121
122 typedef struct {
123   gboolean eavesdrop;
124   GDBusMessageType type;
125   int n_elements;
126   MatchElement *elements;
127 } Match;
128
129 static GDBusMessage *filter_function   (GDBusConnection *connection,
130                                         GDBusMessage    *message,
131                                         gboolean         incoming,
132                                         gpointer         user_data);
133 static void          connection_closed (GDBusConnection *connection,
134                                         gboolean         remote_peer_vanished,
135                                         GError          *error,
136                                         Client          *client);
137
138 static NameOwner *
139 name_owner_new (Client *client, guint32 flags)
140 {
141   NameOwner *owner;
142
143   owner = g_new0 (NameOwner, 1);
144   owner->client = client;
145   owner->flags = flags;
146   return owner;
147 }
148
149 static void
150 name_owner_free (NameOwner *owner)
151 {
152   g_free (owner);
153 }
154
155 static Name *
156 name_new (GDBusDaemon *daemon, const char *str)
157 {
158   Name *name;
159
160   name = g_new0 (Name, 1);
161   name->refcount = 1;
162   name->daemon = daemon;
163   name->name = g_strdup (str);
164
165   g_hash_table_insert (daemon->names, name->name, name);
166
167   return name;
168 }
169
170 static Name *
171 name_ref (Name *name)
172 {
173   g_assert (name->refcount > 0);
174   name->refcount++;
175   return name;
176 }
177
178 static void
179 name_unref (Name *name)
180 {
181   g_assert (name->refcount > 0);
182   if (--name->refcount == 0)
183     {
184       g_hash_table_remove (name->daemon->names, name->name);
185       g_free (name->name);
186       g_free (name);
187     }
188 }
189
190 static Name *
191 name_ensure (GDBusDaemon *daemon, const char *str)
192 {
193   Name *name;
194
195   name = g_hash_table_lookup (daemon->names, str);
196
197   if (name != NULL)
198     return name_ref (name);
199   return name_new (daemon, str);
200 }
201
202 static Name *
203 name_lookup (GDBusDaemon *daemon, const char *str)
204 {
205   return g_hash_table_lookup (daemon->names, str);
206 }
207
208 static gboolean
209 is_key (const char *key_start, const char *key_end, const char *value)
210 {
211   gsize len = strlen (value);
212
213   if (len != key_end - key_start)
214     return FALSE;
215
216   return strncmp (key_start, value, len) == 0;
217 }
218
219 static gboolean
220 parse_key (MatchElement *element, const char *key_start, const char *key_end)
221 {
222   gboolean res = TRUE;
223
224   if (is_key (key_start, key_end, "type"))
225     {
226       element->type = MATCH_ELEMENT_TYPE;
227     }
228   else if (is_key (key_start, key_end, "sender"))
229     {
230       element->type = MATCH_ELEMENT_SENDER;
231     }
232   else if (is_key (key_start, key_end, "interface"))
233     {
234       element->type = MATCH_ELEMENT_INTERFACE;
235     }
236   else if (is_key (key_start, key_end, "member"))
237     {
238       element->type = MATCH_ELEMENT_MEMBER;
239     }
240   else if (is_key (key_start, key_end, "path"))
241     {
242       element->type = MATCH_ELEMENT_PATH;
243     }
244   else if (is_key (key_start, key_end, "path_namespace"))
245     {
246       element->type = MATCH_ELEMENT_PATH_NAMESPACE;
247     }
248   else if (is_key (key_start, key_end, "destination"))
249     {
250       element->type = MATCH_ELEMENT_DESTINATION;
251     }
252   else if (is_key (key_start, key_end, "arg0namespace"))
253     {
254       element->type = MATCH_ELEMENT_ARG0NAMESPACE;
255     }
256   else if (is_key (key_start, key_end, "eavesdrop"))
257     {
258       element->type = MATCH_ELEMENT_EAVESDROP;
259     }
260   else if (key_end - key_start > 3 && is_key (key_start, key_start + 3, "arg"))
261     {
262       const char *digits = key_start + 3;
263       const char *end_digits = digits;
264
265       while (end_digits < key_end && g_ascii_isdigit (*end_digits))
266         end_digits++;
267
268       if (end_digits == key_end) /* argN */
269         {
270           element->type = MATCH_ELEMENT_ARGN;
271           element->arg = atoi (digits);
272         }
273       else if (is_key (end_digits, key_end, "path")) /* argNpath */
274         {
275           element->type = MATCH_ELEMENT_ARGNPATH;
276           element->arg = atoi (digits);
277         }
278       else
279         res = FALSE;
280     }
281   else
282     res = FALSE;
283
284   return res;
285 }
286
287 static const char *
288 parse_value (MatchElement *element, const char *s)
289 {
290   char quote_char;
291   GString *value;
292
293   value = g_string_new ("");
294
295   quote_char = 0;
296
297   for (;*s; s++)
298     {
299       if (quote_char == 0)
300         {
301           switch (*s)
302             {
303             case '\'':
304               quote_char = '\'';
305               break;
306
307             case ',':
308               s++;
309               goto out;
310
311             case '\\':
312               quote_char = '\\';
313               break;
314
315             default:
316               g_string_append_c (value, *s);
317               break;
318             }
319         }
320       else if (quote_char == '\\')
321         {
322           /* \ only counts as an escape if escaping a quote mark */
323           if (*s != '\'')
324             g_string_append_c (value, '\\');
325
326           g_string_append_c (value, *s);
327           quote_char = 0;
328         }
329       else /* quote_char == ' */
330         {
331           if (*s == '\'')
332             quote_char = 0;
333           else
334             g_string_append_c (value, *s);
335         }
336     }
337
338  out:
339
340   if (quote_char == '\\')
341     g_string_append_c (value, '\\');
342   else if (quote_char == '\'')
343     {
344       g_string_free (value, TRUE);
345       return NULL;
346     }
347
348   element->value = g_string_free (value, FALSE);
349   return s;
350 }
351
352 static Match *
353 match_new (const char *str)
354 {
355   Match *match;
356   GArray *elements;
357   const char *p;
358   const char *key_start;
359   const char *key_end;
360   MatchElement element;
361   gboolean eavesdrop;
362   GDBusMessageType type;
363   int i;
364
365   eavesdrop = FALSE;
366   type = G_DBUS_MESSAGE_TYPE_INVALID;
367   elements = g_array_new (TRUE, TRUE, sizeof (MatchElement));
368
369   p = str;
370
371   while (*p != 0)
372     {
373       memset (&element, 0, sizeof (element));
374
375       /* Skip initial whitespace */
376       while (*p && g_ascii_isspace (*p))
377         p++;
378
379       key_start = p;
380
381       /* Read non-whitespace non-equals chars */
382       while (*p && *p != '=' && !g_ascii_isspace (*p))
383         p++;
384
385       key_end = p;
386
387       /* Skip any whitespace after key */
388       while (*p && g_ascii_isspace (*p))
389         p++;
390
391       if (key_start == key_end)
392         continue; /* Allow trailing whitespace */
393
394       if (*p != '=')
395         goto error;
396
397       ++p;
398
399       if (!parse_key (&element, key_start, key_end))
400         goto error;
401
402       p = parse_value (&element, p);
403       if (p == NULL)
404         goto error;
405
406       if (element.type == MATCH_ELEMENT_EAVESDROP)
407         {
408           if (strcmp (element.value, "true") == 0)
409             eavesdrop = TRUE;
410           else if (strcmp (element.value, "false") == 0)
411             eavesdrop = FALSE;
412           else
413             {
414               g_free (element.value);
415               goto error;
416             }
417           g_free (element.value);
418         }
419       else if (element.type == MATCH_ELEMENT_TYPE)
420         {
421           if (strcmp (element.value, "signal") == 0)
422             type = G_DBUS_MESSAGE_TYPE_SIGNAL;
423           else if (strcmp (element.value, "method_call") == 0)
424             type = G_DBUS_MESSAGE_TYPE_METHOD_CALL;
425           else if (strcmp (element.value, "method_return") == 0)
426             type = G_DBUS_MESSAGE_TYPE_METHOD_RETURN;
427           else if (strcmp (element.value, "error") == 0)
428             type = G_DBUS_MESSAGE_TYPE_ERROR;
429           else
430             {
431               g_free (element.value);
432               goto error;
433             }
434           g_free (element.value);
435         }
436       else
437         g_array_append_val (elements, element);
438     }
439
440   match = g_new0 (Match, 1);
441   match->n_elements = elements->len;
442   match->elements = (MatchElement *)g_array_free (elements, FALSE);
443   match->eavesdrop = eavesdrop;
444   match->type = type;
445
446   return match;
447
448  error:
449   for (i = 0; i < elements->len; i++)
450     g_free (g_array_index (elements, MatchElement, i).value);
451   g_array_free (elements, TRUE);
452   return NULL;
453 }
454
455 static void
456 match_free (Match *match)
457 {
458   int i;
459   for (i = 0; i < match->n_elements; i++)
460     g_free (match->elements[i].value);
461   g_free (match->elements);
462   g_free (match);
463 }
464
465 static gboolean
466 match_equal (Match *a, Match *b)
467 {
468   int i;
469
470   if (a->eavesdrop != b->eavesdrop)
471     return FALSE;
472   if (a->type != b->type)
473     return FALSE;
474  if (a->n_elements != b->n_elements)
475     return FALSE;
476   for (i = 0; i < a->n_elements; i++)
477     {
478       if (a->elements[i].type != b->elements[i].type ||
479           a->elements[i].arg != b->elements[i].arg ||
480           strcmp (a->elements[i].value, b->elements[i].value) != 0)
481         return FALSE;
482     }
483   return TRUE;
484 }
485
486 static const gchar *
487 message_get_argN (GDBusMessage *message, int n, gboolean allow_path)
488 {
489   const gchar *ret;
490   GVariant *body;
491
492   ret = NULL;
493
494   body = g_dbus_message_get_body (message);
495
496   if (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE_TUPLE))
497     {
498       GVariant *item;
499       item = g_variant_get_child_value (body, n);
500       if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING) ||
501           (allow_path && g_variant_is_of_type (item, G_VARIANT_TYPE_OBJECT_PATH)))
502         ret = g_variant_get_string (item, NULL);
503       g_variant_unref (item);
504     }
505
506   return ret;
507 }
508
509 enum {
510   CHECK_TYPE_STRING,
511   CHECK_TYPE_NAME,
512   CHECK_TYPE_PATH_PREFIX,
513   CHECK_TYPE_PATH_RELATED,
514   CHECK_TYPE_NAMESPACE_PREFIX
515 };
516
517 static gboolean
518 match_matches (GDBusDaemon *daemon,
519                Match *match, GDBusMessage *message,
520                gboolean has_destination)
521 {
522   MatchElement *element;
523   Name *name;
524   int i, len, len2;
525   const char *value;
526   int check_type;
527
528   if (has_destination && !match->eavesdrop)
529     return FALSE;
530
531   if (match->type != G_DBUS_MESSAGE_TYPE_INVALID &&
532       g_dbus_message_get_message_type (message) != match->type)
533     return FALSE;
534
535   for (i = 0; i < match->n_elements; i++)
536     {
537       element = &match->elements[i];
538       check_type = CHECK_TYPE_STRING;
539       switch (element->type)
540         {
541         case MATCH_ELEMENT_SENDER:
542           check_type = CHECK_TYPE_NAME;
543           value = g_dbus_message_get_sender (message);
544           if (value == NULL)
545             value = DBUS_SERVICE_NAME;
546           break;
547         case MATCH_ELEMENT_DESTINATION:
548           check_type = CHECK_TYPE_NAME;
549           value = g_dbus_message_get_destination (message);
550           break;
551         case MATCH_ELEMENT_INTERFACE:
552           value = g_dbus_message_get_interface (message);
553           break;
554         case MATCH_ELEMENT_MEMBER:
555           value = g_dbus_message_get_member (message);
556           break;
557         case MATCH_ELEMENT_PATH:
558           value = g_dbus_message_get_path (message);
559           break;
560         case MATCH_ELEMENT_PATH_NAMESPACE:
561           check_type = CHECK_TYPE_PATH_PREFIX;
562           value = g_dbus_message_get_path (message);
563           break;
564         case MATCH_ELEMENT_ARG0NAMESPACE:
565           check_type = CHECK_TYPE_NAMESPACE_PREFIX;
566           value = message_get_argN (message, 0, FALSE);
567           break;
568         case MATCH_ELEMENT_ARGN:
569           value = message_get_argN (message, element->arg, FALSE);
570           break;
571         case MATCH_ELEMENT_ARGNPATH:
572           check_type = CHECK_TYPE_PATH_RELATED;
573           value = message_get_argN (message, element->arg, TRUE);
574           break;
575         default:
576         case MATCH_ELEMENT_TYPE:
577         case MATCH_ELEMENT_EAVESDROP:
578           g_assert_not_reached ();
579         }
580
581       if (value == NULL)
582         return FALSE;
583
584       switch (check_type)
585         {
586         case CHECK_TYPE_STRING:
587           if (strcmp (element->value, value) != 0)
588             return FALSE;
589           break;
590         case CHECK_TYPE_NAME:
591           name = name_lookup (daemon, element->value);
592           if (name != NULL && name->owner != NULL)
593             {
594               if (strcmp (name->owner->client->id, value) != 0)
595                 return FALSE;
596             }
597           else if (strcmp (element->value, value) != 0)
598             return FALSE;
599           break;
600         case CHECK_TYPE_PATH_PREFIX:
601           len = strlen (element->value);
602
603           /* Make sure to handle the case of element->value == '/'. */
604           if (len == 1)
605             break;
606
607           /* Fail if there's no prefix match, or if the prefix match doesn't
608            * finish at the end of or at a separator in the @value. */
609           if (!g_str_has_prefix (value, element->value))
610             return FALSE;
611           if (value[len] != 0 && value[len] != '/')
612             return FALSE;
613
614           break;
615         case CHECK_TYPE_PATH_RELATED:
616           len = strlen (element->value);
617           len2 = strlen (value);
618
619           if (!(strcmp (value, element->value) == 0 ||
620                 (len2 > 0 && value[len2-1] == '/' && g_str_has_prefix (element->value, value)) ||
621                 (len > 0 && element->value[len-1] == '/' && g_str_has_prefix (value, element->value))))
622             return FALSE;
623           break;
624         case CHECK_TYPE_NAMESPACE_PREFIX:
625           len = strlen (element->value);
626           if (!(g_str_has_prefix (value, element->value) &&
627                 (value[len] == 0 || value[len] == '.')))
628             return FALSE;
629           break;
630         default:
631           g_assert_not_reached ();
632         }
633     }
634
635   return TRUE;
636 }
637
638 static void
639 broadcast_message (GDBusDaemon *daemon,
640                    GDBusMessage *message,
641                    gboolean has_destination,
642                    gboolean preserve_serial,
643                    Client *not_to)
644 {
645   GList *clients, *l, *ll;
646   GDBusMessage *copy;
647
648   clients = g_hash_table_get_values (daemon->clients);
649   for (l = clients; l != NULL; l = l->next)
650     {
651       Client *client = l->data;
652
653       if (client == not_to)
654         continue;
655
656       for (ll = client->matches; ll != NULL; ll = ll->next)
657         {
658           Match *match = ll->data;
659
660           if (match_matches (daemon, match, message, has_destination))
661             break;
662         }
663
664       if (ll != NULL)
665         {
666           copy = g_dbus_message_copy (message, NULL);
667           if (copy)
668             {
669               g_dbus_connection_send_message (client->connection, copy,
670                                               preserve_serial?G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL:0, NULL, NULL);
671               g_object_unref (copy);
672             }
673         }
674     }
675
676   g_list_free (clients);
677 }
678
679 static void
680 send_name_owner_changed (GDBusDaemon *daemon,
681                          const char *name,
682                          const char *old_owner,
683                          const char *new_owner)
684 {
685   GDBusMessage *signal_message;
686
687   signal_message = g_dbus_message_new_signal ("/org/freedesktop/DBus",
688                                               "org.freedesktop.DBus",
689                                               "NameOwnerChanged");
690   g_dbus_message_set_body (signal_message,
691                            g_variant_new ("(sss)",
692                                           name,
693                                           old_owner ? old_owner : "",
694                                           new_owner ? new_owner : ""));
695
696   broadcast_message (daemon, signal_message, FALSE, FALSE, NULL);
697   g_object_unref (signal_message);
698
699 }
700
701 static gboolean
702 name_unqueue_owner (Name *name, Client *client)
703 {
704   GList *l;
705
706   for (l = name->queue; l != NULL; l = l->next)
707     {
708       NameOwner *other = l->data;
709
710       if (other->client == client)
711         {
712           name->queue = g_list_delete_link (name->queue, l);
713           name_unref (name);
714           name_owner_free (other);
715           return TRUE;
716         }
717     }
718
719   return FALSE;
720 }
721
722 static void
723 name_replace_owner (Name *name, NameOwner *owner)
724 {
725   GDBusDaemon *daemon = name->daemon;
726   NameOwner *old_owner;
727   char *old_name = NULL, *new_name = NULL;
728   Client *new_client = NULL;
729
730   if (owner)
731     new_client = owner->client;
732
733   name_ref (name);
734
735   old_owner = name->owner;
736   if (old_owner)
737     {
738       Client *old_client = old_owner->client;
739
740       g_assert (old_owner->client != new_client);
741
742       g_dbus_connection_emit_signal (old_client->connection,
743                                      NULL, "/org/freedesktop/DBus",
744                                      "org.freedesktop.DBus", "NameLost",
745                                      g_variant_new ("(s)",
746                                                     name->name), NULL);
747
748       old_name = g_strdup (old_client->id);
749       if (old_owner->flags & DBUS_NAME_FLAG_DO_NOT_QUEUE)
750         {
751           name_unref (name);
752           name_owner_free (old_owner);
753         }
754       else
755         name->queue = g_list_prepend (name->queue, old_owner);
756     }
757
758   name->owner = owner;
759   if (owner)
760     {
761       name_unqueue_owner (name, owner->client);
762       name_ref (name);
763       new_name = new_client->id;
764
765       g_dbus_connection_emit_signal (new_client->connection,
766                                      NULL, "/org/freedesktop/DBus",
767                                      "org.freedesktop.DBus", "NameAcquired",
768                                      g_variant_new ("(s)",
769                                                     name->name), NULL);
770     }
771
772   send_name_owner_changed (daemon, name->name, old_name, new_name);
773
774   g_free (old_name);
775
776   name_unref (name);
777 }
778
779 static void
780 name_release_owner (Name *name)
781 {
782   NameOwner *next_owner = NULL;
783
784   name_ref (name);
785
786   /* Will someone else take over? */
787   if (name->queue)
788     {
789       next_owner = name->queue->data;
790       name_unref (name);
791       name->queue = g_list_delete_link (name->queue, name->queue);
792     }
793
794   name->owner->flags |= DBUS_NAME_FLAG_DO_NOT_QUEUE;
795   name_replace_owner (name, next_owner);
796
797   name_unref (name);
798 }
799
800 static void
801 name_queue_owner (Name *name, NameOwner *owner)
802 {
803   GList *l;
804
805   for (l = name->queue; l != NULL; l = l->next)
806     {
807       NameOwner *other = l->data;
808
809       if (other->client == owner->client)
810         {
811           other->flags = owner->flags;
812           name_owner_free (owner);
813           return;
814         }
815     }
816
817   name->queue = g_list_append (name->queue, owner);
818   name_ref (name);
819 }
820
821 static Client *
822 client_new (GDBusDaemon *daemon, GDBusConnection *connection)
823 {
824   Client *client;
825   GError *error = NULL;
826
827   client = g_new0 (Client, 1);
828   client->daemon = daemon;
829   client->id = g_strdup_printf (":%d.%d", daemon->next_major_id, daemon->next_minor_id);
830   client->connection = g_object_ref (connection);
831
832   if (daemon->next_minor_id == G_MAXUINT32)
833     {
834       daemon->next_minor_id = 0;
835       daemon->next_major_id++;
836     }
837   else
838     daemon->next_minor_id++;
839
840   g_object_set_data (G_OBJECT (connection), "client", client);
841   g_hash_table_insert (daemon->clients, client->id, client);
842
843   g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (daemon), connection,
844                                     "/org/freedesktop/DBus", &error);
845   g_assert_no_error (error);
846
847   g_signal_connect (connection, "closed", G_CALLBACK (connection_closed), client);
848   g_dbus_connection_add_filter (connection,
849                                 filter_function,
850                                 client, NULL);
851
852   send_name_owner_changed (daemon, client->id, NULL, client->id);
853
854   return client;
855 }
856
857 static void
858 client_free (Client *client)
859 {
860   GDBusDaemon *daemon = client->daemon;
861   GList *l, *names;
862
863   g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (daemon),
864                                                       client->connection);
865
866   g_hash_table_remove (daemon->clients, client->id);
867
868   names = g_hash_table_get_values (daemon->names);
869   for (l = names; l != NULL; l = l->next)
870     {
871       Name *name = l->data;
872
873       name_ref (name);
874
875       if (name->owner && name->owner->client == client)
876         name_release_owner (name);
877
878       name_unqueue_owner (name, client);
879
880       name_unref (name);
881     }
882   g_list_free (names);
883
884   send_name_owner_changed (daemon, client->id, client->id, NULL);
885
886   g_object_unref (client->connection);
887
888   for (l = client->matches; l != NULL; l = l->next)
889     match_free (l->data);
890   g_list_free (client->matches);
891
892   g_free (client->id);
893   g_free (client);
894 }
895
896 static gboolean
897 idle_timeout_cb (gpointer user_data)
898 {
899   GDBusDaemon *daemon = user_data;
900
901   daemon->timeout = 0;
902
903   g_signal_emit (daemon,
904                  g_dbus_daemon_signals[SIGNAL_IDLE_TIMEOUT],
905                  0);
906
907   return G_SOURCE_REMOVE;
908 }
909
910 static void
911 connection_closed (GDBusConnection *connection,
912                    gboolean remote_peer_vanished,
913                    GError *error,
914                    Client *client)
915 {
916   GDBusDaemon *daemon = client->daemon;
917
918   client_free (client);
919
920   if (g_hash_table_size (daemon->clients) == 0)
921     daemon->timeout = g_timeout_add (IDLE_TIMEOUT_MSEC,
922                                      idle_timeout_cb,
923                                      daemon);
924 }
925
926 static gboolean
927 handle_add_match (_GFreedesktopDBus *object,
928                   GDBusMethodInvocation *invocation,
929                   const gchar *arg_rule)
930 {
931   Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
932   Match *match;
933
934   match = match_new (arg_rule);
935
936   if (match == NULL)
937     g_dbus_method_invocation_return_error (invocation,
938                                            G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_INVALID,
939                                            "Invalid rule: %s", arg_rule);
940   else
941     {
942       client->matches = g_list_prepend (client->matches, match);
943       _g_freedesktop_dbus_complete_add_match (object, invocation);
944     }
945   return TRUE;
946 }
947
948 static gboolean
949 handle_get_connection_selinux_security_context (_GFreedesktopDBus *object,
950                                                 GDBusMethodInvocation *invocation,
951                                                 const gchar *arg_name)
952 {
953   g_dbus_method_invocation_return_error (invocation,
954                                          G_DBUS_ERROR, G_DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
955                                          "selinux context not supported");
956   _g_freedesktop_dbus_complete_get_connection_selinux_security_context (object, invocation, "");
957   return TRUE;
958 }
959
960 static gboolean
961 handle_get_connection_unix_process_id (_GFreedesktopDBus *object,
962                                        GDBusMethodInvocation *invocation,
963                                        const gchar *arg_name)
964 {
965   g_dbus_method_invocation_return_error (invocation,
966                                          G_DBUS_ERROR, G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
967                                          "connection pid not supported");
968   return TRUE;
969 }
970
971 static gboolean
972 handle_get_connection_unix_user (_GFreedesktopDBus *object,
973                                  GDBusMethodInvocation *invocation,
974                                  const gchar *arg_name)
975 {
976   g_dbus_method_invocation_return_error (invocation,
977                                          G_DBUS_ERROR, G_DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
978                                          "connection user not supported");
979   return TRUE;
980 }
981
982 static gboolean
983 handle_get_id (_GFreedesktopDBus *object,
984                GDBusMethodInvocation *invocation)
985 {
986   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
987   _g_freedesktop_dbus_complete_get_id (object, invocation,
988                                        daemon->guid);
989   return TRUE;
990 }
991
992 static gboolean
993 handle_get_name_owner (_GFreedesktopDBus *object,
994                        GDBusMethodInvocation *invocation,
995                        const gchar *arg_name)
996 {
997   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
998   Name *name;
999
1000   if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0)
1001     {
1002       _g_freedesktop_dbus_complete_get_name_owner (object, invocation, DBUS_SERVICE_NAME);
1003       return TRUE;
1004     }
1005
1006   if (arg_name[0] == ':')
1007     {
1008       if (g_hash_table_lookup (daemon->clients, arg_name) == NULL)
1009         g_dbus_method_invocation_return_error (invocation,
1010                                                G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1011                                                "Could not get owner of name '%s': no such name", arg_name);
1012       else
1013         _g_freedesktop_dbus_complete_get_name_owner (object, invocation, arg_name);
1014       return TRUE;
1015     }
1016
1017   name = name_lookup (daemon, arg_name);
1018   if (name == NULL || name->owner == NULL)
1019     {
1020       g_dbus_method_invocation_return_error (invocation,
1021                                              G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER,
1022                                              "Could not get owner of name '%s': no such name", arg_name);
1023       return TRUE;
1024     }
1025
1026   _g_freedesktop_dbus_complete_get_name_owner (object, invocation, name->owner->client->id);
1027   return TRUE;
1028 }
1029
1030 static gboolean
1031 handle_hello (_GFreedesktopDBus *object,
1032               GDBusMethodInvocation *invocation)
1033 {
1034   Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1035   _g_freedesktop_dbus_complete_hello (object, invocation, client->id);
1036
1037   g_dbus_connection_emit_signal (client->connection,
1038                                  NULL, "/org/freedesktop/DBus",
1039                                  "org.freedesktop.DBus", "NameAcquired",
1040                                  g_variant_new ("(s)",
1041                                                 client->id), NULL);
1042
1043   return TRUE;
1044 }
1045
1046 static gboolean
1047 handle_list_activatable_names (_GFreedesktopDBus *object,
1048                                GDBusMethodInvocation *invocation)
1049 {
1050   const char *names[] = { NULL };
1051
1052   _g_freedesktop_dbus_complete_list_activatable_names (object,
1053                                                        invocation,
1054                                                        names);
1055   return TRUE;
1056 }
1057
1058 static gboolean
1059 handle_list_names (_GFreedesktopDBus *object,
1060                    GDBusMethodInvocation *invocation)
1061 {
1062   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1063   GPtrArray *array;
1064   GList *clients, *names, *l;
1065
1066   array = g_ptr_array_new ();
1067
1068   clients = g_hash_table_get_values (daemon->clients);
1069   for (l = clients; l != NULL; l = l->next)
1070     {
1071       Client *client = l->data;
1072
1073       g_ptr_array_add (array, client->id);
1074     }
1075
1076   g_list_free (clients);
1077
1078   names = g_hash_table_get_values (daemon->names);
1079   for (l = names; l != NULL; l = l->next)
1080     {
1081       Name *name = l->data;
1082
1083       g_ptr_array_add (array, name->name);
1084     }
1085
1086   g_list_free (names);
1087
1088   g_ptr_array_add (array, NULL);
1089
1090   _g_freedesktop_dbus_complete_list_names (object,
1091                                            invocation,
1092                                            (const gchar * const*)array->pdata);
1093   g_ptr_array_free (array, TRUE);
1094   return TRUE;
1095 }
1096
1097 static gboolean
1098 handle_list_queued_owners (_GFreedesktopDBus *object,
1099                            GDBusMethodInvocation *invocation,
1100                            const gchar *arg_name)
1101 {
1102   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1103   GPtrArray *array;
1104   Name *name;
1105   GList *l;
1106
1107   array = g_ptr_array_new ();
1108
1109   name = name_lookup (daemon, arg_name);
1110   if (name && name->owner)
1111     {
1112       for (l = name->queue; l != NULL; l = l->next)
1113         {
1114           Client *client = l->data;
1115
1116           g_ptr_array_add (array, client->id);
1117         }
1118     }
1119
1120   g_ptr_array_add (array, NULL);
1121
1122   _g_freedesktop_dbus_complete_list_queued_owners (object,
1123                                                    invocation,
1124                                                    (const gchar * const*)array->pdata);
1125   g_ptr_array_free (array, TRUE);
1126   return TRUE;
1127 }
1128
1129 static gboolean
1130 handle_name_has_owner (_GFreedesktopDBus *object,
1131                        GDBusMethodInvocation *invocation,
1132                        const gchar *arg_name)
1133 {
1134   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1135   Name *name;
1136   Client *client;
1137
1138   name = name_lookup (daemon, arg_name);
1139   client = g_hash_table_lookup (daemon->clients, arg_name);
1140
1141   _g_freedesktop_dbus_complete_name_has_owner (object, invocation,
1142                                                name != NULL || client != NULL);
1143   return TRUE;
1144 }
1145
1146 static gboolean
1147 handle_release_name (_GFreedesktopDBus *object,
1148                      GDBusMethodInvocation *invocation,
1149                      const gchar *arg_name)
1150 {
1151   Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1152   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1153   Name *name;
1154   guint32 result;
1155
1156   if (!g_dbus_is_name (arg_name))
1157     {
1158       g_dbus_method_invocation_return_error (invocation,
1159                                              G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1160                                              "Given bus name \"%s\" is not valid", arg_name);
1161       return TRUE;
1162     }
1163
1164   if (*arg_name == ':')
1165     {
1166       g_dbus_method_invocation_return_error (invocation,
1167                                              G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1168                                              "Cannot release a service starting with ':' such as \"%s\"", arg_name);
1169       return TRUE;
1170     }
1171
1172   if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0)
1173     {
1174       g_dbus_method_invocation_return_error (invocation,
1175                                              G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1176                                              "Cannot release a service named " DBUS_SERVICE_NAME ", because that is owned by the bus");
1177       return TRUE;
1178     }
1179
1180   name = name_lookup (daemon, arg_name);
1181
1182   if (name == NULL)
1183     result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
1184   else if (name->owner && name->owner->client == client)
1185     {
1186       name_release_owner (name);
1187       result = DBUS_RELEASE_NAME_REPLY_RELEASED;
1188     }
1189   else if (name_unqueue_owner (name, client))
1190     result = DBUS_RELEASE_NAME_REPLY_RELEASED;
1191   else
1192     result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
1193
1194   _g_freedesktop_dbus_complete_release_name (object, invocation, result);
1195   return TRUE;
1196 }
1197
1198 static gboolean
1199 handle_reload_config (_GFreedesktopDBus *object,
1200                       GDBusMethodInvocation *invocation)
1201 {
1202   _g_freedesktop_dbus_complete_reload_config (object, invocation);
1203   return TRUE;
1204 }
1205
1206 static gboolean
1207 handle_update_activation_environment (_GFreedesktopDBus *object,
1208                                       GDBusMethodInvocation *invocation,
1209                                       GVariant *arg_environment)
1210 {
1211   g_dbus_method_invocation_return_error (invocation,
1212                                          G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
1213                                          "UpdateActivationEnvironment not implemented");
1214   return TRUE;
1215 }
1216
1217 static gboolean
1218 handle_remove_match (_GFreedesktopDBus *object,
1219                      GDBusMethodInvocation *invocation,
1220                      const gchar *arg_rule)
1221 {
1222   Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1223   Match *match, *other_match;
1224   GList *l;
1225
1226   match = match_new (arg_rule);
1227
1228   if (match == NULL)
1229     g_dbus_method_invocation_return_error (invocation,
1230                                            G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_INVALID,
1231                                            "Invalid rule: %s", arg_rule);
1232   else
1233     {
1234       for (l = client->matches; l != NULL; l = l->next)
1235         {
1236           other_match = l->data;
1237           if (match_equal (match, other_match))
1238             {
1239               match_free (other_match);
1240               client->matches = g_list_delete_link (client->matches, l);
1241               break;
1242             }
1243         }
1244
1245       if (l == NULL)
1246         g_dbus_method_invocation_return_error (invocation,
1247                                                G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_NOT_FOUND,
1248                                                "The given match rule wasn't found and can't be removed");
1249       else
1250         _g_freedesktop_dbus_complete_remove_match (object, invocation);
1251     }
1252   if (match)    
1253     match_free (match);
1254
1255   return TRUE;
1256 }
1257
1258 static gboolean
1259 handle_request_name (_GFreedesktopDBus *object,
1260                      GDBusMethodInvocation *invocation,
1261                      const gchar *arg_name,
1262                      guint flags)
1263 {
1264   Client *client = g_object_get_data (G_OBJECT (g_dbus_method_invocation_get_connection (invocation)), "client");
1265   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1266   Name *name;
1267   NameOwner *owner;
1268   guint32 result;
1269
1270   if (!g_dbus_is_name (arg_name))
1271     {
1272       g_dbus_method_invocation_return_error (invocation,
1273                                              G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1274                                              "Requested bus name \"%s\" is not valid", arg_name);
1275       return TRUE;
1276     }
1277
1278   if (*arg_name == ':')
1279     {
1280       g_dbus_method_invocation_return_error (invocation,
1281                                              G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1282                                              "Cannot acquire a service starting with ':' such as \"%s\"", arg_name);
1283       return TRUE;
1284     }
1285
1286   if (strcmp (arg_name, DBUS_SERVICE_NAME) == 0)
1287     {
1288       g_dbus_method_invocation_return_error (invocation,
1289                                              G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
1290                                              "Cannot acquire a service named " DBUS_SERVICE_NAME ", because that is reserved");
1291       return TRUE;
1292     }
1293
1294   name = name_ensure (daemon, arg_name);
1295   if (name->owner == NULL)
1296     {
1297       owner = name_owner_new (client, flags);
1298       name_replace_owner (name, owner);
1299
1300       result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
1301     }
1302   else if (name->owner && name->owner->client == client)
1303     {
1304       name->owner->flags = flags;
1305       result = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
1306     }
1307   else if ((flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
1308            (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
1309             !(name->owner->flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)))
1310     {
1311       /* Unqueue if queued */
1312       name_unqueue_owner (name, client);
1313       result = DBUS_REQUEST_NAME_REPLY_EXISTS;
1314     }
1315   else if (!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) &&
1316            (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) ||
1317             !(name->owner->flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)))
1318     {
1319       /* Queue the connection */
1320       owner = name_owner_new (client, flags);
1321       name_queue_owner (name, owner);
1322       result = DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
1323     }
1324   else
1325     {
1326       /* Replace the current owner */
1327
1328       owner = name_owner_new (client, flags);
1329       name_replace_owner (name, owner);
1330
1331       result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
1332     }
1333
1334   name_unref (name);
1335
1336   _g_freedesktop_dbus_complete_request_name (object, invocation, result);
1337   return TRUE;
1338 }
1339
1340 static gboolean
1341 handle_start_service_by_name (_GFreedesktopDBus *object,
1342                               GDBusMethodInvocation *invocation,
1343                               const gchar *arg_name,
1344                               guint arg_flags)
1345 {
1346   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1347   Name *name;
1348
1349   name = name_lookup (daemon, arg_name);
1350   if (name)
1351     _g_freedesktop_dbus_complete_start_service_by_name (object, invocation,
1352                                                         DBUS_START_REPLY_ALREADY_RUNNING);
1353   else
1354     g_dbus_method_invocation_return_error (invocation,
1355                                            G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN,
1356                                            "No support for activation for name: %s", arg_name);
1357
1358   return TRUE;
1359 }
1360
1361 G_GNUC_PRINTF(5, 6)
1362 static void
1363 return_error (Client *client, GDBusMessage *message,
1364               GQuark                 domain,
1365               gint                   code,
1366               const gchar           *format,
1367               ...)
1368 {
1369   GDBusMessage *reply;
1370   va_list var_args;
1371   char *error_message;
1372   GError *error;
1373   gchar *dbus_error_name;
1374
1375   va_start (var_args, format);
1376   error_message = g_strdup_vprintf (format, var_args);
1377   va_end (var_args);
1378
1379   error = g_error_new_literal (domain, code, "");
1380   dbus_error_name = g_dbus_error_encode_gerror (error);
1381
1382   reply = g_dbus_message_new_method_error_literal (message,
1383                                                    dbus_error_name,
1384                                                    error_message);
1385
1386   g_error_free (error);
1387   g_free (dbus_error_name);
1388   g_free (error_message);
1389
1390   if (!g_dbus_connection_send_message (client->connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL))
1391       g_warning ("Error sending reply");
1392   g_object_unref (reply);
1393 }
1394
1395 static GDBusMessage *
1396 route_message (Client *source_client, GDBusMessage *message)
1397 {
1398   const char *dest;
1399   Client *dest_client;
1400   GDBusDaemon *daemon;
1401
1402   daemon = source_client->daemon;
1403
1404   dest_client = NULL;
1405   dest = g_dbus_message_get_destination (message);
1406   if (dest != NULL && strcmp (dest, DBUS_SERVICE_NAME) != 0)
1407     {
1408       dest_client = g_hash_table_lookup (daemon->clients, dest);
1409
1410       if (dest_client == NULL)
1411         {
1412           Name *name;
1413           name = name_lookup (daemon, dest);
1414           if (name && name->owner)
1415             dest_client = name->owner->client;
1416         }
1417
1418       if (dest_client == NULL)
1419         {
1420           if (g_dbus_message_get_message_type (message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL)
1421             return_error (source_client, message,
1422                           G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN,
1423                           "The name %s is unknown", dest);
1424         }
1425       else
1426         {
1427           GError *error = NULL;
1428
1429           if (!g_dbus_connection_send_message (dest_client->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, NULL, &error))
1430             {
1431               g_warning ("Error forwarding message: %s", error->message);
1432               g_error_free (error);
1433             }
1434         }
1435     }
1436
1437   broadcast_message (daemon, message, dest_client != NULL, TRUE, dest_client);
1438
1439   /* Swallow messages not for the bus */
1440   if (dest == NULL || strcmp (dest, DBUS_SERVICE_NAME) != 0)
1441     {
1442       g_object_unref (message);
1443       message = NULL;
1444     }
1445
1446   return message;
1447 }
1448
1449 static GDBusMessage *
1450 copy_if_locked (GDBusMessage *message)
1451 {
1452   if (g_dbus_message_get_locked (message))
1453     {
1454       GDBusMessage *copy = g_dbus_message_copy (message, NULL);
1455       g_object_unref (message);
1456       message = copy;
1457     }
1458   return message;
1459 }
1460
1461 static GDBusMessage *
1462 filter_function (GDBusConnection *connection,
1463                  GDBusMessage    *message,
1464                  gboolean         incoming,
1465                  gpointer         user_data)
1466 {
1467   Client *client = user_data;
1468
1469   if (0)
1470     {
1471       const char *types[] = {"invalid", "method_call", "method_return", "error", "signal" };
1472       g_printerr ("%s%s %s %d(%d) sender: %s destination: %s %s %s.%s\n",
1473                 client->id,
1474                 incoming? "->" : "<-",
1475                 types[g_dbus_message_get_message_type (message)],
1476                 g_dbus_message_get_serial (message),
1477                 g_dbus_message_get_reply_serial (message),
1478                 g_dbus_message_get_sender (message),
1479                 g_dbus_message_get_destination (message),
1480                 g_dbus_message_get_path (message),
1481                 g_dbus_message_get_interface (message),
1482                 g_dbus_message_get_member (message));
1483     }
1484
1485   if (incoming)
1486     {
1487       /* Ensure its not locked so we can set the sender */
1488       message = copy_if_locked (message);
1489       if (message == NULL)
1490         {
1491           g_warning ("Failed to copy incoming message");
1492           return NULL;
1493         }
1494       g_dbus_message_set_sender (message, client->id);
1495
1496       return route_message (client, message);
1497     }
1498   else
1499     {
1500       if (g_dbus_message_get_sender (message) == NULL ||
1501           g_dbus_message_get_destination (message) == NULL)
1502         {
1503           message = copy_if_locked (message);
1504           if (message == NULL)
1505             {
1506               g_warning ("Failed to copy outgoing message");
1507               return NULL;
1508             }
1509         }
1510
1511       if (g_dbus_message_get_sender (message) == NULL)
1512         g_dbus_message_set_sender (message, DBUS_SERVICE_NAME);
1513       if (g_dbus_message_get_destination (message) == NULL)
1514         g_dbus_message_set_destination (message, client->id);
1515     }
1516
1517   return message;
1518 }
1519
1520 static gboolean
1521 on_new_connection (GDBusServer *server,
1522                    GDBusConnection *connection,
1523                    gpointer user_data)
1524 {
1525   GDBusDaemon *daemon = user_data;
1526
1527   g_dbus_connection_set_exit_on_close (connection, FALSE);
1528
1529   if (daemon->timeout)
1530     {
1531       g_source_remove (daemon->timeout);
1532       daemon->timeout = 0;
1533     }
1534
1535   client_new (daemon, connection);
1536
1537   return TRUE;
1538 }
1539
1540 static gboolean
1541 on_authorize_authenticated_peer (GDBusAuthObserver *observer,
1542                                  GIOStream         *stream,
1543                                  GCredentials      *credentials,
1544                                  gpointer           user_data)
1545 {
1546   gboolean authorized = FALSE;
1547
1548   if (credentials != NULL)
1549     {
1550       GCredentials *own_credentials;
1551
1552       own_credentials = g_credentials_new ();
1553       authorized = g_credentials_is_same_user (credentials, own_credentials, NULL);
1554       g_object_unref (own_credentials);
1555     }
1556 #ifdef G_OS_WIN32
1557   else
1558     {
1559       /* We allow ANONYMOUS authentication on Windows for now, in
1560        * combination with the nonce-tcp transport. */
1561       authorized = TRUE;
1562     }
1563 #endif
1564
1565   return authorized;
1566 }
1567
1568 static void
1569 g_dbus_daemon_finalize (GObject *object)
1570 {
1571   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1572   GList *clients, *l;
1573
1574   if (daemon->timeout)
1575     g_source_remove (daemon->timeout);
1576
1577   clients = g_hash_table_get_values (daemon->clients);
1578   for (l = clients; l != NULL; l = l->next)
1579     client_free (l->data);
1580   g_list_free (clients);
1581
1582   g_assert (g_hash_table_size (daemon->clients) == 0);
1583   g_assert (g_hash_table_size (daemon->names) == 0);
1584
1585   g_hash_table_destroy (daemon->clients);
1586   g_hash_table_destroy (daemon->names);
1587
1588   g_object_unref (daemon->server);
1589
1590   if (daemon->tmpdir)
1591     {
1592       g_rmdir (daemon->tmpdir);
1593       g_free (daemon->tmpdir);
1594     }
1595
1596   g_free (daemon->guid);
1597   g_free (daemon->address);
1598
1599   G_OBJECT_CLASS (g_dbus_daemon_parent_class)->finalize (object);
1600 }
1601
1602 static void
1603 g_dbus_daemon_init (GDBusDaemon *daemon)
1604 {
1605   daemon->next_major_id = 1;
1606   daemon->clients = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1607   daemon->names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1608   daemon->guid = g_dbus_generate_guid ();
1609 }
1610
1611 static gboolean
1612 initable_init (GInitable     *initable,
1613                GCancellable  *cancellable,
1614                GError       **error)
1615 {
1616   GDBusDaemon *daemon = G_DBUS_DAEMON (initable);
1617   GDBusAuthObserver *observer;
1618   GDBusServerFlags flags;
1619
1620   flags = G_DBUS_SERVER_FLAGS_NONE;
1621   if (daemon->address == NULL)
1622     {
1623 #ifdef G_OS_UNIX
1624       if (g_unix_socket_address_abstract_names_supported ())
1625         daemon->address = g_strdup ("unix:tmpdir=/tmp/gdbus-daemon");
1626       else
1627         {
1628           daemon->tmpdir = g_dir_make_tmp ("gdbus-daemon-XXXXXX", NULL);
1629           daemon->address = g_strdup_printf ("unix:tmpdir=%s", daemon->tmpdir);
1630         }
1631 #else
1632       daemon->address = g_strdup ("nonce-tcp:");
1633       flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
1634 #endif
1635     }
1636
1637   observer = g_dbus_auth_observer_new ();
1638   daemon->server = g_dbus_server_new_sync (daemon->address,
1639                                            flags,
1640                                            daemon->guid,
1641                                            observer,
1642                                            cancellable,
1643                                            error);
1644   if (daemon->server == NULL)
1645     {
1646       g_object_unref (observer);
1647       return FALSE;
1648     }
1649
1650
1651   g_dbus_server_start (daemon->server);
1652
1653   g_signal_connect (daemon->server, "new-connection",
1654                     G_CALLBACK (on_new_connection),
1655                     daemon);
1656   g_signal_connect (observer,
1657                     "authorize-authenticated-peer",
1658                     G_CALLBACK (on_authorize_authenticated_peer),
1659                     daemon);
1660
1661   g_object_unref (observer);
1662
1663   return TRUE;
1664 }
1665
1666 static void
1667 g_dbus_daemon_set_property (GObject      *object,
1668                             guint         prop_id,
1669                             const GValue *value,
1670                             GParamSpec   *pspec)
1671 {
1672   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1673
1674   switch (prop_id)
1675     {
1676     case PROP_ADDRESS:
1677       g_free (daemon->address);
1678       daemon->address = g_value_dup_string (value);
1679       break;
1680
1681     default:
1682       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1683     }
1684 }
1685
1686 static void
1687 g_dbus_daemon_get_property (GObject    *object,
1688                             guint       prop_id,
1689                             GValue     *value,
1690                             GParamSpec *pspec)
1691 {
1692   GDBusDaemon *daemon = G_DBUS_DAEMON (object);
1693
1694   switch (prop_id)
1695     {
1696       case PROP_ADDRESS:
1697         g_value_set_string (value, daemon->address);
1698         break;
1699
1700     default:
1701         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1702     }
1703 }
1704
1705 static void
1706 g_dbus_daemon_class_init (GDBusDaemonClass *klass)
1707 {
1708   GObjectClass *gobject_class;
1709
1710   gobject_class = G_OBJECT_CLASS (klass);
1711   gobject_class->finalize = g_dbus_daemon_finalize;
1712   gobject_class->set_property = g_dbus_daemon_set_property;
1713   gobject_class->get_property = g_dbus_daemon_get_property;
1714
1715   g_dbus_daemon_signals[SIGNAL_IDLE_TIMEOUT] =
1716     g_signal_new (I_("idle-timeout"),
1717                   G_TYPE_DBUS_DAEMON,
1718                   G_SIGNAL_RUN_LAST,
1719                   0,
1720                   NULL, NULL,
1721                   NULL,
1722                   G_TYPE_NONE, 0);
1723
1724   g_object_class_install_property (gobject_class,
1725                                    PROP_ADDRESS,
1726                                    g_param_spec_string ("address",
1727                                                         "Bus Address",
1728                                                         "The address the bus should use",
1729                                                         NULL,
1730                                                         G_PARAM_READWRITE |
1731                                                         G_PARAM_CONSTRUCT_ONLY |
1732                                                         G_PARAM_STATIC_STRINGS));
1733 }
1734
1735 static void
1736 g_dbus_daemon_iface_init (_GFreedesktopDBusIface *iface)
1737 {
1738   iface->handle_add_match = handle_add_match;
1739   iface->handle_get_connection_selinux_security_context = handle_get_connection_selinux_security_context;
1740   iface->handle_get_connection_unix_process_id = handle_get_connection_unix_process_id;
1741   iface->handle_get_connection_unix_user = handle_get_connection_unix_user;
1742   iface->handle_get_id = handle_get_id;
1743   iface->handle_get_name_owner = handle_get_name_owner;
1744   iface->handle_hello = handle_hello;
1745   iface->handle_list_activatable_names = handle_list_activatable_names;
1746   iface->handle_list_names = handle_list_names;
1747   iface->handle_list_queued_owners = handle_list_queued_owners;
1748   iface->handle_name_has_owner = handle_name_has_owner;
1749   iface->handle_release_name = handle_release_name;
1750   iface->handle_reload_config = handle_reload_config;
1751   iface->handle_update_activation_environment = handle_update_activation_environment;
1752   iface->handle_remove_match = handle_remove_match;
1753   iface->handle_request_name = handle_request_name;
1754   iface->handle_start_service_by_name = handle_start_service_by_name;
1755 }
1756
1757 static void
1758 initable_iface_init (GInitableIface *initable_iface)
1759 {
1760   initable_iface->init = initable_init;
1761 }
1762
1763 GDBusDaemon *
1764 _g_dbus_daemon_new (const char *address,
1765                     GCancellable *cancellable,
1766                     GError **error)
1767 {
1768   return g_initable_new (G_TYPE_DBUS_DAEMON,
1769                          cancellable,
1770                          error,
1771                          "address", address,
1772                          NULL);
1773 }
1774
1775 const char *
1776 _g_dbus_daemon_get_address (GDBusDaemon *daemon)
1777 {
1778   return g_dbus_server_get_client_address (daemon->server);
1779 }