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