13dd2b6ddb5da079c660f3cd573cd22a8b6b41b8
[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 /**
1231  * Get the length of the kdbus message content.
1232  *
1233  * @param msg kdbus message
1234  * @return the length of the kdbus message
1235  */
1236 static int kdbus_message_size(const struct kdbus_msg* msg)
1237 {
1238         const struct kdbus_item *item;
1239         int ret_size = 0;
1240
1241         KDBUS_PART_FOREACH(item, msg, items)
1242         {
1243                 if (item->size <= KDBUS_PART_HEADER_SIZE)
1244                 {
1245                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
1246                         return -1;
1247                 }
1248                 switch (item->type)
1249                 {
1250                         case KDBUS_MSG_PAYLOAD_OFF:
1251                                 ret_size += item->vec.size;
1252                                 break;
1253                         case KDBUS_MSG_PAYLOAD_MEMFD:
1254                                 ret_size += item->memfd.size;
1255                                 break;
1256                         default:
1257                                 break;
1258                 }
1259         }
1260
1261         return ret_size;
1262 }
1263
1264 /**
1265  * Decodes kdbus message in order to extract dbus message and put it into data and fds.
1266  * Also captures and decodes kdbus error messages and kdbus kernel broadcasts and converts
1267  * all of them into dbus messages.
1268  *
1269  * @param msg kdbus message
1270  * @param data place to copy dbus message to
1271  * @param socket_transport transport
1272  * @param fds place to store file descriptors received
1273  * @param n_fds place to store quantity of file descriptor
1274  * @return number of dbus message's bytes received or -1 on error
1275  */
1276 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, DBusTransportSocket* socket_transport, int* fds, int* n_fds)
1277 {
1278         const struct kdbus_item *item;
1279         int ret_size = 0;
1280         DBusMessage *message = NULL;
1281         DBusMessageIter args;
1282         const char* emptyString = "";
1283     const char* pString = NULL;
1284         char dbus_name[(unsigned int)(snprintf((char*)pString, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
1285         const char* pDBusName = dbus_name;
1286 #if KDBUS_MSG_DECODE_DEBUG == 1
1287         char buf[32];
1288 #endif
1289
1290 #if KDBUS_MSG_DECODE_DEBUG == 1
1291         _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
1292                 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
1293                 (unsigned long long) msg->flags,
1294                 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
1295                 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
1296 #endif
1297
1298         *n_fds = 0;
1299
1300         KDBUS_PART_FOREACH(item, msg, items)
1301         {
1302                 if (item->size <= KDBUS_PART_HEADER_SIZE)
1303                 {
1304                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
1305                         break;  //??? continue (because dbus will find error) or break
1306                 }
1307
1308                 switch (item->type)
1309                 {
1310                         case KDBUS_MSG_PAYLOAD_OFF:
1311                                 memcpy(data, (char *)socket_transport->kdbus_mmap_ptr + item->vec.offset, item->vec.size);
1312                                 data += item->vec.size;
1313                                 ret_size += item->vec.size;
1314
1315                                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
1316                                         enum_MSG(item->type), item->size,
1317                                         (unsigned long long)item->vec.offset,
1318                                         (unsigned long long)item->vec.size);
1319                         break;
1320
1321                         case KDBUS_MSG_PAYLOAD_MEMFD:
1322                         {
1323                                 char *buf;
1324                                 uint64_t size;
1325
1326                                 size = item->memfd.size;
1327                                 _dbus_verbose("memfd.size : %llu\n", (unsigned long long)size);
1328
1329                                 buf = mmap(NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0);
1330                                 if (buf == MAP_FAILED)
1331                                 {
1332                                         _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
1333                                         return -1;
1334                                 }
1335
1336                                 memcpy(data, buf, size);
1337                                 data += size;
1338                                 ret_size += size;
1339
1340                                 munmap(buf, size);
1341
1342                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
1343                                            enum_MSG(item->type), item->size,
1344                                            (unsigned long long)item->vec.offset,
1345                                            (unsigned long long)item->vec.size);
1346                         break;
1347                         }
1348
1349                         case KDBUS_MSG_FDS:
1350                         {
1351                                 int i;
1352
1353                                 *n_fds = (item->size - KDBUS_PART_HEADER_SIZE) / sizeof(int);
1354                                 memcpy(fds, item->fds, *n_fds * sizeof(int));
1355                     for (i = 0; i < *n_fds; i++)
1356                       _dbus_fd_set_close_on_exec(fds[i]);
1357                         break;
1358                         }
1359
1360 #if KDBUS_MSG_DECODE_DEBUG == 1
1361                         case KDBUS_MSG_SRC_CREDS:
1362                                 _dbus_verbose("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
1363                                         enum_MSG(item->type), item->size,
1364                                         item->creds.uid, item->creds.gid,
1365                                         item->creds.pid, item->creds.tid,
1366                                         item->creds.starttime);
1367                         break;
1368
1369                         case KDBUS_MSG_SRC_PID_COMM:
1370                         case KDBUS_MSG_SRC_TID_COMM:
1371                         case KDBUS_MSG_SRC_EXE:
1372                         case KDBUS_MSG_SRC_CGROUP:
1373                         case KDBUS_MSG_SRC_SECLABEL:
1374                         case KDBUS_MSG_DST_NAME:
1375                                 _dbus_verbose("  +%s (%llu bytes) '%s' (%zu)\n",
1376                                            enum_MSG(item->type), item->size, item->str, strlen(item->str));
1377                                 break;
1378
1379                         case KDBUS_MSG_SRC_CMDLINE:
1380                         case KDBUS_MSG_SRC_NAMES: {
1381                                 __u64 size = item->size - KDBUS_PART_HEADER_SIZE;
1382                                 const char *str = item->str;
1383                                 int count = 0;
1384
1385                                 _dbus_verbose("  +%s (%llu bytes) ", enum_MSG(item->type), item->size);
1386                                 while (size) {
1387                                         _dbus_verbose("'%s' ", str);
1388                                         size -= strlen(str) + 1;
1389                                         str += strlen(str) + 1;
1390                                         count++;
1391                                 }
1392
1393                                 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
1394                                 break;
1395                         }
1396
1397                         case KDBUS_MSG_SRC_AUDIT:
1398                                 _dbus_verbose("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
1399                                            enum_MSG(item->type), item->size,
1400                                            (unsigned long long)item->data64[0],
1401                                            (unsigned long long)item->data64[1]);
1402                                 break;
1403
1404                         case KDBUS_MSG_SRC_CAPS: {
1405                                 int n;
1406                                 const uint32_t *cap;
1407                                 int i;
1408
1409                                 _dbus_verbose("  +%s (%llu bytes) len=%llu bytes)\n",
1410                                            enum_MSG(item->type), item->size,
1411                                            (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
1412
1413                                 cap = item->data32;
1414                                 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
1415
1416                                 _dbus_verbose("    CapInh=");
1417                                 for (i = 0; i < n; i++)
1418                                         _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
1419
1420                                 _dbus_verbose(" CapPrm=");
1421                                 for (i = 0; i < n; i++)
1422                                         _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
1423
1424                                 _dbus_verbose(" CapEff=");
1425                                 for (i = 0; i < n; i++)
1426                                         _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
1427
1428                                 _dbus_verbose(" CapInh=");
1429                                 for (i = 0; i < n; i++)
1430                                         _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
1431                                 _dbus_verbose("\n");
1432                                 break;
1433                         }
1434
1435                         case KDBUS_MSG_TIMESTAMP:
1436                                 _dbus_verbose("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
1437                                            enum_MSG(item->type), item->size,
1438                                            (unsigned long long)item->timestamp.realtime_ns,
1439                                            (unsigned long long)item->timestamp.monotonic_ns);
1440                                 break;
1441 #endif
1442
1443                         case KDBUS_MSG_REPLY_TIMEOUT:
1444                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
1445                                            enum_MSG(item->type), item->size, msg->cookie_reply);
1446
1447                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NO_REPLY, NULL);
1448                                 if(message == NULL)
1449                                 {
1450                                         ret_size = -1;
1451                                         goto out;
1452                                 }
1453
1454                                 ret_size = put_message_into_data(message, data);
1455                         break;
1456
1457                         case KDBUS_MSG_REPLY_DEAD:
1458                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
1459                                            enum_MSG(item->type), item->size, msg->cookie_reply);
1460
1461                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NAME_HAS_NO_OWNER, NULL);
1462                                 if(message == NULL)
1463                                 {
1464                                         ret_size = -1;
1465                                         goto out;
1466                                 }
1467
1468                                 ret_size = put_message_into_data(message, data);
1469                         break;
1470
1471                         case KDBUS_MSG_NAME_ADD:
1472                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1473                                         enum_MSG(item->type), (unsigned long long) item->size,
1474                                         item->name_change.name, item->name_change.old_id,
1475                                         item->name_change.new_id, item->name_change.flags);
1476
1477                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1478                                 if(message == NULL)
1479                                 {
1480                                         ret_size = -1;
1481                                         goto out;
1482                                 }
1483
1484                                 sprintf(dbus_name,":1.%llu",item->name_change.new_id);
1485                                 pString = item->name_change.name;
1486                                 _dbus_verbose ("Name added: %s\n", pString);
1487                             dbus_message_iter_init_append(message, &args);
1488                             ITER_APPEND_STR(pString)
1489                             ITER_APPEND_STR(emptyString)
1490                             ITER_APPEND_STR(pDBusName)
1491                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1492
1493                                 ret_size = put_message_into_data(message, data);
1494                         break;
1495
1496                         case KDBUS_MSG_NAME_REMOVE:
1497                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1498                                         enum_MSG(item->type), (unsigned long long) item->size,
1499                                         item->name_change.name, item->name_change.old_id,
1500                                         item->name_change.new_id, item->name_change.flags);
1501
1502                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged"); // name of the signal
1503                                 if(message == NULL)
1504                                 {
1505                                         ret_size = -1;
1506                                         goto out;
1507                                 }
1508
1509                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1510                                 pString = item->name_change.name;
1511                                 _dbus_verbose ("Name removed: %s\n", pString);
1512                             dbus_message_iter_init_append(message, &args);
1513                             ITER_APPEND_STR(pString)
1514                             ITER_APPEND_STR(pDBusName)
1515                             ITER_APPEND_STR(emptyString)
1516                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1517
1518                                 ret_size = put_message_into_data(message, data);
1519                         break;
1520
1521                         case KDBUS_MSG_NAME_CHANGE:
1522                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1523                                         enum_MSG(item->type), (unsigned long long) item->size,
1524                                         item->name_change.name, item->name_change.old_id,
1525                                         item->name_change.new_id, item->name_change.flags);
1526
1527                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1528                                 if(message == NULL)
1529                                 {
1530                                         ret_size = -1;
1531                                         goto out;
1532                                 }
1533
1534                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1535                                 pString = item->name_change.name;
1536                                 _dbus_verbose ("Name changed: %s\n", pString);
1537                             dbus_message_iter_init_append(message, &args);
1538                             ITER_APPEND_STR(pString)
1539                             ITER_APPEND_STR(pDBusName)
1540                             sprintf(&dbus_name[3],"%llu",item->name_change.new_id);
1541                             _dbus_verbose ("New id: %s\n", pDBusName);
1542                             ITER_APPEND_STR(pDBusName)
1543                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1544
1545                                 ret_size = put_message_into_data(message, data);
1546                         break;
1547
1548                         case KDBUS_MSG_ID_ADD:
1549                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1550                                            enum_MSG(item->type), (unsigned long long) item->size,
1551                                            (unsigned long long) item->id_change.id,
1552                                            (unsigned long long) item->id_change.flags);
1553
1554                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1555                                 if(message == NULL)
1556                                 {
1557                                         ret_size = -1;
1558                                         goto out;
1559                                 }
1560
1561                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1562                             dbus_message_iter_init_append(message, &args);
1563                             ITER_APPEND_STR(pDBusName)
1564                             ITER_APPEND_STR(emptyString)
1565                             ITER_APPEND_STR(pDBusName)
1566                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1567
1568                                 ret_size = put_message_into_data(message, data);
1569                         break;
1570
1571                         case KDBUS_MSG_ID_REMOVE:
1572                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1573                                            enum_MSG(item->type), (unsigned long long) item->size,
1574                                            (unsigned long long) item->id_change.id,
1575                                            (unsigned long long) item->id_change.flags);
1576
1577                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1578                                 if(message == NULL)
1579                                 {
1580                                         ret_size = -1;
1581                                         goto out;
1582                                 }
1583
1584                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1585                             dbus_message_iter_init_append(message, &args);
1586                             ITER_APPEND_STR(pDBusName)
1587                             ITER_APPEND_STR(pDBusName)
1588                             ITER_APPEND_STR(emptyString)
1589                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1590
1591                                 ret_size = put_message_into_data(message, data);
1592                         break;
1593 #if KDBUS_MSG_DECODE_DEBUG == 1
1594                         default:
1595                                 _dbus_verbose("  +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
1596                         break;
1597 #endif
1598                 }
1599         }
1600
1601 #if KDBUS_MSG_DECODE_DEBUG == 1
1602
1603         if ((char *)item - ((char *)msg + msg->size) >= 8)
1604                 _dbus_verbose("invalid padding at end of message\n");
1605 #endif
1606
1607 out:
1608         if(message)
1609                 dbus_message_unref(message);
1610         return ret_size;
1611 }
1612
1613 /**
1614  * Reads message from kdbus and puts it into dbus buffer and fds
1615  *
1616  * @param transport transport
1617  * @param buffer place to copy received message to
1618  * @param fds place to store file descriptors sent in the message
1619  * @param n_fds place  to store number of file descriptors
1620  * @return size of received message on success, -1 on error
1621  */
1622 static int kdbus_read_message(DBusTransportSocket *socket_transport, DBusString *buffer, int* fds, int* n_fds)
1623 {
1624         int ret_size, buf_size;
1625         uint64_t __attribute__ ((__aligned__(8))) offset;
1626         struct kdbus_msg *msg;
1627         char *data;
1628         int start;
1629
1630         start = _dbus_string_get_length (buffer);
1631
1632         again:
1633         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
1634         {
1635                 if(errno == EINTR)
1636                         goto again;
1637                 _dbus_verbose("kdbus error receiving message: %d (%m)\n", errno);
1638                 _dbus_string_set_length (buffer, start);
1639                 return -1;
1640         }
1641
1642         msg = (struct kdbus_msg *)((char*)socket_transport->kdbus_mmap_ptr + offset);
1643
1644         buf_size = kdbus_message_size(msg);
1645         if (buf_size == -1)
1646         {
1647                 _dbus_verbose("kdbus error - too short message: %d (%m)\n", errno);
1648                 return -1;
1649         }
1650
1651         /* What is the maximum size of the locally generated message?
1652            I just assume 2048 bytes */
1653         buf_size = MAX(buf_size, 2048);
1654
1655         if (!_dbus_string_lengthen (buffer, buf_size))
1656         {
1657                 errno = ENOMEM;
1658                 return -1;
1659         }
1660         data = _dbus_string_get_data_len (buffer, start, buf_size);
1661
1662         ret_size = kdbus_decode_msg(msg, data, socket_transport, fds, n_fds);
1663
1664         if(ret_size == -1) /* error */
1665         {
1666                 _dbus_string_set_length (buffer, start);
1667                 return -1;
1668         }
1669         else if (buf_size != ret_size) /* case of locally generated message */
1670         {
1671                 _dbus_string_set_length (buffer, start + ret_size);
1672         }
1673
1674         again2:
1675         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
1676         {
1677                 if(errno == EINTR)
1678                         goto again2;
1679                 _dbus_verbose("kdbus error freeing message: %d (%m)\n", errno);
1680                 return -1;
1681         }
1682
1683         return ret_size;
1684 }
1685
1686 static void
1687 free_watches (DBusTransport *transport)
1688 {
1689   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1690
1691   _dbus_verbose ("start\n");
1692
1693   if (socket_transport->read_watch)
1694     {
1695       if (transport->connection)
1696         _dbus_connection_remove_watch_unlocked (transport->connection,
1697                                                 socket_transport->read_watch);
1698       _dbus_watch_invalidate (socket_transport->read_watch);
1699       _dbus_watch_unref (socket_transport->read_watch);
1700       socket_transport->read_watch = NULL;
1701     }
1702
1703   if (socket_transport->write_watch)
1704     {
1705       if (transport->connection)
1706         _dbus_connection_remove_watch_unlocked (transport->connection,
1707                                                 socket_transport->write_watch);
1708       _dbus_watch_invalidate (socket_transport->write_watch);
1709       _dbus_watch_unref (socket_transport->write_watch);
1710       socket_transport->write_watch = NULL;
1711     }
1712
1713   _dbus_verbose ("end\n");
1714 }
1715
1716 static void
1717 socket_finalize (DBusTransport *transport)
1718 {
1719   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1720
1721   _dbus_verbose ("\n");
1722
1723   free_watches (transport);
1724
1725   _dbus_string_free (&socket_transport->encoded_outgoing);
1726   _dbus_string_free (&socket_transport->encoded_incoming);
1727
1728   _dbus_transport_finalize_base (transport);
1729
1730   _dbus_assert (socket_transport->read_watch == NULL);
1731   _dbus_assert (socket_transport->write_watch == NULL);
1732
1733   dbus_free (transport);
1734 }
1735
1736 static void
1737 check_write_watch (DBusTransport *transport)
1738 {
1739   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1740   dbus_bool_t needed;
1741
1742   if (transport->connection == NULL)
1743     return;
1744
1745   if (transport->disconnected)
1746     {
1747       _dbus_assert (socket_transport->write_watch == NULL);
1748       return;
1749     }
1750
1751   _dbus_transport_ref (transport);
1752
1753 #ifdef DBUS_AUTHENTICATION
1754   if (_dbus_transport_try_to_authenticate (transport))
1755 #endif
1756     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1757 #ifdef DBUS_AUTHENTICATION
1758   else
1759     {
1760       if (transport->send_credentials_pending)
1761         needed = TRUE;
1762       else
1763         {
1764           DBusAuthState auth_state;
1765
1766           auth_state = _dbus_auth_do_work (transport->auth);
1767
1768           /* If we need memory we install the write watch just in case,
1769            * if there's no need for it, it will get de-installed
1770            * next time we try reading.
1771            */
1772           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
1773               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1774             needed = TRUE;
1775           else
1776             needed = FALSE;
1777         }
1778     }
1779 #endif
1780   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1781                  needed, transport->connection, socket_transport->write_watch,
1782                  socket_transport->fd,
1783                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1784
1785   _dbus_connection_toggle_watch_unlocked (transport->connection,
1786                                           socket_transport->write_watch,
1787                                           needed);
1788
1789   _dbus_transport_unref (transport);
1790 }
1791
1792 static void
1793 check_read_watch (DBusTransport *transport)
1794 {
1795   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1796   dbus_bool_t need_read_watch;
1797
1798   _dbus_verbose ("fd = %d\n",socket_transport->fd);
1799
1800   if (transport->connection == NULL)
1801     return;
1802
1803   if (transport->disconnected)
1804     {
1805       _dbus_assert (socket_transport->read_watch == NULL);
1806       return;
1807     }
1808
1809   _dbus_transport_ref (transport);
1810
1811 #ifdef DBUS_AUTHENTICATION
1812   if (_dbus_transport_try_to_authenticate (transport))
1813 #endif
1814     need_read_watch =
1815       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1816       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1817 #ifdef DBUS_AUTHENTICATION
1818   else
1819     {
1820       if (transport->receive_credentials_pending)
1821         need_read_watch = TRUE;
1822       else
1823         {
1824           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
1825            * is to avoid spinning on the file descriptor when we're waiting
1826            * to write or for some other part of the auth process
1827            */
1828           DBusAuthState auth_state;
1829
1830           auth_state = _dbus_auth_do_work (transport->auth);
1831
1832           /* If we need memory we install the read watch just in case,
1833            * if there's no need for it, it will get de-installed
1834            * next time we try reading. If we're authenticated we
1835            * install it since we normally have it installed while
1836            * authenticated.
1837            */
1838           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
1839               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
1840               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
1841             need_read_watch = TRUE;
1842           else
1843             need_read_watch = FALSE;
1844         }
1845     }
1846 #endif
1847
1848   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
1849   _dbus_connection_toggle_watch_unlocked (transport->connection,
1850                                           socket_transport->read_watch,
1851                                           need_read_watch);
1852
1853   _dbus_transport_unref (transport);
1854 }
1855
1856 static void
1857 do_io_error (DBusTransport *transport)
1858 {
1859   _dbus_transport_ref (transport);
1860   _dbus_transport_disconnect (transport);
1861   _dbus_transport_unref (transport);
1862 }
1863
1864 #ifdef DBUS_AUTHENTICATION
1865 /* return value is whether we successfully read any new data. */
1866 static dbus_bool_t
1867 read_data_into_auth (DBusTransport *transport,
1868                      dbus_bool_t   *oom)
1869 {
1870   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1871   DBusString *buffer;
1872   int bytes_read;
1873   int *fds, n_fds;
1874
1875   *oom = FALSE;
1876
1877   _dbus_auth_get_buffer (transport->auth, &buffer);
1878
1879   bytes_read = kdbus_read_message(socket_transport, buffer, fds, &n_fds);
1880
1881   _dbus_auth_return_buffer (transport->auth, buffer,
1882                             bytes_read > 0 ? bytes_read : 0);
1883
1884   if (bytes_read > 0)
1885     {
1886       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
1887       return TRUE;
1888     }
1889   else if (bytes_read < 0)
1890     {
1891       /* EINTR already handled for us */
1892
1893       if (_dbus_get_is_errno_enomem ())
1894         {
1895           *oom = TRUE;
1896         }
1897       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1898         ; /* do nothing, just return FALSE below */
1899       else
1900         {
1901           _dbus_verbose ("Error reading from remote app: %s\n",
1902                          _dbus_strerror_from_errno ());
1903           do_io_error (transport);
1904         }
1905
1906       return FALSE;
1907     }
1908   else
1909     {
1910       _dbus_assert (bytes_read == 0);
1911
1912       _dbus_verbose ("Disconnected from remote app\n");
1913       do_io_error (transport);
1914
1915       return FALSE;
1916     }
1917 }
1918
1919 static int kdbus_send_auth (DBusTransport *transport,  const DBusString *buffer)
1920 {
1921         int len;
1922         int bytes_written = -1;
1923         struct kdbus_msg *msg;
1924         struct kdbus_item *item;
1925
1926         len = _dbus_string_get_length (buffer);
1927 //      data = _dbus_string_get_const_data_len (buffer, 0, len);
1928
1929         msg = kdbus_init_msg(NULL, 1, 0, FALSE, 0, (DBusTransportSocket*)transport);
1930         item = msg->items;
1931         MSG_ITEM_BUILD_VEC(_dbus_string_get_const_data_len (buffer, 0, len), len);
1932
1933     again:
1934     if(ioctl(((DBusTransportSocket*)transport)->fd, KDBUS_CMD_MSG_SEND, msg))
1935     {
1936         if(errno == EINTR)
1937             goto again;
1938         _dbus_verbose ("Error writing auth: %d, %m\n", errno);
1939     }
1940     else
1941         bytes_written = len;
1942
1943         return bytes_written;
1944 }
1945
1946 /* Return value is whether we successfully wrote any bytes */
1947 static dbus_bool_t
1948 write_data_from_auth (DBusTransport *transport)
1949 {
1950 //  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1951   int bytes_written;
1952   const DBusString *buffer;
1953
1954   if (!_dbus_auth_get_bytes_to_send (transport->auth,
1955                                      &buffer))
1956     return FALSE;
1957
1958   bytes_written = kdbus_send_auth (transport, buffer);
1959
1960   if (bytes_written > 0)
1961     {
1962       _dbus_auth_bytes_sent (transport->auth, bytes_written);
1963       return TRUE;
1964     }
1965   else if (bytes_written < 0)
1966     {
1967       /* EINTR already handled for us */
1968
1969       if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1970         ;
1971       else
1972         {
1973           _dbus_verbose ("Error writing to remote app: %s\n",
1974                          _dbus_strerror_from_errno ());
1975           do_io_error (transport);
1976         }
1977     }
1978
1979   return FALSE;
1980 }
1981
1982 /* FALSE on OOM */
1983 static dbus_bool_t
1984 exchange_credentials (DBusTransport *transport,
1985                       dbus_bool_t    do_reading,
1986                       dbus_bool_t    do_writing)
1987 {
1988   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1989   DBusError error = DBUS_ERROR_INIT;
1990
1991   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
1992                   do_reading, do_writing);
1993
1994   if (do_writing && transport->send_credentials_pending)
1995     {
1996       if (_dbus_send_credentials_socket (socket_transport->fd,
1997                                          &error))
1998         {
1999           transport->send_credentials_pending = FALSE;
2000         }
2001       else
2002         {
2003           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
2004           dbus_error_free (&error);
2005           do_io_error (transport);
2006         }
2007     }
2008
2009   if (do_reading && transport->receive_credentials_pending)
2010     {
2011       /* FIXME this can fail due to IO error _or_ OOM, broken
2012        * (somewhat tricky to fix since the OOM error can be set after
2013        * we already read the credentials byte, so basically we need to
2014        * separate reading the byte and storing it in the
2015        * transport->credentials). Does not really matter for now
2016        * because storing in credentials never actually fails on unix.
2017        */
2018       if (_dbus_read_credentials_socket (socket_transport->fd,
2019                                          transport->credentials,
2020                                          &error))
2021         {
2022           transport->receive_credentials_pending = FALSE;
2023         }
2024       else
2025         {
2026           _dbus_verbose ("Failed to read credentials %s\n", error.message);
2027           dbus_error_free (&error);
2028           do_io_error (transport);
2029         }
2030     }
2031
2032   if (!(transport->send_credentials_pending ||
2033         transport->receive_credentials_pending))
2034     {
2035       if (!_dbus_auth_set_credentials (transport->auth,
2036                                        transport->credentials))
2037         return FALSE;
2038     }
2039
2040   return TRUE;
2041 }
2042
2043 static dbus_bool_t
2044 do_authentication (DBusTransport *transport,
2045                    dbus_bool_t    do_reading,
2046                    dbus_bool_t    do_writing,
2047                    dbus_bool_t   *auth_completed)
2048 {
2049   dbus_bool_t oom;
2050   dbus_bool_t orig_auth_state;
2051
2052   oom = FALSE;
2053
2054   orig_auth_state = _dbus_transport_try_to_authenticate (transport);
2055
2056   /* This is essential to avoid the check_write_watch() at the end,
2057    * we don't want to add a write watch in do_iteration before
2058    * we try writing and get EAGAIN
2059    */
2060   if (orig_auth_state)
2061     {
2062       if (auth_completed)
2063         *auth_completed = FALSE;
2064       return TRUE;
2065     }
2066
2067   _dbus_transport_ref (transport);
2068
2069    while (!_dbus_transport_try_to_authenticate (transport) &&
2070          _dbus_transport_get_is_connected (transport))
2071     {
2072       if (!exchange_credentials (transport, do_reading, do_writing))
2073         {
2074           oom = TRUE;
2075           goto out;
2076         }
2077
2078       if (transport->send_credentials_pending ||
2079           transport->receive_credentials_pending)
2080         {
2081           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
2082                          transport->send_credentials_pending,
2083                          transport->receive_credentials_pending);
2084           goto out;
2085         }
2086
2087 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
2088       switch (_dbus_auth_do_work (transport->auth))
2089         {
2090         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
2091           _dbus_verbose (" %s auth state: waiting for input\n",
2092                          TRANSPORT_SIDE (transport));
2093           if (!do_reading || !read_data_into_auth (transport, &oom))
2094             goto out;
2095           break;
2096
2097         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
2098           _dbus_verbose (" %s auth state: waiting for memory\n",
2099                          TRANSPORT_SIDE (transport));
2100           oom = TRUE;
2101           goto out;
2102           break;
2103
2104         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
2105           _dbus_verbose (" %s auth state: bytes to send\n",
2106                          TRANSPORT_SIDE (transport));
2107           if (!do_writing || !write_data_from_auth (transport))
2108             goto out;
2109           break;
2110
2111         case DBUS_AUTH_STATE_NEED_DISCONNECT:
2112           _dbus_verbose (" %s auth state: need to disconnect\n",
2113                          TRANSPORT_SIDE (transport));
2114           do_io_error (transport);
2115           break;
2116
2117         case DBUS_AUTH_STATE_AUTHENTICATED:
2118           _dbus_verbose (" %s auth state: authenticated\n",
2119                          TRANSPORT_SIDE (transport));
2120           break;
2121         }
2122     }
2123
2124  out:
2125   if (auth_completed)
2126     *auth_completed = (orig_auth_state != _dbus_transport_try_to_authenticate (transport));
2127
2128   check_read_watch (transport);
2129   check_write_watch (transport);
2130   _dbus_transport_unref (transport);
2131
2132   if (oom)
2133     return FALSE;
2134   else
2135     return TRUE;
2136 }
2137 #endif
2138
2139 /* returns false on oom */
2140 static dbus_bool_t
2141 do_writing (DBusTransport *transport)
2142 {
2143         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2144         dbus_bool_t oom;
2145
2146 #ifdef DBUS_AUTHENTICATION
2147         /* No messages without authentication! */
2148         if (!_dbus_transport_try_to_authenticate (transport))
2149     {
2150                 _dbus_verbose ("Not authenticated, not writing anything\n");
2151                 return TRUE;
2152     }
2153 #endif
2154
2155         if (transport->disconnected)
2156     {
2157                 _dbus_verbose ("Not connected, not writing anything\n");
2158                 return TRUE;
2159     }
2160
2161 #if 1
2162         _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
2163                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
2164                  socket_transport->fd);
2165 #endif
2166
2167         oom = FALSE;
2168
2169         while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
2170     {
2171                 int bytes_written;
2172                 DBusMessage *message;
2173                 const DBusString *header;
2174                 const DBusString *body;
2175                 int total_bytes_to_write;
2176                 const char* pDestination;
2177
2178                 message = _dbus_connection_get_message_to_send (transport->connection);
2179                 _dbus_assert (message != NULL);
2180                 if(dbus_message_get_sender(message) == NULL)  //needed for daemon to pass pending activation messages
2181                 {
2182             dbus_message_unlock(message);
2183             dbus_message_set_sender(message, socket_transport->sender);
2184             dbus_message_lock (message);
2185                 }
2186                 _dbus_message_get_network_data (message, &header, &body);
2187                 total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
2188                 pDestination = dbus_message_get_destination(message);
2189
2190                 if(pDestination)
2191                 {
2192                         if(!strcmp(pDestination, DBUS_SERVICE_DBUS))
2193                         {
2194                                 if(!strcmp(dbus_message_get_interface(message), DBUS_INTERFACE_DBUS))
2195                                 {
2196                                         int ret;
2197
2198                                         ret = emulateOrgFreedesktopDBus(transport, message);
2199                                         if(ret < 0)
2200                                         {
2201                                                 bytes_written = -1;
2202                                                 goto written;
2203                                         }
2204                                         else if(ret == 0)
2205                                         {
2206                                                 bytes_written = total_bytes_to_write;
2207                                                 goto written;
2208                                         }
2209                                         //else send to "daemon" as to normal recipient
2210                                 }
2211                         }
2212                 }
2213                 if (_dbus_auth_needs_encoding (transport->auth))
2214         {
2215                         if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
2216             {
2217                                 if (!_dbus_auth_encode_data (transport->auth,
2218                                            header, &socket_transport->encoded_outgoing))
2219                 {
2220                                         oom = TRUE;
2221                                         goto out;
2222                 }
2223
2224                                 if (!_dbus_auth_encode_data (transport->auth,
2225                                            body, &socket_transport->encoded_outgoing))
2226                 {
2227                                         _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
2228                                         oom = TRUE;
2229                                         goto out;
2230                 }
2231             }
2232
2233                         total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
2234                         if(total_bytes_to_write > socket_transport->max_bytes_written_per_iteration)
2235                                 return -E2BIG;
2236
2237                         bytes_written = kdbus_write_msg(socket_transport, message, pDestination, TRUE);
2238         }
2239                 else
2240                 {
2241                         if(total_bytes_to_write > socket_transport->max_bytes_written_per_iteration)
2242                                 return -E2BIG;
2243
2244                         bytes_written = kdbus_write_msg(socket_transport, message, pDestination, FALSE);
2245                 }
2246
2247 written:
2248                 if (bytes_written < 0)
2249                 {
2250                         /* EINTR already handled for us */
2251
2252           /* For some discussion of why we also ignore EPIPE here, see
2253            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
2254            */
2255
2256                         if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
2257                                 goto out;
2258                         else
2259                         {
2260                                 _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
2261                                 do_io_error (transport);
2262                                 goto out;
2263                         }
2264                 }
2265                 else
2266                 {
2267                         _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
2268                          total_bytes_to_write);
2269
2270                         socket_transport->message_bytes_written += bytes_written;
2271
2272                         _dbus_assert (socket_transport->message_bytes_written <=
2273                         total_bytes_to_write);
2274
2275                           if (socket_transport->message_bytes_written == total_bytes_to_write)
2276                           {
2277                                   socket_transport->message_bytes_written = 0;
2278                                   _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
2279                                   _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
2280
2281                                   _dbus_connection_message_sent_unlocked (transport->connection,
2282                                                                                                                   message);
2283                           }
2284                 }
2285     }
2286
2287         out:
2288         if (oom)
2289                 return FALSE;
2290         return TRUE;
2291 }
2292
2293 /* returns false on out-of-memory */
2294 static dbus_bool_t
2295 do_reading (DBusTransport *transport)
2296 {
2297   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2298   DBusString *buffer;
2299   int bytes_read;
2300   dbus_bool_t oom = FALSE;
2301   int *fds, n_fds;
2302
2303   _dbus_verbose ("fd = %d\n",socket_transport->fd);
2304
2305 #ifdef DBUS_AUTHENTICATION
2306   /* No messages without authentication! */
2307   if (!_dbus_transport_try_to_authenticate (transport))
2308     return TRUE;
2309 #endif
2310
2311  again:
2312
2313   /* See if we've exceeded max messages and need to disable reading */
2314   check_read_watch (transport);
2315
2316   _dbus_assert (socket_transport->read_watch != NULL ||
2317                 transport->disconnected);
2318
2319   if (transport->disconnected)
2320     goto out;
2321
2322   if (!dbus_watch_get_enabled (socket_transport->read_watch))
2323     return TRUE;
2324
2325   if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
2326   {
2327       _dbus_verbose ("Out of memory reading file descriptors\n");
2328       oom = TRUE;
2329       goto out;
2330   }
2331   _dbus_message_loader_get_buffer (transport->loader, &buffer);
2332
2333   if (_dbus_auth_needs_decoding (transport->auth))
2334   {
2335           bytes_read = kdbus_read_message(socket_transport,  &socket_transport->encoded_incoming, fds, &n_fds);
2336
2337       _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) == bytes_read);
2338
2339       if (bytes_read > 0)
2340       {
2341           if (!_dbus_auth_decode_data (transport->auth,
2342                                        &socket_transport->encoded_incoming,
2343                                        buffer))
2344           {
2345               _dbus_verbose ("Out of memory decoding incoming data\n");
2346               _dbus_message_loader_return_buffer (transport->loader,
2347                                               buffer,
2348                                               _dbus_string_get_length (buffer));
2349               oom = TRUE;
2350               goto out;
2351           }
2352
2353           _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
2354           _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
2355       }
2356   }
2357   else
2358           bytes_read = kdbus_read_message(socket_transport, buffer, fds, &n_fds);
2359
2360   if (bytes_read >= 0 && n_fds > 0)
2361     _dbus_verbose("Read %i unix fds\n", n_fds);
2362
2363   _dbus_message_loader_return_buffer (transport->loader,
2364                                       buffer,
2365                                       bytes_read < 0 ? 0 : bytes_read);
2366   _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
2367
2368   if (bytes_read < 0)
2369     {
2370       /* EINTR already handled for us */
2371
2372       if (_dbus_get_is_errno_enomem ())
2373         {
2374           _dbus_verbose ("Out of memory in read()/do_reading()\n");
2375           oom = TRUE;
2376           goto out;
2377         }
2378       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
2379         goto out;
2380       else
2381         {
2382           _dbus_verbose ("Error reading from remote app: %s\n",
2383                          _dbus_strerror_from_errno ());
2384           do_io_error (transport);
2385           goto out;
2386         }
2387     }
2388   else if (bytes_read == 0)
2389     {
2390       _dbus_verbose ("Disconnected from remote app\n");
2391       do_io_error (transport);
2392       goto out;
2393     }
2394   else
2395     {
2396       _dbus_verbose (" read %d bytes\n", bytes_read);
2397
2398       if (!_dbus_transport_queue_messages (transport))
2399         {
2400           oom = TRUE;
2401           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
2402           goto out;
2403         }
2404
2405       /* Try reading more data until we get EAGAIN and return, or
2406        * exceed max bytes per iteration.  If in blocking mode of
2407        * course we'll block instead of returning.
2408        */
2409       goto again;
2410     }
2411
2412  out:
2413   if (oom)
2414     return FALSE;
2415   return TRUE;
2416 }
2417
2418 static dbus_bool_t
2419 unix_error_with_read_to_come (DBusTransport *itransport,
2420                               DBusWatch     *watch,
2421                               unsigned int   flags)
2422 {
2423    DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
2424
2425    if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
2426       return FALSE;
2427
2428   /* If we have a read watch enabled ...
2429      we -might have data incoming ... => handle the HANGUP there */
2430    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
2431       return FALSE;
2432
2433    return TRUE;
2434 }
2435
2436 static dbus_bool_t
2437 socket_handle_watch (DBusTransport *transport,
2438                    DBusWatch     *watch,
2439                    unsigned int   flags)
2440 {
2441   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2442
2443   _dbus_assert (watch == socket_transport->read_watch ||
2444                 watch == socket_transport->write_watch);
2445   _dbus_assert (watch != NULL);
2446
2447   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
2448    * still be in the buffer and do_reading may need several iteration to read
2449    * it all (because of its max_bytes_read_per_iteration limit).
2450    */
2451   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
2452     {
2453       _dbus_verbose ("Hang up or error on watch\n");
2454       _dbus_transport_disconnect (transport);
2455       return TRUE;
2456     }
2457
2458   if (watch == socket_transport->read_watch &&
2459       (flags & DBUS_WATCH_READABLE))
2460     {
2461 #ifdef DBUS_AUTHENTICATION
2462       dbus_bool_t auth_finished;
2463 #endif
2464 #if 1
2465       _dbus_verbose ("handling read watch %p flags = %x\n",
2466                      watch, flags);
2467 #endif
2468 #ifdef DBUS_AUTHENTICATION
2469       if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
2470         return FALSE;
2471
2472       /* We don't want to do a read immediately following
2473        * a successful authentication.  This is so we
2474        * have a chance to propagate the authentication
2475        * state further up.  Specifically, we need to
2476        * process any pending data from the auth object.
2477        */
2478       if (!auth_finished)
2479         {
2480 #endif
2481           if (!do_reading (transport))
2482             {
2483               _dbus_verbose ("no memory to read\n");
2484               return FALSE;
2485             }
2486 #ifdef DBUS_AUTHENTICATION
2487         }
2488       else
2489         {
2490           _dbus_verbose ("Not reading anything since we just completed the authentication\n");
2491         }
2492 #endif
2493     }
2494   else if (watch == socket_transport->write_watch &&
2495            (flags & DBUS_WATCH_WRITABLE))
2496     {
2497 #if 1
2498       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
2499                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
2500 #endif
2501 #ifdef DBUS_AUTHENTICATION
2502       if (!do_authentication (transport, FALSE, TRUE, NULL))
2503         return FALSE;
2504 #endif
2505       if (!do_writing (transport))
2506         {
2507           _dbus_verbose ("no memory to write\n");
2508           return FALSE;
2509         }
2510
2511       /* See if we still need the write watch */
2512       check_write_watch (transport);
2513     }
2514 #ifdef DBUS_ENABLE_VERBOSE_MODE
2515   else
2516     {
2517       if (watch == socket_transport->read_watch)
2518         _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
2519                        flags);
2520       else if (watch == socket_transport->write_watch)
2521         _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
2522                        flags);
2523       else
2524         _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
2525                        watch, dbus_watch_get_socket (watch));
2526     }
2527 #endif /* DBUS_ENABLE_VERBOSE_MODE */
2528
2529   return TRUE;
2530 }
2531
2532 static void
2533 socket_disconnect (DBusTransport *transport)
2534 {
2535   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2536
2537   _dbus_verbose ("\n");
2538
2539   free_watches (transport);
2540
2541   _dbus_close_socket (socket_transport->fd, NULL);
2542   socket_transport->fd = -1;
2543 }
2544
2545 static dbus_bool_t
2546 kdbus_connection_set (DBusTransport *transport)
2547 {
2548   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2549
2550   dbus_connection_set_is_authenticated(transport->connection); //now we don't have authentication in kdbus
2551
2552   _dbus_watch_set_handler (socket_transport->write_watch,
2553                            _dbus_connection_handle_watch,
2554                            transport->connection, NULL);
2555
2556   _dbus_watch_set_handler (socket_transport->read_watch,
2557                            _dbus_connection_handle_watch,
2558                            transport->connection, NULL);
2559
2560   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2561                                             socket_transport->write_watch))
2562     return FALSE;
2563
2564   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2565                                             socket_transport->read_watch))
2566     {
2567       _dbus_connection_remove_watch_unlocked (transport->connection,
2568                                               socket_transport->write_watch);
2569       return FALSE;
2570     }
2571
2572   check_read_watch (transport);
2573   check_write_watch (transport);
2574
2575   return TRUE;
2576 }
2577
2578 /**  original dbus copy-pasted
2579  * @todo We need to have a way to wake up the select sleep if
2580  * a new iteration request comes in with a flag (read/write) that
2581  * we're not currently serving. Otherwise a call that just reads
2582  * could block a write call forever (if there are no incoming
2583  * messages).
2584  */
2585 static  void
2586 kdbus_do_iteration (DBusTransport *transport,
2587                    unsigned int   flags,
2588                    int            timeout_milliseconds)
2589 {
2590         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2591         DBusPollFD poll_fd;
2592         int poll_res;
2593         int poll_timeout;
2594
2595         _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
2596                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
2597                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
2598                  timeout_milliseconds,
2599                  socket_transport->read_watch,
2600                  socket_transport->write_watch,
2601                  socket_transport->fd);
2602
2603   /* the passed in DO_READING/DO_WRITING flags indicate whether to
2604    * read/write messages, but regardless of those we may need to block
2605    * for reading/writing to do auth.  But if we do reading for auth,
2606    * we don't want to read any messages yet if not given DO_READING.
2607    */
2608
2609    poll_fd.fd = socket_transport->fd;
2610    poll_fd.events = 0;
2611
2612    if (_dbus_transport_try_to_authenticate (transport))
2613    {
2614       /* This is kind of a hack; if we have stuff to write, then try
2615        * to avoid the poll. This is probably about a 5% speedup on an
2616        * echo client/server.
2617        *
2618        * If both reading and writing were requested, we want to avoid this
2619        * since it could have funky effects:
2620        *   - both ends spinning waiting for the other one to read
2621        *     data so they can finish writing
2622        *   - prioritizing all writing ahead of reading
2623        */
2624       if ((flags & DBUS_ITERATION_DO_WRITING) &&
2625           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
2626           !transport->disconnected &&
2627           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
2628       {
2629          do_writing (transport);
2630
2631          if (transport->disconnected ||
2632               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
2633             goto out;
2634       }
2635
2636       /* If we get here, we decided to do the poll() after all */
2637       _dbus_assert (socket_transport->read_watch);
2638       if (flags & DBUS_ITERATION_DO_READING)
2639              poll_fd.events |= _DBUS_POLLIN;
2640
2641       _dbus_assert (socket_transport->write_watch);
2642       if (flags & DBUS_ITERATION_DO_WRITING)
2643          poll_fd.events |= _DBUS_POLLOUT;
2644    }
2645    else
2646    {
2647       DBusAuthState auth_state;
2648
2649       auth_state = _dbus_auth_do_work (transport->auth);
2650
2651       if (transport->receive_credentials_pending || auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
2652              poll_fd.events |= _DBUS_POLLIN;
2653
2654       if (transport->send_credentials_pending || auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
2655              poll_fd.events |= _DBUS_POLLOUT;
2656    }
2657
2658    if (poll_fd.events)
2659    {
2660       if (flags & DBUS_ITERATION_BLOCK)
2661              poll_timeout = timeout_milliseconds;
2662       else
2663              poll_timeout = 0;
2664
2665       /* For blocking selects we drop the connection lock here
2666        * to avoid blocking out connection access during a potentially
2667        * indefinite blocking call. The io path is still protected
2668        * by the io_path_cond condvar, so we won't reenter this.
2669        */
2670       if (flags & DBUS_ITERATION_BLOCK)
2671       {
2672          _dbus_verbose ("unlock pre poll\n");
2673          _dbus_connection_unlock (transport->connection);
2674       }
2675
2676     again:
2677       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
2678
2679       if (poll_res < 0 && _dbus_get_is_errno_eintr ())
2680       {
2681          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2682          goto again;
2683       }
2684
2685       if (flags & DBUS_ITERATION_BLOCK)
2686       {
2687          _dbus_verbose ("lock post poll\n");
2688          _dbus_connection_lock (transport->connection);
2689       }
2690
2691       if (poll_res >= 0)
2692       {
2693          if (poll_res == 0)
2694             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
2695                                   * valgrind flags it as an error. though it probably
2696                                   * is guaranteed on linux at least.
2697                                   */
2698
2699          if (poll_fd.revents & _DBUS_POLLERR)
2700             do_io_error (transport);
2701          else
2702          {
2703             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
2704             dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
2705 #ifdef DBUS_AUTHENTICATION
2706               dbus_bool_t authentication_completed;
2707 #endif
2708
2709             _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
2710                              need_read, need_write);
2711 #ifdef DBUS_AUTHENTICATION
2712               do_authentication (transport, need_read, need_write,
2713                                  &authentication_completed);
2714
2715               /* See comment in socket_handle_watch. */
2716               if (authentication_completed)
2717                 goto out;
2718 #endif
2719             if (need_read && (flags & DBUS_ITERATION_DO_READING))
2720                do_reading (transport);
2721             if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
2722                do_writing (transport);
2723          }
2724       }
2725       else
2726          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2727    }
2728
2729  out:
2730   /* We need to install the write watch only if we did not
2731    * successfully write everything. Note we need to be careful that we
2732    * don't call check_write_watch *before* do_writing, since it's
2733    * inefficient to add the write watch, and we can avoid it most of
2734    * the time since we can write immediately.
2735    *
2736    * However, we MUST always call check_write_watch(); DBusConnection code
2737    * relies on the fact that running an iteration will notice that
2738    * messages are pending.
2739    */
2740    check_write_watch (transport);
2741
2742    _dbus_verbose (" ... leaving do_iteration()\n");
2743 }
2744
2745 static void
2746 socket_live_messages_changed (DBusTransport *transport)
2747 {
2748   /* See if we should look for incoming messages again */
2749   check_read_watch (transport);
2750 }
2751
2752 static const DBusTransportVTable kdbus_vtable = {
2753   socket_finalize,
2754   socket_handle_watch,
2755   socket_disconnect,
2756   kdbus_connection_set,
2757   kdbus_do_iteration,
2758   socket_live_messages_changed,
2759   socket_get_socket_fd
2760 };
2761
2762 /**
2763  * Creates a new transport for the given kdbus file descriptor.  The file
2764  * descriptor must be nonblocking.
2765  *
2766  * @param fd the file descriptor.
2767  * @param address the transport's address
2768  * @returns the new transport, or #NULL if no memory.
2769  */
2770 static DBusTransport*
2771 _dbus_transport_new_for_socket_kdbus (int       fd,
2772                                           const DBusString *address)
2773 {
2774         DBusTransportSocket *socket_transport;
2775
2776   socket_transport = dbus_new0 (DBusTransportSocket, 1);
2777   if (socket_transport == NULL)
2778     return NULL;
2779
2780   if (!_dbus_string_init (&socket_transport->encoded_outgoing))
2781     goto failed_0;
2782
2783   if (!_dbus_string_init (&socket_transport->encoded_incoming))
2784     goto failed_1;
2785
2786   socket_transport->write_watch = _dbus_watch_new (fd,
2787                                                  DBUS_WATCH_WRITABLE,
2788                                                  FALSE,
2789                                                  NULL, NULL, NULL);
2790   if (socket_transport->write_watch == NULL)
2791     goto failed_2;
2792
2793   socket_transport->read_watch = _dbus_watch_new (fd,
2794                                                 DBUS_WATCH_READABLE,
2795                                                 FALSE,
2796                                                 NULL, NULL, NULL);
2797   if (socket_transport->read_watch == NULL)
2798     goto failed_3;
2799
2800   if (!_dbus_transport_init_base (&socket_transport->base,
2801                                   &kdbus_vtable,
2802                                   NULL, address))
2803     goto failed_4;
2804
2805 #ifdef DBUS_AUTHENTICATION
2806 #ifdef HAVE_UNIX_FD_PASSING
2807   _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
2808 #endif
2809 #endif
2810
2811   socket_transport->fd = fd;
2812   socket_transport->message_bytes_written = 0;
2813
2814   /* These values should probably be tunable or something. */
2815   socket_transport->max_bytes_read_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2816   socket_transport->max_bytes_written_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2817
2818   socket_transport->kdbus_mmap_ptr = NULL;
2819   socket_transport->memfd = -1;
2820   
2821   return (DBusTransport*) socket_transport;
2822
2823  failed_4:
2824   _dbus_watch_invalidate (socket_transport->read_watch);
2825   _dbus_watch_unref (socket_transport->read_watch);
2826  failed_3:
2827   _dbus_watch_invalidate (socket_transport->write_watch);
2828   _dbus_watch_unref (socket_transport->write_watch);
2829  failed_2:
2830   _dbus_string_free (&socket_transport->encoded_incoming);
2831  failed_1:
2832   _dbus_string_free (&socket_transport->encoded_outgoing);
2833  failed_0:
2834   dbus_free (socket_transport);
2835   return NULL;
2836 }
2837
2838
2839 /**
2840  * Opens a connection to the kdbus bus
2841  *
2842  * This will set FD_CLOEXEC for the socket returned.
2843  *
2844  * @param path the path to UNIX domain socket
2845  * @param error return location for error code
2846  * @returns connection file descriptor or -1 on error
2847  */
2848 static int _dbus_connect_kdbus (const char *path, DBusError *error)
2849 {
2850         int fd;
2851
2852         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2853         _dbus_verbose ("connecting to kdbus bus %s\n", path);
2854
2855         fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK);
2856         if (fd < 0)
2857                 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
2858
2859         return fd;
2860 }
2861
2862 /**
2863  * Creates a new transport for kdbus.
2864  * This creates a client-side of a transport.
2865  *
2866  * @param path the path to the bus.
2867  * @param error address where an error can be returned.
2868  * @returns a new transport, or #NULL on failure.
2869  */
2870 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
2871 {
2872         int fd;
2873         DBusTransport *transport;
2874         DBusString address;
2875
2876         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2877
2878         if (!_dbus_string_init (&address))
2879     {
2880                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2881                 return NULL;
2882     }
2883
2884         fd = -1;
2885
2886         if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
2887     {
2888                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2889                 goto failed_0;
2890     }
2891
2892         fd = _dbus_connect_kdbus (path, error);
2893         if (fd < 0)
2894     {
2895                 _DBUS_ASSERT_ERROR_IS_SET (error);
2896                 goto failed_0;
2897     }
2898
2899         _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
2900
2901         transport = _dbus_transport_new_for_socket_kdbus (fd, &address);
2902         if (transport == NULL)
2903     {
2904                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2905                 goto failed_1;
2906     }
2907
2908         _dbus_string_free (&address);
2909
2910         return transport;
2911
2912         failed_1:
2913                 _dbus_close_socket (fd, NULL);
2914         failed_0:
2915                 _dbus_string_free (&address);
2916         return NULL;
2917 }
2918
2919
2920 /**
2921  * Opens kdbus transport if method from address entry is kdbus
2922  *
2923  * @param entry the address entry to try opening
2924  * @param transport_p return location for the opened transport
2925  * @param error error to be set
2926  * @returns result of the attempt
2927  */
2928 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
2929                                                            DBusTransport    **transport_p,
2930                                                            DBusError         *error)
2931 {
2932         const char *method;
2933
2934         method = dbus_address_entry_get_method (entry);
2935         _dbus_assert (method != NULL);
2936
2937         if (strcmp (method, "kdbus") == 0)
2938     {
2939                 const char *path = dbus_address_entry_get_value (entry, "path");
2940
2941                 if (path == NULL)
2942         {
2943                         _dbus_set_bad_address (error, "kdbus", "path", NULL);
2944                         return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
2945         }
2946
2947         *transport_p = _dbus_transport_new_for_kdbus (path, error);
2948
2949         if (*transport_p == NULL)
2950         {
2951                 _DBUS_ASSERT_ERROR_IS_SET (error);
2952                 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
2953         }
2954         else
2955         {
2956                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2957                 return DBUS_TRANSPORT_OPEN_OK;
2958         }
2959     }
2960         else
2961     {
2962                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2963                 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
2964     }
2965 }