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