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