Remove kdbus interface header
[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   flags = KDBUS_HELLO_ACCEPT_FD;
1229   if (registration_flags & REGISTER_FLAG_MONITOR)
1230     flags |= KDBUS_HELLO_MONITOR;
1231
1232   ret = _kdbus_hello (transport->kdbus,
1233                       flags,
1234                       _KDBUS_ATTACH_ANY,
1235                       get_attach_flags_recv (transport),
1236                       get_pool_size (),
1237                       transport->activator,
1238                       "libdbus-kdbus");
1239   if (ret != 0)
1240     {
1241       dbus_set_error (error, DBUS_ERROR_FAILED, "Hello failed: %d", -ret);
1242       return FALSE;
1243     }
1244
1245   transport->my_DBus_unique_name = create_unique_name_from_unique_id (_kdbus_get_id (transport->kdbus));
1246   if (NULL == transport->my_DBus_unique_name)
1247     {
1248       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, "Hello post failed: %d", -ret);
1249       return FALSE;
1250     }
1251
1252   _dbus_verbose ("-- Our peer ID is: %llu\n", (unsigned long long)_kdbus_get_id (transport->kdbus));
1253
1254   return TRUE;
1255 }
1256
1257 static dbus_bool_t
1258 can_own (DBusTransportKdbus *transport,
1259          const char         *name)
1260 {
1261   dbus_bool_t result = TRUE;
1262
1263 #ifdef LIBDBUSPOLICY
1264   if (NULL != transport->policy)
1265     result = (dbuspolicy1_can_own (transport->policy, name) == 1);
1266 #endif
1267
1268   return result;
1269 }
1270
1271 static dbus_bool_t
1272 request_DBus_name (DBusTransportKdbus *transport,
1273                    DBusMessage        *msg,
1274                    int                *result,
1275                    DBusError          *error)
1276 {
1277   DBusString service_name_real;
1278   const DBusString *service_name = &service_name_real;
1279   char* name;
1280   dbus_uint32_t flags;
1281
1282   if (!dbus_message_get_args (msg, error,
1283                               DBUS_TYPE_STRING, &name,
1284                               DBUS_TYPE_UINT32, &flags,
1285                               DBUS_TYPE_INVALID))
1286    return FALSE;
1287
1288   _dbus_string_init_const (&service_name_real, name);
1289
1290   if (!_dbus_validate_bus_name (service_name, 0,
1291                                _dbus_string_get_length (service_name)))
1292    {
1293      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1294                      "Requested bus name \"%s\" is not valid", name);
1295
1296      _dbus_verbose ("Attempt to acquire invalid service name\n");
1297
1298      return FALSE;
1299    }
1300
1301   if (_dbus_string_get_byte (service_name, 0) == ':')
1302    {
1303      /* Not allowed; only base services can start with ':' */
1304      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1305                      "Cannot acquire a service starting with ':' such as \"%s\"", name);
1306
1307      _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"", name);
1308
1309      return FALSE;
1310    }
1311
1312   if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
1313    {
1314      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1315                      "Connection is not allowed to own the service \"%s\"because "
1316                      "it is reserved for D-Bus' use only", DBUS_SERVICE_DBUS);
1317      return FALSE;
1318    }
1319
1320   if (!can_own (transport, name))
1321     {
1322       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1323                       "Connection \"%s\" is not allowed to own the "
1324                       "service \"%s\" due to security policies",
1325                       transport->my_DBus_unique_name,
1326                       name);
1327       return FALSE;
1328     }
1329
1330   *result = _kdbus_request_name (transport->kdbus, name, flags);
1331   if (*result == -EPERM)
1332    {
1333      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1334          "Kdbus doesn't allow %s to own the service \"%s\"",
1335          transport->my_DBus_unique_name, _dbus_string_get_const_data (service_name));
1336      return FALSE;
1337    }
1338   else if (*result < 0)
1339    {
1340      dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired, %d, %m", name, errno);
1341      return FALSE;
1342    }
1343
1344   return TRUE;
1345 }
1346
1347 static dbus_bool_t
1348 release_DBus_name (DBusTransportKdbus *transport,
1349                    DBusMessage        *msg,
1350                    int                *result,
1351                    DBusError          *error)
1352 {
1353   const char *name;
1354   DBusString service_name;
1355
1356   if (!dbus_message_get_args (msg, error,
1357                               DBUS_TYPE_STRING, &name,
1358                               DBUS_TYPE_INVALID))
1359     return FALSE;
1360
1361   _dbus_string_init_const (&service_name, name);
1362
1363   if (!_dbus_validate_bus_name (&service_name, 0,
1364                                 _dbus_string_get_length (&service_name)))
1365     {
1366       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1367                       "Given bus name \"%s\" is not valid",
1368                       _dbus_string_get_const_data (&service_name));
1369
1370       _dbus_verbose ("Attempt to release invalid service name\n");
1371       return FALSE;
1372     }
1373
1374   if (_dbus_string_get_byte (&service_name, 0) == ':')
1375     {
1376       /* Not allowed; the base service name cannot be created or released */
1377       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1378                       "Cannot release a service starting with ':' such as \"%s\"",
1379                       _dbus_string_get_const_data (&service_name));
1380
1381       _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
1382                      _dbus_string_get_const_data (&service_name));
1383       return FALSE;
1384     }
1385
1386    if (_dbus_string_equal_c_str (&service_name, DBUS_SERVICE_DBUS))
1387     {
1388       /* Not allowed; the base service name cannot be created or released */
1389       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1390                       "Cannot release the %s service because it is owned by the bus",
1391                      DBUS_SERVICE_DBUS);
1392
1393       _dbus_verbose ("Attempt to release service name \"%s\"",
1394                      DBUS_SERVICE_DBUS);
1395       return FALSE;
1396     }
1397
1398     *result = _kdbus_release_name (transport->kdbus, name);
1399     if (*result < 0)
1400       {
1401         dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be released, %d, %m", name, errno);
1402         return FALSE;
1403       }
1404
1405     return TRUE;
1406 }
1407
1408 static int
1409 strcmp_existing (const char *str1, const char *str2)
1410 {
1411   if (NULL == str1 || NULL == str2)
1412     return 0;
1413   return strcmp (str1, str2);
1414 }
1415
1416 static dbus_bool_t
1417 is_bloom_needed (MatchRule *rule)
1418 {
1419   int rule_int;
1420   int i;
1421
1422   if (_match_rule_get_message_type (rule) != DBUS_TYPE_INVALID
1423       || _match_rule_get_interface (rule) != NULL
1424       || _match_rule_get_member (rule) != NULL
1425       || _match_rule_get_path (rule) != NULL
1426       || _match_rule_get_path_namespace (rule) != NULL)
1427     return TRUE;
1428
1429   rule_int = _match_rule_get_args_len (rule);
1430   for (i = 0; i < rule_int; i++)
1431     {
1432       if (_match_rule_get_args (rule, i) != NULL)
1433         return TRUE;
1434     }
1435
1436   return FALSE;
1437 }
1438
1439 static void
1440 get_bloom (kdbus_t *kdbus, MatchRule *rule, kdbus_bloom_data_t *bloom_data)
1441 {
1442   int rule_int;
1443   const char *rule_string;
1444   int i;
1445   char argument_buf[sizeof ("arg")-1 + 2 + sizeof ("-slash-prefix") +1];
1446
1447   rule_int = _match_rule_get_message_type (rule);
1448   if (rule_int != DBUS_MESSAGE_TYPE_INVALID)
1449   {
1450     bloom_add_pair (bloom_data, kdbus, "message-type", dbus_message_type_to_string (rule_int));
1451     _dbus_verbose ("Adding type %s \n", dbus_message_type_to_string (rule_int));
1452   }
1453
1454   rule_string = _match_rule_get_interface (rule);
1455   if (rule_string != NULL)
1456     {
1457       bloom_add_pair (bloom_data, kdbus, "interface", rule_string);
1458       _dbus_verbose ("Adding interface %s \n", rule_string);
1459     }
1460
1461   rule_string = _match_rule_get_member (rule);
1462   if (rule_string != NULL)
1463   {
1464     bloom_add_pair (bloom_data, kdbus, "member", rule_string);
1465     _dbus_verbose ("Adding member %s \n", rule_string);
1466   }
1467
1468   rule_string = _match_rule_get_path (rule);
1469   if (rule_string != NULL)
1470   {
1471     bloom_add_pair (bloom_data, kdbus, "path", rule_string);
1472     _dbus_verbose ("Adding path %s \n", rule_string);
1473   }
1474
1475   rule_string = _match_rule_get_path_namespace (rule);
1476   if (rule_string != NULL)
1477   {
1478     bloom_add_pair (bloom_data, kdbus, "path-slash-prefix", rule_string);
1479     _dbus_verbose ("Adding path-slash-prefix %s \n", rule_string);
1480   }
1481
1482   rule_int = _match_rule_get_args_len (rule);
1483   for (i = 0; i < rule_int; i++)
1484     {
1485       rule_string = _match_rule_get_args (rule, i);
1486       if (rule_string != NULL)
1487         {
1488           unsigned int rule_arg_lens = _match_rule_get_arg_lens (rule, i);
1489           if (rule_arg_lens & MATCH_ARG_IS_PATH)
1490             {
1491               snprintf (argument_buf, sizeof (argument_buf), "arg%d-slash-prefix", i);
1492               bloom_add_prefixes (bloom_data, kdbus, argument_buf, rule_string, '/');
1493             }
1494           else if (rule_arg_lens & MATCH_ARG_NAMESPACE)
1495             {
1496               snprintf (argument_buf, sizeof (argument_buf), "arg%d-dot-prefix", i);
1497               bloom_add_prefixes (bloom_data, kdbus, argument_buf, rule_string, '.');
1498             }
1499           else
1500             {
1501               snprintf (argument_buf, sizeof (argument_buf), "arg%d", i);
1502               bloom_add_pair (bloom_data, kdbus, argument_buf, rule_string);
1503             }
1504         }
1505     }
1506 }
1507
1508 /**
1509  * Adds a match rule to match broadcast messages going through the message bus.
1510  * Do no affect messages addressed directly.
1511  *
1512  * TODO add error reporting
1513  *
1514  * @param transport transport
1515  * @param match rule
1516  */
1517 static dbus_bool_t
1518 add_match_kdbus (DBusTransportKdbus *transport,
1519                  MatchRule          *rule)
1520 {
1521   struct kdbus_cmd_match    *cmd;
1522   struct kdbus_item         *item;
1523   __u64       rule_cookie;
1524   uint64_t    src_id = KDBUS_MATCH_ID_ANY;
1525   __u64       items_size;
1526   dbus_bool_t need_bloom = FALSE;
1527
1528   const char *rule_sender;
1529   const char *rule_arg0 = NULL;
1530   int ret;
1531
1532   rule_cookie = match_rule_get_cookie (rule);
1533   rule_sender = _match_rule_get_sender (rule);
1534
1535 /*
1536  * First check if it is org.freedesktop.DBus's NameOwnerChanged or any
1537  * org.freedesktop.DBus combination that includes this,
1538  * because it must be converted to special kdbus rule (kdbus has separate rules
1539  * for kdbus (kernel) generated broadcasts).
1540  */
1541   if (!strcmp_existing (rule_sender, DBUS_SERVICE_DBUS))
1542     {
1543       int message_type = _match_rule_get_message_type (rule);
1544
1545       if ((DBUS_MESSAGE_TYPE_INVALID == message_type || DBUS_MESSAGE_TYPE_SIGNAL == message_type)
1546           && !strcmp_existing (_match_rule_get_interface (rule), DBUS_INTERFACE_DBUS)
1547           && !strcmp_existing (_match_rule_get_path (rule), DBUS_PATH_DBUS))
1548         {
1549           if (_match_rule_get_args_len(rule) == 1)
1550             {
1551               rule_arg0 = _match_rule_get_args(rule, 0);
1552               if (rule_arg0)
1553                 {
1554                   DBusString str;
1555                   _dbus_string_init_const (&str, rule_arg0);
1556                   ret = _dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str));
1557                   if (!ret)
1558                     return FALSE;
1559                 }
1560             }
1561           if (!strcmp_existing (_match_rule_get_member (rule), "NameOwnerChanged"))
1562             {
1563               ret = _kdbus_add_match_name_change (transport->kdbus,
1564                                                   0,
1565                                                   rule_cookie,
1566                                                   KDBUS_MATCH_ID_ANY,
1567                                                   0,
1568                                                   KDBUS_MATCH_ID_ANY,
1569                                                   0,
1570                                                   rule_arg0);
1571               if (0 != ret)
1572                 {
1573                   _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
1574                                   ret, _dbus_strerror (ret));
1575                   return FALSE;
1576                 }
1577
1578               _dbus_verbose ("Added match rule for kernel correctly.\n");
1579
1580               ret = _kdbus_add_match_id_change (transport->kdbus,
1581                                                 0,
1582                                                 rule_cookie,
1583                                                 KDBUS_MATCH_ID_ANY,
1584                                                 0,
1585                                                 rule_arg0);
1586               if (0 != ret)
1587                 {
1588                   _dbus_verbose ("Failed adding match rule for adding id for daemon, error: %d, %s\n",
1589                                   ret, _dbus_strerror (ret));
1590                   return FALSE;
1591                 }
1592             }
1593           else if (strcmp (_match_rule_get_member (rule), "NameAcquired") == 0)
1594             {
1595               ret = _kdbus_add_match_name_acquired (transport->kdbus,
1596                                                     0,
1597                                                     rule_cookie,
1598                                                     KDBUS_MATCH_ID_ANY,
1599                                                     0,
1600                                                     _kdbus_get_id (transport->kdbus),
1601                                                     0,
1602                                                     rule_arg0);
1603               if (0 != ret)
1604                 {
1605                   _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
1606                                   ret, _dbus_strerror (ret));
1607                   return FALSE;
1608                 }
1609             }
1610           else if (strcmp (_match_rule_get_member (rule), "NameLost") == 0)
1611             {
1612               ret = _kdbus_add_match_name_lost (transport->kdbus,
1613                                                0,
1614                                                 rule_cookie,
1615                                                 _kdbus_get_id (transport->kdbus),
1616                                                 0,
1617                                                 KDBUS_MATCH_ID_ANY,
1618                                                 0,
1619                                                 rule_arg0);
1620               if (0 != ret)
1621                 {
1622                   _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
1623                   ret, _dbus_strerror (ret));
1624                   return FALSE;
1625                 }
1626             }
1627         }
1628       /* Sender=DBUS_SERVICE_DBUS matches (as opposed to wildcard sender) need no standard rule. */
1629       if (rule_sender)
1630         return TRUE;
1631     }
1632
1633 /*
1634  * standard rule - registered in general way, for non-kernel broadcasts
1635  * kdbus doesn't use it to check kdbus (kernel) generated broadcasts
1636  */
1637
1638   need_bloom = is_bloom_needed (rule);
1639
1640   if (rule_sender != NULL)
1641     {
1642       DBusString str;
1643       _dbus_string_init_const (&str, rule_sender);
1644
1645       if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
1646         return FALSE;
1647
1648       src_id = parse_name (rule_sender);
1649       if (0 == src_id)
1650           /* well-known name */
1651           src_id = KDBUS_MATCH_ID_ANY;
1652       else
1653           /* unique id */
1654           rule_sender = NULL;
1655     }
1656
1657   items_size = _kdbus_compute_match_items_size (transport->kdbus,
1658                                                 need_bloom,
1659                                                 src_id,
1660                                                 rule_sender);
1661
1662   cmd = _kdbus_new_cmd_match (transport->kdbus,
1663                               items_size,
1664                               0,
1665                               rule_cookie);
1666   if (NULL == cmd)
1667     ret = ENOMEM;
1668   else
1669     {
1670       item = cmd->items;
1671       if (NULL != rule_sender)  /* well-known name */
1672         {
1673           item = _kdbus_item_add_string (item,
1674                                          KDBUS_ITEM_NAME,
1675                                          rule_sender,
1676                                          strlen (rule_sender) + 1);
1677           _dbus_verbose ("Adding sender %s \n", rule_sender);
1678         }
1679       else if (KDBUS_MATCH_ID_ANY != src_id) /* unique id */
1680         {
1681           item = _kdbus_item_add_id (item, src_id);
1682           _dbus_verbose ("Adding src_id %llu \n", (unsigned long long)src_id);
1683         }
1684
1685       if (need_bloom)
1686         {
1687           __u64 *bloom;
1688           item = _kdbus_item_add_bloom_mask (item, transport->kdbus, &bloom);
1689           get_bloom (transport->kdbus, rule, bloom);
1690         }
1691
1692       ret = _kdbus_add_match (transport->kdbus, cmd);
1693
1694       _kdbus_free_cmd_match (cmd);
1695     }
1696
1697   if (0 != ret)
1698     {
1699       _dbus_verbose ("Failed adding match bus rule cookie %llu,\nerror: %d, %s\n",
1700                      rule_cookie, ret, _dbus_strerror (ret));
1701       return FALSE;
1702     }
1703
1704   _dbus_verbose ("Added match bus rule %llu\n", rule_cookie);
1705   return TRUE;
1706 }
1707
1708 static DBusMessage *
1709 capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport,
1710                                     DBusMessage        *message,
1711                                     DBusError          *error)
1712 {
1713   DBusMessageIter args;
1714   dbus_uint32_t registration_flags = 0;
1715
1716   dbus_message_iter_init (message, &args);
1717   if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_UINT32)
1718     dbus_message_iter_get_basic (&args, &registration_flags);
1719
1720   if (!bus_register_kdbus (transport, registration_flags, error))
1721     goto out;
1722
1723   return reply_1_data (message, DBUS_TYPE_STRING, &transport->my_DBus_unique_name);
1724
1725 out:
1726   free (transport->my_DBus_unique_name);
1727   return NULL;
1728 }
1729
1730 static DBusMessage *
1731 capture_org_freedesktop_DBus_RequestName (DBusTransportKdbus *transport,
1732                                           DBusMessage        *message,
1733                                           DBusError          *error)
1734 {
1735   int result;
1736
1737   if (!request_DBus_name (transport, message, &result, error))
1738     return NULL;
1739
1740   return reply_1_data (message, DBUS_TYPE_UINT32, &result);
1741 }
1742
1743 static DBusMessage *
1744 capture_org_freedesktop_DBus_ReleaseName (DBusTransportKdbus *transport,
1745                                           DBusMessage        *message,
1746                                           DBusError          *error)
1747 {
1748   int result;
1749
1750   if (!release_DBus_name (transport, message, &result, error))
1751     return NULL;
1752
1753   return reply_1_data (message, DBUS_TYPE_UINT32, &result);
1754 }
1755
1756 static DBusMessage *
1757 capture_org_freedesktop_DBus_AddMatch (DBusTransportKdbus *transport,
1758                                        DBusMessage        *message,
1759                                        DBusError          *error)
1760 {
1761   const char *arg;
1762   DBusString arg_str;
1763   MatchRule *rule = NULL;
1764   DBusConnection *connection = transport->base.connection;
1765
1766   if (!dbus_message_get_args (message, error,
1767         DBUS_TYPE_STRING, &arg,
1768         DBUS_TYPE_INVALID))
1769     goto failed;
1770
1771   _dbus_string_init_const (&arg_str, arg);
1772
1773   rule = match_rule_parse (connection, &arg_str, error);
1774   if (rule == NULL)
1775     goto failed;
1776
1777   if (!matchmaker_add_rule (transport->matchmaker, rule))
1778   {
1779     dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, "No memory to store match rule");
1780     goto failed;
1781   }
1782
1783   if (!add_match_kdbus (transport, rule))
1784   {
1785     dbus_set_error (error, _dbus_error_from_errno (errno), "Could not add match rule, %s",
1786         _dbus_strerror_from_errno ());
1787     goto failed;
1788   }
1789
1790   match_rule_unref (rule);
1791   return dbus_message_new_method_return (message);
1792
1793 failed:
1794   if (rule)
1795     match_rule_unref (rule);
1796   _dbus_verbose ("Error during AddMatch in lib: %s, %s\n", error->name, error->message);
1797   return NULL;
1798 }
1799
1800 static dbus_uint64_t
1801 get_match_cookie_for_remove (Matchmaker *matchmaker, MatchRule *rule_to_remove)
1802 {
1803   DBusList *rules = matchmaker_get_rules_list (matchmaker, rule_to_remove);
1804   if (NULL != rules)
1805     {
1806       DBusList *link = _dbus_list_get_last_link (&rules);
1807       while (NULL != link)
1808         {
1809           if (match_rule_equal_lib (link->data, rule_to_remove))
1810             {
1811               return match_rule_get_cookie (link->data);
1812             }
1813           link = _dbus_list_get_prev_link (&rules, link);
1814         }
1815     }
1816   return 0;
1817 }
1818
1819 static DBusMessage *
1820 capture_org_freedesktop_DBus_RemoveMatch (DBusTransportKdbus *transport,
1821                                           DBusMessage        *message,
1822                                           DBusError          *error)
1823 {
1824   const char *arg;
1825   DBusString arg_str;
1826   MatchRule *rule = NULL;
1827   DBusConnection *connection = transport->base.connection;
1828   dbus_uint64_t cookie;
1829
1830   if (!dbus_message_get_args (message, error,
1831         DBUS_TYPE_STRING, &arg,
1832         DBUS_TYPE_INVALID))
1833     return NULL;
1834
1835   _dbus_string_init_const (&arg_str, arg);
1836
1837   rule = match_rule_parse (connection, &arg_str, error);
1838   if (rule != NULL)
1839     {
1840       cookie = get_match_cookie_for_remove (transport->matchmaker, rule);
1841       if (0 == cookie)
1842         {
1843           dbus_set_error (error,
1844                           DBUS_ERROR_MATCH_RULE_NOT_FOUND,
1845                           "The given match rule wasn't found and can't be removed");
1846         }
1847       else
1848         {
1849           int ret = _kdbus_remove_match (transport->kdbus, cookie);
1850           if (ret != 0)
1851             dbus_set_error (error,
1852                             _dbus_error_from_errno (ret),
1853                             "Could not remove match rule");
1854
1855           if (!dbus_error_is_set (error))
1856             matchmaker_remove_rule_by_value (transport->matchmaker, rule, error);
1857         }
1858
1859       match_rule_unref (rule);
1860     }
1861
1862   if (dbus_error_is_set (error))
1863     {
1864       _dbus_verbose ("Error during RemoveMatch in lib: %s, %s\n",
1865                      error->name,
1866                      error->message);
1867       return NULL;
1868     }
1869
1870   return dbus_message_new_method_return (message);
1871 }
1872
1873 static int
1874 get_connection_info_by_name (DBusMessage        *message,
1875                              DBusError          *error,
1876                              struct nameInfo    *info,
1877                              DBusTransportKdbus *transport,
1878                              const char         *name,
1879                              dbus_bool_t         getLabel)
1880 {
1881   int ret;
1882   if (!dbus_validate_bus_name (name, error))
1883     return -1;
1884
1885   if ((ret = _kdbus_connection_info_by_name (transport->kdbus, name, getLabel, info)) != 0)
1886     {
1887       if (ESRCH == ret || ENXIO == ret)
1888           dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1889               "Could not get owner of name '%s': no such name", name);
1890       else
1891         dbus_set_error (error, DBUS_ERROR_FAILED,
1892             "Unable to query name %s, returned %d, errno = %d (%m).",
1893                         name, ret, errno);
1894       return -1;
1895     }
1896   if (info->flags & KDBUS_HELLO_ACTIVATOR)
1897   {
1898     dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1899         "Could not get owner of name '%s'", name);
1900     /* we return ESRCH - this is an indicator that name has an activator */
1901     return -ESRCH;
1902   }
1903   return 0;
1904 }
1905
1906 /* This local function handles common case for org.freedesktop.DBus method handlers:
1907  * 1. gets string argument from incoming message;
1908  * 2. gets connection info for such name.
1909  * Note: if getLabel argument is set to TRUE, the caller must free info.sec_label.
1910  */
1911 static int
1912 get_connection_info_from_message_argument (DBusMessage        *message,
1913                                            DBusError          *error,
1914                                            struct nameInfo    *info,
1915                                            DBusTransportKdbus *transport,
1916                                            dbus_bool_t         getLabel)
1917 {
1918   const char *arg;
1919
1920   if (!dbus_message_get_args (message, error,
1921                               DBUS_TYPE_STRING, &arg,
1922                               DBUS_TYPE_INVALID))
1923       return -1;
1924
1925   return get_connection_info_by_name (message, error, info, transport, arg, getLabel);
1926 }
1927
1928 static DBusMessage *
1929 capture_org_freedesktop_DBus_GetConnectionCredentials (DBusTransportKdbus *transport,
1930                                                        DBusMessage        *message,
1931                                                        DBusError          *error)
1932 {
1933   DBusMessage *reply = NULL;
1934   DBusMessageIter reply_iter;
1935   DBusMessageIter array_iter;
1936   struct nameInfo info;
1937
1938   if (get_connection_info_from_message_argument (message, error, &info, transport, TRUE) != 0)
1939     return NULL;
1940
1941   reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
1942   if (reply == NULL)
1943     return NULL;
1944
1945   /* we can't represent > 32-bit pids; if your system needs them, please
1946    * add ProcessID64 to the spec or something */
1947   if (info.processId <= _DBUS_UINT32_MAX)
1948     {
1949       if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", info.processId))
1950         goto oom;
1951     }
1952   /* we can't represent > 32-bit uids; if your system needs them, please
1953    * add UnixUserID64 to the spec or something */
1954   if (info.userId <= _DBUS_UINT32_MAX)
1955     {
1956       if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", info.userId))
1957         goto oom;
1958     }
1959
1960   if (info.sec_label != NULL)
1961     {
1962       dbus_bool_t res = _dbus_asv_add_byte_array (&array_iter,
1963                                                   "LinuxSecurityLabel",
1964                                                   info.sec_label,
1965                                                   info.sec_label_len);
1966
1967       dbus_free (info.sec_label);
1968
1969       if (!res)
1970         goto oom;
1971     }
1972
1973   if (!_dbus_asv_close (&reply_iter, &array_iter))
1974     goto oom;
1975
1976   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
1977     goto oom;
1978
1979   return reply;
1980
1981 oom:
1982   _dbus_asv_abandon (&reply_iter, &array_iter);
1983   dbus_message_unref (reply);
1984
1985   return NULL;
1986 }
1987
1988 static dbus_bool_t
1989 _mac_smack_use (void)
1990 {
1991   static int cached_use = -1;
1992
1993   if (cached_use < 0)
1994     cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
1995
1996   return cached_use;
1997 }
1998
1999 static DBusMessage *
2000 capture_org_freedesktop_DBus_GetConnectionSELinuxSecurityContext (DBusTransportKdbus *transport,
2001                                                                   DBusMessage        *message,
2002                                                                   DBusError          *error)
2003 {
2004   struct nameInfo info;
2005
2006   if (get_connection_info_from_message_argument (message, error, &info, transport, TRUE) != 0)
2007     return NULL;
2008
2009   if (info.sec_label != NULL)
2010     {
2011       if (_mac_smack_use())
2012         {
2013           dbus_set_error (error, DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN,
2014                           "Could not determine security context");
2015           dbus_free (info.sec_label);
2016         }
2017       else
2018         {
2019           DBusMessage *reply;
2020
2021           reply = reply_fixed_array (message, DBUS_TYPE_BYTE,
2022                                      info.sec_label,
2023                                      info.sec_label_len);
2024
2025           dbus_free (info.sec_label);
2026           return reply;
2027         }
2028     }
2029   else
2030     {
2031       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, "Operation not supported");
2032     }
2033
2034   return NULL;
2035 }
2036
2037 static DBusMessage *
2038 capture_org_freedesktop_DBus_GetConnectionUnixProcessID (DBusTransportKdbus *transport,
2039                                                          DBusMessage        *message,
2040                                                          DBusError          *error)
2041 {
2042   struct nameInfo info;
2043   dbus_uint32_t processId;
2044
2045   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0 ||
2046       info.processId > _DBUS_UINT32_MAX)
2047     return NULL;
2048
2049   processId = info.processId;
2050
2051   return reply_1_data (message, DBUS_TYPE_UINT32, &processId);
2052 }
2053
2054 static DBusMessage *
2055 capture_org_freedesktop_DBus_GetConnectionUnixUser (DBusTransportKdbus *transport,
2056                                                     DBusMessage        *message,
2057                                                     DBusError          *error)
2058 {
2059   struct nameInfo info;
2060   dbus_uint32_t userId;
2061
2062   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0 ||
2063       info.userId > _DBUS_UINT32_MAX)
2064     return NULL;
2065
2066   userId = info.userId;
2067
2068   return reply_1_data (message, DBUS_TYPE_UINT32, &userId);
2069 }
2070
2071 static DBusMessage *
2072 capture_org_freedesktop_DBus_GetId (DBusTransportKdbus *transport,
2073                                     DBusMessage        *message,
2074                                     DBusError          *error)
2075 {
2076   dbus_uint64_t bus_id_size = _kdbus_get_bus_id_size ();
2077   char bus_id[bus_id_size*2+1];
2078   char *bus_id_ptr = bus_id;
2079   char *bus_id_original = _kdbus_get_bus_id (transport->kdbus);
2080   dbus_uint64_t i = 0;
2081   for (; i < bus_id_size; i++)
2082     snprintf (bus_id + 2*i, sizeof (bus_id) - 2*i, "%02x", bus_id_original[i]);
2083   return reply_1_data (message, DBUS_TYPE_STRING, &bus_id_ptr);
2084 }
2085
2086 static DBusMessage *
2087 capture_org_freedesktop_DBus_GetNameOwner (DBusTransportKdbus *transport,
2088                                            DBusMessage        *message,
2089                                            DBusError          *error)
2090 {
2091   DBusMessage *reply;
2092   struct nameInfo info;
2093   char *unique_name;
2094   const char *arg;
2095
2096   if (!dbus_message_get_args (message, error,
2097                               DBUS_TYPE_STRING, &arg,
2098                               DBUS_TYPE_INVALID))
2099       return NULL;
2100
2101   if (strcmp (arg, DBUS_SERVICE_DBUS) == 0)
2102     {
2103       if (-1 == asprintf (&unique_name, "%s", DBUS_SERVICE_DBUS))
2104         return NULL;
2105     }
2106   else
2107     {
2108       if (get_connection_info_by_name (message, error, &info, transport, arg, FALSE) != 0)
2109         return NULL;
2110
2111       unique_name = create_unique_name_from_unique_id (info.uniqueId);
2112       if (NULL == unique_name)
2113         return NULL;
2114     }
2115
2116   reply = reply_1_data (message, DBUS_TYPE_STRING, &unique_name);
2117
2118   free (unique_name);
2119
2120   return reply;
2121 }
2122
2123 static DBusMessage *
2124 reply_listNames (DBusTransportKdbus *transport,
2125                  DBusMessage        *message,
2126                  DBusError          *error,
2127                  dbus_uint64_t       flags)
2128 {
2129   DBusMessage *reply = NULL;
2130   dbus_uint64_t prev_id = 0;
2131
2132   /* First, get the list from kdbus */
2133
2134   struct kdbus_info *name_list, *name;
2135   __u64 list_size;
2136   int ret;
2137   DBusMessageIter iter;
2138   DBusMessageIter array_iter;
2139
2140   ret = _kdbus_list (transport->kdbus,
2141                      flags,
2142                      &name_list,
2143                      &list_size);
2144   if (ret != 0)
2145     {
2146       dbus_set_error (error, DBUS_ERROR_FAILED, "Error listing names");
2147       return NULL;
2148     }
2149
2150   /* Compose the reply on the fly */
2151   reply = dbus_message_new_method_return (message);
2152   if (reply == NULL)
2153     goto oom;
2154
2155   dbus_message_iter_init_append (reply, &iter);
2156   if (!dbus_message_iter_open_container (&iter,
2157                                          DBUS_TYPE_ARRAY,
2158                                          DBUS_TYPE_STRING_AS_STRING,
2159                                          &array_iter))
2160     goto oom_reply;
2161
2162   KDBUS_FOREACH (name, name_list, list_size)
2163     {
2164       struct kdbus_item *item;
2165
2166       if ((flags & KDBUS_LIST_UNIQUE) && name->id != prev_id)
2167         {
2168           dbus_bool_t res;
2169
2170           char *unique_name = create_unique_name_from_unique_id (name->id);
2171
2172           if (NULL == unique_name)
2173             goto oom_iterator;
2174
2175           res = dbus_message_iter_append_basic (&array_iter,
2176                                                 DBUS_TYPE_STRING,
2177                                                 &unique_name);
2178           free (unique_name);
2179
2180           if (!res)
2181             goto oom_iterator;
2182         }
2183
2184       KDBUS_ITEM_FOREACH (item, name, items)
2185         {
2186           if (item->type == KDBUS_ITEM_OWNED_NAME)
2187             {
2188               DBusError local_error;
2189               char *name_ptr = item->name.name;
2190
2191               dbus_error_init ( &local_error );
2192               if (!dbus_validate_bus_name (name_ptr, &local_error))
2193                 continue;
2194
2195               if (flags & KDBUS_LIST_QUEUED)
2196                 name_ptr = create_unique_name_from_unique_id (name->id);
2197
2198               if (NULL == name_ptr)
2199                 goto oom_iterator;
2200
2201               if (!dbus_message_iter_append_basic (&array_iter,
2202                                                    DBUS_TYPE_STRING,
2203                                                    &name_ptr))
2204                 {
2205                   if (flags & KDBUS_LIST_QUEUED)
2206                     free (name_ptr);
2207                   goto oom_iterator;
2208                 }
2209
2210               if (flags & KDBUS_LIST_QUEUED)
2211                 free (name_ptr);
2212             }
2213         }
2214     }
2215
2216   if (!dbus_message_iter_close_container (&iter, &array_iter))
2217     goto oom_reply;
2218
2219   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
2220     goto oom_reply;
2221
2222   _kdbus_free_mem (transport->kdbus, name_list);
2223
2224   return reply;
2225
2226 oom_iterator:
2227   dbus_message_iter_abandon_container (&iter, &array_iter);
2228
2229 oom_reply:
2230   dbus_message_unref (reply);
2231 oom:
2232   _kdbus_free_mem (transport->kdbus, name_list);
2233   return NULL;
2234 }
2235
2236 static DBusMessage *
2237 capture_org_freedesktop_DBus_ListActivatableNames (DBusTransportKdbus *transport,
2238                                                    DBusMessage        *message,
2239                                                    DBusError          *error)
2240 {
2241   return reply_listNames (transport, message, error, KDBUS_LIST_ACTIVATORS);
2242 }
2243
2244 static DBusMessage *
2245 capture_org_freedesktop_DBus_ListNames (DBusTransportKdbus *transport,
2246                                         DBusMessage        *message,
2247                                         DBusError          *error)
2248 {
2249   return reply_listNames (transport, message, error, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES);
2250 }
2251
2252 static DBusMessage *
2253 capture_org_freedesktop_DBus_ListQueuedOwners (DBusTransportKdbus *transport,
2254                                                DBusMessage        *message,
2255                                                DBusError          *error)
2256 {
2257   struct nameInfo info;
2258
2259   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2260     return NULL;
2261
2262   return reply_listNames (transport, message, error, KDBUS_LIST_QUEUED);
2263 }
2264
2265 static DBusMessage *
2266 capture_org_freedesktop_DBus_NameHasOwner (DBusTransportKdbus *transport,
2267                                            DBusMessage        *message,
2268                                            DBusError          *error)
2269 {
2270   struct nameInfo info;
2271   dbus_bool_t result = TRUE;
2272
2273   if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2274     {
2275       if (dbus_error_is_set (error) && dbus_error_has_name (error, DBUS_ERROR_NAME_HAS_NO_OWNER))
2276         {
2277           result = FALSE;
2278           dbus_error_free (error);
2279         }
2280       else
2281         return NULL;
2282     }
2283
2284   return reply_1_data (message, DBUS_TYPE_BOOLEAN, &result);
2285 }
2286
2287 static DBusMessage *
2288 capture_org_freedesktop_DBus_ReloadConfig (DBusTransportKdbus *transport,
2289                                            DBusMessage        *message,
2290                                            DBusError          *error)
2291 {
2292   DBusMessageIter iter;
2293   DBusMessage *reply = NULL;
2294
2295   dbus_message_iter_init (message, &iter);
2296   if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT)
2297     {
2298       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2299           "Call to 'ReloadConfig' has wrong args");
2300       return NULL;
2301     }
2302
2303   reply = dbus_message_new_method_return (message);
2304   if (reply == NULL)
2305     return NULL;
2306
2307   if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
2308     goto oom;
2309
2310   return reply;
2311
2312 oom:
2313   dbus_message_unref (reply);
2314   return NULL;
2315 }
2316
2317 static DBusMessage *
2318 capture_org_freedesktop_DBus_StartServiceByName (DBusTransportKdbus *transport,
2319                                                  DBusMessage        *message,
2320                                                  DBusError          *error)
2321 {
2322   struct nameInfo info;
2323   char *name;
2324   dbus_uint32_t flags; /* Spec says: not used, but we check the syntax anyway */
2325   int ret = 0;
2326   dbus_bool_t dbus_service = FALSE;
2327
2328   if (!dbus_message_get_args (message, error,
2329                               DBUS_TYPE_STRING, &name,
2330                               DBUS_TYPE_UINT32, &flags,
2331                               DBUS_TYPE_INVALID))
2332     return NULL;
2333
2334   dbus_service = (strncmp (name, DBUS_SERVICE_DBUS, strlen (DBUS_SERVICE_DBUS) + 1) == 0);
2335
2336   if (!dbus_service)
2337     ret = get_connection_info_by_name (message,
2338                                        error,
2339                                        &info,
2340                                        transport,
2341                                        name,
2342                                        FALSE);
2343
2344   if (dbus_service || 0 == ret)
2345     {
2346       dbus_uint32_t status = DBUS_START_REPLY_ALREADY_RUNNING;
2347       return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2348     }
2349   else if (-ESRCH == ret) /* there is an activator */
2350     {
2351       DBusMessage *sub_message;
2352
2353       /* if we are here, then we have error set - free place for possible real error */
2354       dbus_error_free (error);
2355
2356       /* send method call to org.freedesktop.DBus.Peer.Ping */
2357       sub_message = dbus_message_new_method_call (name, "/", DBUS_INTERFACE_PEER, "Ping");
2358       if (sub_message == NULL)
2359         return NULL;
2360
2361       /* The serial number here is set to -1. A message needs a valid serial number.
2362        * We do not have access to connection's serial numbers counter, so we need to make up one.
2363        * -1 is the last valid serial, so we hope that we'll never get there, especially with 64-bit
2364        * kdbus cookies.
2365        */
2366       dbus_message_set_serial (sub_message, -1);
2367
2368       dbus_message_lock (sub_message);
2369
2370       if (kdbus_write_msg_internal (transport, sub_message, name, NULL, FALSE) == -1)
2371           return NULL;
2372       else
2373         {
2374           dbus_uint32_t status = DBUS_START_REPLY_SUCCESS;
2375           return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2376         }
2377     }
2378   else
2379     {
2380       /*
2381        * There was an error set in get_connection_info_by_name()
2382        * We want to have another error return from StartServiceByName.
2383        */
2384       dbus_error_free (error);
2385       dbus_set_error (error,
2386                       DBUS_ERROR_SERVICE_UNKNOWN,
2387                       "The name %s was not provided by any .service files",
2388                       name);
2389     }
2390
2391   return NULL;
2392 }
2393
2394 static DBusMessage *
2395 capture_org_freedesktop_DBus_UpdateActivationEnvironment (DBusTransportKdbus *transport,
2396                                                           DBusMessage        *message,
2397                                                           DBusError          *error)
2398 {
2399   dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
2400       "'%s' method not supported", dbus_message_get_member (message));
2401   return NULL;
2402 }
2403
2404 typedef DBusMessage * (*CaptureHandler)(DBusTransportKdbus *, DBusMessage *, DBusError *);
2405 struct CaptureHandlers {
2406   const char *method_name;
2407   CaptureHandler handler;
2408 };
2409
2410 #define HANDLER_ELEMENT(x) {#x, capture_org_freedesktop_DBus_##x}
2411
2412 /* This is to cut the code to parts, and keep it organized:
2413  * an array of elements of type, as in example:
2414  * { "RequestName", capture_org_freedesktop_DBus_RequestName }
2415  * That is, a method of name RequestName will be handled by capture_org_freedesktop_DBus_RequestName ().
2416  */
2417 static struct CaptureHandlers capture_handlers[] =
2418 {
2419 // "Hello" is handled separately
2420 //  HANDLER_ELEMENT (Hello),
2421   HANDLER_ELEMENT (RequestName),
2422   HANDLER_ELEMENT (ReleaseName),
2423   HANDLER_ELEMENT (AddMatch),
2424   HANDLER_ELEMENT (RemoveMatch),
2425   HANDLER_ELEMENT (GetConnectionCredentials),
2426   HANDLER_ELEMENT (GetConnectionSELinuxSecurityContext),
2427   HANDLER_ELEMENT (GetConnectionUnixProcessID),
2428   HANDLER_ELEMENT (GetConnectionUnixUser),
2429   HANDLER_ELEMENT (GetId),
2430   HANDLER_ELEMENT (GetNameOwner),
2431   HANDLER_ELEMENT (ListActivatableNames),
2432   HANDLER_ELEMENT (ListNames),
2433   HANDLER_ELEMENT (ListQueuedOwners),
2434   HANDLER_ELEMENT (NameHasOwner),
2435   HANDLER_ELEMENT (ReloadConfig),
2436   HANDLER_ELEMENT (StartServiceByName),
2437   HANDLER_ELEMENT (UpdateActivationEnvironment)
2438 };
2439
2440 /**
2441  * Looks over messages sent to org.freedesktop.DBus. Hello message, which performs
2442  * registration on the bus, is captured as it must be locally converted into
2443  * appropriate ioctl. AddMatch and RemoveMatch are captured to store match rules
2444  * locally in case of false positive result of kdbus bloom filters, but after
2445  * being read they are passed to org.freedesktop.DBus to register these rules
2446  * in kdbus.
2447  * All the rest org.freedesktop.DBus methods are left untouched
2448  * and they are sent to dbus-daemon in the same way as every other messages.
2449  *
2450  * @param transport Transport
2451  * @param message Message being sent.
2452  * @returns
2453         1 if message is not captured and should be passed to kdbus
2454  *      0 if message was handled locally and correctly (it includes proper return of error reply),
2455  *     -1 message to org.freedesktop.DBus was not handled correctly.
2456  */
2457 static int
2458 capture_org_freedesktop_DBus (DBusTransportKdbus *transport,
2459                               const char         *destination,
2460                               DBusMessage        *message,
2461                               DBusMessage       **reply)
2462 {
2463   int ret = 1;
2464   if (!strcmp (destination, DBUS_SERVICE_DBUS))
2465     {
2466       const char *interface = dbus_message_get_interface (message);
2467       if (interface && !strcmp (interface, DBUS_INTERFACE_DBUS))
2468         {
2469           DBusError error;
2470           const char *member = dbus_message_get_member (message);
2471
2472           dbus_error_init (&error);
2473
2474           if (!strcmp (member, "Hello"))
2475             {
2476               *reply = capture_org_freedesktop_DBus_Hello (transport, message, &error);
2477             }
2478           else
2479             {
2480               int i = 0;
2481               int handlers_size = sizeof (capture_handlers)/sizeof (capture_handlers[0]);
2482
2483               while (i < handlers_size && strcmp (member, capture_handlers[i].method_name) != 0)
2484                 i++;
2485
2486               if (i < handlers_size)
2487                 {
2488                   *reply = capture_handlers[i].handler (transport, message, &error);
2489                 }
2490               else
2491                 {
2492                   dbus_set_error (&error, DBUS_ERROR_UNKNOWN_METHOD,
2493                       "org.freedesktop.DBus does not understand message %s", member);
2494                 }
2495             }
2496
2497           if (*reply == NULL && dbus_error_is_set (&error))
2498             {
2499               *reply = reply_with_error ((char*)error.name,
2500                                          NULL,
2501                                          error.message,
2502                                          message);
2503               dbus_error_free (&error);
2504             }
2505
2506            if (*reply == NULL)
2507              ret = -1;
2508            else
2509              ret = 0;
2510
2511         } /* id DBUS_INTERFACE_DBUS */
2512     } /* if DBUS_SERVICE_DBUS */
2513
2514   return ret;
2515 }
2516
2517 #ifdef DBUS_ENABLE_VERBOSE_MODE
2518 #define ENUM_NAME_ITEM(x) case x : return #x
2519
2520 static const char *
2521 enum_MSG (long long id)
2522 {
2523   switch (id)
2524     {
2525       ENUM_NAME_ITEM (_KDBUS_ITEM_NULL);
2526       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_VEC);
2527       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_OFF);
2528       ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_MEMFD);
2529       ENUM_NAME_ITEM (KDBUS_ITEM_FDS);
2530       ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_PARAMETER);
2531       ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_FILTER);
2532       ENUM_NAME_ITEM (KDBUS_ITEM_DST_NAME);
2533       ENUM_NAME_ITEM (KDBUS_ITEM_CREDS);
2534       ENUM_NAME_ITEM (KDBUS_ITEM_PID_COMM);
2535       ENUM_NAME_ITEM (KDBUS_ITEM_TID_COMM);
2536       ENUM_NAME_ITEM (KDBUS_ITEM_EXE);
2537       ENUM_NAME_ITEM (KDBUS_ITEM_CMDLINE);
2538       ENUM_NAME_ITEM (KDBUS_ITEM_CGROUP);
2539       ENUM_NAME_ITEM (KDBUS_ITEM_CAPS);
2540       ENUM_NAME_ITEM (KDBUS_ITEM_SECLABEL);
2541       ENUM_NAME_ITEM (KDBUS_ITEM_AUDIT);
2542       ENUM_NAME_ITEM (KDBUS_ITEM_CONN_DESCRIPTION);
2543       ENUM_NAME_ITEM (KDBUS_ITEM_NAME);
2544       ENUM_NAME_ITEM (KDBUS_ITEM_TIMESTAMP);
2545       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_ADD);
2546       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_REMOVE);
2547       ENUM_NAME_ITEM (KDBUS_ITEM_NAME_CHANGE);
2548       ENUM_NAME_ITEM (KDBUS_ITEM_ID_ADD);
2549       ENUM_NAME_ITEM (KDBUS_ITEM_ID_REMOVE);
2550       ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_TIMEOUT);
2551       ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_DEAD);
2552     }
2553   return "UNKNOWN";
2554 }
2555
2556 #if KDBUS_MSG_DECODE_DEBUG == 1
2557 static const char *
2558 enum_PAYLOAD (long long id)
2559 {
2560   switch (id)
2561     {
2562       ENUM_NAME_ITEM (KDBUS_PAYLOAD_KERNEL);
2563       ENUM_NAME_ITEM (KDBUS_PAYLOAD_DBUS);
2564     }
2565   return "UNKNOWN";
2566 }
2567
2568 static const char *
2569 msg_id (uint64_t id)
2570 {
2571   char buf[64];
2572   const char* const_ptr;
2573
2574   if (id == 0)
2575     return "KERNEL";
2576   if (id == ~0ULL)
2577     return "BROADCAST";
2578
2579   snprintf (buf, sizeof (buf), "%llu", (unsigned long long)id);
2580
2581   const_ptr = buf;
2582   return const_ptr;
2583 }
2584 #endif
2585 #endif
2586
2587 static dbus_uint32_t
2588 get_next_client_serial (DBusTransportKdbus *transport)
2589 {
2590   dbus_uint32_t serial;
2591
2592   serial = transport->client_serial++;
2593
2594   if (transport->client_serial == 0)
2595     transport->client_serial = 1;
2596
2597   return serial;
2598 }
2599
2600 /**
2601  * Calculates length of the kdbus message content (payload).
2602  *
2603  * @param msg kdbus message
2604  * @return the length of the kdbus message's payload.
2605  */
2606 static int
2607 kdbus_message_size (const struct kdbus_msg *msg,
2608                     int                    *n_fds)
2609 {
2610   const struct kdbus_item *item;
2611   int ret_size = 0;
2612
2613   *n_fds = 0;
2614   KDBUS_ITEM_FOREACH (item, msg, items)
2615     {
2616       if (item->size < KDBUS_ITEM_HEADER_SIZE)
2617         {
2618           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2619           return -1;
2620         }
2621       switch (item->type)
2622         {
2623           case KDBUS_ITEM_PAYLOAD_OFF:
2624             ret_size += item->vec.size;
2625             break;
2626           case KDBUS_ITEM_PAYLOAD_MEMFD:
2627             ret_size += item->memfd.size;
2628             break;
2629           case KDBUS_ITEM_FDS:
2630             *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof (int);
2631             break;
2632           default:
2633             break;
2634         }
2635     }
2636
2637   return ret_size;
2638 }
2639
2640 static int
2641 generate_NameSignal (const char         *signal,
2642                      const char         *name,
2643                      DBusTransportKdbus *transport)
2644 {
2645   DBusMessage *message;
2646
2647   _dbus_verbose ("Generating %s for %s.\n", signal, name);
2648
2649   message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, signal);
2650   if (message == NULL)
2651     return -1;
2652
2653   if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
2654     goto error;
2655   if (!dbus_message_set_destination (message, transport->my_DBus_unique_name))
2656     goto error;
2657   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
2658     goto error;
2659   dbus_message_set_serial (message, get_next_client_serial (transport));
2660
2661   if (!add_message_to_received (message, transport->base.connection))
2662     return -1;
2663
2664   return 0;
2665
2666   error:
2667     dbus_message_unref (message);
2668     return -1;
2669 }
2670
2671 /*
2672  * The NameOwnerChanged signals take three parameters with
2673  * unique or well-known names, but only some forms actually
2674  * exist:
2675  *
2676  * WELLKNOWN, "", UNIQUE       â†’ KDBUS_ITEM_NAME_ADD
2677  * WELLKNOWN, UNIQUE, ""       â†’ KDBUS_ITEM_NAME_REMOVE
2678  * WELLKNOWN, UNIQUE, UNIQUE   â†’ KDBUS_ITEM_NAME_CHANGE
2679  * UNIQUE, "", UNIQUE          â†’ KDBUS_ITEM_ID_ADD
2680  * UNIQUE, UNIQUE, ""          â†’ KDBUS_ITEM_ID_REMOVE
2681  *
2682  * For the latter two the two unique names must be identical.
2683  */
2684 static int
2685 kdbus_handle_name_owner_changed (__u64               type,
2686                                  const char         *bus_name,
2687                                  __u64               old,
2688                                  __u64               new,
2689                                  DBusTransportKdbus *transport)
2690 {
2691   DBusMessage *message = NULL;
2692   DBusMessageIter args;
2693   char tmp_str[128];
2694   const char *const_ptr;
2695
2696   if ((message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) == NULL)
2697     return -1;
2698
2699   dbus_message_iter_init_append (message, &args);
2700
2701   // for ID_ADD and ID_REMOVE this function takes NULL as bus_name
2702   if (bus_name == NULL)
2703     {
2704       snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old != 0 ? old : new);
2705       const_ptr = tmp_str;
2706     }
2707   else
2708     const_ptr = bus_name;
2709
2710   if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2711     goto error;
2712
2713   _dbus_verbose ("%s\n", const_ptr);
2714
2715
2716   if ((old==0) && (new==0))
2717     {
2718       /* kdbus generates its own set of events that can not be passed to
2719        * client without translation. */
2720       const char *src = "org.freedesktop.DBus";
2721       const char *dst = "org.freedesktop.DBus";
2722
2723       if (type == KDBUS_ITEM_NAME_ADD || type == KDBUS_ITEM_ID_ADD)
2724         src = "";
2725       else if (type == KDBUS_ITEM_NAME_REMOVE || type == KDBUS_ITEM_ID_REMOVE)
2726         dst = "";
2727
2728       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &src))
2729         goto error;
2730       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &dst))
2731         goto error;
2732
2733       _dbus_verbose ("[NameOwnerChanged:%s, old=%lld, new=%lld\n", __func__, old, new);
2734     }
2735   else
2736     {
2737       // determine and append old_id
2738       if (old != 0)
2739       {
2740         snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old);
2741         const_ptr = tmp_str;
2742       }
2743       else
2744         const_ptr = "";
2745
2746       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2747         goto error;
2748
2749       _dbus_verbose ("%s\n", const_ptr);
2750       // determine and append new_id
2751       if (new != 0)
2752       {
2753         snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", new);
2754         const_ptr = tmp_str;
2755       }
2756       else
2757         const_ptr = "";
2758
2759       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2760         goto error;
2761
2762       _dbus_verbose ("%s\n", const_ptr);
2763     }
2764
2765   dbus_message_set_sender (message, DBUS_SERVICE_DBUS);
2766   dbus_message_set_serial (message, get_next_client_serial (transport));
2767
2768   if (!add_message_to_received (message, transport->base.connection))
2769     return -1;
2770
2771   return 0;
2772
2773 error:
2774   dbus_message_unref (message);
2775
2776   return -1;
2777 }
2778
2779 static void
2780 handle_item_timestamp (const struct kdbus_item *item)
2781 {
2782 #if KDBUS_MSG_DECODE_DEBUG == 1
2783   _dbus_verbose ("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
2784                 enum_MSG (item->type), item->size,
2785                 (unsigned long long)item->timestamp.realtime_ns,
2786                 (unsigned long long)item->timestamp.monotonic_ns);
2787 #endif
2788 }
2789
2790 static void
2791 handle_unexpected_item (const struct kdbus_item *item)
2792 {
2793   _dbus_assert_not_reached ("unexpected item from kdbus");
2794 }
2795
2796 static void
2797 handle_padding (const struct kdbus_msg *msg,
2798                  const struct kdbus_item *end_of_items)
2799 {
2800 #if KDBUS_MSG_DECODE_DEBUG == 1
2801   if ((char *)end_of_items - ((char *)msg + msg->size) >= 8)
2802     _dbus_verbose ("invalid padding at end of message\n");
2803 #endif
2804 }
2805
2806 #ifdef LIBDBUSPOLICY
2807 static dbus_bool_t
2808 load_dbus_header (DBusTransportKdbus *transport,
2809                   DBusHeader         *header,
2810                   const char         *message_data,
2811                   dbus_uint32_t       message_len)
2812 {
2813   DBusValidity validity = DBUS_VALID;
2814   DBusString message;
2815   dbus_uint32_t fields_array_len_unsigned;
2816   dbus_uint32_t body_len_unsigned;
2817   int i;
2818
2819   if (0 == message_len)
2820     return FALSE;
2821
2822   _dbus_string_init_const_len (&message, message_data, message_len);
2823   _dbus_gvariant_raw_get_lengths (&message,
2824                                   &fields_array_len_unsigned,
2825                                   &body_len_unsigned,
2826                                   &validity);
2827
2828   _dbus_string_init_const_len (&header->data,
2829                                message_data,
2830                                fields_array_len_unsigned + FIRST_GVARIANT_FIELD_OFFSET);
2831
2832   header->padding = 0;
2833   header->byte_order = message_data[0];
2834   header->protocol_version = DBUS_PROTOCOL_VERSION_GVARIANT;
2835   for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
2836     header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
2837
2838   return _dbus_header_load_gvariant (header, &validity);
2839 }
2840 #endif
2841
2842 static dbus_bool_t
2843 can_receive (DBusTransportKdbus     *transport,
2844              const struct kdbus_msg *msg,
2845              const char             *message_data,
2846              dbus_uint32_t           message_len)
2847 {
2848   dbus_bool_t result = TRUE;
2849
2850 #ifdef LIBDBUSPOLICY
2851   if (transport->policy)
2852   {
2853     DBusHeader header;
2854     dbus_bool_t got_header = FALSE;
2855     dbus_bool_t got_creds = FALSE;
2856     dbus_bool_t got_seclabel = FALSE;
2857
2858     if (KDBUS_PAYLOAD_DBUS == msg->payload_type)
2859       {
2860         const struct kdbus_item *item;
2861         uid_t sender_euid = -1;
2862         gid_t sender_egid = -1;
2863         const char *seclabel = NULL;
2864         DBusString names;
2865
2866         result = FALSE;
2867
2868         _dbus_string_init (&names);
2869
2870         KDBUS_ITEM_FOREACH(item, msg, items)
2871           switch (item->type)
2872             {
2873               case KDBUS_ITEM_CREDS:
2874                 sender_euid = (uid_t) item->creds.euid;
2875                 sender_egid = (gid_t) item->creds.egid;
2876                 got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1);
2877                 break;
2878               case KDBUS_ITEM_SECLABEL:
2879                 seclabel = item->str;
2880                 got_seclabel = (seclabel != NULL);
2881                 break;
2882               case KDBUS_ITEM_OWNED_NAME:
2883                 {
2884                   DBusString name;
2885                   _dbus_string_init_const (&name, item->name.name);
2886                   if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))
2887                     {
2888                       if (_dbus_string_get_length (&names) != 0)
2889                         _dbus_string_append_byte (&names, ' ');
2890
2891                       _dbus_string_copy (&name,
2892                                          0,
2893                                          &names,
2894                                          _dbus_string_get_length (&names));
2895                     }
2896                 }
2897                 break;
2898               default:
2899                 break; /* ignore all other items */
2900             }
2901
2902         if (NULL != message_data && message_len > 0)
2903           {
2904             if (load_dbus_header (transport, &header, message_data, message_len))
2905               got_header = TRUE;
2906           }
2907         if (got_header &&
2908             _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL &&
2909             _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_SIGNAL)
2910           {
2911             result = TRUE;
2912           }
2913         else if (got_header && got_creds && got_seclabel)
2914           {
2915             const char *destination = NULL;
2916             const char *path = NULL;
2917             const char *interface = NULL;
2918             const char *member = NULL;
2919             const char *error_name = NULL;
2920             dbus_uint64_t reply_cookie = 0;
2921             dbus_bool_t requested_reply = FALSE;
2922             int ret;
2923
2924             _dbus_header_get_field_basic (&header,
2925                                           DBUS_HEADER_FIELD_DESTINATION,
2926                                           DBUS_TYPE_STRING,
2927                                           &destination);
2928             if (!destination)
2929                destination = transport->my_DBus_unique_name;
2930
2931             _dbus_header_get_field_basic (&header,
2932                                           DBUS_HEADER_FIELD_PATH,
2933                                           DBUS_TYPE_STRING,
2934                                           &path);
2935
2936             _dbus_header_get_field_basic (&header,
2937                                           DBUS_HEADER_FIELD_INTERFACE,
2938                                           DBUS_TYPE_STRING,
2939                                           &interface);
2940
2941             _dbus_header_get_field_basic (&header,
2942                                           DBUS_HEADER_FIELD_MEMBER,
2943                                           DBUS_TYPE_STRING,
2944                                           &member);
2945
2946             _dbus_header_get_field_basic (&header,
2947                                           DBUS_HEADER_FIELD_ERROR_NAME,
2948                                           DBUS_TYPE_STRING,
2949                                           &error_name);
2950
2951             _dbus_header_get_field_basic (&header,
2952                                           DBUS_HEADER_FIELD_REPLY_SERIAL,
2953                                           DBUS_TYPE_UINT64,
2954                                           &reply_cookie);
2955
2956             requested_reply = !(_dbus_header_get_flag (&header,
2957                                                        DBUS_HEADER_FLAG_NO_REPLY_EXPECTED));
2958
2959             ret = dbuspolicy1_check_in (transport->policy,
2960                                         destination,
2961                                         _dbus_string_get_length (&names) > 0 ?
2962                                           _dbus_string_get_const_data (&names) :
2963                                           NULL,
2964                                         seclabel,
2965                                         sender_euid,
2966                                         sender_egid,
2967                                         path,
2968                                         interface,
2969                                         member,
2970                                         _dbus_header_get_message_type (&header),
2971                                         error_name,
2972                                         reply_cookie,
2973                                         requested_reply);
2974             result = (1 == ret);
2975           }
2976
2977         _dbus_string_free (&names);
2978       }
2979   }
2980 #endif
2981
2982   return result;
2983 }
2984
2985 static int
2986 kdbus_decode_dbus_message (const struct kdbus_msg *msg,
2987                            char                   *data,
2988                            DBusTransportKdbus     *kdbus_transport,
2989                            int                    *fds,
2990                            int                    *n_fds)
2991 {
2992   const struct kdbus_item *item;
2993   int ret_size = 0;
2994   char *buffer = data;
2995
2996   *n_fds = 0;
2997
2998   KDBUS_ITEM_FOREACH (item, msg, items)
2999     {
3000       if (item->size < KDBUS_ITEM_HEADER_SIZE)
3001         {
3002           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
3003           ret_size = -1;
3004           break;
3005         }
3006
3007       switch (item->type)
3008         {
3009           case KDBUS_ITEM_PAYLOAD_OFF:
3010             memcpy (data, (char *)msg+item->vec.offset, item->vec.size);
3011             data += item->vec.size;
3012             ret_size += item->vec.size;
3013
3014 #ifdef DBUS_ENABLE_VERBOSE_MODE
3015             if (-1 != debug)
3016               {
3017                 debug_c_str ("Message part arrived:", (char *)msg+item->vec.offset, item->vec.size);
3018               }
3019 #endif
3020
3021             _dbus_verbose ("  +%s (%llu bytes) off=%llu size=%llu\n",
3022                 enum_MSG (item->type), item->size,
3023                 (unsigned long long)item->vec.offset,
3024                 (unsigned long long)item->vec.size);
3025             break;
3026
3027           case KDBUS_ITEM_PAYLOAD_MEMFD:
3028             {
3029               char *buf;
3030               uint64_t size;
3031
3032               size = item->memfd.size;
3033               _dbus_verbose ("memfd.size : %llu\n", (unsigned long long)size);
3034
3035               buf = mmap (NULL, size, PROT_READ, MAP_PRIVATE, item->memfd.fd, 0);
3036               if (buf == MAP_FAILED)
3037                 {
3038                   _dbus_verbose ("mmap () fd=%i failed:%m", item->memfd.fd);
3039                   return -1;
3040                 }
3041
3042               memcpy (data, buf, size);
3043               data += size;
3044               ret_size += size;
3045
3046               munmap (buf, size);
3047               close (item->memfd.fd);
3048
3049               _dbus_verbose ("  +%s (%llu bytes) off=%llu size=%llu\n",
3050                   enum_MSG (item->type), item->size,
3051                   (unsigned long long)item->vec.offset,
3052                   (unsigned long long)item->vec.size);
3053             }
3054             break;
3055
3056           case KDBUS_ITEM_FDS:
3057             {
3058               int i;
3059
3060               *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof (int);
3061               memcpy (fds, item->fds, *n_fds * sizeof (int));
3062               for (i = 0; i < *n_fds; i++)
3063                 _dbus_fd_set_close_on_exec (fds[i]);
3064             }
3065             break;
3066
3067           case KDBUS_ITEM_CREDS:
3068 #if KDBUS_MSG_DECODE_DEBUG == 1
3069             _dbus_verbose ("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
3070                           enum_MSG (item->type), item->size,
3071                           item->creds.uid, item->creds.gid,
3072                           item->creds.pid, item->creds.tid,
3073                           item->creds.starttime);
3074 #endif
3075             break;
3076
3077           case KDBUS_ITEM_PID_COMM:
3078           case KDBUS_ITEM_TID_COMM:
3079           case KDBUS_ITEM_EXE:
3080           case KDBUS_ITEM_CGROUP:
3081           case KDBUS_ITEM_SECLABEL:
3082           case KDBUS_ITEM_DST_NAME:
3083 #if KDBUS_MSG_DECODE_DEBUG == 1
3084             _dbus_verbose ("  +%s (%llu bytes) '%s' (%zu)\n",
3085                           enum_MSG (item->type), item->size, item->str, strlen (item->str));
3086 #endif
3087             break;
3088
3089           case KDBUS_ITEM_CMDLINE:
3090           case KDBUS_ITEM_NAME:
3091 #if KDBUS_MSG_DECODE_DEBUG == 1
3092             {
3093               __u64 size = item->size - KDBUS_ITEM_HEADER_SIZE;
3094               const char *str = item->str;
3095               int count = 0;
3096
3097               _dbus_verbose ("  +%s (%llu bytes) ", enum_MSG (item->type), item->size);
3098               while (size)
3099               {
3100                 _dbus_verbose ("'%s' ", str);
3101                 size -= strlen (str) + 1;
3102                 str += strlen (str) + 1;
3103                 count++;
3104               }
3105
3106               _dbus_verbose ("(%d string%s)\n", count, (count == 1) ? "" : "s");
3107             }
3108 #endif
3109             break;
3110
3111           case KDBUS_ITEM_AUDIT:
3112 #if KDBUS_MSG_DECODE_DEBUG == 1
3113             _dbus_verbose ("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
3114                           enum_MSG (item->type), item->size,
3115                           (unsigned long long)item->data64[0],
3116                           (unsigned long long)item->data64[1]);
3117 #endif
3118             break;
3119
3120           case KDBUS_ITEM_CAPS:
3121 #if KDBUS_MSG_DECODE_DEBUG == 1
3122             {
3123               int n;
3124               const uint32_t *cap;
3125               int i;
3126
3127               _dbus_verbose ("  +%s (%llu bytes) len=%llu bytes)\n",
3128                   enum_MSG (item->type), item->size,
3129                   (unsigned long long)item->size - KDBUS_ITEM_HEADER_SIZE);
3130
3131               cap = item->data32;
3132               n = (item->size - KDBUS_ITEM_HEADER_SIZE) / 4 / sizeof (uint32_t);
3133
3134               _dbus_verbose ("    CapInh=");
3135               for (i = 0; i < n; i++)
3136                 _dbus_verbose ("%08x", cap[(0 * n) + (n - i - 1)]);
3137
3138               _dbus_verbose (" CapPrm=");
3139               for (i = 0; i < n; i++)
3140                 _dbus_verbose ("%08x", cap[(1 * n) + (n - i - 1)]);
3141
3142               _dbus_verbose (" CapEff=");
3143               for (i = 0; i < n; i++)
3144                 _dbus_verbose ("%08x", cap[(2 * n) + (n - i - 1)]);
3145
3146               _dbus_verbose (" CapInh=");
3147               for (i = 0; i < n; i++)
3148                 _dbus_verbose ("%08x", cap[(3 * n) + (n - i - 1)]);
3149               _dbus_verbose ("\n");
3150             }
3151 #endif
3152             break;
3153
3154           case KDBUS_ITEM_TIMESTAMP:
3155             handle_item_timestamp (item);
3156             break;
3157
3158           case KDBUS_ITEM_BLOOM_FILTER:
3159             /* no handling */
3160             break;
3161
3162           default:
3163             handle_unexpected_item (item);
3164             break;
3165         }
3166     }
3167
3168   handle_padding (msg, item);
3169
3170   if (!can_receive (kdbus_transport, msg, buffer, ret_size))
3171     return 0;   /* ignore message if not allowed */
3172
3173   return ret_size;
3174 }
3175
3176 static int
3177 kdbus_decode_kernel_message (const struct kdbus_msg *msg,
3178                              DBusTransportKdbus     *kdbus_transport)
3179 {
3180   const struct kdbus_item *item;
3181   int ret_size = 0;
3182
3183   KDBUS_ITEM_FOREACH (item, msg, items)
3184     {
3185       if (item->size < KDBUS_ITEM_HEADER_SIZE)
3186         {
3187           _dbus_verbose ("  +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
3188           ret_size = -1;
3189           break;
3190         }
3191
3192       switch (item->type)
3193         {
3194           case KDBUS_ITEM_REPLY_TIMEOUT:
3195           case KDBUS_ITEM_REPLY_DEAD:
3196             _dbus_verbose ("  +%s (%llu bytes) cookie=%llu\n",
3197                           enum_MSG (item->type), item->size, msg->cookie_reply);
3198             break;
3199
3200           case KDBUS_ITEM_NAME_ADD:
3201           case KDBUS_ITEM_NAME_REMOVE:
3202           case KDBUS_ITEM_NAME_CHANGE:
3203             {
3204               int local_ret;
3205
3206               _dbus_verbose ("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n",
3207                              enum_MSG (item->type), (unsigned long long) item->size,
3208                              item->name_change.name, item->name_change.old_id.id,
3209                              item->name_change.new_id.id, item->name_change.old_id.flags,
3210                              item->name_change.new_id.flags);
3211
3212               if (item->name_change.new_id.id == _kdbus_get_id (kdbus_transport->kdbus))
3213                 ret_size = generate_NameSignal ("NameAcquired", item->name_change.name, kdbus_transport);
3214               else if (item->name_change.old_id.id == _kdbus_get_id (kdbus_transport->kdbus))
3215                 ret_size = generate_NameSignal ("NameLost", item->name_change.name, kdbus_transport);
3216
3217               if (ret_size == -1)
3218                 goto out;
3219
3220               if (item->name_change.new_id.flags & KDBUS_NAME_ACTIVATOR)
3221                 local_ret = kdbus_handle_name_owner_changed (item->type,
3222                                                              item->name_change.name,
3223                                                              item->name_change.old_id.id, 0,
3224                                                              kdbus_transport);
3225               else if (item->name_change.old_id.flags & KDBUS_NAME_ACTIVATOR)
3226                 local_ret = kdbus_handle_name_owner_changed (item->type,
3227                                                              item->name_change.name, 0,
3228                                                              item->name_change.new_id.id,
3229                                                              kdbus_transport);
3230               else
3231                 local_ret = kdbus_handle_name_owner_changed (item->type,
3232                                                              item->name_change.name,
3233                                                              item->name_change.old_id.id,
3234                                                              item->name_change.new_id.id,
3235                                                              kdbus_transport);
3236               if (local_ret == -1)
3237                 goto out;
3238
3239               ret_size += local_ret;
3240             }
3241             break;
3242
3243           case KDBUS_ITEM_ID_ADD:
3244           case KDBUS_ITEM_ID_REMOVE:
3245             _dbus_verbose ("  +%s (%llu bytes) id=%llu flags=%llu\n",
3246                           enum_MSG (item->type), (unsigned long long) item->size,
3247                           (unsigned long long) item->id_change.id,
3248                           (unsigned long long) item->id_change.flags);
3249
3250             if (item->id_change.flags & KDBUS_HELLO_ACTIVATOR)
3251               ret_size = kdbus_handle_name_owner_changed (item->type, NULL, 0, 0,
3252                                                           kdbus_transport);
3253             else
3254               ret_size = kdbus_handle_name_owner_changed (item->type, NULL,
3255                                                           item->type == KDBUS_ITEM_ID_ADD ? 0 : item->id_change.id,
3256                                                           item->type == KDBUS_ITEM_ID_ADD ? item->id_change.id : 0,
3257                                                           kdbus_transport);
3258
3259             if (ret_size == -1)
3260               goto out;
3261             break;
3262
3263           case KDBUS_ITEM_TIMESTAMP:
3264             handle_item_timestamp (item);
3265             break;
3266
3267           default:
3268             handle_unexpected_item (item);
3269             break;
3270         }
3271     }
3272
3273   handle_padding (msg, item);
3274
3275 out:
3276   return ret_size;
3277 }
3278
3279 /**
3280  * Decodes kdbus message in order to extract DBus message and puts it into received data buffer
3281  * and file descriptor's buffer. Also captures kdbus error messages and kdbus kernel broadcasts
3282  * and converts all of them into appropriate DBus messages.
3283  *
3284  * @param msg kdbus message
3285  * @param data place to copy DBus message to
3286  * @param kdbus_transport transport
3287  * @param fds place to store file descriptors received
3288  * @param n_fds place to store quantity of file descriptors received
3289  * @return number of DBus message's bytes received or -1 on error
3290  */
3291 static int
3292 kdbus_decode_msg (const struct kdbus_msg *msg,
3293                   char                   *data,
3294                   DBusTransportKdbus     *kdbus_transport,
3295                   int                    *fds,
3296                   int                    *n_fds,
3297                   DBusError              *error)
3298 {
3299   int ret_size = 0;
3300
3301 #if KDBUS_MSG_DECODE_DEBUG == 1
3302   _dbus_verbose ("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
3303                 enum_PAYLOAD (msg->payload_type),
3304                 (unsigned long long) msg->size,
3305                 (unsigned long long) msg->flags,
3306                 msg_id (msg->src_id),
3307                 msg_id (msg->dst_id),
3308                 (unsigned long long) msg->cookie,
3309                 (unsigned long long) msg->timeout_ns);
3310 #endif
3311
3312   switch (msg->payload_type)
3313     {
3314       case KDBUS_PAYLOAD_DBUS:
3315         ret_size = kdbus_decode_dbus_message (msg, data, kdbus_transport, fds, n_fds);
3316         break;
3317       case KDBUS_PAYLOAD_KERNEL:
3318         ret_size = kdbus_decode_kernel_message (msg, kdbus_transport);
3319         break;
3320       default:
3321         _dbus_assert_not_reached ("unexpected payload type from kdbus");
3322         break;
3323     }
3324
3325   return ret_size;
3326 }
3327
3328 /**
3329  * Reads message from kdbus and puts it into DBus buffers
3330  *
3331  * @param kdbus_transport transport
3332  * @param buffer place to copy received message to
3333  * @param fds place to store file descriptors received with the message
3334  * @param n_fds place to store quantity of file descriptors received
3335  * @return size of received message on success, -1 on error
3336  */
3337 static int
3338 kdbus_read_message (DBusTransportKdbus *kdbus_transport,
3339                     DBusString         *buffer,
3340                     int                *fds,
3341                     int                *n_fds)
3342 {
3343   int ret_size, buf_size;
3344   struct kdbus_msg *msg;
3345   char *data;
3346   int start;
3347   dbus_uint64_t flags = 0;
3348   int ret;
3349   DBusError error;
3350
3351   dbus_error_init (&error);
3352
3353   start = _dbus_string_get_length (buffer);
3354
3355   if (kdbus_transport->activator != NULL)
3356     flags |= KDBUS_RECV_PEEK;
3357
3358   ret = _kdbus_recv (kdbus_transport->kdbus, flags, 0, &msg);
3359
3360   if (0 != ret)
3361     {
3362       _dbus_verbose ("kdbus error receiving message: %d (%s)\n", ret, _dbus_strerror (ret));
3363       return -1;
3364     }
3365
3366   buf_size = kdbus_message_size (msg, n_fds);
3367   if (buf_size == -1)
3368     {
3369       _dbus_verbose ("kdbus error - too short message: %d (%m)\n", errno);
3370       return -1;
3371     }
3372
3373   /* What is the maximum size of the locally generated message?
3374      I just assume 2048 bytes */
3375   buf_size = MAX (buf_size, 2048);
3376
3377   if (!_dbus_string_lengthen (buffer, buf_size))
3378     {
3379       errno = ENOMEM;
3380       return -1;
3381     }
3382   data = _dbus_string_get_data_len (buffer, start, buf_size);
3383
3384   ret_size = kdbus_decode_msg (msg, data, kdbus_transport, fds, n_fds, &error);
3385
3386   if (ret_size == -1) /* error */
3387     _dbus_string_set_length (buffer, start);
3388   else if (ret_size >= 0 && buf_size != ret_size) /* case of locally generated message */
3389     _dbus_string_set_length (buffer, start + ret_size);
3390
3391   if (ret_size >= 0)
3392     _dbus_message_loader_set_unique_sender_id (kdbus_transport->base.loader, msg->src_id);
3393
3394   if (kdbus_transport->activator != NULL)
3395     return ret_size;
3396
3397   ret = _kdbus_free_mem (kdbus_transport->kdbus, msg);
3398   if (0 != ret)
3399   {
3400     _dbus_verbose ("kdbus error freeing message: %d (%s)\n", ret, _dbus_strerror (ret));
3401     return -1;
3402   }
3403
3404   return ret_size;
3405 }
3406
3407 static DBusMessage *
3408 kdbus_send_sync_call (DBusTransportKdbus  *transport,
3409                       DBusMessage         *message)
3410 {
3411   DBusMessage *reply = NULL;
3412   DBusError error;
3413   const char *destination;
3414
3415   dbus_message_lock (message);
3416
3417   destination = dbus_message_get_destination (message);
3418   if (destination)
3419     {
3420       int ret;
3421
3422       ret = capture_org_freedesktop_DBus ((DBusTransportKdbus*)transport, destination, message, &reply);
3423       if (ret < 0)
3424         goto error;
3425       else if (ret == 0)
3426         goto out;
3427     }
3428
3429   kdbus_write_msg_internal (transport, message, destination, &reply, TRUE);
3430   if (reply == NULL)
3431     goto error;
3432   else
3433     goto out;
3434
3435 error:
3436
3437   dbus_error_init (&error);
3438
3439   dbus_set_error (&error, DBUS_ERROR_FAILED,
3440                   "Something went wrong");
3441
3442   reply = reply_with_error ((char*)error.name,
3443                             NULL,
3444                             error.message,
3445                             message);
3446
3447   dbus_error_free (&error);
3448
3449 out:
3450
3451   _dbus_assert (reply != NULL);
3452   dbus_message_lock (reply);
3453
3454   return reply;
3455 }
3456
3457 /**
3458  * Copy-paste from socket transport. Only renames done.
3459  */
3460 static void
3461 free_watches (DBusTransportKdbus *kdbus_transport)
3462 {
3463   DBusConnection *connection = kdbus_transport->base.connection;
3464   _dbus_verbose ("start\n");
3465
3466   if (kdbus_transport->read_watch)
3467     {
3468       if (connection)
3469         _dbus_connection_remove_watch_unlocked (connection,
3470                                                 kdbus_transport->read_watch);
3471       _dbus_watch_invalidate (kdbus_transport->read_watch);
3472       _dbus_watch_unref (kdbus_transport->read_watch);
3473       kdbus_transport->read_watch = NULL;
3474     }
3475
3476   if (kdbus_transport->write_watch)
3477     {
3478       if (connection)
3479         _dbus_connection_remove_watch_unlocked (connection,
3480                                                 kdbus_transport->write_watch);
3481       _dbus_watch_invalidate (kdbus_transport->write_watch);
3482       _dbus_watch_unref (kdbus_transport->write_watch);
3483       kdbus_transport->write_watch = NULL;
3484     }
3485
3486   _dbus_verbose ("end\n");
3487 }
3488
3489 static void
3490 free_policies (DBusTransportKdbus *transport)
3491 {
3492 #ifdef LIBDBUSPOLICY
3493   if (NULL != transport->policy)
3494     dbuspolicy1_free (transport->policy);
3495 #endif
3496 }
3497
3498 /**
3499  * Copy-paste from socket transport. Only done needed renames and removed
3500  * lines related to encoded messages.
3501  */
3502 static void
3503 transport_finalize (DBusTransport *transport)
3504 {
3505   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus *)transport;
3506   _dbus_verbose ("\n");
3507
3508   free_watches (kdbus_transport);
3509
3510   _dbus_transport_finalize_base (transport);
3511
3512   _dbus_assert (kdbus_transport->read_watch == NULL);
3513   _dbus_assert (kdbus_transport->write_watch == NULL);
3514
3515   free_matchmaker (kdbus_transport->matchmaker);
3516
3517   dbus_free (kdbus_transport->activator);
3518
3519   free_policies ( kdbus_transport );
3520
3521   _kdbus_free (kdbus_transport->kdbus);
3522   free (kdbus_transport->my_DBus_unique_name);
3523
3524   dbus_free (transport);
3525 }
3526
3527 /**
3528  * Copy-paste from socket transport. Removed code related to authentication,
3529  * socket_transport replaced by kdbus_transport.
3530  */
3531 static void
3532 check_write_watch (DBusTransportKdbus *kdbus_transport)
3533 {
3534   dbus_bool_t needed;
3535   DBusTransport *transport = &kdbus_transport->base;
3536
3537   if (transport->connection == NULL)
3538     return;
3539
3540   if (transport->disconnected)
3541     {
3542       _dbus_assert (kdbus_transport->write_watch == NULL);
3543       return;
3544     }
3545
3546   _dbus_transport_ref (transport);
3547
3548   needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
3549
3550   _dbus_verbose ("check_write_watch (): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
3551                  needed, transport->connection, kdbus_transport->write_watch,
3552                  _kdbus_get_fd (kdbus_transport->kdbus),
3553                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3554
3555   _dbus_connection_toggle_watch_unlocked (transport->connection,
3556                                           kdbus_transport->write_watch,
3557                                           needed);
3558
3559   _dbus_transport_unref (transport);
3560 }
3561
3562 /**
3563  * Copy-paste from socket transport. Removed code related to authentication,
3564  * socket_transport replaced by kdbus_transport.
3565  */
3566 static void
3567 check_read_watch (DBusTransportKdbus *kdbus_transport)
3568 {
3569   dbus_bool_t need_read_watch;
3570   DBusTransport *transport = &kdbus_transport->base;
3571
3572   _dbus_verbose ("fd = %d\n",_kdbus_get_fd (kdbus_transport->kdbus));
3573
3574   if (transport->connection == NULL)
3575     return;
3576
3577   if (transport->disconnected)
3578     {
3579       _dbus_assert (kdbus_transport->read_watch == NULL);
3580       return;
3581     }
3582
3583   _dbus_transport_ref (transport);
3584
3585    need_read_watch =
3586       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
3587       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
3588
3589   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
3590
3591   _dbus_connection_toggle_watch_unlocked (transport->connection,
3592                                           kdbus_transport->read_watch,
3593                                           need_read_watch);
3594
3595   _dbus_transport_unref (transport);
3596 }
3597
3598 /**
3599  * Copy-paste from socket transport.
3600  */
3601 static void
3602 do_io_error (DBusTransport *transport)
3603 {
3604   _dbus_transport_ref (transport);
3605   _dbus_transport_disconnect (transport);
3606   _dbus_transport_unref (transport);
3607 }
3608
3609 /**
3610  *  Based on do_writing from socket transport.
3611  *  Removed authentication code and code related to encoded messages
3612  *  and adapted to kdbus transport.
3613  *  In socket transport returns false on out-of-memory. Here this won't happen,
3614  *  so it always returns TRUE.
3615  */
3616 static dbus_bool_t
3617 do_writing (DBusTransport *transport)
3618 {
3619   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3620   int total = 0;
3621   dbus_bool_t oom = FALSE;
3622
3623   if (transport->disconnected)
3624     {
3625       _dbus_verbose ("Not connected, not writing anything\n");
3626       return TRUE;
3627     }
3628
3629   _dbus_verbose ("do_writing (), have_messages = %d, fd = %d\n",
3630                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
3631                  _kdbus_get_fd (kdbus_transport->kdbus));
3632
3633   while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
3634     {
3635       int bytes_written;
3636       DBusMessage *message;
3637       DBusMessage *reply;
3638       const DBusString *header;
3639       const DBusString *body;
3640       const char* pDestination;
3641
3642       if (total > kdbus_transport->max_bytes_written_per_iteration)
3643         {
3644           _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
3645                          total, kdbus_transport->max_bytes_written_per_iteration);
3646           goto out;
3647         }
3648
3649       reply = NULL;
3650       message = _dbus_connection_get_message_to_send (transport->connection);
3651       _dbus_assert (message != NULL);
3652       pDestination = dbus_message_get_destination (message);
3653
3654       if (pDestination)
3655         {
3656           int ret;
3657
3658           ret = capture_org_freedesktop_DBus ((DBusTransportKdbus*)transport, pDestination, message, &reply);
3659           if (ret < 0)  //error
3660             {
3661               bytes_written = -1;
3662               goto written;
3663             }
3664           else if (ret == 0)  //message captured and handled correctly
3665             {
3666               /* puts locally generated reply into received messages queue */
3667               if (!add_message_to_received (reply, kdbus_transport->base.connection))
3668                 {
3669                   bytes_written = -1;
3670                   goto written;
3671                 }
3672
3673               _dbus_message_get_network_data (message, &header, &body);
3674               bytes_written = _dbus_string_get_length (header) + _dbus_string_get_length (body);
3675               goto written;
3676             }
3677           //else send as regular message
3678         }
3679
3680       bytes_written = kdbus_write_msg (kdbus_transport, message, pDestination);
3681
3682       written:
3683       if (bytes_written < 0)
3684         {
3685           if (errno == ENOMEM)
3686             {
3687               oom = TRUE;
3688               goto out;
3689             }
3690
3691           /* EINTR already handled for us */
3692
3693           /* For some discussion of why we also ignore EPIPE here, see
3694            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
3695            */
3696
3697           if (_dbus_get_is_errno_eagain_or_ewouldblock (errno) || _dbus_get_is_errno_epipe (errno))
3698             goto out;
3699           else
3700             {
3701               _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
3702               do_io_error (transport);
3703               goto out;
3704             }
3705         }
3706       else
3707         {
3708 #if defined (DBUS_ENABLE_VERBOSE_MODE) || !defined (DBUS_DISABLE_ASSERT)
3709           int total_bytes_to_write;
3710
3711           _dbus_message_get_network_data (message, &header, &body);
3712           total_bytes_to_write = _dbus_string_get_length (header)
3713                                    + _dbus_string_get_length (body);
3714           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
3715                          total_bytes_to_write);
3716
3717           _dbus_assert (bytes_written == total_bytes_to_write);
3718 #endif
3719           total += bytes_written;
3720
3721           _dbus_connection_message_sent_unlocked (transport->connection,
3722                   message);
3723         }
3724     }
3725
3726 out:
3727   if (oom)
3728     return FALSE;
3729   else
3730     return TRUE;
3731 }
3732
3733 /**
3734  *  Based on do_reading from socket transport.
3735  *  Removed authentication code and code related to encoded messages
3736  *  and adapted to kdbus transport.
3737  *  returns false on out-of-memory
3738  */
3739 static dbus_bool_t
3740 do_reading (DBusTransport *transport)
3741 {
3742   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3743   DBusString *buffer;
3744   int bytes_read;
3745   dbus_bool_t oom = FALSE;
3746   int *fds, n_fds;
3747   int total = 0;
3748
3749   _dbus_verbose ("fd = %d\n", _kdbus_get_fd (kdbus_transport->kdbus));
3750
3751  again:
3752
3753   /* See if we've exceeded max messages and need to disable reading */
3754   if (kdbus_transport->activator == NULL)
3755     check_read_watch (kdbus_transport);
3756
3757   if (total > kdbus_transport->max_bytes_read_per_iteration)
3758     {
3759       _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
3760                      total, kdbus_transport->max_bytes_read_per_iteration);
3761       goto out;
3762     }
3763
3764   _dbus_assert (kdbus_transport->read_watch != NULL ||
3765                 transport->disconnected);
3766
3767   if (transport->disconnected)
3768     goto out;
3769
3770   if (!dbus_watch_get_enabled (kdbus_transport->read_watch))
3771     return TRUE;
3772
3773   if (!_dbus_message_loader_get_unix_fds (transport->loader, &fds, &n_fds))
3774   {
3775       _dbus_verbose ("Out of memory reading file descriptors\n");
3776       oom = TRUE;
3777       goto out;
3778   }
3779   _dbus_message_loader_get_buffer (transport->loader, &buffer);
3780
3781   bytes_read = kdbus_read_message (kdbus_transport, buffer, fds, &n_fds);
3782
3783   if (bytes_read >= 0 && n_fds > 0)
3784     _dbus_verbose ("Read %i unix fds\n", n_fds);
3785
3786   _dbus_message_loader_return_buffer (transport->loader,
3787                                       buffer);
3788   _dbus_message_loader_return_unix_fds (transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
3789
3790   if (bytes_read < 0)
3791     {
3792       /* EINTR already handled for us */
3793
3794       if (_dbus_get_is_errno_enomem (errno))
3795         {
3796           _dbus_verbose ("Out of memory in read()/do_reading()\n");
3797           oom = TRUE;
3798           goto out;
3799         }
3800       else if (_dbus_get_is_errno_eagain_or_ewouldblock (errno))
3801         goto out;
3802       else
3803         {
3804           _dbus_verbose ("Error reading from remote app: %s\n",
3805                          _dbus_strerror_from_errno ());
3806           do_io_error (transport);
3807           goto out;
3808         }
3809     }
3810   else if (bytes_read > 0)
3811     {
3812       _dbus_verbose (" read %d bytes\n", bytes_read);
3813
3814       total += bytes_read;
3815
3816       if (!_dbus_transport_queue_messages (transport))
3817         {
3818           oom = TRUE;
3819           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
3820           goto out;
3821         }
3822
3823       /* Try reading more data until we get EAGAIN and return, or
3824        * exceed max bytes per iteration.  If in blocking mode of
3825        * course we'll block instead of returning.
3826        */
3827       goto again;
3828     }
3829   /* 0 == bytes_read is for kernel and ignored messages */
3830
3831  out:
3832   if (oom)
3833     return FALSE;
3834   return TRUE;
3835 }
3836
3837 /**
3838  * Copy-paste from socket transport, with socket replaced by kdbus.
3839  */
3840 static dbus_bool_t
3841 unix_error_with_read_to_come (DBusTransport *itransport,
3842                               DBusWatch     *watch,
3843                               unsigned int   flags)
3844 {
3845    DBusTransportKdbus *transport = (DBusTransportKdbus *) itransport;
3846
3847    if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
3848       return FALSE;
3849
3850   /* If we have a read watch enabled ...
3851      we -might have data incoming ... => handle the HANGUP there */
3852    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
3853       return FALSE;
3854
3855    return TRUE;
3856 }
3857
3858 /**
3859  *  Copy-paste from socket transport. Removed authentication related code
3860  *  and renamed socket_transport to kdbus_transport.
3861  */
3862 static dbus_bool_t
3863 kdbus_handle_watch (DBusTransport *transport,
3864                     DBusWatch     *watch,
3865                     unsigned int   flags)
3866 {
3867   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3868
3869   _dbus_assert (watch == kdbus_transport->read_watch ||
3870                 watch == kdbus_transport->write_watch);
3871   _dbus_assert (watch != NULL);
3872
3873   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
3874    * still be in the buffer and do_reading may need several iteration to read
3875    * it all (because of its max_bytes_read_per_iteration limit).
3876    */
3877   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
3878     {
3879       _dbus_verbose ("Hang up or error on watch\n");
3880       _dbus_transport_disconnect (transport);
3881       return TRUE;
3882     }
3883
3884   if (watch == kdbus_transport->read_watch &&
3885       (flags & DBUS_WATCH_READABLE))
3886     {
3887       _dbus_verbose ("handling read watch %p flags = %x\n",
3888                      watch, flags);
3889
3890       if (!do_reading (transport))
3891         {
3892           _dbus_verbose ("no memory to read\n");
3893           return FALSE;
3894         }
3895     }
3896   else if (watch == kdbus_transport->write_watch &&
3897           (flags & DBUS_WATCH_WRITABLE))
3898     {
3899       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
3900                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3901
3902       if (!do_writing (transport))
3903         {
3904           _dbus_verbose ("no memory to write\n");
3905           return FALSE;
3906         }
3907
3908       /* See if we still need the write watch */
3909       check_write_watch (kdbus_transport);
3910     }
3911
3912   return TRUE;
3913 }
3914
3915 /**
3916  * Copy-paste from socket transport, but socket_transport renamed to kdbus_transport
3917  * and _dbus_close_socket replaced with close ().
3918  */
3919 static void
3920 kdbus_disconnect (DBusTransport *transport)
3921 {
3922   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3923
3924   _dbus_verbose ("\n");
3925
3926   free_watches (kdbus_transport);
3927
3928   _kdbus_close (kdbus_transport->kdbus);
3929 }
3930
3931 /**
3932  *  Copy-paste from socket transport. Renamed socket_transport to
3933  *  kdbus_transport and added setting authenticated to TRUE, because
3934  *  we do not perform authentication in kdbus, so we have mark is as already done
3935  *  to make everything work.
3936  */
3937 static dbus_bool_t
3938 kdbus_connection_set (DBusTransport *transport)
3939 {
3940   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3941
3942   _dbus_watch_set_handler (kdbus_transport->write_watch,
3943                            _dbus_connection_handle_watch,
3944                            transport->connection, NULL);
3945
3946   _dbus_watch_set_handler (kdbus_transport->read_watch,
3947                            _dbus_connection_handle_watch,
3948                            transport->connection, NULL);
3949
3950   if (!_dbus_connection_add_watch_unlocked (transport->connection,
3951                                             kdbus_transport->write_watch))
3952     return FALSE;
3953
3954   if (!_dbus_connection_add_watch_unlocked (transport->connection,
3955                                             kdbus_transport->read_watch))
3956     {
3957       _dbus_connection_remove_watch_unlocked (transport->connection,
3958                                               kdbus_transport->write_watch);
3959       return FALSE;
3960     }
3961
3962   check_read_watch (kdbus_transport);
3963   check_write_watch (kdbus_transport);
3964
3965   return TRUE;
3966 }
3967
3968 /**
3969  *  Copy-paste from socket_transport.
3970  *  Socket_transport renamed to kdbus_transport
3971  *
3972  *   Original dbus copy-pasted @todo comment below.
3973  * @todo We need to have a way to wake up the select sleep if
3974  * a new iteration request comes in with a flag (read/write) that
3975  * we're not currently serving. Otherwise a call that just reads
3976  * could block a write call forever (if there are no incoming
3977  * messages).
3978  */
3979 static void
3980 kdbus_do_iteration (DBusTransport *transport,
3981                    unsigned int   flags,
3982                    int            timeout_milliseconds)
3983 {
3984   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3985   DBusPollFD poll_fd;
3986   int poll_res;
3987   int poll_timeout;
3988
3989   _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
3990                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
3991                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
3992                  timeout_milliseconds,
3993                  kdbus_transport->read_watch,
3994                  kdbus_transport->write_watch,
3995                  _kdbus_get_fd (kdbus_transport->kdbus));
3996
3997    poll_fd.fd = _kdbus_get_fd (kdbus_transport->kdbus);
3998    poll_fd.events = 0;
3999
4000    /*
4001     * TODO test this.
4002     * This fix is for reply_with_error function.
4003     * When timeout is set to -1 in client application,
4004     * error messages are inserted directly to incoming queue and
4005     * application hangs on dbus_poll.
4006     *
4007     * This causes a busy loop in _dbus_connection_block_pending_call() 
4008     * There is no case of waiting for the locally-generated error reply
4009
4010    if (_dbus_connection_get_n_incoming (transport->connection) > 0)
4011    {
4012      timeout_milliseconds = 0;
4013    }
4014     */
4015
4016    /* This is kind of a hack; if we have stuff to write, then try
4017     * to avoid the poll. This is probably about a 5% speedup on an
4018     * echo client/server.
4019     *
4020     * If both reading and writing were requested, we want to avoid this
4021     * since it could have funky effects:
4022     *   - both ends spinning waiting for the other one to read
4023     *     data so they can finish writing
4024     *   - prioritizing all writing ahead of reading
4025     */
4026    if ((flags & DBUS_ITERATION_DO_WRITING) &&
4027        !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
4028        !transport->disconnected &&
4029        _dbus_connection_has_messages_to_send_unlocked (transport->connection))
4030      {
4031        do_writing (transport);
4032
4033        if (transport->disconnected ||
4034            !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
4035          goto out;
4036      }
4037
4038    /* If we get here, we decided to do the poll() after all */
4039    _dbus_assert (kdbus_transport->read_watch);
4040    if (flags & DBUS_ITERATION_DO_READING)
4041      poll_fd.events |= _DBUS_POLLIN;
4042
4043    _dbus_assert (kdbus_transport->write_watch);
4044    if (flags & DBUS_ITERATION_DO_WRITING)
4045      poll_fd.events |= _DBUS_POLLOUT;
4046
4047    if (poll_fd.events)
4048    {
4049       if ( (flags & DBUS_ITERATION_BLOCK) && !(flags & DBUS_ITERATION_DO_WRITING))
4050         poll_timeout = timeout_milliseconds;
4051       else
4052         poll_timeout = 0;
4053
4054       /* For blocking selects we drop the connection lock here
4055        * to avoid blocking out connection access during a potentially
4056        * indefinite blocking call. The io path is still protected
4057        * by the io_path_cond condvar, so we won't reenter this.
4058        */
4059       if (flags & DBUS_ITERATION_BLOCK)
4060       {
4061          _dbus_verbose ("unlock pre poll\n");
4062          _dbus_connection_unlock (transport->connection);
4063       }
4064
4065     again:
4066       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
4067
4068       if (poll_res < 0 && _dbus_get_is_errno_eintr (errno))
4069         goto again;
4070
4071       if (flags & DBUS_ITERATION_BLOCK)
4072       {
4073          _dbus_verbose ("lock post poll\n");
4074          _dbus_connection_lock (transport->connection);
4075       }
4076
4077       if (poll_res >= 0)
4078       {
4079          if (poll_res == 0)
4080             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
4081                                   * valgrind flags it as an error. though it probably
4082                                   * is guaranteed on linux at least.
4083                                   */
4084
4085          if (poll_fd.revents & _DBUS_POLLERR)
4086             do_io_error (transport);
4087          else
4088          {
4089             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
4090
4091             _dbus_verbose ("in iteration, need_read=%d\n",
4092                              need_read);
4093
4094             if (need_read && (flags & DBUS_ITERATION_DO_READING))
4095                do_reading (transport);
4096             /* We always be able to write to kdbus */
4097             if (flags & DBUS_ITERATION_DO_WRITING)
4098                do_writing (transport);
4099          }
4100       }
4101       else
4102          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
4103    }
4104
4105  out:
4106   /* We need to install the write watch only if we did not
4107    * successfully write everything. Note we need to be careful that we
4108    * don't call check_write_watch *before* do_writing, since it's
4109    * inefficient to add the write watch, and we can avoid it most of
4110    * the time since we can write immediately.
4111    *
4112    * However, we MUST always call check_write_watch(); DBusConnection code
4113    * relies on the fact that running an iteration will notice that
4114    * messages are pending.
4115    */
4116    check_write_watch (kdbus_transport);
4117
4118    _dbus_verbose (" ... leaving do_iteration()\n");
4119 }
4120
4121 /**
4122  * Copy-paste from socket transport.
4123  */
4124 static void
4125 kdbus_live_messages_changed (DBusTransport *transport)
4126 {
4127   /* See if we should look for incoming messages again */
4128   check_read_watch ((DBusTransportKdbus *)transport);
4129 }
4130
4131 /**
4132  * Gets file descriptor of the kdbus bus.
4133  * @param transport transport
4134  * @param fd_p place to write fd to
4135  * @returns always TRUE
4136  */
4137 static dbus_bool_t
4138 kdbus_get_kdbus_fd (DBusTransport *transport,
4139                     DBusSocket    *fd_p)
4140 {
4141   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
4142
4143   fd_p->fd = _kdbus_get_fd (kdbus_transport->kdbus);
4144
4145   return TRUE;
4146 }
4147
4148 static const DBusTransportVTable kdbus_vtable = {
4149   transport_finalize,
4150   kdbus_handle_watch,
4151   kdbus_disconnect,
4152   kdbus_connection_set,
4153   kdbus_do_iteration,
4154   kdbus_live_messages_changed,
4155   kdbus_get_kdbus_fd
4156 };
4157
4158 typedef unsigned long (*ConnectionInfoExtractField) (struct nameInfo *);
4159
4160 static inline unsigned long
4161 _extract_name_info_userId (struct nameInfo *nameInfo)
4162 {
4163   return nameInfo->userId;
4164 }
4165
4166 static inline unsigned long
4167 _extract_name_info_processId (struct nameInfo *nameInfo)
4168 {
4169   return nameInfo->processId;
4170 }
4171
4172 static dbus_bool_t
4173 _dbus_transport_kdbus_get_connection_info_ulong_field (DBusTransportKdbus         *transport,
4174                                                        ConnectionInfoExtractField  function,
4175                                                        unsigned long              *val)
4176 {
4177   struct nameInfo conn_info;
4178   int ret;
4179
4180   ret = _kdbus_connection_info_by_id (transport->kdbus,
4181                                       _kdbus_get_id (transport->kdbus),
4182                                       FALSE,
4183                                       &conn_info);
4184   if (ret != 0)
4185     return FALSE;
4186
4187   *val = function (&conn_info);
4188   return TRUE;
4189 }
4190
4191 static dbus_bool_t
4192 _dbus_transport_kdbus_get_unix_user (DBusTransport *transport,
4193                                      unsigned long *uid)
4194 {
4195   return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
4196                                                                 _extract_name_info_userId,
4197                                                                 uid);
4198 }
4199
4200 static dbus_bool_t
4201 _dbus_transport_kdbus_get_unix_process_id (DBusTransport *transport,
4202                                            unsigned long *pid)
4203 {
4204   return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
4205                                                                 _extract_name_info_processId,
4206                                                                 pid);
4207 }
4208
4209 /**
4210  * Copy-paste from dbus_transport_socket with needed changes.
4211  *
4212  * Creates a new transport for the given kdbus file descriptor and address.
4213  * The file descriptor must be nonblocking.
4214  *
4215  * @param fd the file descriptor.
4216  * @param address the transport's address
4217  * @returns the new transport, or #NULL if no memory.
4218  */
4219 static DBusTransportKdbus *
4220 new_kdbus_transport (kdbus_t          *kdbus,
4221                      const DBusString *address,
4222                      const char       *activator)
4223 {
4224   DBusTransportKdbus *kdbus_transport;
4225
4226   kdbus_transport = dbus_new0 (DBusTransportKdbus, 1);
4227   if (kdbus_transport == NULL)
4228     return NULL;
4229
4230   kdbus_transport->kdbus = kdbus;
4231
4232   kdbus_transport->write_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
4233                                                  DBUS_WATCH_WRITABLE,
4234                                                  FALSE,
4235                                                  NULL, NULL, NULL);
4236   if (kdbus_transport->write_watch == NULL)
4237     goto failed_2;
4238
4239   kdbus_transport->read_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
4240                                                 DBUS_WATCH_READABLE,
4241                                                 FALSE,
4242                                                 NULL, NULL, NULL);
4243   if (kdbus_transport->read_watch == NULL)
4244     goto failed_3;
4245
4246   if (!_dbus_transport_init_base_authenticated (&kdbus_transport->base,
4247                                                 &kdbus_vtable,
4248                                                 NULL, address))
4249     goto failed_4;
4250
4251   _dbus_transport_set_get_unix_user_function (&kdbus_transport->base,
4252                                               _dbus_transport_kdbus_get_unix_user);
4253   _dbus_transport_set_get_unix_process_id_function (&kdbus_transport->base,
4254                                                     _dbus_transport_kdbus_get_unix_process_id);
4255 #ifdef ENABLE_KDBUS_SYNC_CALLS
4256   _dbus_transport_set_send_sync_call_function (&kdbus_transport->base,
4257                                                (DBusTransportSendSyncCallFunction) kdbus_send_sync_call);
4258 #endif
4259   _dbus_transport_set_assure_protocol_function (&kdbus_transport->base,
4260                                                 _dbus_message_assure_gvariant,
4261                                                 DBUS_PROTOCOL_VERSION_GVARIANT);
4262
4263   /* These values should probably be tunable or something. */
4264   kdbus_transport->max_bytes_read_per_iteration = MAX_BYTES_PER_ITERATION;
4265   kdbus_transport->max_bytes_written_per_iteration = MAX_BYTES_PER_ITERATION;
4266
4267   if (activator!=NULL)
4268     {
4269       kdbus_transport->activator = _dbus_strdup (activator);
4270       if (kdbus_transport->activator == NULL)
4271         goto failed_4;
4272     }
4273
4274   kdbus_transport->matchmaker = matchmaker_new ();
4275
4276   kdbus_transport->client_serial = 1;
4277
4278   return kdbus_transport;
4279
4280  failed_4:
4281   _dbus_watch_invalidate (kdbus_transport->read_watch);
4282   _dbus_watch_unref (kdbus_transport->read_watch);
4283  failed_3:
4284   _dbus_watch_invalidate (kdbus_transport->write_watch);
4285   _dbus_watch_unref (kdbus_transport->write_watch);
4286  failed_2:
4287   dbus_free (kdbus_transport);
4288   return NULL;
4289 }
4290
4291 /**
4292  * Connects to kdbus, creates and sets-up transport.
4293  *
4294  * @param path the path to the bus.
4295  * @param error address where an error can be returned.
4296  * @returns a new transport, or #NULL on failure.
4297  */
4298 static DBusTransport*
4299 _dbus_transport_new_for_kdbus (const char *path,
4300                                const char *activator,
4301                                DBusError  *error)
4302 {
4303   int ret;
4304   DBusTransportKdbus *transport;
4305   DBusString address;
4306   kdbus_t *kdbus;
4307 #ifdef LIBDBUSPOLICY
4308   void *policy;
4309 #endif
4310
4311 #ifdef DBUS_ENABLE_VERBOSE_MODE
4312   const char *dbgenv = _dbus_getenv ("G_DBUS_DEBUG");
4313   if (dbgenv != NULL)
4314   {
4315     if (!strcmp (dbgenv, "message"))
4316       debug = 1;
4317     else if (!strcmp (dbgenv, "all"))
4318       debug = 2;
4319   }
4320 #endif
4321
4322   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4323
4324   if (!_dbus_string_init (&address))
4325     {
4326       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4327       return NULL;
4328     }
4329
4330   if ((!_dbus_string_append (&address, DBUS_ADDRESS_KDBUS "path=")) || (!_dbus_string_append (&address, path)))
4331     {
4332       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4333       goto failed_0;
4334     }
4335
4336   kdbus = _kdbus_new ();
4337   if (NULL == kdbus)
4338     {
4339       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4340       goto failed_0;
4341     }
4342
4343 #ifdef LIBDBUSPOLICY
4344   policy = dbuspolicy1_init (path);
4345   if (NULL == policy)
4346     {
4347       dbus_set_error (error,
4348                       DBUS_ERROR_NO_REPLY,
4349                       "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.");
4350       goto failed_0_with_kdbus;
4351     }
4352 #endif
4353
4354   ret = _kdbus_open (kdbus, path);
4355   if (ret < 0)
4356     {
4357       dbus_set_error (error,
4358                       _dbus_error_from_errno (-ret),
4359                       "Failed to open file descriptor: %s: %s",
4360                       path,
4361                       _dbus_strerror (-ret));
4362       goto failed_0_with_kdbus_and_policy;
4363     }
4364
4365   _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
4366
4367   transport = new_kdbus_transport (kdbus, &address, activator);
4368   if (transport == NULL)
4369     {
4370       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4371       goto failed_1;
4372     }
4373 #ifdef LIBDBUSPOLICY
4374   transport->policy = policy;
4375 #endif
4376
4377   _dbus_string_free (&address);
4378
4379   return (DBusTransport*)transport;
4380
4381 failed_1:
4382   _kdbus_close (kdbus);
4383 failed_0_with_kdbus_and_policy:
4384 #ifdef LIBDBUSPOLICY
4385   dbuspolicy1_free (policy);
4386 #endif
4387 failed_0_with_kdbus:
4388   _kdbus_free (kdbus);
4389 failed_0:
4390   _dbus_string_free (&address);
4391   return NULL;
4392 }
4393
4394
4395 /**
4396  * Opens kdbus transport if method from address entry is kdbus
4397  *
4398  * @param entry the address entry to open
4399  * @param transport_p return location for the opened transport
4400  * @param error place to store error
4401  * @returns result of the attempt as a DBusTransportOpenResult enum
4402  */
4403 DBusTransportOpenResult
4404 _dbus_transport_open_kdbus (DBusAddressEntry  *entry,
4405                             DBusTransport    **transport_p,
4406                             DBusError         *error)
4407 {
4408   const char *method;
4409
4410   method = dbus_address_entry_get_method (entry);
4411   _dbus_assert (method != NULL);
4412
4413   if (strcmp (method, "kernel") == 0)
4414     {
4415       const char *path = dbus_address_entry_get_value (entry, "path");
4416       const char *activator = dbus_address_entry_get_value (entry, "activator");
4417
4418       if (path == NULL)
4419         {
4420           _dbus_set_bad_address (error, "kdbus", "path", NULL);
4421           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
4422         }
4423
4424       *transport_p = _dbus_transport_new_for_kdbus (path, activator, error);
4425
4426       if (*transport_p == NULL)
4427         {
4428           _DBUS_ASSERT_ERROR_IS_SET (error);
4429           return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
4430         }
4431       else
4432         {
4433           _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4434           return DBUS_TRANSPORT_OPEN_OK;
4435         }
4436     }
4437   else
4438     {
4439       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4440       return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
4441     }
4442 }
4443
4444 /** @} */