Merge "Bug fix for kdbus_do_iteration() causing busy loop" into tizen
[platform/upstream/dbus.git] / dbus / dbus-transport-kdbus.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport-kdbus.c  kdbus subclasses of DBusTransport
3  *
4  * Copyright (C) 2002, 2003, 2004, 2006  Red Hat Inc
5  * Copyright (C) 2013  Samsung Electronics
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 and under the terms of the GNU
13  * Lesser General Public License as published by the
14  * Free Software Foundation; either version 2.1 of the License, or (at
15  * your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  */
27 #include <config.h>
28 #include "dbus-transport.h"
29 #include "dbus-transport-kdbus.h"
30 #include "dbus-transport-protected.h"
31 #include "dbus-connection-internal.h"
32 #include "dbus-marshal-gvariant.h"
33 #include "dbus-marshal-validate.h"
34 #include "dbus-asv-util.h"
35 #include "kdbus.h"
36 #include "dbus-watch.h"
37 #include "dbus-errors.h"
38 #include "dbus-bus.h"
39 #include "kdbus-common.h"
40 #include "dbus-protocol-gvariant.h"
41 #include <linux/types.h>
42 #include <errno.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <sys/mman.h>
48 #include <sys/stat.h>
49 #include <sys/syscall.h>
50 #include <fcntl.h>
51 #ifdef LIBDBUSPOLICY
52 #include <dbuspolicy/libdbuspolicy1.h>
53 #include "dbus-marshal-header.h"
54 #include "dbus-protocol-gvariant.h"
55 #endif
56 #include "dbus-sysdeps-unix.h"
57
58 #include <linux/version.h>
59 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
60 #  if defined(__arm__) || defined(__aarch64__)
61 #    define __NR_memfd_create 385
62 #  elif defined(__i386__)
63 #    define __NR_memfd_create 279
64 #  else
65 #    error "Architecture not supported"
66 #  endif
67 #else
68 #  include <linux/memfd.h>
69 #endif
70
71 #ifdef DBUS_ENABLE_VERBOSE_MODE
72 int debug = -1;
73 #endif
74
75 /* FIXME shouldn't it be in fcntl.h header file? copied from systemd's missing.h */
76 #ifndef F_LINUX_SPECIFIC_BASE
77 #define F_LINUX_SPECIFIC_BASE 1024
78 #endif
79
80 #ifndef F_ADD_SEALS
81 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
82 #define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
83
84 #define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
85 #define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
86 #define F_SEAL_GROW     0x0004  /* prevent file from growing */
87 #define F_SEAL_WRITE    0x0008  /* prevent writes */
88 #endif
89
90 #ifndef MFD_CLOEXEC
91 #define MFD_CLOEXEC             0x0001U
92 #endif
93
94 #ifndef MFD_ALLOW_SEALING
95 #define MFD_ALLOW_SEALING       0x0002U
96 #endif
97
98 /* ALIGN8 and KDBUS_FOREACH taken from systemd */
99 #define ALIGN8(l) (((l) + 7) & ~7)
100 #define KDBUS_FOREACH(iter, first, _size)                               \
101         for (iter = (first);                                            \
102              ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) &&      \
103                ((uint8_t *)(iter) >= (uint8_t *)(first));               \
104              iter = (void*)(((uint8_t *)iter) + ALIGN8((iter)->size)))
105 #define KDBUS_DEFAULT_TIMEOUT_NS   5000000000LU
106
107 /**
108  * @defgroup DBusTransportKdbus DBusTransport implementations for kdbus
109  * @ingroup  DBusInternals
110  * @brief Implementation details of DBusTransport on kdbus
111  *
112  * @{
113  */
114
115 /** Default Size of the memory area for received non-memfd messages. */
116 #define RECEIVE_POOL_SIZE_DEFAULT_SIZE (2 * 1024LU * 1024LU)
117 /** Name of environmental variable to define receive pool size*/
118 #define RECEIVE_POOL_SIZE_ENV_VAR_NAME "KDBUS_MEMORY_POOL_SIZE"
119 /** Max size of pool size in megabytes*/
120 #define RECEIVE_POOL_SIZE_MAX_MBYTES 64
121 /** Min size of pool size in kilobytes*/
122 #define RECEIVE_POOL_SIZE_MIN_KBYTES 16
123
124 /** Over this memfd is used to send (if it is not broadcast). */
125 #define MEMFD_SIZE_THRESHOLD (512 * 1024LU)
126
127 /** Define max bytes read or written in one iteration.
128 * This is to avoid blocking on reading or writing for too long. It is checked after each message is sent or received,
129 * so if message is bigger than MAX_BYTES_PER_ITERATION it will be handled in one iteration, but sending/writing
130 * will break after that message.
131 **/
132 #define MAX_BYTES_PER_ITERATION 16384
133
134 #if (MEMFD_SIZE_THRESHOLD > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE)
135   #error  Memfd size threshold higher than max kdbus message payload vector size
136 #endif
137
138 /** Enables verbosing more information about kdbus message.
139  *  Works only if DBUS_VERBOSE=1 is used.
140  */
141 #define KDBUS_MSG_DECODE_DEBUG 0
142
143 /**
144  * Opaque object representing a transport.
145  */
146 typedef struct DBusTransportKdbus DBusTransportKdbus;
147
148 /**
149  * Implementation details of DBusTransportKdbus. All members are private.
150  */
151 struct DBusTransportKdbus
152 {
153   DBusTransport base;                   /**< Parent instance */
154   kdbus_t   *kdbus;                     /**< kdbus data for low level operations */
155   DBusWatch *read_watch;                /**< Watch for readability. */
156   DBusWatch *write_watch;               /**< Watch for writability. */
157
158   int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
159   int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
160
161   char* my_DBus_unique_name;               /**< unique name in DBus string format - :1.x , where x is kdbus id*/
162   char* activator;                      /**< well known name for activator */
163   Matchmaker *matchmaker;            /**< for match rules management */
164   dbus_uint32_t client_serial;           /**< serial number for messages synthesized by library*/
165 #ifdef LIBDBUSPOLICY
166   void *policy;
167 #endif
168 };
169
170 /**
171  * Creates unique name string frong unique id.
172  *
173  *  @param id unique id
174  *  @returns allocated string with unique name
175  *
176  * Caller has to free allocated string with free.
177  */
178 static char *
179 create_unique_name_from_unique_id (unsigned long long id)
180 {
181   char *str = NULL;
182   if (asprintf (&str, ":1.%llu", id) == -1)
183     str = NULL;
184   return str;
185 }
186
187 /**
188  * Puts locally generated message into received messages queue
189  * @param message message that will be added
190  * @param connection connection to which message will be added
191  * @returns TRUE on success, FALSE on memory allocation error
192  */
193 static dbus_bool_t
194 add_message_to_received (DBusMessage     *message,
195                         DBusConnection  *connection)
196 {
197   DBusList *message_link;
198
199   message_link = _dbus_list_alloc_link (message);
200   if (message_link == NULL)
201     {
202       dbus_message_unref (message);
203       return FALSE;
204     }
205
206   dbus_message_lock (message);
207
208   _dbus_connection_queue_synthesized_message_link (connection, message_link);
209   return TRUE;
210 }
211
212 static DBusMessage *
213 reply_with_error_preset_sender (const char     *error_type,
214                                 const char     *template,
215                                 const char     *object,
216                                 DBusMessage    *message,
217                                 const char     *sender)
218 {
219   DBusMessage *errMessage;
220   char* error_msg = "";
221
222   if (template)
223   {
224     size_t len = strlen (template) + strlen (object) + 1;
225     error_msg = alloca (len);
226     snprintf (error_msg, len, template, object);
227   }
228   else if (object)
229     error_msg = (char*)object;
230
231   errMessage = _dbus_generate_local_error_message ( dbus_message_get_serial (message),
232                                                    (char*)error_type,
233                                                    error_msg);
234
235   if (errMessage == NULL)
236      return NULL;
237
238   if (sender)
239     dbus_message_set_sender (errMessage, sender);
240
241   return errMessage;
242 }
243
244 /**
245  * Generates local error message as a reply to message given as parameter
246  * and adds generated error message to received messages queue.
247  * @param error_type type of error, preferably DBUS_ERROR_(...)
248  * @param template Template of error description. It can has formatting
249  *      characters to print object string into it. Can be NULL.
250  * @param object String to print into error description. Can be NULL.
251  *      If object is not NULL while template is NULL, the object string
252  *      will be the only error description.
253  * @param message Message for which the error reply is generated.
254  * @returns local error message on success, otherwise NULL
255  */
256 static DBusMessage *
257 reply_with_error (const char     *error_type,
258                   const char     *template,
259                   const char     *object,
260                   DBusMessage    *message)
261 {
262   return reply_with_error_preset_sender (error_type, template,
263       object, message, NULL);
264 }
265
266 /**
267  *  Generates reply to the message given as a parameter with one item in the reply body
268  *  and adds generated reply message to received messages queue.
269  *  @param message The message we are replying to.
270  *  @param data_type Type of data sent in the reply.Use DBUS_TYPE_(...)
271  *  @param pData Address of data sent in the reply.
272  *  @returns generated reply on success, otherwise NULL
273  */
274 static DBusMessage *
275 reply_1_data (DBusMessage    *message,
276               int             data_type,
277               void           *pData)
278 {
279   DBusMessageIter args;
280   DBusMessage *reply;
281
282   reply = dbus_message_new_method_return (message);
283   if (reply == NULL)
284     return NULL;
285
286   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
287     goto oom_free;
288
289   dbus_message_iter_init_append (reply, &args);
290   if (!dbus_message_iter_append_basic (&args, data_type, pData))
291     goto oom_free;
292
293   return reply;
294
295 oom_free:
296   dbus_message_unref (reply);
297
298   return NULL;
299 }
300
301 static DBusMessage *
302 reply_fixed_array (DBusMessage    *message,
303                    int             element_type,
304                    const void     *data,
305                    int             n_elements)
306 {
307   DBusMessageIter args, array_iter;
308   DBusMessage *reply;
309
310   reply = dbus_message_new_method_return (message);
311   if (reply == NULL)
312     return NULL;
313
314   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
315     goto oom_free;
316
317   dbus_message_iter_init_append (reply, &args);
318
319   if (!dbus_message_iter_open_container (&args,
320                                          DBUS_TYPE_ARRAY,
321                                          DBUS_TYPE_BYTE_AS_STRING,
322                                          &array_iter))
323     goto oom_free;
324
325   if (!dbus_message_iter_append_fixed_array (&array_iter, element_type, &data, n_elements))
326     goto oom_array_iter;
327
328   if (!dbus_message_iter_close_container (&args, &array_iter))
329     goto oom_free;
330
331   return reply;
332
333 oom_array_iter:
334   dbus_message_iter_abandon_container (&args, &array_iter);
335
336 oom_free:
337   dbus_message_unref (reply);
338   return NULL;
339 }
340
341 /**
342  * Retrieves file descriptor to memory pool from kdbus module and stores
343  * it in kdbus_transport->memfd. It is then used to send large message.
344  * Triggered when message payload is over MEMFD_SIZE_THRESHOLD
345  * @param kdbus_transport DBusTransportKdbus transport structure
346  * @returns 0 on success, otherwise -1
347  */
348 static int
349 kdbus_acquire_memfd ( void )
350 {
351   int fd;
352
353   /* FIXME add HAVE_MEMFD_CREATE */
354   if ((fd = syscall (__NR_memfd_create, "kdbus", MFD_ALLOW_SEALING | MFD_CLOEXEC )) < 0)
355     {
356       _dbus_verbose ("memfd_create failed (%d): %m\n", fd);
357     }
358
359   _dbus_verbose ("%s: memfd=%d\n", __FUNCTION__, fd);
360   return fd;
361 }
362
363 static void
364 bloom_add_pair (kdbus_bloom_data_t *bloom_data,
365                 kdbus_t            *kdbus,
366                 const char         *parameter,
367                 const char         *value)
368 {
369   char buf[1024];
370   size_t size;
371
372   if (NULL == value)
373     return;
374
375   size = strlen (parameter) + strlen (value) + 1;
376   if (size > 1024)
377     return;
378
379   snprintf (buf, size, "%s:%s", parameter, value);
380   _kdbus_bloom_add_data (kdbus, bloom_data, buf, size);
381 }
382
383 static void
384 bloom_add_prefixes (kdbus_bloom_data_t *bloom_data,
385                     kdbus_t            *kdbus,
386                     const char         *parameter,
387                     const char         *value,
388                     char                separator)
389 {
390   char buf[1024];
391   size_t size;
392
393   size = strlen (parameter) + strlen (value) + 1;
394   if (size > 1024)
395     return;
396
397   snprintf (buf, size, "%s:%s", parameter, value);
398
399   for (;;)
400     {
401       char *last_sep;
402       last_sep = strrchr (buf, separator);
403       if (!last_sep || last_sep == buf)
404         break;
405
406       *last_sep = 0;
407       _kdbus_bloom_add_data (kdbus, bloom_data, buf, last_sep-buf);
408     }
409 }
410
411 static int
412 setup_bloom_filter_for_message (DBusMessage               *msg,
413                                 kdbus_t                   *kdbus,
414                                 struct kdbus_bloom_filter *bloom_filter)
415 {
416   kdbus_bloom_data_t *bloom_data;
417   unsigned i;
418   const char *str;
419   DBusMessageIter args;
420
421   _dbus_assert (msg);
422   _dbus_assert (bloom_filter);
423
424   bloom_data = _kdbus_bloom_filter_get_data (bloom_filter);
425
426   bloom_add_pair (bloom_data,
427                   kdbus,
428                   "message-type",
429                   dbus_message_type_to_string (dbus_message_get_type (msg)));
430
431   bloom_add_pair (bloom_data, kdbus, "interface", dbus_message_get_interface (msg));
432   bloom_add_pair (bloom_data, kdbus, "member", dbus_message_get_member (msg));
433   str = dbus_message_get_path (msg);
434   if (str)
435     {
436       bloom_add_pair (bloom_data, kdbus, "path", str);
437       bloom_add_pair (bloom_data, kdbus, "path-slash-prefix", str);
438       bloom_add_prefixes (bloom_data, kdbus, "path-slash-prefix", str, '/');
439     }
440
441   if (!dbus_message_iter_init (msg, &args))
442     return 0;
443
444   for (i = 0; i < 64; i++)
445     {
446       char type;
447       char buf[sizeof ("arg")-1 + 2 + sizeof ("-slash-prefix")];
448       char *e;
449       size_t len;
450
451       type = dbus_message_iter_get_arg_type (&args);
452       if (type != DBUS_TYPE_STRING &&
453           type != DBUS_TYPE_OBJECT_PATH &&
454           type != DBUS_TYPE_SIGNATURE)
455         break;
456
457       dbus_message_iter_get_basic (&args, &str);
458
459       snprintf (buf, sizeof (buf), "arg%d", i);
460
461       bloom_add_pair (bloom_data, kdbus, buf, str);
462
463       /* point e to end of string, we will add suffixes */
464       len = strlen (buf);
465       e = buf + len;
466       /* we need remaining length of the buffer */
467       len = sizeof (buf) - len;
468
469       strncpy (e, "-dot-prefix", len);
470       bloom_add_prefixes (bloom_data, kdbus, buf, str, '.');
471       strncpy (e, "-slash-prefix", len);
472       bloom_add_prefixes (bloom_data, kdbus, buf, str, '/');
473
474       if (!dbus_message_iter_next (&args))
475         break;
476   }
477
478   return 0;
479 }
480
481 /**
482  * Checks if a string is a unique name or well known name.
483  *
484  * @param name a valid D-Bus name
485  * @returns 0 for well-known names, otherwise unique id
486  */
487 static dbus_uint64_t
488 parse_name (const char *name)
489 {
490   dbus_uint64_t unique_id = 0;
491   char *endptr;
492   /* if name is unique name it must be converted to unique id */
493   if (strncmp (name, ":1.", 3) == 0)
494     {
495       errno = 0;
496       unique_id = strtoull (&name[3], &endptr, 10);
497
498       if (unique_id == 0 || *endptr != '\0' || errno ==  ERANGE)
499         return 0;
500     }
501
502   return unique_id;
503 }
504
505 static int
506 prepare_mfd (int memfd,
507              const char *header,
508              uint64_t header_size,
509              const char *body,
510              uint64_t body_size)
511 {
512   const char *data[] = { header, body };
513   uint64_t count[] = { header_size, body_size };
514   int64_t wr;
515   size_t p;
516
517   _dbus_verbose ("sending data via memfd\n");
518   for (p = 0; p < sizeof (data) / sizeof (data[0]); ++p)
519     {
520       while (count[p])
521         {
522           wr = write (memfd, data[p], count[p]);
523           if (wr < 0)
524             {
525               _dbus_verbose ("writing to memfd failed: (%d) %m\n", errno);
526               return -1;
527             }
528           count[p] -= wr;
529           data[p] += wr;
530         }
531     }
532
533   // seal data - kdbus module needs it
534   if (fcntl (memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) < 0)
535     {
536       _dbus_verbose ("memfd sealing failed: %d (%m)\n", errno);
537       return -1;
538     }
539   return 0;
540 }
541
542 static int
543 send_message (DBusTransportKdbus *transport,
544               struct kdbus_msg   *kdbus_msg,
545               dbus_bool_t         sync,
546               const char         *destination,
547               dbus_bool_t         is_auto_start,
548               struct kdbus_msg  **kdbus_msg_reply,
549               DBusError          *error)
550 {
551   int ret;
552   dbus_uint64_t flags = 0;
553
554   if (sync)
555     flags |= KDBUS_SEND_SYNC_REPLY;
556
557   ret = _kdbus_send (transport->kdbus,
558                      flags,
559                      kdbus_msg,
560                      kdbus_msg_reply);
561   if (ret != 0)
562     {
563       _dbus_verbose ("kdbus error sending message: err %d (%s)\n", ret, _dbus_strerror (ret) );
564
565       switch (ret)
566         {
567           case ENXIO: /* no such id on the bus */
568           case ESRCH:
569             dbus_set_error (error,
570                             DBUS_ERROR_NAME_HAS_NO_OWNER,
571                             "Name \"%s\" does not exist",
572                             destination);
573             break;
574
575           case EADDRNOTAVAIL:
576           case ECONNRESET:
577             /* when well known name is not available on the bus */
578             if (is_auto_start)
579                 dbus_set_error (error,
580                                 DBUS_ERROR_SERVICE_UNKNOWN,
581                                 "The name %s was not provided by any .service files",
582                                 destination);
583             else
584                 dbus_set_error (error,
585                                 DBUS_ERROR_NAME_HAS_NO_OWNER,
586                                 "Name \"%s\" does not exist",
587                                 destination);
588             break;
589
590           case EMLINK:
591             dbus_set_error (error,
592                             DBUS_ERROR_LIMITS_EXCEEDED,
593                             NULL,
594                             "The maximum number of pending replies per connection has been reached");
595             break;
596
597           case ENOBUFS:
598           case EXFULL:
599             dbus_set_error (error,
600                             DBUS_ERROR_LIMITS_EXCEEDED,
601                             "No space in receiver's buffer",
602                             destination);
603             break;
604
605           default:
606             break;
607         }
608
609       ret = -1;
610     }
611   return ret;
612 }
613
614 static void
615 kdbus_close_message (DBusTransportKdbus *transport, struct kdbus_msg *msg)
616 {
617   struct kdbus_item *item;
618
619   KDBUS_ITEM_FOREACH (item, msg, items)
620     {
621       if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
622         close (item->memfd.fd);
623     }
624
625   _kdbus_free_mem (transport->kdbus, msg);
626 }
627
628 #ifdef DBUS_ENABLE_VERBOSE_MODE
629 static void
630 debug_c_str (const char *msg, const char *str, int len)
631 {
632   int i;
633   fprintf (stderr, "%s\n", msg);
634   for (i = 0; i < len; i++)
635   {
636       fprintf (stderr, "%02x ", (unsigned char)str[i]);
637       if (i%16==15) fprintf (stderr, "\n");
638   }
639   fprintf (stderr, "\n");
640 }
641
642 static void
643 debug_str (const char *msg, const DBusString *str)
644 {
645   debug_c_str (msg, _dbus_string_get_const_data (str), _dbus_string_get_length (str));
646 }
647 #endif
648
649 static dbus_bool_t
650 can_send (DBusTransportKdbus *transport,
651           DBusMessage        *message)
652 {
653   dbus_bool_t result = TRUE;
654
655 #ifdef LIBDBUSPOLICY
656   {
657     int ret = 1;
658     if (NULL != transport->policy)
659       {
660         dbus_uint32_t reply_serial = dbus_message_get_reply_serial (message);
661
662         /* If reply_serial is non-zero, then it is a reply - just send it.
663          * Otherwise - check the policy.
664          */
665         if (0 == reply_serial)
666           ret = dbuspolicy1_check_out (transport->policy,
667                                        dbus_message_get_destination (message),
668                                        dbus_message_get_sender (message),
669                                        dbus_message_get_path (message),
670                                        dbus_message_get_interface (message),
671                                        dbus_message_get_member (message),
672                                        dbus_message_get_type (message),
673                                        dbus_message_get_error_name (message),
674                                        reply_serial,
675                                        !dbus_message_get_no_reply (message));
676       }
677     result = (1 == ret);
678   }
679 #endif
680
681   return result;
682 }
683
684 static int
685 kdbus_write_msg_internal (DBusTransportKdbus  *transport,
686                           DBusMessage         *message,
687                           const char          *destination,
688                           dbus_bool_t          check_sync_reply,
689                           dbus_bool_t          check_privileges)
690 {
691   struct kdbus_msg *msg = NULL;
692   struct kdbus_msg *msg_reply = NULL;
693   struct kdbus_item *item;
694   uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
695   const DBusString *header;
696   const DBusString *body;
697   int64_t ret_size = -1;
698   uint64_t body_size = 0;
699   uint64_t header_size = 0;
700   int memfd = -1;
701   const int *unix_fds;
702   unsigned fds_count;
703   DBusError error;
704
705   dbus_uint64_t items_size;
706   dbus_uint64_t flags = 0;
707   dbus_uint64_t timeout_ns_or_cookie_reply = 0;
708
709
710   dbus_error_init (&error);
711
712   // determine destination and destination id
713   if (destination)
714     {
715       DBusString str;
716
717       _dbus_string_init_const (&str, destination);
718       if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
719         {
720           _dbus_verbose ("error: unique name is not valid: %s\n", destination);
721           return -1;
722         }
723
724       dst_id = parse_name (destination);
725       if (0 != dst_id)
726         destination = NULL;
727       else
728         dst_id = KDBUS_DST_ID_NAME;     /* OK, this is zero anyway
729                                          * but leave it in case
730                                          * the kdbus constant changes
731                                          */
732     }
733
734   _dbus_message_get_network_data (message, &header, &body);
735   header_size = _dbus_string_get_length (header);
736   body_size = _dbus_string_get_length (body);
737   ret_size = header_size + body_size;
738
739   /* check whether we can and should use memfd */
740   if ((dst_id != KDBUS_DST_ID_BROADCAST) && (ret_size > MEMFD_SIZE_THRESHOLD))
741       memfd = kdbus_acquire_memfd ();
742
743   _dbus_message_get_unix_fds (message, &unix_fds, &fds_count);
744
745   items_size = _kdbus_compute_msg_items_size (transport->kdbus,
746                                               destination,
747                                               dst_id,
748                                               body_size,
749                                               memfd >= 0,
750                                               fds_count);
751
752   if (!dbus_message_get_auto_start (message))
753     flags |= KDBUS_MSG_NO_AUTO_START;
754
755   if (KDBUS_DST_ID_BROADCAST == dst_id)       /* signals */
756       flags |= KDBUS_MSG_SIGNAL;
757   else
758     {
759       if (dbus_message_get_no_reply (message)) /* method replies and errors */
760         timeout_ns_or_cookie_reply = dbus_message_get_reply_serial (message);
761       else                                    /* method calls */
762         {
763           long tv_sec, tv_usec;
764
765           _dbus_get_monotonic_time (&tv_sec, &tv_usec);
766                                            /* ms        us        ns */
767           timeout_ns_or_cookie_reply = (dbus_uint64_t)tv_sec * 1000ULL * 1000ULL * 1000ULL
768                                        + tv_usec * 1000ULL
769                                        + KDBUS_DEFAULT_TIMEOUT_NS;
770
771           flags |= KDBUS_MSG_EXPECT_REPLY;
772         }
773     }
774
775   msg = _kdbus_new_msg (transport->kdbus,
776                         items_size,
777                         flags,
778                         0,
779                         dst_id,
780                         0,
781                         KDBUS_PAYLOAD_DBUS,
782                         dbus_message_get_serial (message),
783                         timeout_ns_or_cookie_reply);
784   if (NULL == msg)
785     return -1;
786
787   /* build message contents */
788   item = msg->items;
789
790   if (memfd >= 0)
791     {
792       if (prepare_mfd (memfd,
793                        _dbus_string_get_const_data (header), header_size,
794                        _dbus_string_get_const_data (body), body_size) == -1)
795         {
796           ret_size = -1;
797           goto out;
798         }
799
800       item = _kdbus_item_add_payload_memfd (item,
801                                             0,
802                                             ret_size,
803                                             memfd);
804     }
805   else
806     {
807       const char* header_data = _dbus_string_get_const_data (header);
808
809       _dbus_verbose ("sending data by vec\n");
810       item = _kdbus_item_add_payload_vec (item,
811                                           header_size,
812                                           (uintptr_t)header_data);
813       if (body_size > 0)
814         {
815           const char* body_data = _dbus_string_get_const_data (body);
816
817 #ifdef DBUS_ENABLE_VERBOSE_MODE
818           if (-1 != debug)
819             {
820               debug_str ("Header to send:", header);
821               debug_str ("Body to send:", body);
822             }
823 #endif
824
825           while (body_size > 0)
826             {
827               dbus_uint64_t part_size = body_size;
828
829               if (part_size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE)
830                 part_size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
831
832               _dbus_verbose ("attaching body part\n");
833               item = _kdbus_item_add_payload_vec (item,
834                                                   part_size,
835                                                   (uintptr_t)body_data);
836               body_data += part_size;
837               body_size -= part_size;
838             }
839         }
840     }
841
842   if (fds_count)
843       item = _kdbus_item_add_fds (item, unix_fds, fds_count);
844
845   if (NULL != destination)
846       item = _kdbus_item_add_string (item,
847                                      KDBUS_ITEM_DST_NAME,
848                                      destination,
849                                      strlen (destination) + 1);
850   else if (dst_id == KDBUS_DST_ID_BROADCAST)
851     {
852       struct kdbus_bloom_filter *filter = NULL;
853       item = _kdbus_item_add_bloom_filter (item,
854                                            transport->kdbus,
855                                            &filter);
856       setup_bloom_filter_for_message (message, transport->kdbus, filter);
857     }
858
859   if (check_privileges && !can_send (transport, message))
860     {
861       DBusMessage *reply;
862
863       reply = reply_with_error (DBUS_ERROR_ACCESS_DENIED,
864                                 NULL,
865                                 "Cannot send message - message rejected "
866                                 "due to security policies",
867                                 message);
868       if (reply == NULL)
869         {
870           ret_size = -1;
871         }
872       else
873         {
874           /* puts locally generated reply into received messages queue */
875           if (!add_message_to_received (reply, transport->base.connection))
876             ret_size = -1;
877         }
878
879       goto out;
880     }
881
882   if (send_message (transport,
883                     msg,
884                     check_sync_reply,
885                     dbus_message_get_destination (message),
886                     dbus_message_get_auto_start (message),
887                     &msg_reply,
888                     &error) != 0)
889     {
890       DBusMessage *reply = NULL;
891
892       if (dbus_error_is_set (&error))
893         {
894           reply = reply_with_error (error.name,
895                                     NULL,
896                                     error.message,
897                                     message);
898         }
899
900       if (reply == NULL)
901         {
902           ret_size = -1;
903         }
904       else
905         {
906           /* puts locally generated reply into received messages queue */
907           if (!add_message_to_received (reply, transport->base.connection))
908             ret_size = -1;
909         }
910     }
911
912   if (-1 != ret_size && check_sync_reply)
913     kdbus_close_message (transport, msg_reply);
914
915   out:
916   if (msg)
917     _kdbus_free_msg (msg);
918   if (memfd >= 0)
919     close (memfd);
920
921   return ret_size;
922 }
923
924 /**
925  * Sends DBus message using kdbus.
926  * Handles broadcasts and unicast messages, and passing of Unix fds.
927  * Also can locally generate error replies on some error returned by kernel.
928  *
929  * TODO refactor to be more compact - maybe we can send header always as a payload vector
930  *  and only message body as memfd if needed.
931  *
932  * @param transport Transport.
933  * @param message DBus message to be sent
934  * @param destination Destination of the message.
935  * @returns bytes sent or -1 if sending failed
936  */
937 static int
938 kdbus_write_msg (DBusTransportKdbus  *transport,
939                  DBusMessage         *message,
940                  const char          *destination)
941 {
942   return kdbus_write_msg_internal (transport, message, destination, FALSE, TRUE);
943 }
944
945 static dbus_uint64_t
946 get_pool_size (void)
947 {
948   dbus_uint64_t receive_pool_size = RECEIVE_POOL_SIZE_DEFAULT_SIZE;
949   const char *env_pool;
950
951   env_pool = _dbus_getenv (RECEIVE_POOL_SIZE_ENV_VAR_NAME);
952   if (env_pool)
953     {
954       dbus_uint64_t size = 0;
955       unsigned int multiply = 1;
956       long int page_size;
957
958       page_size = sysconf (_SC_PAGESIZE);
959       if (page_size == -1)
960         {
961           goto finish;
962         }
963
964       errno = 0;
965       size = strtoul (env_pool, (char**)&env_pool, 10);
966       if ((errno == EINVAL) || size == 0)
967         {
968           size = 0;
969           goto finish;
970         }
971
972       if (*env_pool == 'k')
973         {
974           multiply = 1024;
975           env_pool++;
976         }
977       else if (*env_pool == 'M')
978         {
979           multiply = 1024 * 1024;
980           env_pool++;
981         }
982
983       if (*env_pool != '\0')
984         {
985           size = 0;
986           goto finish;
987         }
988
989       receive_pool_size = size * multiply;
990
991       if ((receive_pool_size > RECEIVE_POOL_SIZE_MAX_MBYTES * 1024 * 1024) ||
992          (receive_pool_size < RECEIVE_POOL_SIZE_MIN_KBYTES * 1024) ||
993          ((receive_pool_size & (page_size - 1)) != 0))  //pool size must be aligned to page size
994         size = 0;
995
996     finish:
997       if (size == 0)
998         {
999           _dbus_warn ("%s value is invalid, default value %luB will be used.\n", RECEIVE_POOL_SIZE_ENV_VAR_NAME,
1000                       RECEIVE_POOL_SIZE_DEFAULT_SIZE);
1001           _dbus_warn ("Correct value must be between %ukB and %uMB and must be aligned to page size: %ldB.\n",
1002                       RECEIVE_POOL_SIZE_MIN_KBYTES, RECEIVE_POOL_SIZE_MAX_MBYTES, page_size);
1003
1004           receive_pool_size = RECEIVE_POOL_SIZE_DEFAULT_SIZE;
1005         }
1006     }
1007
1008   _dbus_verbose ("Receive pool size set to %llu.\n", (unsigned long long)receive_pool_size);
1009   return receive_pool_size;
1010 }
1011
1012 static dbus_uint64_t
1013 get_attach_flags_recv (DBusTransportKdbus *transport)
1014 {
1015   dbus_uint64_t attach_flags_recv = 0;
1016
1017 #ifdef LIBDBUSPOLICY
1018   attach_flags_recv = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_NAMES | KDBUS_ATTACH_SECLABEL;
1019 #endif
1020
1021   return attach_flags_recv;
1022 }
1023
1024 /**
1025  * Performs kdbus hello - registration on the kdbus bus
1026  * needed to send and receive messages on the bus,
1027  * and configures transport.
1028  * As a result unique id on he bus is obtained.
1029  *
1030  * @see KDBUS_HELLO_* flags in kdbus.h
1031  *
1032  * @param transport transport structure
1033  * @param registration_flags aditional flags to modify registration process
1034  * @returns #TRUE on success
1035  */
1036 static dbus_bool_t
1037 bus_register_kdbus (DBusTransportKdbus *transport,
1038                     dbus_uint32_t       registration_flags,
1039                     DBusError          *error)
1040 {
1041   int ret;
1042   dbus_uint64_t flags;
1043
1044   flags = KDBUS_HELLO_ACCEPT_FD;
1045   if (registration_flags & REGISTER_FLAG_MONITOR)
1046     flags |= KDBUS_HELLO_MONITOR;
1047
1048   ret = _kdbus_hello (transport->kdbus,
1049                       flags,
1050                       _KDBUS_ATTACH_ANY,
1051                       get_attach_flags_recv (transport),
1052                       get_pool_size (),
1053                       transport->activator,
1054                       "libdbus-kdbus");
1055   if (ret != 0)
1056     {
1057       dbus_set_error (error, DBUS_ERROR_FAILED, "Hello failed: %d", -ret);
1058       return FALSE;
1059     }
1060
1061   transport->my_DBus_unique_name = create_unique_name_from_unique_id (_kdbus_get_id (transport->kdbus));
1062   if (NULL == transport->my_DBus_unique_name)
1063     {
1064       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, "Hello post failed: %d", -ret);
1065       return FALSE;
1066     }
1067
1068   _dbus_verbose ("-- Our peer ID is: %llu\n", (unsigned long long)_kdbus_get_id (transport->kdbus));
1069
1070   return TRUE;
1071 }
1072
1073 static dbus_bool_t
1074 can_own (DBusTransportKdbus *transport,
1075          const char         *name)
1076 {
1077   dbus_bool_t result = TRUE;
1078
1079 #ifdef LIBDBUSPOLICY
1080   if (NULL != transport->policy)
1081     result = (dbuspolicy1_can_own (transport->policy, name) == 1);
1082 #endif
1083
1084   return result;
1085 }
1086
1087 static dbus_bool_t
1088 request_DBus_name (DBusTransportKdbus *transport,
1089                    DBusMessage        *msg,
1090                    int                *result,
1091                    DBusError          *error)
1092 {
1093   DBusString service_name_real;
1094   const DBusString *service_name = &service_name_real;
1095   char* name;
1096   dbus_uint32_t flags;
1097
1098   if (!dbus_message_get_args (msg, error,
1099                               DBUS_TYPE_STRING, &name,
1100                               DBUS_TYPE_UINT32, &flags,
1101                               DBUS_TYPE_INVALID))
1102    return FALSE;
1103
1104   _dbus_string_init_const (&service_name_real, name);
1105
1106   if (!_dbus_validate_bus_name (service_name, 0,
1107                                _dbus_string_get_length (service_name)))
1108    {
1109      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1110                      "Requested bus name \"%s\" is not valid", name);
1111
1112      _dbus_verbose ("Attempt to acquire invalid service name\n");
1113
1114      return FALSE;
1115    }
1116
1117   if (_dbus_string_get_byte (service_name, 0) == ':')
1118    {
1119      /* Not allowed; only base services can start with ':' */
1120      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1121                      "Cannot acquire a service starting with ':' such as \"%s\"", name);
1122
1123      _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"", name);
1124
1125      return FALSE;
1126    }
1127
1128   if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
1129    {
1130      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1131                      "Connection is not allowed to own the service \"%s\"because "
1132                      "it is reserved for D-Bus' use only", DBUS_SERVICE_DBUS);
1133      return FALSE;
1134    }
1135
1136   if (!can_own (transport, name))
1137     {
1138       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1139                       "Connection \"%s\" is not allowed to own the "
1140                       "service \"%s\" due to security policies",
1141                       transport->my_DBus_unique_name,
1142                       name);
1143       return FALSE;
1144     }
1145
1146   *result = _kdbus_request_name (transport->kdbus, name, flags);
1147   if (*result == -EPERM)
1148    {
1149      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1150          "Kdbus doesn't allow %s to own the service \"%s\"",
1151          transport->my_DBus_unique_name, _dbus_string_get_const_data (service_name));
1152      return FALSE;
1153    }
1154   else if (*result < 0)
1155    {
1156      dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired, %d, %m", name, errno);
1157      return FALSE;
1158    }
1159
1160   return TRUE;
1161 }
1162
1163 static dbus_bool_t
1164 release_DBus_name (DBusTransportKdbus *transport,
1165                    DBusMessage        *msg,
1166                    int                *result,
1167                    DBusError          *error)
1168 {
1169   const char *name;
1170   DBusString service_name;
1171
1172   if (!dbus_message_get_args (msg, error,
1173                               DBUS_TYPE_STRING, &name,
1174                               DBUS_TYPE_INVALID))
1175     return FALSE;
1176
1177   _dbus_string_init_const (&service_name, name);
1178
1179   if (!_dbus_validate_bus_name (&service_name, 0,
1180                                 _dbus_string_get_length (&service_name)))
1181     {
1182       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1183                       "Given bus name \"%s\" is not valid",
1184                       _dbus_string_get_const_data (&service_name));
1185
1186       _dbus_verbose ("Attempt to release invalid service name\n");
1187       return FALSE;
1188     }
1189
1190   if (_dbus_string_get_byte (&service_name, 0) == ':')
1191     {
1192       /* Not allowed; the base service name cannot be created or released */
1193       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1194                       "Cannot release a service starting with ':' such as \"%s\"",
1195                       _dbus_string_get_const_data (&service_name));
1196
1197       _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
1198                      _dbus_string_get_const_data (&service_name));
1199       return FALSE;
1200     }
1201
1202    if (_dbus_string_equal_c_str (&service_name, DBUS_SERVICE_DBUS))
1203     {
1204       /* Not allowed; the base service name cannot be created or released */
1205       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1206                       "Cannot release the %s service because it is owned by the bus",
1207                      DBUS_SERVICE_DBUS);
1208
1209       _dbus_verbose ("Attempt to release service name \"%s\"",
1210                      DBUS_SERVICE_DBUS);
1211       return FALSE;
1212     }
1213
1214     *result = _kdbus_release_name (transport->kdbus, name);
1215     if (*result < 0)
1216       {
1217         dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be released, %d, %m", name, errno);
1218         return FALSE;
1219       }
1220
1221     return TRUE;
1222 }
1223
1224 static int
1225 strcmp_existing (const char *str1, const char *str2)
1226 {
1227   if (NULL == str1 || NULL == str2)
1228     return 0;
1229   return strcmp (str1, str2);
1230 }
1231
1232 static dbus_bool_t
1233 kernel_match_needed (MatchRule *rule)
1234 {
1235   int message_type;
1236
1237   /* Allow only NameOwnerChanged member */
1238   if (strcmp_existing (_match_rule_get_member (rule), "NameOwnerChanged") != 0)
1239     return FALSE;
1240
1241   /* Allow only signals */
1242   message_type = _match_rule_get_message_type (rule);
1243   if (message_type != DBUS_MESSAGE_TYPE_INVALID && message_type != DBUS_MESSAGE_TYPE_SIGNAL)
1244     return FALSE;
1245
1246   /* Check if from DBus */
1247   if (strcmp_existing (_match_rule_get_sender (rule), DBUS_SERVICE_DBUS) != 0)
1248     return FALSE;
1249
1250   if (strcmp_existing (_match_rule_get_interface (rule), DBUS_INTERFACE_DBUS) != 0)
1251     return FALSE;
1252
1253   if (strcmp_existing (_match_rule_get_path (rule), DBUS_PATH_DBUS) != 0)
1254     return FALSE;
1255
1256   return TRUE;
1257 }
1258
1259 static dbus_bool_t
1260 is_bloom_needed (MatchRule *rule)
1261 {
1262   int rule_int;
1263   int i;
1264
1265   if (_match_rule_get_message_type (rule) != DBUS_TYPE_INVALID
1266       || _match_rule_get_interface (rule) != NULL
1267       || _match_rule_get_member (rule) != NULL
1268       || _match_rule_get_path (rule) != NULL
1269       || _match_rule_get_path_namespace (rule) != NULL)
1270     return TRUE;
1271
1272   rule_int = _match_rule_get_args_len (rule);
1273   for (i = 0; i < rule_int; i++)
1274     {
1275       if (_match_rule_get_args (rule, i) != NULL)
1276         return TRUE;
1277     }
1278
1279   return FALSE;
1280 }
1281
1282 static void
1283 get_bloom (kdbus_t *kdbus, MatchRule *rule, kdbus_bloom_data_t *bloom_data)
1284 {
1285   int rule_int;
1286   const char *rule_string;
1287   int i;
1288   char argument_buf[sizeof ("arg")-1 + 2 + sizeof ("-slash-prefix") +1];
1289
1290   rule_int = _match_rule_get_message_type (rule);
1291   if (rule_int != DBUS_MESSAGE_TYPE_INVALID)
1292   {
1293     bloom_add_pair (bloom_data, kdbus, "message-type", dbus_message_type_to_string (rule_int));
1294     _dbus_verbose ("Adding type %s \n", dbus_message_type_to_string (rule_int));
1295   }
1296
1297   rule_string = _match_rule_get_interface (rule);
1298   if (rule_string != NULL)
1299     {
1300       bloom_add_pair (bloom_data, kdbus, "interface", rule_string);
1301       _dbus_verbose ("Adding interface %s \n", rule_string);
1302     }
1303
1304   rule_string = _match_rule_get_member (rule);
1305   if (rule_string != NULL)
1306   {
1307     bloom_add_pair (bloom_data, kdbus, "member", rule_string);
1308     _dbus_verbose ("Adding member %s \n", rule_string);
1309   }
1310
1311   rule_string = _match_rule_get_path (rule);
1312   if (rule_string != NULL)
1313   {
1314     bloom_add_pair (bloom_data, kdbus, "path", rule_string);
1315     _dbus_verbose ("Adding path %s \n", rule_string);
1316   }
1317
1318   rule_string = _match_rule_get_path_namespace (rule);
1319   if (rule_string != NULL)
1320   {
1321     bloom_add_pair (bloom_data, kdbus, "path-slash-prefix", rule_string);
1322     _dbus_verbose ("Adding path-slash-prefix %s \n", rule_string);
1323   }
1324
1325   rule_int = _match_rule_get_args_len (rule);
1326   for (i = 0; i < rule_int; i++)
1327     {
1328       rule_string = _match_rule_get_args (rule, i);
1329       if (rule_string != NULL)
1330         {
1331           unsigned int rule_arg_lens = _match_rule_get_arg_lens (rule, i);
1332           if (rule_arg_lens & MATCH_ARG_IS_PATH)
1333             {
1334               snprintf (argument_buf, sizeof (argument_buf), "arg%d-slash-prefix", i);
1335               bloom_add_prefixes (bloom_data, kdbus, argument_buf, rule_string, '/');
1336             }
1337           else if (rule_arg_lens & MATCH_ARG_NAMESPACE)
1338             {
1339               snprintf (argument_buf, sizeof (argument_buf), "arg%d-dot-prefix", i);
1340               bloom_add_prefixes (bloom_data, kdbus, argument_buf, rule_string, '.');
1341             }
1342           else
1343             {
1344               snprintf (argument_buf, sizeof (argument_buf), "arg%d", i);
1345               bloom_add_pair (bloom_data, kdbus, argument_buf, rule_string);
1346             }
1347         }
1348     }
1349 }
1350
1351 /**
1352  * Adds a match rule to match broadcast messages going through the message bus.
1353  * Do no affect messages addressed directly.
1354  *
1355  * TODO add error reporting
1356  *
1357  * @param transport transport
1358  * @param match rule
1359  */
1360 static dbus_bool_t
1361 add_match_kdbus (DBusTransportKdbus *transport,
1362                  MatchRule          *rule)
1363 {
1364   struct kdbus_cmd_match    *cmd;
1365   struct kdbus_item         *item;
1366   __u64       rule_cookie;
1367   uint64_t    src_id = KDBUS_MATCH_ID_ANY;
1368   __u64       items_size;
1369   dbus_bool_t need_bloom = FALSE;
1370
1371   const char *rule_sender;
1372   int ret;
1373
1374   rule_cookie = match_rule_get_cookie (rule);
1375
1376 /*
1377  * First check if it is org.freedesktop.DBus's NameOwnerChanged or any
1378  * org.freedesktop.DBus combination that includes this,
1379  * because it must be converted to special kdbus rule (kdbus has separate rules
1380  * for kdbus (kernel) generated broadcasts).
1381  */
1382   if (kernel_match_needed (rule))
1383     {
1384       ret = _kdbus_add_match_name_change (transport->kdbus,
1385                                           0,
1386                                           rule_cookie,
1387                                           KDBUS_MATCH_ID_ANY,
1388                                           0,
1389                                           KDBUS_MATCH_ID_ANY,
1390                                           0);
1391       if (0 != ret)
1392         {
1393           _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
1394                          ret, _dbus_strerror (ret));
1395           return FALSE;
1396         }
1397
1398       ret = _kdbus_add_match_id_change (transport->kdbus,
1399                                         0,
1400                                         rule_cookie,
1401                                         KDBUS_MATCH_ID_ANY,
1402                                         0);
1403       if (0 != ret)
1404         {
1405           _dbus_verbose ("Failed adding match rule for adding id for daemon, error: %d, %s\n",
1406                          ret, _dbus_strerror (ret));
1407           return FALSE;
1408         }
1409
1410       _dbus_verbose ("Added match rule for kernel correctly.\n");
1411
1412 /*
1413  * In case all of sender, interface and path are NULL, the rule
1414  * says simply about NameHasOwner signal from any object, any interface, any sender.
1415  * So, we need to consider that.
1416  * Otherwise, our job is finished here.
1417  */
1418       if (_match_rule_get_sender (rule) != NULL
1419           || _match_rule_get_interface (rule) != NULL
1420           || _match_rule_get_path (rule) != NULL)
1421         return TRUE;
1422     }
1423
1424 /*
1425  * standard rule - registered in general way, for non-kernel broadcasts
1426  * kdbus doesn't use it to check kdbus (kernel) generated broadcasts
1427  */
1428
1429   need_bloom = is_bloom_needed (rule);
1430
1431   rule_sender = _match_rule_get_sender (rule);
1432   if (rule_sender != NULL)
1433     {
1434       DBusString str;
1435       _dbus_string_init_const (&str, rule_sender);
1436
1437       if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
1438         return FALSE;
1439
1440       src_id = parse_name (rule_sender);
1441       if (0 == src_id)
1442           /* well-known name */
1443           src_id = KDBUS_MATCH_ID_ANY;
1444       else
1445           /* unique id */
1446           rule_sender = NULL;
1447     }
1448
1449   items_size = _kdbus_compute_match_items_size (transport->kdbus,
1450                                                 need_bloom,
1451                                                 src_id,
1452                                                 rule_sender);
1453
1454   cmd = _kdbus_new_cmd_match (transport->kdbus,
1455                               items_size,
1456                               0,
1457                               rule_cookie);
1458   if (NULL == cmd)
1459     ret = ENOMEM;
1460   else
1461     {
1462       item = cmd->items;
1463       if (NULL != rule_sender)  /* well-known name */
1464         {
1465           item = _kdbus_item_add_string (item,
1466                                          KDBUS_ITEM_NAME,
1467                                          rule_sender,
1468                                          strlen (rule_sender) + 1);
1469           _dbus_verbose ("Adding sender %s \n", rule_sender);
1470         }
1471       else if (KDBUS_MATCH_ID_ANY != src_id) /* unique id */
1472         {
1473           item = _kdbus_item_add_id (item, src_id);
1474           _dbus_verbose ("Adding src_id %llu \n", (unsigned long long)src_id);
1475         }
1476
1477       if (need_bloom)
1478         {
1479           __u64 *bloom;
1480           item = _kdbus_item_add_bloom_mask (item, transport->kdbus, &bloom);
1481           get_bloom (transport->kdbus, rule, bloom);
1482         }
1483
1484       ret = _kdbus_add_match (transport->kdbus, cmd);
1485
1486       _kdbus_free_cmd_match (cmd);
1487     }
1488
1489   if (0 != ret)
1490     {
1491       _dbus_verbose ("Failed adding match bus rule cookie %llu,\nerror: %d, %s\n",
1492                      rule_cookie, ret, _dbus_strerror (ret));
1493       return FALSE;
1494     }
1495
1496   _dbus_verbose ("Added match bus rule %llu\n", rule_cookie);
1497   return TRUE;
1498 }
1499
1500 static DBusMessage *
1501 capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport,
1502                                     DBusMessage        *message,
1503                                     DBusError          *error)
1504 {
1505   DBusMessageIter args;
1506   dbus_uint32_t registration_flags = 0;
1507
1508   dbus_message_iter_init (message, &args);
1509   if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_UINT32)
1510     dbus_message_iter_get_basic (&args, &registration_flags);
1511
1512   if (!bus_register_kdbus (transport, registration_flags, error))
1513     goto out;
1514
1515   return reply_1_data (message, DBUS_TYPE_STRING, &transport->my_DBus_unique_name);
1516
1517 out:
1518   free (transport->my_DBus_unique_name);
1519   return NULL;
1520 }
1521
1522 static DBusMessage *
1523 capture_org_freedesktop_DBus_RequestName (DBusTransportKdbus *transport,
1524                                           DBusMessage        *message,
1525                                           DBusError          *error)
1526 {
1527   int result;
1528
1529   if (!request_DBus_name (transport, message, &result, error))
1530     return NULL;
1531
1532   return reply_1_data (message, DBUS_TYPE_UINT32, &result);
1533 }
1534
1535 static DBusMessage *
1536 capture_org_freedesktop_DBus_ReleaseName (DBusTransportKdbus *transport,
1537                                           DBusMessage        *message,
1538                                           DBusError          *error)
1539 {
1540   int result;
1541
1542   if (!release_DBus_name (transport, message, &result, error))
1543     return NULL;
1544
1545   return reply_1_data (message, DBUS_TYPE_UINT32, &result);
1546 }
1547
1548 static DBusMessage *
1549 capture_org_freedesktop_DBus_AddMatch (DBusTransportKdbus *transport,
1550                                        DBusMessage        *message,
1551                                        DBusError          *error)
1552 {
1553   const char *arg;
1554   DBusString arg_str;
1555   MatchRule *rule = NULL;
1556   DBusConnection *connection = transport->base.connection;
1557
1558   if (!dbus_message_get_args (message, error,
1559         DBUS_TYPE_STRING, &arg,
1560         DBUS_TYPE_INVALID))
1561     goto failed;
1562
1563   _dbus_string_init_const (&arg_str, arg);
1564
1565   rule = match_rule_parse (connection, &arg_str, error);
1566   if (rule == NULL)
1567     goto failed;
1568
1569   if (!matchmaker_add_rule (transport->matchmaker, rule))
1570   {
1571     dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, "No memory to store match rule");
1572     goto failed;
1573   }
1574
1575   if (!add_match_kdbus (transport, rule))
1576   {
1577     dbus_set_error (error, _dbus_error_from_errno (errno), "Could not add match rule, %s",
1578         _dbus_strerror_from_errno ());
1579     goto failed;
1580   }
1581
1582   match_rule_unref (rule);
1583   return dbus_message_new_method_return (message);
1584
1585 failed:
1586   if (rule)
1587     match_rule_unref (rule);
1588   _dbus_verbose ("Error during AddMatch in lib: %s, %s\n", error->name, error->message);
1589   return NULL;
1590 }
1591
1592 static dbus_uint64_t
1593 get_match_cookie_for_remove (Matchmaker *matchmaker, MatchRule *rule_to_remove)
1594 {
1595   DBusList *rules = matchmaker_get_rules_list (matchmaker, rule_to_remove);
1596   if (NULL != rules)
1597     {
1598       DBusList *link = _dbus_list_get_last_link (&rules);
1599       while (NULL != link)
1600         {
1601           if (match_rule_equal_lib (link->data, rule_to_remove))
1602             {
1603               return match_rule_get_cookie (link->data);
1604             }
1605           link = _dbus_list_get_prev_link (&rules, link);
1606         }
1607     }
1608   return 0;
1609 }
1610
1611 static DBusMessage *
1612 capture_org_freedesktop_DBus_RemoveMatch (DBusTransportKdbus *transport,
1613                                           DBusMessage        *message,
1614                                           DBusError          *error)
1615 {
1616   const char *arg;
1617   DBusString arg_str;
1618   MatchRule *rule = NULL;
1619   DBusConnection *connection = transport->base.connection;
1620   dbus_uint64_t cookie;
1621
1622   if (!dbus_message_get_args (message, error,
1623         DBUS_TYPE_STRING, &arg,
1624         DBUS_TYPE_INVALID))
1625     return NULL;
1626
1627   _dbus_string_init_const (&arg_str, arg);
1628
1629   rule = match_rule_parse (connection, &arg_str, error);
1630   if (rule != NULL)
1631     {
1632       cookie = get_match_cookie_for_remove (transport->matchmaker, rule);
1633       if (0 == cookie)
1634         {
1635           dbus_set_error (error,
1636                           DBUS_ERROR_MATCH_RULE_NOT_FOUND,
1637                           "The given match rule wasn't found and can't be removed");
1638         }
1639       else
1640         {
1641           int ret = _kdbus_remove_match (transport->kdbus, cookie);
1642           if (ret != 0)
1643             dbus_set_error (error,
1644                             _dbus_error_from_errno (ret),
1645                             "Could not remove match rule");
1646
1647           if (!dbus_error_is_set (error))
1648             matchmaker_remove_rule_by_value (transport->matchmaker, rule, error);
1649         }
1650
1651       match_rule_unref (rule);
1652     }
1653
1654   if (dbus_error_is_set (error))
1655     {
1656       _dbus_verbose ("Error during RemoveMatch in lib: %s, %s\n",
1657                      error->name,
1658                      error->message);
1659       return NULL;
1660     }
1661
1662   return dbus_message_new_method_return (message);
1663 }
1664
1665 static int
1666 get_connection_info_by_name (DBusMessage        *message,
1667                              DBusError          *error,
1668                              struct nameInfo    *info,
1669                              DBusTransportKdbus *transport,
1670                              const char         *name,
1671                              dbus_bool_t         getLabel)
1672 {
1673   int ret;
1674   if (!dbus_validate_bus_name (name, error))
1675     return -1;
1676
1677   if ((ret = _kdbus_connection_info_by_name (transport->kdbus, name, getLabel, info)) != 0)
1678     {
1679       if (ESRCH == ret || ENXIO == ret)
1680           dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1681               "Could not get owner of name '%s': no such name", name);
1682       else
1683         dbus_set_error (error, DBUS_ERROR_FAILED,
1684             "Unable to query name %s, returned %d, errno = %d (%m).",
1685                         name, ret, errno);
1686       return -1;
1687     }
1688   if (info->flags & KDBUS_HELLO_ACTIVATOR)
1689   {
1690     dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1691         "Could not get owner of name '%s'", name);
1692     /* we return ESRCH - this is an indicator that name has an activator */
1693     return -ESRCH;
1694   }
1695   return 0;
1696 }
1697
1698 /* This local function handles common case for org.freedesktop.DBus method handlers:
1699  * 1. gets string argument from incoming message;
1700  * 2. gets connection info for such name.
1701  * Note: if getLabel argument is set to TRUE, the caller must free info.sec_label.
1702  */
1703 static int
1704 get_connection_info_from_message_argument (DBusMessage        *message,
1705                                            DBusError          *error,
1706                                            struct nameInfo    *info,
1707                                            DBusTransportKdbus *transport,
1708                                            dbus_bool_t         getLabel)
1709 {
1710   const char *arg;
1711
1712   if (!dbus_message_get_args (message, error,
1713                               DBUS_TYPE_STRING, &arg,
1714                               DBUS_TYPE_INVALID))
1715       return -1;
1716
1717   return get_connection_info_by_name (message, error, info, transport, arg, getLabel);
1718 }
1719
1720 static DBusMessage *
1721 capture_org_freedesktop_DBus_GetConnectionCredentials (DBusTransportKdbus *transport,
1722                                                        DBusMessage        *message,
1723                                                        DBusError          *error)
1724 {
1725   DBusMessage *reply = NULL;
1726   DBusMessageIter reply_iter;
1727   DBusMessageIter array_iter;
1728   struct nameInfo info;
1729
1730   if (get_connection_info_from_message_argument (message, error, &info, transport, TRUE) != 0)
1731     return NULL;
1732
1733   reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
1734   if (reply == NULL)
1735     return NULL;
1736
1737   /* we can't represent > 32-bit pids; if your system needs them, please
1738    * add ProcessID64 to the spec or something */
1739   if (info.processId <= _DBUS_UINT32_MAX)
1740     {
1741       if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", info.processId))
1742         goto oom;
1743     }
1744   /* we can't represent > 32-bit uids; if your system needs them, please
1745    * add UnixUserID64 to the spec or something */
1746   if (info.userId <= _DBUS_UINT32_MAX)
1747     {
1748       if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", info.userId))
1749         goto oom;
1750     }
1751
1752   if (info.sec_label != NULL)
1753     {
1754       dbus_bool_t res = _dbus_asv_add_byte_array (&array_iter,
1755                                                   "LinuxSecurityLabel",
1756                                                   info.sec_label,
1757                                                   strlen (info.sec_label)+1);
1758
1759       dbus_free (info.sec_label);
1760
1761       if (!res)
1762         goto oom;
1763     }
1764
1765   if (!_dbus_asv_close (&reply_iter, &array_iter))
1766     goto oom;
1767
1768   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
1769     goto oom;
1770
1771   return reply;
1772
1773 oom:
1774   _dbus_asv_abandon (&reply_iter, &array_iter);
1775   dbus_message_unref (reply);
1776
1777   return NULL;
1778 }
1779
1780 static DBusMessage *
1781 capture_org_freedesktop_DBus_GetConnectionSELinuxSecurityContext (DBusTransportKdbus *transport,
1782                                                                   DBusMessage        *message,
1783                                                                   DBusError          *error)
1784 {
1785   struct nameInfo info;
1786
1787   if (get_connection_info_from_message_argument (message, error, &info, transport, TRUE) != 0)
1788     return NULL;
1789
1790   if (info.sec_label != NULL)
1791     {
1792       DBusMessage *reply;
1793
1794       reply = reply_fixed_array (message, DBUS_TYPE_BYTE,
1795                                  info.sec_label,
1796                                  strlen (info.sec_label)+1);
1797
1798       dbus_free (info.sec_label);
1799       return reply;
1800     }
1801   else
1802     {
1803       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, "Operation not supported");
1804     }
1805
1806   return NULL;
1807 }
1808
1809 static DBusMessage *
1810 capture_org_freedesktop_DBus_GetConnectionUnixProcessID (DBusTransportKdbus *transport,
1811                                                          DBusMessage        *message,
1812                                                          DBusError          *error)
1813 {
1814   struct nameInfo info;
1815   dbus_uint32_t processId;
1816
1817   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0 ||
1818       info.processId > _DBUS_UINT32_MAX)
1819     return NULL;
1820
1821   processId = info.processId;
1822
1823   return reply_1_data (message, DBUS_TYPE_UINT32, &processId);
1824 }
1825
1826 static DBusMessage *
1827 capture_org_freedesktop_DBus_GetConnectionUnixUser (DBusTransportKdbus *transport,
1828                                                     DBusMessage        *message,
1829                                                     DBusError          *error)
1830 {
1831   struct nameInfo info;
1832   dbus_uint32_t userId;
1833
1834   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0 ||
1835       info.userId > _DBUS_UINT32_MAX)
1836     return NULL;
1837
1838   userId = info.userId;
1839
1840   return reply_1_data (message, DBUS_TYPE_UINT32, &userId);
1841 }
1842
1843 static DBusMessage *
1844 capture_org_freedesktop_DBus_GetId (DBusTransportKdbus *transport,
1845                                     DBusMessage        *message,
1846                                     DBusError          *error)
1847 {
1848   dbus_uint64_t bus_id_size = _kdbus_get_bus_id_size ();
1849   char bus_id[bus_id_size*2+1];
1850   char *bus_id_ptr = bus_id;
1851   char *bus_id_original = _kdbus_get_bus_id (transport->kdbus);
1852   dbus_uint64_t i = 0;
1853   for (; i < bus_id_size; i++)
1854     snprintf (bus_id + 2*i, sizeof (bus_id) - 2*i, "%02x", bus_id_original[i]);
1855   return reply_1_data (message, DBUS_TYPE_STRING, &bus_id_ptr);
1856 }
1857
1858 static DBusMessage *
1859 capture_org_freedesktop_DBus_GetNameOwner (DBusTransportKdbus *transport,
1860                                            DBusMessage        *message,
1861                                            DBusError          *error)
1862 {
1863   DBusMessage *reply;
1864   struct nameInfo info;
1865   char *unique_name;
1866   const char *arg;
1867
1868   if (!dbus_message_get_args (message, error,
1869                               DBUS_TYPE_STRING, &arg,
1870                               DBUS_TYPE_INVALID))
1871       return NULL;
1872
1873   if (strcmp (arg, DBUS_SERVICE_DBUS) == 0)
1874     {
1875       if (-1 == asprintf (&unique_name, "%s", DBUS_SERVICE_DBUS))
1876         return NULL;
1877     }
1878   else
1879     {
1880       if (get_connection_info_by_name (message, error, &info, transport, arg, FALSE) != 0)
1881         return NULL;
1882
1883       unique_name = create_unique_name_from_unique_id (info.uniqueId);
1884       if (NULL == unique_name)
1885         return NULL;
1886     }
1887
1888   reply = reply_1_data (message, DBUS_TYPE_STRING, &unique_name);
1889
1890   free (unique_name);
1891
1892   return reply;
1893 }
1894
1895 static DBusMessage *
1896 reply_listNames (DBusTransportKdbus *transport,
1897                  DBusMessage        *message,
1898                  DBusError          *error,
1899                  dbus_uint64_t       flags)
1900 {
1901   DBusMessage *reply = NULL;
1902   dbus_uint64_t prev_id = 0;
1903
1904   /* First, get the list from kdbus */
1905
1906   struct kdbus_info *name_list, *name;
1907   __u64 list_size;
1908   int ret;
1909   DBusMessageIter iter;
1910   DBusMessageIter array_iter;
1911
1912   ret = _kdbus_list (transport->kdbus,
1913                      flags,
1914                      &name_list,
1915                      &list_size);
1916   if (ret != 0)
1917     {
1918       dbus_set_error (error, DBUS_ERROR_FAILED, "Error listing names");
1919       return NULL;
1920     }
1921
1922   /* Compose the reply on the fly */
1923   reply = dbus_message_new_method_return (message);
1924   if (reply == NULL)
1925     goto oom;
1926
1927   dbus_message_iter_init_append (reply, &iter);
1928   if (!dbus_message_iter_open_container (&iter,
1929                                          DBUS_TYPE_ARRAY,
1930                                          DBUS_TYPE_STRING_AS_STRING,
1931                                          &array_iter))
1932     goto oom_reply;
1933
1934   KDBUS_FOREACH (name, name_list, list_size)
1935     {
1936       struct kdbus_item *item;
1937
1938       if ((flags & KDBUS_LIST_UNIQUE) && name->id != prev_id)
1939         {
1940           dbus_bool_t res;
1941
1942           char *unique_name = create_unique_name_from_unique_id (name->id);
1943
1944           if (NULL == unique_name)
1945             goto oom_iterator;
1946
1947           res = dbus_message_iter_append_basic (&array_iter,
1948                                                 DBUS_TYPE_STRING,
1949                                                 &unique_name);
1950           free (unique_name);
1951
1952           if (!res)
1953             goto oom_iterator;
1954         }
1955
1956       KDBUS_ITEM_FOREACH (item, name, items)
1957         {
1958           if (item->type == KDBUS_ITEM_OWNED_NAME)
1959             {
1960               DBusError local_error;
1961               char *name_ptr = item->name.name;
1962
1963               dbus_error_init ( &local_error );
1964               if (!dbus_validate_bus_name (name_ptr, &local_error))
1965                 continue;
1966
1967               if (flags & KDBUS_LIST_QUEUED)
1968                 name_ptr = create_unique_name_from_unique_id (name->id);
1969
1970               if (NULL == name_ptr)
1971                 goto oom_iterator;
1972
1973               if (!dbus_message_iter_append_basic (&array_iter,
1974                                                    DBUS_TYPE_STRING,
1975                                                    &name_ptr))
1976                 goto oom_iterator;
1977
1978               if (flags & KDBUS_LIST_QUEUED)
1979                 free (name_ptr);
1980             }
1981         }
1982     }
1983
1984   if (!dbus_message_iter_close_container (&iter, &array_iter))
1985     goto oom_reply;
1986
1987   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
1988     goto oom_reply;
1989
1990   return reply;
1991
1992 oom_iterator:
1993   dbus_message_iter_abandon_container (&iter, &array_iter);
1994
1995 oom_reply:
1996   dbus_message_unref (reply);
1997 oom:
1998   _kdbus_free_mem (transport->kdbus, name_list);
1999   return NULL;
2000 }
2001
2002 static DBusMessage *
2003 capture_org_freedesktop_DBus_ListActivatableNames (DBusTransportKdbus *transport,
2004                                                    DBusMessage        *message,
2005                                                    DBusError          *error)
2006 {
2007   return reply_listNames (transport, message, error, KDBUS_LIST_ACTIVATORS);
2008 }
2009
2010 static DBusMessage *
2011 capture_org_freedesktop_DBus_ListNames (DBusTransportKdbus *transport,
2012                                         DBusMessage        *message,
2013                                         DBusError          *error)
2014 {
2015   return reply_listNames (transport, message, error, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES);
2016 }
2017
2018 static DBusMessage *
2019 capture_org_freedesktop_DBus_ListQueuedOwners (DBusTransportKdbus *transport,
2020                                                DBusMessage        *message,
2021                                                DBusError          *error)
2022 {
2023   struct nameInfo info;
2024
2025   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2026     return NULL;
2027
2028   return reply_listNames (transport, message, error, KDBUS_LIST_QUEUED);
2029 }
2030
2031 static DBusMessage *
2032 capture_org_freedesktop_DBus_NameHasOwner (DBusTransportKdbus *transport,
2033                                            DBusMessage        *message,
2034                                            DBusError          *error)
2035 {
2036   struct nameInfo info;
2037   dbus_bool_t result = TRUE;
2038
2039   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2040     {
2041       if (dbus_error_is_set (error) && dbus_error_has_name (error, DBUS_ERROR_NAME_HAS_NO_OWNER))
2042         {
2043           result = FALSE;
2044           dbus_error_free (error);
2045         }
2046       else
2047         return NULL;
2048     }
2049
2050   return reply_1_data (message, DBUS_TYPE_BOOLEAN, &result);
2051 }
2052
2053 static DBusMessage *
2054 capture_org_freedesktop_DBus_ReloadConfig (DBusTransportKdbus *transport,
2055                                            DBusMessage        *message,
2056                                            DBusError          *error)
2057 {
2058   DBusMessageIter iter;
2059   DBusMessage *reply = NULL;
2060
2061   dbus_message_iter_init (message, &iter);
2062   if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT)
2063     {
2064       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2065           "Call to 'ReloadConfig' has wrong args");
2066       return NULL;
2067     }
2068
2069   reply = dbus_message_new_method_return (message);
2070   if (reply == NULL)
2071     return NULL;
2072
2073   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
2074     goto oom;
2075
2076   return reply;
2077
2078 oom:
2079   dbus_message_unref (reply);
2080   return NULL;
2081 }
2082
2083 static DBusMessage *
2084 capture_org_freedesktop_DBus_StartServiceByName (DBusTransportKdbus *transport,
2085                                                  DBusMessage        *message,
2086                                                  DBusError          *error)
2087 {
2088   struct nameInfo info;
2089   char *name;
2090   dbus_uint32_t flags; /* Spec says: not used, but we check the syntax anyway */
2091   int ret = 0;
2092   dbus_bool_t dbus_service = FALSE;
2093
2094   if (!dbus_message_get_args (message, error,
2095                               DBUS_TYPE_STRING, &name,
2096                               DBUS_TYPE_UINT32, &flags,
2097                               DBUS_TYPE_INVALID))
2098     return NULL;
2099
2100   dbus_service = (strncmp (name, DBUS_SERVICE_DBUS, strlen (DBUS_SERVICE_DBUS) + 1) == 0);
2101
2102   if (!dbus_service)
2103     ret = get_connection_info_by_name (message,
2104                                        error,
2105                                        &info,
2106                                        transport,
2107                                        name,
2108                                        FALSE);
2109
2110   if (dbus_service || 0 == ret)
2111     {
2112       dbus_uint32_t status = DBUS_START_REPLY_ALREADY_RUNNING;
2113       return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2114     }
2115   else if (-ESRCH == ret) /* there is an activator */
2116     {
2117       DBusMessage *sub_message;
2118
2119       /* if we are here, then we have error set - free place for possible real error */
2120       dbus_error_free (error);
2121
2122       /* send method call to org.freedesktop.DBus.Peer.Ping */
2123       sub_message = dbus_message_new_method_call (name, "/", DBUS_INTERFACE_PEER, "Ping");
2124       if (sub_message == NULL)
2125         return NULL;
2126
2127       /* The serial number here is set to -1. A message needs a valid serial number.
2128        * We do not have access to connection's serial numbers counter, so we need to make up one.
2129        * -1 is the last valid serial, so we hope that we'll never get there, especially with 64-bit
2130        * kdbus cookies.
2131        */
2132       dbus_message_set_serial (sub_message, -1);
2133
2134       dbus_message_lock (sub_message);
2135
2136       if (kdbus_write_msg_internal (transport, sub_message, name, FALSE, FALSE) == -1)
2137           return NULL;
2138       else
2139         {
2140           dbus_uint32_t status = DBUS_START_REPLY_SUCCESS;
2141           return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2142         }
2143     }
2144   else
2145     {
2146       /*
2147        * There was an error set in get_connection_info_by_name()
2148        * We want to have another error return from StartServiceByName.
2149        */
2150       dbus_error_free (error);
2151       dbus_set_error (error,
2152                       DBUS_ERROR_SERVICE_UNKNOWN,
2153                       "The name %s was not provided by any .service files",
2154                       name);
2155     }
2156
2157   return NULL;
2158 }
2159
2160 static DBusMessage *
2161 capture_org_freedesktop_DBus_UpdateActivationEnvironment (DBusTransportKdbus *transport,
2162                                                           DBusMessage        *message,
2163                                                           DBusError          *error)
2164 {
2165   dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
2166       "'%s' method not supported", dbus_message_get_member (message));
2167   return NULL;
2168 }
2169
2170 typedef DBusMessage * (*CaptureHandler)(DBusTransportKdbus *, DBusMessage *, DBusError *);
2171 struct CaptureHandlers {
2172   const char *method_name;
2173   CaptureHandler handler;
2174 };
2175
2176 #define HANDLER_ELEMENT(x) {#x, capture_org_freedesktop_DBus_##x}
2177
2178 /* This is to cut the code to parts, and keep it organized:
2179  * an array of elements of type, as in example:
2180  * { "RequestName", capture_org_freedesktop_DBus_RequestName }
2181  * That is, a method of name RequestName will be handled by capture_org_freedesktop_DBus_RequestName ().
2182  */
2183 static struct CaptureHandlers capture_handlers[] =
2184 {
2185 // "Hello" is handled separately
2186 //  HANDLER_ELEMENT (Hello),
2187   HANDLER_ELEMENT (RequestName),
2188   HANDLER_ELEMENT (ReleaseName),
2189   HANDLER_ELEMENT (AddMatch),
2190   HANDLER_ELEMENT (RemoveMatch),
2191   HANDLER_ELEMENT (GetConnectionCredentials),
2192   HANDLER_ELEMENT (GetConnectionSELinuxSecurityContext),
2193   HANDLER_ELEMENT (GetConnectionUnixProcessID),
2194   HANDLER_ELEMENT (GetConnectionUnixUser),
2195   HANDLER_ELEMENT (GetId),
2196   HANDLER_ELEMENT (GetNameOwner),
2197   HANDLER_ELEMENT (ListActivatableNames),
2198   HANDLER_ELEMENT (ListNames),
2199   HANDLER_ELEMENT (ListQueuedOwners),
2200   HANDLER_ELEMENT (NameHasOwner),
2201   HANDLER_ELEMENT (ReloadConfig),
2202   HANDLER_ELEMENT (StartServiceByName),
2203   HANDLER_ELEMENT (UpdateActivationEnvironment)
2204 };
2205
2206 /**
2207  * Looks over messages sent to org.freedesktop.DBus. Hello message, which performs
2208  * registration on the bus, is captured as it must be locally converted into
2209  * appropriate ioctl. AddMatch and RemoveMatch are captured to store match rules
2210  * locally in case of false positive result of kdbus bloom filters, but after
2211  * being read they are passed to org.freedesktop.DBus to register these rules
2212  * in kdbus.
2213  * All the rest org.freedesktop.DBus methods are left untouched
2214  * and they are sent to dbus-daemon in the same way as every other messages.
2215  *
2216  * @param transport Transport
2217  * @param message Message being sent.
2218  * @returns
2219         1 if message is not captured and should be passed to kdbus
2220  *      0 if message was handled locally and correctly (it includes proper return of error reply),
2221  *     -1 message to org.freedesktop.DBus was not handled correctly.
2222  */
2223 static int
2224 capture_org_freedesktop_DBus (DBusTransportKdbus *transport,
2225                               const char         *destination,
2226                               DBusMessage        *message,
2227                               DBusMessage       **reply)
2228 {
2229   int ret = 1;
2230   if (!strcmp (destination, DBUS_SERVICE_DBUS))
2231     {
2232       if (!strcmp (dbus_message_get_interface (message), DBUS_INTERFACE_DBUS))
2233         {
2234           DBusError error;
2235           const char *member = dbus_message_get_member (message);
2236
2237           dbus_error_init (&error);
2238
2239           if (!strcmp (member, "Hello"))
2240             {
2241               *reply = capture_org_freedesktop_DBus_Hello (transport, message, &error);
2242             }
2243           else
2244             {
2245               int i = 0;
2246               int handlers_size = sizeof (capture_handlers)/sizeof (capture_handlers[0]);
2247
2248               while (i < handlers_size && strcmp (member, capture_handlers[i].method_name) != 0)
2249                 i++;
2250
2251               if (i < handlers_size)
2252                 {
2253                   *reply = capture_handlers[i].handler (transport, message, &error);
2254                 }
2255               else
2256                 {
2257                   dbus_set_error (&error, DBUS_ERROR_UNKNOWN_METHOD,
2258                       "org.freedesktop.DBus does not understand message %s", member);
2259                 }
2260             }
2261
2262           if (*reply == NULL && dbus_error_is_set (&error))
2263             {
2264               *reply = reply_with_error ((char*)error.name,
2265                                          NULL,
2266                                          error.message,
2267                                          message);
2268               dbus_error_free (&error);
2269             }
2270
2271            if (*reply == NULL)
2272              ret = -1;
2273            else
2274              ret = 0;
2275
2276         } /* id DBUS_INTERFACE_DBUS */
2277     } /* if DBUS_SERVICE_DBUS */
2278
2279   return ret;
2280 }
2281
2282 #ifdef DBUS_ENABLE_VERBOSE_MODE
2283 #define ENUM_NAME_ITEM(x) case x : return #x
2284
2285 static const char *
2286 enum_MSG (long long id)
2287 {
2288   switch (id)
2289     {
2290       ENUM_NAME_ITEM (_KDBUS_ITEM_NULL);
2291       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_VEC);
2292       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_OFF);
2293       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_MEMFD);
2294       ENUM_NAME_ITEM (KDBUS_ITEM_FDS);
2295       ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_PARAMETER);
2296       ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_FILTER);
2297       ENUM_NAME_ITEM (KDBUS_ITEM_DST_NAME);
2298       ENUM_NAME_ITEM (KDBUS_ITEM_CREDS);
2299       ENUM_NAME_ITEM (KDBUS_ITEM_PID_COMM);
2300       ENUM_NAME_ITEM (KDBUS_ITEM_TID_COMM);
2301       ENUM_NAME_ITEM (KDBUS_ITEM_EXE);
2302       ENUM_NAME_ITEM (KDBUS_ITEM_CMDLINE);
2303       ENUM_NAME_ITEM (KDBUS_ITEM_CGROUP);
2304       ENUM_NAME_ITEM (KDBUS_ITEM_CAPS);
2305       ENUM_NAME_ITEM (KDBUS_ITEM_SECLABEL);
2306       ENUM_NAME_ITEM (KDBUS_ITEM_AUDIT);
2307       ENUM_NAME_ITEM (KDBUS_ITEM_CONN_DESCRIPTION);
2308       ENUM_NAME_ITEM (KDBUS_ITEM_NAME);
2309       ENUM_NAME_ITEM (KDBUS_ITEM_TIMESTAMP);
2310       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_ADD);
2311       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_REMOVE);
2312       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_CHANGE);
2313       ENUM_NAME_ITEM (KDBUS_ITEM_ID_ADD);
2314       ENUM_NAME_ITEM (KDBUS_ITEM_ID_REMOVE);
2315       ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_TIMEOUT);
2316       ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_DEAD);
2317     }
2318   return "UNKNOWN";
2319 }
2320
2321 #if KDBUS_MSG_DECODE_DEBUG == 1
2322 static const char *
2323 enum_PAYLOAD (long long id)
2324 {
2325   switch (id)
2326     {
2327       ENUM_NAME_ITEM (KDBUS_PAYLOAD_KERNEL);
2328       ENUM_NAME_ITEM (KDBUS_PAYLOAD_DBUS);
2329     }
2330   return "UNKNOWN";
2331 }
2332
2333 static const char *
2334 msg_id (uint64_t id)
2335 {
2336   char buf[64];
2337   const char* const_ptr;
2338
2339   if (id == 0)
2340     return "KERNEL";
2341   if (id == ~0ULL)
2342     return "BROADCAST";
2343
2344   snprintf (buf, sizeof (buf), "%llu", (unsigned long long)id);
2345
2346   const_ptr = buf;
2347   return const_ptr;
2348 }
2349 #endif
2350 #endif
2351
2352 static dbus_uint32_t
2353 get_next_client_serial (DBusTransportKdbus *transport)
2354 {
2355   dbus_uint32_t serial;
2356
2357   serial = transport->client_serial++;
2358
2359   if (transport->client_serial == 0)
2360     transport->client_serial = 1;
2361
2362   return serial;
2363 }
2364
2365 /**
2366  * Calculates length of the kdbus message content (payload).
2367  *
2368  * @param msg kdbus message
2369  * @return the length of the kdbus message's payload.
2370  */
2371 static int
2372 kdbus_message_size (const struct kdbus_msg *msg)
2373 {
2374   const struct kdbus_item *item;
2375   int ret_size = 0;
2376
2377   KDBUS_ITEM_FOREACH (item, msg, items)
2378     {
2379       if (item->size < KDBUS_ITEM_HEADER_SIZE)
2380         {
2381           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2382           return -1;
2383         }
2384       switch (item->type)
2385         {
2386           case KDBUS_ITEM_PAYLOAD_OFF:
2387             ret_size += item->vec.size;
2388             break;
2389           case KDBUS_ITEM_PAYLOAD_MEMFD:
2390             ret_size += item->memfd.size;
2391             break;
2392           default:
2393             break;
2394         }
2395     }
2396
2397   return ret_size;
2398 }
2399
2400 static int
2401 generate_NameSignal (const char         *signal,
2402                      const char         *name,
2403                      DBusTransportKdbus *transport)
2404 {
2405   DBusMessage *message;
2406
2407   _dbus_verbose ("Generating %s for %s.\n", signal, name);
2408
2409   message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, signal);
2410   if (message == NULL)
2411     return -1;
2412
2413   if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
2414     goto error;
2415   if (!dbus_message_set_destination (message, transport->my_DBus_unique_name))
2416     goto error;
2417   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
2418     goto error;
2419   dbus_message_set_serial (message, get_next_client_serial (transport));
2420
2421   if (!add_message_to_received (message, transport->base.connection))
2422     return -1;
2423
2424   return 0;
2425
2426   error:
2427     dbus_message_unref (message);
2428     return -1;
2429 }
2430
2431 /*
2432  * The NameOwnerChanged signals take three parameters with
2433  * unique or well-known names, but only some forms actually
2434  * exist:
2435  *
2436  * WELLKNOWN, "", UNIQUE       â†’ KDBUS_ITEM_NAME_ADD
2437  * WELLKNOWN, UNIQUE, ""       â†’ KDBUS_ITEM_NAME_REMOVE
2438  * WELLKNOWN, UNIQUE, UNIQUE   â†’ KDBUS_ITEM_NAME_CHANGE
2439  * UNIQUE, "", UNIQUE          â†’ KDBUS_ITEM_ID_ADD
2440  * UNIQUE, UNIQUE, ""          â†’ KDBUS_ITEM_ID_REMOVE
2441  *
2442  * For the latter two the two unique names must be identical.
2443  */
2444 static int
2445 kdbus_handle_name_owner_changed (__u64               type,
2446                                  const char         *bus_name,
2447                                  __u64               old,
2448                                  __u64               new,
2449                                  DBusTransportKdbus *transport)
2450 {
2451   DBusMessage *message = NULL;
2452   DBusMessageIter args;
2453   char tmp_str[128];
2454   const char *const_ptr;
2455
2456   if ((message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) == NULL)
2457     return -1;
2458
2459   dbus_message_iter_init_append (message, &args);
2460
2461   // for ID_ADD and ID_REMOVE this function takes NULL as bus_name
2462   if (bus_name == NULL)
2463     {
2464       snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old != 0 ? old : new);
2465       const_ptr = tmp_str;
2466     }
2467   else
2468     const_ptr = bus_name;
2469
2470   if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2471     goto error;
2472
2473   _dbus_verbose ("%s\n", const_ptr);
2474
2475
2476   if ((old==0) && (new==0))
2477     {
2478       /* kdbus generates its own set of events that can not be passed to
2479        * client without translation. */
2480       const char *src = "org.freedesktop.DBus";
2481       const char *dst = "org.freedesktop.DBus";
2482
2483       if (type == KDBUS_ITEM_NAME_ADD || type == KDBUS_ITEM_ID_ADD)
2484         src = "";
2485       else if (type == KDBUS_ITEM_NAME_REMOVE || type == KDBUS_ITEM_ID_REMOVE)
2486         dst = "";
2487
2488       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &src))
2489         goto error;
2490       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &dst))
2491         goto error;
2492
2493       _dbus_verbose ("[NameOwnerChanged:%s, old=%lld, new=%lld\n", __func__, old, new);
2494     }
2495   else
2496     {
2497       // determine and append old_id
2498       if (old != 0)
2499       {
2500         snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old);
2501         const_ptr = tmp_str;
2502       }
2503       else
2504         const_ptr = "";
2505
2506       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2507         goto error;
2508
2509       _dbus_verbose ("%s\n", const_ptr);
2510       // determine and append new_id
2511       if (new != 0)
2512       {
2513         snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", new);
2514         const_ptr = tmp_str;
2515       }
2516       else
2517         const_ptr = "";
2518
2519       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2520         goto error;
2521
2522       _dbus_verbose ("%s\n", const_ptr);
2523     }
2524
2525   dbus_message_set_sender (message, DBUS_SERVICE_DBUS);
2526   dbus_message_set_serial (message, get_next_client_serial (transport));
2527
2528   if (!add_message_to_received (message, transport->base.connection))
2529     return -1;
2530
2531   return 0;
2532
2533 error:
2534   dbus_message_unref (message);
2535
2536   return -1;
2537 }
2538
2539 static void
2540 handle_item_timestamp (const struct kdbus_item *item)
2541 {
2542 #if KDBUS_MSG_DECODE_DEBUG == 1
2543   _dbus_verbose ("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
2544                 enum_MSG (item->type), item->size,
2545                 (unsigned long long)item->timestamp.realtime_ns,
2546                 (unsigned long long)item->timestamp.monotonic_ns);
2547 #endif
2548 }
2549
2550 static void
2551 handle_unexpected_item (const struct kdbus_item *item)
2552 {
2553   _dbus_assert_not_reached ("unexpected item from kdbus");
2554 }
2555
2556 static void
2557 handle_padding (const struct kdbus_msg *msg,
2558                  const struct kdbus_item *end_of_items)
2559 {
2560 #if KDBUS_MSG_DECODE_DEBUG == 1
2561   if ((char *)end_of_items - ((char *)msg + msg->size) >= 8)
2562     _dbus_verbose ("invalid padding at end of message\n");
2563 #endif
2564 }
2565
2566 #ifdef LIBDBUSPOLICY
2567 static dbus_bool_t
2568 load_dbus_header (DBusTransportKdbus *transport,
2569                   DBusHeader         *header,
2570                   const char         *message_data,
2571                   dbus_uint32_t       message_len)
2572 {
2573   DBusValidity validity = DBUS_VALID;
2574   DBusString message;
2575   dbus_uint32_t fields_array_len_unsigned;
2576   dbus_uint32_t body_len_unsigned;
2577   int i;
2578
2579   if (0 == message_len)
2580     return FALSE;
2581
2582   _dbus_string_init_const_len (&message, message_data, message_len);
2583   _dbus_gvariant_raw_get_lengths (&message,
2584                                   &fields_array_len_unsigned,
2585                                   &body_len_unsigned,
2586                                   &validity);
2587
2588   _dbus_string_init_const_len (&header->data,
2589                                message_data,
2590                                fields_array_len_unsigned + FIRST_GVARIANT_FIELD_OFFSET);
2591
2592   header->padding = 0;
2593   header->byte_order = message_data[0];
2594   header->protocol_version = DBUS_PROTOCOL_VERSION_GVARIANT;
2595   for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
2596     header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
2597
2598   return _dbus_header_load_gvariant (header, &validity);
2599 }
2600 #endif
2601
2602 static dbus_bool_t
2603 can_receive (DBusTransportKdbus     *transport,
2604              const struct kdbus_msg *msg,
2605              const char             *message_data,
2606              dbus_uint32_t           message_len)
2607 {
2608   dbus_bool_t result = TRUE;
2609
2610 #ifdef LIBDBUSPOLICY
2611   if (transport->policy)
2612   {
2613     DBusHeader header;
2614     dbus_bool_t got_header = FALSE;
2615     dbus_bool_t got_creds = FALSE;
2616     dbus_bool_t got_seclabel = FALSE;
2617
2618     if (KDBUS_PAYLOAD_DBUS == msg->payload_type)
2619       {
2620         const struct kdbus_item *item;
2621         uid_t sender_euid = -1;
2622         gid_t sender_egid = -1;
2623         const char *seclabel = NULL;
2624         DBusString names;
2625
2626         result = FALSE;
2627
2628         _dbus_string_init (&names);
2629
2630         KDBUS_ITEM_FOREACH(item, msg, items)
2631           switch (item->type)
2632             {
2633               case KDBUS_ITEM_CREDS:
2634                 sender_euid = (uid_t) item->creds.euid;
2635                 sender_egid = (gid_t) item->creds.egid;
2636                 got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1);
2637                 break;
2638               case KDBUS_ITEM_SECLABEL:
2639                 seclabel = item->str;
2640                 got_seclabel = (seclabel != NULL);
2641                 break;
2642               case KDBUS_ITEM_OWNED_NAME:
2643                 {
2644                   DBusString name;
2645                   _dbus_string_init_const (&name, item->name.name);
2646                   if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))
2647                     {
2648                       if (_dbus_string_get_length (&names) != 0)
2649                         _dbus_string_append_byte (&names, ' ');
2650
2651                       _dbus_string_copy (&name,
2652                                          0,
2653                                          &names,
2654                                          _dbus_string_get_length (&names));
2655                     }
2656                 }
2657                 break;
2658               default:
2659                 break; /* ignore all other items */
2660             }
2661
2662         if (NULL != message_data && message_len > 0)
2663           {
2664             if (load_dbus_header (transport, &header, message_data, message_len))
2665               got_header = TRUE;
2666           }
2667
2668         if (got_header && _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2669           {
2670             result = TRUE;
2671           }
2672         else if (got_header && got_creds && got_seclabel)
2673           {
2674             const char *destination = NULL;
2675             const char *path = NULL;
2676             const char *interface = NULL;
2677             const char *member = NULL;
2678             const char *error_name = NULL;
2679             dbus_uint64_t reply_cookie = 0;
2680             dbus_bool_t requested_reply = FALSE;
2681             int ret;
2682
2683             _dbus_header_get_field_basic (&header,
2684                                           DBUS_HEADER_FIELD_DESTINATION,
2685                                           DBUS_TYPE_STRING,
2686                                           &destination);
2687
2688             _dbus_header_get_field_basic (&header,
2689                                           DBUS_HEADER_FIELD_PATH,
2690                                           DBUS_TYPE_STRING,
2691                                           &path);
2692
2693             _dbus_header_get_field_basic (&header,
2694                                           DBUS_HEADER_FIELD_INTERFACE,
2695                                           DBUS_TYPE_STRING,
2696                                           &interface);
2697
2698             _dbus_header_get_field_basic (&header,
2699                                           DBUS_HEADER_FIELD_MEMBER,
2700                                           DBUS_TYPE_STRING,
2701                                           &member);
2702
2703             _dbus_header_get_field_basic (&header,
2704                                           DBUS_HEADER_FIELD_ERROR_NAME,
2705                                           DBUS_TYPE_STRING,
2706                                           &error_name);
2707
2708             _dbus_header_get_field_basic (&header,
2709                                           DBUS_HEADER_FIELD_REPLY_SERIAL,
2710                                           DBUS_TYPE_UINT64,
2711                                           &reply_cookie);
2712
2713             requested_reply = !(_dbus_header_get_flag (&header,
2714                                                        DBUS_HEADER_FLAG_NO_REPLY_EXPECTED));
2715
2716             ret = dbuspolicy1_check_in (transport->policy,
2717                                         destination,
2718                                         _dbus_string_get_length (&names) > 0 ?
2719                                           _dbus_string_get_const_data (&names) :
2720                                           NULL,
2721                                         seclabel,
2722                                         sender_euid,
2723                                         sender_egid,
2724                                         path,
2725                                         interface,
2726                                         member,
2727                                         _dbus_header_get_message_type (&header),
2728                                         error_name,
2729                                         reply_cookie,
2730                                         requested_reply);
2731             result = (1 == ret);
2732           }
2733
2734         _dbus_string_free (&names);
2735       }
2736   }
2737 #endif
2738
2739   return result;
2740 }
2741
2742 static int
2743 kdbus_decode_dbus_message (const struct kdbus_msg *msg,
2744                            char                   *data,
2745                            DBusTransportKdbus     *kdbus_transport,
2746                            int                    *fds,
2747                            int                    *n_fds)
2748 {
2749   const struct kdbus_item *item;
2750   int ret_size = 0;
2751   char *buffer = data;
2752
2753   *n_fds = 0;
2754
2755   KDBUS_ITEM_FOREACH (item, msg, items)
2756     {
2757       if (item->size < KDBUS_ITEM_HEADER_SIZE)
2758         {
2759           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2760           ret_size = -1;
2761           break;
2762         }
2763
2764       switch (item->type)
2765         {
2766           case KDBUS_ITEM_PAYLOAD_OFF:
2767             memcpy (data, (char *)msg+item->vec.offset, item->vec.size);
2768             data += item->vec.size;
2769             ret_size += item->vec.size;
2770
2771 #ifdef DBUS_ENABLE_VERBOSE_MODE
2772             if (-1 != debug)
2773               {
2774                 debug_c_str ("Message part arrived:", (char *)msg+item->vec.offset, item->vec.size);
2775               }
2776 #endif
2777
2778             _dbus_verbose ("  +%s (%llu bytes) off=%llu size=%llu\n",
2779                 enum_MSG (item->type), item->size,
2780                 (unsigned long long)item->vec.offset,
2781                 (unsigned long long)item->vec.size);
2782             break;
2783
2784           case KDBUS_ITEM_PAYLOAD_MEMFD:
2785             {
2786               char *buf;
2787               uint64_t size;
2788
2789               size = item->memfd.size;
2790               _dbus_verbose ("memfd.size : %llu\n", (unsigned long long)size);
2791
2792               buf = mmap (NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0);
2793               if (buf == MAP_FAILED)
2794                 {
2795                   _dbus_verbose ("mmap () fd=%i failed:%m", item->memfd.fd);
2796                   return -1;
2797                 }
2798
2799               memcpy (data, buf, size);
2800               data += size;
2801               ret_size += size;
2802
2803               munmap (buf, size);
2804               close (item->memfd.fd);
2805
2806               _dbus_verbose ("  +%s (%llu bytes) off=%llu size=%llu\n",
2807                   enum_MSG (item->type), item->size,
2808                   (unsigned long long)item->vec.offset,
2809                   (unsigned long long)item->vec.size);
2810             }
2811             break;
2812
2813           case KDBUS_ITEM_FDS:
2814             {
2815               int i;
2816
2817               *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof (int);
2818               memcpy (fds, item->fds, *n_fds * sizeof (int));
2819               for (i = 0; i < *n_fds; i++)
2820                 _dbus_fd_set_close_on_exec (fds[i]);
2821             }
2822             break;
2823
2824           case KDBUS_ITEM_CREDS:
2825 #if KDBUS_MSG_DECODE_DEBUG == 1
2826             _dbus_verbose ("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
2827                           enum_MSG (item->type), item->size,
2828                           item->creds.uid, item->creds.gid,
2829                           item->creds.pid, item->creds.tid,
2830                           item->creds.starttime);
2831 #endif
2832             break;
2833
2834           case KDBUS_ITEM_PID_COMM:
2835           case KDBUS_ITEM_TID_COMM:
2836           case KDBUS_ITEM_EXE:
2837           case KDBUS_ITEM_CGROUP:
2838           case KDBUS_ITEM_SECLABEL:
2839           case KDBUS_ITEM_DST_NAME:
2840 #if KDBUS_MSG_DECODE_DEBUG == 1
2841             _dbus_verbose ("  +%s (%llu bytes) '%s' (%zu)\n",
2842                           enum_MSG (item->type), item->size, item->str, strlen (item->str));
2843 #endif
2844             break;
2845
2846           case KDBUS_ITEM_CMDLINE:
2847           case KDBUS_ITEM_NAME:
2848 #if KDBUS_MSG_DECODE_DEBUG == 1
2849             {
2850               __u64 size = item->size - KDBUS_ITEM_HEADER_SIZE;
2851               const char *str = item->str;
2852               int count = 0;
2853
2854               _dbus_verbose ("  +%s (%llu bytes) ", enum_MSG (item->type), item->size);
2855               while (size)
2856               {
2857                 _dbus_verbose ("'%s' ", str);
2858                 size -= strlen (str) + 1;
2859                 str += strlen (str) + 1;
2860                 count++;
2861               }
2862
2863               _dbus_verbose ("(%d string%s)\n", count, (count == 1) ? "" : "s");
2864             }
2865 #endif
2866             break;
2867
2868           case KDBUS_ITEM_AUDIT:
2869 #if KDBUS_MSG_DECODE_DEBUG == 1
2870             _dbus_verbose ("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
2871                           enum_MSG (item->type), item->size,
2872                           (unsigned long long)item->data64[0],
2873                           (unsigned long long)item->data64[1]);
2874 #endif
2875             break;
2876
2877           case KDBUS_ITEM_CAPS:
2878 #if KDBUS_MSG_DECODE_DEBUG == 1
2879             {
2880               int n;
2881               const uint32_t *cap;
2882               int i;
2883
2884               _dbus_verbose ("  +%s (%llu bytes) len=%llu bytes)\n",
2885                   enum_MSG (item->type), item->size,
2886                   (unsigned long long)item->size - KDBUS_ITEM_HEADER_SIZE);
2887
2888               cap = item->data32;
2889               n = (item->size - KDBUS_ITEM_HEADER_SIZE) / 4 / sizeof (uint32_t);
2890
2891               _dbus_verbose ("    CapInh=");
2892               for (i = 0; i < n; i++)
2893                 _dbus_verbose ("%08x", cap[(0 * n) + (n - i - 1)]);
2894
2895               _dbus_verbose (" CapPrm=");
2896               for (i = 0; i < n; i++)
2897                 _dbus_verbose ("%08x", cap[(1 * n) + (n - i - 1)]);
2898
2899               _dbus_verbose (" CapEff=");
2900               for (i = 0; i < n; i++)
2901                 _dbus_verbose ("%08x", cap[(2 * n) + (n - i - 1)]);
2902
2903               _dbus_verbose (" CapInh=");
2904               for (i = 0; i < n; i++)
2905                 _dbus_verbose ("%08x", cap[(3 * n) + (n - i - 1)]);
2906               _dbus_verbose ("\n");
2907             }
2908 #endif
2909             break;
2910
2911           case KDBUS_ITEM_TIMESTAMP:
2912             handle_item_timestamp (item);
2913             break;
2914
2915           case KDBUS_ITEM_BLOOM_FILTER:
2916             /* no handling */
2917             break;
2918
2919           default:
2920             handle_unexpected_item (item);
2921             break;
2922         }
2923     }
2924
2925   handle_padding (msg, item);
2926
2927   if (!can_receive (kdbus_transport, msg, buffer, ret_size))
2928     return 0;   /* ignore message if not allowed */
2929
2930   return ret_size;
2931 }
2932
2933 static int
2934 kdbus_decode_kernel_message (const struct kdbus_msg *msg,
2935                              DBusTransportKdbus     *kdbus_transport)
2936 {
2937   const struct kdbus_item *item;
2938   int ret_size = 0;
2939
2940   KDBUS_ITEM_FOREACH (item, msg, items)
2941     {
2942       if (item->size < KDBUS_ITEM_HEADER_SIZE)
2943         {
2944           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2945           ret_size = -1;
2946           break;
2947         }
2948
2949       switch (item->type)
2950         {
2951           case KDBUS_ITEM_REPLY_TIMEOUT:
2952           case KDBUS_ITEM_REPLY_DEAD:
2953             {
2954               DBusMessage *message = NULL;
2955               _dbus_verbose ("  +%s (%llu bytes) cookie=%llu\n",
2956                             enum_MSG (item->type), item->size, msg->cookie_reply);
2957
2958               message = _dbus_generate_local_error_message (msg->cookie_reply,
2959                       item->type == KDBUS_ITEM_REPLY_TIMEOUT ? DBUS_ERROR_NO_REPLY : DBUS_ERROR_NAME_HAS_NO_OWNER, NULL);
2960               if (message == NULL)
2961                 {
2962                   ret_size = -1;
2963                   goto out;
2964                 }
2965
2966               dbus_message_set_serial (message, get_next_client_serial (kdbus_transport));
2967
2968               if (!add_message_to_received (message, kdbus_transport->base.connection))
2969                 ret_size = -1;
2970             }
2971             break;
2972
2973           case KDBUS_ITEM_NAME_ADD:
2974           case KDBUS_ITEM_NAME_REMOVE:
2975           case KDBUS_ITEM_NAME_CHANGE:
2976             {
2977               int local_ret;
2978
2979               _dbus_verbose ("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n",
2980                              enum_MSG (item->type), (unsigned long long) item->size,
2981                              item->name_change.name, item->name_change.old_id.id,
2982                              item->name_change.new_id.id, item->name_change.old_id.flags,
2983                              item->name_change.new_id.flags);
2984
2985               if (item->name_change.new_id.id == _kdbus_get_id (kdbus_transport->kdbus))
2986                 ret_size = generate_NameSignal ("NameAcquired", item->name_change.name, kdbus_transport);
2987               else if (item->name_change.old_id.id == _kdbus_get_id (kdbus_transport->kdbus))
2988                 ret_size = generate_NameSignal ("NameLost", item->name_change.name, kdbus_transport);
2989
2990               if (ret_size == -1)
2991                 goto out;
2992
2993               if (item->name_change.new_id.flags & KDBUS_NAME_ACTIVATOR)
2994                 local_ret = kdbus_handle_name_owner_changed (item->type,
2995                                                              item->name_change.name,
2996                                                              item->name_change.old_id.id, 0,
2997                                                              kdbus_transport);
2998               else if (item->name_change.old_id.flags & KDBUS_NAME_ACTIVATOR)
2999                 local_ret = kdbus_handle_name_owner_changed (item->type,
3000                                                              item->name_change.name, 0,
3001                                                              item->name_change.new_id.id,
3002                                                              kdbus_transport);
3003               else
3004                 local_ret = kdbus_handle_name_owner_changed (item->type,
3005                                                              item->name_change.name,
3006                                                              item->name_change.old_id.id,
3007                                                              item->name_change.new_id.id,
3008                                                              kdbus_transport);
3009               if (local_ret == -1)
3010                 goto out;
3011
3012               ret_size += local_ret;
3013             }
3014             break;
3015
3016           case KDBUS_ITEM_ID_ADD:
3017           case KDBUS_ITEM_ID_REMOVE:
3018             _dbus_verbose ("  +%s (%llu bytes) id=%llu flags=%llu\n",
3019                           enum_MSG (item->type), (unsigned long long) item->size,
3020                           (unsigned long long) item->id_change.id,
3021                           (unsigned long long) item->id_change.flags);
3022
3023             if (item->id_change.flags & KDBUS_HELLO_ACTIVATOR)
3024               ret_size = kdbus_handle_name_owner_changed (item->type, NULL, 0, 0,
3025                                                           kdbus_transport);
3026             else
3027               ret_size = kdbus_handle_name_owner_changed (item->type, NULL,
3028                                                           item->type == KDBUS_ITEM_ID_ADD ? 0 : item->id_change.id,
3029                                                           item->type == KDBUS_ITEM_ID_ADD ? item->id_change.id : 0,
3030                                                           kdbus_transport);
3031
3032             if (ret_size == -1)
3033               goto out;
3034             break;
3035
3036           case KDBUS_ITEM_TIMESTAMP:
3037             handle_item_timestamp (item);
3038             break;
3039
3040           default:
3041             handle_unexpected_item (item);
3042             break;
3043         }
3044     }
3045
3046   handle_padding (msg, item);
3047
3048 out:
3049   return ret_size;
3050 }
3051
3052 /**
3053  * Decodes kdbus message in order to extract DBus message and puts it into received data buffer
3054  * and file descriptor's buffer. Also captures kdbus error messages and kdbus kernel broadcasts
3055  * and converts all of them into appropriate DBus messages.
3056  *
3057  * @param msg kdbus message
3058  * @param data place to copy DBus message to
3059  * @param kdbus_transport transport
3060  * @param fds place to store file descriptors received
3061  * @param n_fds place to store quantity of file descriptors received
3062  * @return number of DBus message's bytes received or -1 on error
3063  */
3064 static int
3065 kdbus_decode_msg (const struct kdbus_msg *msg,
3066                   char                   *data,
3067                   DBusTransportKdbus     *kdbus_transport,
3068                   int                    *fds,
3069                   int                    *n_fds,
3070                   DBusError              *error)
3071 {
3072   int ret_size = 0;
3073
3074 #if KDBUS_MSG_DECODE_DEBUG == 1
3075   _dbus_verbose ("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
3076                 enum_PAYLOAD (msg->payload_type),
3077                 (unsigned long long) msg->size,
3078                 (unsigned long long) msg->flags,
3079                 msg_id (msg->src_id),
3080                 msg_id (msg->dst_id),
3081                 (unsigned long long) msg->cookie,
3082                 (unsigned long long) msg->timeout_ns);
3083 #endif
3084
3085   switch (msg->payload_type)
3086     {
3087       case KDBUS_PAYLOAD_DBUS:
3088         ret_size = kdbus_decode_dbus_message (msg, data, kdbus_transport, fds, n_fds);
3089         break;
3090       case KDBUS_PAYLOAD_KERNEL:
3091         ret_size = kdbus_decode_kernel_message (msg, kdbus_transport);
3092         break;
3093       default:
3094         _dbus_assert_not_reached ("unexpected payload type from kdbus");
3095         break;
3096     }
3097
3098   return ret_size;
3099 }
3100
3101 /**
3102  * Reads message from kdbus and puts it into DBus buffers
3103  *
3104  * @param kdbus_transport transport
3105  * @param buffer place to copy received message to
3106  * @param fds place to store file descriptors received with the message
3107  * @param n_fds place to store quantity of file descriptors received
3108  * @return size of received message on success, -1 on error
3109  */
3110 static int
3111 kdbus_read_message (DBusTransportKdbus *kdbus_transport,
3112                     DBusString         *buffer,
3113                     int                *fds,
3114                     int                *n_fds)
3115 {
3116   int ret_size, buf_size;
3117   struct kdbus_msg *msg;
3118   char *data;
3119   int start;
3120   dbus_uint64_t flags = 0;
3121   int ret;
3122   DBusError error;
3123
3124   dbus_error_init (&error);
3125
3126   start = _dbus_string_get_length (buffer);
3127
3128   if (kdbus_transport->activator != NULL)
3129     flags |= KDBUS_RECV_PEEK;
3130
3131   ret = _kdbus_recv (kdbus_transport->kdbus, flags, 0, &msg);
3132
3133   if (0 != ret)
3134     {
3135       _dbus_verbose ("kdbus error receiving message: %d (%s)\n", ret, _dbus_strerror (ret));
3136       return -1;
3137     }
3138
3139   buf_size = kdbus_message_size (msg);
3140   if (buf_size == -1)
3141     {
3142       _dbus_verbose ("kdbus error - too short message: %d (%m)\n", errno);
3143       return -1;
3144     }
3145
3146   /* What is the maximum size of the locally generated message?
3147      I just assume 2048 bytes */
3148   buf_size = MAX (buf_size, 2048);
3149
3150   if (!_dbus_string_lengthen (buffer, buf_size))
3151     {
3152       errno = ENOMEM;
3153       return -1;
3154     }
3155   data = _dbus_string_get_data_len (buffer, start, buf_size);
3156
3157   ret_size = kdbus_decode_msg (msg, data, kdbus_transport, fds, n_fds, &error);
3158
3159   if (ret_size == -1) /* error */
3160     _dbus_string_set_length (buffer, start);
3161   else if (ret_size >= 0 && buf_size != ret_size) /* case of locally generated message */
3162     _dbus_string_set_length (buffer, start + ret_size);
3163
3164   if (ret_size >= 0)
3165     _dbus_message_loader_set_unique_sender_id (kdbus_transport->base.loader, msg->src_id);
3166
3167   if (kdbus_transport->activator != NULL)
3168     return ret_size;
3169
3170   ret = _kdbus_free_mem (kdbus_transport->kdbus, msg);
3171   if (0 != ret)
3172   {
3173     _dbus_verbose ("kdbus error freeing message: %d (%s)\n", ret, _dbus_strerror (ret));
3174     return -1;
3175   }
3176
3177   return ret_size;
3178 }
3179
3180 /**
3181  * Copy-paste from socket transport. Only renames done.
3182  */
3183 static void
3184 free_watches (DBusTransportKdbus *kdbus_transport)
3185 {
3186   DBusConnection *connection = kdbus_transport->base.connection;
3187   _dbus_verbose ("start\n");
3188
3189   if (kdbus_transport->read_watch)
3190     {
3191       if (connection)
3192         _dbus_connection_remove_watch_unlocked (connection,
3193                                                 kdbus_transport->read_watch);
3194       _dbus_watch_invalidate (kdbus_transport->read_watch);
3195       _dbus_watch_unref (kdbus_transport->read_watch);
3196       kdbus_transport->read_watch = NULL;
3197     }
3198
3199   if (kdbus_transport->write_watch)
3200     {
3201       if (connection)
3202         _dbus_connection_remove_watch_unlocked (connection,
3203                                                 kdbus_transport->write_watch);
3204       _dbus_watch_invalidate (kdbus_transport->write_watch);
3205       _dbus_watch_unref (kdbus_transport->write_watch);
3206       kdbus_transport->write_watch = NULL;
3207     }
3208
3209   _dbus_verbose ("end\n");
3210 }
3211
3212 static void
3213 free_policies (DBusTransportKdbus *transport)
3214 {
3215 #ifdef LIBDBUSPOLICY
3216   if (NULL != transport->policy)
3217     dbuspolicy1_free (transport->policy);
3218 #endif
3219 }
3220
3221 /**
3222  * Copy-paste from socket transport. Only done needed renames and removed
3223  * lines related to encoded messages.
3224  */
3225 static void
3226 transport_finalize (DBusTransport *transport)
3227 {
3228   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus *)transport;
3229   _dbus_verbose ("\n");
3230
3231   free_watches (kdbus_transport);
3232
3233   _dbus_transport_finalize_base (transport);
3234
3235   _dbus_assert (kdbus_transport->read_watch == NULL);
3236   _dbus_assert (kdbus_transport->write_watch == NULL);
3237
3238   free_matchmaker (kdbus_transport->matchmaker);
3239
3240   dbus_free (kdbus_transport->activator);
3241
3242   free_policies ( kdbus_transport );
3243
3244   _kdbus_free (kdbus_transport->kdbus);
3245   free (kdbus_transport->my_DBus_unique_name);
3246
3247   dbus_free (transport);
3248 }
3249
3250 /**
3251  * Copy-paste from socket transport. Removed code related to authentication,
3252  * socket_transport replaced by kdbus_transport.
3253  */
3254 static void
3255 check_write_watch (DBusTransportKdbus *kdbus_transport)
3256 {
3257   dbus_bool_t needed;
3258   DBusTransport *transport = &kdbus_transport->base;
3259
3260   if (transport->connection == NULL)
3261     return;
3262
3263   if (transport->disconnected)
3264     {
3265       _dbus_assert (kdbus_transport->write_watch == NULL);
3266       return;
3267     }
3268
3269   _dbus_transport_ref (transport);
3270
3271   needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
3272
3273   _dbus_verbose ("check_write_watch (): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
3274                  needed, transport->connection, kdbus_transport->write_watch,
3275                  _kdbus_get_fd (kdbus_transport->kdbus),
3276                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3277
3278   _dbus_connection_toggle_watch_unlocked (transport->connection,
3279                                           kdbus_transport->write_watch,
3280                                           needed);
3281
3282   _dbus_transport_unref (transport);
3283 }
3284
3285 /**
3286  * Copy-paste from socket transport. Removed code related to authentication,
3287  * socket_transport replaced by kdbus_transport.
3288  */
3289 static void
3290 check_read_watch (DBusTransportKdbus *kdbus_transport)
3291 {
3292   dbus_bool_t need_read_watch;
3293   DBusTransport *transport = &kdbus_transport->base;
3294
3295   _dbus_verbose ("fd = %d\n",_kdbus_get_fd (kdbus_transport->kdbus));
3296
3297   if (transport->connection == NULL)
3298     return;
3299
3300   if (transport->disconnected)
3301     {
3302       _dbus_assert (kdbus_transport->read_watch == NULL);
3303       return;
3304     }
3305
3306   _dbus_transport_ref (transport);
3307
3308    need_read_watch =
3309       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
3310       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
3311
3312   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
3313
3314   _dbus_connection_toggle_watch_unlocked (transport->connection,
3315                                           kdbus_transport->read_watch,
3316                                           need_read_watch);
3317
3318   _dbus_transport_unref (transport);
3319 }
3320
3321 /**
3322  * Copy-paste from socket transport.
3323  */
3324 static void
3325 do_io_error (DBusTransport *transport)
3326 {
3327   _dbus_transport_ref (transport);
3328   _dbus_transport_disconnect (transport);
3329   _dbus_transport_unref (transport);
3330 }
3331
3332 /**
3333  *  Based on do_writing from socket transport.
3334  *  Removed authentication code and code related to encoded messages
3335  *  and adapted to kdbus transport.
3336  *  In socket transport returns false on out-of-memory. Here this won't happen,
3337  *  so it always returns TRUE.
3338  */
3339 static dbus_bool_t
3340 do_writing (DBusTransport *transport)
3341 {
3342   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3343   int total = 0;
3344   dbus_bool_t oom = FALSE;
3345
3346   if (transport->disconnected)
3347     {
3348       _dbus_verbose ("Not connected, not writing anything\n");
3349       return TRUE;
3350     }
3351
3352   _dbus_verbose ("do_writing (), have_messages = %d, fd = %d\n",
3353                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
3354                  _kdbus_get_fd (kdbus_transport->kdbus));
3355
3356   while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
3357     {
3358       int bytes_written;
3359       DBusMessage *message;
3360       DBusMessage *reply;
3361       const DBusString *header;
3362       const DBusString *body;
3363       const char* pDestination;
3364
3365       if (total > kdbus_transport->max_bytes_written_per_iteration)
3366         {
3367           _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
3368                          total, kdbus_transport->max_bytes_written_per_iteration);
3369           goto out;
3370         }
3371
3372       reply = NULL;
3373       message = _dbus_connection_get_message_to_send (transport->connection);
3374       _dbus_assert (message != NULL);
3375       pDestination = dbus_message_get_destination (message);
3376
3377       if (pDestination)
3378         {
3379           int ret;
3380
3381           ret = capture_org_freedesktop_DBus ((DBusTransportKdbus*)transport, pDestination, message, &reply);
3382           if (ret < 0)  //error
3383             {
3384               bytes_written = -1;
3385               goto written;
3386             }
3387           else if (ret == 0)  //message captured and handled correctly
3388             {
3389               /* puts locally generated reply into received messages queue */
3390               if (!add_message_to_received (reply, kdbus_transport->base.connection))
3391                 {
3392                   bytes_written = -1;
3393                   goto written;
3394                 }
3395
3396               _dbus_message_get_network_data (message, &header, &body);
3397               bytes_written = _dbus_string_get_length (header) + _dbus_string_get_length (body);
3398               goto written;
3399             }
3400           //else send as regular message
3401         }
3402
3403       bytes_written = kdbus_write_msg (kdbus_transport, message, pDestination);
3404
3405       written:
3406       if (bytes_written < 0)
3407         {
3408           if (errno == ENOMEM)
3409             {
3410               oom = TRUE;
3411               goto out;
3412             }
3413
3414           /* EINTR already handled for us */
3415
3416           /* For some discussion of why we also ignore EPIPE here, see
3417            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
3418            */
3419
3420           if (_dbus_get_is_errno_eagain_or_ewouldblock (errno) || _dbus_get_is_errno_epipe (errno))
3421             goto out;
3422           else
3423             {
3424               _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
3425               do_io_error (transport);
3426               goto out;
3427             }
3428         }
3429       else
3430         {
3431 #if defined (DBUS_ENABLE_VERBOSE_MODE) || !defined (DBUS_DISABLE_ASSERT)
3432           int total_bytes_to_write;
3433
3434           _dbus_message_get_network_data (message, &header, &body);
3435           total_bytes_to_write = _dbus_string_get_length (header)
3436                                    + _dbus_string_get_length (body);
3437           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
3438                          total_bytes_to_write);
3439
3440           _dbus_assert (bytes_written == total_bytes_to_write);
3441 #endif
3442           total += bytes_written;
3443
3444           _dbus_connection_message_sent_unlocked (transport->connection,
3445                   message);
3446         }
3447     }
3448
3449 out:
3450   if (oom)
3451     return FALSE;
3452   else
3453     return TRUE;
3454 }
3455
3456 /**
3457  *  Based on do_reading from socket transport.
3458  *  Removed authentication code and code related to encoded messages
3459  *  and adapted to kdbus transport.
3460  *  returns false on out-of-memory
3461  */
3462 static dbus_bool_t
3463 do_reading (DBusTransport *transport)
3464 {
3465   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3466   DBusString *buffer;
3467   int bytes_read;
3468   dbus_bool_t oom = FALSE;
3469   int *fds, n_fds;
3470   int total = 0;
3471
3472   _dbus_verbose ("fd = %d\n", _kdbus_get_fd (kdbus_transport->kdbus));
3473
3474  again:
3475
3476   /* See if we've exceeded max messages and need to disable reading */
3477  if (kdbus_transport->activator == NULL)
3478   check_read_watch (kdbus_transport);
3479
3480   if (total > kdbus_transport->max_bytes_read_per_iteration)
3481     {
3482       _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
3483                      total, kdbus_transport->max_bytes_read_per_iteration);
3484       goto out;
3485     }
3486
3487   _dbus_assert (kdbus_transport->read_watch != NULL ||
3488                 transport->disconnected);
3489
3490   if (transport->disconnected)
3491     goto out;
3492
3493   if (!dbus_watch_get_enabled (kdbus_transport->read_watch))
3494     return TRUE;
3495
3496   if (!_dbus_message_loader_get_unix_fds (transport->loader, &fds, &n_fds))
3497   {
3498       _dbus_verbose ("Out of memory reading file descriptors\n");
3499       oom = TRUE;
3500       goto out;
3501   }
3502   _dbus_message_loader_get_buffer (transport->loader, &buffer);
3503
3504   bytes_read = kdbus_read_message (kdbus_transport, buffer, fds, &n_fds);
3505
3506   if (bytes_read >= 0 && n_fds > 0)
3507     _dbus_verbose ("Read %i unix fds\n", n_fds);
3508
3509   _dbus_message_loader_return_buffer (transport->loader,
3510                                       buffer);
3511   _dbus_message_loader_return_unix_fds (transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
3512
3513   if (bytes_read < 0)
3514     {
3515       /* EINTR already handled for us */
3516
3517       if (_dbus_get_is_errno_enomem (errno))
3518         {
3519           _dbus_verbose ("Out of memory in read()/do_reading()\n");
3520           oom = TRUE;
3521           goto out;
3522         }
3523       else if (_dbus_get_is_errno_eagain_or_ewouldblock (errno))
3524         goto out;
3525       else
3526         {
3527           _dbus_verbose ("Error reading from remote app: %s\n",
3528                          _dbus_strerror_from_errno ());
3529           do_io_error (transport);
3530           goto out;
3531         }
3532     }
3533   else if (bytes_read > 0)
3534     {
3535       _dbus_verbose (" read %d bytes\n", bytes_read);
3536
3537       total += bytes_read;
3538
3539       if (!_dbus_transport_queue_messages (transport))
3540         {
3541           oom = TRUE;
3542           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
3543           goto out;
3544         }
3545
3546       /* Try reading more data until we get EAGAIN and return, or
3547        * exceed max bytes per iteration.  If in blocking mode of
3548        * course we'll block instead of returning.
3549        */
3550       goto again;
3551     }
3552   /* 0 == bytes_read is for kernel and ignored messages */
3553
3554  out:
3555   if (oom)
3556     return FALSE;
3557   return TRUE;
3558 }
3559
3560 /**
3561  * Copy-paste from socket transport, with socket replaced by kdbus.
3562  */
3563 static dbus_bool_t
3564 unix_error_with_read_to_come (DBusTransport *itransport,
3565                               DBusWatch     *watch,
3566                               unsigned int   flags)
3567 {
3568    DBusTransportKdbus *transport = (DBusTransportKdbus *) itransport;
3569
3570    if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
3571       return FALSE;
3572
3573   /* If we have a read watch enabled ...
3574      we -might have data incoming ... => handle the HANGUP there */
3575    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
3576       return FALSE;
3577
3578    return TRUE;
3579 }
3580
3581 /**
3582  *  Copy-paste from socket transport. Removed authentication related code
3583  *  and renamed socket_transport to kdbus_transport.
3584  */
3585 static dbus_bool_t
3586 kdbus_handle_watch (DBusTransport *transport,
3587                     DBusWatch     *watch,
3588                     unsigned int   flags)
3589 {
3590   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3591
3592   _dbus_assert (watch == kdbus_transport->read_watch ||
3593                 watch == kdbus_transport->write_watch);
3594   _dbus_assert (watch != NULL);
3595
3596   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
3597    * still be in the buffer and do_reading may need several iteration to read
3598    * it all (because of its max_bytes_read_per_iteration limit).
3599    */
3600   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
3601     {
3602       _dbus_verbose ("Hang up or error on watch\n");
3603       _dbus_transport_disconnect (transport);
3604       return TRUE;
3605     }
3606
3607   if (watch == kdbus_transport->read_watch &&
3608       (flags & DBUS_WATCH_READABLE))
3609     {
3610       _dbus_verbose ("handling read watch %p flags = %x\n",
3611                      watch, flags);
3612
3613       if (!do_reading (transport))
3614         {
3615           _dbus_verbose ("no memory to read\n");
3616           return FALSE;
3617         }
3618     }
3619   else if (watch == kdbus_transport->write_watch &&
3620           (flags & DBUS_WATCH_WRITABLE))
3621     {
3622       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
3623                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3624
3625       if (!do_writing (transport))
3626         {
3627           _dbus_verbose ("no memory to write\n");
3628           return FALSE;
3629         }
3630
3631       /* See if we still need the write watch */
3632       check_write_watch (kdbus_transport);
3633     }
3634
3635   return TRUE;
3636 }
3637
3638 /**
3639  * Copy-paste from socket transport, but socket_transport renamed to kdbus_transport
3640  * and _dbus_close_socket replaced with close ().
3641  */
3642 static void
3643 kdbus_disconnect (DBusTransport *transport)
3644 {
3645   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3646
3647   _dbus_verbose ("\n");
3648
3649   free_watches (kdbus_transport);
3650
3651   _kdbus_close (kdbus_transport->kdbus);
3652 }
3653
3654 /**
3655  *  Copy-paste from socket transport. Renamed socket_transport to
3656  *  kdbus_transport and added setting authenticated to TRUE, because
3657  *  we do not perform authentication in kdbus, so we have mark is as already done
3658  *  to make everything work.
3659  */
3660 static dbus_bool_t
3661 kdbus_connection_set (DBusTransport *transport)
3662 {
3663   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3664
3665   _dbus_watch_set_handler (kdbus_transport->write_watch,
3666                            _dbus_connection_handle_watch,
3667                            transport->connection, NULL);
3668
3669   _dbus_watch_set_handler (kdbus_transport->read_watch,
3670                            _dbus_connection_handle_watch,
3671                            transport->connection, NULL);
3672
3673   if (!_dbus_connection_add_watch_unlocked (transport->connection,
3674                                             kdbus_transport->write_watch))
3675     return FALSE;
3676
3677   if (!_dbus_connection_add_watch_unlocked (transport->connection,
3678                                             kdbus_transport->read_watch))
3679     {
3680       _dbus_connection_remove_watch_unlocked (transport->connection,
3681                                               kdbus_transport->write_watch);
3682       return FALSE;
3683     }
3684
3685   check_read_watch (kdbus_transport);
3686   check_write_watch (kdbus_transport);
3687
3688   return TRUE;
3689 }
3690
3691 /**
3692  *  Copy-paste from socket_transport.
3693  *  Socket_transport renamed to kdbus_transport
3694  *
3695  *   Original dbus copy-pasted @todo comment below.
3696  * @todo We need to have a way to wake up the select sleep if
3697  * a new iteration request comes in with a flag (read/write) that
3698  * we're not currently serving. Otherwise a call that just reads
3699  * could block a write call forever (if there are no incoming
3700  * messages).
3701  */
3702 static void
3703 kdbus_do_iteration (DBusTransport *transport,
3704                    unsigned int   flags,
3705                    int            timeout_milliseconds)
3706 {
3707   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3708   DBusPollFD poll_fd;
3709   int poll_res;
3710   int poll_timeout;
3711
3712   _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
3713                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
3714                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
3715                  timeout_milliseconds,
3716                  kdbus_transport->read_watch,
3717                  kdbus_transport->write_watch,
3718                  _kdbus_get_fd (kdbus_transport->kdbus));
3719
3720    poll_fd.fd = _kdbus_get_fd (kdbus_transport->kdbus);
3721    poll_fd.events = 0;
3722
3723    /*
3724     * TODO test this.
3725     * This fix is for reply_with_error function.
3726     * When timeout is set to -1 in client application,
3727     * error messages are inserted directly to incoming queue and
3728     * application hangs on dbus_poll.
3729     *
3730     * This causes a busy loop in _dbus_connection_block_pending_call() 
3731     * There is no case of waiting for the locally-generated error reply
3732
3733    if (_dbus_connection_get_n_incoming (transport->connection) > 0)
3734    {
3735      timeout_milliseconds = 0;
3736    }
3737     */
3738
3739    /* This is kind of a hack; if we have stuff to write, then try
3740     * to avoid the poll. This is probably about a 5% speedup on an
3741     * echo client/server.
3742     *
3743     * If both reading and writing were requested, we want to avoid this
3744     * since it could have funky effects:
3745     *   - both ends spinning waiting for the other one to read
3746     *     data so they can finish writing
3747     *   - prioritizing all writing ahead of reading
3748     */
3749    if ((flags & DBUS_ITERATION_DO_WRITING) &&
3750        !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
3751        !transport->disconnected &&
3752        _dbus_connection_has_messages_to_send_unlocked (transport->connection))
3753      {
3754        do_writing (transport);
3755
3756        if (transport->disconnected ||
3757            !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
3758          goto out;
3759      }
3760
3761    /* If we get here, we decided to do the poll() after all */
3762    _dbus_assert (kdbus_transport->read_watch);
3763    if (flags & DBUS_ITERATION_DO_READING)
3764      poll_fd.events |= _DBUS_POLLIN;
3765
3766    _dbus_assert (kdbus_transport->write_watch);
3767    if (flags & DBUS_ITERATION_DO_WRITING)
3768      poll_fd.events |= _DBUS_POLLOUT;
3769
3770    if (poll_fd.events)
3771    {
3772       if ( (flags & DBUS_ITERATION_BLOCK) && !(flags & DBUS_ITERATION_DO_WRITING))
3773         poll_timeout = timeout_milliseconds;
3774       else
3775         poll_timeout = 0;
3776
3777       /* For blocking selects we drop the connection lock here
3778        * to avoid blocking out connection access during a potentially
3779        * indefinite blocking call. The io path is still protected
3780        * by the io_path_cond condvar, so we won't reenter this.
3781        */
3782       if (flags & DBUS_ITERATION_BLOCK)
3783       {
3784          _dbus_verbose ("unlock pre poll\n");
3785          _dbus_connection_unlock (transport->connection);
3786       }
3787
3788     again:
3789       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
3790
3791       if (poll_res < 0 && _dbus_get_is_errno_eintr (errno))
3792         goto again;
3793
3794       if (flags & DBUS_ITERATION_BLOCK)
3795       {
3796          _dbus_verbose ("lock post poll\n");
3797          _dbus_connection_lock (transport->connection);
3798       }
3799
3800       if (poll_res >= 0)
3801       {
3802          if (poll_res == 0)
3803             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
3804                                   * valgrind flags it as an error. though it probably
3805                                   * is guaranteed on linux at least.
3806                                   */
3807
3808          if (poll_fd.revents & _DBUS_POLLERR)
3809             do_io_error (transport);
3810          else
3811          {
3812             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
3813
3814             _dbus_verbose ("in iteration, need_read=%d\n",
3815                              need_read);
3816
3817             if (need_read && (flags & DBUS_ITERATION_DO_READING))
3818                do_reading (transport);
3819             /* We always be able to write to kdbus */
3820             if (flags & DBUS_ITERATION_DO_WRITING)
3821                do_writing (transport);
3822          }
3823       }
3824       else
3825          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
3826    }
3827
3828  out:
3829   /* We need to install the write watch only if we did not
3830    * successfully write everything. Note we need to be careful that we
3831    * don't call check_write_watch *before* do_writing, since it's
3832    * inefficient to add the write watch, and we can avoid it most of
3833    * the time since we can write immediately.
3834    *
3835    * However, we MUST always call check_write_watch(); DBusConnection code
3836    * relies on the fact that running an iteration will notice that
3837    * messages are pending.
3838    */
3839    check_write_watch (kdbus_transport);
3840
3841    _dbus_verbose (" ... leaving do_iteration()\n");
3842 }
3843
3844 /**
3845  * Copy-paste from socket transport.
3846  */
3847 static void
3848 kdbus_live_messages_changed (DBusTransport *transport)
3849 {
3850   /* See if we should look for incoming messages again */
3851   check_read_watch ((DBusTransportKdbus *)transport);
3852 }
3853
3854 /**
3855  * Gets file descriptor of the kdbus bus.
3856  * @param transport transport
3857  * @param fd_p place to write fd to
3858  * @returns always TRUE
3859  */
3860 static dbus_bool_t
3861 kdbus_get_kdbus_fd (DBusTransport *transport,
3862                     DBusSocket    *fd_p)
3863 {
3864   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3865
3866   fd_p->fd = _kdbus_get_fd (kdbus_transport->kdbus);
3867
3868   return TRUE;
3869 }
3870
3871 static const DBusTransportVTable kdbus_vtable = {
3872   transport_finalize,
3873   kdbus_handle_watch,
3874   kdbus_disconnect,
3875   kdbus_connection_set,
3876   kdbus_do_iteration,
3877   kdbus_live_messages_changed,
3878   kdbus_get_kdbus_fd
3879 };
3880
3881 typedef unsigned long (*ConnectionInfoExtractField) (struct nameInfo *);
3882
3883 static inline unsigned long
3884 _extract_name_info_userId (struct nameInfo *nameInfo)
3885 {
3886   return nameInfo->userId;
3887 }
3888
3889 static inline unsigned long
3890 _extract_name_info_processId (struct nameInfo *nameInfo)
3891 {
3892   return nameInfo->processId;
3893 }
3894
3895 static dbus_bool_t
3896 _dbus_transport_kdbus_get_connection_info_ulong_field (DBusTransportKdbus         *transport,
3897                                                        ConnectionInfoExtractField  function,
3898                                                        unsigned long              *val)
3899 {
3900   struct nameInfo conn_info;
3901   int ret;
3902
3903   ret = _kdbus_connection_info_by_id (transport->kdbus,
3904                                       _kdbus_get_id (transport->kdbus),
3905                                       FALSE,
3906                                       &conn_info);
3907   if (ret != 0)
3908     return FALSE;
3909
3910   *val = function (&conn_info);
3911   return TRUE;
3912 }
3913
3914 static dbus_bool_t
3915 _dbus_transport_kdbus_get_unix_user (DBusTransport *transport,
3916                                      unsigned long *uid)
3917 {
3918   return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
3919                                                                 _extract_name_info_userId,
3920                                                                 uid);
3921 }
3922
3923 static dbus_bool_t
3924 _dbus_transport_kdbus_get_unix_process_id (DBusTransport *transport,
3925                                            unsigned long *pid)
3926 {
3927   return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
3928                                                                 _extract_name_info_processId,
3929                                                                 pid);
3930 }
3931
3932 /**
3933  * Copy-paste from dbus_transport_socket with needed changes.
3934  *
3935  * Creates a new transport for the given kdbus file descriptor and address.
3936  * The file descriptor must be nonblocking.
3937  *
3938  * @param fd the file descriptor.
3939  * @param address the transport's address
3940  * @returns the new transport, or #NULL if no memory.
3941  */
3942 static DBusTransportKdbus *
3943 new_kdbus_transport (kdbus_t          *kdbus,
3944                      const DBusString *address,
3945                      const char       *activator)
3946 {
3947   DBusTransportKdbus *kdbus_transport;
3948
3949   kdbus_transport = dbus_new0 (DBusTransportKdbus, 1);
3950   if (kdbus_transport == NULL)
3951     return NULL;
3952
3953   kdbus_transport->kdbus = kdbus;
3954
3955   kdbus_transport->write_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
3956                                                  DBUS_WATCH_WRITABLE,
3957                                                  FALSE,
3958                                                  NULL, NULL, NULL);
3959   if (kdbus_transport->write_watch == NULL)
3960     goto failed_2;
3961
3962   kdbus_transport->read_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
3963                                                 DBUS_WATCH_READABLE,
3964                                                 FALSE,
3965                                                 NULL, NULL, NULL);
3966   if (kdbus_transport->read_watch == NULL)
3967     goto failed_3;
3968
3969   if (!_dbus_transport_init_base_authenticated (&kdbus_transport->base,
3970                                                 &kdbus_vtable,
3971                                                 NULL, address))
3972     goto failed_4;
3973
3974   _dbus_transport_set_get_unix_user_function (&kdbus_transport->base,
3975                                               _dbus_transport_kdbus_get_unix_user);
3976   _dbus_transport_set_get_unix_process_id_function (&kdbus_transport->base,
3977                                                     _dbus_transport_kdbus_get_unix_process_id);
3978   _dbus_transport_set_assure_protocol_function (&kdbus_transport->base,
3979                                                 _dbus_message_assure_gvariant,
3980                                                 DBUS_PROTOCOL_VERSION_GVARIANT);
3981
3982   /* These values should probably be tunable or something. */
3983   kdbus_transport->max_bytes_read_per_iteration = MAX_BYTES_PER_ITERATION;
3984   kdbus_transport->max_bytes_written_per_iteration = MAX_BYTES_PER_ITERATION;
3985
3986   if (activator!=NULL)
3987     {
3988       kdbus_transport->activator = _dbus_strdup (activator);
3989       if (kdbus_transport->activator == NULL)
3990         goto failed_4;
3991     }
3992
3993   kdbus_transport->matchmaker = matchmaker_new ();
3994
3995   kdbus_transport->client_serial = 1;
3996
3997   return kdbus_transport;
3998
3999  failed_4:
4000   _dbus_watch_invalidate (kdbus_transport->read_watch);
4001   _dbus_watch_unref (kdbus_transport->read_watch);
4002  failed_3:
4003   _dbus_watch_invalidate (kdbus_transport->write_watch);
4004   _dbus_watch_unref (kdbus_transport->write_watch);
4005  failed_2:
4006   dbus_free (kdbus_transport);
4007   return NULL;
4008 }
4009
4010 static dbus_bool_t
4011 initialize_policies (DBusTransportKdbus *transport, const char *path)
4012 {
4013   dbus_bool_t result = TRUE;
4014
4015 #ifdef LIBDBUSPOLICY
4016   transport->policy = dbuspolicy1_init (path);
4017   if (NULL == transport->policy)
4018     result = FALSE;
4019 #endif
4020
4021   return result;
4022 }
4023
4024 /**
4025  * Connects to kdbus, creates and sets-up transport.
4026  *
4027  * @param path the path to the bus.
4028  * @param error address where an error can be returned.
4029  * @returns a new transport, or #NULL on failure.
4030  */
4031 static DBusTransport*
4032 _dbus_transport_new_for_kdbus (const char *path,
4033                                const char *activator,
4034                                DBusError  *error)
4035 {
4036   int ret;
4037   DBusTransportKdbus *transport;
4038   DBusString address;
4039   kdbus_t *kdbus;
4040
4041 #ifdef DBUS_ENABLE_VERBOSE_MODE
4042   const char *dbgenv = _dbus_getenv ("G_DBUS_DEBUG");
4043   if (dbgenv != NULL)
4044   {
4045     if (!strcmp (dbgenv, "message"))
4046       debug = 1;
4047     else if (!strcmp (dbgenv, "all"))
4048       debug = 2;
4049   }
4050 #endif
4051
4052   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4053
4054   if (!_dbus_string_init (&address))
4055     {
4056       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4057       return NULL;
4058     }
4059
4060   if ((!_dbus_string_append (&address, DBUS_ADDRESS_KDBUS "path=")) || (!_dbus_string_append (&address, path)))
4061     {
4062       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4063       goto failed_0;
4064     }
4065
4066   kdbus = _kdbus_new ();
4067   if (NULL == kdbus)
4068     {
4069       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4070       goto failed_0;
4071     }
4072
4073   ret = _kdbus_open (kdbus, path);
4074   if (ret < 0)
4075     {
4076       dbus_set_error (error,
4077                       _dbus_error_from_errno (-ret),
4078                       "Failed to open file descriptor: %s: %s",
4079                       path,
4080                       _dbus_strerror (-ret));
4081       goto failed_0_with_kdbus;
4082     }
4083
4084   _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
4085
4086   transport = new_kdbus_transport (kdbus, &address, activator);
4087   if (transport == NULL)
4088     {
4089       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4090       goto failed_1;
4091     }
4092
4093   if (!initialize_policies (transport, path))
4094     {
4095       dbus_set_error (error,
4096                       DBUS_ERROR_FAILED,
4097                       "Can't load dbus policy for kdbus transport");
4098       _kdbus_close (kdbus);
4099       transport_finalize ((DBusTransport*)transport);
4100       transport = NULL;
4101     }
4102
4103   _dbus_string_free (&address);
4104
4105   return (DBusTransport*)transport;
4106
4107 failed_1:
4108   _kdbus_close (kdbus);
4109 failed_0_with_kdbus:
4110   _kdbus_free (kdbus);
4111 failed_0:
4112   _dbus_string_free (&address);
4113   return NULL;
4114 }
4115
4116
4117 /**
4118  * Opens kdbus transport if method from address entry is kdbus
4119  *
4120  * @param entry the address entry to open
4121  * @param transport_p return location for the opened transport
4122  * @param error place to store error
4123  * @returns result of the attempt as a DBusTransportOpenResult enum
4124  */
4125 DBusTransportOpenResult
4126 _dbus_transport_open_kdbus (DBusAddressEntry  *entry,
4127                             DBusTransport    **transport_p,
4128                             DBusError         *error)
4129 {
4130   const char *method;
4131
4132   method = dbus_address_entry_get_method (entry);
4133   _dbus_assert (method != NULL);
4134
4135   if (strcmp (method, "kernel") == 0)
4136     {
4137       const char *path = dbus_address_entry_get_value (entry, "path");
4138       const char *activator = dbus_address_entry_get_value (entry, "activator");
4139
4140       if (path == NULL)
4141         {
4142           _dbus_set_bad_address (error, "kdbus", "path", NULL);
4143           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
4144         }
4145
4146       *transport_p = _dbus_transport_new_for_kdbus (path, activator, error);
4147
4148       if (*transport_p == NULL)
4149         {
4150           _DBUS_ASSERT_ERROR_IS_SET (error);
4151           return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
4152         }
4153       else
4154         {
4155           _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4156           return DBUS_TRANSPORT_OPEN_OK;
4157         }
4158     }
4159   else
4160     {
4161       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4162       return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
4163     }
4164 }
4165
4166 /** @} */