1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport-kdbus.c kdbus subclasses of DBusTransport
4 * Copyright (C) 2002, 2003, 2004, 2006 Red Hat Inc
5 * Copyright (C) 2013 Samsung Electronics
7 * Licensed under the Academic Free License version 2.1
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.
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.
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
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"
36 #include "dbus-watch.h"
37 #include "dbus-errors.h"
39 #include "kdbus-common.h"
40 #include "dbus-protocol-gvariant.h"
41 #include <linux/types.h>
49 #include <sys/syscall.h>
52 #include <dbuspolicy/libdbuspolicy1.h>
53 #include "dbus-marshal-header.h"
54 #include "dbus-protocol-gvariant.h"
56 #include "dbus-sysdeps-unix.h"
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
65 # error "Architecture not supported"
68 # include <linux/memfd.h>
71 #ifdef DBUS_ENABLE_VERBOSE_MODE
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
81 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
82 #define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
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 */
91 #define MFD_CLOEXEC 0x0001U
94 #ifndef MFD_ALLOW_SEALING
95 #define MFD_ALLOW_SEALING 0x0002U
98 /* ALIGN8 and KDBUS_FOREACH taken from systemd */
99 #define ALIGN8(l) (((l) + 7) & ~7)
100 #define KDBUS_FOREACH(iter, first, _size) \
101 for (iter = (first); \
102 ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \
103 ((uint8_t *)(iter) >= (uint8_t *)(first)); \
104 iter = (void*)(((uint8_t *)iter) + ALIGN8((iter)->size)))
105 #define KDBUS_DEFAULT_TIMEOUT_NS 5000000000LU
108 * @defgroup DBusTransportKdbus DBusTransport implementations for kdbus
109 * @ingroup DBusInternals
110 * @brief Implementation details of DBusTransport on kdbus
115 /** Default Size of the memory area for received non-memfd messages. */
116 #define RECEIVE_POOL_SIZE_DEFAULT_SIZE (2 * 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
124 /** Over this memfd is used to send (if it is not broadcast). */
125 #define MEMFD_SIZE_THRESHOLD (512 * 1024LU)
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.
132 #define MAX_BYTES_PER_ITERATION 16384
134 #if (MEMFD_SIZE_THRESHOLD > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE)
135 #error Memfd size threshold higher than max kdbus message payload vector size
138 /** Enables verbosing more information about kdbus message.
139 * Works only if DBUS_VERBOSE=1 is used.
141 #define KDBUS_MSG_DECODE_DEBUG 0
144 * Opaque object representing a transport.
146 typedef struct DBusTransportKdbus DBusTransportKdbus;
149 * Implementation details of DBusTransportKdbus. All members are private.
151 struct DBusTransportKdbus
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. */
158 int max_bytes_read_per_iteration; /**< To avoid blocking too long. */
159 int max_bytes_written_per_iteration; /**< To avoid blocking too long. */
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*/
171 * Creates unique name string frong unique id.
173 * @param id unique id
174 * @returns allocated string with unique name
176 * Caller has to free allocated string with free.
179 create_unique_name_from_unique_id (unsigned long long id)
182 if (asprintf (&str, ":1.%llu", id) == -1)
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
194 add_message_to_received (DBusMessage *message,
195 DBusConnection *connection)
197 DBusList *message_link;
199 message_link = _dbus_list_alloc_link (message);
200 if (message_link == NULL)
202 dbus_message_unref (message);
206 dbus_message_lock (message);
208 _dbus_connection_queue_synthesized_message_link (connection, message_link);
213 reply_with_error_preset_sender (const char *error_type,
214 const char *template,
216 DBusMessage *message,
219 DBusMessage *errMessage;
220 char* error_msg = "";
224 size_t len = strlen (template) + strlen (object) + 1;
225 error_msg = alloca (len);
226 snprintf (error_msg, len, template, object);
229 error_msg = (char*)object;
231 errMessage = _dbus_generate_local_error_message ( dbus_message_get_serial (message),
235 if (errMessage == NULL)
239 dbus_message_set_sender (errMessage, sender);
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
257 reply_with_error (const char *error_type,
258 const char *template,
260 DBusMessage *message)
262 return reply_with_error_preset_sender (error_type, template,
263 object, message, NULL);
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
275 reply_1_data (DBusMessage *message,
279 DBusMessageIter args;
282 reply = dbus_message_new_method_return (message);
286 if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
289 dbus_message_iter_init_append (reply, &args);
290 if (!dbus_message_iter_append_basic (&args, data_type, pData))
296 dbus_message_unref (reply);
302 reply_fixed_array (DBusMessage *message,
307 DBusMessageIter args, array_iter;
310 reply = dbus_message_new_method_return (message);
314 if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
317 dbus_message_iter_init_append (reply, &args);
319 if (!dbus_message_iter_open_container (&args,
321 DBUS_TYPE_BYTE_AS_STRING,
325 if (!dbus_message_iter_append_fixed_array (&array_iter, element_type, &data, n_elements))
328 if (!dbus_message_iter_close_container (&args, &array_iter))
334 dbus_message_iter_abandon_container (&args, &array_iter);
337 dbus_message_unref (reply);
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
349 kdbus_acquire_memfd ( void )
353 /* FIXME add HAVE_MEMFD_CREATE */
354 if ((fd = syscall (__NR_memfd_create, "kdbus", MFD_ALLOW_SEALING | MFD_CLOEXEC )) < 0)
356 _dbus_verbose ("memfd_create failed (%d): %m\n", fd);
359 _dbus_verbose ("%s: memfd=%d\n", __FUNCTION__, fd);
364 bloom_add_pair (kdbus_bloom_data_t *bloom_data,
366 const char *parameter,
375 size = strlen (parameter) + strlen (value) + 1;
379 snprintf (buf, size, "%s:%s", parameter, value);
380 _kdbus_bloom_add_data (kdbus, bloom_data, buf, size);
384 bloom_add_prefixes (kdbus_bloom_data_t *bloom_data,
386 const char *parameter,
393 size = strlen (parameter) + strlen (value) + 1;
397 snprintf (buf, size, "%s:%s", parameter, value);
402 last_sep = strrchr (buf, separator);
403 if (!last_sep || last_sep == buf)
407 _kdbus_bloom_add_data (kdbus, bloom_data, buf, last_sep-buf);
412 setup_bloom_filter_for_message (DBusMessage *msg,
414 struct kdbus_bloom_filter *bloom_filter)
416 kdbus_bloom_data_t *bloom_data;
419 DBusMessageIter args;
422 _dbus_assert (bloom_filter);
424 bloom_data = _kdbus_bloom_filter_get_data (bloom_filter);
426 bloom_add_pair (bloom_data,
429 dbus_message_type_to_string (dbus_message_get_type (msg)));
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);
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, '/');
441 if (!dbus_message_iter_init (msg, &args))
444 for (i = 0; i < 64; i++)
447 char buf[sizeof ("arg")-1 + 2 + sizeof ("-slash-prefix")];
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)
457 dbus_message_iter_get_basic (&args, &str);
459 snprintf (buf, sizeof (buf), "arg%d", i);
461 bloom_add_pair (bloom_data, kdbus, buf, str);
463 /* point e to end of string, we will add suffixes */
466 /* we need remaining length of the buffer */
467 len = sizeof (buf) - len;
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, '/');
474 if (!dbus_message_iter_next (&args))
482 * Checks if a string is a unique name or well known name.
484 * @param name a valid D-Bus name
485 * @returns 0 for well-known names, otherwise unique id
488 parse_name (const char *name)
490 dbus_uint64_t unique_id = 0;
492 /* if name is unique name it must be converted to unique id */
493 if (strncmp (name, ":1.", 3) == 0)
496 unique_id = strtoull (&name[3], &endptr, 10);
498 if (unique_id == 0 || *endptr != '\0' || errno == ERANGE)
506 prepare_mfd (int memfd,
508 uint64_t header_size,
512 const char *data[] = { header, body };
513 uint64_t count[] = { header_size, body_size };
517 _dbus_verbose ("sending data via memfd\n");
518 for (p = 0; p < sizeof (data) / sizeof (data[0]); ++p)
522 wr = write (memfd, data[p], count[p]);
525 _dbus_verbose ("writing to memfd failed: (%d) %m\n", errno);
533 // seal data - kdbus module needs it
534 if (fcntl (memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) < 0)
536 _dbus_verbose ("memfd sealing failed: %d (%m)\n", errno);
543 send_message (DBusTransportKdbus *transport,
544 struct kdbus_msg *kdbus_msg,
546 const char *destination,
547 dbus_bool_t is_auto_start,
548 struct kdbus_msg **kdbus_msg_reply,
552 dbus_uint64_t flags = 0;
555 flags |= KDBUS_SEND_SYNC_REPLY;
557 ret = _kdbus_send (transport->kdbus,
563 _dbus_verbose ("kdbus error sending message: err %d (%s)\n", ret, _dbus_strerror (ret) );
567 case ENXIO: /* no such id on the bus */
569 dbus_set_error (error,
570 DBUS_ERROR_NAME_HAS_NO_OWNER,
571 "Name \"%s\" does not exist",
577 /* when well known name is not available on the bus */
579 dbus_set_error (error,
580 DBUS_ERROR_SERVICE_UNKNOWN,
581 "The name %s was not provided by any .service files",
584 dbus_set_error (error,
585 DBUS_ERROR_NAME_HAS_NO_OWNER,
586 "Name \"%s\" does not exist",
591 dbus_set_error (error,
592 DBUS_ERROR_LIMITS_EXCEEDED,
594 "The maximum number of pending replies per connection has been reached");
599 dbus_set_error (error,
600 DBUS_ERROR_LIMITS_EXCEEDED,
601 "No space in receiver's buffer",
615 kdbus_close_message (DBusTransportKdbus *transport, struct kdbus_msg *msg)
617 struct kdbus_item *item;
619 KDBUS_ITEM_FOREACH (item, msg, items)
621 if (item->type == KDBUS_ITEM_PAYLOAD_MEMFD)
622 close (item->memfd.fd);
625 _kdbus_free_mem (transport->kdbus, msg);
628 #ifdef DBUS_ENABLE_VERBOSE_MODE
630 debug_c_str (const char *msg, const char *str, int len)
633 fprintf (stderr, "%s\n", msg);
634 for (i = 0; i < len; i++)
636 fprintf (stderr, "%02x ", (unsigned char)str[i]);
637 if (i%16==15) fprintf (stderr, "\n");
639 fprintf (stderr, "\n");
643 debug_str (const char *msg, const DBusString *str)
645 debug_c_str (msg, _dbus_string_get_const_data (str), _dbus_string_get_length (str));
650 can_send (DBusTransportKdbus *transport,
651 DBusMessage *message)
653 dbus_bool_t result = TRUE;
658 if (NULL != transport->policy)
660 dbus_uint32_t reply_serial = dbus_message_get_reply_serial (message);
662 /* If reply_serial is non-zero, then it is a reply - just send it.
663 * Otherwise - check the policy.
665 if (0 == reply_serial)
666 ret = dbuspolicy1_check_out (transport->policy,
667 dbus_message_get_destination (message),
668 dbus_message_get_sender (message),
669 dbus_message_get_path (message),
670 dbus_message_get_interface (message),
671 dbus_message_get_member (message),
672 dbus_message_get_type (message),
673 dbus_message_get_error_name (message),
675 !dbus_message_get_no_reply (message));
685 kdbus_write_msg_internal (DBusTransportKdbus *transport,
686 DBusMessage *message,
687 const char *destination,
688 dbus_bool_t check_sync_reply,
689 dbus_bool_t check_privileges)
691 struct kdbus_msg *msg = NULL;
692 struct kdbus_msg *msg_reply = NULL;
693 struct kdbus_item *item;
694 uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
695 const DBusString *header;
696 const DBusString *body;
697 int64_t ret_size = -1;
698 uint64_t body_size = 0;
699 uint64_t header_size = 0;
705 dbus_uint64_t items_size;
706 dbus_uint64_t flags = 0;
707 dbus_uint64_t timeout_ns_or_cookie_reply = 0;
710 dbus_error_init (&error);
712 // determine destination and destination id
717 _dbus_string_init_const (&str, destination);
718 if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
720 _dbus_verbose ("error: unique name is not valid: %s\n", destination);
724 dst_id = parse_name (destination);
728 dst_id = KDBUS_DST_ID_NAME; /* OK, this is zero anyway
729 * but leave it in case
730 * the kdbus constant changes
734 _dbus_message_get_network_data (message, &header, &body);
735 header_size = _dbus_string_get_length (header);
736 body_size = _dbus_string_get_length (body);
737 ret_size = header_size + body_size;
739 /* check whether we can and should use memfd */
740 if ((dst_id != KDBUS_DST_ID_BROADCAST) && (ret_size > MEMFD_SIZE_THRESHOLD))
741 memfd = kdbus_acquire_memfd ();
743 _dbus_message_get_unix_fds (message, &unix_fds, &fds_count);
745 items_size = _kdbus_compute_msg_items_size (transport->kdbus,
752 if (!dbus_message_get_auto_start (message))
753 flags |= KDBUS_MSG_NO_AUTO_START;
755 if (KDBUS_DST_ID_BROADCAST == dst_id) /* signals */
756 flags |= KDBUS_MSG_SIGNAL;
759 if (dbus_message_get_no_reply (message)) /* method replies and errors */
760 timeout_ns_or_cookie_reply = dbus_message_get_reply_serial (message);
761 else /* method calls */
763 long tv_sec, tv_usec;
765 _dbus_get_monotonic_time (&tv_sec, &tv_usec);
767 timeout_ns_or_cookie_reply = (dbus_uint64_t)tv_sec * 1000ULL * 1000ULL * 1000ULL
769 + KDBUS_DEFAULT_TIMEOUT_NS;
771 flags |= KDBUS_MSG_EXPECT_REPLY;
775 msg = _kdbus_new_msg (transport->kdbus,
782 dbus_message_get_serial (message),
783 timeout_ns_or_cookie_reply);
787 /* build message contents */
792 if (prepare_mfd (memfd,
793 _dbus_string_get_const_data (header), header_size,
794 _dbus_string_get_const_data (body), body_size) == -1)
800 item = _kdbus_item_add_payload_memfd (item,
807 const char* header_data = _dbus_string_get_const_data (header);
809 _dbus_verbose ("sending data by vec\n");
810 item = _kdbus_item_add_payload_vec (item,
812 (uintptr_t)header_data);
815 const char* body_data = _dbus_string_get_const_data (body);
817 #ifdef DBUS_ENABLE_VERBOSE_MODE
820 debug_str ("Header to send:", header);
821 debug_str ("Body to send:", body);
825 while (body_size > 0)
827 dbus_uint64_t part_size = body_size;
829 if (part_size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE)
830 part_size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
832 _dbus_verbose ("attaching body part\n");
833 item = _kdbus_item_add_payload_vec (item,
835 (uintptr_t)body_data);
836 body_data += part_size;
837 body_size -= part_size;
843 item = _kdbus_item_add_fds (item, unix_fds, fds_count);
845 if (NULL != destination)
846 item = _kdbus_item_add_string (item,
849 strlen (destination) + 1);
850 else if (dst_id == KDBUS_DST_ID_BROADCAST)
852 struct kdbus_bloom_filter *filter = NULL;
853 item = _kdbus_item_add_bloom_filter (item,
856 setup_bloom_filter_for_message (message, transport->kdbus, filter);
859 if (check_privileges && !can_send (transport, message))
863 reply = reply_with_error (DBUS_ERROR_ACCESS_DENIED,
865 "Cannot send message - message rejected "
866 "due to security policies",
874 /* puts locally generated reply into received messages queue */
875 if (!add_message_to_received (reply, transport->base.connection))
882 if (send_message (transport,
885 dbus_message_get_destination (message),
886 dbus_message_get_auto_start (message),
890 DBusMessage *reply = NULL;
892 if (dbus_error_is_set (&error))
894 reply = reply_with_error (error.name,
906 /* puts locally generated reply into received messages queue */
907 if (!add_message_to_received (reply, transport->base.connection))
912 if (-1 != ret_size && check_sync_reply)
913 kdbus_close_message (transport, msg_reply);
917 _kdbus_free_msg (msg);
925 * Sends DBus message using kdbus.
926 * Handles broadcasts and unicast messages, and passing of Unix fds.
927 * Also can locally generate error replies on some error returned by kernel.
929 * TODO refactor to be more compact - maybe we can send header always as a payload vector
930 * and only message body as memfd if needed.
932 * @param transport Transport.
933 * @param message DBus message to be sent
934 * @param destination Destination of the message.
935 * @returns bytes sent or -1 if sending failed
938 kdbus_write_msg (DBusTransportKdbus *transport,
939 DBusMessage *message,
940 const char *destination)
942 return kdbus_write_msg_internal (transport, message, destination, FALSE, TRUE);
948 dbus_uint64_t receive_pool_size = RECEIVE_POOL_SIZE_DEFAULT_SIZE;
949 const char *env_pool;
951 env_pool = _dbus_getenv (RECEIVE_POOL_SIZE_ENV_VAR_NAME);
954 dbus_uint64_t size = 0;
955 unsigned int multiply = 1;
958 page_size = sysconf (_SC_PAGESIZE);
965 size = strtoul (env_pool, (char**)&env_pool, 10);
966 if ((errno == EINVAL) || size == 0)
972 if (*env_pool == 'k')
977 else if (*env_pool == 'M')
979 multiply = 1024 * 1024;
983 if (*env_pool != '\0')
989 receive_pool_size = size * multiply;
991 if ((receive_pool_size > RECEIVE_POOL_SIZE_MAX_MBYTES * 1024 * 1024) ||
992 (receive_pool_size < RECEIVE_POOL_SIZE_MIN_KBYTES * 1024) ||
993 ((receive_pool_size & (page_size - 1)) != 0)) //pool size must be aligned to page size
999 _dbus_warn ("%s value is invalid, default value %luB will be used.\n", RECEIVE_POOL_SIZE_ENV_VAR_NAME,
1000 RECEIVE_POOL_SIZE_DEFAULT_SIZE);
1001 _dbus_warn ("Correct value must be between %ukB and %uMB and must be aligned to page size: %ldB.\n",
1002 RECEIVE_POOL_SIZE_MIN_KBYTES, RECEIVE_POOL_SIZE_MAX_MBYTES, page_size);
1004 receive_pool_size = RECEIVE_POOL_SIZE_DEFAULT_SIZE;
1008 _dbus_verbose ("Receive pool size set to %llu.\n", (unsigned long long)receive_pool_size);
1009 return receive_pool_size;
1012 static dbus_uint64_t
1013 get_attach_flags_recv (DBusTransportKdbus *transport)
1015 dbus_uint64_t attach_flags_recv = 0;
1017 #ifdef LIBDBUSPOLICY
1018 attach_flags_recv = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_NAMES | KDBUS_ATTACH_SECLABEL;
1021 return attach_flags_recv;
1025 * Performs kdbus hello - registration on the kdbus bus
1026 * needed to send and receive messages on the bus,
1027 * and configures transport.
1028 * As a result unique id on he bus is obtained.
1030 * @see KDBUS_HELLO_* flags in kdbus.h
1032 * @param transport transport structure
1033 * @param registration_flags aditional flags to modify registration process
1034 * @returns #TRUE on success
1037 bus_register_kdbus (DBusTransportKdbus *transport,
1038 dbus_uint32_t registration_flags,
1042 dbus_uint64_t flags;
1044 flags = KDBUS_HELLO_ACCEPT_FD;
1045 if (registration_flags & REGISTER_FLAG_MONITOR)
1046 flags |= KDBUS_HELLO_MONITOR;
1048 ret = _kdbus_hello (transport->kdbus,
1051 get_attach_flags_recv (transport),
1053 transport->activator,
1057 dbus_set_error (error, DBUS_ERROR_FAILED, "Hello failed: %d", -ret);
1061 transport->my_DBus_unique_name = create_unique_name_from_unique_id (_kdbus_get_id (transport->kdbus));
1062 if (NULL == transport->my_DBus_unique_name)
1064 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, "Hello post failed: %d", -ret);
1068 _dbus_verbose ("-- Our peer ID is: %llu\n", (unsigned long long)_kdbus_get_id (transport->kdbus));
1074 can_own (DBusTransportKdbus *transport,
1077 dbus_bool_t result = TRUE;
1079 #ifdef LIBDBUSPOLICY
1080 if (NULL != transport->policy)
1081 result = (dbuspolicy1_can_own (transport->policy, name) == 1);
1088 request_DBus_name (DBusTransportKdbus *transport,
1093 DBusString service_name_real;
1094 const DBusString *service_name = &service_name_real;
1096 dbus_uint32_t flags;
1098 if (!dbus_message_get_args (msg, error,
1099 DBUS_TYPE_STRING, &name,
1100 DBUS_TYPE_UINT32, &flags,
1104 _dbus_string_init_const (&service_name_real, name);
1106 if (!_dbus_validate_bus_name (service_name, 0,
1107 _dbus_string_get_length (service_name)))
1109 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1110 "Requested bus name \"%s\" is not valid", name);
1112 _dbus_verbose ("Attempt to acquire invalid service name\n");
1117 if (_dbus_string_get_byte (service_name, 0) == ':')
1119 /* Not allowed; only base services can start with ':' */
1120 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1121 "Cannot acquire a service starting with ':' such as \"%s\"", name);
1123 _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"", name);
1128 if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
1130 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1131 "Connection is not allowed to own the service \"%s\"because "
1132 "it is reserved for D-Bus' use only", DBUS_SERVICE_DBUS);
1136 if (!can_own (transport, name))
1138 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1139 "Connection \"%s\" is not allowed to own the "
1140 "service \"%s\" due to security policies",
1141 transport->my_DBus_unique_name,
1146 *result = _kdbus_request_name (transport->kdbus, name, flags);
1147 if (*result == -EPERM)
1149 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1150 "Kdbus doesn't allow %s to own the service \"%s\"",
1151 transport->my_DBus_unique_name, _dbus_string_get_const_data (service_name));
1154 else if (*result < 0)
1156 dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired, %d, %m", name, errno);
1164 release_DBus_name (DBusTransportKdbus *transport,
1170 DBusString service_name;
1172 if (!dbus_message_get_args (msg, error,
1173 DBUS_TYPE_STRING, &name,
1177 _dbus_string_init_const (&service_name, name);
1179 if (!_dbus_validate_bus_name (&service_name, 0,
1180 _dbus_string_get_length (&service_name)))
1182 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1183 "Given bus name \"%s\" is not valid",
1184 _dbus_string_get_const_data (&service_name));
1186 _dbus_verbose ("Attempt to release invalid service name\n");
1190 if (_dbus_string_get_byte (&service_name, 0) == ':')
1192 /* Not allowed; the base service name cannot be created or released */
1193 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1194 "Cannot release a service starting with ':' such as \"%s\"",
1195 _dbus_string_get_const_data (&service_name));
1197 _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
1198 _dbus_string_get_const_data (&service_name));
1202 if (_dbus_string_equal_c_str (&service_name, DBUS_SERVICE_DBUS))
1204 /* Not allowed; the base service name cannot be created or released */
1205 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1206 "Cannot release the %s service because it is owned by the bus",
1209 _dbus_verbose ("Attempt to release service name \"%s\"",
1214 *result = _kdbus_release_name (transport->kdbus, name);
1217 dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be released, %d, %m", name, errno);
1225 strcmp_existing (const char *str1, const char *str2)
1227 if (NULL == str1 || NULL == str2)
1229 return strcmp (str1, str2);
1233 kernel_match_needed (MatchRule *rule)
1237 /* Allow only NameOwnerChanged member */
1238 if (strcmp_existing (_match_rule_get_member (rule), "NameOwnerChanged") != 0)
1241 /* Allow only signals */
1242 message_type = _match_rule_get_message_type (rule);
1243 if (message_type != DBUS_MESSAGE_TYPE_INVALID && message_type != DBUS_MESSAGE_TYPE_SIGNAL)
1246 /* Check if from DBus */
1247 if (strcmp_existing (_match_rule_get_sender (rule), DBUS_SERVICE_DBUS) != 0)
1250 if (strcmp_existing (_match_rule_get_interface (rule), DBUS_INTERFACE_DBUS) != 0)
1253 if (strcmp_existing (_match_rule_get_path (rule), DBUS_PATH_DBUS) != 0)
1260 is_bloom_needed (MatchRule *rule)
1265 if (_match_rule_get_message_type (rule) != DBUS_TYPE_INVALID
1266 || _match_rule_get_interface (rule) != NULL
1267 || _match_rule_get_member (rule) != NULL
1268 || _match_rule_get_path (rule) != NULL
1269 || _match_rule_get_path_namespace (rule) != NULL)
1272 rule_int = _match_rule_get_args_len (rule);
1273 for (i = 0; i < rule_int; i++)
1275 if (_match_rule_get_args (rule, i) != NULL)
1283 get_bloom (kdbus_t *kdbus, MatchRule *rule, kdbus_bloom_data_t *bloom_data)
1286 const char *rule_string;
1288 char argument_buf[sizeof ("arg")-1 + 2 + sizeof ("-slash-prefix") +1];
1290 rule_int = _match_rule_get_message_type (rule);
1291 if (rule_int != DBUS_MESSAGE_TYPE_INVALID)
1293 bloom_add_pair (bloom_data, kdbus, "message-type", dbus_message_type_to_string (rule_int));
1294 _dbus_verbose ("Adding type %s \n", dbus_message_type_to_string (rule_int));
1297 rule_string = _match_rule_get_interface (rule);
1298 if (rule_string != NULL)
1300 bloom_add_pair (bloom_data, kdbus, "interface", rule_string);
1301 _dbus_verbose ("Adding interface %s \n", rule_string);
1304 rule_string = _match_rule_get_member (rule);
1305 if (rule_string != NULL)
1307 bloom_add_pair (bloom_data, kdbus, "member", rule_string);
1308 _dbus_verbose ("Adding member %s \n", rule_string);
1311 rule_string = _match_rule_get_path (rule);
1312 if (rule_string != NULL)
1314 bloom_add_pair (bloom_data, kdbus, "path", rule_string);
1315 _dbus_verbose ("Adding path %s \n", rule_string);
1318 rule_string = _match_rule_get_path_namespace (rule);
1319 if (rule_string != NULL)
1321 bloom_add_pair (bloom_data, kdbus, "path-slash-prefix", rule_string);
1322 _dbus_verbose ("Adding path-slash-prefix %s \n", rule_string);
1325 rule_int = _match_rule_get_args_len (rule);
1326 for (i = 0; i < rule_int; i++)
1328 rule_string = _match_rule_get_args (rule, i);
1329 if (rule_string != NULL)
1331 unsigned int rule_arg_lens = _match_rule_get_arg_lens (rule, i);
1332 if (rule_arg_lens & MATCH_ARG_IS_PATH)
1334 snprintf (argument_buf, sizeof (argument_buf), "arg%d-slash-prefix", i);
1335 bloom_add_prefixes (bloom_data, kdbus, argument_buf, rule_string, '/');
1337 else if (rule_arg_lens & MATCH_ARG_NAMESPACE)
1339 snprintf (argument_buf, sizeof (argument_buf), "arg%d-dot-prefix", i);
1340 bloom_add_prefixes (bloom_data, kdbus, argument_buf, rule_string, '.');
1344 snprintf (argument_buf, sizeof (argument_buf), "arg%d", i);
1345 bloom_add_pair (bloom_data, kdbus, argument_buf, rule_string);
1352 * Adds a match rule to match broadcast messages going through the message bus.
1353 * Do no affect messages addressed directly.
1355 * TODO add error reporting
1357 * @param transport transport
1361 add_match_kdbus (DBusTransportKdbus *transport,
1364 struct kdbus_cmd_match *cmd;
1365 struct kdbus_item *item;
1367 uint64_t src_id = KDBUS_MATCH_ID_ANY;
1369 dbus_bool_t need_bloom = FALSE;
1371 const char *rule_sender;
1374 rule_cookie = match_rule_get_cookie (rule);
1377 * First check if it is org.freedesktop.DBus's NameOwnerChanged or any
1378 * org.freedesktop.DBus combination that includes this,
1379 * because it must be converted to special kdbus rule (kdbus has separate rules
1380 * for kdbus (kernel) generated broadcasts).
1382 if (kernel_match_needed (rule))
1384 ret = _kdbus_add_match_name_change (transport->kdbus,
1393 _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
1394 ret, _dbus_strerror (ret));
1398 ret = _kdbus_add_match_id_change (transport->kdbus,
1405 _dbus_verbose ("Failed adding match rule for adding id for daemon, error: %d, %s\n",
1406 ret, _dbus_strerror (ret));
1410 _dbus_verbose ("Added match rule for kernel correctly.\n");
1413 * In case all of sender, interface and path are NULL, the rule
1414 * says simply about NameHasOwner signal from any object, any interface, any sender.
1415 * So, we need to consider that.
1416 * Otherwise, our job is finished here.
1418 if (_match_rule_get_sender (rule) != NULL
1419 || _match_rule_get_interface (rule) != NULL
1420 || _match_rule_get_path (rule) != NULL)
1425 * standard rule - registered in general way, for non-kernel broadcasts
1426 * kdbus doesn't use it to check kdbus (kernel) generated broadcasts
1429 need_bloom = is_bloom_needed (rule);
1431 rule_sender = _match_rule_get_sender (rule);
1432 if (rule_sender != NULL)
1435 _dbus_string_init_const (&str, rule_sender);
1437 if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
1440 src_id = parse_name (rule_sender);
1442 /* well-known name */
1443 src_id = KDBUS_MATCH_ID_ANY;
1449 items_size = _kdbus_compute_match_items_size (transport->kdbus,
1454 cmd = _kdbus_new_cmd_match (transport->kdbus,
1463 if (NULL != rule_sender) /* well-known name */
1465 item = _kdbus_item_add_string (item,
1468 strlen (rule_sender) + 1);
1469 _dbus_verbose ("Adding sender %s \n", rule_sender);
1471 else if (KDBUS_MATCH_ID_ANY != src_id) /* unique id */
1473 item = _kdbus_item_add_id (item, src_id);
1474 _dbus_verbose ("Adding src_id %llu \n", (unsigned long long)src_id);
1480 item = _kdbus_item_add_bloom_mask (item, transport->kdbus, &bloom);
1481 get_bloom (transport->kdbus, rule, bloom);
1484 ret = _kdbus_add_match (transport->kdbus, cmd);
1486 _kdbus_free_cmd_match (cmd);
1491 _dbus_verbose ("Failed adding match bus rule cookie %llu,\nerror: %d, %s\n",
1492 rule_cookie, ret, _dbus_strerror (ret));
1496 _dbus_verbose ("Added match bus rule %llu\n", rule_cookie);
1500 static DBusMessage *
1501 capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport,
1502 DBusMessage *message,
1505 DBusMessageIter args;
1506 dbus_uint32_t registration_flags = 0;
1508 dbus_message_iter_init (message, &args);
1509 if (dbus_message_iter_get_arg_type (&args) == DBUS_TYPE_UINT32)
1510 dbus_message_iter_get_basic (&args, ®istration_flags);
1512 if (!bus_register_kdbus (transport, registration_flags, error))
1515 return reply_1_data (message, DBUS_TYPE_STRING, &transport->my_DBus_unique_name);
1518 free (transport->my_DBus_unique_name);
1522 static DBusMessage *
1523 capture_org_freedesktop_DBus_RequestName (DBusTransportKdbus *transport,
1524 DBusMessage *message,
1529 if (!request_DBus_name (transport, message, &result, error))
1532 return reply_1_data (message, DBUS_TYPE_UINT32, &result);
1535 static DBusMessage *
1536 capture_org_freedesktop_DBus_ReleaseName (DBusTransportKdbus *transport,
1537 DBusMessage *message,
1542 if (!release_DBus_name (transport, message, &result, error))
1545 return reply_1_data (message, DBUS_TYPE_UINT32, &result);
1548 static DBusMessage *
1549 capture_org_freedesktop_DBus_AddMatch (DBusTransportKdbus *transport,
1550 DBusMessage *message,
1555 MatchRule *rule = NULL;
1556 DBusConnection *connection = transport->base.connection;
1558 if (!dbus_message_get_args (message, error,
1559 DBUS_TYPE_STRING, &arg,
1563 _dbus_string_init_const (&arg_str, arg);
1565 rule = match_rule_parse (connection, &arg_str, error);
1569 if (!matchmaker_add_rule (transport->matchmaker, rule))
1571 dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, "No memory to store match rule");
1575 if (!add_match_kdbus (transport, rule))
1577 dbus_set_error (error, _dbus_error_from_errno (errno), "Could not add match rule, %s",
1578 _dbus_strerror_from_errno ());
1582 match_rule_unref (rule);
1583 return dbus_message_new_method_return (message);
1587 match_rule_unref (rule);
1588 _dbus_verbose ("Error during AddMatch in lib: %s, %s\n", error->name, error->message);
1592 static dbus_uint64_t
1593 get_match_cookie_for_remove (Matchmaker *matchmaker, MatchRule *rule_to_remove)
1595 DBusList *rules = matchmaker_get_rules_list (matchmaker, rule_to_remove);
1598 DBusList *link = _dbus_list_get_last_link (&rules);
1599 while (NULL != link)
1601 if (match_rule_equal_lib (link->data, rule_to_remove))
1603 return match_rule_get_cookie (link->data);
1605 link = _dbus_list_get_prev_link (&rules, link);
1611 static DBusMessage *
1612 capture_org_freedesktop_DBus_RemoveMatch (DBusTransportKdbus *transport,
1613 DBusMessage *message,
1618 MatchRule *rule = NULL;
1619 DBusConnection *connection = transport->base.connection;
1620 dbus_uint64_t cookie;
1622 if (!dbus_message_get_args (message, error,
1623 DBUS_TYPE_STRING, &arg,
1627 _dbus_string_init_const (&arg_str, arg);
1629 rule = match_rule_parse (connection, &arg_str, error);
1632 cookie = get_match_cookie_for_remove (transport->matchmaker, rule);
1635 dbus_set_error (error,
1636 DBUS_ERROR_MATCH_RULE_NOT_FOUND,
1637 "The given match rule wasn't found and can't be removed");
1641 int ret = _kdbus_remove_match (transport->kdbus, cookie);
1643 dbus_set_error (error,
1644 _dbus_error_from_errno (ret),
1645 "Could not remove match rule");
1647 if (!dbus_error_is_set (error))
1648 matchmaker_remove_rule_by_value (transport->matchmaker, rule, error);
1651 match_rule_unref (rule);
1654 if (dbus_error_is_set (error))
1656 _dbus_verbose ("Error during RemoveMatch in lib: %s, %s\n",
1662 return dbus_message_new_method_return (message);
1666 get_connection_info_by_name (DBusMessage *message,
1668 struct nameInfo *info,
1669 DBusTransportKdbus *transport,
1671 dbus_bool_t getLabel)
1674 if (!dbus_validate_bus_name (name, error))
1677 if ((ret = _kdbus_connection_info_by_name (transport->kdbus, name, getLabel, info)) != 0)
1679 if (ESRCH == ret || ENXIO == ret)
1680 dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1681 "Could not get owner of name '%s': no such name", name);
1683 dbus_set_error (error, DBUS_ERROR_FAILED,
1684 "Unable to query name %s, returned %d, errno = %d (%m).",
1688 if (info->flags & KDBUS_HELLO_ACTIVATOR)
1690 dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
1691 "Could not get owner of name '%s'", name);
1692 /* we return ESRCH - this is an indicator that name has an activator */
1698 /* This local function handles common case for org.freedesktop.DBus method handlers:
1699 * 1. gets string argument from incoming message;
1700 * 2. gets connection info for such name.
1701 * Note: if getLabel argument is set to TRUE, the caller must free info.sec_label.
1704 get_connection_info_from_message_argument (DBusMessage *message,
1706 struct nameInfo *info,
1707 DBusTransportKdbus *transport,
1708 dbus_bool_t getLabel)
1712 if (!dbus_message_get_args (message, error,
1713 DBUS_TYPE_STRING, &arg,
1717 return get_connection_info_by_name (message, error, info, transport, arg, getLabel);
1720 static DBusMessage *
1721 capture_org_freedesktop_DBus_GetConnectionCredentials (DBusTransportKdbus *transport,
1722 DBusMessage *message,
1725 DBusMessage *reply = NULL;
1726 DBusMessageIter reply_iter;
1727 DBusMessageIter array_iter;
1728 struct nameInfo info;
1730 if (get_connection_info_from_message_argument (message, error, &info, transport, TRUE) != 0)
1733 reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
1737 /* we can't represent > 32-bit pids; if your system needs them, please
1738 * add ProcessID64 to the spec or something */
1739 if (info.processId <= _DBUS_UINT32_MAX)
1741 if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", info.processId))
1744 /* we can't represent > 32-bit uids; if your system needs them, please
1745 * add UnixUserID64 to the spec or something */
1746 if (info.userId <= _DBUS_UINT32_MAX)
1748 if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", info.userId))
1752 if (info.sec_label != NULL)
1754 dbus_bool_t res = _dbus_asv_add_byte_array (&array_iter,
1755 "LinuxSecurityLabel",
1757 strlen (info.sec_label)+1);
1759 dbus_free (info.sec_label);
1765 if (!_dbus_asv_close (&reply_iter, &array_iter))
1768 if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
1774 _dbus_asv_abandon (&reply_iter, &array_iter);
1775 dbus_message_unref (reply);
1780 static DBusMessage *
1781 capture_org_freedesktop_DBus_GetConnectionSELinuxSecurityContext (DBusTransportKdbus *transport,
1782 DBusMessage *message,
1785 struct nameInfo info;
1787 if (get_connection_info_from_message_argument (message, error, &info, transport, TRUE) != 0)
1790 if (info.sec_label != NULL)
1794 reply = reply_fixed_array (message, DBUS_TYPE_BYTE,
1796 strlen (info.sec_label)+1);
1798 dbus_free (info.sec_label);
1803 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, "Operation not supported");
1809 static DBusMessage *
1810 capture_org_freedesktop_DBus_GetConnectionUnixProcessID (DBusTransportKdbus *transport,
1811 DBusMessage *message,
1814 struct nameInfo info;
1815 dbus_uint32_t processId;
1817 if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0 ||
1818 info.processId > _DBUS_UINT32_MAX)
1821 processId = info.processId;
1823 return reply_1_data (message, DBUS_TYPE_UINT32, &processId);
1826 static DBusMessage *
1827 capture_org_freedesktop_DBus_GetConnectionUnixUser (DBusTransportKdbus *transport,
1828 DBusMessage *message,
1831 struct nameInfo info;
1832 dbus_uint32_t userId;
1834 if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0 ||
1835 info.userId > _DBUS_UINT32_MAX)
1838 userId = info.userId;
1840 return reply_1_data (message, DBUS_TYPE_UINT32, &userId);
1843 static DBusMessage *
1844 capture_org_freedesktop_DBus_GetId (DBusTransportKdbus *transport,
1845 DBusMessage *message,
1848 dbus_uint64_t bus_id_size = _kdbus_get_bus_id_size ();
1849 char bus_id[bus_id_size*2+1];
1850 char *bus_id_ptr = bus_id;
1851 char *bus_id_original = _kdbus_get_bus_id (transport->kdbus);
1852 dbus_uint64_t i = 0;
1853 for (; i < bus_id_size; i++)
1854 snprintf (bus_id + 2*i, sizeof (bus_id) - 2*i, "%02x", bus_id_original[i]);
1855 return reply_1_data (message, DBUS_TYPE_STRING, &bus_id_ptr);
1858 static DBusMessage *
1859 capture_org_freedesktop_DBus_GetNameOwner (DBusTransportKdbus *transport,
1860 DBusMessage *message,
1864 struct nameInfo info;
1868 if (!dbus_message_get_args (message, error,
1869 DBUS_TYPE_STRING, &arg,
1873 if (strcmp (arg, DBUS_SERVICE_DBUS) == 0)
1875 if (-1 == asprintf (&unique_name, "%s", DBUS_SERVICE_DBUS))
1880 if (get_connection_info_by_name (message, error, &info, transport, arg, FALSE) != 0)
1883 unique_name = create_unique_name_from_unique_id (info.uniqueId);
1884 if (NULL == unique_name)
1888 reply = reply_1_data (message, DBUS_TYPE_STRING, &unique_name);
1895 static DBusMessage *
1896 reply_listNames (DBusTransportKdbus *transport,
1897 DBusMessage *message,
1899 dbus_uint64_t flags)
1901 DBusMessage *reply = NULL;
1902 dbus_uint64_t prev_id = 0;
1904 /* First, get the list from kdbus */
1906 struct kdbus_info *name_list, *name;
1909 DBusMessageIter iter;
1910 DBusMessageIter array_iter;
1912 ret = _kdbus_list (transport->kdbus,
1918 dbus_set_error (error, DBUS_ERROR_FAILED, "Error listing names");
1922 /* Compose the reply on the fly */
1923 reply = dbus_message_new_method_return (message);
1927 dbus_message_iter_init_append (reply, &iter);
1928 if (!dbus_message_iter_open_container (&iter,
1930 DBUS_TYPE_STRING_AS_STRING,
1934 KDBUS_FOREACH (name, name_list, list_size)
1936 struct kdbus_item *item;
1938 if ((flags & KDBUS_LIST_UNIQUE) && name->id != prev_id)
1942 char *unique_name = create_unique_name_from_unique_id (name->id);
1944 if (NULL == unique_name)
1947 res = dbus_message_iter_append_basic (&array_iter,
1956 KDBUS_ITEM_FOREACH (item, name, items)
1958 if (item->type == KDBUS_ITEM_OWNED_NAME)
1960 DBusError local_error;
1961 char *name_ptr = item->name.name;
1963 dbus_error_init ( &local_error );
1964 if (!dbus_validate_bus_name (name_ptr, &local_error))
1967 if (flags & KDBUS_LIST_QUEUED)
1968 name_ptr = create_unique_name_from_unique_id (name->id);
1970 if (NULL == name_ptr)
1973 if (!dbus_message_iter_append_basic (&array_iter,
1978 if (flags & KDBUS_LIST_QUEUED)
1984 if (!dbus_message_iter_close_container (&iter, &array_iter))
1987 if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
1993 dbus_message_iter_abandon_container (&iter, &array_iter);
1996 dbus_message_unref (reply);
1998 _kdbus_free_mem (transport->kdbus, name_list);
2002 static DBusMessage *
2003 capture_org_freedesktop_DBus_ListActivatableNames (DBusTransportKdbus *transport,
2004 DBusMessage *message,
2007 return reply_listNames (transport, message, error, KDBUS_LIST_ACTIVATORS);
2010 static DBusMessage *
2011 capture_org_freedesktop_DBus_ListNames (DBusTransportKdbus *transport,
2012 DBusMessage *message,
2015 return reply_listNames (transport, message, error, KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES);
2018 static DBusMessage *
2019 capture_org_freedesktop_DBus_ListQueuedOwners (DBusTransportKdbus *transport,
2020 DBusMessage *message,
2023 struct nameInfo info;
2025 if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2028 return reply_listNames (transport, message, error, KDBUS_LIST_QUEUED);
2031 static DBusMessage *
2032 capture_org_freedesktop_DBus_NameHasOwner (DBusTransportKdbus *transport,
2033 DBusMessage *message,
2036 struct nameInfo info;
2037 dbus_bool_t result = TRUE;
2039 if (get_connection_info_from_message_argument (message, error, &info, transport, FALSE) != 0)
2041 if (dbus_error_is_set (error) && dbus_error_has_name (error, DBUS_ERROR_NAME_HAS_NO_OWNER))
2044 dbus_error_free (error);
2050 return reply_1_data (message, DBUS_TYPE_BOOLEAN, &result);
2053 static DBusMessage *
2054 capture_org_freedesktop_DBus_ReloadConfig (DBusTransportKdbus *transport,
2055 DBusMessage *message,
2058 DBusMessageIter iter;
2059 DBusMessage *reply = NULL;
2061 dbus_message_iter_init (message, &iter);
2062 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT)
2064 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
2065 "Call to 'ReloadConfig' has wrong args");
2069 reply = dbus_message_new_method_return (message);
2073 if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
2079 dbus_message_unref (reply);
2083 static DBusMessage *
2084 capture_org_freedesktop_DBus_StartServiceByName (DBusTransportKdbus *transport,
2085 DBusMessage *message,
2088 struct nameInfo info;
2090 dbus_uint32_t flags; /* Spec says: not used, but we check the syntax anyway */
2092 dbus_bool_t dbus_service = FALSE;
2094 if (!dbus_message_get_args (message, error,
2095 DBUS_TYPE_STRING, &name,
2096 DBUS_TYPE_UINT32, &flags,
2100 dbus_service = (strncmp (name, DBUS_SERVICE_DBUS, strlen (DBUS_SERVICE_DBUS) + 1) == 0);
2103 ret = get_connection_info_by_name (message,
2110 if (dbus_service || 0 == ret)
2112 dbus_uint32_t status = DBUS_START_REPLY_ALREADY_RUNNING;
2113 return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2115 else if (-ESRCH == ret) /* there is an activator */
2117 DBusMessage *sub_message;
2119 /* if we are here, then we have error set - free place for possible real error */
2120 dbus_error_free (error);
2122 /* send method call to org.freedesktop.DBus.Peer.Ping */
2123 sub_message = dbus_message_new_method_call (name, "/", DBUS_INTERFACE_PEER, "Ping");
2124 if (sub_message == NULL)
2127 /* The serial number here is set to -1. A message needs a valid serial number.
2128 * We do not have access to connection's serial numbers counter, so we need to make up one.
2129 * -1 is the last valid serial, so we hope that we'll never get there, especially with 64-bit
2132 dbus_message_set_serial (sub_message, -1);
2134 dbus_message_lock (sub_message);
2136 if (kdbus_write_msg_internal (transport, sub_message, name, FALSE, FALSE) == -1)
2140 dbus_uint32_t status = DBUS_START_REPLY_SUCCESS;
2141 return reply_1_data (message, DBUS_TYPE_UINT32, &status);
2147 * There was an error set in get_connection_info_by_name()
2148 * We want to have another error return from StartServiceByName.
2150 dbus_error_free (error);
2151 dbus_set_error (error,
2152 DBUS_ERROR_SERVICE_UNKNOWN,
2153 "The name %s was not provided by any .service files",
2160 static DBusMessage *
2161 capture_org_freedesktop_DBus_UpdateActivationEnvironment (DBusTransportKdbus *transport,
2162 DBusMessage *message,
2165 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
2166 "'%s' method not supported", dbus_message_get_member (message));
2170 typedef DBusMessage * (*CaptureHandler)(DBusTransportKdbus *, DBusMessage *, DBusError *);
2171 struct CaptureHandlers {
2172 const char *method_name;
2173 CaptureHandler handler;
2176 #define HANDLER_ELEMENT(x) {#x, capture_org_freedesktop_DBus_##x}
2178 /* This is to cut the code to parts, and keep it organized:
2179 * an array of elements of type, as in example:
2180 * { "RequestName", capture_org_freedesktop_DBus_RequestName }
2181 * That is, a method of name RequestName will be handled by capture_org_freedesktop_DBus_RequestName ().
2183 static struct CaptureHandlers capture_handlers[] =
2185 // "Hello" is handled separately
2186 // HANDLER_ELEMENT (Hello),
2187 HANDLER_ELEMENT (RequestName),
2188 HANDLER_ELEMENT (ReleaseName),
2189 HANDLER_ELEMENT (AddMatch),
2190 HANDLER_ELEMENT (RemoveMatch),
2191 HANDLER_ELEMENT (GetConnectionCredentials),
2192 HANDLER_ELEMENT (GetConnectionSELinuxSecurityContext),
2193 HANDLER_ELEMENT (GetConnectionUnixProcessID),
2194 HANDLER_ELEMENT (GetConnectionUnixUser),
2195 HANDLER_ELEMENT (GetId),
2196 HANDLER_ELEMENT (GetNameOwner),
2197 HANDLER_ELEMENT (ListActivatableNames),
2198 HANDLER_ELEMENT (ListNames),
2199 HANDLER_ELEMENT (ListQueuedOwners),
2200 HANDLER_ELEMENT (NameHasOwner),
2201 HANDLER_ELEMENT (ReloadConfig),
2202 HANDLER_ELEMENT (StartServiceByName),
2203 HANDLER_ELEMENT (UpdateActivationEnvironment)
2207 * Looks over messages sent to org.freedesktop.DBus. Hello message, which performs
2208 * registration on the bus, is captured as it must be locally converted into
2209 * appropriate ioctl. AddMatch and RemoveMatch are captured to store match rules
2210 * locally in case of false positive result of kdbus bloom filters, but after
2211 * being read they are passed to org.freedesktop.DBus to register these rules
2213 * All the rest org.freedesktop.DBus methods are left untouched
2214 * and they are sent to dbus-daemon in the same way as every other messages.
2216 * @param transport Transport
2217 * @param message Message being sent.
2219 1 if message is not captured and should be passed to kdbus
2220 * 0 if message was handled locally and correctly (it includes proper return of error reply),
2221 * -1 message to org.freedesktop.DBus was not handled correctly.
2224 capture_org_freedesktop_DBus (DBusTransportKdbus *transport,
2225 const char *destination,
2226 DBusMessage *message,
2227 DBusMessage **reply)
2230 if (!strcmp (destination, DBUS_SERVICE_DBUS))
2232 if (!strcmp (dbus_message_get_interface (message), DBUS_INTERFACE_DBUS))
2235 const char *member = dbus_message_get_member (message);
2237 dbus_error_init (&error);
2239 if (!strcmp (member, "Hello"))
2241 *reply = capture_org_freedesktop_DBus_Hello (transport, message, &error);
2246 int handlers_size = sizeof (capture_handlers)/sizeof (capture_handlers[0]);
2248 while (i < handlers_size && strcmp (member, capture_handlers[i].method_name) != 0)
2251 if (i < handlers_size)
2253 *reply = capture_handlers[i].handler (transport, message, &error);
2257 dbus_set_error (&error, DBUS_ERROR_UNKNOWN_METHOD,
2258 "org.freedesktop.DBus does not understand message %s", member);
2262 if (*reply == NULL && dbus_error_is_set (&error))
2264 *reply = reply_with_error ((char*)error.name,
2268 dbus_error_free (&error);
2276 } /* id DBUS_INTERFACE_DBUS */
2277 } /* if DBUS_SERVICE_DBUS */
2282 #ifdef DBUS_ENABLE_VERBOSE_MODE
2283 #define ENUM_NAME_ITEM(x) case x : return #x
2286 enum_MSG (long long id)
2290 ENUM_NAME_ITEM (_KDBUS_ITEM_NULL);
2291 ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_VEC);
2292 ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_OFF);
2293 ENUM_NAME_ITEM (KDBUS_ITEM_PAYLOAD_MEMFD);
2294 ENUM_NAME_ITEM (KDBUS_ITEM_FDS);
2295 ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_PARAMETER);
2296 ENUM_NAME_ITEM (KDBUS_ITEM_BLOOM_FILTER);
2297 ENUM_NAME_ITEM (KDBUS_ITEM_DST_NAME);
2298 ENUM_NAME_ITEM (KDBUS_ITEM_CREDS);
2299 ENUM_NAME_ITEM (KDBUS_ITEM_PID_COMM);
2300 ENUM_NAME_ITEM (KDBUS_ITEM_TID_COMM);
2301 ENUM_NAME_ITEM (KDBUS_ITEM_EXE);
2302 ENUM_NAME_ITEM (KDBUS_ITEM_CMDLINE);
2303 ENUM_NAME_ITEM (KDBUS_ITEM_CGROUP);
2304 ENUM_NAME_ITEM (KDBUS_ITEM_CAPS);
2305 ENUM_NAME_ITEM (KDBUS_ITEM_SECLABEL);
2306 ENUM_NAME_ITEM (KDBUS_ITEM_AUDIT);
2307 ENUM_NAME_ITEM (KDBUS_ITEM_CONN_DESCRIPTION);
2308 ENUM_NAME_ITEM (KDBUS_ITEM_NAME);
2309 ENUM_NAME_ITEM (KDBUS_ITEM_TIMESTAMP);
2310 ENUM_NAME_ITEM (KDBUS_ITEM_NAME_ADD);
2311 ENUM_NAME_ITEM (KDBUS_ITEM_NAME_REMOVE);
2312 ENUM_NAME_ITEM (KDBUS_ITEM_NAME_CHANGE);
2313 ENUM_NAME_ITEM (KDBUS_ITEM_ID_ADD);
2314 ENUM_NAME_ITEM (KDBUS_ITEM_ID_REMOVE);
2315 ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_TIMEOUT);
2316 ENUM_NAME_ITEM (KDBUS_ITEM_REPLY_DEAD);
2321 #if KDBUS_MSG_DECODE_DEBUG == 1
2323 enum_PAYLOAD (long long id)
2327 ENUM_NAME_ITEM (KDBUS_PAYLOAD_KERNEL);
2328 ENUM_NAME_ITEM (KDBUS_PAYLOAD_DBUS);
2334 msg_id (uint64_t id)
2337 const char* const_ptr;
2344 snprintf (buf, sizeof (buf), "%llu", (unsigned long long)id);
2352 static dbus_uint32_t
2353 get_next_client_serial (DBusTransportKdbus *transport)
2355 dbus_uint32_t serial;
2357 serial = transport->client_serial++;
2359 if (transport->client_serial == 0)
2360 transport->client_serial = 1;
2366 * Calculates length of the kdbus message content (payload).
2368 * @param msg kdbus message
2369 * @return the length of the kdbus message's payload.
2372 kdbus_message_size (const struct kdbus_msg *msg)
2374 const struct kdbus_item *item;
2377 KDBUS_ITEM_FOREACH (item, msg, items)
2379 if (item->size < KDBUS_ITEM_HEADER_SIZE)
2381 _dbus_verbose (" +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2386 case KDBUS_ITEM_PAYLOAD_OFF:
2387 ret_size += item->vec.size;
2389 case KDBUS_ITEM_PAYLOAD_MEMFD:
2390 ret_size += item->memfd.size;
2401 generate_NameSignal (const char *signal,
2403 DBusTransportKdbus *transport)
2405 DBusMessage *message;
2407 _dbus_verbose ("Generating %s for %s.\n", signal, name);
2409 message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, signal);
2410 if (message == NULL)
2413 if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
2415 if (!dbus_message_set_destination (message, transport->my_DBus_unique_name))
2417 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
2419 dbus_message_set_serial (message, get_next_client_serial (transport));
2421 if (!add_message_to_received (message, transport->base.connection))
2427 dbus_message_unref (message);
2432 * The NameOwnerChanged signals take three parameters with
2433 * unique or well-known names, but only some forms actually
2436 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
2437 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
2438 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
2439 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
2440 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
2442 * For the latter two the two unique names must be identical.
2445 kdbus_handle_name_owner_changed (__u64 type,
2446 const char *bus_name,
2449 DBusTransportKdbus *transport)
2451 DBusMessage *message = NULL;
2452 DBusMessageIter args;
2454 const char *const_ptr;
2456 if ((message = dbus_message_new_signal (DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) == NULL)
2459 dbus_message_iter_init_append (message, &args);
2461 // for ID_ADD and ID_REMOVE this function takes NULL as bus_name
2462 if (bus_name == NULL)
2464 snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old != 0 ? old : new);
2465 const_ptr = tmp_str;
2468 const_ptr = bus_name;
2470 if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2473 _dbus_verbose ("%s\n", const_ptr);
2476 if ((old==0) && (new==0))
2478 /* kdbus generates its own set of events that can not be passed to
2479 * client without translation. */
2480 const char *src = "org.freedesktop.DBus";
2481 const char *dst = "org.freedesktop.DBus";
2483 if (type == KDBUS_ITEM_NAME_ADD || type == KDBUS_ITEM_ID_ADD)
2485 else if (type == KDBUS_ITEM_NAME_REMOVE || type == KDBUS_ITEM_ID_REMOVE)
2488 if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &src))
2490 if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &dst))
2493 _dbus_verbose ("[NameOwnerChanged:%s, old=%lld, new=%lld\n", __func__, old, new);
2497 // determine and append old_id
2500 snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", old);
2501 const_ptr = tmp_str;
2506 if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2509 _dbus_verbose ("%s\n", const_ptr);
2510 // determine and append new_id
2513 snprintf (tmp_str, sizeof (tmp_str), ":1.%llu", new);
2514 const_ptr = tmp_str;
2519 if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &const_ptr))
2522 _dbus_verbose ("%s\n", const_ptr);
2525 dbus_message_set_sender (message, DBUS_SERVICE_DBUS);
2526 dbus_message_set_serial (message, get_next_client_serial (transport));
2528 if (!add_message_to_received (message, transport->base.connection))
2534 dbus_message_unref (message);
2540 handle_item_timestamp (const struct kdbus_item *item)
2542 #if KDBUS_MSG_DECODE_DEBUG == 1
2543 _dbus_verbose (" +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
2544 enum_MSG (item->type), item->size,
2545 (unsigned long long)item->timestamp.realtime_ns,
2546 (unsigned long long)item->timestamp.monotonic_ns);
2551 handle_unexpected_item (const struct kdbus_item *item)
2553 _dbus_assert_not_reached ("unexpected item from kdbus");
2557 handle_padding (const struct kdbus_msg *msg,
2558 const struct kdbus_item *end_of_items)
2560 #if KDBUS_MSG_DECODE_DEBUG == 1
2561 if ((char *)end_of_items - ((char *)msg + msg->size) >= 8)
2562 _dbus_verbose ("invalid padding at end of message\n");
2566 #ifdef LIBDBUSPOLICY
2568 load_dbus_header (DBusTransportKdbus *transport,
2570 const char *message_data,
2571 dbus_uint32_t message_len)
2573 DBusValidity validity = DBUS_VALID;
2575 dbus_uint32_t fields_array_len_unsigned;
2576 dbus_uint32_t body_len_unsigned;
2579 if (0 == message_len)
2582 _dbus_string_init_const_len (&message, message_data, message_len);
2583 _dbus_gvariant_raw_get_lengths (&message,
2584 &fields_array_len_unsigned,
2588 _dbus_string_init_const_len (&header->data,
2590 fields_array_len_unsigned + FIRST_GVARIANT_FIELD_OFFSET);
2592 header->padding = 0;
2593 header->byte_order = message_data[0];
2594 header->protocol_version = DBUS_PROTOCOL_VERSION_GVARIANT;
2595 for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
2596 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
2598 return _dbus_header_load_gvariant (header, &validity);
2603 can_receive (DBusTransportKdbus *transport,
2604 const struct kdbus_msg *msg,
2605 const char *message_data,
2606 dbus_uint32_t message_len)
2608 dbus_bool_t result = TRUE;
2610 #ifdef LIBDBUSPOLICY
2611 if (transport->policy)
2614 dbus_bool_t got_header = FALSE;
2615 dbus_bool_t got_creds = FALSE;
2616 dbus_bool_t got_seclabel = FALSE;
2618 if (KDBUS_PAYLOAD_DBUS == msg->payload_type)
2620 const struct kdbus_item *item;
2621 uid_t sender_euid = -1;
2622 gid_t sender_egid = -1;
2623 const char *seclabel = NULL;
2628 _dbus_string_init (&names);
2630 KDBUS_ITEM_FOREACH(item, msg, items)
2633 case KDBUS_ITEM_CREDS:
2634 sender_euid = (uid_t) item->creds.euid;
2635 sender_egid = (gid_t) item->creds.egid;
2636 got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1);
2638 case KDBUS_ITEM_SECLABEL:
2639 seclabel = item->str;
2640 got_seclabel = (seclabel != NULL);
2642 case KDBUS_ITEM_OWNED_NAME:
2645 _dbus_string_init_const (&name, item->name.name);
2646 if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))
2648 if (_dbus_string_get_length (&names) != 0)
2649 _dbus_string_append_byte (&names, ' ');
2651 _dbus_string_copy (&name,
2654 _dbus_string_get_length (&names));
2659 break; /* ignore all other items */
2662 if (NULL != message_data && message_len > 0)
2664 if (load_dbus_header (transport, &header, message_data, message_len))
2668 if (got_header && _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL)
2672 else if (got_header && got_creds && got_seclabel)
2674 const char *destination = NULL;
2675 const char *path = NULL;
2676 const char *interface = NULL;
2677 const char *member = NULL;
2678 const char *error_name = NULL;
2679 dbus_uint64_t reply_cookie = 0;
2680 dbus_bool_t requested_reply = FALSE;
2683 _dbus_header_get_field_basic (&header,
2684 DBUS_HEADER_FIELD_DESTINATION,
2688 _dbus_header_get_field_basic (&header,
2689 DBUS_HEADER_FIELD_PATH,
2693 _dbus_header_get_field_basic (&header,
2694 DBUS_HEADER_FIELD_INTERFACE,
2698 _dbus_header_get_field_basic (&header,
2699 DBUS_HEADER_FIELD_MEMBER,
2703 _dbus_header_get_field_basic (&header,
2704 DBUS_HEADER_FIELD_ERROR_NAME,
2708 _dbus_header_get_field_basic (&header,
2709 DBUS_HEADER_FIELD_REPLY_SERIAL,
2713 requested_reply = !(_dbus_header_get_flag (&header,
2714 DBUS_HEADER_FLAG_NO_REPLY_EXPECTED));
2716 ret = dbuspolicy1_check_in (transport->policy,
2718 _dbus_string_get_length (&names) > 0 ?
2719 _dbus_string_get_const_data (&names) :
2727 _dbus_header_get_message_type (&header),
2731 result = (1 == ret);
2734 _dbus_string_free (&names);
2743 kdbus_decode_dbus_message (const struct kdbus_msg *msg,
2745 DBusTransportKdbus *kdbus_transport,
2749 const struct kdbus_item *item;
2751 char *buffer = data;
2755 KDBUS_ITEM_FOREACH (item, msg, items)
2757 if (item->size < KDBUS_ITEM_HEADER_SIZE)
2759 _dbus_verbose (" +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2766 case KDBUS_ITEM_PAYLOAD_OFF:
2767 memcpy (data, (char *)msg+item->vec.offset, item->vec.size);
2768 data += item->vec.size;
2769 ret_size += item->vec.size;
2771 #ifdef DBUS_ENABLE_VERBOSE_MODE
2774 debug_c_str ("Message part arrived:", (char *)msg+item->vec.offset, item->vec.size);
2778 _dbus_verbose (" +%s (%llu bytes) off=%llu size=%llu\n",
2779 enum_MSG (item->type), item->size,
2780 (unsigned long long)item->vec.offset,
2781 (unsigned long long)item->vec.size);
2784 case KDBUS_ITEM_PAYLOAD_MEMFD:
2789 size = item->memfd.size;
2790 _dbus_verbose ("memfd.size : %llu\n", (unsigned long long)size);
2792 buf = mmap (NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0);
2793 if (buf == MAP_FAILED)
2795 _dbus_verbose ("mmap () fd=%i failed:%m", item->memfd.fd);
2799 memcpy (data, buf, size);
2804 close (item->memfd.fd);
2806 _dbus_verbose (" +%s (%llu bytes) off=%llu size=%llu\n",
2807 enum_MSG (item->type), item->size,
2808 (unsigned long long)item->vec.offset,
2809 (unsigned long long)item->vec.size);
2813 case KDBUS_ITEM_FDS:
2817 *n_fds = (item->size - KDBUS_ITEM_HEADER_SIZE) / sizeof (int);
2818 memcpy (fds, item->fds, *n_fds * sizeof (int));
2819 for (i = 0; i < *n_fds; i++)
2820 _dbus_fd_set_close_on_exec (fds[i]);
2824 case KDBUS_ITEM_CREDS:
2825 #if KDBUS_MSG_DECODE_DEBUG == 1
2826 _dbus_verbose (" +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
2827 enum_MSG (item->type), item->size,
2828 item->creds.uid, item->creds.gid,
2829 item->creds.pid, item->creds.tid,
2830 item->creds.starttime);
2834 case KDBUS_ITEM_PID_COMM:
2835 case KDBUS_ITEM_TID_COMM:
2836 case KDBUS_ITEM_EXE:
2837 case KDBUS_ITEM_CGROUP:
2838 case KDBUS_ITEM_SECLABEL:
2839 case KDBUS_ITEM_DST_NAME:
2840 #if KDBUS_MSG_DECODE_DEBUG == 1
2841 _dbus_verbose (" +%s (%llu bytes) '%s' (%zu)\n",
2842 enum_MSG (item->type), item->size, item->str, strlen (item->str));
2846 case KDBUS_ITEM_CMDLINE:
2847 case KDBUS_ITEM_NAME:
2848 #if KDBUS_MSG_DECODE_DEBUG == 1
2850 __u64 size = item->size - KDBUS_ITEM_HEADER_SIZE;
2851 const char *str = item->str;
2854 _dbus_verbose (" +%s (%llu bytes) ", enum_MSG (item->type), item->size);
2857 _dbus_verbose ("'%s' ", str);
2858 size -= strlen (str) + 1;
2859 str += strlen (str) + 1;
2863 _dbus_verbose ("(%d string%s)\n", count, (count == 1) ? "" : "s");
2868 case KDBUS_ITEM_AUDIT:
2869 #if KDBUS_MSG_DECODE_DEBUG == 1
2870 _dbus_verbose (" +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
2871 enum_MSG (item->type), item->size,
2872 (unsigned long long)item->data64[0],
2873 (unsigned long long)item->data64[1]);
2877 case KDBUS_ITEM_CAPS:
2878 #if KDBUS_MSG_DECODE_DEBUG == 1
2881 const uint32_t *cap;
2884 _dbus_verbose (" +%s (%llu bytes) len=%llu bytes)\n",
2885 enum_MSG (item->type), item->size,
2886 (unsigned long long)item->size - KDBUS_ITEM_HEADER_SIZE);
2889 n = (item->size - KDBUS_ITEM_HEADER_SIZE) / 4 / sizeof (uint32_t);
2891 _dbus_verbose (" CapInh=");
2892 for (i = 0; i < n; i++)
2893 _dbus_verbose ("%08x", cap[(0 * n) + (n - i - 1)]);
2895 _dbus_verbose (" CapPrm=");
2896 for (i = 0; i < n; i++)
2897 _dbus_verbose ("%08x", cap[(1 * n) + (n - i - 1)]);
2899 _dbus_verbose (" CapEff=");
2900 for (i = 0; i < n; i++)
2901 _dbus_verbose ("%08x", cap[(2 * n) + (n - i - 1)]);
2903 _dbus_verbose (" CapInh=");
2904 for (i = 0; i < n; i++)
2905 _dbus_verbose ("%08x", cap[(3 * n) + (n - i - 1)]);
2906 _dbus_verbose ("\n");
2911 case KDBUS_ITEM_TIMESTAMP:
2912 handle_item_timestamp (item);
2915 case KDBUS_ITEM_BLOOM_FILTER:
2920 handle_unexpected_item (item);
2925 handle_padding (msg, item);
2927 if (!can_receive (kdbus_transport, msg, buffer, ret_size))
2928 return 0; /* ignore message if not allowed */
2934 kdbus_decode_kernel_message (const struct kdbus_msg *msg,
2935 DBusTransportKdbus *kdbus_transport)
2937 const struct kdbus_item *item;
2940 KDBUS_ITEM_FOREACH (item, msg, items)
2942 if (item->size < KDBUS_ITEM_HEADER_SIZE)
2944 _dbus_verbose (" +%s (%llu bytes) invalid data record\n", enum_MSG (item->type), item->size);
2951 case KDBUS_ITEM_REPLY_TIMEOUT:
2952 case KDBUS_ITEM_REPLY_DEAD:
2954 DBusMessage *message = NULL;
2955 _dbus_verbose (" +%s (%llu bytes) cookie=%llu\n",
2956 enum_MSG (item->type), item->size, msg->cookie_reply);
2958 message = _dbus_generate_local_error_message (msg->cookie_reply,
2959 item->type == KDBUS_ITEM_REPLY_TIMEOUT ? DBUS_ERROR_NO_REPLY : DBUS_ERROR_NAME_HAS_NO_OWNER, NULL);
2960 if (message == NULL)
2966 dbus_message_set_serial (message, get_next_client_serial (kdbus_transport));
2968 if (!add_message_to_received (message, kdbus_transport->base.connection))
2973 case KDBUS_ITEM_NAME_ADD:
2974 case KDBUS_ITEM_NAME_REMOVE:
2975 case KDBUS_ITEM_NAME_CHANGE:
2979 _dbus_verbose (" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, old flags=0x%llx, new flags=0x%llx\n",
2980 enum_MSG (item->type), (unsigned long long) item->size,
2981 item->name_change.name, item->name_change.old_id.id,
2982 item->name_change.new_id.id, item->name_change.old_id.flags,
2983 item->name_change.new_id.flags);
2985 if (item->name_change.new_id.id == _kdbus_get_id (kdbus_transport->kdbus))
2986 ret_size = generate_NameSignal ("NameAcquired", item->name_change.name, kdbus_transport);
2987 else if (item->name_change.old_id.id == _kdbus_get_id (kdbus_transport->kdbus))
2988 ret_size = generate_NameSignal ("NameLost", item->name_change.name, kdbus_transport);
2993 if (item->name_change.new_id.flags & KDBUS_NAME_ACTIVATOR)
2994 local_ret = kdbus_handle_name_owner_changed (item->type,
2995 item->name_change.name,
2996 item->name_change.old_id.id, 0,
2998 else if (item->name_change.old_id.flags & KDBUS_NAME_ACTIVATOR)
2999 local_ret = kdbus_handle_name_owner_changed (item->type,
3000 item->name_change.name, 0,
3001 item->name_change.new_id.id,
3004 local_ret = kdbus_handle_name_owner_changed (item->type,
3005 item->name_change.name,
3006 item->name_change.old_id.id,
3007 item->name_change.new_id.id,
3009 if (local_ret == -1)
3012 ret_size += local_ret;
3016 case KDBUS_ITEM_ID_ADD:
3017 case KDBUS_ITEM_ID_REMOVE:
3018 _dbus_verbose (" +%s (%llu bytes) id=%llu flags=%llu\n",
3019 enum_MSG (item->type), (unsigned long long) item->size,
3020 (unsigned long long) item->id_change.id,
3021 (unsigned long long) item->id_change.flags);
3023 if (item->id_change.flags & KDBUS_HELLO_ACTIVATOR)
3024 ret_size = kdbus_handle_name_owner_changed (item->type, NULL, 0, 0,
3027 ret_size = kdbus_handle_name_owner_changed (item->type, NULL,
3028 item->type == KDBUS_ITEM_ID_ADD ? 0 : item->id_change.id,
3029 item->type == KDBUS_ITEM_ID_ADD ? item->id_change.id : 0,
3036 case KDBUS_ITEM_TIMESTAMP:
3037 handle_item_timestamp (item);
3041 handle_unexpected_item (item);
3046 handle_padding (msg, item);
3053 * Decodes kdbus message in order to extract DBus message and puts it into received data buffer
3054 * and file descriptor's buffer. Also captures kdbus error messages and kdbus kernel broadcasts
3055 * and converts all of them into appropriate DBus messages.
3057 * @param msg kdbus message
3058 * @param data place to copy DBus message to
3059 * @param kdbus_transport transport
3060 * @param fds place to store file descriptors received
3061 * @param n_fds place to store quantity of file descriptors received
3062 * @return number of DBus message's bytes received or -1 on error
3065 kdbus_decode_msg (const struct kdbus_msg *msg,
3067 DBusTransportKdbus *kdbus_transport,
3074 #if KDBUS_MSG_DECODE_DEBUG == 1
3075 _dbus_verbose ("MESSAGE: %s (%llu bytes) flags=0x%llx, %s → %s, cookie=%llu, timeout=%llu\n",
3076 enum_PAYLOAD (msg->payload_type),
3077 (unsigned long long) msg->size,
3078 (unsigned long long) msg->flags,
3079 msg_id (msg->src_id),
3080 msg_id (msg->dst_id),
3081 (unsigned long long) msg->cookie,
3082 (unsigned long long) msg->timeout_ns);
3085 switch (msg->payload_type)
3087 case KDBUS_PAYLOAD_DBUS:
3088 ret_size = kdbus_decode_dbus_message (msg, data, kdbus_transport, fds, n_fds);
3090 case KDBUS_PAYLOAD_KERNEL:
3091 ret_size = kdbus_decode_kernel_message (msg, kdbus_transport);
3094 _dbus_assert_not_reached ("unexpected payload type from kdbus");
3102 * Reads message from kdbus and puts it into DBus buffers
3104 * @param kdbus_transport transport
3105 * @param buffer place to copy received message to
3106 * @param fds place to store file descriptors received with the message
3107 * @param n_fds place to store quantity of file descriptors received
3108 * @return size of received message on success, -1 on error
3111 kdbus_read_message (DBusTransportKdbus *kdbus_transport,
3116 int ret_size, buf_size;
3117 struct kdbus_msg *msg;
3120 dbus_uint64_t flags = 0;
3124 dbus_error_init (&error);
3126 start = _dbus_string_get_length (buffer);
3128 if (kdbus_transport->activator != NULL)
3129 flags |= KDBUS_RECV_PEEK;
3131 ret = _kdbus_recv (kdbus_transport->kdbus, flags, 0, &msg);
3135 _dbus_verbose ("kdbus error receiving message: %d (%s)\n", ret, _dbus_strerror (ret));
3139 buf_size = kdbus_message_size (msg);
3142 _dbus_verbose ("kdbus error - too short message: %d (%m)\n", errno);
3146 /* What is the maximum size of the locally generated message?
3147 I just assume 2048 bytes */
3148 buf_size = MAX (buf_size, 2048);
3150 if (!_dbus_string_lengthen (buffer, buf_size))
3155 data = _dbus_string_get_data_len (buffer, start, buf_size);
3157 ret_size = kdbus_decode_msg (msg, data, kdbus_transport, fds, n_fds, &error);
3159 if (ret_size == -1) /* error */
3160 _dbus_string_set_length (buffer, start);
3161 else if (ret_size >= 0 && buf_size != ret_size) /* case of locally generated message */
3162 _dbus_string_set_length (buffer, start + ret_size);
3165 _dbus_message_loader_set_unique_sender_id (kdbus_transport->base.loader, msg->src_id);
3167 if (kdbus_transport->activator != NULL)
3170 ret = _kdbus_free_mem (kdbus_transport->kdbus, msg);
3173 _dbus_verbose ("kdbus error freeing message: %d (%s)\n", ret, _dbus_strerror (ret));
3181 * Copy-paste from socket transport. Only renames done.
3184 free_watches (DBusTransportKdbus *kdbus_transport)
3186 DBusConnection *connection = kdbus_transport->base.connection;
3187 _dbus_verbose ("start\n");
3189 if (kdbus_transport->read_watch)
3192 _dbus_connection_remove_watch_unlocked (connection,
3193 kdbus_transport->read_watch);
3194 _dbus_watch_invalidate (kdbus_transport->read_watch);
3195 _dbus_watch_unref (kdbus_transport->read_watch);
3196 kdbus_transport->read_watch = NULL;
3199 if (kdbus_transport->write_watch)
3202 _dbus_connection_remove_watch_unlocked (connection,
3203 kdbus_transport->write_watch);
3204 _dbus_watch_invalidate (kdbus_transport->write_watch);
3205 _dbus_watch_unref (kdbus_transport->write_watch);
3206 kdbus_transport->write_watch = NULL;
3209 _dbus_verbose ("end\n");
3213 free_policies (DBusTransportKdbus *transport)
3215 #ifdef LIBDBUSPOLICY
3216 if (NULL != transport->policy)
3217 dbuspolicy1_free (transport->policy);
3222 * Copy-paste from socket transport. Only done needed renames and removed
3223 * lines related to encoded messages.
3226 transport_finalize (DBusTransport *transport)
3228 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus *)transport;
3229 _dbus_verbose ("\n");
3231 free_watches (kdbus_transport);
3233 _dbus_transport_finalize_base (transport);
3235 _dbus_assert (kdbus_transport->read_watch == NULL);
3236 _dbus_assert (kdbus_transport->write_watch == NULL);
3238 free_matchmaker (kdbus_transport->matchmaker);
3240 dbus_free (kdbus_transport->activator);
3242 free_policies ( kdbus_transport );
3244 _kdbus_free (kdbus_transport->kdbus);
3245 free (kdbus_transport->my_DBus_unique_name);
3247 dbus_free (transport);
3251 * Copy-paste from socket transport. Removed code related to authentication,
3252 * socket_transport replaced by kdbus_transport.
3255 check_write_watch (DBusTransportKdbus *kdbus_transport)
3258 DBusTransport *transport = &kdbus_transport->base;
3260 if (transport->connection == NULL)
3263 if (transport->disconnected)
3265 _dbus_assert (kdbus_transport->write_watch == NULL);
3269 _dbus_transport_ref (transport);
3271 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
3273 _dbus_verbose ("check_write_watch (): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
3274 needed, transport->connection, kdbus_transport->write_watch,
3275 _kdbus_get_fd (kdbus_transport->kdbus),
3276 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3278 _dbus_connection_toggle_watch_unlocked (transport->connection,
3279 kdbus_transport->write_watch,
3282 _dbus_transport_unref (transport);
3286 * Copy-paste from socket transport. Removed code related to authentication,
3287 * socket_transport replaced by kdbus_transport.
3290 check_read_watch (DBusTransportKdbus *kdbus_transport)
3292 dbus_bool_t need_read_watch;
3293 DBusTransport *transport = &kdbus_transport->base;
3295 _dbus_verbose ("fd = %d\n",_kdbus_get_fd (kdbus_transport->kdbus));
3297 if (transport->connection == NULL)
3300 if (transport->disconnected)
3302 _dbus_assert (kdbus_transport->read_watch == NULL);
3306 _dbus_transport_ref (transport);
3309 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
3310 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
3312 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
3314 _dbus_connection_toggle_watch_unlocked (transport->connection,
3315 kdbus_transport->read_watch,
3318 _dbus_transport_unref (transport);
3322 * Copy-paste from socket transport.
3325 do_io_error (DBusTransport *transport)
3327 _dbus_transport_ref (transport);
3328 _dbus_transport_disconnect (transport);
3329 _dbus_transport_unref (transport);
3333 * Based on do_writing from socket transport.
3334 * Removed authentication code and code related to encoded messages
3335 * and adapted to kdbus transport.
3336 * In socket transport returns false on out-of-memory. Here this won't happen,
3337 * so it always returns TRUE.
3340 do_writing (DBusTransport *transport)
3342 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3344 dbus_bool_t oom = FALSE;
3346 if (transport->disconnected)
3348 _dbus_verbose ("Not connected, not writing anything\n");
3352 _dbus_verbose ("do_writing (), have_messages = %d, fd = %d\n",
3353 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
3354 _kdbus_get_fd (kdbus_transport->kdbus));
3356 while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
3359 DBusMessage *message;
3361 const DBusString *header;
3362 const DBusString *body;
3363 const char* pDestination;
3365 if (total > kdbus_transport->max_bytes_written_per_iteration)
3367 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
3368 total, kdbus_transport->max_bytes_written_per_iteration);
3373 message = _dbus_connection_get_message_to_send (transport->connection);
3374 _dbus_assert (message != NULL);
3375 pDestination = dbus_message_get_destination (message);
3381 ret = capture_org_freedesktop_DBus ((DBusTransportKdbus*)transport, pDestination, message, &reply);
3382 if (ret < 0) //error
3387 else if (ret == 0) //message captured and handled correctly
3389 /* puts locally generated reply into received messages queue */
3390 if (!add_message_to_received (reply, kdbus_transport->base.connection))
3396 _dbus_message_get_network_data (message, &header, &body);
3397 bytes_written = _dbus_string_get_length (header) + _dbus_string_get_length (body);
3400 //else send as regular message
3403 bytes_written = kdbus_write_msg (kdbus_transport, message, pDestination);
3406 if (bytes_written < 0)
3408 if (errno == ENOMEM)
3414 /* EINTR already handled for us */
3416 /* For some discussion of why we also ignore EPIPE here, see
3417 * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
3420 if (_dbus_get_is_errno_eagain_or_ewouldblock (errno) || _dbus_get_is_errno_epipe (errno))
3424 _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
3425 do_io_error (transport);
3431 #if defined (DBUS_ENABLE_VERBOSE_MODE) || !defined (DBUS_DISABLE_ASSERT)
3432 int total_bytes_to_write;
3434 _dbus_message_get_network_data (message, &header, &body);
3435 total_bytes_to_write = _dbus_string_get_length (header)
3436 + _dbus_string_get_length (body);
3437 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
3438 total_bytes_to_write);
3440 _dbus_assert (bytes_written == total_bytes_to_write);
3442 total += bytes_written;
3444 _dbus_connection_message_sent_unlocked (transport->connection,
3457 * Based on do_reading from socket transport.
3458 * Removed authentication code and code related to encoded messages
3459 * and adapted to kdbus transport.
3460 * returns false on out-of-memory
3463 do_reading (DBusTransport *transport)
3465 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3468 dbus_bool_t oom = FALSE;
3472 _dbus_verbose ("fd = %d\n", _kdbus_get_fd (kdbus_transport->kdbus));
3476 /* See if we've exceeded max messages and need to disable reading */
3477 if (kdbus_transport->activator == NULL)
3478 check_read_watch (kdbus_transport);
3480 if (total > kdbus_transport->max_bytes_read_per_iteration)
3482 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
3483 total, kdbus_transport->max_bytes_read_per_iteration);
3487 _dbus_assert (kdbus_transport->read_watch != NULL ||
3488 transport->disconnected);
3490 if (transport->disconnected)
3493 if (!dbus_watch_get_enabled (kdbus_transport->read_watch))
3496 if (!_dbus_message_loader_get_unix_fds (transport->loader, &fds, &n_fds))
3498 _dbus_verbose ("Out of memory reading file descriptors\n");
3502 _dbus_message_loader_get_buffer (transport->loader, &buffer);
3504 bytes_read = kdbus_read_message (kdbus_transport, buffer, fds, &n_fds);
3506 if (bytes_read >= 0 && n_fds > 0)
3507 _dbus_verbose ("Read %i unix fds\n", n_fds);
3509 _dbus_message_loader_return_buffer (transport->loader,
3511 _dbus_message_loader_return_unix_fds (transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
3515 /* EINTR already handled for us */
3517 if (_dbus_get_is_errno_enomem (errno))
3519 _dbus_verbose ("Out of memory in read()/do_reading()\n");
3523 else if (_dbus_get_is_errno_eagain_or_ewouldblock (errno))
3527 _dbus_verbose ("Error reading from remote app: %s\n",
3528 _dbus_strerror_from_errno ());
3529 do_io_error (transport);
3533 else if (bytes_read > 0)
3535 _dbus_verbose (" read %d bytes\n", bytes_read);
3537 total += bytes_read;
3539 if (!_dbus_transport_queue_messages (transport))
3542 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
3546 /* Try reading more data until we get EAGAIN and return, or
3547 * exceed max bytes per iteration. If in blocking mode of
3548 * course we'll block instead of returning.
3552 /* 0 == bytes_read is for kernel and ignored messages */
3561 * Copy-paste from socket transport, with socket replaced by kdbus.
3564 unix_error_with_read_to_come (DBusTransport *itransport,
3568 DBusTransportKdbus *transport = (DBusTransportKdbus *) itransport;
3570 if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
3573 /* If we have a read watch enabled ...
3574 we -might have data incoming ... => handle the HANGUP there */
3575 if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
3582 * Copy-paste from socket transport. Removed authentication related code
3583 * and renamed socket_transport to kdbus_transport.
3586 kdbus_handle_watch (DBusTransport *transport,
3590 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3592 _dbus_assert (watch == kdbus_transport->read_watch ||
3593 watch == kdbus_transport->write_watch);
3594 _dbus_assert (watch != NULL);
3596 /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
3597 * still be in the buffer and do_reading may need several iteration to read
3598 * it all (because of its max_bytes_read_per_iteration limit).
3600 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
3602 _dbus_verbose ("Hang up or error on watch\n");
3603 _dbus_transport_disconnect (transport);
3607 if (watch == kdbus_transport->read_watch &&
3608 (flags & DBUS_WATCH_READABLE))
3610 _dbus_verbose ("handling read watch %p flags = %x\n",
3613 if (!do_reading (transport))
3615 _dbus_verbose ("no memory to read\n");
3619 else if (watch == kdbus_transport->write_watch &&
3620 (flags & DBUS_WATCH_WRITABLE))
3622 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
3623 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
3625 if (!do_writing (transport))
3627 _dbus_verbose ("no memory to write\n");
3631 /* See if we still need the write watch */
3632 check_write_watch (kdbus_transport);
3639 * Copy-paste from socket transport, but socket_transport renamed to kdbus_transport
3640 * and _dbus_close_socket replaced with close ().
3643 kdbus_disconnect (DBusTransport *transport)
3645 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3647 _dbus_verbose ("\n");
3649 free_watches (kdbus_transport);
3651 _kdbus_close (kdbus_transport->kdbus);
3655 * Copy-paste from socket transport. Renamed socket_transport to
3656 * kdbus_transport and added setting authenticated to TRUE, because
3657 * we do not perform authentication in kdbus, so we have mark is as already done
3658 * to make everything work.
3661 kdbus_connection_set (DBusTransport *transport)
3663 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3665 _dbus_watch_set_handler (kdbus_transport->write_watch,
3666 _dbus_connection_handle_watch,
3667 transport->connection, NULL);
3669 _dbus_watch_set_handler (kdbus_transport->read_watch,
3670 _dbus_connection_handle_watch,
3671 transport->connection, NULL);
3673 if (!_dbus_connection_add_watch_unlocked (transport->connection,
3674 kdbus_transport->write_watch))
3677 if (!_dbus_connection_add_watch_unlocked (transport->connection,
3678 kdbus_transport->read_watch))
3680 _dbus_connection_remove_watch_unlocked (transport->connection,
3681 kdbus_transport->write_watch);
3685 check_read_watch (kdbus_transport);
3686 check_write_watch (kdbus_transport);
3692 * Copy-paste from socket_transport.
3693 * Socket_transport renamed to kdbus_transport
3695 * Original dbus copy-pasted @todo comment below.
3696 * @todo We need to have a way to wake up the select sleep if
3697 * a new iteration request comes in with a flag (read/write) that
3698 * we're not currently serving. Otherwise a call that just reads
3699 * could block a write call forever (if there are no incoming
3703 kdbus_do_iteration (DBusTransport *transport,
3705 int timeout_milliseconds)
3707 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3712 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
3713 flags & DBUS_ITERATION_DO_READING ? "read" : "",
3714 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
3715 timeout_milliseconds,
3716 kdbus_transport->read_watch,
3717 kdbus_transport->write_watch,
3718 _kdbus_get_fd (kdbus_transport->kdbus));
3720 poll_fd.fd = _kdbus_get_fd (kdbus_transport->kdbus);
3725 * This fix is for reply_with_error function.
3726 * When timeout is set to -1 in client application,
3727 * error messages are inserted directly to incoming queue and
3728 * application hangs on dbus_poll.
3730 * This causes a busy loop in _dbus_connection_block_pending_call()
3731 * There is no case of waiting for the locally-generated error reply
3733 if (_dbus_connection_get_n_incoming (transport->connection) > 0)
3735 timeout_milliseconds = 0;
3739 /* This is kind of a hack; if we have stuff to write, then try
3740 * to avoid the poll. This is probably about a 5% speedup on an
3741 * echo client/server.
3743 * If both reading and writing were requested, we want to avoid this
3744 * since it could have funky effects:
3745 * - both ends spinning waiting for the other one to read
3746 * data so they can finish writing
3747 * - prioritizing all writing ahead of reading
3749 if ((flags & DBUS_ITERATION_DO_WRITING) &&
3750 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
3751 !transport->disconnected &&
3752 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
3754 do_writing (transport);
3756 if (transport->disconnected ||
3757 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
3761 /* If we get here, we decided to do the poll() after all */
3762 _dbus_assert (kdbus_transport->read_watch);
3763 if (flags & DBUS_ITERATION_DO_READING)
3764 poll_fd.events |= _DBUS_POLLIN;
3766 _dbus_assert (kdbus_transport->write_watch);
3767 if (flags & DBUS_ITERATION_DO_WRITING)
3768 poll_fd.events |= _DBUS_POLLOUT;
3772 if ( (flags & DBUS_ITERATION_BLOCK) && !(flags & DBUS_ITERATION_DO_WRITING))
3773 poll_timeout = timeout_milliseconds;
3777 /* For blocking selects we drop the connection lock here
3778 * to avoid blocking out connection access during a potentially
3779 * indefinite blocking call. The io path is still protected
3780 * by the io_path_cond condvar, so we won't reenter this.
3782 if (flags & DBUS_ITERATION_BLOCK)
3784 _dbus_verbose ("unlock pre poll\n");
3785 _dbus_connection_unlock (transport->connection);
3789 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
3791 if (poll_res < 0 && _dbus_get_is_errno_eintr (errno))
3794 if (flags & DBUS_ITERATION_BLOCK)
3796 _dbus_verbose ("lock post poll\n");
3797 _dbus_connection_lock (transport->connection);
3803 poll_fd.revents = 0; /* some concern that posix does not guarantee this;
3804 * valgrind flags it as an error. though it probably
3805 * is guaranteed on linux at least.
3808 if (poll_fd.revents & _DBUS_POLLERR)
3809 do_io_error (transport);
3812 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
3814 _dbus_verbose ("in iteration, need_read=%d\n",
3817 if (need_read && (flags & DBUS_ITERATION_DO_READING))
3818 do_reading (transport);
3819 /* We always be able to write to kdbus */
3820 if (flags & DBUS_ITERATION_DO_WRITING)
3821 do_writing (transport);
3825 _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
3829 /* We need to install the write watch only if we did not
3830 * successfully write everything. Note we need to be careful that we
3831 * don't call check_write_watch *before* do_writing, since it's
3832 * inefficient to add the write watch, and we can avoid it most of
3833 * the time since we can write immediately.
3835 * However, we MUST always call check_write_watch(); DBusConnection code
3836 * relies on the fact that running an iteration will notice that
3837 * messages are pending.
3839 check_write_watch (kdbus_transport);
3841 _dbus_verbose (" ... leaving do_iteration()\n");
3845 * Copy-paste from socket transport.
3848 kdbus_live_messages_changed (DBusTransport *transport)
3850 /* See if we should look for incoming messages again */
3851 check_read_watch ((DBusTransportKdbus *)transport);
3855 * Gets file descriptor of the kdbus bus.
3856 * @param transport transport
3857 * @param fd_p place to write fd to
3858 * @returns always TRUE
3861 kdbus_get_kdbus_fd (DBusTransport *transport,
3864 DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
3866 fd_p->fd = _kdbus_get_fd (kdbus_transport->kdbus);
3871 static const DBusTransportVTable kdbus_vtable = {
3875 kdbus_connection_set,
3877 kdbus_live_messages_changed,
3881 typedef unsigned long (*ConnectionInfoExtractField) (struct nameInfo *);
3883 static inline unsigned long
3884 _extract_name_info_userId (struct nameInfo *nameInfo)
3886 return nameInfo->userId;
3889 static inline unsigned long
3890 _extract_name_info_processId (struct nameInfo *nameInfo)
3892 return nameInfo->processId;
3896 _dbus_transport_kdbus_get_connection_info_ulong_field (DBusTransportKdbus *transport,
3897 ConnectionInfoExtractField function,
3900 struct nameInfo conn_info;
3903 ret = _kdbus_connection_info_by_id (transport->kdbus,
3904 _kdbus_get_id (transport->kdbus),
3910 *val = function (&conn_info);
3915 _dbus_transport_kdbus_get_unix_user (DBusTransport *transport,
3918 return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
3919 _extract_name_info_userId,
3924 _dbus_transport_kdbus_get_unix_process_id (DBusTransport *transport,
3927 return _dbus_transport_kdbus_get_connection_info_ulong_field ((DBusTransportKdbus *)transport,
3928 _extract_name_info_processId,
3933 * Copy-paste from dbus_transport_socket with needed changes.
3935 * Creates a new transport for the given kdbus file descriptor and address.
3936 * The file descriptor must be nonblocking.
3938 * @param fd the file descriptor.
3939 * @param address the transport's address
3940 * @returns the new transport, or #NULL if no memory.
3942 static DBusTransportKdbus *
3943 new_kdbus_transport (kdbus_t *kdbus,
3944 const DBusString *address,
3945 const char *activator)
3947 DBusTransportKdbus *kdbus_transport;
3949 kdbus_transport = dbus_new0 (DBusTransportKdbus, 1);
3950 if (kdbus_transport == NULL)
3953 kdbus_transport->kdbus = kdbus;
3955 kdbus_transport->write_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
3956 DBUS_WATCH_WRITABLE,
3959 if (kdbus_transport->write_watch == NULL)
3962 kdbus_transport->read_watch = _dbus_watch_new (_kdbus_get_fd (kdbus),
3963 DBUS_WATCH_READABLE,
3966 if (kdbus_transport->read_watch == NULL)
3969 if (!_dbus_transport_init_base_authenticated (&kdbus_transport->base,
3974 _dbus_transport_set_get_unix_user_function (&kdbus_transport->base,
3975 _dbus_transport_kdbus_get_unix_user);
3976 _dbus_transport_set_get_unix_process_id_function (&kdbus_transport->base,
3977 _dbus_transport_kdbus_get_unix_process_id);
3978 _dbus_transport_set_assure_protocol_function (&kdbus_transport->base,
3979 _dbus_message_assure_gvariant,
3980 DBUS_PROTOCOL_VERSION_GVARIANT);
3982 /* These values should probably be tunable or something. */
3983 kdbus_transport->max_bytes_read_per_iteration = MAX_BYTES_PER_ITERATION;
3984 kdbus_transport->max_bytes_written_per_iteration = MAX_BYTES_PER_ITERATION;
3986 if (activator!=NULL)
3988 kdbus_transport->activator = _dbus_strdup (activator);
3989 if (kdbus_transport->activator == NULL)
3993 kdbus_transport->matchmaker = matchmaker_new ();
3995 kdbus_transport->client_serial = 1;
3997 return kdbus_transport;
4000 _dbus_watch_invalidate (kdbus_transport->read_watch);
4001 _dbus_watch_unref (kdbus_transport->read_watch);
4003 _dbus_watch_invalidate (kdbus_transport->write_watch);
4004 _dbus_watch_unref (kdbus_transport->write_watch);
4006 dbus_free (kdbus_transport);
4011 initialize_policies (DBusTransportKdbus *transport, const char *path)
4013 dbus_bool_t result = TRUE;
4015 #ifdef LIBDBUSPOLICY
4016 transport->policy = dbuspolicy1_init (path);
4017 if (NULL == transport->policy)
4025 * Connects to kdbus, creates and sets-up transport.
4027 * @param path the path to the bus.
4028 * @param error address where an error can be returned.
4029 * @returns a new transport, or #NULL on failure.
4031 static DBusTransport*
4032 _dbus_transport_new_for_kdbus (const char *path,
4033 const char *activator,
4037 DBusTransportKdbus *transport;
4041 #ifdef DBUS_ENABLE_VERBOSE_MODE
4042 const char *dbgenv = _dbus_getenv ("G_DBUS_DEBUG");
4045 if (!strcmp (dbgenv, "message"))
4047 else if (!strcmp (dbgenv, "all"))
4052 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4054 if (!_dbus_string_init (&address))
4056 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4060 if ((!_dbus_string_append (&address, DBUS_ADDRESS_KDBUS "path=")) || (!_dbus_string_append (&address, path)))
4062 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4066 kdbus = _kdbus_new ();
4069 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4073 ret = _kdbus_open (kdbus, path);
4076 dbus_set_error (error,
4077 _dbus_error_from_errno (-ret),
4078 "Failed to open file descriptor: %s: %s",
4080 _dbus_strerror (-ret));
4081 goto failed_0_with_kdbus;
4084 _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
4086 transport = new_kdbus_transport (kdbus, &address, activator);
4087 if (transport == NULL)
4089 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4093 if (!initialize_policies (transport, path))
4095 dbus_set_error (error,
4097 "Can't load dbus policy for kdbus transport");
4098 _kdbus_close (kdbus);
4099 transport_finalize ((DBusTransport*)transport);
4103 _dbus_string_free (&address);
4105 return (DBusTransport*)transport;
4108 _kdbus_close (kdbus);
4109 failed_0_with_kdbus:
4110 _kdbus_free (kdbus);
4112 _dbus_string_free (&address);
4118 * Opens kdbus transport if method from address entry is kdbus
4120 * @param entry the address entry to open
4121 * @param transport_p return location for the opened transport
4122 * @param error place to store error
4123 * @returns result of the attempt as a DBusTransportOpenResult enum
4125 DBusTransportOpenResult
4126 _dbus_transport_open_kdbus (DBusAddressEntry *entry,
4127 DBusTransport **transport_p,
4132 method = dbus_address_entry_get_method (entry);
4133 _dbus_assert (method != NULL);
4135 if (strcmp (method, "kernel") == 0)
4137 const char *path = dbus_address_entry_get_value (entry, "path");
4138 const char *activator = dbus_address_entry_get_value (entry, "activator");
4142 _dbus_set_bad_address (error, "kdbus", "path", NULL);
4143 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
4146 *transport_p = _dbus_transport_new_for_kdbus (path, activator, error);
4148 if (*transport_p == NULL)
4150 _DBUS_ASSERT_ERROR_IS_SET (error);
4151 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
4155 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4156 return DBUS_TRANSPORT_OPEN_OK;
4161 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4162 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;