2eb532c414cb5d72936e3182c16cc69f7df77c75
[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               char *name_ptr = item->name.name;
2218
2219               if (!dbus_validate_bus_name (name_ptr, NULL))
2220                 continue;
2221
2222               if (flags & KDBUS_LIST_QUEUED)
2223                 name_ptr = create_unique_name_from_unique_id (name->id);
2224
2225               if (NULL == name_ptr)
2226                 goto oom_iterator;
2227
2228               if (!dbus_message_iter_append_basic (&array_iter,
2229                                                    DBUS_TYPE_STRING,
2230                                                    &name_ptr))
2231                 {
2232                   if (flags & KDBUS_LIST_QUEUED)
2233                     free (name_ptr);
2234                   goto oom_iterator;
2235                 }
2236
2237               if (flags & KDBUS_LIST_QUEUED)
2238                 free (name_ptr);
2239             }
2240         }
2241     }
2242
2243   if (!dbus_message_iter_close_container (&iter, &array_iter))
2244     goto oom_reply;
2245
2246   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
2247     goto oom_reply;
2248
2249   _kdbus_free_mem (transport->kdbus, name_list);
2250
2251   return reply;
2252
2253 oom_iterator:
2254   dbus_message_iter_abandon_container (&iter, &array_iter);
2255
2256 oom_reply:
2257   dbus_message_unref (reply);
2258 oom:
2259   _kdbus_free_mem (transport->kdbus, name_list);
2260   return NULL;
2261 }
2262
2263 static DBusMessage *
2264 capture_org_freedesktop_DBus_ListActivatableNames (DBusTransportKdbus *transport,
2265                                                    DBusMessage        *message,
2266                                                    DBusError          *error)
2267 {
2268   return reply_listNames (transport, message, error, KDBUS_LIST_ACTIVATORS);
2269 }
2270
2271 static DBusMessage *
2272 capture_org_freedesktop_DBus_ListNames (DBusTransportKdbus *transport,
2273                                         DBusMessage        *message,
2274                                         DBusError          *error)
2275 {
2276   return reply_listNames (transport, message, error, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES);
2277 }
2278
2279 static DBusMessage *
2280 capture_org_freedesktop_DBus_ListQueuedOwners (DBusTransportKdbus *transport,
2281                                                DBusMessage        *message,
2282                                                DBusError          *error)
2283 {
2284   struct nameInfo info;
2285
2286   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2287     return NULL;
2288
2289   return reply_listNames (transport, message, error, KDBUS_LIST_QUEUED);
2290 }
2291
2292 static DBusMessage *
2293 capture_org_freedesktop_DBus_NameHasOwner (DBusTransportKdbus *transport,
2294                                            DBusMessage        *message,
2295                                            DBusError          *error)
2296 {
2297   struct nameInfo info;
2298   dbus_bool_t result = TRUE;
2299
2300   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2301     {
2302       if (dbus_error_is_set (error) && dbus_error_has_name (error, DBUS_ERROR_NAME_HAS_NO_OWNER))
2303         {
2304           result = FALSE;
2305           dbus_error_free (error);
2306         }
2307       else
2308         return NULL;
2309     }
2310
2311   return reply_1_data (message, DBUS_TYPE_BOOLEAN, &result);
2312 }
2313
2314 static DBusMessage *
2315 capture_org_freedesktop_DBus_ReloadConfig (DBusTransportKdbus *transport,
2316                                            DBusMessage        *message,
2317                                            DBusError          *error)
2318 {
2319   DBusMessageIter iter;
2320   DBusMessage *reply = NULL;
2321
2322   dbus_message_iter_init (message, &iter);
2323   if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT)
2324     {
2325       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2326           "Call to 'ReloadConfig' has wrong args");
2327       return NULL;
2328     }
2329
2330   reply = dbus_message_new_method_return (message);
2331   if (reply == NULL)
2332     return NULL;
2333
2334   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
2335     goto oom;
2336
2337   return reply;
2338
2339 oom:
2340   dbus_message_unref (reply);
2341   return NULL;
2342 }
2343
2344 static DBusMessage *
2345 capture_org_freedesktop_DBus_StartServiceByName (DBusTransportKdbus *transport,
2346                                                  DBusMessage        *message,
2347                                                  DBusError          *error)
2348 {
2349   struct nameInfo info;
2350   char *name;
2351   dbus_uint32_t flags; /* Spec says: not used, but we check the syntax anyway */
2352   int ret = 0;
2353   dbus_bool_t dbus_service = FALSE;
2354
2355   if (!dbus_message_get_args (message, error,
2356                               DBUS_TYPE_STRING, &name,
2357                               DBUS_TYPE_UINT32, &flags,
2358                               DBUS_TYPE_INVALID))
2359     return NULL;
2360
2361   dbus_service = (strncmp (name, DBUS_SERVICE_DBUS, strlen (DBUS_SERVICE_DBUS) + 1) == 0);
2362
2363   if (!dbus_service)
2364     ret = get_connection_info_by_name (message,
2365                                        error,
2366                                        &info,
2367                                        transport,
2368                                        name,
2369                                        FALSE);
2370
2371   if (dbus_service || 0 == ret)
2372     {
2373       dbus_uint32_t status = DBUS_START_REPLY_ALREADY_RUNNING;
2374       return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2375     }
2376   else if (-ESRCH == ret) /* there is an activator */
2377     {
2378       DBusMessage *sub_message;
2379
2380       /* if we are here, then we have error set - free place for possible real error */
2381       dbus_error_free (error);
2382
2383       /* send method call to org.freedesktop.DBus.Peer.Ping */
2384       sub_message = dbus_message_new_method_call (name, "/", DBUS_INTERFACE_PEER, "Ping");
2385       if (sub_message == NULL)
2386         return NULL;
2387
2388       /* The serial number here is set to -1. A message needs a valid serial number.
2389        * We do not have access to connection's serial numbers counter, so we need to make up one.
2390        * -1 is the last valid serial, so we hope that we'll never get there, especially with 64-bit
2391        * kdbus cookies.
2392        */
2393       dbus_message_set_serial (sub_message, -1);
2394
2395       dbus_message_lock (sub_message);
2396
2397       ret = kdbus_write_msg_internal (transport, sub_message, name, NULL, FALSE);
2398
2399       dbus_message_unref (sub_message);
2400
2401       if (ret == -1)
2402           return NULL;
2403       else
2404         {
2405           dbus_uint32_t status = DBUS_START_REPLY_SUCCESS;
2406           return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2407         }
2408     }
2409   else
2410     {
2411       /*
2412        * There was an error set in get_connection_info_by_name()
2413        * We want to have another error return from StartServiceByName.
2414        */
2415       dbus_error_free (error);
2416       dbus_set_error (error,
2417                       DBUS_ERROR_SERVICE_UNKNOWN,
2418                       "The name %s was not provided by any .service files",
2419                       name);
2420     }
2421
2422   return NULL;
2423 }
2424
2425 static DBusMessage *
2426 capture_org_freedesktop_DBus_UpdateActivationEnvironment (DBusTransportKdbus *transport,
2427                                                           DBusMessage        *message,
2428                                                           DBusError          *error)
2429 {
2430   dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
2431       "'%s' method not supported", dbus_message_get_member (message));
2432   return NULL;
2433 }
2434
2435 typedef DBusMessage * (*CaptureHandler)(DBusTransportKdbus *, DBusMessage *, DBusError *);
2436 struct CaptureHandlers {
2437   const char *method_name;
2438   CaptureHandler handler;
2439 };
2440
2441 #define HANDLER_ELEMENT(x) {#x, capture_org_freedesktop_DBus_##x}
2442
2443 /* This is to cut the code to parts, and keep it organized:
2444  * an array of elements of type, as in example:
2445  * { "RequestName", capture_org_freedesktop_DBus_RequestName }
2446  * That is, a method of name RequestName will be handled by capture_org_freedesktop_DBus_RequestName ().
2447  */
2448 static struct CaptureHandlers capture_handlers[] =
2449 {
2450 // "Hello" is handled separately
2451 //  HANDLER_ELEMENT (Hello),
2452   HANDLER_ELEMENT (RequestName),
2453   HANDLER_ELEMENT (ReleaseName),
2454   HANDLER_ELEMENT (AddMatch),
2455   HANDLER_ELEMENT (RemoveMatch),
2456   HANDLER_ELEMENT (GetConnectionCredentials),
2457   HANDLER_ELEMENT (GetConnectionSELinuxSecurityContext),
2458   HANDLER_ELEMENT (GetConnectionUnixProcessID),
2459   HANDLER_ELEMENT (GetConnectionUnixUser),
2460   HANDLER_ELEMENT (GetId),
2461   HANDLER_ELEMENT (GetNameOwner),
2462   HANDLER_ELEMENT (ListActivatableNames),
2463   HANDLER_ELEMENT (ListNames),
2464   HANDLER_ELEMENT (ListQueuedOwners),
2465   HANDLER_ELEMENT (NameHasOwner),
2466   HANDLER_ELEMENT (ReloadConfig),
2467   HANDLER_ELEMENT (StartServiceByName),
2468   HANDLER_ELEMENT (UpdateActivationEnvironment)
2469 };
2470
2471 /**
2472  * Looks over messages sent to org.freedesktop.DBus. Hello message, which performs
2473  * registration on the bus, is captured as it must be locally converted into
2474  * appropriate ioctl. AddMatch and RemoveMatch are captured to store match rules
2475  * locally in case of false positive result of kdbus bloom filters, but after
2476  * being read they are passed to org.freedesktop.DBus to register these rules
2477  * in kdbus.
2478  * All the rest org.freedesktop.DBus methods are left untouched
2479  * and they are sent to dbus-daemon in the same way as every other messages.
2480  *
2481  * @param transport Transport
2482  * @param message Message being sent.
2483  * @returns
2484         1 if message is not captured and should be passed to kdbus
2485  *      0 if message was handled locally and correctly (it includes proper return of error reply),
2486  *     -1 message to org.freedesktop.DBus was not handled correctly.
2487  */
2488 static int
2489 capture_org_freedesktop_DBus (DBusTransportKdbus *transport,
2490                               const char         *destination,
2491                               DBusMessage        *message,
2492                               DBusMessage       **reply)
2493 {
2494   int ret = 1;
2495   if (!strcmp (destination, DBUS_SERVICE_DBUS))
2496     {
2497       const char *interface = dbus_message_get_interface (message);
2498       if (interface && !strcmp (interface, DBUS_INTERFACE_DBUS))
2499         {
2500           DBusError error;
2501           const char *member = dbus_message_get_member (message);
2502
2503           _dbus_assert (member != NULL);
2504
2505           dbus_error_init (&error);
2506
2507           if (!strcmp (member, "Hello"))
2508             {
2509               *reply = capture_org_freedesktop_DBus_Hello (transport, message, &error);
2510             }
2511           else
2512             {
2513               int i = 0;
2514               int handlers_size = sizeof (capture_handlers)/sizeof (capture_handlers[0]);
2515
2516               while (i < handlers_size && strcmp (member, capture_handlers[i].method_name) != 0)
2517                 i++;
2518
2519               if (i < handlers_size)
2520                 {
2521                   *reply = capture_handlers[i].handler (transport, message, &error);
2522                 }
2523               else
2524                 {
2525                   dbus_set_error (&error, DBUS_ERROR_UNKNOWN_METHOD,
2526                       "org.freedesktop.DBus does not understand message %s", member);
2527                 }
2528             }
2529
2530           if (*reply == NULL && dbus_error_is_set (&error))
2531             {
2532               *reply = reply_with_error ((char*)error.name,
2533                                          NULL,
2534                                          error.message,
2535                                          message);
2536               dbus_error_free (&error);
2537             }
2538
2539            if (*reply == NULL)
2540              ret = -1;
2541            else
2542              ret = 0;
2543
2544         } /* if DBUS_INTERFACE_DBUS */
2545     } /* if DBUS_SERVICE_DBUS */
2546
2547   return ret;
2548 }
2549
2550 #ifdef DBUS_ENABLE_VERBOSE_MODE
2551 #define ENUM_NAME_ITEM(x) case x : return #x
2552
2553 static const char *
2554 enum_MSG (long long id)
2555 {
2556   switch (id)
2557     {
2558       ENUM_NAME_ITEM (_KDBUS_ITEM_NULL);
2559       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_VEC);
2560       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_OFF);
2561       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_MEMFD);
2562       ENUM_NAME_ITEM (KDBUS_ITEM_FDS);
2563       ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_PARAMETER);
2564       ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_FILTER);
2565       ENUM_NAME_ITEM (KDBUS_ITEM_DST_NAME);
2566       ENUM_NAME_ITEM (KDBUS_ITEM_CREDS);
2567       ENUM_NAME_ITEM (KDBUS_ITEM_PID_COMM);
2568       ENUM_NAME_ITEM (KDBUS_ITEM_TID_COMM);
2569       ENUM_NAME_ITEM (KDBUS_ITEM_EXE);
2570       ENUM_NAME_ITEM (KDBUS_ITEM_CMDLINE);
2571       ENUM_NAME_ITEM (KDBUS_ITEM_CGROUP);
2572       ENUM_NAME_ITEM (KDBUS_ITEM_CAPS);
2573       ENUM_NAME_ITEM (KDBUS_ITEM_SECLABEL);
2574       ENUM_NAME_ITEM (KDBUS_ITEM_AUDIT);
2575       ENUM_NAME_ITEM (KDBUS_ITEM_CONN_DESCRIPTION);
2576       ENUM_NAME_ITEM (KDBUS_ITEM_NAME);
2577       ENUM_NAME_ITEM (KDBUS_ITEM_TIMESTAMP);
2578       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_ADD);
2579       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_REMOVE);
2580       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_CHANGE);
2581       ENUM_NAME_ITEM (KDBUS_ITEM_ID_ADD);
2582       ENUM_NAME_ITEM (KDBUS_ITEM_ID_REMOVE);
2583       ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_TIMEOUT);
2584       ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_DEAD);
2585     }
2586   return "UNKNOWN";
2587 }
2588
2589 #if KDBUS_MSG_DECODE_DEBUG == 1
2590 static const char *
2591 enum_PAYLOAD (long long id)
2592 {
2593   switch (id)
2594     {
2595       ENUM_NAME_ITEM (KDBUS_PAYLOAD_KERNEL);
2596       ENUM_NAME_ITEM (KDBUS_PAYLOAD_DBUS);
2597     }
2598   return "UNKNOWN";
2599 }
2600
2601 static const char *
2602 msg_id (uint64_t id)
2603 {
2604   char buf[64];
2605   const char* const_ptr;
2606
2607   if (id == 0)
2608     return "KERNEL";
2609   if (id == ~0ULL)
2610     return "BROADCAST";
2611
2612   snprintf (buf, sizeof (buf), "%llu", (unsigned long long)id);
2613
2614   const_ptr = buf;
2615   return const_ptr;
2616 }
2617 #endif
2618 #endif
2619
2620 static dbus_uint32_t
2621 get_next_client_serial (DBusTransportKdbus *transport)
2622 {
2623   dbus_uint32_t serial;
2624
2625   serial = transport->client_serial++;
2626
2627   if (transport->client_serial == 0)
2628     transport->client_serial = 1;
2629
2630   return serial;
2631 }
2632
2633 /**
2634  * Calculates length of the kdbus message content (payload).
2635  *
2636  * @param msg kdbus message
2637  * @return the length of the kdbus message's payload.
2638  */
2639 static int
2640 kdbus_message_size (const struct kdbus_msg *msg,
2641                     int                    *n_fds)
2642 {
2643   const struct kdbus_item *item;
2644   int ret_size = 0;
2645
2646   *n_fds = 0;
2647   KDBUS_ITEM_FOREACH (item, msg, items)
2648     {
2649       if (item->size < KDBUS_ITEM_HEADER_SIZE)
2650         {
2651           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2652           return -1;
2653         }
2654       switch (item->type)
2655         {
2656           case KDBUS_ITEM_PAYLOAD_OFF:
2657             ret_size += item->vec.size;
2658             break;
2659           case KDBUS_ITEM_PAYLOAD_MEMFD:
2660             ret_size += item->memfd.size;
2661             break;
2662           case KDBUS_ITEM_FDS:
2663             *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof (int);
2664             break;
2665           default:
2666             break;
2667         }
2668     }
2669
2670   return ret_size;
2671 }
2672
2673 static int
2674 generate_NameSignal (const char         *signal,
2675                      const char         *name,
2676                      DBusTransportKdbus *transport)
2677 {
2678   DBusMessage *message;
2679
2680   _dbus_verbose ("Generating %s for %s.\n", signal, name);
2681
2682   message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, signal);
2683   if (message == NULL)
2684     return -1;
2685
2686   if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
2687     goto error;
2688   if (!dbus_message_set_destination (message, transport->my_DBus_unique_name))
2689     goto error;
2690   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
2691     goto error;
2692   dbus_message_set_serial (message, get_next_client_serial (transport));
2693
2694   if (!add_message_to_received (message, transport->base.connection))
2695     return -1;
2696
2697   return 0;
2698
2699   error:
2700     dbus_message_unref (message);
2701     return -1;
2702 }
2703
2704 /*
2705  * The NameOwnerChanged signals take three parameters with
2706  * unique or well-known names, but only some forms actually
2707  * exist:
2708  *
2709  * WELLKNOWN, "", UNIQUE       â†’ KDBUS_ITEM_NAME_ADD
2710  * WELLKNOWN, UNIQUE, ""       â†’ KDBUS_ITEM_NAME_REMOVE
2711  * WELLKNOWN, UNIQUE, UNIQUE   â†’ KDBUS_ITEM_NAME_CHANGE
2712  * UNIQUE, "", UNIQUE          â†’ KDBUS_ITEM_ID_ADD
2713  * UNIQUE, UNIQUE, ""          â†’ KDBUS_ITEM_ID_REMOVE
2714  *
2715  * For the latter two the two unique names must be identical.
2716  */
2717 static int
2718 kdbus_handle_name_owner_changed (__u64               type,
2719                                  const char         *bus_name,
2720                                  __u64               old,
2721                                  __u64               new,
2722                                  DBusTransportKdbus *transport)
2723 {
2724   DBusMessage *message = NULL;
2725   DBusMessageIter args;
2726   char tmp_str[128];
2727   const char *const_ptr;
2728
2729   if ((message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) == NULL)
2730     return -1;
2731
2732   dbus_message_iter_init_append (message, &args);
2733
2734   // for ID_ADD and ID_REMOVE this function takes NULL as bus_name
2735   if (bus_name == NULL)
2736     {
2737       snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old != 0 ? old : new);
2738       const_ptr = tmp_str;
2739     }
2740   else
2741     const_ptr = bus_name;
2742
2743   if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2744     goto error;
2745
2746   _dbus_verbose ("%s\n", const_ptr);
2747
2748
2749   if ((old==0) && (new==0))
2750     {
2751       /* kdbus generates its own set of events that can not be passed to
2752        * client without translation. */
2753       const char *src = "org.freedesktop.DBus";
2754       const char *dst = "org.freedesktop.DBus";
2755
2756       if (type == KDBUS_ITEM_NAME_ADD || type == KDBUS_ITEM_ID_ADD)
2757         src = "";
2758       else if (type == KDBUS_ITEM_NAME_REMOVE || type == KDBUS_ITEM_ID_REMOVE)
2759         dst = "";
2760
2761       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &src))
2762         goto error;
2763       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &dst))
2764         goto error;
2765
2766       _dbus_verbose ("[NameOwnerChanged:%s, old=%lld, new=%lld\n", __func__, old, new);
2767     }
2768   else
2769     {
2770       // determine and append old_id
2771       if (old != 0)
2772       {
2773         snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old);
2774         const_ptr = tmp_str;
2775       }
2776       else
2777         const_ptr = "";
2778
2779       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2780         goto error;
2781
2782       _dbus_verbose ("%s\n", const_ptr);
2783       // determine and append new_id
2784       if (new != 0)
2785       {
2786         snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", new);
2787         const_ptr = tmp_str;
2788       }
2789       else
2790         const_ptr = "";
2791
2792       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2793         goto error;
2794
2795       _dbus_verbose ("%s\n", const_ptr);
2796     }
2797
2798   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
2799     goto error;
2800   dbus_message_set_serial (message, get_next_client_serial (transport));
2801
2802   if (!add_message_to_received (message, transport->base.connection))
2803     return -1;
2804
2805   return 0;
2806
2807 error:
2808   dbus_message_unref (message);
2809
2810   return -1;
2811 }
2812
2813 static void
2814 handle_item_timestamp (const struct kdbus_item *item)
2815 {
2816 #if KDBUS_MSG_DECODE_DEBUG == 1
2817   _dbus_verbose ("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
2818                 enum_MSG (item->type), item->size,
2819                 (unsigned long long)item->timestamp.realtime_ns,
2820                 (unsigned long long)item->timestamp.monotonic_ns);
2821 #endif
2822 }
2823
2824 static void
2825 handle_unexpected_item (const struct kdbus_item *item)
2826 {
2827   _dbus_assert_not_reached ("unexpected item from kdbus");
2828 }
2829
2830 static void
2831 handle_padding (const struct kdbus_msg *msg,
2832                  const struct kdbus_item *end_of_items)
2833 {
2834 #if KDBUS_MSG_DECODE_DEBUG == 1
2835   if ((char *)end_of_items - ((char *)msg + msg->size) >= 8)
2836     _dbus_verbose ("invalid padding at end of message\n");
2837 #endif
2838 }
2839
2840 #ifdef LIBDBUSPOLICY
2841 static dbus_bool_t
2842 load_dbus_header (DBusTransportKdbus *transport,
2843                   DBusHeader         *header,
2844                   const char         *message_data,
2845                   dbus_uint32_t       message_len)
2846 {
2847   DBusValidity validity = DBUS_VALID;
2848   DBusString message;
2849   dbus_uint32_t fields_array_len_unsigned;
2850   dbus_uint32_t body_len_unsigned;
2851   int i;
2852
2853   if (0 == message_len)
2854     return FALSE;
2855
2856   _dbus_string_init_const_len (&message, message_data, message_len);
2857   _dbus_gvariant_raw_get_lengths (&message,
2858                                   &fields_array_len_unsigned,
2859                                   &body_len_unsigned,
2860                                   &validity);
2861
2862   _dbus_string_init_const_len (&header->data,
2863                                message_data,
2864                                fields_array_len_unsigned + FIRST_GVARIANT_FIELD_OFFSET);
2865
2866   header->padding = 0;
2867   header->byte_order = message_data[0];
2868   header->protocol_version = DBUS_PROTOCOL_VERSION_GVARIANT;
2869   for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
2870     header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
2871
2872   return _dbus_header_load_gvariant (header, &validity);
2873 }
2874 #endif
2875
2876 static dbus_bool_t
2877 can_receive (DBusTransportKdbus     *transport,
2878              const struct kdbus_msg *msg,
2879              const char             *message_data,
2880              dbus_uint32_t           message_len)
2881 {
2882   dbus_bool_t result = TRUE;
2883
2884 #ifdef LIBDBUSPOLICY
2885   if (transport->policy)
2886   {
2887     DBusHeader header;
2888     dbus_bool_t got_header = FALSE;
2889     dbus_bool_t got_creds = FALSE;
2890     dbus_bool_t got_seclabel = FALSE;
2891
2892     if (KDBUS_PAYLOAD_DBUS == msg->payload_type)
2893       {
2894         const struct kdbus_item *item;
2895         uid_t sender_euid = -1;
2896         gid_t sender_egid = -1;
2897         const char *seclabel = NULL;
2898         DBusString names;
2899
2900         result = FALSE;
2901
2902         if (!_dbus_string_init (&names))
2903           {
2904             _dbus_verbose ("oom:_dbus_string_init");
2905             return FALSE;
2906           }
2907
2908         KDBUS_ITEM_FOREACH(item, msg, items)
2909           switch (item->type)
2910             {
2911               case KDBUS_ITEM_CREDS:
2912                 sender_euid = (uid_t) item->creds.euid;
2913                 sender_egid = (gid_t) item->creds.egid;
2914                 got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1);
2915                 break;
2916               case KDBUS_ITEM_SECLABEL:
2917                 seclabel = item->str;
2918                 got_seclabel = (seclabel != NULL);
2919                 break;
2920               case KDBUS_ITEM_OWNED_NAME:
2921                 {
2922                   DBusString name;
2923                   _dbus_string_init_const (&name, item->name.name);
2924                   if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))
2925                     {
2926                       if (_dbus_string_get_length (&names) != 0)
2927                         {
2928                           if (!_dbus_string_append_byte (&names, ' '))
2929                             {
2930                               _dbus_string_free (&names);
2931                               return FALSE;
2932                             }
2933                         }
2934
2935                       if (!_dbus_string_copy (&name,
2936                                          0,
2937                                          &names,
2938                                          _dbus_string_get_length (&names)))
2939                         {
2940                           _dbus_string_free (&names);
2941                           return FALSE;
2942                         }
2943                     }
2944                 }
2945                 break;
2946               default:
2947                 break; /* ignore all other items */
2948             }
2949
2950         if (NULL != message_data && message_len > 0)
2951           {
2952             if (load_dbus_header (transport, &header, message_data, message_len))
2953               got_header = TRUE;
2954           }
2955         if (got_header &&
2956             _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL &&
2957             _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_SIGNAL)
2958           {
2959             result = TRUE;
2960           }
2961         else if (got_header && got_creds && got_seclabel)
2962           {
2963             const char *destination = NULL;
2964             const char *path = NULL;
2965             const char *interface = NULL;
2966             const char *member = NULL;
2967             const char *error_name = NULL;
2968             dbus_uint64_t reply_cookie = 0;
2969             dbus_bool_t requested_reply = FALSE;
2970             int ret;
2971
2972             _dbus_header_get_field_basic (&header,
2973                                           DBUS_HEADER_FIELD_DESTINATION,
2974                                           DBUS_TYPE_STRING,
2975                                           &destination);
2976             if (!destination)
2977                destination = transport->my_DBus_unique_name;
2978
2979             _dbus_header_get_field_basic (&header,
2980                                           DBUS_HEADER_FIELD_PATH,
2981                                           DBUS_TYPE_STRING,
2982                                           &path);
2983
2984             _dbus_header_get_field_basic (&header,
2985                                           DBUS_HEADER_FIELD_INTERFACE,
2986                                           DBUS_TYPE_STRING,
2987                                           &interface);
2988
2989             _dbus_header_get_field_basic (&header,
2990                                           DBUS_HEADER_FIELD_MEMBER,
2991                                           DBUS_TYPE_STRING,
2992                                           &member);
2993
2994             _dbus_header_get_field_basic (&header,
2995                                           DBUS_HEADER_FIELD_ERROR_NAME,
2996                                           DBUS_TYPE_STRING,
2997                                           &error_name);
2998
2999             _dbus_header_get_field_basic (&header,
3000                                           DBUS_HEADER_FIELD_REPLY_SERIAL,
3001                                           DBUS_TYPE_UINT64,
3002                                           &reply_cookie);
3003
3004             requested_reply = !(_dbus_header_get_flag (&header,
3005                                                        DBUS_HEADER_FLAG_NO_REPLY_EXPECTED));
3006
3007             ret = dbuspolicy1_check_in (transport->policy,
3008                                         destination,
3009                                         _dbus_string_get_length (&names) > 0 ?
3010                                           _dbus_string_get_const_data (&names) :
3011                                           NULL,
3012                                         seclabel,
3013                                         sender_euid,
3014                                         sender_egid,
3015                                         path,
3016                                         interface,
3017                                         member,
3018                                         _dbus_header_get_message_type (&header),
3019                                         error_name,
3020                                         reply_cookie,
3021                                         requested_reply);
3022             result = (1 == ret);
3023           }
3024
3025         _dbus_string_free (&names);
3026       }
3027   }
3028 #endif
3029
3030   return result;
3031 }
3032
3033 static int
3034 kdbus_decode_dbus_message (const struct kdbus_msg *msg,
3035                            char                   *data,
3036                            DBusTransportKdbus     *kdbus_transport,
3037                            int                    *fds,
3038                            int                    *n_fds)
3039 {
3040   const struct kdbus_item *item;
3041   int ret_size = 0;
3042   char *buffer = data;
3043
3044   *n_fds = 0;
3045
3046   KDBUS_ITEM_FOREACH (item, msg, items)
3047     {
3048       if (item->size < KDBUS_ITEM_HEADER_SIZE)
3049         {
3050           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
3051           ret_size = -1;
3052           break;
3053         }
3054
3055       switch (item->type)
3056         {
3057           case KDBUS_ITEM_PAYLOAD_OFF:
3058             memcpy (data, (char *)msg+item->vec.offset, item->vec.size);
3059             data += item->vec.size;
3060             ret_size += item->vec.size;
3061
3062 #ifdef DBUS_ENABLE_VERBOSE_MODE
3063             if (-1 != debug)
3064               {
3065                 debug_c_str ("Message part arrived:", (char *)msg+item->vec.offset, item->vec.size);
3066               }
3067 #endif
3068
3069             _dbus_verbose ("  +%s (%llu bytes) off=%llu size=%llu\n",
3070                 enum_MSG (item->type), item->size,
3071                 (unsigned long long)item->vec.offset,
3072                 (unsigned long long)item->vec.size);
3073             break;
3074
3075           case KDBUS_ITEM_PAYLOAD_MEMFD:
3076             {
3077               char *buf;
3078               uint64_t size;
3079
3080               size = item->memfd.size;
3081               _dbus_verbose ("memfd.size : %llu\n", (unsigned long long)size);
3082
3083               buf = mmap (NULL, size, PROT_READ, MAP_PRIVATE, item->memfd.fd, 0);
3084               if (buf == MAP_FAILED)
3085                 {
3086                   _dbus_verbose ("mmap () fd=%i failed:%m", item->memfd.fd);
3087                   return -1;
3088                 }
3089
3090               memcpy (data, buf, size);
3091               data += size;
3092               ret_size += size;
3093
3094               munmap (buf, size);
3095               close (item->memfd.fd);
3096
3097               _dbus_verbose ("  +%s (%llu bytes) off=%llu size=%llu\n",
3098                   enum_MSG (item->type), item->size,
3099                   (unsigned long long)item->vec.offset,
3100                   (unsigned long long)item->vec.size);
3101             }
3102             break;
3103
3104           case KDBUS_ITEM_FDS:
3105             {
3106               int i;
3107
3108               *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof (int);
3109               memcpy (fds, item->fds, *n_fds * sizeof (int));
3110               for (i = 0; i < *n_fds; i++)
3111                 _dbus_fd_set_close_on_exec (fds[i]);
3112             }
3113             break;
3114
3115           case KDBUS_ITEM_CREDS:
3116 #if KDBUS_MSG_DECODE_DEBUG == 1
3117             _dbus_verbose ("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
3118                           enum_MSG (item->type), item->size,
3119                           item->creds.uid, item->creds.gid,
3120                           item->creds.pid, item->creds.tid,
3121                           item->creds.starttime);
3122 #endif
3123             break;
3124
3125           case KDBUS_ITEM_PID_COMM:
3126           case KDBUS_ITEM_TID_COMM:
3127           case KDBUS_ITEM_EXE:
3128           case KDBUS_ITEM_CGROUP:
3129           case KDBUS_ITEM_SECLABEL:
3130           case KDBUS_ITEM_DST_NAME:
3131 #if KDBUS_MSG_DECODE_DEBUG == 1
3132             _dbus_verbose ("  +%s (%llu bytes) '%s' (%zu)\n",
3133                           enum_MSG (item->type), item->size, item->str, strlen (item->str));
3134 #endif
3135             break;
3136
3137           case KDBUS_ITEM_CMDLINE:
3138           case KDBUS_ITEM_NAME:
3139 #if KDBUS_MSG_DECODE_DEBUG == 1
3140             {
3141               __u64 size = item->size - KDBUS_ITEM_HEADER_SIZE;
3142               const char *str = item->str;
3143               int count = 0;
3144
3145               _dbus_verbose ("  +%s (%llu bytes) ", enum_MSG (item->type), item->size);
3146               while (size)
3147               {
3148                 _dbus_verbose ("'%s' ", str);
3149                 size -= strlen (str) + 1;
3150                 str += strlen (str) + 1;
3151                 count++;
3152               }
3153
3154               _dbus_verbose ("(%d string%s)\n", count, (count == 1) ? "" : "s");
3155             }
3156 #endif
3157             break;
3158
3159           case KDBUS_ITEM_AUDIT:
3160 #if KDBUS_MSG_DECODE_DEBUG == 1
3161             _dbus_verbose ("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
3162                           enum_MSG (item->type), item->size,
3163                           (unsigned long long)item->data64[0],
3164                           (unsigned long long)item->data64[1]);
3165 #endif
3166             break;
3167
3168           case KDBUS_ITEM_CAPS:
3169 #if KDBUS_MSG_DECODE_DEBUG == 1
3170             {
3171               int n;
3172               const uint32_t *cap;
3173               int i;
3174
3175               _dbus_verbose ("  +%s (%llu bytes) len=%llu bytes)\n",
3176                   enum_MSG (item->type), item->size,
3177                   (unsigned long long)item->size - KDBUS_ITEM_HEADER_SIZE);
3178
3179               cap = item->data32;
3180               n = (item->size - KDBUS_ITEM_HEADER_SIZE) / 4 / sizeof (uint32_t);
3181
3182               _dbus_verbose ("    CapInh=");
3183               for (i = 0; i < n; i++)
3184                 _dbus_verbose ("%08x", cap[(0 * n) + (n - i - 1)]);
3185
3186               _dbus_verbose (" CapPrm=");
3187               for (i = 0; i < n; i++)
3188                 _dbus_verbose ("%08x", cap[(1 * n) + (n - i - 1)]);
3189
3190               _dbus_verbose (" CapEff=");
3191               for (i = 0; i < n; i++)
3192                 _dbus_verbose ("%08x", cap[(2 * n) + (n - i - 1)]);
3193
3194               _dbus_verbose (" CapInh=");
3195               for (i = 0; i < n; i++)
3196                 _dbus_verbose ("%08x", cap[(3 * n) + (n - i - 1)]);
3197               _dbus_verbose ("\n");
3198             }
3199 #endif
3200             break;
3201
3202           case KDBUS_ITEM_TIMESTAMP:
3203             handle_item_timestamp (item);
3204             break;
3205
3206           case KDBUS_ITEM_BLOOM_FILTER:
3207             /* no handling */
3208             break;
3209
3210           default:
3211             handle_unexpected_item (item);
3212             break;
3213         }
3214     }
3215
3216   handle_padding (msg, item);
3217
3218   if (!can_receive (kdbus_transport, msg, buffer, ret_size))
3219     return 0;   /* ignore message if not allowed */
3220
3221   return ret_size;
3222 }
3223
3224 static int
3225 kdbus_decode_kernel_message (const struct kdbus_msg *msg,
3226                              DBusTransportKdbus     *kdbus_transport)
3227 {
3228   const struct kdbus_item *item;
3229   int ret_size = 0;
3230
3231   KDBUS_ITEM_FOREACH (item, msg, items)
3232     {
3233       if (item->size < KDBUS_ITEM_HEADER_SIZE)
3234         {
3235           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
3236           ret_size = -1;
3237           break;
3238         }
3239
3240       switch (item->type)
3241         {
3242           case KDBUS_ITEM_REPLY_TIMEOUT:
3243           case KDBUS_ITEM_REPLY_DEAD:
3244             _dbus_verbose ("  +%s (%llu bytes) cookie=%llu\n",
3245                           enum_MSG (item->type), item->size, msg->cookie_reply);
3246             break;
3247
3248           case KDBUS_ITEM_NAME_ADD:
3249           case KDBUS_ITEM_NAME_REMOVE:
3250           case KDBUS_ITEM_NAME_CHANGE:
3251             {
3252               int local_ret;
3253
3254               _dbus_verbose ("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n",
3255                              enum_MSG (item->type), (unsigned long long) item->size,
3256                              item->name_change.name, item->name_change.old_id.id,
3257                              item->name_change.new_id.id, item->name_change.old_id.flags,
3258                              item->name_change.new_id.flags);
3259
3260               if (item->name_change.new_id.id == _kdbus_get_id (kdbus_transport->kdbus))
3261                 ret_size = generate_NameSignal ("NameAcquired", item->name_change.name, kdbus_transport);
3262               else if (item->name_change.old_id.id == _kdbus_get_id (kdbus_transport->kdbus))
3263                 ret_size = generate_NameSignal ("NameLost", item->name_change.name, kdbus_transport);
3264
3265               if (ret_size == -1)
3266                 goto out;
3267
3268               if (item->name_change.new_id.flags & KDBUS_NAME_ACTIVATOR)
3269                 local_ret = kdbus_handle_name_owner_changed (item->type,
3270                                                              item->name_change.name,
3271                                                              item->name_change.old_id.id, 0,
3272                                                              kdbus_transport);
3273               else if (item->name_change.old_id.flags & KDBUS_NAME_ACTIVATOR)
3274                 local_ret = kdbus_handle_name_owner_changed (item->type,
3275                                                              item->name_change.name, 0,
3276                                                              item->name_change.new_id.id,
3277                                                              kdbus_transport);
3278               else
3279                 local_ret = kdbus_handle_name_owner_changed (item->type,
3280                                                              item->name_change.name,
3281                                                              item->name_change.old_id.id,
3282                                                              item->name_change.new_id.id,
3283                                                              kdbus_transport);
3284               if (local_ret == -1)
3285                 goto out;
3286
3287               ret_size += local_ret;
3288             }
3289             break;
3290
3291           case KDBUS_ITEM_ID_ADD:
3292           case KDBUS_ITEM_ID_REMOVE:
3293             _dbus_verbose ("  +%s (%llu bytes) id=%llu flags=%llu\n",
3294                           enum_MSG (item->type), (unsigned long long) item->size,
3295                           (unsigned long long) item->id_change.id,
3296                           (unsigned long long) item->id_change.flags);
3297
3298             if (item->id_change.flags & KDBUS_HELLO_ACTIVATOR)
3299               ret_size = kdbus_handle_name_owner_changed (item->type, NULL, 0, 0,
3300                                                           kdbus_transport);
3301             else
3302               ret_size = kdbus_handle_name_owner_changed (item->type, NULL,
3303                                                           item->type == KDBUS_ITEM_ID_ADD ? 0 : item->id_change.id,
3304                                                           item->type == KDBUS_ITEM_ID_ADD ? item->id_change.id : 0,
3305                                                           kdbus_transport);
3306
3307             if (ret_size == -1)
3308               goto out;
3309             break;
3310
3311           case KDBUS_ITEM_TIMESTAMP:
3312             handle_item_timestamp (item);
3313             break;
3314
3315           default:
3316             handle_unexpected_item (item);
3317             break;
3318         }
3319     }
3320
3321   handle_padding (msg, item);
3322
3323 out:
3324   return ret_size;
3325 }
3326
3327 /**
3328  * Decodes kdbus message in order to extract DBus message and puts it into received data buffer
3329  * and file descriptor's buffer. Also captures kdbus error messages and kdbus kernel broadcasts
3330  * and converts all of them into appropriate DBus messages.
3331  *
3332  * @param msg kdbus message
3333  * @param data place to copy DBus message to
3334  * @param kdbus_transport transport
3335  * @param fds place to store file descriptors received
3336  * @param n_fds place to store quantity of file descriptors received
3337  * @return number of DBus message's bytes received or -1 on error
3338  */
3339 static int
3340 kdbus_decode_msg (const struct kdbus_msg *msg,
3341                   char                   *data,
3342                   DBusTransportKdbus     *kdbus_transport,
3343                   int                    *fds,
3344                   int                    *n_fds)
3345 {
3346   int ret_size = 0;
3347
3348 #if KDBUS_MSG_DECODE_DEBUG == 1
3349   _dbus_verbose ("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
3350                 enum_PAYLOAD (msg->payload_type),
3351                 (unsigned long long) msg->size,
3352                 (unsigned long long) msg->flags,
3353                 msg_id (msg->src_id),
3354                 msg_id (msg->dst_id),
3355                 (unsigned long long) msg->cookie,
3356                 (unsigned long long) msg->timeout_ns);
3357 #endif
3358
3359   switch (msg->payload_type)
3360     {
3361       case KDBUS_PAYLOAD_DBUS:
3362         ret_size = kdbus_decode_dbus_message (msg, data, kdbus_transport, fds, n_fds);
3363         break;
3364       case KDBUS_PAYLOAD_KERNEL:
3365         ret_size = kdbus_decode_kernel_message (msg, kdbus_transport);
3366         break;
3367       default:
3368         _dbus_assert_not_reached ("unexpected payload type from kdbus");
3369         break;
3370     }
3371
3372   return ret_size;
3373 }
3374
3375 /**
3376  * Reads message from kdbus and puts it into DBus buffers
3377  *
3378  * @param kdbus_transport transport
3379  * @param buffer place to copy received message to
3380  * @param fds place to store file descriptors received with the message
3381  * @param n_fds place to store quantity of file descriptors received
3382  * @return size of received message on success, -1 on error
3383  */
3384 static int
3385 kdbus_read_message (DBusTransportKdbus *kdbus_transport,
3386                     DBusString         *buffer,
3387                     int                *fds,
3388                     int                *n_fds)
3389 {
3390   int ret_size, buf_size;
3391   struct kdbus_msg *msg;
3392   char *data;
3393   int start;
3394   dbus_uint64_t flags = 0;
3395   int ret;
3396
3397   start = _dbus_string_get_length (buffer);
3398
3399   if (kdbus_transport->activator != NULL)
3400     flags |= KDBUS_RECV_PEEK;
3401
3402   ret = _kdbus_recv (kdbus_transport->kdbus, flags, 0, &msg);
3403
3404   if (0 != ret)
3405     {
3406       _dbus_verbose ("kdbus error receiving message: %d (%s)\n", ret, _dbus_strerror (ret));
3407       return -1;
3408     }
3409
3410   buf_size = kdbus_message_size (msg, n_fds);
3411   if (buf_size == -1)
3412     {
3413       _dbus_verbose ("kdbus error - too short message: %d (%m)\n", errno);
3414       return -1;
3415     }
3416
3417   /* What is the maximum size of the locally generated message?
3418      I just assume 2048 bytes */
3419   buf_size = MAX (buf_size, 2048);
3420
3421   if (!_dbus_string_lengthen (buffer, buf_size))
3422     {
3423       errno = ENOMEM;
3424       return -1;
3425     }
3426   data = _dbus_string_get_data_len (buffer, start, buf_size);
3427
3428   ret_size = kdbus_decode_msg (msg, data, kdbus_transport, fds, n_fds);
3429
3430   if (ret_size == -1) /* error */
3431     _dbus_string_set_length (buffer, start);
3432   else if (ret_size >= 0 && buf_size != ret_size) /* case of locally generated message */
3433     _dbus_string_set_length (buffer, start + ret_size);
3434
3435   if (ret_size >= 0)
3436     _dbus_message_loader_set_unique_sender_id (kdbus_transport->base.loader, msg->src_id);
3437
3438   if (kdbus_transport->activator != NULL)
3439     return ret_size;
3440
3441   ret = _kdbus_free_mem (kdbus_transport->kdbus, msg);
3442   if (0 != ret)
3443   {
3444     _dbus_verbose ("kdbus error freeing message: %d (%s)\n", ret, _dbus_strerror (ret));
3445     return -1;
3446   }
3447
3448   return ret_size;
3449 }
3450
3451 #ifdef ENABLE_KDBUS_SYNC_CALLS
3452 static DBusMessage *
3453 kdbus_send_sync_call (DBusTransportKdbus  *transport,
3454                       DBusMessage         *message)
3455 {
3456   DBusMessage *reply = NULL;
3457   DBusError error;
3458   const char *destination;
3459
3460   dbus_message_lock (message);
3461
3462   destination = dbus_message_get_destination (message);
3463   if (destination)
3464     {
3465       int ret;
3466
3467       ret = capture_org_freedesktop_DBus ((DBusTransportKdbus*)transport, destination, message, &reply);
3468       if (ret < 0)
3469         goto error;
3470       else if (ret == 0)
3471         goto out;
3472     }
3473
3474   kdbus_write_msg_internal (transport, message, destination, &reply, TRUE);
3475   if (reply == NULL)
3476     goto error;
3477   else
3478     goto out;
3479
3480 error:
3481
3482   dbus_error_init (&error);
3483
3484   dbus_set_error (&error, DBUS_ERROR_FAILED,
3485                   "Something went wrong");
3486
3487   reply = reply_with_error ((char*)error.name,
3488                             NULL,
3489                             error.message,
3490                             message);
3491
3492   dbus_error_free (&error);
3493
3494 out:
3495
3496   _dbus_assert (reply != NULL);
3497   dbus_message_lock (reply);
3498
3499   return reply;
3500 }
3501 #endif
3502
3503 /**
3504  * Copy-paste from socket transport. Only renames done.
3505  */
3506 static void
3507 free_watches (DBusTransportKdbus *kdbus_transport)
3508 {
3509   DBusConnection *connection = kdbus_transport->base.connection;
3510   _dbus_verbose ("start\n");
3511
3512   if (kdbus_transport->read_watch)
3513     {
3514       if (connection)
3515         _dbus_connection_remove_watch_unlocked (connection,
3516                                                 kdbus_transport->read_watch);
3517       _dbus_watch_invalidate (kdbus_transport->read_watch);
3518       _dbus_watch_unref (kdbus_transport->read_watch);
3519       kdbus_transport->read_watch = NULL;
3520     }
3521
3522   if (kdbus_transport->write_watch)
3523     {
3524       if (connection)
3525         _dbus_connection_remove_watch_unlocked (connection,
3526                                                 kdbus_transport->write_watch);
3527       _dbus_watch_invalidate (kdbus_transport->write_watch);
3528       _dbus_watch_unref (kdbus_transport->write_watch);
3529       kdbus_transport->write_watch = NULL;
3530     }
3531
3532   _dbus_verbose ("end\n");
3533 }
3534
3535 static void
3536 free_policies (DBusTransportKdbus *transport)
3537 {
3538 #ifdef LIBDBUSPOLICY
3539   if (NULL != transport->policy)
3540     dbuspolicy1_free (transport->policy);
3541 #endif
3542 }
3543
3544 /**
3545  * Copy-paste from socket transport. Only done needed renames and removed
3546  * lines related to encoded messages.
3547  */
3548 static void
3549 transport_finalize (DBusTransport *transport)
3550 {
3551   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus *)transport;
3552   _dbus_verbose ("\n");
3553
3554   free_watches (kdbus_transport);
3555
3556   _dbus_transport_finalize_base (transport);
3557
3558   _dbus_assert (kdbus_transport->read_watch == NULL);
3559   _dbus_assert (kdbus_transport->write_watch == NULL);
3560
3561   free_matchmaker (kdbus_transport->matchmaker);
3562
3563   dbus_free (kdbus_transport->activator);
3564
3565   free_policies ( kdbus_transport );
3566
3567   _kdbus_free (kdbus_transport->kdbus);
3568   free (kdbus_transport->my_DBus_unique_name);
3569
3570   dbus_free (transport);
3571 }
3572
3573 /**
3574  * Copy-paste from socket transport. Removed code related to authentication,
3575  * socket_transport replaced by kdbus_transport.
3576  */
3577 static void
3578 check_write_watch (DBusTransportKdbus *kdbus_transport)
3579 {
3580   dbus_bool_t needed;
3581   DBusTransport *transport = &kdbus_transport->base;
3582
3583   if (transport->connection == NULL)
3584     return;
3585
3586   if (transport->disconnected)
3587     {
3588       _dbus_assert (kdbus_transport->write_watch == NULL);
3589       return;
3590     }
3591
3592   _dbus_transport_ref (transport);
3593
3594   needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
3595
3596   _dbus_verbose ("check_write_watch (): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
3597                  needed, transport->connection, kdbus_transport->write_watch,
3598                  _kdbus_get_fd (kdbus_transport->kdbus),
3599                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3600
3601   _dbus_connection_toggle_watch_unlocked (transport->connection,
3602                                           kdbus_transport->write_watch,
3603                                           needed);
3604
3605   _dbus_transport_unref (transport);
3606 }
3607
3608 /**
3609  * Copy-paste from socket transport. Removed code related to authentication,
3610  * socket_transport replaced by kdbus_transport.
3611  */
3612 static void
3613 check_read_watch (DBusTransportKdbus *kdbus_transport)
3614 {
3615   dbus_bool_t need_read_watch;
3616   DBusTransport *transport = &kdbus_transport->base;
3617
3618   _dbus_verbose ("fd = %d\n",_kdbus_get_fd (kdbus_transport->kdbus));
3619
3620   if (transport->connection == NULL)
3621     return;
3622
3623   if (transport->disconnected)
3624     {
3625       _dbus_assert (kdbus_transport->read_watch == NULL);
3626       return;
3627     }
3628
3629   _dbus_transport_ref (transport);
3630
3631    need_read_watch =
3632       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
3633       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
3634
3635   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
3636
3637   _dbus_connection_toggle_watch_unlocked (transport->connection,
3638                                           kdbus_transport->read_watch,
3639                                           need_read_watch);
3640
3641   _dbus_transport_unref (transport);
3642 }
3643
3644 /**
3645  * Copy-paste from socket transport.
3646  */
3647 static void
3648 do_io_error (DBusTransport *transport)
3649 {
3650   _dbus_transport_ref (transport);
3651   _dbus_transport_disconnect (transport);
3652   _dbus_transport_unref (transport);
3653 }
3654
3655 /**
3656  *  Based on do_writing from socket transport.
3657  *  Removed authentication code and code related to encoded messages
3658  *  and adapted to kdbus transport.
3659  *  In socket transport returns false on out-of-memory. Here this won't happen,
3660  *  so it always returns TRUE.
3661  */
3662 static dbus_bool_t
3663 do_writing (DBusTransport *transport)
3664 {
3665   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3666   int total = 0;
3667   dbus_bool_t oom = FALSE;
3668
3669   if (transport->disconnected)
3670     {
3671       _dbus_verbose ("Not connected, not writing anything\n");
3672       return TRUE;
3673     }
3674
3675   _dbus_verbose ("do_writing (), have_messages = %d, fd = %d\n",
3676                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
3677                  _kdbus_get_fd (kdbus_transport->kdbus));
3678
3679   while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
3680     {
3681       int bytes_written;
3682       DBusMessage *message;
3683       DBusMessage *reply;
3684       const DBusString *header;
3685       const DBusString *body;
3686       const char* pDestination;
3687
3688       if (total > kdbus_transport->max_bytes_written_per_iteration)
3689         {
3690           _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
3691                          total, kdbus_transport->max_bytes_written_per_iteration);
3692           goto out;
3693         }
3694
3695       reply = NULL;
3696       message = _dbus_connection_get_message_to_send (transport->connection);
3697       _dbus_assert (message != NULL);
3698       pDestination = dbus_message_get_destination (message);
3699
3700       if (pDestination)
3701         {
3702           int ret;
3703
3704           ret = capture_org_freedesktop_DBus ((DBusTransportKdbus*)transport, pDestination, message, &reply);
3705           if (ret < 0)  //error
3706             {
3707               bytes_written = -1;
3708               goto written;
3709             }
3710           else if (ret == 0)  //message captured and handled correctly
3711             {
3712               /* puts locally generated reply into received messages queue */
3713               if (!add_message_to_received (reply, kdbus_transport->base.connection))
3714                 {
3715                   bytes_written = -1;
3716                   goto written;
3717                 }
3718
3719               _dbus_message_get_network_data (message, &header, &body);
3720               bytes_written = _dbus_string_get_length (header) + _dbus_string_get_length (body);
3721               goto written;
3722             }
3723           //else send as regular message
3724         }
3725
3726       bytes_written = kdbus_write_msg (kdbus_transport, message, pDestination);
3727
3728       written:
3729       if (bytes_written < 0)
3730         {
3731           if (errno == ENOMEM)
3732             {
3733               oom = TRUE;
3734               goto out;
3735             }
3736
3737           /* EINTR already handled for us */
3738
3739           /* For some discussion of why we also ignore EPIPE here, see
3740            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
3741            */
3742
3743           if (_dbus_get_is_errno_eagain_or_ewouldblock (errno) || _dbus_get_is_errno_epipe (errno))
3744             goto out;
3745           else
3746             {
3747               _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
3748               do_io_error (transport);
3749               goto out;
3750             }
3751         }
3752       else
3753         {
3754 #if defined (DBUS_ENABLE_VERBOSE_MODE) || !defined (DBUS_DISABLE_ASSERT)
3755           int total_bytes_to_write;
3756
3757           _dbus_message_get_network_data (message, &header, &body);
3758           total_bytes_to_write = _dbus_string_get_length (header)
3759                                    + _dbus_string_get_length (body);
3760           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
3761                          total_bytes_to_write);
3762
3763           _dbus_assert (bytes_written == total_bytes_to_write);
3764 #endif
3765           total += bytes_written;
3766
3767           _dbus_connection_message_sent_unlocked (transport->connection,
3768                   message);
3769         }
3770     }
3771
3772 out:
3773   if (oom)
3774     return FALSE;
3775   else
3776     return TRUE;
3777 }
3778
3779 /**
3780  *  Based on do_reading from socket transport.
3781  *  Removed authentication code and code related to encoded messages
3782  *  and adapted to kdbus transport.
3783  *  returns false on out-of-memory
3784  */
3785 static dbus_bool_t
3786 do_reading (DBusTransport *transport)
3787 {
3788   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3789   DBusString *buffer;
3790   int bytes_read;
3791   dbus_bool_t oom = FALSE;
3792   int *fds, n_fds;
3793   int total = 0;
3794
3795   _dbus_verbose ("fd = %d\n", _kdbus_get_fd (kdbus_transport->kdbus));
3796
3797  again:
3798
3799   /* See if we've exceeded max messages and need to disable reading */
3800   if (kdbus_transport->activator == NULL)
3801     check_read_watch (kdbus_transport);
3802
3803   if (total > kdbus_transport->max_bytes_read_per_iteration)
3804     {
3805       _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
3806                      total, kdbus_transport->max_bytes_read_per_iteration);
3807       goto out;
3808     }
3809
3810   _dbus_assert (kdbus_transport->read_watch != NULL ||
3811                 transport->disconnected);
3812
3813   if (transport->disconnected)
3814     goto out;
3815
3816   if (!dbus_watch_get_enabled (kdbus_transport->read_watch))
3817     return TRUE;
3818
3819   if (!_dbus_message_loader_get_unix_fds (transport->loader, &fds, &n_fds))
3820   {
3821       _dbus_verbose ("Out of memory reading file descriptors\n");
3822       oom = TRUE;
3823       goto out;
3824   }
3825   _dbus_message_loader_get_buffer (transport->loader, &buffer, NULL, NULL);
3826
3827   bytes_read = kdbus_read_message (kdbus_transport, buffer, fds, &n_fds);
3828
3829   if (bytes_read >= 0 && n_fds > 0)
3830     _dbus_verbose ("Read %i unix fds\n", n_fds);
3831
3832   _dbus_message_loader_return_buffer (transport->loader,
3833                                       buffer);
3834   _dbus_message_loader_return_unix_fds (transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
3835
3836   if (bytes_read < 0)
3837     {
3838       /* EINTR already handled for us */
3839
3840       if (_dbus_get_is_errno_enomem (errno))
3841         {
3842           _dbus_verbose ("Out of memory in read()/do_reading()\n");
3843           oom = TRUE;
3844           goto out;
3845         }
3846       else if (_dbus_get_is_errno_eagain_or_ewouldblock (errno))
3847         goto out;
3848       else
3849         {
3850           _dbus_verbose ("Error reading from remote app: %s\n",
3851                          _dbus_strerror_from_errno ());
3852           do_io_error (transport);
3853           goto out;
3854         }
3855     }
3856   else if (bytes_read > 0)
3857     {
3858       _dbus_verbose (" read %d bytes\n", bytes_read);
3859
3860       total += bytes_read;
3861
3862       if (!_dbus_transport_queue_messages (transport))
3863         {
3864           oom = TRUE;
3865           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
3866           goto out;
3867         }
3868
3869       /* Try reading more data until we get EAGAIN and return, or
3870        * exceed max bytes per iteration.  If in blocking mode of
3871        * course we'll block instead of returning.
3872        */
3873       goto again;
3874     }
3875   /* 0 == bytes_read is for kernel and ignored messages */
3876
3877  out:
3878   if (oom)
3879     return FALSE;
3880   return TRUE;
3881 }
3882
3883 /**
3884  * Copy-paste from socket transport, with socket replaced by kdbus.
3885  */
3886 static dbus_bool_t
3887 unix_error_with_read_to_come (DBusTransport *itransport,
3888                               DBusWatch     *watch,
3889                               unsigned int   flags)
3890 {
3891    DBusTransportKdbus *transport = (DBusTransportKdbus *) itransport;
3892
3893    if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
3894       return FALSE;
3895
3896   /* If we have a read watch enabled ...
3897      we -might have data incoming ... => handle the HANGUP there */
3898    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
3899       return FALSE;
3900
3901    return TRUE;
3902 }
3903
3904 /**
3905  *  Copy-paste from socket transport. Removed authentication related code
3906  *  and renamed socket_transport to kdbus_transport.
3907  */
3908 static dbus_bool_t
3909 kdbus_handle_watch (DBusTransport *transport,
3910                     DBusWatch     *watch,
3911                     unsigned int   flags)
3912 {
3913   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3914
3915   _dbus_assert (watch == kdbus_transport->read_watch ||
3916                 watch == kdbus_transport->write_watch);
3917   _dbus_assert (watch != NULL);
3918
3919   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
3920    * still be in the buffer and do_reading may need several iteration to read
3921    * it all (because of its max_bytes_read_per_iteration limit).
3922    */
3923   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
3924     {
3925       _dbus_verbose ("Hang up or error on watch\n");
3926       _dbus_transport_disconnect (transport);
3927       return TRUE;
3928     }
3929
3930   if (watch == kdbus_transport->read_watch &&
3931       (flags & DBUS_WATCH_READABLE))
3932     {
3933       _dbus_verbose ("handling read watch %p flags = %x\n",
3934                      watch, flags);
3935
3936       if (!do_reading (transport))
3937         {
3938           _dbus_verbose ("no memory to read\n");
3939           return FALSE;
3940         }
3941     }
3942   else if (watch == kdbus_transport->write_watch &&
3943           (flags & DBUS_WATCH_WRITABLE))
3944     {
3945       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
3946                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3947
3948       if (!do_writing (transport))
3949         {
3950           _dbus_verbose ("no memory to write\n");
3951           return FALSE;
3952         }
3953
3954       /* See if we still need the write watch */
3955       check_write_watch (kdbus_transport);
3956     }
3957
3958   return TRUE;
3959 }
3960
3961 /**
3962  * Copy-paste from socket transport, but socket_transport renamed to kdbus_transport
3963  * and _dbus_close_socket replaced with close ().
3964  */
3965 static void
3966 kdbus_disconnect (DBusTransport *transport)
3967 {
3968   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3969
3970   _dbus_verbose ("\n");
3971
3972   free_watches (kdbus_transport);
3973
3974   _kdbus_close (kdbus_transport->kdbus);
3975 }
3976
3977 /**
3978  *  Copy-paste from socket transport. Renamed socket_transport to
3979  *  kdbus_transport and added setting authenticated to TRUE, because
3980  *  we do not perform authentication in kdbus, so we have mark is as already done
3981  *  to make everything work.
3982  */
3983 static dbus_bool_t
3984 kdbus_connection_set (DBusTransport *transport)
3985 {
3986   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3987
3988   _dbus_watch_set_handler (kdbus_transport->write_watch,
3989                            _dbus_connection_handle_watch,
3990                            transport->connection, NULL);
3991
3992   _dbus_watch_set_handler (kdbus_transport->read_watch,
3993                            _dbus_connection_handle_watch,
3994                            transport->connection, NULL);
3995
3996   if (!_dbus_connection_add_watch_unlocked (transport->connection,
3997                                             kdbus_transport->write_watch))
3998     return FALSE;
3999
4000   if (!_dbus_connection_add_watch_unlocked (transport->connection,
4001                                             kdbus_transport->read_watch))
4002     {
4003       _dbus_connection_remove_watch_unlocked (transport->connection,
4004                                               kdbus_transport->write_watch);
4005       return FALSE;
4006     }
4007
4008   check_read_watch (kdbus_transport);
4009   check_write_watch (kdbus_transport);
4010
4011   return TRUE;
4012 }
4013
4014 /**
4015  *  Copy-paste from socket_transport.
4016  *  Socket_transport renamed to kdbus_transport
4017  *
4018  *   Original dbus copy-pasted @todo comment below.
4019  * @todo We need to have a way to wake up the select sleep if
4020  * a new iteration request comes in with a flag (read/write) that
4021  * we're not currently serving. Otherwise a call that just reads
4022  * could block a write call forever (if there are no incoming
4023  * messages).
4024  */
4025 static void
4026 kdbus_do_iteration (DBusTransport *transport,
4027                    unsigned int   flags,
4028                    int            timeout_milliseconds)
4029 {
4030   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
4031   DBusPollFD poll_fd;
4032   int poll_res;
4033   int poll_timeout;
4034
4035   _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
4036                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
4037                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
4038                  timeout_milliseconds,
4039                  kdbus_transport->read_watch,
4040                  kdbus_transport->write_watch,
4041                  _kdbus_get_fd (kdbus_transport->kdbus));
4042
4043    poll_fd.fd = _kdbus_get_fd (kdbus_transport->kdbus);
4044    poll_fd.events = 0;
4045
4046    /*
4047     * TODO test this.
4048     * This fix is for reply_with_error function.
4049     * When timeout is set to -1 in client application,
4050     * error messages are inserted directly to incoming queue and
4051     * application hangs on dbus_poll.
4052     *
4053     * This causes a busy loop in _dbus_connection_block_pending_call()
4054     * There is no case of waiting for the locally-generated error reply
4055
4056    if (_dbus_connection_get_n_incoming (transport->connection) > 0)
4057    {
4058      timeout_milliseconds = 0;
4059    }
4060     */
4061
4062    /* This is kind of a hack; if we have stuff to write, then try
4063     * to avoid the poll. This is probably about a 5% speedup on an
4064     * echo client/server.
4065     *
4066     * If both reading and writing were requested, we want to avoid this
4067     * since it could have funky effects:
4068     *   - both ends spinning waiting for the other one to read
4069     *     data so they can finish writing
4070     *   - prioritizing all writing ahead of reading
4071     */
4072    if ((flags & DBUS_ITERATION_DO_WRITING) &&
4073        !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
4074        !transport->disconnected &&
4075        _dbus_connection_has_messages_to_send_unlocked (transport->connection))
4076      {
4077        do_writing (transport);
4078
4079        if (transport->disconnected ||
4080            !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
4081          goto out;
4082      }
4083
4084    /* If we get here, we decided to do the poll() after all */
4085    _dbus_assert (kdbus_transport->read_watch);
4086    if (flags & DBUS_ITERATION_DO_READING)
4087      poll_fd.events |= _DBUS_POLLIN;
4088
4089    _dbus_assert (kdbus_transport->write_watch);
4090    if (flags & DBUS_ITERATION_DO_WRITING)
4091      poll_fd.events |= _DBUS_POLLOUT;
4092
4093    if (poll_fd.events)
4094    {
4095       if ( (flags & DBUS_ITERATION_BLOCK) && !(flags & DBUS_ITERATION_DO_WRITING))
4096         poll_timeout = timeout_milliseconds;
4097       else
4098         poll_timeout = 0;
4099
4100       /* For blocking selects we drop the connection lock here
4101        * to avoid blocking out connection access during a potentially
4102        * indefinite blocking call. The io path is still protected
4103        * by the io_path_cond condvar, so we won't reenter this.
4104        */
4105       if (flags & DBUS_ITERATION_BLOCK)
4106       {
4107          _dbus_verbose ("unlock pre poll\n");
4108          _dbus_connection_unlock (transport->connection);
4109       }
4110
4111     again:
4112       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
4113
4114       if (poll_res < 0 && _dbus_get_is_errno_eintr (errno))
4115         goto again;
4116
4117       if (flags & DBUS_ITERATION_BLOCK)
4118       {
4119          _dbus_verbose ("lock post poll\n");
4120          _dbus_connection_lock (transport->connection);
4121       }
4122
4123       if (poll_res >= 0)
4124       {
4125          if (poll_res == 0)
4126             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
4127                                   * valgrind flags it as an error. though it probably
4128                                   * is guaranteed on linux at least.
4129                                   */
4130
4131          if (poll_fd.revents & _DBUS_POLLERR)
4132             do_io_error (transport);
4133          else
4134          {
4135             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
4136
4137             _dbus_verbose ("in iteration, need_read=%d\n",
4138                              need_read);
4139
4140             if (need_read && (flags & DBUS_ITERATION_DO_READING))
4141                do_reading (transport);
4142             /* We always be able to write to kdbus */
4143             if (flags & DBUS_ITERATION_DO_WRITING)
4144                do_writing (transport);
4145          }
4146       }
4147       else
4148          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
4149    }
4150
4151  out:
4152   /* We need to install the write watch only if we did not
4153    * successfully write everything. Note we need to be careful that we
4154    * don't call check_write_watch *before* do_writing, since it's
4155    * inefficient to add the write watch, and we can avoid it most of
4156    * the time since we can write immediately.
4157    *
4158    * However, we MUST always call check_write_watch(); DBusConnection code
4159    * relies on the fact that running an iteration will notice that
4160    * messages are pending.
4161    */
4162    check_write_watch (kdbus_transport);
4163
4164    _dbus_verbose (" ... leaving do_iteration()\n");
4165 }
4166
4167 /**
4168  * Copy-paste from socket transport.
4169  */
4170 static void
4171 kdbus_live_messages_changed (DBusTransport *transport)
4172 {
4173   /* See if we should look for incoming messages again */
4174   check_read_watch ((DBusTransportKdbus *)transport);
4175 }
4176
4177 /**
4178  * Gets file descriptor of the kdbus bus.
4179  * @param transport transport
4180  * @param fd_p place to write fd to
4181  * @returns always TRUE
4182  */
4183 static dbus_bool_t
4184 kdbus_get_kdbus_fd (DBusTransport *transport,
4185                     DBusSocket    *fd_p)
4186 {
4187   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
4188
4189   fd_p->fd = _kdbus_get_fd (kdbus_transport->kdbus);
4190
4191   return TRUE;
4192 }
4193
4194 static const DBusTransportVTable kdbus_vtable = {
4195   transport_finalize,
4196   kdbus_handle_watch,
4197   kdbus_disconnect,
4198   kdbus_connection_set,
4199   kdbus_do_iteration,
4200   kdbus_live_messages_changed,
4201   kdbus_get_kdbus_fd
4202 };
4203
4204 typedef unsigned long (*ConnectionInfoExtractField) (struct nameInfo *);
4205
4206 static inline unsigned long
4207 _extract_name_info_userId (struct nameInfo *nameInfo)
4208 {
4209   return nameInfo->userId;
4210 }
4211
4212 static inline unsigned long
4213 _extract_name_info_processId (struct nameInfo *nameInfo)
4214 {
4215   return nameInfo->processId;
4216 }
4217
4218 static dbus_bool_t
4219 _dbus_transport_kdbus_get_connection_info_ulong_field (DBusTransportKdbus         *transport,
4220                                                        ConnectionInfoExtractField  function,
4221                                                        unsigned long              *val)
4222 {
4223   struct nameInfo conn_info;
4224   int ret;
4225
4226   ret = _kdbus_connection_info_by_id (transport->kdbus,
4227                                       _kdbus_get_id (transport->kdbus),
4228                                       FALSE,
4229                                       &conn_info);
4230   if (ret != 0)
4231     return FALSE;
4232
4233   *val = function (&conn_info);
4234   return TRUE;
4235 }
4236
4237 static dbus_bool_t
4238 _dbus_transport_kdbus_get_unix_user (DBusTransport *transport,
4239                                      unsigned long *uid)
4240 {
4241   return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
4242                                                                 _extract_name_info_userId,
4243                                                                 uid);
4244 }
4245
4246 static dbus_bool_t
4247 _dbus_transport_kdbus_get_unix_process_id (DBusTransport *transport,
4248                                            unsigned long *pid)
4249 {
4250   return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
4251                                                                 _extract_name_info_processId,
4252                                                                 pid);
4253 }
4254
4255 /**
4256  * Copy-paste from dbus_transport_socket with needed changes.
4257  *
4258  * Creates a new transport for the given kdbus file descriptor and address.
4259  * The file descriptor must be nonblocking.
4260  *
4261  * @param fd the file descriptor.
4262  * @param address the transport's address
4263  * @returns the new transport, or #NULL if no memory.
4264  */
4265 static DBusTransportKdbus *
4266 new_kdbus_transport (kdbus_t          *kdbus,
4267                      const DBusString *address,
4268                      const char       *activator)
4269 {
4270   DBusTransportKdbus *kdbus_transport;
4271
4272   kdbus_transport = dbus_new0 (DBusTransportKdbus, 1);
4273   if (kdbus_transport == NULL)
4274     return NULL;
4275
4276   kdbus_transport->kdbus = kdbus;
4277
4278   kdbus_transport->write_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
4279                                                  DBUS_WATCH_WRITABLE,
4280                                                  FALSE,
4281                                                  NULL, NULL, NULL);
4282   if (kdbus_transport->write_watch == NULL)
4283     goto failed_2;
4284
4285   kdbus_transport->read_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
4286                                                 DBUS_WATCH_READABLE,
4287                                                 FALSE,
4288                                                 NULL, NULL, NULL);
4289   if (kdbus_transport->read_watch == NULL)
4290     goto failed_3;
4291
4292   if (!_dbus_transport_init_base_authenticated (&kdbus_transport->base,
4293                                                 &kdbus_vtable,
4294                                                 NULL, address))
4295     goto failed_4;
4296
4297   _dbus_transport_set_get_unix_user_function (&kdbus_transport->base,
4298                                               _dbus_transport_kdbus_get_unix_user);
4299   _dbus_transport_set_get_unix_process_id_function (&kdbus_transport->base,
4300                                                     _dbus_transport_kdbus_get_unix_process_id);
4301 #ifdef ENABLE_KDBUS_SYNC_CALLS
4302   _dbus_transport_set_send_sync_call_function (&kdbus_transport->base,
4303                                                (DBusTransportSendSyncCallFunction) kdbus_send_sync_call);
4304 #endif
4305   _dbus_transport_set_assure_protocol_function (&kdbus_transport->base,
4306                                                 _dbus_message_assure_gvariant,
4307                                                 DBUS_PROTOCOL_VERSION_GVARIANT);
4308
4309   /* These values should probably be tunable or something. */
4310   kdbus_transport->max_bytes_read_per_iteration = MAX_BYTES_PER_ITERATION;
4311   kdbus_transport->max_bytes_written_per_iteration = MAX_BYTES_PER_ITERATION;
4312
4313   if (activator!=NULL)
4314     {
4315       kdbus_transport->activator = _dbus_strdup (activator);
4316       if (kdbus_transport->activator == NULL)
4317         goto failed_4;
4318     }
4319
4320   kdbus_transport->matchmaker = matchmaker_new ();
4321
4322   kdbus_transport->client_serial = 1;
4323
4324   return kdbus_transport;
4325
4326  failed_4:
4327   _dbus_watch_invalidate (kdbus_transport->read_watch);
4328   _dbus_watch_unref (kdbus_transport->read_watch);
4329  failed_3:
4330   _dbus_watch_invalidate (kdbus_transport->write_watch);
4331   _dbus_watch_unref (kdbus_transport->write_watch);
4332  failed_2:
4333   dbus_free (kdbus_transport);
4334   return NULL;
4335 }
4336
4337 /**
4338  * Connects to kdbus, creates and sets-up transport.
4339  *
4340  * @param path the path to the bus.
4341  * @param error address where an error can be returned.
4342  * @returns a new transport, or #NULL on failure.
4343  */
4344 static DBusTransport*
4345 _dbus_transport_new_for_kdbus (const char *path,
4346                                const char *activator,
4347                                DBusError  *error)
4348 {
4349   int ret;
4350   DBusTransportKdbus *transport;
4351   DBusString address;
4352   kdbus_t *kdbus;
4353
4354 #ifdef DBUS_ENABLE_VERBOSE_MODE
4355   const char *dbgenv = _dbus_getenv ("G_DBUS_DEBUG");
4356   if (dbgenv != NULL)
4357   {
4358     if (!strcmp (dbgenv, "message"))
4359       debug = 1;
4360     else if (!strcmp (dbgenv, "all"))
4361       debug = 2;
4362   }
4363 #endif
4364
4365   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4366
4367   if (!_dbus_string_init (&address))
4368     {
4369       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4370       return NULL;
4371     }
4372
4373   if ((!_dbus_string_append (&address, DBUS_ADDRESS_KDBUS "path=")) || (!_dbus_string_append (&address, path)))
4374     {
4375       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4376       goto failed_0;
4377     }
4378
4379   kdbus = _kdbus_new (path);
4380   if (NULL == kdbus)
4381     {
4382       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4383       goto failed_0;
4384     }
4385
4386   ret = _kdbus_open (kdbus);
4387   if (ret < 0)
4388     {
4389       dbus_set_error (error,
4390                       _dbus_error_from_errno (-ret),
4391                       "Failed to open file descriptor: %s: %s",
4392                       path,
4393                       _dbus_strerror (-ret));
4394       goto failed_0_with_kdbus;
4395     }
4396
4397   _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
4398
4399   transport = new_kdbus_transport (kdbus, &address, activator);
4400   if (transport == NULL)
4401     {
4402       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4403       goto failed_1;
4404     }
4405
4406   _dbus_string_free (&address);
4407
4408   return (DBusTransport*)transport;
4409
4410 failed_1:
4411   _kdbus_close (kdbus);
4412 failed_0_with_kdbus:
4413   _kdbus_free (kdbus);
4414 failed_0:
4415   _dbus_string_free (&address);
4416   return NULL;
4417 }
4418
4419
4420 /**
4421  * Opens kdbus transport if method from address entry is kdbus
4422  *
4423  * @param entry the address entry to open
4424  * @param transport_p return location for the opened transport
4425  * @param error place to store error
4426  * @returns result of the attempt as a DBusTransportOpenResult enum
4427  */
4428 DBusTransportOpenResult
4429 _dbus_transport_open_kdbus (DBusAddressEntry  *entry,
4430                             DBusTransport    **transport_p,
4431                             DBusError         *error)
4432 {
4433   const char *method;
4434
4435   method = dbus_address_entry_get_method (entry);
4436   _dbus_assert (method != NULL);
4437
4438   if (strcmp (method, "kernel") == 0)
4439     {
4440       const char *path = dbus_address_entry_get_value (entry, "path");
4441       const char *activator = dbus_address_entry_get_value (entry, "activator");
4442
4443       if (path == NULL)
4444         {
4445           _dbus_set_bad_address (error, "kdbus", "path", NULL);
4446           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
4447         }
4448
4449       *transport_p = _dbus_transport_new_for_kdbus (path, activator, error);
4450
4451       if (*transport_p == NULL)
4452         {
4453           _DBUS_ASSERT_ERROR_IS_SET (error);
4454           return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
4455         }
4456       else
4457         {
4458           _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4459           return DBUS_TRANSPORT_OPEN_OK;
4460         }
4461     }
4462   else
4463     {
4464       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4465       return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
4466     }
4467 }
4468
4469 /** @} */