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