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