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