[daemon-dev][lib-opt] Fix in freeing memory, cleanup, comments, renames
[platform/upstream/dbus.git] / dbus / dbus-transport-kdbus.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport-kdbus.c  kdbus subclasses of DBusTransport
3  *
4  * Copyright (C) 2002, 2003, 2004, 2006  Red Hat Inc
5  * Copyright (C) 2013  Samsung Electronics
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version and under the terms of the GNU
13  * Lesser General Public License as published by the
14  * Free Software Foundation; either version 2.1 of the License, or (at
15  * your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  */
27 #include "dbus-transport.h"
28 #include "dbus-transport-kdbus.h"
29 #include "dbus-transport-protected.h"
30 #include "dbus-connection-internal.h"
31 #include "kdbus.h"
32 #include "dbus-watch.h"
33 #include "dbus-errors.h"
34 #include "dbus-bus.h"
35 #include "kdbus-common.h"
36 #include <linux/types.h>
37 #include <fcntl.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <sys/ioctl.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <sys/mman.h>
46 #include <limits.h>
47 #include <sys/stat.h>
48
49 #define KDBUS_PART_FOREACH(part, head, first)                           \
50         for (part = (head)->first;                                      \
51              (uint8_t *)(part) < (uint8_t *)(head) + (head)->size;      \
52              part = KDBUS_PART_NEXT(part))
53 #define RECEIVE_POOL_SIZE (10 * 1024LU * 1024LU)
54 #define MEMFD_SIZE_THRESHOLD (2 * 1024 * 1024LU) // over this memfd is used
55
56 #define KDBUS_MSG_DECODE_DEBUG 0
57 //#define DBUS_AUTHENTICATION
58
59 #define ITER_APPEND_STR(string) \
60 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string))   \
61 { \
62         ret_size = -1;  \
63         goto out;  \
64 }\
65
66 #define MSG_ITEM_BUILD_VEC(data, datasize)                                    \
67         item->type = KDBUS_MSG_PAYLOAD_VEC;                                     \
68         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);         \
69         item->vec.address = (unsigned long) data;                               \
70         item->vec.size = datasize;
71
72 /**
73  * Opaque object representing a transport. In kdbus transport it has nothing common
74  * with socket, but the name was preserved to comply with  upper functions.
75  */
76 typedef struct DBusTransportKdbus DBusTransportKdbus;
77
78 /**
79  * Implementation details of DBusTransportSocket. All members are private.
80  */
81 struct DBusTransportKdbus
82 {
83   DBusTransport base;                   /**< Parent instance */
84   int fd;                               /**< File descriptor. */
85   DBusWatch *read_watch;                /**< Watch for readability. */
86   DBusWatch *write_watch;               /**< Watch for writability. */
87
88   int max_bytes_read_per_iteration;     /**< In kdbus only to control overall message size*/
89   int max_bytes_written_per_iteration;  /**< In kdbus only to control overall message size*/
90
91   int message_bytes_written;            /**< Number of bytes of current
92                                          *   outgoing message that have
93                                          *   been written.
94                                          */
95   DBusString encoded_outgoing;          /**< Encoded version of current
96                                          *   outgoing message.
97                                          */
98   DBusString encoded_incoming;          /**< Encoded version of current
99                                          *   incoming data.
100                                          */
101   void* kdbus_mmap_ptr;                 /**< Mapped memory where Kdbus (kernel) writes
102                                          *   messages incoming to us.
103                                          */
104   int memfd;                            /**< File descriptor to special 
105                                          *   memory pool for bulk data
106                                          *   transfer. Retrieved from 
107                                          *   Kdbus kernel module. 
108                                          */
109   __u64 bloom_size;                                             /**<  bloom filter field size */
110   char* sender;                         /**< uniqe name of the sender */
111 };
112
113 static dbus_bool_t
114 kdbus_get_kdbus_fd (DBusTransport *transport,
115                       int           *fd_p)
116 {
117   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
118
119   *fd_p = kdbus_transport->fd;
120
121   return TRUE;
122 }
123
124 /*
125  * Adds locally generated message to received messages queue
126  *
127  */
128 static dbus_bool_t add_message_to_received(DBusMessage *message, DBusConnection* connection)
129 {
130         DBusList *message_link;
131
132         message_link = _dbus_list_alloc_link (message);
133         if (message_link == NULL)
134         {
135                 dbus_message_unref (message);
136                 return FALSE;
137         }
138
139         _dbus_connection_queue_synthesized_message_link(connection, message_link);
140
141         return TRUE;
142 }
143
144 /*
145  * Generates local error message as a reply to message given as parameter
146  * and adds generated error message to received messages queue.
147  */
148 static int reply_with_error(char* error_type, const char* template, const char* object, DBusMessage *message, DBusConnection* connection)
149 {
150         DBusMessage *errMessage;
151         char* error_msg = "";
152
153         if(template)
154         {
155                 error_msg = alloca(strlen(template) + strlen(object));
156                 sprintf(error_msg, template, object);
157         }
158         else if(object)
159                 error_msg = (char*)object;
160
161         errMessage = generate_local_error_message(dbus_message_get_serial(message), error_type, error_msg);
162         if(errMessage == NULL)
163                 return -1;
164         if (add_message_to_received(errMessage, connection))
165                 return 0;
166
167         return -1;
168 }
169
170 /*
171  *  Generates reply to the message given as a parameter with one item in the reply body
172  *  and adds generated reply message to received messages queue.
173  */
174 static int reply_1_data(DBusMessage *message, int data_type, void* pData, DBusConnection* connection)
175 {
176         DBusMessageIter args;
177         DBusMessage *reply;
178
179         reply = dbus_message_new_method_return(message);
180         if(reply == NULL)
181                 return -1;
182         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
183     dbus_message_iter_init_append(reply, &args);
184     if (!dbus_message_iter_append_basic(&args, data_type, pData))
185     {
186         dbus_message_unref(reply);
187         return -1;
188     }
189     if(add_message_to_received(reply, connection))
190         return 0;
191
192     return -1;
193 }
194
195 /*
196 static int reply_ack(DBusMessage *message, DBusConnection* connection)
197 {
198         DBusMessage *reply;
199
200         reply = dbus_message_new_method_return(message);
201         if(reply == NULL)
202                 return -1;
203     if(add_message_to_received(reply, connection))
204         return 0;
205     return -1;
206 }*/
207
208 /**
209  * Retrieves file descriptor to memory pool from kdbus module.
210  * It is then used for bulk data sending.
211  * Triggered when message payload is over MEMFD_SIZE_THRESHOLD
212  * 
213  */
214 static int kdbus_init_memfd(DBusTransportKdbus* socket_transport)
215 {
216         int memfd;
217         
218                 if (ioctl(socket_transport->fd, KDBUS_CMD_MEMFD_NEW, &memfd) < 0) {
219                         _dbus_verbose("KDBUS_CMD_MEMFD_NEW failed: \n");
220                         return -1;
221                 }
222
223                 socket_transport->memfd = memfd;
224                 _dbus_verbose("kdbus_init_memfd: %d!!\n", socket_transport->memfd);
225         return 0;
226 }
227
228 /**
229  * Initiates Kdbus message structure. 
230  * Calculates it's size, allocates memory and fills some fields.
231  * @param name Well-known name or NULL
232  * @param dst_id Numeric id of recipient
233  * @param body_size size of message body if present
234  * @param use_memfd flag to build memfd message
235  * @param fds_count number of file descriptors used
236  * @param transport transport
237  * @return initialized kdbus message
238  */
239 static struct kdbus_msg* kdbus_init_msg(const char* name, __u64 dst_id, uint64_t body_size, dbus_bool_t use_memfd, int fds_count, DBusTransportKdbus *transport)
240 {
241     struct kdbus_msg* msg;
242     uint64_t msg_size;
243
244     msg_size = sizeof(struct kdbus_msg);
245
246     if(use_memfd == TRUE)  // bulk data - memfd - encoded and plain
247         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
248     else {
249         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
250         if(body_size)
251                 msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
252     }
253
254     if(fds_count)
255         msg_size += KDBUS_ITEM_SIZE(sizeof(int)*fds_count);
256
257     if (name)
258         msg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
259     else if (dst_id == KDBUS_DST_ID_BROADCAST)
260         msg_size += KDBUS_PART_HEADER_SIZE + transport->bloom_size;
261
262     msg = malloc(msg_size);
263     if (!msg)
264     {
265         _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
266                 return NULL;
267     }
268
269     memset(msg, 0, msg_size);
270     msg->size = msg_size;
271     msg->payload_type = KDBUS_PAYLOAD_DBUS1;
272     msg->dst_id = name ? 0 : dst_id;
273     msg->src_id = strtoull(dbus_bus_get_unique_name(transport->base.connection), NULL , 10);
274
275     return msg;
276 }
277
278 /**
279  * Builds and sends kdbus message using DBus message.
280  * Decide whether used payload vector or memfd memory pool.
281  * Handles broadcasts and unicast messages, and passing of Unix fds.
282  * Does error handling.
283  * TODO refactor to be more compact
284  *
285  * @param transport transport
286  * @param message DBus message to be sent
287  * @param encoded flag if the message is encoded
288  * @return size of data sent
289  */
290 static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message, const char* destination, dbus_bool_t encoded)
291 {
292     struct kdbus_msg *msg;
293     struct kdbus_item *item;
294     uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
295     const DBusString *header;
296     const DBusString *body;
297     uint64_t ret_size = 0;
298     uint64_t body_size = 0;
299     uint64_t header_size = 0;
300     dbus_bool_t use_memfd;
301     const int *unix_fds;
302     unsigned fds_count;
303     dbus_bool_t autostart;
304
305     // determine destination and destination id
306     if(destination)
307     {
308         dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
309                 if((destination[0] == ':') && (destination[1] == '1') && (destination[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
310         {
311                 dst_id = strtoull(&destination[3], NULL, 10);
312                 destination = NULL;
313         }    
314     }
315     
316     // get size of data
317     if(encoded)
318         ret_size = _dbus_string_get_length (&transport->encoded_outgoing);
319     else
320     {
321         _dbus_message_get_network_data (message, &header, &body);
322         header_size = _dbus_string_get_length(header);
323         body_size = _dbus_string_get_length(body);
324         ret_size = header_size + body_size;
325     }
326
327     // check if message size is big enough to use memfd kdbus transport
328     use_memfd = ret_size > MEMFD_SIZE_THRESHOLD ? TRUE : FALSE;
329     if(use_memfd) kdbus_init_memfd(transport);
330     
331     _dbus_message_get_unix_fds(message, &unix_fds, &fds_count);
332
333     // init basic message fields
334     msg = kdbus_init_msg(destination, dst_id, body_size, use_memfd, fds_count, transport);
335     msg->cookie = dbus_message_get_serial(message);
336     autostart = dbus_message_get_auto_start (message);
337     if(!autostart)
338         msg->flags |= KDBUS_MSG_FLAGS_NO_AUTO_START;
339     
340     // build message contents
341     item = msg->items;
342
343     // case 1 - bulk data transfer - memfd - encoded and plain
344     if(use_memfd)          
345     {
346         char *buf;
347
348         if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 0) < 0)
349             {
350                         _dbus_verbose("memfd sealing failed: \n");
351                         goto out;
352             }
353
354             buf = mmap(NULL, ret_size, PROT_WRITE, MAP_SHARED, transport->memfd, 0);
355             if (buf == MAP_FAILED) 
356             {
357                         _dbus_verbose("mmap() fd=%i failed:%m", transport->memfd);
358                         goto out;
359             }
360
361                 if(encoded)
362                         memcpy(buf, &transport->encoded_outgoing, ret_size);
363                 else
364                 {
365                         memcpy(buf, _dbus_string_get_const_data(header), header_size);
366                         if(body_size) {
367                                 buf+=header_size;
368                                 memcpy(buf, _dbus_string_get_const_data(body),  body_size);
369                                 buf-=header_size;
370                         }
371                 }
372
373                 munmap(buf, ret_size);
374
375                 // seal data - kdbus module needs it
376                 if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) < 0) {
377                         _dbus_verbose("memfd sealing failed: %d (%m)\n", errno);
378                         ret_size = -1;
379                         goto out;
380                 }
381
382             item->type = KDBUS_MSG_PAYLOAD_MEMFD;
383                 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_memfd);
384                 item->memfd.size = ret_size;
385                 item->memfd.fd = transport->memfd;
386     // case 2 - small encoded - don't use memfd
387     } else if(encoded) { 
388         _dbus_verbose("sending encoded data\n");
389         MSG_ITEM_BUILD_VEC(&transport->encoded_outgoing, _dbus_string_get_length (&transport->encoded_outgoing));
390
391     // case 3 - small not encoded - don't use memfd
392     } else { 
393         _dbus_verbose("sending normal vector data\n");
394         MSG_ITEM_BUILD_VEC(_dbus_string_get_const_data(header), header_size);
395
396         if(body_size)
397         {
398             _dbus_verbose("body attaching\n");
399             item = KDBUS_PART_NEXT(item);
400             MSG_ITEM_BUILD_VEC(_dbus_string_get_const_data(body), body_size);
401         }
402     }
403
404     if(fds_count)
405     {
406         item = KDBUS_PART_NEXT(item);
407         item->type = KDBUS_MSG_FDS;
408         item->size = KDBUS_PART_HEADER_SIZE + (sizeof(int) * fds_count);
409         memcpy(item->fds, unix_fds, sizeof(int) * fds_count);
410     }
411
412         if (destination)
413         {
414                 item = KDBUS_PART_NEXT(item);
415                 item->type = KDBUS_MSG_DST_NAME;
416                 item->size = KDBUS_PART_HEADER_SIZE + strlen(destination) + 1;
417                 memcpy(item->str, destination, item->size - KDBUS_PART_HEADER_SIZE);
418         }
419         else if (dst_id == KDBUS_DST_ID_BROADCAST)
420         {
421                 item = KDBUS_PART_NEXT(item);
422                 item->type = KDBUS_MSG_BLOOM;
423                 item->size = KDBUS_PART_HEADER_SIZE + transport->bloom_size;
424                 strncpy(item->data, dbus_message_get_interface(message), transport->bloom_size);
425         }
426
427         again:
428         if (ioctl(transport->fd, KDBUS_CMD_MSG_SEND, msg))
429         {
430                 if(errno == EINTR)
431                         goto again;
432                 else if(errno == ENXIO) //no such id on the bus
433                 {
434             if(!reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Name \"%s\" does not exist", dbus_message_get_destination(message), message, transport->base.connection))
435                 goto out;
436                 }
437         else if((errno == ESRCH) || (errno = EADDRNOTAVAIL))  //when well known name is not available on the bus
438                 {
439                         if(autostart)
440                         {
441                                 if(!reply_with_error(DBUS_ERROR_SERVICE_UNKNOWN, "The name %s was not provided by any .service files", dbus_message_get_destination(message), message, transport->base.connection))
442                                         goto out;
443                         }
444                         else
445                     if(!reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Name \"%s\" does not exist", dbus_message_get_destination(message), message, transport->base.connection))
446                         goto out;
447                 }
448                 _dbus_verbose("kdbus error sending message: err %d (%m)\n", errno);
449                 ret_size = -1;
450         }
451 out:
452     free(msg);
453     if(use_memfd)
454         close(transport->memfd);
455
456     return ret_size;
457 }
458
459 /**
460  * Performs kdbus query of id of the given name
461  *
462  * @param name name to query for
463  * @param transport transport
464  * @param pInfo nameInfo structure address to store info about the name
465  * @return 0 on success, -errno if failed
466  */
467 int kdbus_NameQuery(const char* name, DBusTransport* transport, struct nameInfo* pInfo)
468 {
469         struct kdbus_cmd_name_info *msg;
470         struct kdbus_item *item;
471         uint64_t size;
472         int ret;
473         uint64_t item_size;
474
475         pInfo->sec_label_len = 0;
476         pInfo->sec_label = NULL;
477         
478     item_size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
479         item_size = (item_size < 56) ? 56 : item_size;  //at least 56 bytes are needed by kernel to place info about name, otherwise error
480     size = sizeof(struct kdbus_cmd_name_info) + item_size;
481
482         msg = malloc(size);
483         if (!msg)
484         {
485                 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
486                 return -errno;
487         }
488
489         memset(msg, 0, size);
490         msg->size = size;
491         if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
492                 msg->id = strtoull(&name[3], NULL, 10);
493         else
494                 msg->id = 0;
495
496         item = msg->items;
497         item->type = KDBUS_NAME_INFO_ITEM_NAME;
498         item->size = item_size;
499         memcpy(item->str, name, strlen(name) + 1);
500
501         again:
502         ret = ioctl(((DBusTransportKdbus*)transport)->fd, KDBUS_CMD_NAME_QUERY, msg);
503         if (ret < 0)
504         {
505                 if(errno == EINTR)
506                         goto again;
507                 if(errno == EAGAIN)
508                                 goto again;
509                 else if(ret == -ENOBUFS)
510                 {
511                         msg = realloc(msg, msg->size);  //prepare memory
512                         if(msg != NULL)
513                                 goto again;
514                 }
515                 pInfo->uniqueId = 0;
516                 ret = -errno;
517         }
518         else
519         {
520                 pInfo->uniqueId = msg->id;
521                 pInfo->userId = msg->creds.uid;
522                 pInfo->processId = msg->creds.pid;
523                 item = msg->items;
524                 while((uint8_t *)(item) < (uint8_t *)(msg) + msg->size)
525                 {
526                         if(item->type == KDBUS_NAME_INFO_ITEM_SECLABEL)
527                         {
528                             pInfo->sec_label_len = item->size - KDBUS_PART_HEADER_SIZE - 1;
529                                 if(pInfo->sec_label_len != 0)
530                                 {
531                                         pInfo->sec_label = malloc(pInfo->sec_label_len);
532                                         if(pInfo->sec_label == NULL)
533                                                 ret = -1;
534                                         else
535                                                 memcpy(pInfo->sec_label, item->data, pInfo->sec_label_len);
536                                 }
537                                 break;
538                         }
539                         item = KDBUS_PART_NEXT(item);
540                 }
541         }
542
543         free(msg);
544         return ret;
545 }
546
547 /**
548  * Performs kdbus hello - registration on the kdbus bus
549  *
550  * @param name place to store unique name given by bus
551  * @param transportS transport structure
552  * @returns #TRUE on success
553  */
554 static dbus_bool_t bus_register_kdbus(char* name, DBusTransportKdbus* transportS)
555 {
556         struct kdbus_cmd_hello __attribute__ ((__aligned__(8))) hello;
557
558         hello.conn_flags = KDBUS_HELLO_ACCEPT_FD/* |
559                            KDBUS_HELLO_ATTACH_COMM |
560                            KDBUS_HELLO_ATTACH_EXE |
561                            KDBUS_HELLO_ATTACH_CMDLINE |
562                            KDBUS_HELLO_ATTACH_CAPS |
563                            KDBUS_HELLO_ATTACH_CGROUP |
564                            KDBUS_HELLO_ATTACH_SECLABEL |
565                            KDBUS_HELLO_ATTACH_AUDIT*/;
566         hello.size = sizeof(struct kdbus_cmd_hello);
567         hello.pool_size = RECEIVE_POOL_SIZE;
568
569         if (ioctl(transportS->fd, KDBUS_CMD_HELLO, &hello))
570         {
571                 _dbus_verbose ("Failed to send hello: %m, %d",errno);
572                 return FALSE;
573         }
574
575         sprintf(name, "%llu", (unsigned long long)hello.id);
576         _dbus_verbose("-- Our peer ID is: %s\n", name);
577         transportS->bloom_size = hello.bloom_size;
578
579         transportS->kdbus_mmap_ptr = mmap(NULL, RECEIVE_POOL_SIZE, PROT_READ, MAP_SHARED, transportS->fd, 0);
580         if (transportS->kdbus_mmap_ptr == MAP_FAILED)
581         {
582                 _dbus_verbose("Error when mmap: %m, %d",errno);
583                 return FALSE;
584         }
585
586         return TRUE;
587 }
588
589 /**
590  * Seeks key in rule string, and duplicates value of the key into pValue.
591  * If value is "org.freedesktop.DBus" it is indicated by returning -1, because it
592  * needs to be handled in different manner.
593  * Value is duplicated from rule string to newly allocated memory pointe by pValue,
594  * so it must be freed after use.
595  *
596  * @param rule rule to look through
597  * @param key key to look for
598  * @param pValue pointer to value of the key found
599  * @return length of the value string, 0 means not found, -1 means "org.freedesktop.DBus"
600  */
601 static int parse_match_key(const char *rule, const char* key, char** pValue)
602 {
603         const char* pBegin;
604         const char* pValueEnd;
605         int value_length = 0;
606
607         pBegin = strstr(rule, key);
608         if(pBegin)
609         {
610                 pBegin += strlen(key);
611                 pValueEnd = strchr(pBegin, '\'');
612                 if(pValueEnd)
613                 {
614                         value_length = pValueEnd - pBegin;
615                         *pValue = strndup(pBegin, value_length);
616                         if(*pValue)
617                         {
618                                 if(strcmp(*pValue, "org.freedesktop.DBus") == 0)
619                                         value_length = -1;
620                                 _dbus_verbose ("found for key: %s value:'%s'\n", key, *pValue);
621                         }
622                 }
623         }
624         return value_length;
625 }
626
627 /**
628  * Adds a match rule to match broadcast messages going through the message bus.
629  * Do no affect messages addressed directly.
630  *
631  * The "rule" argument is the string form of a match rule.
632  *
633  * Only part of the dbus's matching capabilities is implemented in kdbus now, because of different mechanism.
634  * Current mapping:
635  * interface match key mapped to bloom
636  * sender match key mapped to src_name
637  * also handled org.freedesktop.dbus member: NameOwnerChanged
638  * and separately NameLost, NameAcquired, IdAdded, IdRemoved
639  *
640  * @param transport transport
641  * @param id id of connection for which the rule is to be added
642  * @param rule textual form of match rule
643   */
644 dbus_bool_t add_match_kdbus (DBusTransport* transport, __u64 id, const char *rule)
645 {
646         struct kdbus_cmd_match* pCmd_match;
647         struct kdbus_item *pItem;
648         __u64 src_id = KDBUS_MATCH_SRC_ID_ANY;
649         uint64_t size;
650         unsigned int kernel_item = 0;
651         int name_size;
652         char* pName = NULL;
653         char* pInterface = NULL;
654         dbus_bool_t ret_value = FALSE;
655         DBusTransportKdbus* transportS = (DBusTransportKdbus*)transport;
656
657         /*parsing rule and calculating size of command*/
658         size = sizeof(struct kdbus_cmd_match);
659
660         if(strstr(rule, "member='NameOwnerChanged'"))
661         {
662                 kernel_item = ~0;
663                 size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2;  /*std DBus: 3 name related items plus 2 id related items*/
664         }
665         else if(strstr(rule, "member='NameChanged'"))
666         {
667                 kernel_item = KDBUS_MATCH_NAME_CHANGE;
668                 size += KDBUS_ITEM_SIZE(1);
669         }
670         else if(strstr(rule, "member='NameLost'"))
671         {
672                 kernel_item = KDBUS_MATCH_NAME_REMOVE;
673                 size += KDBUS_ITEM_SIZE(1);
674         }
675         else if(strstr(rule, "member='NameAcquired'"))
676         {
677                 kernel_item = KDBUS_MATCH_NAME_ADD;
678                 size += KDBUS_ITEM_SIZE(1);
679         }
680     else if(strstr(rule, "member='IdAdded'"))
681     {
682         kernel_item = KDBUS_MATCH_ID_ADD;
683         size += KDBUS_ITEM_SIZE(sizeof(__u64));
684     }
685     else if(strstr(rule, "member='IdRemoved'"))
686     {
687         kernel_item = KDBUS_MATCH_ID_REMOVE;
688         size += KDBUS_ITEM_SIZE(sizeof(__u64));
689     }
690
691         name_size = parse_match_key(rule, "interface='", &pInterface);
692         if((name_size == -1) && (kernel_item == 0))   //means org.freedesktop.DBus without specified member
693         {
694                 kernel_item = ~0;
695                 size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2;  /* 3 above name related items plus 2 id related items*/
696         }
697         else if(name_size > 0)                  /*actual size is not important for interface because bloom size is defined by bus*/
698                 size += KDBUS_PART_HEADER_SIZE + transportS->bloom_size;
699
700         name_size = parse_match_key(rule, "sender='", &pName);
701         if((name_size == -1) && (kernel_item == 0))  //means org.freedesktop.DBus without specified name - same as interface few line above
702         {
703                 kernel_item = ~0;
704                 size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2; /* 3 above     name related items plus 2 id related items*/
705         }
706         else if(name_size > 0)
707         {
708                 if(!strncmp(pName, ":1.", 3)) /*if name is unique name it must be converted to unique id*/
709                 {
710                         src_id = strtoull(&pName[3], NULL, 10);
711                         free(pName);
712                         pName = NULL;
713                 }
714                 else
715                         size += KDBUS_ITEM_SIZE(name_size + 1);  //well known name
716         }
717
718         pCmd_match = alloca(size);
719         if(pCmd_match == NULL)
720                 goto out;
721
722         pCmd_match->id = id;
723         pCmd_match->cookie = id;
724         pCmd_match->size = size;
725
726         pItem = pCmd_match->items;
727         if(kernel_item == ~0)  //all signals from kernel
728         {
729                 pCmd_match->src_id = 0;
730                 pItem->type = KDBUS_MATCH_NAME_CHANGE;
731                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
732                 pItem = KDBUS_PART_NEXT(pItem);
733                 pItem->type = KDBUS_MATCH_NAME_ADD;
734                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
735                 pItem = KDBUS_PART_NEXT(pItem);
736                 pItem->type = KDBUS_MATCH_NAME_REMOVE;
737                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
738                 pItem = KDBUS_PART_NEXT(pItem);
739                 pItem->type = KDBUS_MATCH_ID_ADD;
740                 pItem->size = KDBUS_PART_HEADER_SIZE + sizeof(__u64);
741                 pItem = KDBUS_PART_NEXT(pItem);
742                 pItem->type = KDBUS_MATCH_ID_REMOVE;
743                 pItem->size = KDBUS_PART_HEADER_SIZE + sizeof(__u64);
744         }
745         else if(kernel_item) //only one item
746         {
747                 pCmd_match->src_id = 0;
748                 pItem->type = kernel_item;
749                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
750         }
751         else
752         {
753                 pCmd_match->src_id = src_id;
754                 if(pName)
755                 {
756                         pItem->type = KDBUS_MATCH_SRC_NAME;
757                         pItem->size = KDBUS_PART_HEADER_SIZE + name_size + 1;
758                         memcpy(pItem->str, pName, strlen(pName) + 1);
759                         pItem = KDBUS_PART_NEXT(pItem);
760                 }
761
762                 if(pInterface)
763                 {
764                         pItem->type = KDBUS_MATCH_BLOOM;
765                         pItem->size = KDBUS_PART_HEADER_SIZE + transportS->bloom_size;
766                         strncpy(pItem->data, pInterface, transportS->bloom_size);
767                 }
768         }
769
770         if(ioctl(transportS->fd, KDBUS_CMD_MATCH_ADD, pCmd_match))
771                 _dbus_verbose("Failed adding match bus rule %s,\nerror: %d, %m\n", rule, errno);
772         else
773         {
774                 _dbus_verbose("Added match bus rule %s for id:%llu\n", rule, (unsigned long long)id);
775                 ret_value = TRUE;
776         }
777
778 out:
779         if(pName)
780                 free(pName);
781         if(pInterface)
782                 free(pInterface);
783         return ret_value;
784 }
785
786 /**
787  * Opposing to dbus, in kdbus removes all match rules with given
788  * cookie, which in this implementation is equal to uniqe id.
789  *
790  * @param transport transport
791  * @param id connection id for which rules are to be removed
792  */
793 dbus_bool_t remove_match_kdbus (DBusTransport* transport, __u64 id)
794 {
795         struct kdbus_cmd_match __attribute__ ((__aligned__(8))) cmd;
796         DBusTransportKdbus* transportS = (DBusTransportKdbus*) transport;
797
798         cmd.cookie = id;
799         cmd.id = id;
800         cmd.size = sizeof(struct kdbus_cmd_match);
801
802         if(ioctl(transportS->fd, KDBUS_CMD_MATCH_REMOVE, &cmd))
803         {
804                 _dbus_verbose("Failed removing match rule for id: %llu; error: %d, %m\n", (unsigned long long)id, errno);
805                 return FALSE;
806         }
807         else
808         {
809                 _dbus_verbose("Match rule removed correctly.\n");
810                 return TRUE;
811         }
812 }
813
814 /**
815  * Handles messages sent to bus daemon - "org.freedesktop.DBus" and translates them to appropriate
816  * kdbus ioctl commands. Than translate kdbus reply into dbus message and put it into recived messages queue.
817  *
818  * Now it captures only Hello message, which must be handled locally.
819  * All the rest is passed to dbus-daemon.
820  */
821 static int emulateOrgFreedesktopDBus(DBusTransport *transport, DBusMessage *message)
822 {
823 #ifdef DBUS_SERVICES_IN_LIB
824         int inter_ret;
825         struct nameInfo info;
826 #endif
827         int ret_value = -1;
828
829         if(!strcmp(dbus_message_get_member(message), "Hello"))
830         {
831                 char* sender = NULL;
832                 char* name = NULL;
833
834                 name = malloc(snprintf(name, 0, "%llu", ULLONG_MAX) + 1);
835                 if(name == NULL)
836                         return -1;
837                 if(!bus_register_kdbus(name, (DBusTransportKdbus*)transport))
838                         goto outH1;
839                 if(!register_kdbus_policy(name, ((DBusTransportKdbus*)transport)->fd))
840                         goto outH1;
841
842                 sender = malloc (strlen(name) + 4);
843                 if(!sender)
844                         goto outH1;
845                 sprintf(sender, ":1.%s", name);
846                 ((DBusTransportKdbus*)transport)->sender = sender;
847
848                 if(!reply_1_data(message, DBUS_TYPE_STRING, &name, transport->connection))
849                         return 0;  //todo why we cannot free name after sending reply, shouldn't we?
850                 else
851                         free(sender);
852
853         outH1:
854                 free(name);
855         }
856 #ifdef DBUS_SERVICES_IN_LIB
857         else if(!strcmp(dbus_message_get_member(message), "RequestName"))
858         {
859                 char* name;
860                 int flags;
861                 int result;
862
863                 if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
864                         return -1;
865
866                 if(!register_kdbus_policy(name, ((DBusTransportKdbus*)transport)->fd))
867                         return -1;
868
869                 result = request_kdbus_name(((DBusTransportKdbus*)transport)->fd, name, flags, 0);
870                 if(result == -EPERM)
871                         return reply_with_error(DBUS_ERROR_ACCESS_DENIED,
872                                           "Connection is not allowed to own the service \"%s\" due to security policies in the configuration file",
873                                           name, message, transport->connection);
874                 else if(result < 0)
875                         return reply_with_error(DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired", name, message, transport->connection);
876                 else
877                         return reply_1_data(message, DBUS_TYPE_UINT32, &result, transport->connection);
878         }
879         else if(!strcmp(dbus_message_get_member(message), "AddMatch"))
880         {
881                 char* rule;
882
883                 if(!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &rule, DBUS_TYPE_INVALID))
884                         return -1;
885
886                 if(!add_match_kdbus(transport, 0, rule))
887                         return -1;
888
889                 return reply_ack(message,transport->connection);
890         }
891         else if(!strcmp(dbus_message_get_member(message), "RemoveMatch"))
892         {
893                 if(!remove_match_kdbus(transport, 0))
894                         return -1;
895                 return reply_ack(message, transport->connection);
896         }
897         else if(!strcmp(dbus_message_get_member(message), "GetNameOwner"))  //returns id of the well known name
898         {
899                 char* name = NULL;
900
901                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
902                 inter_ret = kdbus_NameQuery(name, transport, &info);
903                 if(inter_ret == 0) //unique id of the name
904                 {
905                         char unique_name[(unsigned int)(snprintf(name, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
906                         const char* pString = unique_name;
907
908                         sprintf(unique_name, ":1.%llu", (unsigned long long int)info.uniqueId);
909                         _dbus_verbose("Unique name discovered:%s\n", unique_name);
910                         ret_value = reply_1_data(message, DBUS_TYPE_STRING, &pString, transport->connection);
911                 }
912                 else if(inter_ret == -ENOENT)  //name has no owner
913                         return reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owner of name '%s': no such name", name, message, transport->connection);
914                 else
915                 {
916                         _dbus_verbose("kdbus error sending name query: err %d (%m)\n", errno);
917                         ret_value = reply_with_error(DBUS_ERROR_FAILED, "Could not determine unique name for '%s'", name, message, transport->connection);
918                 }
919         }
920         else if(!strcmp(dbus_message_get_member(message), "NameHasOwner"))   //returns if name is currently registered on the bus
921         {
922                 char* name = NULL;
923                 dbus_bool_t result;
924
925                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
926                 inter_ret = kdbus_NameQuery(name, transport, &info);
927                 if((inter_ret == 0) || (inter_ret == -ENOENT))
928                 {
929                         result = (inter_ret == 0) ? TRUE : FALSE;
930                         ret_value = reply_1_data(message, DBUS_TYPE_BOOLEAN, &result, transport->connection);
931                 }
932                 else
933                 {
934                         _dbus_verbose("kdbus error checking if name exists: err %d (%m)\n", errno);
935                         ret_value = reply_with_error(DBUS_ERROR_FAILED, "Could not determine whether name '%s' exists", name, message, transport->connection);
936                 }
937         }
938         else if(!strcmp(dbus_message_get_member(message), "GetConnectionUnixUser"))
939         {
940                 char* name = NULL;
941
942                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
943                 inter_ret = kdbus_NameQuery(name, transport, &info);
944                 if(inter_ret == 0) //name found
945                 {
946                         _dbus_verbose("User id:%llu\n", (unsigned long long) info.userId);
947                         ret_value = reply_1_data(message, DBUS_TYPE_UINT32, &info.userId, transport->connection);
948                 }
949                 else if(inter_ret == -ENOENT)  //name has no owner
950                         return reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get UID of name '%s': no such name", name, message, transport->connection);
951                 else
952                 {
953                         _dbus_verbose("kdbus error determining UID: err %d (%m)\n", errno);
954                         ret_value = reply_with_error(DBUS_ERROR_FAILED, "Could not determine UID for '%s'", name, message, transport->connection);
955                 }
956         }
957         else if(!strcmp(dbus_message_get_member(message), "GetConnectionUnixProcessID"))
958         {
959                 char* name = NULL;
960
961                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
962                 inter_ret = kdbus_NameQuery(name, transport, &info);
963                 if(inter_ret == 0) //name found
964                         ret_value = reply_1_data(message, DBUS_TYPE_UINT32, &info.processId, transport->connection);
965                 else if(inter_ret == -ENOENT)  //name has no owner
966                         return reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get PID of name '%s': no such name", name, message, transport->connection);
967                 else
968                 {
969                         _dbus_verbose("kdbus error determining PID: err %d (%m)\n", errno);
970                         ret_value = reply_with_error(DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,"Could not determine PID for '%s'", name, message, transport->connection);
971                 }
972         }
973         else if(!strcmp(dbus_message_get_member(message), "ListNames"))  //return all well known names on he bus
974         {
975                 struct kdbus_cmd_names* pCmd;
976                 uint64_t cmd_size;
977
978                 cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1);
979                 pCmd = malloc(cmd_size);
980                 if(pCmd == NULL)
981                         goto out;
982                 pCmd->size = cmd_size;
983
984   again:
985                 cmd_size = 0;
986                 if(ioctl(((DBusTransportKdbus*)transport)->fd, KDBUS_CMD_NAME_LIST, pCmd))
987                 {
988                         if(errno == EINTR)
989                                 goto again;
990                         if(errno == ENOBUFS)                    //buffer to small to put all names into it
991                                 cmd_size = pCmd->size;          //here kernel tells how much memory it needs
992                         else
993                         {
994                                 _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
995                                 goto out;
996                         }
997                 }
998                 if(cmd_size)  //kernel needs more memory
999                 {
1000                         pCmd = realloc(pCmd, cmd_size);  //prepare memory
1001                         if(pCmd == NULL)
1002                                 return -1;
1003                         goto again;                                             //and try again
1004                 }
1005                 else
1006                 {
1007                         DBusMessage *reply;
1008                         DBusMessageIter iter, sub;
1009                         struct kdbus_cmd_name* pCmd_name;
1010                         char* pName;
1011
1012                         reply = dbus_message_new_method_return(message);
1013                         if(reply == NULL)
1014                                 goto out;
1015                         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
1016                         dbus_message_iter_init_append(reply, &iter);
1017                         if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &sub))
1018                         {
1019                                 dbus_message_unref(reply);
1020                                 goto out;
1021                         }
1022                         for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
1023                         {
1024                                 pName = pCmd_name->name;
1025                                 if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &pName))
1026                                 {
1027                                         dbus_message_unref(reply);
1028                                         goto out;
1029                                 }
1030                         }
1031
1032                         if (!dbus_message_iter_close_container (&iter, &sub))
1033                         {
1034                                 dbus_message_unref (reply);
1035                                 goto out;
1036                         }
1037
1038                         if(add_message_to_received(reply, transport->connection))
1039                                 ret_value = 0;
1040                 }
1041 out:
1042                 if(pCmd)
1043                         free(pCmd);
1044                 return ret_value;
1045         }
1046         else if(!strcmp(dbus_message_get_member(message), "GetId"))
1047         {
1048                 char* path;
1049                 char uuid[DBUS_UUID_LENGTH_BYTES];
1050                 struct stat stats;
1051                 MD5_CTX md5;
1052                 DBusString binary, encoded;
1053
1054                 path = &transport->address[11]; //start of kdbus bus path
1055                 if(stat(path, &stats) < -1)
1056                 {
1057                         _dbus_verbose("kdbus error reading stats of bus: err %d (%m)\n", errno);
1058                         return reply_with_error(DBUS_ERROR_FAILED, "Could not determine bus '%s' uuid", path, message, transport->connection);
1059                 }
1060
1061                 MD5_Init(&md5);
1062         MD5_Update(&md5, path, strlen(path));
1063         MD5_Update(&md5, &stats.st_ctim.tv_sec, sizeof(stats.st_ctim.tv_sec));
1064                 MD5_Final(uuid, &md5);
1065
1066                 if(!_dbus_string_init (&encoded))
1067                         goto outgid;
1068                 _dbus_string_init_const_len (&binary, uuid, DBUS_UUID_LENGTH_BYTES);
1069                 if(!_dbus_string_hex_encode (&binary, 0, &encoded, _dbus_string_get_length (&encoded)))
1070                         goto outb;
1071                 path = (char*)_dbus_string_get_const_data (&encoded);
1072                 ret_value = reply_1_data(message, DBUS_TYPE_STRING, &path, transport->connection);
1073
1074         outb:
1075                 _dbus_string_free(&binary);
1076                 _dbus_string_free(&encoded);
1077         outgid:
1078                 return ret_value;
1079         }
1080 #endif
1081 /*      else if(!strcmp(dbus_message_get_member(message), "GetAdtAuditSessionData"))  //todo to be implemented if needed and possible
1082         {
1083                 char* name = NULL;
1084
1085                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
1086                 return reply_with_error(DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN, "Could not determine audit session data for '%s'", name, message, transport->connection);
1087         }*/
1088 #ifdef DBUS_SERVICES_IN_LIB
1089         else if(!strcmp(dbus_message_get_member(message), "GetConnectionSELinuxSecurityContext"))
1090         {
1091                 char* name = NULL;
1092
1093                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
1094                 inter_ret = kdbus_NameQuery(name, transport, &info);
1095                 if(inter_ret == -ENOENT)  //name has no owner
1096                         return reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get security context of name '%s': no such name", name, message, transport->connection);
1097                 else if(inter_ret < 0)
1098                         return reply_with_error(DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN, "Could not determine security context for '%s'", name, message, transport->connection);
1099                 else
1100                 {
1101                         DBusMessage *reply;
1102
1103                         reply = dbus_message_new_method_return(message);
1104                         if(reply != NULL)
1105                         {
1106                                 dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
1107                                 if (!dbus_message_append_args (reply, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &info.sec_label, info.sec_label_len, DBUS_TYPE_INVALID))
1108                                         dbus_message_unref(reply);
1109                                 else if(add_message_to_received(reply, transport->connection))
1110                                         ret_value = 0;
1111                         }
1112                 }
1113         }
1114 #endif
1115         else
1116                 return 1;  //send to daemon
1117
1118 #ifdef DBUS_SERVICES_IN_LIB
1119         if(info.sec_label)
1120                 free(info.sec_label);
1121 #endif
1122         return ret_value;
1123 }
1124
1125 #if KDBUS_MSG_DECODE_DEBUG == 1
1126 static char *msg_id(uint64_t id, char *buf)
1127 {
1128         if (id == 0)
1129                 return "KERNEL";
1130         if (id == ~0ULL)
1131                 return "BROADCAST";
1132         sprintf(buf, "%llu", (unsigned long long)id);
1133         return buf;
1134 }
1135 #endif
1136 struct kdbus_enum_table {
1137         long long id;
1138         const char *name;
1139 };
1140 #define _STRINGIFY(x) #x
1141 #define STRINGIFY(x) _STRINGIFY(x)
1142 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
1143 #define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
1144 #define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) }
1145 #define LOOKUP(what)                                                            \
1146         const char *enum_##what(long long id) {                                 \
1147         size_t i; \
1148                 for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++)    \
1149                         if (id == kdbus_table_##what[i].id)                     \
1150                                 return kdbus_table_##what[i].name;              \
1151                 return "UNKNOWN";                                               \
1152         }
1153 const char *enum_MSG(long long id);
1154 TABLE(MSG) = {
1155         ENUM(_KDBUS_MSG_NULL),
1156         ENUM(KDBUS_MSG_PAYLOAD_VEC),
1157         ENUM(KDBUS_MSG_PAYLOAD_OFF),
1158         ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
1159         ENUM(KDBUS_MSG_FDS),
1160         ENUM(KDBUS_MSG_BLOOM),
1161         ENUM(KDBUS_MSG_DST_NAME),
1162         ENUM(KDBUS_MSG_SRC_CREDS),
1163         ENUM(KDBUS_MSG_SRC_PID_COMM),
1164         ENUM(KDBUS_MSG_SRC_TID_COMM),
1165         ENUM(KDBUS_MSG_SRC_EXE),
1166         ENUM(KDBUS_MSG_SRC_CMDLINE),
1167         ENUM(KDBUS_MSG_SRC_CGROUP),
1168         ENUM(KDBUS_MSG_SRC_CAPS),
1169         ENUM(KDBUS_MSG_SRC_SECLABEL),
1170         ENUM(KDBUS_MSG_SRC_AUDIT),
1171         ENUM(KDBUS_MSG_SRC_NAMES),
1172         ENUM(KDBUS_MSG_TIMESTAMP),
1173         ENUM(KDBUS_MSG_NAME_ADD),
1174         ENUM(KDBUS_MSG_NAME_REMOVE),
1175         ENUM(KDBUS_MSG_NAME_CHANGE),
1176         ENUM(KDBUS_MSG_ID_ADD),
1177         ENUM(KDBUS_MSG_ID_REMOVE),
1178         ENUM(KDBUS_MSG_REPLY_TIMEOUT),
1179         ENUM(KDBUS_MSG_REPLY_DEAD),
1180 };
1181 LOOKUP(MSG);
1182 const char *enum_PAYLOAD(long long id);
1183 TABLE(PAYLOAD) = {
1184         ENUM(KDBUS_PAYLOAD_KERNEL),
1185         ENUM(KDBUS_PAYLOAD_DBUS1),
1186         ENUM(KDBUS_PAYLOAD_GVARIANT),
1187 };
1188 LOOKUP(PAYLOAD);
1189
1190 /**
1191  * Puts locally generated message into received data buffer.
1192  * Use only during receiving phase!
1193  *
1194  * @param message message to load
1195  * @param data place to load message
1196  * @return size of message
1197  */
1198 static int put_message_into_data(DBusMessage *message, char* data)
1199 {
1200         int ret_size;
1201     const DBusString *header;
1202     const DBusString *body;
1203     int size;
1204
1205     dbus_message_set_serial(message, 1);
1206     dbus_message_lock (message);
1207     _dbus_message_get_network_data (message, &header, &body);
1208     ret_size = _dbus_string_get_length(header);
1209         memcpy(data, _dbus_string_get_const_data(header), ret_size);
1210         data += ret_size;
1211         size = _dbus_string_get_length(body);
1212         memcpy(data, _dbus_string_get_const_data(body), size);
1213         ret_size += size;
1214
1215         return ret_size;
1216 }
1217
1218 /**
1219  * Get the length of the kdbus message content.
1220  *
1221  * @param msg kdbus message
1222  * @return the length of the kdbus message
1223  */
1224 static int kdbus_message_size(const struct kdbus_msg* msg)
1225 {
1226         const struct kdbus_item *item;
1227         int ret_size = 0;
1228
1229         KDBUS_PART_FOREACH(item, msg, items)
1230         {
1231                 if (item->size <= KDBUS_PART_HEADER_SIZE)
1232                 {
1233                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
1234                         return -1;
1235                 }
1236                 switch (item->type)
1237                 {
1238                         case KDBUS_MSG_PAYLOAD_OFF:
1239                                 ret_size += item->vec.size;
1240                                 break;
1241                         case KDBUS_MSG_PAYLOAD_MEMFD:
1242                                 ret_size += item->memfd.size;
1243                                 break;
1244                         default:
1245                                 break;
1246                 }
1247         }
1248
1249         return ret_size;
1250 }
1251
1252 /**
1253  * Decodes kdbus message in order to extract dbus message and put it into data and fds.
1254  * Also captures and decodes kdbus error messages and kdbus kernel broadcasts and converts
1255  * all of them into dbus messages.
1256  *
1257  * @param msg kdbus message
1258  * @param data place to copy dbus message to
1259  * @param kdbus_transport transport
1260  * @param fds place to store file descriptors received
1261  * @param n_fds place to store quantity of file descriptor
1262  * @return number of dbus message's bytes received or -1 on error
1263  */
1264 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, DBusTransportKdbus* kdbus_transport, int* fds, int* n_fds)
1265 {
1266         const struct kdbus_item *item;
1267         int ret_size = 0;
1268         DBusMessage *message = NULL;
1269         DBusMessageIter args;
1270         const char* emptyString = "";
1271     const char* pString = NULL;
1272         char dbus_name[(unsigned int)(snprintf((char*)pString, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
1273         const char* pDBusName = dbus_name;
1274 #if KDBUS_MSG_DECODE_DEBUG == 1
1275         char buf[32];
1276 #endif
1277
1278 #if KDBUS_MSG_DECODE_DEBUG == 1
1279         _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
1280                 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
1281                 (unsigned long long) msg->flags,
1282                 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
1283                 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
1284 #endif
1285
1286         *n_fds = 0;
1287
1288         KDBUS_PART_FOREACH(item, msg, items)
1289         {
1290                 if (item->size <= KDBUS_PART_HEADER_SIZE)
1291                 {
1292                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
1293                         break;  //??? continue (because dbus will find error) or break
1294                 }
1295
1296                 switch (item->type)
1297                 {
1298                         case KDBUS_MSG_PAYLOAD_OFF:
1299                                 memcpy(data, (char *)kdbus_transport->kdbus_mmap_ptr + item->vec.offset, item->vec.size);
1300                                 data += item->vec.size;
1301                                 ret_size += item->vec.size;
1302
1303                                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
1304                                         enum_MSG(item->type), item->size,
1305                                         (unsigned long long)item->vec.offset,
1306                                         (unsigned long long)item->vec.size);
1307                         break;
1308
1309                         case KDBUS_MSG_PAYLOAD_MEMFD:
1310                         {
1311                                 char *buf;
1312                                 uint64_t size;
1313
1314                                 size = item->memfd.size;
1315                                 _dbus_verbose("memfd.size : %llu\n", (unsigned long long)size);
1316
1317                                 buf = mmap(NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0);
1318                                 if (buf == MAP_FAILED)
1319                                 {
1320                                         _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
1321                                         return -1;
1322                                 }
1323
1324                                 memcpy(data, buf, size);
1325                                 data += size;
1326                                 ret_size += size;
1327
1328                                 munmap(buf, size);
1329
1330                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
1331                                            enum_MSG(item->type), item->size,
1332                                            (unsigned long long)item->vec.offset,
1333                                            (unsigned long long)item->vec.size);
1334                         break;
1335                         }
1336
1337                         case KDBUS_MSG_FDS:
1338                         {
1339                                 int i;
1340
1341                                 *n_fds = (item->size - KDBUS_PART_HEADER_SIZE) / sizeof(int);
1342                                 memcpy(fds, item->fds, *n_fds * sizeof(int));
1343                     for (i = 0; i < *n_fds; i++)
1344                       _dbus_fd_set_close_on_exec(fds[i]);
1345                         break;
1346                         }
1347
1348 #if KDBUS_MSG_DECODE_DEBUG == 1
1349                         case KDBUS_MSG_SRC_CREDS:
1350                                 _dbus_verbose("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
1351                                         enum_MSG(item->type), item->size,
1352                                         item->creds.uid, item->creds.gid,
1353                                         item->creds.pid, item->creds.tid,
1354                                         item->creds.starttime);
1355                         break;
1356
1357                         case KDBUS_MSG_SRC_PID_COMM:
1358                         case KDBUS_MSG_SRC_TID_COMM:
1359                         case KDBUS_MSG_SRC_EXE:
1360                         case KDBUS_MSG_SRC_CGROUP:
1361                         case KDBUS_MSG_SRC_SECLABEL:
1362                         case KDBUS_MSG_DST_NAME:
1363                                 _dbus_verbose("  +%s (%llu bytes) '%s' (%zu)\n",
1364                                            enum_MSG(item->type), item->size, item->str, strlen(item->str));
1365                                 break;
1366
1367                         case KDBUS_MSG_SRC_CMDLINE:
1368                         case KDBUS_MSG_SRC_NAMES: {
1369                                 __u64 size = item->size - KDBUS_PART_HEADER_SIZE;
1370                                 const char *str = item->str;
1371                                 int count = 0;
1372
1373                                 _dbus_verbose("  +%s (%llu bytes) ", enum_MSG(item->type), item->size);
1374                                 while (size) {
1375                                         _dbus_verbose("'%s' ", str);
1376                                         size -= strlen(str) + 1;
1377                                         str += strlen(str) + 1;
1378                                         count++;
1379                                 }
1380
1381                                 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
1382                                 break;
1383                         }
1384
1385                         case KDBUS_MSG_SRC_AUDIT:
1386                                 _dbus_verbose("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
1387                                            enum_MSG(item->type), item->size,
1388                                            (unsigned long long)item->data64[0],
1389                                            (unsigned long long)item->data64[1]);
1390                                 break;
1391
1392                         case KDBUS_MSG_SRC_CAPS: {
1393                                 int n;
1394                                 const uint32_t *cap;
1395                                 int i;
1396
1397                                 _dbus_verbose("  +%s (%llu bytes) len=%llu bytes)\n",
1398                                            enum_MSG(item->type), item->size,
1399                                            (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
1400
1401                                 cap = item->data32;
1402                                 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
1403
1404                                 _dbus_verbose("    CapInh=");
1405                                 for (i = 0; i < n; i++)
1406                                         _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
1407
1408                                 _dbus_verbose(" CapPrm=");
1409                                 for (i = 0; i < n; i++)
1410                                         _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
1411
1412                                 _dbus_verbose(" CapEff=");
1413                                 for (i = 0; i < n; i++)
1414                                         _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
1415
1416                                 _dbus_verbose(" CapInh=");
1417                                 for (i = 0; i < n; i++)
1418                                         _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
1419                                 _dbus_verbose("\n");
1420                                 break;
1421                         }
1422
1423                         case KDBUS_MSG_TIMESTAMP:
1424                                 _dbus_verbose("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
1425                                            enum_MSG(item->type), item->size,
1426                                            (unsigned long long)item->timestamp.realtime_ns,
1427                                            (unsigned long long)item->timestamp.monotonic_ns);
1428                                 break;
1429 #endif
1430
1431                         case KDBUS_MSG_REPLY_TIMEOUT:
1432                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
1433                                            enum_MSG(item->type), item->size, msg->cookie_reply);
1434
1435                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NO_REPLY, NULL);
1436                                 if(message == NULL)
1437                                 {
1438                                         ret_size = -1;
1439                                         goto out;
1440                                 }
1441
1442                                 ret_size = put_message_into_data(message, data);
1443                         break;
1444
1445                         case KDBUS_MSG_REPLY_DEAD:
1446                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
1447                                            enum_MSG(item->type), item->size, msg->cookie_reply);
1448
1449                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NAME_HAS_NO_OWNER, NULL);
1450                                 if(message == NULL)
1451                                 {
1452                                         ret_size = -1;
1453                                         goto out;
1454                                 }
1455
1456                                 ret_size = put_message_into_data(message, data);
1457                         break;
1458
1459                         case KDBUS_MSG_NAME_ADD:
1460                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1461                                         enum_MSG(item->type), (unsigned long long) item->size,
1462                                         item->name_change.name, item->name_change.old_id,
1463                                         item->name_change.new_id, item->name_change.flags);
1464
1465                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1466                                 if(message == NULL)
1467                                 {
1468                                         ret_size = -1;
1469                                         goto out;
1470                                 }
1471
1472                                 sprintf(dbus_name,":1.%llu",item->name_change.new_id);
1473                                 pString = item->name_change.name;
1474                                 _dbus_verbose ("Name added: %s\n", pString);
1475                             dbus_message_iter_init_append(message, &args);
1476                             ITER_APPEND_STR(pString)
1477                             ITER_APPEND_STR(emptyString)
1478                             ITER_APPEND_STR(pDBusName)
1479                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1480
1481                                 ret_size = put_message_into_data(message, data);
1482                         break;
1483
1484                         case KDBUS_MSG_NAME_REMOVE:
1485                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1486                                         enum_MSG(item->type), (unsigned long long) item->size,
1487                                         item->name_change.name, item->name_change.old_id,
1488                                         item->name_change.new_id, item->name_change.flags);
1489
1490                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged"); // name of the signal
1491                                 if(message == NULL)
1492                                 {
1493                                         ret_size = -1;
1494                                         goto out;
1495                                 }
1496
1497                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1498                                 pString = item->name_change.name;
1499                                 _dbus_verbose ("Name removed: %s\n", pString);
1500                             dbus_message_iter_init_append(message, &args);
1501                             ITER_APPEND_STR(pString)
1502                             ITER_APPEND_STR(pDBusName)
1503                             ITER_APPEND_STR(emptyString)
1504                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1505
1506                                 ret_size = put_message_into_data(message, data);
1507                         break;
1508
1509                         case KDBUS_MSG_NAME_CHANGE:
1510                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1511                                         enum_MSG(item->type), (unsigned long long) item->size,
1512                                         item->name_change.name, item->name_change.old_id,
1513                                         item->name_change.new_id, item->name_change.flags);
1514
1515                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1516                                 if(message == NULL)
1517                                 {
1518                                         ret_size = -1;
1519                                         goto out;
1520                                 }
1521
1522                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1523                                 pString = item->name_change.name;
1524                                 _dbus_verbose ("Name changed: %s\n", pString);
1525                             dbus_message_iter_init_append(message, &args);
1526                             ITER_APPEND_STR(pString)
1527                             ITER_APPEND_STR(pDBusName)
1528                             sprintf(&dbus_name[3],"%llu",item->name_change.new_id);
1529                             _dbus_verbose ("New id: %s\n", pDBusName);
1530                             ITER_APPEND_STR(pDBusName)
1531                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1532
1533                                 ret_size = put_message_into_data(message, data);
1534                         break;
1535
1536                         case KDBUS_MSG_ID_ADD:
1537                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1538                                            enum_MSG(item->type), (unsigned long long) item->size,
1539                                            (unsigned long long) item->id_change.id,
1540                                            (unsigned long long) item->id_change.flags);
1541
1542                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1543                                 if(message == NULL)
1544                                 {
1545                                         ret_size = -1;
1546                                         goto out;
1547                                 }
1548
1549                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1550                             dbus_message_iter_init_append(message, &args);
1551                             ITER_APPEND_STR(pDBusName)
1552                             ITER_APPEND_STR(emptyString)
1553                             ITER_APPEND_STR(pDBusName)
1554                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1555
1556                                 ret_size = put_message_into_data(message, data);
1557                         break;
1558
1559                         case KDBUS_MSG_ID_REMOVE:
1560                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1561                                            enum_MSG(item->type), (unsigned long long) item->size,
1562                                            (unsigned long long) item->id_change.id,
1563                                            (unsigned long long) item->id_change.flags);
1564
1565                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1566                                 if(message == NULL)
1567                                 {
1568                                         ret_size = -1;
1569                                         goto out;
1570                                 }
1571
1572                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1573                             dbus_message_iter_init_append(message, &args);
1574                             ITER_APPEND_STR(pDBusName)
1575                             ITER_APPEND_STR(pDBusName)
1576                             ITER_APPEND_STR(emptyString)
1577                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1578
1579                                 ret_size = put_message_into_data(message, data);
1580                         break;
1581 #if KDBUS_MSG_DECODE_DEBUG == 1
1582                         default:
1583                                 _dbus_verbose("  +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
1584                         break;
1585 #endif
1586                 }
1587         }
1588
1589 #if KDBUS_MSG_DECODE_DEBUG == 1
1590
1591         if ((char *)item - ((char *)msg + msg->size) >= 8)
1592                 _dbus_verbose("invalid padding at end of message\n");
1593 #endif
1594
1595 out:
1596         if(message)
1597                 dbus_message_unref(message);
1598         return ret_size;
1599 }
1600
1601 /**
1602  * Reads message from kdbus and puts it into dbus buffer and fds
1603  *
1604  * @param transport transport
1605  * @param buffer place to copy received message to
1606  * @param fds place to store file descriptors sent in the message
1607  * @param n_fds place  to store number of file descriptors
1608  * @return size of received message on success, -1 on error
1609  */
1610 static int kdbus_read_message(DBusTransportKdbus *socket_transport, DBusString *buffer, int* fds, int* n_fds)
1611 {
1612         int ret_size, buf_size;
1613         uint64_t __attribute__ ((__aligned__(8))) offset;
1614         struct kdbus_msg *msg;
1615         char *data;
1616         int start;
1617
1618         start = _dbus_string_get_length (buffer);
1619
1620         again:
1621         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
1622         {
1623                 if(errno == EINTR)
1624                         goto again;
1625                 _dbus_verbose("kdbus error receiving message: %d (%m)\n", errno);
1626                 _dbus_string_set_length (buffer, start);
1627                 return -1;
1628         }
1629
1630         msg = (struct kdbus_msg *)((char*)socket_transport->kdbus_mmap_ptr + offset);
1631
1632         buf_size = kdbus_message_size(msg);
1633         if (buf_size == -1)
1634         {
1635                 _dbus_verbose("kdbus error - too short message: %d (%m)\n", errno);
1636                 return -1;
1637         }
1638
1639         /* What is the maximum size of the locally generated message?
1640            I just assume 2048 bytes */
1641         buf_size = MAX(buf_size, 2048);
1642
1643         if (!_dbus_string_lengthen (buffer, buf_size))
1644         {
1645                 errno = ENOMEM;
1646                 return -1;
1647         }
1648         data = _dbus_string_get_data_len (buffer, start, buf_size);
1649
1650         ret_size = kdbus_decode_msg(msg, data, socket_transport, fds, n_fds);
1651
1652         if(ret_size == -1) /* error */
1653         {
1654                 _dbus_string_set_length (buffer, start);
1655                 return -1;
1656         }
1657         else if (buf_size != ret_size) /* case of locally generated message */
1658         {
1659                 _dbus_string_set_length (buffer, start + ret_size);
1660         }
1661
1662         again2:
1663         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
1664         {
1665                 if(errno == EINTR)
1666                         goto again2;
1667                 _dbus_verbose("kdbus error freeing message: %d (%m)\n", errno);
1668                 return -1;
1669         }
1670
1671         return ret_size;
1672 }
1673 /*
1674  * copy-paste from socket transport with needed renames only.
1675  */
1676 static void
1677 free_watches (DBusTransport *transport)
1678 {
1679   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1680
1681   _dbus_verbose ("start\n");
1682
1683   if (kdbus_transport->read_watch)
1684     {
1685       if (transport->connection)
1686         _dbus_connection_remove_watch_unlocked (transport->connection,
1687                                                 kdbus_transport->read_watch);
1688       _dbus_watch_invalidate (kdbus_transport->read_watch);
1689       _dbus_watch_unref (kdbus_transport->read_watch);
1690       kdbus_transport->read_watch = NULL;
1691     }
1692
1693   if (kdbus_transport->write_watch)
1694     {
1695       if (transport->connection)
1696         _dbus_connection_remove_watch_unlocked (transport->connection,
1697                                                 kdbus_transport->write_watch);
1698       _dbus_watch_invalidate (kdbus_transport->write_watch);
1699       _dbus_watch_unref (kdbus_transport->write_watch);
1700       kdbus_transport->write_watch = NULL;
1701     }
1702
1703   _dbus_verbose ("end\n");
1704 }
1705
1706 /*
1707  * copy-paste from socket transport with needed renames only.
1708  */
1709 static void
1710 transport_finalize (DBusTransport *transport)
1711 {
1712   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1713
1714   _dbus_verbose ("\n");
1715
1716   free_watches (transport);
1717
1718   _dbus_string_free (&kdbus_transport->encoded_outgoing);
1719   _dbus_string_free (&kdbus_transport->encoded_incoming);
1720
1721   _dbus_transport_finalize_base (transport);
1722
1723   _dbus_assert (kdbus_transport->read_watch == NULL);
1724   _dbus_assert (kdbus_transport->write_watch == NULL);
1725
1726   dbus_free (transport);
1727 }
1728
1729 /*
1730  * copy-paste from socket transport with needed renames only.
1731  */
1732 static void
1733 check_write_watch (DBusTransport *transport)
1734 {
1735   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1736   dbus_bool_t needed;
1737
1738   if (transport->connection == NULL)
1739     return;
1740
1741   if (transport->disconnected)
1742     {
1743       _dbus_assert (kdbus_transport->write_watch == NULL);
1744       return;
1745     }
1746
1747   _dbus_transport_ref (transport);
1748
1749 #ifdef DBUS_AUTHENTICATION
1750   if (_dbus_transport_try_to_authenticate (transport))
1751 #endif
1752     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1753 #ifdef DBUS_AUTHENTICATION
1754   else
1755     {
1756       if (transport->send_credentials_pending)
1757         needed = TRUE;
1758       else
1759         {
1760           DBusAuthState auth_state;
1761
1762           auth_state = _dbus_auth_do_work (transport->auth);
1763
1764           /* If we need memory we install the write watch just in case,
1765            * if there's no need for it, it will get de-installed
1766            * next time we try reading.
1767            */
1768           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
1769               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1770             needed = TRUE;
1771           else
1772             needed = FALSE;
1773         }
1774     }
1775 #endif
1776   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1777                  needed, transport->connection, kdbus_transport->write_watch,
1778                  kdbus_transport->fd,
1779                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1780
1781   _dbus_connection_toggle_watch_unlocked (transport->connection,
1782                                           kdbus_transport->write_watch,
1783                                           needed);
1784
1785   _dbus_transport_unref (transport);
1786 }
1787
1788 /*
1789  * copy-paste from socket transport with needed renames only.
1790  */
1791 static void
1792 check_read_watch (DBusTransport *transport)
1793 {
1794   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1795   dbus_bool_t need_read_watch;
1796
1797   _dbus_verbose ("fd = %d\n",kdbus_transport->fd);
1798
1799   if (transport->connection == NULL)
1800     return;
1801
1802   if (transport->disconnected)
1803     {
1804       _dbus_assert (kdbus_transport->read_watch == NULL);
1805       return;
1806     }
1807
1808   _dbus_transport_ref (transport);
1809
1810 #ifdef DBUS_AUTHENTICATION
1811   if (_dbus_transport_try_to_authenticate (transport))
1812 #endif
1813     need_read_watch =
1814       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1815       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1816 #ifdef DBUS_AUTHENTICATION
1817   else
1818     {
1819       if (transport->receive_credentials_pending)
1820         need_read_watch = TRUE;
1821       else
1822         {
1823           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
1824            * is to avoid spinning on the file descriptor when we're waiting
1825            * to write or for some other part of the auth process
1826            */
1827           DBusAuthState auth_state;
1828
1829           auth_state = _dbus_auth_do_work (transport->auth);
1830
1831           /* If we need memory we install the read watch just in case,
1832            * if there's no need for it, it will get de-installed
1833            * next time we try reading. If we're authenticated we
1834            * install it since we normally have it installed while
1835            * authenticated.
1836            */
1837           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
1838               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
1839               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
1840             need_read_watch = TRUE;
1841           else
1842             need_read_watch = FALSE;
1843         }
1844     }
1845 #endif
1846
1847   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
1848   _dbus_connection_toggle_watch_unlocked (transport->connection,
1849                                           kdbus_transport->read_watch,
1850                                           need_read_watch);
1851
1852   _dbus_transport_unref (transport);
1853 }
1854
1855 /*
1856  * copy-paste from socket transport.
1857  */
1858 static void
1859 do_io_error (DBusTransport *transport)
1860 {
1861   _dbus_transport_ref (transport);
1862   _dbus_transport_disconnect (transport);
1863   _dbus_transport_unref (transport);
1864 }
1865
1866 #ifdef DBUS_AUTHENTICATION
1867 /* return value is whether we successfully read any new data. */
1868 static dbus_bool_t
1869 read_data_into_auth (DBusTransport *transport,
1870                      dbus_bool_t   *oom)
1871 {
1872   DBusTransportKdbus *socket_transport = (DBusTransportKdbus*) transport;
1873   DBusString *buffer;
1874   int bytes_read;
1875   int *fds, n_fds;
1876
1877   *oom = FALSE;
1878
1879   _dbus_auth_get_buffer (transport->auth, &buffer);
1880
1881   bytes_read = kdbus_read_message(socket_transport, buffer, fds, &n_fds);
1882
1883   _dbus_auth_return_buffer (transport->auth, buffer,
1884                             bytes_read > 0 ? bytes_read : 0);
1885
1886   if (bytes_read > 0)
1887     {
1888       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
1889       return TRUE;
1890     }
1891   else if (bytes_read < 0)
1892     {
1893       /* EINTR already handled for us */
1894
1895       if (_dbus_get_is_errno_enomem ())
1896         {
1897           *oom = TRUE;
1898         }
1899       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1900         ; /* do nothing, just return FALSE below */
1901       else
1902         {
1903           _dbus_verbose ("Error reading from remote app: %s\n",
1904                          _dbus_strerror_from_errno ());
1905           do_io_error (transport);
1906         }
1907
1908       return FALSE;
1909     }
1910   else
1911     {
1912       _dbus_assert (bytes_read == 0);
1913
1914       _dbus_verbose ("Disconnected from remote app\n");
1915       do_io_error (transport);
1916
1917       return FALSE;
1918     }
1919 }
1920
1921 static int kdbus_send_auth (DBusTransport *transport,  const DBusString *buffer)
1922 {
1923         int len;
1924         int bytes_written = -1;
1925         struct kdbus_msg *msg;
1926         struct kdbus_item *item;
1927
1928         len = _dbus_string_get_length (buffer);
1929 //      data = _dbus_string_get_const_data_len (buffer, 0, len);
1930
1931         msg = kdbus_init_msg(NULL, 1, 0, FALSE, 0, (DBusTransportKdbus*)transport);
1932         item = msg->items;
1933         MSG_ITEM_BUILD_VEC(_dbus_string_get_const_data_len (buffer, 0, len), len);
1934
1935     again:
1936     if(ioctl(((DBusTransportKdbus*)transport)->fd, KDBUS_CMD_MSG_SEND, msg))
1937     {
1938         if(errno == EINTR)
1939             goto again;
1940         _dbus_verbose ("Error writing auth: %d, %m\n", errno);
1941     }
1942     else
1943         bytes_written = len;
1944
1945         return bytes_written;
1946 }
1947
1948 /* Return value is whether we successfully wrote any bytes */
1949 static dbus_bool_t
1950 write_data_from_auth (DBusTransport *transport)
1951 {
1952 //  DBusTransportKdbus *socket_transport = (DBusTransportSocket*) transport;
1953   int bytes_written;
1954   const DBusString *buffer;
1955
1956   if (!_dbus_auth_get_bytes_to_send (transport->auth,
1957                                      &buffer))
1958     return FALSE;
1959
1960   bytes_written = kdbus_send_auth (transport, buffer);
1961
1962   if (bytes_written > 0)
1963     {
1964       _dbus_auth_bytes_sent (transport->auth, bytes_written);
1965       return TRUE;
1966     }
1967   else if (bytes_written < 0)
1968     {
1969       /* EINTR already handled for us */
1970
1971       if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1972         ;
1973       else
1974         {
1975           _dbus_verbose ("Error writing to remote app: %s\n",
1976                          _dbus_strerror_from_errno ());
1977           do_io_error (transport);
1978         }
1979     }
1980
1981   return FALSE;
1982 }
1983
1984 /* FALSE on OOM */
1985 static dbus_bool_t
1986 exchange_credentials (DBusTransport *transport,
1987                       dbus_bool_t    do_reading,
1988                       dbus_bool_t    do_writing)
1989 {
1990   DBusTransportKdbus *socket_transport = (DBusTransportKdbus*) transport;
1991   DBusError error = DBUS_ERROR_INIT;
1992
1993   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
1994                   do_reading, do_writing);
1995
1996   if (do_writing && transport->send_credentials_pending)
1997     {
1998       if (_dbus_send_credentials_socket (socket_transport->fd,
1999                                          &error))
2000         {
2001           transport->send_credentials_pending = FALSE;
2002         }
2003       else
2004         {
2005           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
2006           dbus_error_free (&error);
2007           do_io_error (transport);
2008         }
2009     }
2010
2011   if (do_reading && transport->receive_credentials_pending)
2012     {
2013       /* FIXME this can fail due to IO error _or_ OOM, broken
2014        * (somewhat tricky to fix since the OOM error can be set after
2015        * we already read the credentials byte, so basically we need to
2016        * separate reading the byte and storing it in the
2017        * transport->credentials). Does not really matter for now
2018        * because storing in credentials never actually fails on unix.
2019        */
2020       if (_dbus_read_credentials_socket (socket_transport->fd,
2021                                          transport->credentials,
2022                                          &error))
2023         {
2024           transport->receive_credentials_pending = FALSE;
2025         }
2026       else
2027         {
2028           _dbus_verbose ("Failed to read credentials %s\n", error.message);
2029           dbus_error_free (&error);
2030           do_io_error (transport);
2031         }
2032     }
2033
2034   if (!(transport->send_credentials_pending ||
2035         transport->receive_credentials_pending))
2036     {
2037       if (!_dbus_auth_set_credentials (transport->auth,
2038                                        transport->credentials))
2039         return FALSE;
2040     }
2041
2042   return TRUE;
2043 }
2044
2045 static dbus_bool_t
2046 do_authentication (DBusTransport *transport,
2047                    dbus_bool_t    do_reading,
2048                    dbus_bool_t    do_writing,
2049                    dbus_bool_t   *auth_completed)
2050 {
2051   dbus_bool_t oom;
2052   dbus_bool_t orig_auth_state;
2053
2054   oom = FALSE;
2055
2056   orig_auth_state = _dbus_transport_try_to_authenticate (transport);
2057
2058   /* This is essential to avoid the check_write_watch() at the end,
2059    * we don't want to add a write watch in do_iteration before
2060    * we try writing and get EAGAIN
2061    */
2062   if (orig_auth_state)
2063     {
2064       if (auth_completed)
2065         *auth_completed = FALSE;
2066       return TRUE;
2067     }
2068
2069   _dbus_transport_ref (transport);
2070
2071    while (!_dbus_transport_try_to_authenticate (transport) &&
2072          _dbus_transport_get_is_connected (transport))
2073     {
2074       if (!exchange_credentials (transport, do_reading, do_writing))
2075         {
2076           oom = TRUE;
2077           goto out;
2078         }
2079
2080       if (transport->send_credentials_pending ||
2081           transport->receive_credentials_pending)
2082         {
2083           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
2084                          transport->send_credentials_pending,
2085                          transport->receive_credentials_pending);
2086           goto out;
2087         }
2088
2089 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
2090       switch (_dbus_auth_do_work (transport->auth))
2091         {
2092         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
2093           _dbus_verbose (" %s auth state: waiting for input\n",
2094                          TRANSPORT_SIDE (transport));
2095           if (!do_reading || !read_data_into_auth (transport, &oom))
2096             goto out;
2097           break;
2098
2099         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
2100           _dbus_verbose (" %s auth state: waiting for memory\n",
2101                          TRANSPORT_SIDE (transport));
2102           oom = TRUE;
2103           goto out;
2104           break;
2105
2106         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
2107           _dbus_verbose (" %s auth state: bytes to send\n",
2108                          TRANSPORT_SIDE (transport));
2109           if (!do_writing || !write_data_from_auth (transport))
2110             goto out;
2111           break;
2112
2113         case DBUS_AUTH_STATE_NEED_DISCONNECT:
2114           _dbus_verbose (" %s auth state: need to disconnect\n",
2115                          TRANSPORT_SIDE (transport));
2116           do_io_error (transport);
2117           break;
2118
2119         case DBUS_AUTH_STATE_AUTHENTICATED:
2120           _dbus_verbose (" %s auth state: authenticated\n",
2121                          TRANSPORT_SIDE (transport));
2122           break;
2123         }
2124     }
2125
2126  out:
2127   if (auth_completed)
2128     *auth_completed = (orig_auth_state != _dbus_transport_try_to_authenticate (transport));
2129
2130   check_read_watch (transport);
2131   check_write_watch (transport);
2132   _dbus_transport_unref (transport);
2133
2134   if (oom)
2135     return FALSE;
2136   else
2137     return TRUE;
2138 }
2139 #endif
2140
2141 /* returns false on oom */
2142 static dbus_bool_t
2143 do_writing (DBusTransport *transport)
2144 {
2145         DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
2146         dbus_bool_t oom;
2147
2148 #ifdef DBUS_AUTHENTICATION
2149         /* No messages without authentication! */
2150         if (!_dbus_transport_try_to_authenticate (transport))
2151     {
2152                 _dbus_verbose ("Not authenticated, not writing anything\n");
2153                 return TRUE;
2154     }
2155 #endif
2156
2157         if (transport->disconnected)
2158     {
2159                 _dbus_verbose ("Not connected, not writing anything\n");
2160                 return TRUE;
2161     }
2162
2163 #if 1
2164         _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
2165                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
2166                  kdbus_transport->fd);
2167 #endif
2168
2169         oom = FALSE;
2170
2171         while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
2172     {
2173                 int bytes_written;
2174                 DBusMessage *message;
2175                 const DBusString *header;
2176                 const DBusString *body;
2177                 int total_bytes_to_write;
2178                 const char* pDestination;
2179
2180                 message = _dbus_connection_get_message_to_send (transport->connection);
2181                 _dbus_assert (message != NULL);
2182                 if(dbus_message_get_sender(message) == NULL)  //needed for daemon to pass pending activation messages
2183                 {
2184             dbus_message_unlock(message);
2185             dbus_message_set_sender(message, kdbus_transport->sender);
2186             dbus_message_lock (message);
2187                 }
2188                 _dbus_message_get_network_data (message, &header, &body);
2189                 total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
2190                 pDestination = dbus_message_get_destination(message);
2191
2192                 if(pDestination)
2193                 {
2194                         if(!strcmp(pDestination, DBUS_SERVICE_DBUS))
2195                         {
2196                                 if(!strcmp(dbus_message_get_interface(message), DBUS_INTERFACE_DBUS))
2197                                 {
2198                                         int ret;
2199
2200                                         ret = emulateOrgFreedesktopDBus(transport, message);
2201                                         if(ret < 0)
2202                                         {
2203                                                 bytes_written = -1;
2204                                                 goto written;
2205                                         }
2206                                         else if(ret == 0)
2207                                         {
2208                                                 bytes_written = total_bytes_to_write;
2209                                                 goto written;
2210                                         }
2211                                         //else send to "daemon" as to normal recipient
2212                                 }
2213                         }
2214                 }
2215                 if (_dbus_auth_needs_encoding (transport->auth))
2216         {
2217                         if (_dbus_string_get_length (&kdbus_transport->encoded_outgoing) == 0)
2218             {
2219                                 if (!_dbus_auth_encode_data (transport->auth,
2220                                            header, &kdbus_transport->encoded_outgoing))
2221                 {
2222                                         oom = TRUE;
2223                                         goto out;
2224                 }
2225
2226                                 if (!_dbus_auth_encode_data (transport->auth,
2227                                            body, &kdbus_transport->encoded_outgoing))
2228                 {
2229                                         _dbus_string_set_length (&kdbus_transport->encoded_outgoing, 0);
2230                                         oom = TRUE;
2231                                         goto out;
2232                 }
2233             }
2234
2235                         total_bytes_to_write = _dbus_string_get_length (&kdbus_transport->encoded_outgoing);
2236                         if(total_bytes_to_write > kdbus_transport->max_bytes_written_per_iteration)
2237                                 return -E2BIG;
2238
2239                         bytes_written = kdbus_write_msg(kdbus_transport, message, pDestination, TRUE);
2240         }
2241                 else
2242                 {
2243                         if(total_bytes_to_write > kdbus_transport->max_bytes_written_per_iteration)
2244                                 return -E2BIG;
2245
2246                         bytes_written = kdbus_write_msg(kdbus_transport, message, pDestination, FALSE);
2247                 }
2248
2249 written:
2250                 if (bytes_written < 0)
2251                 {
2252                         /* EINTR already handled for us */
2253
2254           /* For some discussion of why we also ignore EPIPE here, see
2255            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
2256            */
2257
2258                         if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
2259                                 goto out;
2260                         else
2261                         {
2262                                 _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
2263                                 do_io_error (transport);
2264                                 goto out;
2265                         }
2266                 }
2267                 else
2268                 {
2269                         _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
2270                          total_bytes_to_write);
2271
2272                         kdbus_transport->message_bytes_written += bytes_written;
2273
2274                         _dbus_assert (kdbus_transport->message_bytes_written <=
2275                         total_bytes_to_write);
2276
2277                           if (kdbus_transport->message_bytes_written == total_bytes_to_write)
2278                           {
2279                                   kdbus_transport->message_bytes_written = 0;
2280                                   _dbus_string_set_length (&kdbus_transport->encoded_outgoing, 0);
2281                                   _dbus_string_compact (&kdbus_transport->encoded_outgoing, 2048);
2282
2283                                   _dbus_connection_message_sent_unlocked (transport->connection,
2284                                                                                                                   message);
2285                           }
2286                 }
2287     }
2288
2289         out:
2290         if (oom)
2291                 return FALSE;
2292         return TRUE;
2293 }
2294
2295 /* returns false on out-of-memory */
2296 static dbus_bool_t
2297 do_reading (DBusTransport *transport)
2298 {
2299   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
2300   DBusString *buffer;
2301   int bytes_read;
2302   dbus_bool_t oom = FALSE;
2303   int *fds, n_fds;
2304
2305   _dbus_verbose ("fd = %d\n",kdbus_transport->fd);
2306
2307 #ifdef DBUS_AUTHENTICATION
2308   /* No messages without authentication! */
2309   if (!_dbus_transport_try_to_authenticate (transport))
2310     return TRUE;
2311 #endif
2312
2313  again:
2314
2315   /* See if we've exceeded max messages and need to disable reading */
2316   check_read_watch (transport);
2317
2318   _dbus_assert (kdbus_transport->read_watch != NULL ||
2319                 transport->disconnected);
2320
2321   if (transport->disconnected)
2322     goto out;
2323
2324   if (!dbus_watch_get_enabled (kdbus_transport->read_watch))
2325     return TRUE;
2326
2327   if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
2328   {
2329       _dbus_verbose ("Out of memory reading file descriptors\n");
2330       oom = TRUE;
2331       goto out;
2332   }
2333   _dbus_message_loader_get_buffer (transport->loader, &buffer);
2334
2335   if (_dbus_auth_needs_decoding (transport->auth))
2336   {
2337           bytes_read = kdbus_read_message(kdbus_transport,  &kdbus_transport->encoded_incoming, fds, &n_fds);
2338
2339       _dbus_assert (_dbus_string_get_length (&kdbus_transport->encoded_incoming) == bytes_read);
2340
2341       if (bytes_read > 0)
2342       {
2343           if (!_dbus_auth_decode_data (transport->auth,
2344                                        &kdbus_transport->encoded_incoming,
2345                                        buffer))
2346           {
2347               _dbus_verbose ("Out of memory decoding incoming data\n");
2348               _dbus_message_loader_return_buffer (transport->loader,
2349                                               buffer,
2350                                               _dbus_string_get_length (buffer));
2351               oom = TRUE;
2352               goto out;
2353           }
2354
2355           _dbus_string_set_length (&kdbus_transport->encoded_incoming, 0);
2356           _dbus_string_compact (&kdbus_transport->encoded_incoming, 2048);
2357       }
2358   }
2359   else
2360           bytes_read = kdbus_read_message(kdbus_transport, buffer, fds, &n_fds);
2361
2362   if (bytes_read >= 0 && n_fds > 0)
2363     _dbus_verbose("Read %i unix fds\n", n_fds);
2364
2365   _dbus_message_loader_return_buffer (transport->loader,
2366                                       buffer,
2367                                       bytes_read < 0 ? 0 : bytes_read);
2368   _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
2369
2370   if (bytes_read < 0)
2371     {
2372       /* EINTR already handled for us */
2373
2374       if (_dbus_get_is_errno_enomem ())
2375         {
2376           _dbus_verbose ("Out of memory in read()/do_reading()\n");
2377           oom = TRUE;
2378           goto out;
2379         }
2380       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
2381         goto out;
2382       else
2383         {
2384           _dbus_verbose ("Error reading from remote app: %s\n",
2385                          _dbus_strerror_from_errno ());
2386           do_io_error (transport);
2387           goto out;
2388         }
2389     }
2390   else if (bytes_read == 0)
2391     {
2392       _dbus_verbose ("Disconnected from remote app\n");
2393       do_io_error (transport);
2394       goto out;
2395     }
2396   else
2397     {
2398       _dbus_verbose (" read %d bytes\n", bytes_read);
2399
2400       if (!_dbus_transport_queue_messages (transport))
2401         {
2402           oom = TRUE;
2403           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
2404           goto out;
2405         }
2406
2407       /* Try reading more data until we get EAGAIN and return, or
2408        * exceed max bytes per iteration.  If in blocking mode of
2409        * course we'll block instead of returning.
2410        */
2411       goto again;
2412     }
2413
2414  out:
2415   if (oom)
2416     return FALSE;
2417   return TRUE;
2418 }
2419
2420 /*
2421  * copy-paste from socket transport.
2422  */
2423 static dbus_bool_t
2424 unix_error_with_read_to_come (DBusTransport *itransport,
2425                               DBusWatch     *watch,
2426                               unsigned int   flags)
2427 {
2428    DBusTransportKdbus *transport = (DBusTransportKdbus *) itransport;
2429
2430    if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
2431       return FALSE;
2432
2433   /* If we have a read watch enabled ...
2434      we -might have data incoming ... => handle the HANGUP there */
2435    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
2436       return FALSE;
2437
2438    return TRUE;
2439 }
2440
2441 /*
2442  * copy-paste from socket transport with needed renames only.
2443  */
2444 static dbus_bool_t
2445 kdbus_handle_watch (DBusTransport *transport,
2446                    DBusWatch     *watch,
2447                    unsigned int   flags)
2448 {
2449   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
2450
2451   _dbus_assert (watch == kdbus_transport->read_watch ||
2452                 watch == kdbus_transport->write_watch);
2453   _dbus_assert (watch != NULL);
2454
2455   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
2456    * still be in the buffer and do_reading may need several iteration to read
2457    * it all (because of its max_bytes_read_per_iteration limit).
2458    */
2459   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
2460     {
2461       _dbus_verbose ("Hang up or error on watch\n");
2462       _dbus_transport_disconnect (transport);
2463       return TRUE;
2464     }
2465
2466   if (watch == kdbus_transport->read_watch &&
2467       (flags & DBUS_WATCH_READABLE))
2468     {
2469 #ifdef DBUS_AUTHENTICATION
2470       dbus_bool_t auth_finished;
2471 #endif
2472 #if 1
2473       _dbus_verbose ("handling read watch %p flags = %x\n",
2474                      watch, flags);
2475 #endif
2476 #ifdef DBUS_AUTHENTICATION
2477       if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
2478         return FALSE;
2479
2480       /* We don't want to do a read immediately following
2481        * a successful authentication.  This is so we
2482        * have a chance to propagate the authentication
2483        * state further up.  Specifically, we need to
2484        * process any pending data from the auth object.
2485        */
2486       if (!auth_finished)
2487         {
2488 #endif
2489           if (!do_reading (transport))
2490             {
2491               _dbus_verbose ("no memory to read\n");
2492               return FALSE;
2493             }
2494 #ifdef DBUS_AUTHENTICATION
2495         }
2496       else
2497         {
2498           _dbus_verbose ("Not reading anything since we just completed the authentication\n");
2499         }
2500 #endif
2501     }
2502   else if (watch == kdbus_transport->write_watch &&
2503            (flags & DBUS_WATCH_WRITABLE))
2504     {
2505 #if 1
2506       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
2507                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
2508 #endif
2509 #ifdef DBUS_AUTHENTICATION
2510       if (!do_authentication (transport, FALSE, TRUE, NULL))
2511         return FALSE;
2512 #endif
2513       if (!do_writing (transport))
2514         {
2515           _dbus_verbose ("no memory to write\n");
2516           return FALSE;
2517         }
2518
2519       /* See if we still need the write watch */
2520       check_write_watch (transport);
2521     }
2522 #ifdef DBUS_ENABLE_VERBOSE_MODE
2523   else
2524     {
2525       if (watch == kdbus_transport->read_watch)
2526         _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
2527                        flags);
2528       else if (watch == kdbus_transport->write_watch)
2529         _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
2530                        flags);
2531       else
2532         _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
2533                        watch, dbus_watch_get_socket (watch));
2534     }
2535 #endif /* DBUS_ENABLE_VERBOSE_MODE */
2536
2537   return TRUE;
2538 }
2539
2540 /*
2541  * copy-paste from socket transport with needed renames only.
2542  */
2543 static void
2544 kdbus_disconnect (DBusTransport *transport)
2545 {
2546   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
2547
2548   _dbus_verbose ("\n");
2549
2550   free_watches (transport);
2551
2552   _dbus_close_socket (kdbus_transport->fd, NULL);
2553   kdbus_transport->fd = -1;
2554 }
2555
2556 /*
2557  * copy-paste from socket transport with needed renames only.
2558  */
2559 static dbus_bool_t
2560 kdbus_connection_set (DBusTransport *transport)
2561 {
2562   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
2563
2564   dbus_connection_set_is_authenticated(transport->connection); //now we don't have authentication in kdbus
2565
2566   _dbus_watch_set_handler (kdbus_transport->write_watch,
2567                            _dbus_connection_handle_watch,
2568                            transport->connection, NULL);
2569
2570   _dbus_watch_set_handler (kdbus_transport->read_watch,
2571                            _dbus_connection_handle_watch,
2572                            transport->connection, NULL);
2573
2574   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2575                                             kdbus_transport->write_watch))
2576     return FALSE;
2577
2578   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2579                                             kdbus_transport->read_watch))
2580     {
2581       _dbus_connection_remove_watch_unlocked (transport->connection,
2582                                               kdbus_transport->write_watch);
2583       return FALSE;
2584     }
2585
2586   check_read_watch (transport);
2587   check_write_watch (transport);
2588
2589   return TRUE;
2590 }
2591
2592 /**  original dbus copy-pasted comment
2593  * @todo We need to have a way to wake up the select sleep if
2594  * a new iteration request comes in with a flag (read/write) that
2595  * we're not currently serving. Otherwise a call that just reads
2596  * could block a write call forever (if there are no incoming
2597  * messages).
2598  */
2599 static  void
2600 kdbus_do_iteration (DBusTransport *transport,
2601                    unsigned int   flags,
2602                    int            timeout_milliseconds)
2603 {
2604         DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
2605         DBusPollFD poll_fd;
2606         int poll_res;
2607         int poll_timeout;
2608
2609         _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
2610                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
2611                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
2612                  timeout_milliseconds,
2613                  kdbus_transport->read_watch,
2614                  kdbus_transport->write_watch,
2615                  kdbus_transport->fd);
2616
2617   /* the passed in DO_READING/DO_WRITING flags indicate whether to
2618    * read/write messages, but regardless of those we may need to block
2619    * for reading/writing to do auth.  But if we do reading for auth,
2620    * we don't want to read any messages yet if not given DO_READING.
2621    */
2622
2623    poll_fd.fd = kdbus_transport->fd;
2624    poll_fd.events = 0;
2625
2626    if (_dbus_transport_try_to_authenticate (transport))
2627    {
2628       /* This is kind of a hack; if we have stuff to write, then try
2629        * to avoid the poll. This is probably about a 5% speedup on an
2630        * echo client/server.
2631        *
2632        * If both reading and writing were requested, we want to avoid this
2633        * since it could have funky effects:
2634        *   - both ends spinning waiting for the other one to read
2635        *     data so they can finish writing
2636        *   - prioritizing all writing ahead of reading
2637        */
2638       if ((flags & DBUS_ITERATION_DO_WRITING) &&
2639           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
2640           !transport->disconnected &&
2641           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
2642       {
2643          do_writing (transport);
2644
2645          if (transport->disconnected ||
2646               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
2647             goto out;
2648       }
2649
2650       /* If we get here, we decided to do the poll() after all */
2651       _dbus_assert (kdbus_transport->read_watch);
2652       if (flags & DBUS_ITERATION_DO_READING)
2653              poll_fd.events |= _DBUS_POLLIN;
2654
2655       _dbus_assert (kdbus_transport->write_watch);
2656       if (flags & DBUS_ITERATION_DO_WRITING)
2657          poll_fd.events |= _DBUS_POLLOUT;
2658    }
2659    else
2660    {
2661       DBusAuthState auth_state;
2662
2663       auth_state = _dbus_auth_do_work (transport->auth);
2664
2665       if (transport->receive_credentials_pending || auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
2666              poll_fd.events |= _DBUS_POLLIN;
2667
2668       if (transport->send_credentials_pending || auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
2669              poll_fd.events |= _DBUS_POLLOUT;
2670    }
2671
2672    if (poll_fd.events)
2673    {
2674       if (flags & DBUS_ITERATION_BLOCK)
2675              poll_timeout = timeout_milliseconds;
2676       else
2677              poll_timeout = 0;
2678
2679       /* For blocking selects we drop the connection lock here
2680        * to avoid blocking out connection access during a potentially
2681        * indefinite blocking call. The io path is still protected
2682        * by the io_path_cond condvar, so we won't reenter this.
2683        */
2684       if (flags & DBUS_ITERATION_BLOCK)
2685       {
2686          _dbus_verbose ("unlock pre poll\n");
2687          _dbus_connection_unlock (transport->connection);
2688       }
2689
2690     again:
2691       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
2692
2693       if (poll_res < 0 && _dbus_get_is_errno_eintr ())
2694       {
2695          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2696          goto again;
2697       }
2698
2699       if (flags & DBUS_ITERATION_BLOCK)
2700       {
2701          _dbus_verbose ("lock post poll\n");
2702          _dbus_connection_lock (transport->connection);
2703       }
2704
2705       if (poll_res >= 0)
2706       {
2707          if (poll_res == 0)
2708             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
2709                                   * valgrind flags it as an error. though it probably
2710                                   * is guaranteed on linux at least.
2711                                   */
2712
2713          if (poll_fd.revents & _DBUS_POLLERR)
2714             do_io_error (transport);
2715          else
2716          {
2717             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
2718             dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
2719 #ifdef DBUS_AUTHENTICATION
2720               dbus_bool_t authentication_completed;
2721 #endif
2722
2723             _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
2724                              need_read, need_write);
2725 #ifdef DBUS_AUTHENTICATION
2726               do_authentication (transport, need_read, need_write,
2727                                  &authentication_completed);
2728
2729               /* See comment in socket_handle_watch. */
2730               if (authentication_completed)
2731                 goto out;
2732 #endif
2733             if (need_read && (flags & DBUS_ITERATION_DO_READING))
2734                do_reading (transport);
2735             if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
2736                do_writing (transport);
2737          }
2738       }
2739       else
2740          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2741    }
2742
2743  out:
2744   /* We need to install the write watch only if we did not
2745    * successfully write everything. Note we need to be careful that we
2746    * don't call check_write_watch *before* do_writing, since it's
2747    * inefficient to add the write watch, and we can avoid it most of
2748    * the time since we can write immediately.
2749    *
2750    * However, we MUST always call check_write_watch(); DBusConnection code
2751    * relies on the fact that running an iteration will notice that
2752    * messages are pending.
2753    */
2754    check_write_watch (transport);
2755
2756    _dbus_verbose (" ... leaving do_iteration()\n");
2757 }
2758
2759 /*
2760  * copy-paste from socket transport with needed renames only.
2761  */
2762 static void
2763 kdbus_live_messages_changed (DBusTransport *transport)
2764 {
2765   /* See if we should look for incoming messages again */
2766   check_read_watch (transport);
2767 }
2768
2769 static const DBusTransportVTable kdbus_vtable = {
2770   transport_finalize,
2771   kdbus_handle_watch,
2772   kdbus_disconnect,
2773   kdbus_connection_set,
2774   kdbus_do_iteration,
2775   kdbus_live_messages_changed,
2776   kdbus_get_kdbus_fd
2777 };
2778
2779 /**
2780  * Creates a new transport for the given kdbus file descriptor.  The file
2781  * descriptor must be nonblocking.
2782  *
2783  * @param fd the file descriptor.
2784  * @param address the transport's address
2785  * @returns the new transport, or #NULL if no memory.
2786  */
2787 static DBusTransport*
2788 _dbus_transport_new_kdbus_transport (int fd, const DBusString *address)
2789 {
2790         DBusTransportKdbus *kdbus_transport;
2791
2792   kdbus_transport = dbus_new0 (DBusTransportKdbus, 1);
2793   if (kdbus_transport == NULL)
2794     return NULL;
2795
2796   if (!_dbus_string_init (&kdbus_transport->encoded_outgoing))
2797     goto failed_0;
2798
2799   if (!_dbus_string_init (&kdbus_transport->encoded_incoming))
2800     goto failed_1;
2801
2802   kdbus_transport->write_watch = _dbus_watch_new (fd,
2803                                                  DBUS_WATCH_WRITABLE,
2804                                                  FALSE,
2805                                                  NULL, NULL, NULL);
2806   if (kdbus_transport->write_watch == NULL)
2807     goto failed_2;
2808
2809   kdbus_transport->read_watch = _dbus_watch_new (fd,
2810                                                 DBUS_WATCH_READABLE,
2811                                                 FALSE,
2812                                                 NULL, NULL, NULL);
2813   if (kdbus_transport->read_watch == NULL)
2814     goto failed_3;
2815
2816   if (!_dbus_transport_init_base (&kdbus_transport->base,
2817                                   &kdbus_vtable,
2818                                   NULL, address))
2819     goto failed_4;
2820
2821 #ifdef DBUS_AUTHENTICATION
2822 #ifdef HAVE_UNIX_FD_PASSING
2823   _dbus_auth_set_unix_fd_possible(kdbus_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
2824 #endif
2825 #endif
2826
2827   kdbus_transport->fd = fd;
2828   kdbus_transport->message_bytes_written = 0;
2829
2830   /* These values should probably be tunable or something. */
2831   kdbus_transport->max_bytes_read_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2832   kdbus_transport->max_bytes_written_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2833
2834   kdbus_transport->kdbus_mmap_ptr = NULL;
2835   kdbus_transport->memfd = -1;
2836   
2837   return (DBusTransport*) kdbus_transport;
2838
2839  failed_4:
2840   _dbus_watch_invalidate (kdbus_transport->read_watch);
2841   _dbus_watch_unref (kdbus_transport->read_watch);
2842  failed_3:
2843   _dbus_watch_invalidate (kdbus_transport->write_watch);
2844   _dbus_watch_unref (kdbus_transport->write_watch);
2845  failed_2:
2846   _dbus_string_free (&kdbus_transport->encoded_incoming);
2847  failed_1:
2848   _dbus_string_free (&kdbus_transport->encoded_outgoing);
2849  failed_0:
2850   dbus_free (kdbus_transport);
2851   return NULL;
2852 }
2853
2854 /**
2855  * Opens a connection to the kdbus bus
2856  *
2857  * This will set FD_CLOEXEC for the socket returned.
2858  *
2859  * @param path the path to UNIX domain socket
2860  * @param error return location for error code
2861  * @returns connection file descriptor or -1 on error
2862  */
2863 static int _dbus_connect_kdbus (const char *path, DBusError *error)
2864 {
2865         int fd;
2866
2867         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2868         _dbus_verbose ("connecting to kdbus bus %s\n", path);
2869
2870         fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK);
2871         if (fd < 0)
2872                 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
2873
2874         return fd;
2875 }
2876
2877 /**
2878  * Creates a new transport for kdbus.
2879  * This creates a client-side of a transport.
2880  *
2881  * @param path the path to the bus.
2882  * @param error address where an error can be returned.
2883  * @returns a new transport, or #NULL on failure.
2884  */
2885 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
2886 {
2887         int fd;
2888         DBusTransport *transport;
2889         DBusString address;
2890
2891         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2892
2893         if (!_dbus_string_init (&address))
2894     {
2895                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2896                 return NULL;
2897     }
2898
2899         fd = -1;
2900
2901         if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
2902     {
2903                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2904                 goto failed_0;
2905     }
2906
2907         fd = _dbus_connect_kdbus (path, error);
2908         if (fd < 0)
2909     {
2910                 _DBUS_ASSERT_ERROR_IS_SET (error);
2911                 goto failed_0;
2912     }
2913
2914         _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
2915
2916         transport = _dbus_transport_new_kdbus_transport (fd, &address);
2917         if (transport == NULL)
2918     {
2919                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2920                 goto failed_1;
2921     }
2922
2923         _dbus_string_free (&address);
2924
2925         return transport;
2926
2927         failed_1:
2928                 _dbus_close_socket (fd, NULL);
2929         failed_0:
2930                 _dbus_string_free (&address);
2931         return NULL;
2932 }
2933
2934
2935 /**
2936  * Opens kdbus transport if method from address entry is kdbus
2937  *
2938  * @param entry the address entry to try opening
2939  * @param transport_p return location for the opened transport
2940  * @param error error to be set
2941  * @returns result of the attempt
2942  */
2943 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
2944                                                            DBusTransport    **transport_p,
2945                                                            DBusError         *error)
2946 {
2947         const char *method;
2948
2949         method = dbus_address_entry_get_method (entry);
2950         _dbus_assert (method != NULL);
2951
2952         if (strcmp (method, "kdbus") == 0)
2953     {
2954                 const char *path = dbus_address_entry_get_value (entry, "path");
2955
2956                 if (path == NULL)
2957         {
2958                         _dbus_set_bad_address (error, "kdbus", "path", NULL);
2959                         return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
2960         }
2961
2962         *transport_p = _dbus_transport_new_for_kdbus (path, error);
2963
2964         if (*transport_p == NULL)
2965         {
2966                 _DBUS_ASSERT_ERROR_IS_SET (error);
2967                 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
2968         }
2969         else
2970         {
2971                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2972                 return DBUS_TRANSPORT_OPEN_OK;
2973         }
2974     }
2975         else
2976     {
2977                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2978                 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
2979     }
2980 }