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