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