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