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