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