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