chiark / gitweb /
983e2f62cddce00a9ebd41bce7bc0fd0f79d1246
[elogind.git] / src / libelogind / sd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "memfd-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37 #include "bus-gvariant.h"
38 #include "bus-util.h"
39
40 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
41
42 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
43
44         if (p == NULL)
45                 return NULL;
46
47         if (old_base == new_base)
48                 return (void*) p;
49
50         if ((uint8_t*) p < (uint8_t*) old_base)
51                 return (void*) p;
52
53         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54                 return (void*) p;
55
56         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 }
58
59 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
60         assert(m);
61         assert(part);
62
63         if (part->memfd >= 0) {
64                 /* If we can reuse the memfd, try that. For that it
65                  * can't be sealed yet. */
66
67                 if (!part->sealed) {
68                         assert(part->memfd_offset == 0);
69                         assert(part->data == part->mmap_begin);
70                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
71                 } else {
72                         if (part->mapped > 0)
73                                 assert_se(munmap(part->mmap_begin, part->mapped) == 0);
74
75                         safe_close(part->memfd);
76                 }
77
78         } else if (part->munmap_this)
79                 munmap(part->mmap_begin, part->mapped);
80         else if (part->free_this)
81                 free(part->data);
82
83         if (part != &m->body)
84                 free(part);
85 }
86
87 static void message_reset_parts(sd_bus_message *m) {
88         struct bus_body_part *part;
89
90         assert(m);
91
92         part = &m->body;
93         while (m->n_body_parts > 0) {
94                 struct bus_body_part *next = part->next;
95                 message_free_part(m, part);
96                 part = next;
97                 m->n_body_parts--;
98         }
99
100         m->body_end = NULL;
101
102         m->cached_rindex_part = NULL;
103         m->cached_rindex_part_begin = 0;
104 }
105
106 static void message_reset_containers(sd_bus_message *m) {
107         unsigned i;
108
109         assert(m);
110
111         for (i = 0; i < m->n_containers; i++) {
112                 free(m->containers[i].signature);
113                 free(m->containers[i].offsets);
114         }
115
116         free(m->containers);
117         m->containers = NULL;
118
119         m->n_containers = m->containers_allocated = 0;
120         m->root_container.index = 0;
121 }
122
123 static void message_free(sd_bus_message *m) {
124         assert(m);
125
126         if (m->free_header)
127                 free(m->header);
128
129         message_reset_parts(m);
130
131         if (m->release_kdbus)
132                 bus_kernel_cmd_free(m->bus, (uint8_t *) m->kdbus - (uint8_t *) m->bus->kdbus_buffer);
133
134         if (m->free_kdbus)
135                 free(m->kdbus);
136
137         sd_bus_unref(m->bus);
138
139         if (m->free_fds) {
140                 close_many(m->fds, m->n_fds);
141                 free(m->fds);
142         }
143
144         if (m->iovec != m->iovec_fixed)
145                 free(m->iovec);
146
147         if (m->destination_ptr) {
148                 free(m->destination_ptr);
149                 m->destination_ptr = NULL;
150         }
151
152         message_reset_containers(m);
153         free(m->root_container.signature);
154         free(m->root_container.offsets);
155
156         free(m->root_container.peeked_signature);
157
158         bus_creds_done(&m->creds);
159         free(m);
160 }
161
162 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
163         void *op, *np;
164         size_t old_size, new_size, start;
165
166         assert(m);
167
168         if (m->poisoned)
169                 return NULL;
170
171         old_size = sizeof(struct bus_header) + m->fields_size;
172         start = ALIGN_TO(old_size, align);
173         new_size = start + sz;
174
175         if (new_size < start ||
176             new_size > (size_t) ((uint32_t) -1))
177                 goto poison;
178
179         if (old_size == new_size)
180                 return (uint8_t*) m->header + old_size;
181
182         if (m->free_header) {
183                 np = realloc(m->header, ALIGN8(new_size));
184                 if (!np)
185                         goto poison;
186         } else {
187                 /* Initially, the header is allocated as part of of
188                  * the sd_bus_message itself, let's replace it by
189                  * dynamic data */
190
191                 np = malloc(ALIGN8(new_size));
192                 if (!np)
193                         goto poison;
194
195                 memcpy(np, m->header, sizeof(struct bus_header));
196         }
197
198         /* Zero out padding */
199         if (start > old_size)
200                 memzero((uint8_t*) np + old_size, start - old_size);
201
202         op = m->header;
203         m->header = np;
204         m->fields_size = new_size - sizeof(struct bus_header);
205
206         /* Adjust quick access pointers */
207         m->path = adjust_pointer(m->path, op, old_size, m->header);
208         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
209         m->member = adjust_pointer(m->member, op, old_size, m->header);
210         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
211         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
212         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
213
214         m->free_header = true;
215
216         if (add_offset) {
217                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
218                         goto poison;
219
220                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
221         }
222
223         return (uint8_t*) np + start;
224
225 poison:
226         m->poisoned = true;
227         return NULL;
228 }
229
230 static int message_append_field_string(
231                 sd_bus_message *m,
232                 uint64_t h,
233                 char type,
234                 const char *s,
235                 const char **ret) {
236
237         size_t l;
238         uint8_t *p;
239
240         assert(m);
241
242         /* dbus1 only allows 8bit header field ids */
243         if (h > 0xFF)
244                 return -EINVAL;
245
246         /* dbus1 doesn't allow strings over 32bit, let's enforce this
247          * globally, to not risk convertability */
248         l = strlen(s);
249         if (l > (size_t) (uint32_t) -1)
250                 return -EINVAL;
251
252         /* Signature "(yv)" where the variant contains "s" */
253
254         if (BUS_MESSAGE_IS_GVARIANT(m)) {
255
256                 /* (field id 64bit, ((string + NUL) + NUL + signature string 's') */
257                 p = message_extend_fields(m, 8, 8 + l + 1 + 1 + 1, true);
258                 if (!p)
259                         return -ENOMEM;
260
261                 *((uint64_t*) p) = h;
262                 memcpy(p+8, s, l);
263                 p[8+l] = 0;
264                 p[8+l+1] = 0;
265                 p[8+l+2] = type;
266
267                 if (ret)
268                         *ret = (char*) p + 8;
269
270         } else {
271                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
272                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
273                 if (!p)
274                         return -ENOMEM;
275
276                 p[0] = (uint8_t) h;
277                 p[1] = 1;
278                 p[2] = type;
279                 p[3] = 0;
280
281                 ((uint32_t*) p)[1] = l;
282                 memcpy(p + 8, s, l + 1);
283
284                 if (ret)
285                         *ret = (char*) p + 8;
286         }
287
288         return 0;
289 }
290
291 static int message_append_field_signature(
292                 sd_bus_message *m,
293                 uint64_t h,
294                 const char *s,
295                 const char **ret) {
296
297         size_t l;
298         uint8_t *p;
299
300         assert(m);
301
302         /* dbus1 only allows 8bit header field ids */
303         if (h > 0xFF)
304                 return -EINVAL;
305
306         /* dbus1 doesn't allow signatures over 8bit, let's enforce
307          * this globally, to not risk convertability */
308         l = strlen(s);
309         if (l > 255)
310                 return -EINVAL;
311
312         /* Signature "(yv)" where the variant contains "g" */
313
314         if (BUS_MESSAGE_IS_GVARIANT(m))
315                 /* For gvariant the serialization is the same as for normal strings */
316                 return message_append_field_string(m, h, 'g', s, ret);
317         else {
318                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
319                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
320                 if (!p)
321                         return -ENOMEM;
322
323                 p[0] = (uint8_t) h;
324                 p[1] = 1;
325                 p[2] = SD_BUS_TYPE_SIGNATURE;
326                 p[3] = 0;
327                 p[4] = l;
328                 memcpy(p + 5, s, l + 1);
329
330                 if (ret)
331                         *ret = (const char*) p + 5;
332         }
333
334         return 0;
335 }
336
337 static int message_append_field_uint32(sd_bus_message *m, uint64_t h, uint32_t x) {
338         uint8_t *p;
339
340         assert(m);
341
342         /* dbus1 only allows 8bit header field ids */
343         if (h > 0xFF)
344                 return -EINVAL;
345
346         if (BUS_MESSAGE_IS_GVARIANT(m)) {
347                 /* (field id 64bit + ((value + NUL + signature string 'u') */
348
349                 p = message_extend_fields(m, 8, 8 + 4 + 1 + 1, true);
350                 if (!p)
351                         return -ENOMEM;
352
353                 *((uint64_t*) p) = h;
354                 *((uint32_t*) (p + 8)) = x;
355                 p[12] = 0;
356                 p[13] = 'u';
357         } else {
358                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
359                 p = message_extend_fields(m, 8, 4 + 4, false);
360                 if (!p)
361                         return -ENOMEM;
362
363                 p[0] = (uint8_t) h;
364                 p[1] = 1;
365                 p[2] = 'u';
366                 p[3] = 0;
367
368                 ((uint32_t*) p)[1] = x;
369         }
370
371         return 0;
372 }
373
374 static int message_append_field_uint64(sd_bus_message *m, uint64_t h, uint64_t x) {
375         uint8_t *p;
376
377         assert(m);
378
379         /* dbus1 only allows 8bit header field ids */
380         if (h > 0xFF)
381                 return -EINVAL;
382
383         if (BUS_MESSAGE_IS_GVARIANT(m)) {
384                 /* (field id 64bit + ((value + NUL + signature string 't') */
385
386                 p = message_extend_fields(m, 8, 8 + 8 + 1 + 1, true);
387                 if (!p)
388                         return -ENOMEM;
389
390                 *((uint64_t*) p) = h;
391                 *((uint64_t*) (p + 8)) = x;
392                 p[16] = 0;
393                 p[17] = 't';
394         } else {
395                 /* (field id byte + (signature length + signature 't' + NUL) + 4 byte padding + value) */
396                 p = message_extend_fields(m, 8, 4 + 4 + 8, false);
397                 if (!p)
398                         return -ENOMEM;
399
400                 p[0] = (uint8_t) h;
401                 p[1] = 1;
402                 p[2] = 't';
403                 p[3] = 0;
404                 p[4] = 0;
405                 p[5] = 0;
406                 p[6] = 0;
407                 p[7] = 0;
408
409                 ((uint64_t*) p)[1] = x;
410         }
411
412         return 0;
413 }
414
415 static int message_append_reply_cookie(sd_bus_message *m, uint64_t cookie) {
416         assert(m);
417
418         if (BUS_MESSAGE_IS_GVARIANT(m))
419                 return message_append_field_uint64(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, cookie);
420         else {
421                 /* 64bit cookies are not supported on dbus1 */
422                 if (cookie > 0xffffffffUL)
423                         return -EOPNOTSUPP;
424
425                 return message_append_field_uint32(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) cookie);
426         }
427 }
428
429 int bus_message_from_header(
430                 sd_bus *bus,
431                 void *header,
432                 size_t header_accessible,
433                 void *footer,
434                 size_t footer_accessible,
435                 size_t message_size,
436                 int *fds,
437                 unsigned n_fds,
438                 const char *label,
439                 size_t extra,
440                 sd_bus_message **ret) {
441
442         _cleanup_free_ sd_bus_message *m = NULL;
443         struct bus_header *h;
444         size_t a, label_sz;
445
446         assert(bus);
447         assert(header || header_accessible <= 0);
448         assert(footer || footer_accessible <= 0);
449         assert(fds || n_fds <= 0);
450         assert(ret);
451
452         if (header_accessible < sizeof(struct bus_header))
453                 return -EBADMSG;
454
455         if (header_accessible > message_size)
456                 return -EBADMSG;
457         if (footer_accessible > message_size)
458                 return -EBADMSG;
459
460         h = header;
461         if (!IN_SET(h->version, 1, 2))
462                 return -EBADMSG;
463
464         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
465                 return -EBADMSG;
466
467         if (!IN_SET(h->endian, BUS_LITTLE_ENDIAN, BUS_BIG_ENDIAN))
468                 return -EBADMSG;
469
470         /* Note that we are happy with unknown flags in the flags header! */
471
472         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
473
474         if (label) {
475                 label_sz = strlen(label);
476                 a += label_sz + 1;
477         }
478
479         m = malloc0(a);
480         if (!m)
481                 return -ENOMEM;
482
483         m->n_ref = 1;
484         m->sealed = true;
485         m->header = header;
486         m->header_accessible = header_accessible;
487         m->footer = footer;
488         m->footer_accessible = footer_accessible;
489
490         if (BUS_MESSAGE_IS_GVARIANT(m)) {
491                 size_t ws;
492
493                 if (h->dbus2.cookie == 0)
494                         return -EBADMSG;
495
496                 /* dbus2 derives the sizes from the message size and
497                 the offset table at the end, since it is formatted as
498                 gvariant "yyyyuta{tv}v". Since the message itself is a
499                 structure with precisely to variable sized entries,
500                 there's only one offset in the table, which marks the
501                 end of the fields array. */
502
503                 ws = bus_gvariant_determine_word_size(message_size, 0);
504                 if (footer_accessible < ws)
505                         return -EBADMSG;
506
507                 m->fields_size = bus_gvariant_read_word_le((uint8_t*) footer + footer_accessible - ws, ws);
508                 if (ALIGN8(m->fields_size) > message_size - ws)
509                         return -EBADMSG;
510                 if (m->fields_size < sizeof(struct bus_header))
511                         return -EBADMSG;
512
513                 m->fields_size -= sizeof(struct bus_header);
514                 m->body_size = message_size - (sizeof(struct bus_header) + ALIGN8(m->fields_size));
515         } else {
516                 if (h->dbus1.serial == 0)
517                         return -EBADMSG;
518
519                 /* dbus1 has the sizes in the header */
520                 m->fields_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.fields_size);
521                 m->body_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.body_size);
522
523                 if (sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size != message_size)
524                         return -EBADMSG;
525         }
526
527         m->fds = fds;
528         m->n_fds = n_fds;
529
530         if (label) {
531                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
532                 memcpy(m->creds.label, label, label_sz + 1);
533
534                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
535         }
536
537         m->bus = sd_bus_ref(bus);
538         *ret = m;
539         m = NULL;
540
541         return 0;
542 }
543
544 int bus_message_from_malloc(
545                 sd_bus *bus,
546                 void *buffer,
547                 size_t length,
548                 int *fds,
549                 unsigned n_fds,
550                 const char *label,
551                 sd_bus_message **ret) {
552
553         sd_bus_message *m;
554         size_t sz;
555         int r;
556
557         r = bus_message_from_header(
558                         bus,
559                         buffer, length, /* in this case the initial bytes and the final bytes are the same */
560                         buffer, length,
561                         length,
562                         fds, n_fds,
563                         label,
564                         0, &m);
565         if (r < 0)
566                 return r;
567
568         sz = length - sizeof(struct bus_header) - ALIGN8(m->fields_size);
569         if (sz > 0) {
570                 m->n_body_parts = 1;
571                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(m->fields_size);
572                 m->body.size = sz;
573                 m->body.sealed = true;
574                 m->body.memfd = -1;
575         }
576
577         m->n_iovec = 1;
578         m->iovec = m->iovec_fixed;
579         m->iovec[0].iov_base = buffer;
580         m->iovec[0].iov_len = length;
581
582         r = bus_message_parse_fields(m);
583         if (r < 0)
584                 goto fail;
585
586         /* We take possession of the memory and fds now */
587         m->free_header = true;
588         m->free_fds = true;
589
590         *ret = m;
591         return 0;
592
593 fail:
594         message_free(m);
595         return r;
596 }
597
598 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
599         sd_bus_message *m;
600
601         assert(bus);
602
603         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
604         if (!m)
605                 return NULL;
606
607         m->n_ref = 1;
608         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
609         m->header->endian = BUS_NATIVE_ENDIAN;
610         m->header->type = type;
611         m->header->version = bus ? bus->message_version : 1;
612         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
613         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
614         m->bus = sd_bus_ref(bus);
615
616         if (bus->allow_interactive_authorization)
617                 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
618
619         return m;
620 }
621
622 _public_ int sd_bus_message_new_signal(
623                 sd_bus *bus,
624                 sd_bus_message **m,
625                 const char *path,
626                 const char *interface,
627                 const char *member) {
628
629         sd_bus_message *t;
630         int r;
631
632         assert_return(bus, -ENOTCONN);
633         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
634         assert_return(object_path_is_valid(path), -EINVAL);
635         assert_return(interface_name_is_valid(interface), -EINVAL);
636         assert_return(member_name_is_valid(member), -EINVAL);
637         assert_return(m, -EINVAL);
638
639         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
640         if (!t)
641                 return -ENOMEM;
642
643         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
644
645         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
646         if (r < 0)
647                 goto fail;
648         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
649         if (r < 0)
650                 goto fail;
651         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
652         if (r < 0)
653                 goto fail;
654
655         *m = t;
656         return 0;
657
658 fail:
659         sd_bus_message_unref(t);
660         return r;
661 }
662
663 _public_ int sd_bus_message_new_method_call(
664                 sd_bus *bus,
665                 sd_bus_message **m,
666                 const char *destination,
667                 const char *path,
668                 const char *interface,
669                 const char *member) {
670
671         sd_bus_message *t;
672         int r;
673
674         assert_return(bus, -ENOTCONN);
675         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
676         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
677         assert_return(object_path_is_valid(path), -EINVAL);
678         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
679         assert_return(member_name_is_valid(member), -EINVAL);
680         assert_return(m, -EINVAL);
681
682         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
683         if (!t)
684                 return -ENOMEM;
685
686         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
687         if (r < 0)
688                 goto fail;
689         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
690         if (r < 0)
691                 goto fail;
692
693         if (interface) {
694                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
695                 if (r < 0)
696                         goto fail;
697         }
698
699         if (destination) {
700                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
701                 if (r < 0)
702                         goto fail;
703         }
704
705         *m = t;
706         return 0;
707
708 fail:
709         message_free(t);
710         return r;
711 }
712
713 static int message_new_reply(
714                 sd_bus_message *call,
715                 uint8_t type,
716                 sd_bus_message **m) {
717
718         sd_bus_message *t;
719         int r;
720
721         assert_return(call, -EINVAL);
722         assert_return(call->sealed, -EPERM);
723         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
724         assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
725         assert_return(m, -EINVAL);
726
727         t = message_new(call->bus, type);
728         if (!t)
729                 return -ENOMEM;
730
731         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
732         t->reply_cookie = BUS_MESSAGE_COOKIE(call);
733         if (t->reply_cookie == 0)
734                 return -EOPNOTSUPP;
735
736         r = message_append_reply_cookie(t, t->reply_cookie);
737         if (r < 0)
738                 goto fail;
739
740         if (call->sender) {
741                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
742                 if (r < 0)
743                         goto fail;
744         }
745
746         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
747         t->enforced_reply_signature = call->enforced_reply_signature;
748
749         *m = t;
750         return 0;
751
752 fail:
753         message_free(t);
754         return r;
755 }
756
757 _public_ int sd_bus_message_new_method_return(
758                 sd_bus_message *call,
759                 sd_bus_message **m) {
760
761         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
762 }
763
764 _public_ int sd_bus_message_new_method_error(
765                 sd_bus_message *call,
766                 sd_bus_message **m,
767                 const sd_bus_error *e) {
768
769         sd_bus_message *t;
770         int r;
771
772         assert_return(sd_bus_error_is_set(e), -EINVAL);
773         assert_return(m, -EINVAL);
774
775         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
776         if (r < 0)
777                 return r;
778
779         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
780         if (r < 0)
781                 goto fail;
782
783         if (e->message) {
784                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
785                 if (r < 0)
786                         goto fail;
787         }
788
789         t->error._need_free = -1;
790
791         *m = t;
792         return 0;
793
794 fail:
795         message_free(t);
796         return r;
797 }
798
799 _public_ int sd_bus_message_new_method_errorf(
800                 sd_bus_message *call,
801                 sd_bus_message **m,
802                 const char *name,
803                 const char *format,
804                 ...) {
805
806         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
807         va_list ap;
808
809         assert_return(name, -EINVAL);
810         assert_return(m, -EINVAL);
811
812         va_start(ap, format);
813         bus_error_setfv(&error, name, format, ap);
814         va_end(ap);
815
816         return sd_bus_message_new_method_error(call, m, &error);
817 }
818
819 _public_ int sd_bus_message_new_method_errno(
820                 sd_bus_message *call,
821                 sd_bus_message **m,
822                 int error,
823                 const sd_bus_error *p) {
824
825         _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
826
827         if (sd_bus_error_is_set(p))
828                 return sd_bus_message_new_method_error(call, m, p);
829
830         sd_bus_error_set_errno(&berror, error);
831
832         return sd_bus_message_new_method_error(call, m, &berror);
833 }
834
835 _public_ int sd_bus_message_new_method_errnof(
836                 sd_bus_message *call,
837                 sd_bus_message **m,
838                 int error,
839                 const char *format,
840                 ...) {
841
842         _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
843         va_list ap;
844
845         va_start(ap, format);
846         sd_bus_error_set_errnofv(&berror, error, format, ap);
847         va_end(ap);
848
849         return sd_bus_message_new_method_error(call, m, &berror);
850 }
851
852 void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) {
853         assert(bus);
854         assert(m);
855
856         m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus.Local";
857         m->creds.well_known_names_local = true;
858         m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
859 }
860
861 void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m) {
862         assert(bus);
863         assert(m);
864
865         m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
866         m->creds.well_known_names_driver = true;
867         m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
868 }
869
870 int bus_message_new_synthetic_error(
871                 sd_bus *bus,
872                 uint64_t cookie,
873                 const sd_bus_error *e,
874                 sd_bus_message **m) {
875
876         sd_bus_message *t;
877         int r;
878
879         assert(bus);
880         assert(sd_bus_error_is_set(e));
881         assert(m);
882
883         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
884         if (!t)
885                 return -ENOMEM;
886
887         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
888         t->reply_cookie = cookie;
889
890         r = message_append_reply_cookie(t, t->reply_cookie);
891         if (r < 0)
892                 goto fail;
893
894         if (bus && bus->unique_name) {
895                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
896                 if (r < 0)
897                         goto fail;
898         }
899
900         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
901         if (r < 0)
902                 goto fail;
903
904         if (e->message) {
905                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
906                 if (r < 0)
907                         goto fail;
908         }
909
910         t->error._need_free = -1;
911
912         bus_message_set_sender_driver(bus, t);
913
914         *m = t;
915         return 0;
916
917 fail:
918         message_free(t);
919         return r;
920 }
921
922 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
923         assert_return(m, NULL);
924
925         assert(m->n_ref > 0);
926         m->n_ref++;
927
928         return m;
929 }
930
931 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
932
933         if (!m)
934                 return NULL;
935
936         assert(m->n_ref > 0);
937         m->n_ref--;
938
939         if (m->n_ref > 0)
940                 return NULL;
941
942         message_free(m);
943         return NULL;
944 }
945
946 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
947         assert_return(m, -EINVAL);
948         assert_return(type, -EINVAL);
949
950         *type = m->header->type;
951         return 0;
952 }
953
954 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
955         uint64_t c;
956
957         assert_return(m, -EINVAL);
958         assert_return(cookie, -EINVAL);
959
960         c = BUS_MESSAGE_COOKIE(m);
961         if (c == 0)
962                 return -ENODATA;
963
964         *cookie = BUS_MESSAGE_COOKIE(m);
965         return 0;
966 }
967
968 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
969         assert_return(m, -EINVAL);
970         assert_return(cookie, -EINVAL);
971
972         if (m->reply_cookie == 0)
973                 return -ENODATA;
974
975         *cookie = m->reply_cookie;
976         return 0;
977 }
978
979 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
980         assert_return(m, -EINVAL);
981
982         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
983                 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
984 }
985
986 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
987         assert_return(m, -EINVAL);
988
989         return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
990 }
991
992 _public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
993         assert_return(m, -EINVAL);
994
995         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
996                 (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
997 }
998
999 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
1000         assert_return(m, NULL);
1001
1002         return m->path;
1003 }
1004
1005 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
1006         assert_return(m, NULL);
1007
1008         return m->interface;
1009 }
1010
1011 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
1012         assert_return(m, NULL);
1013
1014         return m->member;
1015 }
1016
1017 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
1018         assert_return(m, NULL);
1019
1020         return m->destination;
1021 }
1022
1023 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
1024         assert_return(m, NULL);
1025
1026         return m->sender;
1027 }
1028
1029 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
1030         assert_return(m, NULL);
1031         assert_return(sd_bus_error_is_set(&m->error), NULL);
1032
1033         return &m->error;
1034 }
1035
1036 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
1037         assert_return(m, -EINVAL);
1038         assert_return(usec, -EINVAL);
1039
1040         if (m->monotonic <= 0)
1041                 return -ENODATA;
1042
1043         *usec = m->monotonic;
1044         return 0;
1045 }
1046
1047 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
1048         assert_return(m, -EINVAL);
1049         assert_return(usec, -EINVAL);
1050
1051         if (m->realtime <= 0)
1052                 return -ENODATA;
1053
1054         *usec = m->realtime;
1055         return 0;
1056 }
1057
1058 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
1059         assert_return(m, -EINVAL);
1060         assert_return(seqnum, -EINVAL);
1061
1062         if (m->seqnum <= 0)
1063                 return -ENODATA;
1064
1065         *seqnum = m->seqnum;
1066         return 0;
1067 }
1068
1069 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
1070         assert_return(m, NULL);
1071
1072         if (m->creds.mask == 0)
1073                 return NULL;
1074
1075         return &m->creds;
1076 }
1077
1078 _public_ int sd_bus_message_is_signal(
1079                 sd_bus_message *m,
1080                 const char *interface,
1081                 const char *member) {
1082
1083         assert_return(m, -EINVAL);
1084
1085         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1086                 return 0;
1087
1088         if (interface && (!m->interface || !streq(m->interface, interface)))
1089                 return 0;
1090
1091         if (member &&  (!m->member || !streq(m->member, member)))
1092                 return 0;
1093
1094         return 1;
1095 }
1096
1097 _public_ int sd_bus_message_is_method_call(
1098                 sd_bus_message *m,
1099                 const char *interface,
1100                 const char *member) {
1101
1102         assert_return(m, -EINVAL);
1103
1104         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1105                 return 0;
1106
1107         if (interface && (!m->interface || !streq(m->interface, interface)))
1108                 return 0;
1109
1110         if (member &&  (!m->member || !streq(m->member, member)))
1111                 return 0;
1112
1113         return 1;
1114 }
1115
1116 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1117         assert_return(m, -EINVAL);
1118
1119         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1120                 return 0;
1121
1122         if (name && (!m->error.name || !streq(m->error.name, name)))
1123                 return 0;
1124
1125         return 1;
1126 }
1127
1128 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
1129         assert_return(m, -EINVAL);
1130         assert_return(!m->sealed, -EPERM);
1131         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1132
1133         if (b)
1134                 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
1135         else
1136                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1137
1138         return 0;
1139 }
1140
1141 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
1142         assert_return(m, -EINVAL);
1143         assert_return(!m->sealed, -EPERM);
1144
1145         if (b)
1146                 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
1147         else
1148                 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
1149
1150         return 0;
1151 }
1152
1153 _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
1154         assert_return(m, -EINVAL);
1155         assert_return(!m->sealed, -EPERM);
1156
1157         if (b)
1158                 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1159         else
1160                 m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1161
1162         return 0;
1163 }
1164
1165 static struct bus_container *message_get_container(sd_bus_message *m) {
1166         assert(m);
1167
1168         if (m->n_containers == 0)
1169                 return &m->root_container;
1170
1171         assert(m->containers);
1172         return m->containers + m->n_containers - 1;
1173 }
1174
1175 struct bus_body_part *message_append_part(sd_bus_message *m) {
1176         struct bus_body_part *part;
1177
1178         assert(m);
1179
1180         if (m->poisoned)
1181                 return NULL;
1182
1183         if (m->n_body_parts <= 0) {
1184                 part = &m->body;
1185                 zero(*part);
1186         } else {
1187                 assert(m->body_end);
1188
1189                 part = new0(struct bus_body_part, 1);
1190                 if (!part) {
1191                         m->poisoned = true;
1192                         return NULL;
1193                 }
1194
1195                 m->body_end->next = part;
1196         }
1197
1198         part->memfd = -1;
1199         m->body_end = part;
1200         m->n_body_parts ++;
1201
1202         return part;
1203 }
1204
1205 static void part_zero(struct bus_body_part *part, size_t sz) {
1206         assert(part);
1207         assert(sz > 0);
1208         assert(sz < 8);
1209
1210         /* All other fields can be left in their defaults */
1211         assert(!part->data);
1212         assert(part->memfd < 0);
1213
1214         part->size = sz;
1215         part->is_zero = true;
1216         part->sealed = true;
1217 }
1218
1219 static int part_make_space(
1220                 struct sd_bus_message *m,
1221                 struct bus_body_part *part,
1222                 size_t sz,
1223                 void **q) {
1224
1225         void *n;
1226         int r;
1227
1228         assert(m);
1229         assert(part);
1230         assert(!part->sealed);
1231
1232         if (m->poisoned)
1233                 return -ENOMEM;
1234
1235         if (!part->data && part->memfd < 0) {
1236                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1237                 part->mmap_begin = part->data;
1238         }
1239
1240         if (part->memfd >= 0) {
1241
1242                 if (part->allocated == 0 || sz > part->allocated) {
1243                         uint64_t new_allocated;
1244
1245                         new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1246                         r = memfd_set_size(part->memfd, new_allocated);
1247                         if (r < 0) {
1248                                 m->poisoned = true;
1249                                 return r;
1250                         }
1251
1252                         part->allocated = new_allocated;
1253                 }
1254
1255                 if (!part->data || sz > part->mapped) {
1256                         size_t psz;
1257
1258                         psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1259                         if (part->mapped <= 0)
1260                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1261                         else
1262                                 n = mremap(part->mmap_begin, part->mapped, psz, MREMAP_MAYMOVE);
1263
1264                         if (n == MAP_FAILED) {
1265                                 m->poisoned = true;
1266                                 return -errno;
1267                         }
1268
1269                         part->mmap_begin = part->data = n;
1270                         part->mapped = psz;
1271                         part->memfd_offset = 0;
1272                 }
1273
1274                 part->munmap_this = true;
1275         } else {
1276                 if (part->allocated == 0 || sz > part->allocated) {
1277                         size_t new_allocated;
1278
1279                         new_allocated = sz > 0 ? 2 * sz : 64;
1280                         n = realloc(part->data, new_allocated);
1281                         if (!n) {
1282                                 m->poisoned = true;
1283                                 return -ENOMEM;
1284                         }
1285
1286                         part->data = n;
1287                         part->allocated = new_allocated;
1288                         part->free_this = true;
1289                 }
1290         }
1291
1292         if (q)
1293                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1294
1295         part->size = sz;
1296         return 0;
1297 }
1298
1299 static int message_add_offset(sd_bus_message *m, size_t offset) {
1300         struct bus_container *c;
1301
1302         assert(m);
1303         assert(BUS_MESSAGE_IS_GVARIANT(m));
1304
1305         /* Add offset to current container, unless this is the first
1306          * item in it, which will have the 0 offset, which we can
1307          * ignore. */
1308         c = message_get_container(m);
1309
1310         if (!c->need_offsets)
1311                 return 0;
1312
1313         if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1314                 return -ENOMEM;
1315
1316         c->offsets[c->n_offsets++] = offset;
1317         return 0;
1318 }
1319
1320 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1321         struct bus_container *c;
1322
1323         assert(m);
1324
1325         if (expand <= 0)
1326                 return;
1327
1328         /* Update counters */
1329         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1330
1331                 if (c->array_size)
1332                         *c->array_size += expand;
1333         }
1334 }
1335
1336 static void *message_extend_body(
1337                 sd_bus_message *m,
1338                 size_t align,
1339                 size_t sz,
1340                 bool add_offset,
1341                 bool force_inline) {
1342
1343         size_t start_body, end_body, padding, added;
1344         void *p;
1345         int r;
1346
1347         assert(m);
1348         assert(align > 0);
1349         assert(!m->sealed);
1350
1351         if (m->poisoned)
1352                 return NULL;
1353
1354         start_body = ALIGN_TO((size_t) m->body_size, align);
1355         end_body = start_body + sz;
1356
1357         padding = start_body - m->body_size;
1358         added = padding + sz;
1359
1360         /* Check for 32bit overflows */
1361         if (end_body > (size_t) ((uint32_t) -1) ||
1362             end_body < start_body) {
1363                 m->poisoned = true;
1364                 return NULL;
1365         }
1366
1367         if (added > 0) {
1368                 struct bus_body_part *part = NULL;
1369                 bool add_new_part;
1370
1371                 add_new_part =
1372                         m->n_body_parts <= 0 ||
1373                         m->body_end->sealed ||
1374                         (padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size) ||
1375                         (force_inline && m->body_end->size > MEMFD_MIN_SIZE); /* if this must be an inlined extension, let's create a new part if the previous part is large enough to be inlined */
1376
1377                 if (add_new_part) {
1378                         if (padding > 0) {
1379                                 part = message_append_part(m);
1380                                 if (!part)
1381                                         return NULL;
1382
1383                                 part_zero(part, padding);
1384                         }
1385
1386                         part = message_append_part(m);
1387                         if (!part)
1388                                 return NULL;
1389
1390                         r = part_make_space(m, part, sz, &p);
1391                         if (r < 0)
1392                                 return NULL;
1393                 } else {
1394                         struct bus_container *c;
1395                         void *op;
1396                         size_t os, start_part, end_part;
1397
1398                         part = m->body_end;
1399                         op = part->data;
1400                         os = part->size;
1401
1402                         start_part = ALIGN_TO(part->size, align);
1403                         end_part = start_part + sz;
1404
1405                         r = part_make_space(m, part, end_part, &p);
1406                         if (r < 0)
1407                                 return NULL;
1408
1409                         if (padding > 0) {
1410                                 memzero(p, padding);
1411                                 p = (uint8_t*) p + padding;
1412                         }
1413
1414                         /* Readjust pointers */
1415                         for (c = m->containers; c < m->containers + m->n_containers; c++)
1416                                 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1417
1418                         m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1419                 }
1420         } else
1421                 /* Return something that is not NULL and is aligned */
1422                 p = (uint8_t *) NULL + align;
1423
1424         m->body_size = end_body;
1425         message_extend_containers(m, added);
1426
1427         if (add_offset) {
1428                 r = message_add_offset(m, end_body);
1429                 if (r < 0) {
1430                         m->poisoned = true;
1431                         return NULL;
1432                 }
1433         }
1434
1435         return p;
1436 }
1437
1438 static int message_push_fd(sd_bus_message *m, int fd) {
1439         int *f, copy;
1440
1441         assert(m);
1442
1443         if (fd < 0)
1444                 return -EINVAL;
1445
1446         if (!m->allow_fds)
1447                 return -EOPNOTSUPP;
1448
1449         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1450         if (copy < 0)
1451                 return -errno;
1452
1453         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1454         if (!f) {
1455                 m->poisoned = true;
1456                 safe_close(copy);
1457                 return -ENOMEM;
1458         }
1459
1460         m->fds = f;
1461         m->fds[m->n_fds] = copy;
1462         m->free_fds = true;
1463
1464         return copy;
1465 }
1466
1467 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1468         _cleanup_close_ int fd = -1;
1469         struct bus_container *c;
1470         ssize_t align, sz;
1471         void *a;
1472
1473         assert_return(m, -EINVAL);
1474         assert_return(!m->sealed, -EPERM);
1475         assert_return(bus_type_is_basic(type), -EINVAL);
1476         assert_return(!m->poisoned, -ESTALE);
1477
1478         c = message_get_container(m);
1479
1480         if (c->signature && c->signature[c->index]) {
1481                 /* Container signature is already set */
1482
1483                 if (c->signature[c->index] != type)
1484                         return -ENXIO;
1485         } else {
1486                 char *e;
1487
1488                 /* Maybe we can append to the signature? But only if this is the top-level container */
1489                 if (c->enclosing != 0)
1490                         return -ENXIO;
1491
1492                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1493                 if (!e) {
1494                         m->poisoned = true;
1495                         return -ENOMEM;
1496                 }
1497         }
1498
1499         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1500                 uint8_t u8;
1501                 uint32_t u32;
1502
1503                 switch (type) {
1504
1505                 case SD_BUS_TYPE_SIGNATURE:
1506                 case SD_BUS_TYPE_STRING:
1507                         p = strempty(p);
1508
1509                         /* Fall through... */
1510                 case SD_BUS_TYPE_OBJECT_PATH:
1511                         if (!p)
1512                                 return -EINVAL;
1513
1514                         align = 1;
1515                         sz = strlen(p) + 1;
1516                         break;
1517
1518                 case SD_BUS_TYPE_BOOLEAN:
1519
1520                         u8 = p && *(int*) p;
1521                         p = &u8;
1522
1523                         align = sz = 1;
1524                         break;
1525
1526                 case SD_BUS_TYPE_UNIX_FD:
1527
1528                         if (!p)
1529                                 return -EINVAL;
1530
1531                         fd = message_push_fd(m, *(int*) p);
1532                         if (fd < 0)
1533                                 return fd;
1534
1535                         u32 = m->n_fds;
1536                         p = &u32;
1537
1538                         align = sz = 4;
1539                         break;
1540
1541                 default:
1542                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1543                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1544                         break;
1545                 }
1546
1547                 assert(align > 0);
1548                 assert(sz > 0);
1549
1550                 a = message_extend_body(m, align, sz, true, false);
1551                 if (!a)
1552                         return -ENOMEM;
1553
1554                 memcpy(a, p, sz);
1555
1556                 if (stored)
1557                         *stored = (const uint8_t*) a;
1558
1559         } else {
1560                 uint32_t u32;
1561
1562                 switch (type) {
1563
1564                 case SD_BUS_TYPE_STRING:
1565                         /* To make things easy we'll serialize a NULL string
1566                          * into the empty string */
1567                         p = strempty(p);
1568
1569                         /* Fall through... */
1570                 case SD_BUS_TYPE_OBJECT_PATH:
1571
1572                         if (!p)
1573                                 return -EINVAL;
1574
1575                         align = 4;
1576                         sz = 4 + strlen(p) + 1;
1577                         break;
1578
1579                 case SD_BUS_TYPE_SIGNATURE:
1580
1581                         p = strempty(p);
1582
1583                         align = 1;
1584                         sz = 1 + strlen(p) + 1;
1585                         break;
1586
1587                 case SD_BUS_TYPE_BOOLEAN:
1588
1589                         u32 = p && *(int*) p;
1590                         p = &u32;
1591
1592                         align = sz = 4;
1593                         break;
1594
1595                 case SD_BUS_TYPE_UNIX_FD:
1596
1597                         if (!p)
1598                                 return -EINVAL;
1599
1600                         fd = message_push_fd(m, *(int*) p);
1601                         if (fd < 0)
1602                                 return fd;
1603
1604                         u32 = m->n_fds;
1605                         p = &u32;
1606
1607                         align = sz = 4;
1608                         break;
1609
1610                 default:
1611                         align = bus_type_get_alignment(type);
1612                         sz = bus_type_get_size(type);
1613                         break;
1614                 }
1615
1616                 assert(align > 0);
1617                 assert(sz > 0);
1618
1619                 a = message_extend_body(m, align, sz, false, false);
1620                 if (!a)
1621                         return -ENOMEM;
1622
1623                 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1624                         *(uint32_t*) a = sz - 5;
1625                         memcpy((uint8_t*) a + 4, p, sz - 4);
1626
1627                         if (stored)
1628                                 *stored = (const uint8_t*) a + 4;
1629
1630                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1631                         *(uint8_t*) a = sz - 2;
1632                         memcpy((uint8_t*) a + 1, p, sz - 1);
1633
1634                         if (stored)
1635                                 *stored = (const uint8_t*) a + 1;
1636                 } else {
1637                         memcpy(a, p, sz);
1638
1639                         if (stored)
1640                                 *stored = a;
1641                 }
1642         }
1643
1644         if (type == SD_BUS_TYPE_UNIX_FD)
1645                 m->n_fds ++;
1646
1647         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1648                 c->index++;
1649
1650         fd = -1;
1651         return 0;
1652 }
1653
1654 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1655         return message_append_basic(m, type, p, NULL);
1656 }
1657
1658 _public_ int sd_bus_message_append_string_space(
1659                 sd_bus_message *m,
1660                 size_t size,
1661                 char **s) {
1662
1663         struct bus_container *c;
1664         void *a;
1665
1666         assert_return(m, -EINVAL);
1667         assert_return(s, -EINVAL);
1668         assert_return(!m->sealed, -EPERM);
1669         assert_return(!m->poisoned, -ESTALE);
1670
1671         c = message_get_container(m);
1672
1673         if (c->signature && c->signature[c->index]) {
1674                 /* Container signature is already set */
1675
1676                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1677                         return -ENXIO;
1678         } else {
1679                 char *e;
1680
1681                 /* Maybe we can append to the signature? But only if this is the top-level container */
1682                 if (c->enclosing != 0)
1683                         return -ENXIO;
1684
1685                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1686                 if (!e) {
1687                         m->poisoned = true;
1688                         return -ENOMEM;
1689                 }
1690         }
1691
1692         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1693                 a = message_extend_body(m, 1, size + 1, true, false);
1694                 if (!a)
1695                         return -ENOMEM;
1696
1697                 *s = a;
1698         } else {
1699                 a = message_extend_body(m, 4, 4 + size + 1, false, false);
1700                 if (!a)
1701                         return -ENOMEM;
1702
1703                 *(uint32_t*) a = size;
1704                 *s = (char*) a + 4;
1705         }
1706
1707         (*s)[size] = 0;
1708
1709         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1710                 c->index++;
1711
1712         return 0;
1713 }
1714
1715 _public_ int sd_bus_message_append_string_iovec(
1716                 sd_bus_message *m,
1717                 const struct iovec *iov,
1718                 unsigned n) {
1719
1720         size_t size;
1721         unsigned i;
1722         char *p;
1723         int r;
1724
1725         assert_return(m, -EINVAL);
1726         assert_return(!m->sealed, -EPERM);
1727         assert_return(iov || n == 0, -EINVAL);
1728         assert_return(!m->poisoned, -ESTALE);
1729
1730         size = IOVEC_TOTAL_SIZE(iov, n);
1731
1732         r = sd_bus_message_append_string_space(m, size, &p);
1733         if (r < 0)
1734                 return r;
1735
1736         for (i = 0; i < n; i++) {
1737
1738                 if (iov[i].iov_base)
1739                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1740                 else
1741                         memset(p, ' ', iov[i].iov_len);
1742
1743                 p += iov[i].iov_len;
1744         }
1745
1746         return 0;
1747 }
1748
1749 static int bus_message_open_array(
1750                 sd_bus_message *m,
1751                 struct bus_container *c,
1752                 const char *contents,
1753                 uint32_t **array_size,
1754                 size_t *begin,
1755                 bool *need_offsets) {
1756
1757         unsigned nindex;
1758         int alignment, r;
1759
1760         assert(m);
1761         assert(c);
1762         assert(contents);
1763         assert(array_size);
1764         assert(begin);
1765         assert(need_offsets);
1766
1767         if (!signature_is_single(contents, true))
1768                 return -EINVAL;
1769
1770         if (c->signature && c->signature[c->index]) {
1771
1772                 /* Verify the existing signature */
1773
1774                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1775                         return -ENXIO;
1776
1777                 if (!startswith(c->signature + c->index + 1, contents))
1778                         return -ENXIO;
1779
1780                 nindex = c->index + 1 + strlen(contents);
1781         } else {
1782                 char *e;
1783
1784                 if (c->enclosing != 0)
1785                         return -ENXIO;
1786
1787                 /* Extend the existing signature */
1788
1789                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1790                 if (!e) {
1791                         m->poisoned = true;
1792                         return -ENOMEM;
1793                 }
1794
1795                 nindex = e - c->signature;
1796         }
1797
1798         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1799                 alignment = bus_gvariant_get_alignment(contents);
1800                 if (alignment < 0)
1801                         return alignment;
1802
1803                 /* Add alignment padding and add to offset list */
1804                 if (!message_extend_body(m, alignment, 0, false, false))
1805                         return -ENOMEM;
1806
1807                 r = bus_gvariant_is_fixed_size(contents);
1808                 if (r < 0)
1809                         return r;
1810
1811                 *begin = m->body_size;
1812                 *need_offsets = r == 0;
1813         } else {
1814                 void *a, *op;
1815                 size_t os;
1816                 struct bus_body_part *o;
1817
1818                 alignment = bus_type_get_alignment(contents[0]);
1819                 if (alignment < 0)
1820                         return alignment;
1821
1822                 a = message_extend_body(m, 4, 4, false, false);
1823                 if (!a)
1824                         return -ENOMEM;
1825
1826                 o = m->body_end;
1827                 op = m->body_end->data;
1828                 os = m->body_end->size;
1829
1830                 /* Add alignment between size and first element */
1831                 if (!message_extend_body(m, alignment, 0, false, false))
1832                         return -ENOMEM;
1833
1834                 /* location of array size might have changed so let's readjust a */
1835                 if (o == m->body_end)
1836                         a = adjust_pointer(a, op, os, m->body_end->data);
1837
1838                 *(uint32_t*) a = 0;
1839                 *array_size = a;
1840         }
1841
1842         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1843                 c->index = nindex;
1844
1845         return 0;
1846 }
1847
1848 static int bus_message_open_variant(
1849                 sd_bus_message *m,
1850                 struct bus_container *c,
1851                 const char *contents) {
1852
1853         assert(m);
1854         assert(c);
1855         assert(contents);
1856
1857         if (!signature_is_single(contents, false))
1858                 return -EINVAL;
1859
1860         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1861                 return -EINVAL;
1862
1863         if (c->signature && c->signature[c->index]) {
1864
1865                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1866                         return -ENXIO;
1867
1868         } else {
1869                 char *e;
1870
1871                 if (c->enclosing != 0)
1872                         return -ENXIO;
1873
1874                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1875                 if (!e) {
1876                         m->poisoned = true;
1877                         return -ENOMEM;
1878                 }
1879         }
1880
1881         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1882                 /* Variants are always aligned to 8 */
1883
1884                 if (!message_extend_body(m, 8, 0, false, false))
1885                         return -ENOMEM;
1886
1887         } else {
1888                 size_t l;
1889                 void *a;
1890
1891                 l = strlen(contents);
1892                 a = message_extend_body(m, 1, 1 + l + 1, false, false);
1893                 if (!a)
1894                         return -ENOMEM;
1895
1896                 *(uint8_t*) a = l;
1897                 memcpy((uint8_t*) a + 1, contents, l + 1);
1898         }
1899
1900         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1901                 c->index++;
1902
1903         return 0;
1904 }
1905
1906 static int bus_message_open_struct(
1907                 sd_bus_message *m,
1908                 struct bus_container *c,
1909                 const char *contents,
1910                 size_t *begin,
1911                 bool *need_offsets) {
1912
1913         size_t nindex;
1914         int r;
1915
1916         assert(m);
1917         assert(c);
1918         assert(contents);
1919         assert(begin);
1920         assert(need_offsets);
1921
1922         if (!signature_is_valid(contents, false))
1923                 return -EINVAL;
1924
1925         if (c->signature && c->signature[c->index]) {
1926                 size_t l;
1927
1928                 l = strlen(contents);
1929
1930                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1931                     !startswith(c->signature + c->index + 1, contents) ||
1932                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1933                         return -ENXIO;
1934
1935                 nindex = c->index + 1 + l + 1;
1936         } else {
1937                 char *e;
1938
1939                 if (c->enclosing != 0)
1940                         return -ENXIO;
1941
1942                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1943                 if (!e) {
1944                         m->poisoned = true;
1945                         return -ENOMEM;
1946                 }
1947
1948                 nindex = e - c->signature;
1949         }
1950
1951         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1952                 int alignment;
1953
1954                 alignment = bus_gvariant_get_alignment(contents);
1955                 if (alignment < 0)
1956                         return alignment;
1957
1958                 if (!message_extend_body(m, alignment, 0, false, false))
1959                         return -ENOMEM;
1960
1961                 r = bus_gvariant_is_fixed_size(contents);
1962                 if (r < 0)
1963                         return r;
1964
1965                 *begin = m->body_size;
1966                 *need_offsets = r == 0;
1967         } else {
1968                 /* Align contents to 8 byte boundary */
1969                 if (!message_extend_body(m, 8, 0, false, false))
1970                         return -ENOMEM;
1971         }
1972
1973         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1974                 c->index = nindex;
1975
1976         return 0;
1977 }
1978
1979 static int bus_message_open_dict_entry(
1980                 sd_bus_message *m,
1981                 struct bus_container *c,
1982                 const char *contents,
1983                 size_t *begin,
1984                 bool *need_offsets) {
1985
1986         int r;
1987
1988         assert(m);
1989         assert(c);
1990         assert(contents);
1991         assert(begin);
1992         assert(need_offsets);
1993
1994         if (!signature_is_pair(contents))
1995                 return -EINVAL;
1996
1997         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1998                 return -ENXIO;
1999
2000         if (c->signature && c->signature[c->index]) {
2001                 size_t l;
2002
2003                 l = strlen(contents);
2004
2005                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2006                     !startswith(c->signature + c->index + 1, contents) ||
2007                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2008                         return -ENXIO;
2009         } else
2010                 return -ENXIO;
2011
2012         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2013                 int alignment;
2014
2015                 alignment = bus_gvariant_get_alignment(contents);
2016                 if (alignment < 0)
2017                         return alignment;
2018
2019                 if (!message_extend_body(m, alignment, 0, false, false))
2020                         return -ENOMEM;
2021
2022                 r = bus_gvariant_is_fixed_size(contents);
2023                 if (r < 0)
2024                         return r;
2025
2026                 *begin = m->body_size;
2027                 *need_offsets = r == 0;
2028         } else {
2029                 /* Align contents to 8 byte boundary */
2030                 if (!message_extend_body(m, 8, 0, false, false))
2031                         return -ENOMEM;
2032         }
2033
2034         return 0;
2035 }
2036
2037 _public_ int sd_bus_message_open_container(
2038                 sd_bus_message *m,
2039                 char type,
2040                 const char *contents) {
2041
2042         struct bus_container *c, *w;
2043         uint32_t *array_size = NULL;
2044         char *signature;
2045         size_t before, begin = 0;
2046         bool need_offsets = false;
2047         int r;
2048
2049         assert_return(m, -EINVAL);
2050         assert_return(!m->sealed, -EPERM);
2051         assert_return(contents, -EINVAL);
2052         assert_return(!m->poisoned, -ESTALE);
2053
2054         /* Make sure we have space for one more container */
2055         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
2056                 m->poisoned = true;
2057                 return -ENOMEM;
2058         }
2059
2060         c = message_get_container(m);
2061
2062         signature = strdup(contents);
2063         if (!signature) {
2064                 m->poisoned = true;
2065                 return -ENOMEM;
2066         }
2067
2068         /* Save old index in the parent container, in case we have to
2069          * abort this container */
2070         c->saved_index = c->index;
2071         before = m->body_size;
2072
2073         if (type == SD_BUS_TYPE_ARRAY)
2074                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
2075         else if (type == SD_BUS_TYPE_VARIANT)
2076                 r = bus_message_open_variant(m, c, contents);
2077         else if (type == SD_BUS_TYPE_STRUCT)
2078                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
2079         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2080                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
2081         else
2082                 r = -EINVAL;
2083
2084         if (r < 0) {
2085                 free(signature);
2086                 return r;
2087         }
2088
2089         /* OK, let's fill it in */
2090         w = m->containers + m->n_containers++;
2091         w->enclosing = type;
2092         w->signature = signature;
2093         w->index = 0;
2094         w->array_size = array_size;
2095         w->before = before;
2096         w->begin = begin;
2097         w->n_offsets = w->offsets_allocated = 0;
2098         w->offsets = NULL;
2099         w->need_offsets = need_offsets;
2100
2101         return 0;
2102 }
2103
2104 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
2105
2106         assert(m);
2107         assert(c);
2108
2109         if (!BUS_MESSAGE_IS_GVARIANT(m))
2110                 return 0;
2111
2112         if (c->need_offsets) {
2113                 size_t payload, sz, i;
2114                 uint8_t *a;
2115
2116                 /* Variable-width arrays */
2117
2118                 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2119                 sz = bus_gvariant_determine_word_size(payload, c->n_offsets);
2120
2121                 a = message_extend_body(m, 1, sz * c->n_offsets, true, false);
2122                 if (!a)
2123                         return -ENOMEM;
2124
2125                 for (i = 0; i < c->n_offsets; i++)
2126                         bus_gvariant_write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2127         } else {
2128                 void *a;
2129
2130                 /* Fixed-width or empty arrays */
2131
2132                 a = message_extend_body(m, 1, 0, true, false); /* let's add offset to parent */
2133                 if (!a)
2134                         return -ENOMEM;
2135         }
2136
2137         return 0;
2138 }
2139
2140 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2141         uint8_t *a;
2142         size_t l;
2143
2144         assert(m);
2145         assert(c);
2146         assert(c->signature);
2147
2148         if (!BUS_MESSAGE_IS_GVARIANT(m))
2149                 return 0;
2150
2151         l = strlen(c->signature);
2152
2153         a = message_extend_body(m, 1, 1 + l, true, false);
2154         if (!a)
2155                 return -ENOMEM;
2156
2157         a[0] = 0;
2158         memcpy(a+1, c->signature, l);
2159
2160         return 0;
2161 }
2162
2163 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2164         size_t n_variable = 0;
2165         unsigned i = 0;
2166         const char *p;
2167         uint8_t *a;
2168         int r;
2169
2170         assert(m);
2171         assert(c);
2172
2173         if (!BUS_MESSAGE_IS_GVARIANT(m))
2174                 return 0;
2175
2176         p = strempty(c->signature);
2177         while (*p != 0) {
2178                 size_t n;
2179
2180                 r = signature_element_length(p, &n);
2181                 if (r < 0)
2182                         return r;
2183                 else {
2184                         char t[n+1];
2185
2186                         memcpy(t, p, n);
2187                         t[n] = 0;
2188
2189                         r = bus_gvariant_is_fixed_size(t);
2190                         if (r < 0)
2191                                 return r;
2192                 }
2193
2194                 assert(!c->need_offsets || i <= c->n_offsets);
2195
2196                 /* We need to add an offset for each item that has a
2197                  * variable size and that is not the last one in the
2198                  * list */
2199                 if (r == 0 && p[n] != 0)
2200                         n_variable++;
2201
2202                 i++;
2203                 p += n;
2204         }
2205
2206         assert(!c->need_offsets || i == c->n_offsets);
2207         assert(c->need_offsets || n_variable == 0);
2208
2209         if (n_variable <= 0) {
2210                 a = message_extend_body(m, 1, 0, add_offset, false);
2211                 if (!a)
2212                         return -ENOMEM;
2213         } else {
2214                 size_t sz;
2215                 unsigned j;
2216
2217                 assert(c->offsets[c->n_offsets-1] == m->body_size);
2218
2219                 sz = bus_gvariant_determine_word_size(m->body_size - c->begin, n_variable);
2220
2221                 a = message_extend_body(m, 1, sz * n_variable, add_offset, false);
2222                 if (!a)
2223                         return -ENOMEM;
2224
2225                 p = strempty(c->signature);
2226                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2227                         unsigned k;
2228                         size_t n;
2229
2230                         r = signature_element_length(p, &n);
2231                         if (r < 0)
2232                                 return r;
2233                         else {
2234                                 char t[n+1];
2235
2236                                 memcpy(t, p, n);
2237                                 t[n] = 0;
2238
2239                                 p += n;
2240
2241                                 r = bus_gvariant_is_fixed_size(t);
2242                                 if (r < 0)
2243                                         return r;
2244                                 if (r > 0 || p[0] == 0)
2245                                         continue;
2246                         }
2247
2248                         k = n_variable - 1 - j;
2249
2250                         bus_gvariant_write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2251
2252                         j++;
2253                 }
2254         }
2255
2256         return 0;
2257 }
2258
2259 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2260         struct bus_container *c;
2261         int r;
2262
2263         assert_return(m, -EINVAL);
2264         assert_return(!m->sealed, -EPERM);
2265         assert_return(m->n_containers > 0, -EINVAL);
2266         assert_return(!m->poisoned, -ESTALE);
2267
2268         c = message_get_container(m);
2269
2270         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2271                 if (c->signature && c->signature[c->index] != 0)
2272                         return -EINVAL;
2273
2274         m->n_containers--;
2275
2276         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2277                 r = bus_message_close_array(m, c);
2278         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2279                 r = bus_message_close_variant(m, c);
2280         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2281                 r = bus_message_close_struct(m, c, true);
2282         else
2283                 assert_not_reached("Unknown container type");
2284
2285         free(c->signature);
2286         free(c->offsets);
2287
2288         return r;
2289 }
2290
2291 typedef struct {
2292         const char *types;
2293         unsigned n_struct;
2294         unsigned n_array;
2295 } TypeStack;
2296
2297 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2298         assert(stack);
2299         assert(max > 0);
2300
2301         if (*i >= max)
2302                 return -EINVAL;
2303
2304         stack[*i].types = types;
2305         stack[*i].n_struct = n_struct;
2306         stack[*i].n_array = n_array;
2307         (*i)++;
2308
2309         return 0;
2310 }
2311
2312 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2313         assert(stack);
2314         assert(max > 0);
2315         assert(types);
2316         assert(n_struct);
2317         assert(n_array);
2318
2319         if (*i <= 0)
2320                 return 0;
2321
2322         (*i)--;
2323         *types = stack[*i].types;
2324         *n_struct = stack[*i].n_struct;
2325         *n_array = stack[*i].n_array;
2326
2327         return 1;
2328 }
2329
2330 int bus_message_append_ap(
2331                 sd_bus_message *m,
2332                 const char *types,
2333                 va_list ap) {
2334
2335         unsigned n_array, n_struct;
2336         TypeStack stack[BUS_CONTAINER_DEPTH];
2337         unsigned stack_ptr = 0;
2338         int r;
2339
2340         assert(m);
2341
2342         if (!types)
2343                 return 0;
2344
2345         n_array = (unsigned) -1;
2346         n_struct = strlen(types);
2347
2348         for (;;) {
2349                 const char *t;
2350
2351                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2352                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2353                         if (r < 0)
2354                                 return r;
2355                         if (r == 0)
2356                                 break;
2357
2358                         r = sd_bus_message_close_container(m);
2359                         if (r < 0)
2360                                 return r;
2361
2362                         continue;
2363                 }
2364
2365                 t = types;
2366                 if (n_array != (unsigned) -1)
2367                         n_array --;
2368                 else {
2369                         types ++;
2370                         n_struct--;
2371                 }
2372
2373                 switch (*t) {
2374
2375                 case SD_BUS_TYPE_BYTE: {
2376                         uint8_t x;
2377
2378                         x = (uint8_t) va_arg(ap, int);
2379                         r = sd_bus_message_append_basic(m, *t, &x);
2380                         break;
2381                 }
2382
2383                 case SD_BUS_TYPE_BOOLEAN:
2384                 case SD_BUS_TYPE_INT32:
2385                 case SD_BUS_TYPE_UINT32:
2386                 case SD_BUS_TYPE_UNIX_FD: {
2387                         uint32_t x;
2388
2389                         /* We assume a boolean is the same as int32_t */
2390                         assert_cc(sizeof(int32_t) == sizeof(int));
2391
2392                         x = va_arg(ap, uint32_t);
2393                         r = sd_bus_message_append_basic(m, *t, &x);
2394                         break;
2395                 }
2396
2397                 case SD_BUS_TYPE_INT16:
2398                 case SD_BUS_TYPE_UINT16: {
2399                         uint16_t x;
2400
2401                         x = (uint16_t) va_arg(ap, int);
2402                         r = sd_bus_message_append_basic(m, *t, &x);
2403                         break;
2404                 }
2405
2406                 case SD_BUS_TYPE_INT64:
2407                 case SD_BUS_TYPE_UINT64: {
2408                         uint64_t x;
2409
2410                         x = va_arg(ap, uint64_t);
2411                         r = sd_bus_message_append_basic(m, *t, &x);
2412                         break;
2413                 }
2414
2415                 case SD_BUS_TYPE_DOUBLE: {
2416                         double x;
2417
2418                         x = va_arg(ap, double);
2419                         r = sd_bus_message_append_basic(m, *t, &x);
2420                         break;
2421                 }
2422
2423                 case SD_BUS_TYPE_STRING:
2424                 case SD_BUS_TYPE_OBJECT_PATH:
2425                 case SD_BUS_TYPE_SIGNATURE: {
2426                         const char *x;
2427
2428                         x = va_arg(ap, const char*);
2429                         r = sd_bus_message_append_basic(m, *t, x);
2430                         break;
2431                 }
2432
2433                 case SD_BUS_TYPE_ARRAY: {
2434                         size_t k;
2435
2436                         r = signature_element_length(t + 1, &k);
2437                         if (r < 0)
2438                                 return r;
2439
2440                         {
2441                                 char s[k + 1];
2442                                 memcpy(s, t + 1, k);
2443                                 s[k] = 0;
2444
2445                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2446                                 if (r < 0)
2447                                         return r;
2448                         }
2449
2450                         if (n_array == (unsigned) -1) {
2451                                 types += k;
2452                                 n_struct -= k;
2453                         }
2454
2455                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2456                         if (r < 0)
2457                                 return r;
2458
2459                         types = t + 1;
2460                         n_struct = k;
2461                         n_array = va_arg(ap, unsigned);
2462
2463                         break;
2464                 }
2465
2466                 case SD_BUS_TYPE_VARIANT: {
2467                         const char *s;
2468
2469                         s = va_arg(ap, const char*);
2470                         if (!s)
2471                                 return -EINVAL;
2472
2473                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2474                         if (r < 0)
2475                                 return r;
2476
2477                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2478                         if (r < 0)
2479                                 return r;
2480
2481                         types = s;
2482                         n_struct = strlen(s);
2483                         n_array = (unsigned) -1;
2484
2485                         break;
2486                 }
2487
2488                 case SD_BUS_TYPE_STRUCT_BEGIN:
2489                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2490                         size_t k;
2491
2492                         r = signature_element_length(t, &k);
2493                         if (r < 0)
2494                                 return r;
2495
2496                         {
2497                                 char s[k - 1];
2498
2499                                 memcpy(s, t + 1, k - 2);
2500                                 s[k - 2] = 0;
2501
2502                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2503                                 if (r < 0)
2504                                         return r;
2505                         }
2506
2507                         if (n_array == (unsigned) -1) {
2508                                 types += k - 1;
2509                                 n_struct -= k - 1;
2510                         }
2511
2512                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2513                         if (r < 0)
2514                                 return r;
2515
2516                         types = t + 1;
2517                         n_struct = k - 2;
2518                         n_array = (unsigned) -1;
2519
2520                         break;
2521                 }
2522
2523                 default:
2524                         r = -EINVAL;
2525                 }
2526
2527                 if (r < 0)
2528                         return r;
2529         }
2530
2531         return 1;
2532 }
2533
2534 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2535         va_list ap;
2536         int r;
2537
2538         assert_return(m, -EINVAL);
2539         assert_return(types, -EINVAL);
2540         assert_return(!m->sealed, -EPERM);
2541         assert_return(!m->poisoned, -ESTALE);
2542
2543         va_start(ap, types);
2544         r = bus_message_append_ap(m, types, ap);
2545         va_end(ap);
2546
2547         return r;
2548 }
2549
2550 _public_ int sd_bus_message_append_array_space(
2551                 sd_bus_message *m,
2552                 char type,
2553                 size_t size,
2554                 void **ptr) {
2555
2556         ssize_t align, sz;
2557         void *a;
2558         int r;
2559
2560         assert_return(m, -EINVAL);
2561         assert_return(!m->sealed, -EPERM);
2562         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2563         assert_return(ptr || size == 0, -EINVAL);
2564         assert_return(!m->poisoned, -ESTALE);
2565
2566         /* alignment and size of the trivial types (except bool) is
2567          * identical for gvariant and dbus1 marshalling */
2568         align = bus_type_get_alignment(type);
2569         sz = bus_type_get_size(type);
2570
2571         assert_se(align > 0);
2572         assert_se(sz > 0);
2573
2574         if (size % sz != 0)
2575                 return -EINVAL;
2576
2577         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2578         if (r < 0)
2579                 return r;
2580
2581         a = message_extend_body(m, align, size, false, false);
2582         if (!a)
2583                 return -ENOMEM;
2584
2585         r = sd_bus_message_close_container(m);
2586         if (r < 0)
2587                 return r;
2588
2589         *ptr = a;
2590         return 0;
2591 }
2592
2593 _public_ int sd_bus_message_append_array(
2594                 sd_bus_message *m,
2595                 char type,
2596                 const void *ptr,
2597                 size_t size) {
2598         int r;
2599         void *p;
2600
2601         assert_return(m, -EINVAL);
2602         assert_return(!m->sealed, -EPERM);
2603         assert_return(bus_type_is_trivial(type), -EINVAL);
2604         assert_return(ptr || size == 0, -EINVAL);
2605         assert_return(!m->poisoned, -ESTALE);
2606
2607         r = sd_bus_message_append_array_space(m, type, size, &p);
2608         if (r < 0)
2609                 return r;
2610
2611         if (size > 0)
2612                 memcpy(p, ptr, size);
2613
2614         return 0;
2615 }
2616
2617 _public_ int sd_bus_message_append_array_iovec(
2618                 sd_bus_message *m,
2619                 char type,
2620                 const struct iovec *iov,
2621                 unsigned n) {
2622
2623         size_t size;
2624         unsigned i;
2625         void *p;
2626         int r;
2627
2628         assert_return(m, -EINVAL);
2629         assert_return(!m->sealed, -EPERM);
2630         assert_return(bus_type_is_trivial(type), -EINVAL);
2631         assert_return(iov || n == 0, -EINVAL);
2632         assert_return(!m->poisoned, -ESTALE);
2633
2634         size = IOVEC_TOTAL_SIZE(iov, n);
2635
2636         r = sd_bus_message_append_array_space(m, type, size, &p);
2637         if (r < 0)
2638                 return r;
2639
2640         for (i = 0; i < n; i++) {
2641
2642                 if (iov[i].iov_base)
2643                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2644                 else
2645                         memzero(p, iov[i].iov_len);
2646
2647                 p = (uint8_t*) p + iov[i].iov_len;
2648         }
2649
2650         return 0;
2651 }
2652
2653 _public_ int sd_bus_message_append_array_memfd(
2654                 sd_bus_message *m,
2655                 char type,
2656                 int memfd,
2657                 uint64_t offset,
2658                 uint64_t size) {
2659
2660         _cleanup_close_ int copy_fd = -1;
2661         struct bus_body_part *part;
2662         ssize_t align, sz;
2663         uint64_t real_size;
2664         void *a;
2665         int r;
2666
2667         assert_return(m, -EINVAL);
2668         assert_return(memfd >= 0, -EINVAL);
2669         assert_return(bus_type_is_trivial(type), -EINVAL);
2670         assert_return(size > 0, -EINVAL);
2671         assert_return(!m->sealed, -EPERM);
2672         assert_return(!m->poisoned, -ESTALE);
2673
2674         r = memfd_set_sealed(memfd);
2675         if (r < 0)
2676                 return r;
2677
2678         copy_fd = dup(memfd);
2679         if (copy_fd < 0)
2680                 return copy_fd;
2681
2682         r = memfd_get_size(memfd, &real_size);
2683         if (r < 0)
2684                 return r;
2685
2686         if (offset == 0 && size == (uint64_t) -1)
2687                 size = real_size;
2688         else if (offset + size > real_size)
2689                 return -EMSGSIZE;
2690
2691         align = bus_type_get_alignment(type);
2692         sz = bus_type_get_size(type);
2693
2694         assert_se(align > 0);
2695         assert_se(sz > 0);
2696
2697         if (offset % align != 0)
2698                 return -EINVAL;
2699
2700         if (size % sz != 0)
2701                 return -EINVAL;
2702
2703         if (size > (uint64_t) (uint32_t) -1)
2704                 return -EINVAL;
2705
2706         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2707         if (r < 0)
2708                 return r;
2709
2710         a = message_extend_body(m, align, 0, false, false);
2711         if (!a)
2712                 return -ENOMEM;
2713
2714         part = message_append_part(m);
2715         if (!part)
2716                 return -ENOMEM;
2717
2718         part->memfd = copy_fd;
2719         part->memfd_offset = offset;
2720         part->sealed = true;
2721         part->size = size;
2722         copy_fd = -1;
2723
2724         m->body_size += size;
2725         message_extend_containers(m, size);
2726
2727         return sd_bus_message_close_container(m);
2728 }
2729
2730 _public_ int sd_bus_message_append_string_memfd(
2731                 sd_bus_message *m,
2732                 int memfd,
2733                 uint64_t offset,
2734                 uint64_t size) {
2735
2736         _cleanup_close_ int copy_fd = -1;
2737         struct bus_body_part *part;
2738         struct bus_container *c;
2739         uint64_t real_size;
2740         void *a;
2741         int r;
2742
2743         assert_return(m, -EINVAL);
2744         assert_return(memfd >= 0, -EINVAL);
2745         assert_return(size > 0, -EINVAL);
2746         assert_return(!m->sealed, -EPERM);
2747         assert_return(!m->poisoned, -ESTALE);
2748
2749         r = memfd_set_sealed(memfd);
2750         if (r < 0)
2751                 return r;
2752
2753         copy_fd = dup(memfd);
2754         if (copy_fd < 0)
2755                 return copy_fd;
2756
2757         r = memfd_get_size(memfd, &real_size);
2758         if (r < 0)
2759                 return r;
2760
2761         if (offset == 0 && size == (uint64_t) -1)
2762                 size = real_size;
2763         else if (offset + size > real_size)
2764                 return -EMSGSIZE;
2765
2766         /* We require this to be NUL terminated */
2767         if (size == 0)
2768                 return -EINVAL;
2769
2770         if (size > (uint64_t) (uint32_t) -1)
2771                 return -EINVAL;
2772
2773         c = message_get_container(m);
2774         if (c->signature && c->signature[c->index]) {
2775                 /* Container signature is already set */
2776
2777                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2778                         return -ENXIO;
2779         } else {
2780                 char *e;
2781
2782                 /* Maybe we can append to the signature? But only if this is the top-level container */
2783                 if (c->enclosing != 0)
2784                         return -ENXIO;
2785
2786                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2787                 if (!e) {
2788                         m->poisoned = true;
2789                         return -ENOMEM;
2790                 }
2791         }
2792
2793         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2794                 a = message_extend_body(m, 4, 4, false, false);
2795                 if (!a)
2796                         return -ENOMEM;
2797
2798                 *(uint32_t*) a = size - 1;
2799         }
2800
2801         part = message_append_part(m);
2802         if (!part)
2803                 return -ENOMEM;
2804
2805         part->memfd = copy_fd;
2806         part->memfd_offset = offset;
2807         part->sealed = true;
2808         part->size = size;
2809         copy_fd = -1;
2810
2811         m->body_size += size;
2812         message_extend_containers(m, size);
2813
2814         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2815                 r = message_add_offset(m, m->body_size);
2816                 if (r < 0) {
2817                         m->poisoned = true;
2818                         return -ENOMEM;
2819                 }
2820         }
2821
2822         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2823                 c->index++;
2824
2825         return 0;
2826 }
2827
2828 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2829         char **i;
2830         int r;
2831
2832         assert_return(m, -EINVAL);
2833         assert_return(!m->sealed, -EPERM);
2834         assert_return(!m->poisoned, -ESTALE);
2835
2836         r = sd_bus_message_open_container(m, 'a', "s");
2837         if (r < 0)
2838                 return r;
2839
2840         STRV_FOREACH(i, l) {
2841                 r = sd_bus_message_append_basic(m, 's', *i);
2842                 if (r < 0)
2843                         return r;
2844         }
2845
2846         return sd_bus_message_close_container(m);
2847 }
2848
2849 static int bus_message_close_header(sd_bus_message *m) {
2850
2851         assert(m);
2852
2853         /* The actual user data is finished now, we just complete the
2854            variant and struct now (at least on gvariant). Remember
2855            this position, so that during parsing we know where to to
2856            put the outer container end. */
2857         m->user_body_size = m->body_size;
2858
2859         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2860                 const char *signature;
2861                 size_t sz, l;
2862                 void *d;
2863
2864                 /* Add offset table to end of fields array */
2865                 if (m->n_header_offsets >= 1) {
2866                         uint8_t *a;
2867                         unsigned i;
2868
2869                         assert(m->fields_size == m->header_offsets[m->n_header_offsets-1]);
2870
2871                         sz = bus_gvariant_determine_word_size(m->fields_size, m->n_header_offsets);
2872                         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2873                         if (!a)
2874                                 return -ENOMEM;
2875
2876                         for (i = 0; i < m->n_header_offsets; i++)
2877                                 bus_gvariant_write_word_le(a + sz*i, sz, m->header_offsets[i]);
2878                 }
2879
2880                 /* Add gvariant NUL byte plus signature to the end of
2881                  * the body, followed by the final offset pointing to
2882                  * the end of the fields array */
2883
2884                 signature = strempty(m->root_container.signature);
2885                 l = strlen(signature);
2886
2887                 sz = bus_gvariant_determine_word_size(sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size + 1 + l, 1);
2888                 d = message_extend_body(m, 1, 1 + l + sz, false, true);
2889                 if (!d)
2890                         return -ENOMEM;
2891
2892                 *(uint8_t*) d = 0;
2893                 memcpy((uint8_t*) d + 1, signature, l);
2894
2895                 bus_gvariant_write_word_le((uint8_t*) d + 1 + l, sz, sizeof(struct bus_header) + m->fields_size);
2896
2897                 m->footer = d;
2898                 m->footer_accessible = 1 + l + sz;
2899         } else {
2900                 m->header->dbus1.fields_size = m->fields_size;
2901                 m->header->dbus1.body_size = m->body_size;
2902         }
2903
2904         return 0;
2905 }
2906
2907 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2908         struct bus_body_part *part;
2909         size_t a;
2910         unsigned i;
2911         int r;
2912
2913         assert(m);
2914
2915         if (m->sealed)
2916                 return -EPERM;
2917
2918         if (m->n_containers > 0)
2919                 return -EBADMSG;
2920
2921         if (m->poisoned)
2922                 return -ESTALE;
2923
2924         if (cookie > 0xffffffffULL &&
2925             !BUS_MESSAGE_IS_GVARIANT(m))
2926                 return -EOPNOTSUPP;
2927
2928         /* In vtables the return signature of method calls is listed,
2929          * let's check if they match if this is a response */
2930         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2931             m->enforced_reply_signature &&
2932             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2933                 return -ENOMSG;
2934
2935         /* If gvariant marshalling is used we need to close the body structure */
2936         r = bus_message_close_struct(m, &m->root_container, false);
2937         if (r < 0)
2938                 return r;
2939
2940         /* If there's a non-trivial signature set, then add it in
2941          * here, but only on dbus1 */
2942         if (!isempty(m->root_container.signature) && !BUS_MESSAGE_IS_GVARIANT(m)) {
2943                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2944                 if (r < 0)
2945                         return r;
2946         }
2947
2948         if (m->n_fds > 0) {
2949                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2950                 if (r < 0)
2951                         return r;
2952         }
2953
2954         r = bus_message_close_header(m);
2955         if (r < 0)
2956                 return r;
2957
2958         if (BUS_MESSAGE_IS_GVARIANT(m))
2959                 m->header->dbus2.cookie = cookie;
2960         else
2961                 m->header->dbus1.serial = (uint32_t) cookie;
2962
2963         m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2964
2965         /* Add padding at the end of the fields part, since we know
2966          * the body needs to start at an 8 byte alignment. We made
2967          * sure we allocated enough space for this, so all we need to
2968          * do here is to zero it out. */
2969         a = ALIGN8(m->fields_size) - m->fields_size;
2970         if (a > 0)
2971                 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + m->fields_size, a);
2972
2973         /* If this is something we can send as memfd, then let's seal
2974         the memfd now. Note that we can send memfds as payload only
2975         for directed messages, and not for broadcasts. */
2976         if (m->destination && m->bus->use_memfd) {
2977                 MESSAGE_FOREACH_PART(part, i, m)
2978                         if (part->memfd >= 0 &&
2979                             !part->sealed &&
2980                             (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0) &&
2981                             part != m->body_end) { /* The last part may never be sent as memfd */
2982                                 uint64_t sz;
2983
2984                                 /* Try to seal it if that makes
2985                                  * sense. First, unmap our own map to
2986                                  * make sure we don't keep it busy. */
2987                                 bus_body_part_unmap(part);
2988
2989                                 /* Then, sync up real memfd size */
2990                                 sz = part->size;
2991                                 r = memfd_set_size(part->memfd, sz);
2992                                 if (r < 0)
2993                                         return r;
2994
2995                                 /* Finally, try to seal */
2996                                 if (memfd_set_sealed(part->memfd) >= 0)
2997                                         part->sealed = true;
2998                         }
2999         }
3000
3001         m->root_container.end = m->user_body_size;
3002         m->root_container.index = 0;
3003         m->root_container.offset_index = 0;
3004         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
3005
3006         m->sealed = true;
3007
3008         return 0;
3009 }
3010
3011 int bus_body_part_map(struct bus_body_part *part) {
3012         void *p;
3013         size_t psz, shift;
3014
3015         assert_se(part);
3016
3017         if (part->data)
3018                 return 0;
3019
3020         if (part->size <= 0)
3021                 return 0;
3022
3023         /* For smaller zero parts (as used for padding) we don't need to map anything... */
3024         if (part->memfd < 0 && part->is_zero && part->size < 8) {
3025                 static const uint8_t zeroes[7] = { };
3026                 part->data = (void*) zeroes;
3027                 return 0;
3028         }
3029
3030         shift = part->memfd_offset - ((part->memfd_offset / page_size()) * page_size());
3031         psz = PAGE_ALIGN(part->size + shift);
3032
3033         if (part->memfd >= 0)
3034                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset - shift);
3035         else if (part->is_zero)
3036                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
3037         else
3038                 return -EINVAL;
3039
3040         if (p == MAP_FAILED)
3041                 return -errno;
3042
3043         part->mapped = psz;
3044         part->mmap_begin = p;
3045         part->data = (uint8_t*) p + shift;
3046         part->munmap_this = true;
3047
3048         return 0;
3049 }
3050
3051 void bus_body_part_unmap(struct bus_body_part *part) {
3052
3053         assert_se(part);
3054
3055         if (part->memfd < 0)
3056                 return;
3057
3058         if (!part->mmap_begin)
3059                 return;
3060
3061         if (!part->munmap_this)
3062                 return;
3063
3064         assert_se(munmap(part->mmap_begin, part->mapped) == 0);
3065
3066         part->mmap_begin = NULL;
3067         part->data = NULL;
3068         part->mapped = 0;
3069         part->munmap_this = false;
3070
3071         return;
3072 }
3073
3074 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
3075         size_t k, start, end;
3076
3077         assert(rindex);
3078         assert(align > 0);
3079
3080         start = ALIGN_TO((size_t) *rindex, align);
3081         end = start + nbytes;
3082
3083         if (end > sz)
3084                 return -EBADMSG;
3085
3086         /* Verify that padding is 0 */
3087         for (k = *rindex; k < start; k++)
3088                 if (((const uint8_t*) p)[k] != 0)
3089                         return -EBADMSG;
3090
3091         if (r)
3092                 *r = (uint8_t*) p + start;
3093
3094         *rindex = end;
3095
3096         return 1;
3097 }
3098
3099 static bool message_end_of_signature(sd_bus_message *m) {
3100         struct bus_container *c;
3101
3102         assert(m);
3103
3104         c = message_get_container(m);
3105         return !c->signature || c->signature[c->index] == 0;
3106 }
3107
3108 static bool message_end_of_array(sd_bus_message *m, size_t index) {
3109         struct bus_container *c;
3110
3111         assert(m);
3112
3113         c = message_get_container(m);
3114         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3115                 return false;
3116
3117         if (BUS_MESSAGE_IS_GVARIANT(m))
3118                 return index >= c->end;
3119         else {
3120                 assert(c->array_size);
3121                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
3122         }
3123 }
3124
3125 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
3126         assert_return(m, -EINVAL);
3127         assert_return(m->sealed, -EPERM);
3128
3129         if (complete && m->n_containers > 0)
3130                 return false;
3131
3132         if (message_end_of_signature(m))
3133                 return true;
3134
3135         if (message_end_of_array(m, m->rindex))
3136                 return true;
3137
3138         return false;
3139 }
3140
3141 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
3142         struct bus_body_part *part;
3143         size_t begin;
3144         int r;
3145
3146         assert(m);
3147
3148         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
3149                 part = m->cached_rindex_part;
3150                 begin = m->cached_rindex_part_begin;
3151         } else {
3152                 part = &m->body;
3153                 begin = 0;
3154         }
3155
3156         while (part) {
3157                 if (index < begin)
3158                         return NULL;
3159
3160                 if (index + sz <= begin + part->size) {
3161
3162                         r = bus_body_part_map(part);
3163                         if (r < 0)
3164                                 return NULL;
3165
3166                         if (p)
3167                                 *p = (uint8_t*) part->data + index - begin;
3168
3169                         m->cached_rindex_part = part;
3170                         m->cached_rindex_part_begin = begin;
3171
3172                         return part;
3173                 }
3174
3175                 begin += part->size;
3176                 part = part->next;
3177         }
3178
3179         return NULL;
3180 }
3181
3182 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3183         int r;
3184
3185         assert(m);
3186         assert(c);
3187         assert(rindex);
3188
3189         if (!BUS_MESSAGE_IS_GVARIANT(m))
3190                 return 0;
3191
3192         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3193                 int sz;
3194
3195                 sz = bus_gvariant_get_size(c->signature);
3196                 if (sz < 0) {
3197                         int alignment;
3198
3199                         if (c->offset_index+1 >= c->n_offsets)
3200                                 goto end;
3201
3202                         /* Variable-size array */
3203
3204                         alignment = bus_gvariant_get_alignment(c->signature);
3205                         assert(alignment > 0);
3206
3207                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3208                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3209                 } else {
3210
3211                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3212                                 goto end;
3213
3214                         /* Fixed-size array */
3215                         *rindex = c->begin + (c->offset_index+1) * sz;
3216                         c->item_size = sz;
3217                 }
3218
3219                 c->offset_index++;
3220
3221         } else if (c->enclosing == 0 ||
3222                    c->enclosing == SD_BUS_TYPE_STRUCT ||
3223                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3224
3225                 int alignment;
3226                 size_t n, j;
3227
3228                 if (c->offset_index+1 >= c->n_offsets)
3229                         goto end;
3230
3231                 r = signature_element_length(c->signature + c->index, &n);
3232                 if (r < 0)
3233                         return r;
3234
3235                 r = signature_element_length(c->signature + c->index + n, &j);
3236                 if (r < 0)
3237                         return r;
3238                 else {
3239                         char t[j+1];
3240                         memcpy(t, c->signature + c->index + n, j);
3241                         t[j] = 0;
3242
3243                         alignment = bus_gvariant_get_alignment(t);
3244                 }
3245
3246                 assert(alignment > 0);
3247
3248                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3249                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3250
3251                 c->offset_index++;
3252
3253         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3254                 goto end;
3255         else
3256                 assert_not_reached("Unknown container type");
3257
3258         return 0;
3259
3260 end:
3261         /* Reached the end */
3262         *rindex = c->end;
3263         c->item_size = 0;
3264         return 0;
3265 }
3266
3267
3268 static int message_peek_body(
3269                 sd_bus_message *m,
3270                 size_t *rindex,
3271                 size_t align,
3272                 size_t nbytes,
3273                 void **ret) {
3274
3275         size_t k, start, end, padding;
3276         struct bus_body_part *part;
3277         uint8_t *q;
3278
3279         assert(m);
3280         assert(rindex);
3281         assert(align > 0);
3282
3283         start = ALIGN_TO((size_t) *rindex, align);
3284         padding = start - *rindex;
3285         end = start + nbytes;
3286
3287         if (end > m->user_body_size)
3288                 return -EBADMSG;
3289
3290         part = find_part(m, *rindex, padding, (void**) &q);
3291         if (!part)
3292                 return -EBADMSG;
3293
3294         if (q) {
3295                 /* Verify padding */
3296                 for (k = 0; k < padding; k++)
3297                         if (q[k] != 0)
3298                                 return -EBADMSG;
3299         }
3300
3301         part = find_part(m, start, nbytes, (void**) &q);
3302         if (!part || (nbytes > 0 && !q))
3303                 return -EBADMSG;
3304
3305         *rindex = end;
3306
3307         if (ret)
3308                 *ret = q;
3309
3310         return 0;
3311 }
3312
3313 static bool validate_nul(const char *s, size_t l) {
3314
3315         /* Check for NUL chars in the string */
3316         if (memchr(s, 0, l))
3317                 return false;
3318
3319         /* Check for NUL termination */
3320         if (s[l] != 0)
3321                 return false;
3322
3323         return true;
3324 }
3325
3326 static bool validate_string(const char *s, size_t l) {
3327
3328         if (!validate_nul(s, l))
3329                 return false;
3330
3331         /* Check if valid UTF8 */
3332         if (!utf8_is_valid(s))
3333                 return false;
3334
3335         return true;
3336 }
3337
3338 static bool validate_signature(const char *s, size_t l) {
3339
3340         if (!validate_nul(s, l))
3341                 return false;
3342
3343         /* Check if valid signature */
3344         if (!signature_is_valid(s, true))
3345                 return false;
3346
3347         return true;
3348 }
3349
3350 static bool validate_object_path(const char *s, size_t l) {
3351
3352         if (!validate_nul(s, l))
3353                 return false;
3354
3355         if (!object_path_is_valid(s))
3356                 return false;
3357
3358         return true;
3359 }
3360
3361 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3362         struct bus_container *c;
3363         size_t rindex;
3364         void *q;
3365         int r;
3366
3367         assert_return(m, -EINVAL);
3368         assert_return(m->sealed, -EPERM);
3369         assert_return(bus_type_is_basic(type), -EINVAL);
3370
3371         if (message_end_of_signature(m))
3372                 return -ENXIO;
3373
3374         if (message_end_of_array(m, m->rindex))
3375                 return 0;
3376
3377         c = message_get_container(m);
3378         if (c->signature[c->index] != type)
3379                 return -ENXIO;
3380
3381         rindex = m->rindex;
3382
3383         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3384
3385                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3386                         bool ok;
3387
3388                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3389                         if (r < 0)
3390                                 return r;
3391
3392                         if (type == SD_BUS_TYPE_STRING)
3393                                 ok = validate_string(q, c->item_size-1);
3394                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3395                                 ok = validate_object_path(q, c->item_size-1);
3396                         else
3397                                 ok = validate_signature(q, c->item_size-1);
3398
3399                         if (!ok)
3400                                 return -EBADMSG;
3401
3402                         if (p)
3403                                 *(const char**) p = q;
3404                 } else {
3405                         int sz, align;
3406
3407                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3408                         assert(sz > 0);
3409                         if ((size_t) sz != c->item_size)
3410                                 return -EBADMSG;
3411
3412                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3413                         assert(align > 0);
3414
3415                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3416                         if (r < 0)
3417                                 return r;
3418
3419                         switch (type) {
3420
3421                         case SD_BUS_TYPE_BYTE:
3422                                 if (p)
3423                                         *(uint8_t*) p = *(uint8_t*) q;
3424                                 break;
3425
3426                         case SD_BUS_TYPE_BOOLEAN:
3427                                 if (p)
3428                                         *(int*) p = !!*(uint8_t*) q;
3429                                 break;
3430
3431                         case SD_BUS_TYPE_INT16:
3432                         case SD_BUS_TYPE_UINT16:
3433                                 if (p)
3434                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3435                                 break;
3436
3437                         case SD_BUS_TYPE_INT32:
3438                         case SD_BUS_TYPE_UINT32:
3439                                 if (p)
3440                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3441                                 break;
3442
3443                         case SD_BUS_TYPE_INT64:
3444                         case SD_BUS_TYPE_UINT64:
3445                         case SD_BUS_TYPE_DOUBLE:
3446                                 if (p)
3447                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3448                                 break;
3449
3450                         case SD_BUS_TYPE_UNIX_FD: {
3451                                 uint32_t j;
3452
3453                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3454                                 if (j >= m->n_fds)
3455                                         return -EBADMSG;
3456
3457                                 if (p)
3458                                         *(int*) p = m->fds[j];
3459
3460                                 break;
3461                         }
3462
3463                         default:
3464                                 assert_not_reached("unexpected type");
3465                         }
3466                 }
3467
3468                 r = container_next_item(m, c, &rindex);
3469                 if (r < 0)
3470                         return r;
3471         } else {
3472
3473                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3474                         uint32_t l;
3475                         bool ok;
3476
3477                         r = message_peek_body(m, &rindex, 4, 4, &q);
3478                         if (r < 0)
3479                                 return r;
3480
3481                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3482                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3483                         if (r < 0)
3484                                 return r;
3485
3486                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3487                                 ok = validate_object_path(q, l);
3488                         else
3489                                 ok = validate_string(q, l);
3490                         if (!ok)
3491                                 return -EBADMSG;
3492
3493                         if (p)
3494                                 *(const char**) p = q;
3495
3496                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3497                         uint8_t l;
3498
3499                         r = message_peek_body(m, &rindex, 1, 1, &q);
3500                         if (r < 0)
3501                                 return r;
3502
3503                         l = *(uint8_t*) q;
3504                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3505                         if (r < 0)
3506                                 return r;
3507
3508                         if (!validate_signature(q, l))
3509                                 return -EBADMSG;
3510
3511                         if (p)
3512                                 *(const char**) p = q;
3513
3514                 } else {
3515                         ssize_t sz, align;
3516
3517                         align = bus_type_get_alignment(type);
3518                         assert(align > 0);
3519
3520                         sz = bus_type_get_size(type);
3521                         assert(sz > 0);
3522
3523                         r = message_peek_body(m, &rindex, align, sz, &q);
3524                         if (r < 0)
3525                                 return r;
3526
3527                         switch (type) {
3528
3529                         case SD_BUS_TYPE_BYTE:
3530                                 if (p)
3531                                         *(uint8_t*) p = *(uint8_t*) q;
3532                                 break;
3533
3534                         case SD_BUS_TYPE_BOOLEAN:
3535                                 if (p)
3536                                         *(int*) p = !!*(uint32_t*) q;
3537                                 break;
3538
3539                         case SD_BUS_TYPE_INT16:
3540                         case SD_BUS_TYPE_UINT16:
3541                                 if (p)
3542                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3543                                 break;
3544
3545                         case SD_BUS_TYPE_INT32:
3546                         case SD_BUS_TYPE_UINT32:
3547                                 if (p)
3548                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3549                                 break;
3550
3551                         case SD_BUS_TYPE_INT64:
3552                         case SD_BUS_TYPE_UINT64:
3553                         case SD_BUS_TYPE_DOUBLE:
3554                                 if (p)
3555                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3556                                 break;
3557
3558                         case SD_BUS_TYPE_UNIX_FD: {
3559                                 uint32_t j;
3560
3561                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3562                                 if (j >= m->n_fds)
3563                                         return -EBADMSG;
3564
3565                                 if (p)
3566                                         *(int*) p = m->fds[j];
3567                                 break;
3568                         }
3569
3570                         default:
3571                                 assert_not_reached("Unknown basic type...");
3572                         }
3573                 }
3574         }
3575
3576         m->rindex = rindex;
3577
3578         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3579                 c->index++;
3580
3581         return 1;
3582 }
3583
3584 static int bus_message_enter_array(
3585                 sd_bus_message *m,
3586                 struct bus_container *c,
3587                 const char *contents,
3588                 uint32_t **array_size,
3589                 size_t *item_size,
3590                 size_t **offsets,
3591                 size_t *n_offsets) {
3592
3593         size_t rindex;
3594         void *q;
3595         int r, alignment;
3596
3597         assert(m);
3598         assert(c);
3599         assert(contents);
3600         assert(array_size);
3601         assert(item_size);
3602         assert(offsets);
3603         assert(n_offsets);
3604
3605         if (!signature_is_single(contents, true))
3606                 return -EINVAL;
3607
3608         if (!c->signature || c->signature[c->index] == 0)
3609                 return -ENXIO;
3610
3611         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3612                 return -ENXIO;
3613
3614         if (!startswith(c->signature + c->index + 1, contents))
3615                 return -ENXIO;
3616
3617         rindex = m->rindex;
3618
3619         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3620                 /* dbus1 */
3621
3622                 r = message_peek_body(m, &rindex, 4, 4, &q);
3623                 if (r < 0)
3624                         return r;
3625
3626                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3627                         return -EBADMSG;
3628
3629                 alignment = bus_type_get_alignment(contents[0]);
3630                 if (alignment < 0)
3631                         return alignment;
3632
3633                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3634                 if (r < 0)
3635                         return r;
3636
3637                 *array_size = (uint32_t*) q;
3638
3639         } else if (c->item_size <= 0) {
3640
3641                 /* gvariant: empty array */
3642                 *item_size = 0;
3643                 *offsets = NULL;
3644                 *n_offsets = 0;
3645
3646         } else if (bus_gvariant_is_fixed_size(contents)) {
3647
3648                 /* gvariant: fixed length array */
3649                 *item_size = bus_gvariant_get_size(contents);
3650                 *offsets = NULL;
3651                 *n_offsets = 0;
3652
3653         } else {
3654                 size_t where, p = 0, framing, sz;
3655                 unsigned i;
3656
3657                 /* gvariant: variable length array */
3658                 sz = bus_gvariant_determine_word_size(c->item_size, 0);
3659
3660                 where = rindex + c->item_size - sz;
3661                 r = message_peek_body(m, &where, 1, sz, &q);
3662                 if (r < 0)
3663                         return r;
3664
3665                 framing = bus_gvariant_read_word_le(q, sz);
3666                 if (framing > c->item_size - sz)
3667                         return -EBADMSG;
3668                 if ((c->item_size - framing) % sz != 0)
3669                         return -EBADMSG;
3670
3671                 *n_offsets = (c->item_size - framing) / sz;
3672
3673                 where = rindex + framing;
3674                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3675                 if (r < 0)
3676                         return r;
3677
3678                 *offsets = new(size_t, *n_offsets);
3679                 if (!*offsets)
3680                         return -ENOMEM;
3681
3682                 for (i = 0; i < *n_offsets; i++) {
3683                         size_t x;
3684
3685                         x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
3686                         if (x > c->item_size - sz)
3687                                 return -EBADMSG;
3688                         if (x < p)
3689                                 return -EBADMSG;
3690
3691                         (*offsets)[i] = rindex + x;
3692                         p = x;
3693                 }
3694
3695                 *item_size = (*offsets)[0] - rindex;
3696         }
3697
3698         m->rindex = rindex;
3699
3700         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3701                 c->index += 1 + strlen(contents);
3702
3703         return 1;
3704 }
3705
3706 static int bus_message_enter_variant(
3707                 sd_bus_message *m,
3708                 struct bus_container *c,
3709                 const char *contents,
3710                 size_t *item_size) {
3711
3712         size_t rindex;
3713         uint8_t l;
3714         void *q;
3715         int r;
3716
3717         assert(m);
3718         assert(c);
3719         assert(contents);
3720         assert(item_size);
3721
3722         if (!signature_is_single(contents, false))
3723                 return -EINVAL;
3724
3725         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3726                 return -EINVAL;
3727
3728         if (!c->signature || c->signature[c->index] == 0)
3729                 return -ENXIO;
3730
3731         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3732                 return -ENXIO;
3733
3734         rindex = m->rindex;
3735
3736         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3737                 size_t k, where;
3738
3739                 k = strlen(contents);
3740                 if (1+k > c->item_size)
3741                         return -EBADMSG;
3742
3743                 where = rindex + c->item_size - (1+k);
3744                 r = message_peek_body(m, &where, 1, 1+k, &q);
3745                 if (r < 0)
3746                         return r;
3747
3748                 if (*(char*) q != 0)
3749                         return -EBADMSG;
3750
3751                 if (memcmp((uint8_t*) q+1, contents, k))
3752                         return -ENXIO;
3753
3754                 *item_size = c->item_size - (1+k);
3755
3756         } else {
3757                 r = message_peek_body(m, &rindex, 1, 1, &q);
3758                 if (r < 0)
3759                         return r;
3760
3761                 l = *(uint8_t*) q;
3762                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3763                 if (r < 0)
3764                         return r;
3765
3766                 if (!validate_signature(q, l))
3767                         return -EBADMSG;
3768
3769                 if (!streq(q, contents))
3770                         return -ENXIO;
3771         }
3772
3773         m->rindex = rindex;
3774
3775         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3776                 c->index++;
3777
3778         return 1;
3779 }
3780
3781 static int build_struct_offsets(
3782                 sd_bus_message *m,
3783                 const char *signature,
3784                 size_t size,
3785                 size_t *item_size,
3786                 size_t **offsets,
3787                 size_t *n_offsets) {
3788
3789         unsigned n_variable = 0, n_total = 0, v;
3790         size_t previous = 0, where;
3791         const char *p;
3792         size_t sz;
3793         void *q;
3794         int r;
3795
3796         assert(m);
3797         assert(item_size);
3798         assert(offsets);
3799         assert(n_offsets);
3800
3801         if (isempty(signature)) {
3802                 *item_size = 0;
3803                 *offsets = NULL;
3804                 *n_offsets = 0;
3805                 return 0;
3806         }
3807
3808         sz = bus_gvariant_determine_word_size(size, 0);
3809         if (sz <= 0)
3810                 return -EBADMSG;
3811
3812         /* First, loop over signature and count variable elements and
3813          * elements in general. We use this to know how large the
3814          * offset array is at the end of the structure. Note that
3815          * GVariant only stores offsets for all variable size elements
3816          * that are not the last item. */
3817
3818         p = signature;
3819         while (*p != 0) {
3820                 size_t n;
3821
3822                 r = signature_element_length(p, &n);
3823                 if (r < 0)
3824                         return r;
3825                 else {
3826                         char t[n+1];
3827
3828                         memcpy(t, p, n);
3829                         t[n] = 0;
3830
3831                         r = bus_gvariant_is_fixed_size(t);
3832                 }
3833
3834                 if (r < 0)
3835                         return r;
3836                 if (r == 0 && p[n] != 0) /* except the last item */
3837                         n_variable ++;
3838                 n_total++;
3839
3840                 p += n;
3841         }
3842
3843         if (size < n_variable * sz)
3844                 return -EBADMSG;
3845
3846         where = m->rindex + size - (n_variable * sz);
3847         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3848         if (r < 0)
3849                 return r;
3850
3851         v = n_variable;
3852
3853         *offsets = new(size_t, n_total);
3854         if (!*offsets)
3855                 return -ENOMEM;
3856
3857         *n_offsets = 0;
3858
3859         /* Second, loop again and build an offset table */
3860         p = signature;
3861         while (*p != 0) {
3862                 size_t n, offset;
3863                 int k;
3864
3865                 r = signature_element_length(p, &n);
3866                 if (r < 0)
3867                         return r;
3868                 else {
3869                         char t[n+1];
3870
3871                         memcpy(t, p, n);
3872                         t[n] = 0;
3873
3874                         k = bus_gvariant_get_size(t);
3875                         if (k < 0) {
3876                                 size_t x;
3877
3878                                 /* variable size */
3879                                 if (v > 0) {
3880                                         v--;
3881
3882                                         x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
3883                                         if (x >= size)
3884                                                 return -EBADMSG;
3885                                         if (m->rindex + x < previous)
3886                                                 return -EBADMSG;
3887                                 } else
3888                                         /* The last item's end
3889                                          * is determined from
3890                                          * the start of the
3891                                          * offset array */
3892                                         x = size - (n_variable * sz);
3893
3894                                 offset = m->rindex + x;
3895
3896                         } else {
3897                                 size_t align;
3898
3899                                 /* fixed size */
3900                                 align = bus_gvariant_get_alignment(t);
3901                                 assert(align > 0);
3902
3903                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3904                         }
3905                 }
3906
3907                 previous = (*offsets)[(*n_offsets)++] = offset;
3908                 p += n;
3909         }
3910
3911         assert(v == 0);
3912         assert(*n_offsets == n_total);
3913
3914         *item_size = (*offsets)[0] - m->rindex;
3915         return 0;
3916 }
3917
3918 static int enter_struct_or_dict_entry(
3919                 sd_bus_message *m,
3920                 struct bus_container *c,
3921                 const char *contents,
3922                 size_t *item_size,
3923                 size_t **offsets,
3924                 size_t *n_offsets) {
3925
3926         int r;
3927
3928         assert(m);
3929         assert(c);
3930         assert(contents);
3931         assert(item_size);
3932         assert(offsets);
3933         assert(n_offsets);
3934
3935         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3936
3937                 /* dbus1 */
3938                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3939                 if (r < 0)
3940                         return r;
3941
3942         } else if (c->item_size <= 0) {
3943
3944                 /* gvariant empty struct */
3945                 *item_size = 0;
3946                 *offsets = NULL;
3947                 *n_offsets = 0;
3948         } else
3949                 /* gvariant with contents */
3950                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3951
3952         return 0;
3953 }
3954
3955 static int bus_message_enter_struct(
3956                 sd_bus_message *m,
3957                 struct bus_container *c,
3958                 const char *contents,
3959                 size_t *item_size,
3960                 size_t **offsets,
3961                 size_t *n_offsets) {
3962
3963         size_t l;
3964         int r;
3965
3966         assert(m);
3967         assert(c);
3968         assert(contents);
3969         assert(item_size);
3970         assert(offsets);
3971         assert(n_offsets);
3972
3973         if (!signature_is_valid(contents, false))
3974                 return -EINVAL;
3975
3976         if (!c->signature || c->signature[c->index] == 0)
3977                 return -ENXIO;
3978
3979         l = strlen(contents);
3980
3981         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3982             !startswith(c->signature + c->index + 1, contents) ||
3983             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3984                 return -ENXIO;
3985
3986         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3987         if (r < 0)
3988                 return r;
3989
3990         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3991                 c->index += 1 + l + 1;
3992
3993         return 1;
3994 }
3995
3996 static int bus_message_enter_dict_entry(
3997                 sd_bus_message *m,
3998                 struct bus_container *c,
3999                 const char *contents,
4000                 size_t *item_size,
4001                 size_t **offsets,
4002                 size_t *n_offsets) {
4003
4004         size_t l;
4005         int r;
4006
4007         assert(m);
4008         assert(c);
4009         assert(contents);
4010
4011         if (!signature_is_pair(contents))
4012                 return -EINVAL;
4013
4014         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4015                 return -ENXIO;
4016
4017         if (!c->signature || c->signature[c->index] == 0)
4018                 return 0;
4019
4020         l = strlen(contents);
4021
4022         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
4023             !startswith(c->signature + c->index + 1, contents) ||
4024             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
4025                 return -ENXIO;
4026
4027         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
4028         if (r < 0)
4029                 return r;
4030
4031         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4032                 c->index += 1 + l + 1;
4033
4034         return 1;
4035 }
4036
4037 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
4038                                             char type,
4039                                             const char *contents) {
4040         struct bus_container *c, *w;
4041         uint32_t *array_size = NULL;
4042         char *signature;
4043         size_t before;
4044         size_t *offsets = NULL;
4045         size_t n_offsets = 0, item_size = 0;
4046         int r;
4047
4048         assert_return(m, -EINVAL);
4049         assert_return(m->sealed, -EPERM);
4050         assert_return(type != 0 || !contents, -EINVAL);
4051
4052         if (type == 0 || !contents) {
4053                 const char *cc;
4054                 char tt;
4055
4056                 /* Allow entering into anonymous containers */
4057                 r = sd_bus_message_peek_type(m, &tt, &cc);
4058                 if (r < 0)
4059                         return r;
4060
4061                 if (type != 0 && type != tt)
4062                         return -ENXIO;
4063
4064                 if (contents && !streq(contents, cc))
4065                         return -ENXIO;
4066
4067                 type = tt;
4068                 contents = cc;
4069         }
4070
4071         /*
4072          * We enforce a global limit on container depth, that is much
4073          * higher than the 32 structs and 32 arrays the specification
4074          * mandates. This is simpler to implement for us, and we need
4075          * this only to ensure our container array doesn't grow
4076          * without bounds. We are happy to return any data from a
4077          * message as long as the data itself is valid, even if the
4078          * overall message might be not.
4079          *
4080          * Note that the message signature is validated when
4081          * parsing the headers, and that validation does check the
4082          * 32/32 limit.
4083          *
4084          * Note that the specification defines no limits on the depth
4085          * of stacked variants, but we do.
4086          */
4087         if (m->n_containers >= BUS_CONTAINER_DEPTH)
4088                 return -EBADMSG;
4089
4090         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
4091                 return -ENOMEM;
4092
4093         if (message_end_of_signature(m))
4094                 return -ENXIO;
4095
4096         if (message_end_of_array(m, m->rindex))
4097                 return 0;
4098
4099         c = message_get_container(m);
4100
4101         signature = strdup(contents);
4102         if (!signature)
4103                 return -ENOMEM;
4104
4105         c->saved_index = c->index;
4106         before = m->rindex;
4107
4108         if (type == SD_BUS_TYPE_ARRAY)
4109                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
4110         else if (type == SD_BUS_TYPE_VARIANT)
4111                 r = bus_message_enter_variant(m, c, contents, &item_size);
4112         else if (type == SD_BUS_TYPE_STRUCT)
4113                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
4114         else if (type == SD_BUS_TYPE_DICT_ENTRY)
4115                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
4116         else
4117                 r = -EINVAL;
4118
4119         if (r <= 0) {
4120                 free(signature);
4121                 free(offsets);
4122                 return r;
4123         }
4124
4125         /* OK, let's fill it in */
4126         w = m->containers + m->n_containers++;
4127         w->enclosing = type;
4128         w->signature = signature;
4129         w->peeked_signature = NULL;
4130         w->index = 0;
4131
4132         w->before = before;
4133         w->begin = m->rindex;
4134         w->end = m->rindex + c->item_size;
4135
4136         w->array_size = array_size;
4137         w->item_size = item_size;
4138         w->offsets = offsets;
4139         w->n_offsets = n_offsets;
4140         w->offset_index = 0;
4141
4142         return 1;
4143 }
4144
4145 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
4146         struct bus_container *c;
4147         unsigned saved;
4148         int r;
4149
4150         assert_return(m, -EINVAL);
4151         assert_return(m->sealed, -EPERM);
4152         assert_return(m->n_containers > 0, -ENXIO);
4153
4154         c = message_get_container(m);
4155
4156         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
4157                 if (c->signature && c->signature[c->index] != 0)
4158                         return -EBUSY;
4159         }
4160
4161         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4162                 if (m->rindex < c->end)
4163                         return -EBUSY;
4164
4165         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
4166                 uint32_t l;
4167
4168                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4169                 if (c->begin + l != m->rindex)
4170                         return -EBUSY;
4171         }
4172
4173         free(c->signature);
4174         free(c->peeked_signature);
4175         free(c->offsets);
4176         m->n_containers--;
4177
4178         c = message_get_container(m);
4179
4180         saved = c->index;
4181         c->index = c->saved_index;
4182         r = container_next_item(m, c, &m->rindex);
4183         c->index = saved;
4184         if (r < 0)
4185                 return r;
4186
4187         return 1;
4188 }
4189
4190 static void message_quit_container(sd_bus_message *m) {
4191         struct bus_container *c;
4192
4193         assert(m);
4194         assert(m->sealed);
4195         assert(m->n_containers > 0);
4196
4197         c = message_get_container(m);
4198
4199         /* Undo seeks */
4200         assert(m->rindex >= c->before);
4201         m->rindex = c->before;
4202
4203         /* Free container */
4204         free(c->signature);
4205         free(c->offsets);
4206         m->n_containers--;
4207
4208         /* Correct index of new top-level container */
4209         c = message_get_container(m);
4210         c->index = c->saved_index;
4211 }
4212
4213 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4214         struct bus_container *c;
4215         int r;
4216
4217         assert_return(m, -EINVAL);
4218         assert_return(m->sealed, -EPERM);
4219
4220         if (message_end_of_signature(m))
4221                 goto eof;
4222
4223         if (message_end_of_array(m, m->rindex))
4224                 goto eof;
4225
4226         c = message_get_container(m);
4227
4228         if (bus_type_is_basic(c->signature[c->index])) {
4229                 if (contents)
4230                         *contents = NULL;
4231                 if (type)
4232                         *type = c->signature[c->index];
4233                 return 1;
4234         }
4235
4236         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4237
4238                 if (contents) {
4239                         size_t l;
4240                         char *sig;
4241
4242                         r = signature_element_length(c->signature+c->index+1, &l);
4243                         if (r < 0)
4244                                 return r;
4245
4246                         assert(l >= 1);
4247
4248                         sig = strndup(c->signature + c->index + 1, l);
4249                         if (!sig)
4250                                 return -ENOMEM;
4251
4252                         free(c->peeked_signature);
4253                         *contents = c->peeked_signature = sig;
4254                 }
4255
4256                 if (type)
4257                         *type = SD_BUS_TYPE_ARRAY;
4258
4259                 return 1;
4260         }
4261
4262         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4263             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4264
4265                 if (contents) {
4266                         size_t l;
4267                         char *sig;
4268
4269                         r = signature_element_length(c->signature+c->index, &l);
4270                         if (r < 0)
4271                                 return r;
4272
4273                         assert(l >= 2);
4274                         sig = strndup(c->signature + c->index + 1, l - 2);
4275                         if (!sig)
4276                                 return -ENOMEM;
4277
4278                         free(c->peeked_signature);
4279                         *contents = c->peeked_signature = sig;
4280                 }
4281
4282                 if (type)
4283                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4284
4285                 return 1;
4286         }
4287
4288         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4289                 if (contents) {
4290                         void *q;
4291
4292                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4293                                 size_t k;
4294
4295                                 if (c->item_size < 2)
4296                                         return -EBADMSG;
4297
4298                                 /* Look for the NUL delimiter that
4299                                    separates the payload from the
4300                                    signature. Since the body might be
4301                                    in a different part that then the
4302                                    signature we map byte by byte. */
4303
4304                                 for (k = 2; k <= c->item_size; k++) {
4305                                         size_t where;
4306
4307                                         where = m->rindex + c->item_size - k;
4308                                         r = message_peek_body(m, &where, 1, k, &q);
4309                                         if (r < 0)
4310                                                 return r;
4311
4312                                         if (*(char*) q == 0)
4313                                                 break;
4314                                 }
4315
4316                                 if (k > c->item_size)
4317                                         return -EBADMSG;
4318
4319                                 free(c->peeked_signature);
4320                                 c->peeked_signature = strndup((char*) q + 1, k - 1);
4321                                 if (!c->peeked_signature)
4322                                         return -ENOMEM;
4323
4324                                 if (!signature_is_valid(c->peeked_signature, true))
4325                                         return -EBADMSG;
4326
4327                                 *contents = c->peeked_signature;
4328                         } else {
4329                                 size_t rindex, l;
4330
4331                                 rindex = m->rindex;
4332                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4333                                 if (r < 0)
4334                                         return r;
4335
4336                                 l = *(uint8_t*) q;
4337                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4338                                 if (r < 0)
4339                                         return r;
4340
4341                                 if (!validate_signature(q, l))
4342                                         return -EBADMSG;
4343
4344                                 *contents = q;
4345                         }
4346                 }
4347
4348                 if (type)
4349                         *type = SD_BUS_TYPE_VARIANT;
4350
4351                 return 1;
4352         }
4353
4354         return -EINVAL;
4355
4356 eof:
4357         if (type)
4358                 *type = 0;
4359         if (contents)
4360                 *contents = NULL;
4361         return 0;
4362 }
4363
4364 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4365         struct bus_container *c;
4366
4367         assert_return(m, -EINVAL);
4368         assert_return(m->sealed, -EPERM);
4369
4370         if (complete) {
4371                 message_reset_containers(m);
4372                 m->rindex = 0;
4373
4374                 c = message_get_container(m);
4375         } else {
4376                 c = message_get_container(m);
4377
4378                 c->offset_index = 0;
4379                 c->index = 0;
4380                 m->rindex = c->begin;
4381         }
4382
4383         c->offset_index = 0;
4384         c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4385
4386         return !isempty(c->signature);
4387 }
4388
4389 static int message_read_ap(
4390                 sd_bus_message *m,
4391                 const char *types,
4392                 va_list ap) {
4393
4394         unsigned n_array, n_struct;
4395         TypeStack stack[BUS_CONTAINER_DEPTH];
4396         unsigned stack_ptr = 0;
4397         unsigned n_loop = 0;
4398         int r;
4399
4400         assert(m);
4401
4402         if (isempty(types))
4403                 return 0;
4404
4405         /* Ideally, we'd just call ourselves recursively on every
4406          * complex type. However, the state of a va_list that is
4407          * passed to a function is undefined after that function
4408          * returns. This means we need to docode the va_list linearly
4409          * in a single stackframe. We hence implement our own
4410          * home-grown stack in an array. */
4411
4412         n_array = (unsigned) -1; /* length of current array entries */
4413         n_struct = strlen(types); /* length of current struct contents signature */
4414
4415         for (;;) {
4416                 const char *t;
4417
4418                 n_loop++;
4419
4420                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4421                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4422                         if (r < 0)
4423                                 return r;
4424                         if (r == 0)
4425                                 break;
4426
4427                         r = sd_bus_message_exit_container(m);
4428                         if (r < 0)
4429                                 return r;
4430
4431                         continue;
4432                 }
4433
4434                 t = types;
4435                 if (n_array != (unsigned) -1)
4436                         n_array --;
4437                 else {
4438                         types ++;
4439                         n_struct--;
4440                 }
4441
4442                 switch (*t) {
4443
4444                 case SD_BUS_TYPE_BYTE:
4445                 case SD_BUS_TYPE_BOOLEAN:
4446                 case SD_BUS_TYPE_INT16:
4447                 case SD_BUS_TYPE_UINT16:
4448                 case SD_BUS_TYPE_INT32:
4449                 case SD_BUS_TYPE_UINT32:
4450                 case SD_BUS_TYPE_INT64:
4451                 case SD_BUS_TYPE_UINT64:
4452                 case SD_BUS_TYPE_DOUBLE:
4453                 case SD_BUS_TYPE_STRING:
4454                 case SD_BUS_TYPE_OBJECT_PATH:
4455                 case SD_BUS_TYPE_SIGNATURE:
4456                 case SD_BUS_TYPE_UNIX_FD: {
4457                         void *p;
4458
4459                         p = va_arg(ap, void*);
4460                         r = sd_bus_message_read_basic(m, *t, p);
4461                         if (r < 0)
4462                                 return r;
4463                         if (r == 0) {
4464                                 if (n_loop <= 1)
4465                                         return 0;
4466
4467                                 return -ENXIO;
4468                         }
4469
4470                         break;
4471                 }
4472
4473                 case SD_BUS_TYPE_ARRAY: {
4474                         size_t k;
4475
4476                         r = signature_element_length(t + 1, &k);
4477                         if (r < 0)
4478                                 return r;
4479
4480                         {
4481                                 char s[k + 1];
4482                                 memcpy(s, t + 1, k);
4483                                 s[k] = 0;
4484
4485                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4486                                 if (r < 0)
4487                                         return r;
4488                                 if (r == 0) {
4489                                         if (n_loop <= 1)
4490                                                 return 0;
4491
4492                                         return -ENXIO;
4493                                 }
4494                         }
4495
4496                         if (n_array == (unsigned) -1) {
4497                                 types += k;
4498                                 n_struct -= k;
4499                         }
4500
4501                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4502                         if (r < 0)
4503                                 return r;
4504
4505                         types = t + 1;
4506                         n_struct = k;
4507                         n_array = va_arg(ap, unsigned);
4508
4509                         break;
4510                 }
4511
4512                 case SD_BUS_TYPE_VARIANT: {
4513                         const char *s;
4514
4515                         s = va_arg(ap, const char *);
4516                         if (!s)
4517                                 return -EINVAL;
4518
4519                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4520                         if (r < 0)
4521                                 return r;
4522                         if (r == 0) {
4523                                 if (n_loop <= 1)
4524                                         return 0;
4525
4526                                 return -ENXIO;
4527                         }
4528
4529                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4530                         if (r < 0)
4531                                 return r;
4532
4533                         types = s;
4534                         n_struct = strlen(s);
4535                         n_array = (unsigned) -1;
4536
4537                         break;
4538                 }
4539
4540                 case SD_BUS_TYPE_STRUCT_BEGIN:
4541                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4542                         size_t k;
4543
4544                         r = signature_element_length(t, &k);
4545                         if (r < 0)
4546                                 return r;
4547
4548                         {
4549                                 char s[k - 1];
4550                                 memcpy(s, t + 1, k - 2);
4551                                 s[k - 2] = 0;
4552
4553                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4554                                 if (r < 0)
4555                                         return r;
4556                                 if (r == 0) {
4557                                         if (n_loop <= 1)
4558                                                 return 0;
4559                                         return -ENXIO;
4560                                 }
4561                         }
4562
4563                         if (n_array == (unsigned) -1) {
4564                                 types += k - 1;
4565                                 n_struct -= k - 1;
4566                         }
4567
4568                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4569                         if (r < 0)
4570                                 return r;
4571
4572                         types = t + 1;
4573                         n_struct = k - 2;
4574                         n_array = (unsigned) -1;
4575
4576                         break;
4577                 }
4578
4579                 default:
4580                         return -EINVAL;
4581                 }
4582         }
4583
4584         return 1;
4585 }
4586
4587 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4588         va_list ap;
4589         int r;
4590
4591         assert_return(m, -EINVAL);
4592         assert_return(m->sealed, -EPERM);
4593         assert_return(types, -EINVAL);
4594
4595         va_start(ap, types);
4596         r = message_read_ap(m, types, ap);
4597         va_end(ap);
4598
4599         return r;
4600 }
4601
4602 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4603         int r;
4604
4605         assert_return(m, -EINVAL);
4606         assert_return(m->sealed, -EPERM);
4607
4608         /* If types is NULL, read exactly one element */
4609         if (!types) {
4610                 struct bus_container *c;
4611                 size_t l;
4612
4613                 if (message_end_of_signature(m))
4614                         return -ENXIO;
4615
4616                 if (message_end_of_array(m, m->rindex))
4617                         return 0;
4618
4619                 c = message_get_container(m);
4620
4621                 r = signature_element_length(c->signature + c->index, &l);
4622                 if (r < 0)
4623                         return r;
4624
4625                 types = strndupa(c->signature + c->index, l);
4626         }
4627
4628         switch (*types) {
4629
4630         case 0: /* Nothing to drop */
4631                 return 0;
4632
4633         case SD_BUS_TYPE_BYTE:
4634         case SD_BUS_TYPE_BOOLEAN:
4635         case SD_BUS_TYPE_INT16:
4636         case SD_BUS_TYPE_UINT16:
4637         case SD_BUS_TYPE_INT32:
4638         case SD_BUS_TYPE_UINT32:
4639         case SD_BUS_TYPE_INT64:
4640         case SD_BUS_TYPE_UINT64:
4641         case SD_BUS_TYPE_DOUBLE:
4642         case SD_BUS_TYPE_STRING:
4643         case SD_BUS_TYPE_OBJECT_PATH:
4644         case SD_BUS_TYPE_SIGNATURE:
4645         case SD_BUS_TYPE_UNIX_FD:
4646
4647                 r = sd_bus_message_read_basic(m, *types, NULL);
4648                 if (r <= 0)
4649                         return r;
4650
4651                 r = sd_bus_message_skip(m, types + 1);
4652                 if (r < 0)
4653                         return r;
4654
4655                 return 1;
4656
4657         case SD_BUS_TYPE_ARRAY: {
4658                 size_t k;
4659
4660                 r = signature_element_length(types + 1, &k);
4661                 if (r < 0)
4662                         return r;
4663
4664                 {
4665                         char s[k+1];
4666                         memcpy(s, types+1, k);
4667                         s[k] = 0;
4668
4669                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4670                         if (r <= 0)
4671                                 return r;
4672
4673                         for (;;) {
4674                                 r = sd_bus_message_skip(m, s);
4675                                 if (r < 0)
4676                                         return r;
4677                                 if (r == 0)
4678                                         break;
4679                         }
4680
4681                         r = sd_bus_message_exit_container(m);
4682                         if (r < 0)
4683                                 return r;
4684                 }
4685
4686                 r = sd_bus_message_skip(m, types + 1 + k);
4687                 if (r < 0)
4688                         return r;
4689
4690                 return 1;
4691         }
4692
4693         case SD_BUS_TYPE_VARIANT: {
4694                 const char *contents;
4695                 char x;
4696
4697                 r = sd_bus_message_peek_type(m, &x, &contents);
4698                 if (r <= 0)
4699                         return r;
4700
4701                 if (x != SD_BUS_TYPE_VARIANT)
4702                         return -ENXIO;
4703
4704                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4705                 if (r <= 0)
4706                         return r;
4707
4708                 r = sd_bus_message_skip(m, contents);
4709                 if (r < 0)
4710                         return r;
4711                 assert(r != 0);
4712
4713                 r = sd_bus_message_exit_container(m);
4714                 if (r < 0)
4715                         return r;
4716
4717                 r = sd_bus_message_skip(m, types + 1);
4718                 if (r < 0)
4719                         return r;
4720
4721                 return 1;
4722         }
4723
4724         case SD_BUS_TYPE_STRUCT_BEGIN:
4725         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4726                 size_t k;
4727
4728                 r = signature_element_length(types, &k);
4729                 if (r < 0)
4730                         return r;
4731
4732                 {
4733                         char s[k-1];
4734                         memcpy(s, types+1, k-2);
4735                         s[k-2] = 0;
4736
4737                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4738                         if (r <= 0)
4739                                 return r;
4740
4741                         r = sd_bus_message_skip(m, s);
4742                         if (r < 0)
4743                                 return r;
4744                         assert(r != 0);
4745
4746                         r = sd_bus_message_exit_container(m);
4747                         if (r < 0)
4748                                 return r;
4749                 }
4750
4751                 r = sd_bus_message_skip(m, types + k);
4752                 if (r < 0)
4753                         return r;
4754
4755                 return 1;
4756         }
4757
4758         default:
4759                 return -EINVAL;
4760         }
4761 }
4762
4763 _public_ int sd_bus_message_read_array(
4764                 sd_bus_message *m,
4765                 char type,
4766                 const void **ptr,
4767                 size_t *size) {
4768
4769         struct bus_container *c;
4770         void *p;
4771         size_t sz;
4772         ssize_t align;
4773         int r;
4774
4775         assert_return(m, -EINVAL);
4776         assert_return(m->sealed, -EPERM);
4777         assert_return(bus_type_is_trivial(type), -EINVAL);
4778         assert_return(ptr, -EINVAL);
4779         assert_return(size, -EINVAL);
4780         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -EOPNOTSUPP);
4781
4782         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4783         if (r <= 0)
4784                 return r;
4785
4786         c = message_get_container(m);
4787
4788         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4789                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4790                 if (align < 0)
4791                         return align;
4792
4793                 sz = c->end - c->begin;
4794         } else {
4795                 align = bus_type_get_alignment(type);
4796                 if (align < 0)
4797                         return align;
4798
4799                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4800         }
4801
4802         if (sz == 0)
4803                 /* Zero length array, let's return some aligned
4804                  * pointer that is not NULL */
4805                 p = (uint8_t*) NULL + align;
4806         else {
4807                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4808                 if (r < 0)
4809                         goto fail;
4810         }
4811
4812         r = sd_bus_message_exit_container(m);
4813         if (r < 0)
4814                 goto fail;
4815
4816         *ptr = (const void*) p;
4817         *size = sz;
4818
4819         return 1;
4820
4821 fail:
4822         message_quit_container(m);
4823         return r;
4824 }
4825
4826 static int message_peek_fields(
4827                 sd_bus_message *m,
4828                 size_t *rindex,
4829                 size_t align,
4830                 size_t nbytes,
4831                 void **ret) {
4832
4833         assert(m);
4834         assert(rindex);
4835         assert(align > 0);
4836
4837         return buffer_peek(BUS_MESSAGE_FIELDS(m), m->fields_size, rindex, align, nbytes, ret);
4838 }
4839
4840 static int message_peek_field_uint32(
4841                 sd_bus_message *m,
4842                 size_t *ri,
4843                 size_t item_size,
4844                 uint32_t *ret) {
4845
4846         int r;
4847         void *q;
4848
4849         assert(m);
4850         assert(ri);
4851
4852         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4853                 return -EBADMSG;
4854
4855         /* identical for gvariant and dbus1 */
4856
4857         r = message_peek_fields(m, ri, 4, 4, &q);
4858         if (r < 0)
4859                 return r;
4860
4861         if (ret)
4862                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4863
4864         return 0;
4865 }
4866
4867 static int message_peek_field_uint64(
4868                 sd_bus_message *m,
4869                 size_t *ri,
4870                 size_t item_size,
4871                 uint64_t *ret) {
4872
4873         int r;
4874         void *q;
4875
4876         assert(m);
4877         assert(ri);
4878
4879         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 8)
4880                 return -EBADMSG;
4881
4882         /* identical for gvariant and dbus1 */
4883
4884         r = message_peek_fields(m, ri, 8, 8, &q);
4885         if (r < 0)
4886                 return r;
4887
4888         if (ret)
4889                 *ret = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
4890
4891         return 0;
4892 }
4893
4894 static int message_peek_field_string(
4895                 sd_bus_message *m,
4896                 bool (*validate)(const char *p),
4897                 size_t *ri,
4898                 size_t item_size,
4899                 const char **ret) {
4900
4901         uint32_t l;
4902         int r;
4903         void *q;
4904
4905         assert(m);
4906         assert(ri);
4907
4908         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4909
4910                 if (item_size <= 0)
4911                         return -EBADMSG;
4912
4913                 r = message_peek_fields(m, ri, 1, item_size, &q);
4914                 if (r < 0)
4915                         return r;
4916
4917                 l = item_size - 1;
4918         } else {
4919                 r = message_peek_field_uint32(m, ri, 4, &l);
4920                 if (r < 0)
4921                         return r;
4922
4923                 r = message_peek_fields(m, ri, 1, l+1, &q);
4924                 if (r < 0)
4925                         return r;
4926         }
4927
4928         if (validate) {
4929                 if (!validate_nul(q, l))
4930                         return -EBADMSG;
4931
4932                 if (!validate(q))
4933                         return -EBADMSG;
4934         } else {
4935                 if (!validate_string(q, l))
4936                         return -EBADMSG;
4937         }
4938
4939         if (ret)
4940                 *ret = q;
4941
4942         return 0;
4943 }
4944
4945 static int message_peek_field_signature(
4946                 sd_bus_message *m,
4947                 size_t *ri,
4948                 size_t item_size,
4949                 const char **ret) {
4950
4951         size_t l;
4952         int r;
4953         void *q;
4954
4955         assert(m);
4956         assert(ri);
4957
4958         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4959
4960                 if (item_size <= 0)
4961                         return -EBADMSG;
4962
4963                 r = message_peek_fields(m, ri, 1, item_size, &q);
4964                 if (r < 0)
4965                         return r;
4966
4967                 l = item_size - 1;
4968         } else {
4969                 r = message_peek_fields(m, ri, 1, 1, &q);
4970                 if (r < 0)
4971                         return r;
4972
4973                 l = *(uint8_t*) q;
4974                 r = message_peek_fields(m, ri, 1, l+1, &q);
4975                 if (r < 0)
4976                         return r;
4977         }
4978
4979         if (!validate_signature(q, l))
4980                 return -EBADMSG;
4981
4982         if (ret)
4983                 *ret = q;
4984
4985         return 0;
4986 }
4987
4988 static int message_skip_fields(
4989                 sd_bus_message *m,
4990                 size_t *ri,
4991                 uint32_t array_size,
4992                 const char **signature) {
4993
4994         size_t original_index;
4995         int r;
4996
4997         assert(m);
4998         assert(ri);
4999         assert(signature);
5000         assert(!BUS_MESSAGE_IS_GVARIANT(m));
5001
5002         original_index = *ri;
5003
5004         for (;;) {
5005                 char t;
5006                 size_t l;
5007
5008                 if (array_size != (uint32_t) -1 &&
5009                     array_size <= *ri - original_index)
5010                         return 0;
5011
5012                 t = **signature;
5013                 if (!t)
5014                         return 0;
5015
5016                 if (t == SD_BUS_TYPE_STRING) {
5017
5018                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
5019                         if (r < 0)
5020                                 return r;
5021
5022                         (*signature)++;
5023
5024                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
5025
5026                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
5027                         if (r < 0)
5028                                 return r;
5029
5030                         (*signature)++;
5031
5032                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
5033
5034                         r = message_peek_field_signature(m, ri, 0, NULL);
5035                         if (r < 0)
5036                                 return r;
5037
5038                         (*signature)++;
5039
5040                 } else if (bus_type_is_basic(t)) {
5041                         ssize_t align, k;
5042
5043                         align = bus_type_get_alignment(t);
5044                         k = bus_type_get_size(t);
5045                         assert(align > 0 && k > 0);
5046
5047                         r = message_peek_fields(m, ri, align, k, NULL);
5048                         if (r < 0)
5049                                 return r;
5050
5051                         (*signature)++;
5052
5053                 } else if (t == SD_BUS_TYPE_ARRAY) {
5054
5055                         r = signature_element_length(*signature+1, &l);
5056                         if (r < 0)
5057                                 return r;
5058
5059                         assert(l >= 1);
5060                         {
5061                                 char sig[l-1], *s;
5062                                 uint32_t nas;
5063                                 int alignment;
5064
5065                                 strncpy(sig, *signature + 1, l-1);
5066                                 s = sig;
5067
5068                                 alignment = bus_type_get_alignment(sig[0]);
5069                                 if (alignment < 0)
5070                                         return alignment;
5071
5072                                 r = message_peek_field_uint32(m, ri, 0, &nas);
5073                                 if (r < 0)
5074                                         return r;
5075                                 if (nas > BUS_ARRAY_MAX_SIZE)
5076                                         return -EBADMSG;
5077
5078                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
5079                                 if (r < 0)
5080                                         return r;
5081
5082                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
5083                                 if (r < 0)
5084                                         return r;
5085                         }
5086
5087                         (*signature) += 1 + l;
5088
5089                 } else if (t == SD_BUS_TYPE_VARIANT) {
5090                         const char *s;
5091
5092                         r = message_peek_field_signature(m, ri, 0, &s);
5093                         if (r < 0)
5094                                 return r;
5095
5096                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5097                         if (r < 0)
5098                                 return r;
5099
5100                         (*signature)++;
5101
5102                 } else if (t == SD_BUS_TYPE_STRUCT ||
5103                            t == SD_BUS_TYPE_DICT_ENTRY) {
5104
5105                         r = signature_element_length(*signature, &l);
5106                         if (r < 0)
5107                                 return r;
5108
5109                         assert(l >= 2);
5110                         {
5111                                 char sig[l-1], *s;
5112                                 strncpy(sig, *signature + 1, l-1);
5113                                 s = sig;
5114
5115                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5116                                 if (r < 0)
5117                                         return r;
5118                         }
5119
5120                         *signature += l;
5121                 } else
5122                         return -EINVAL;
5123         }
5124 }
5125
5126 int bus_message_parse_fields(sd_bus_message *m) {
5127         size_t ri;
5128         int r;
5129         uint32_t unix_fds = 0;
5130         bool unix_fds_set = false;
5131         void *offsets = NULL;
5132         unsigned n_offsets = 0;
5133         size_t sz = 0;
5134         unsigned i = 0;
5135
5136         assert(m);
5137
5138         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5139                 char *p;
5140
5141                 /* Read the signature from the end of the body variant first */
5142                 sz = bus_gvariant_determine_word_size(BUS_MESSAGE_SIZE(m), 0);
5143                 if (m->footer_accessible < 1 + sz)
5144                         return -EBADMSG;
5145
5146                 p = (char*) m->footer + m->footer_accessible - (1 + sz);
5147                 for (;;) {
5148                         if (p < (char*) m->footer)
5149                                 return -EBADMSG;
5150
5151                         if (*p == 0) {
5152                                 char *c;
5153
5154                                 /* We found the beginning of the signature string, yay! */
5155
5156                                 c = strndup(p + 1, ((char*) m->footer + m->footer_accessible) - p - (1 + sz));
5157                                 if (!c)
5158                                         return -ENOMEM;
5159
5160                                 free(m->root_container.signature);
5161                                 m->root_container.signature = c;
5162                                 break;
5163                         }
5164
5165                         p--;
5166                 }
5167
5168                 /* Calculate the actual user body size, by removing
5169                  * the trailing variant signature and struct offset
5170                  * table */
5171                 m->user_body_size = m->body_size - ((char*) m->footer + m->footer_accessible - p);
5172
5173                 /* Pull out the offset table for the fields array */
5174                 sz = bus_gvariant_determine_word_size(m->fields_size, 0);
5175                 if (sz > 0) {
5176                         size_t framing;
5177                         void *q;
5178
5179                         ri = m->fields_size - sz;
5180                         r = message_peek_fields(m, &ri, 1, sz, &q);
5181                         if (r < 0)
5182                                 return r;
5183
5184                         framing = bus_gvariant_read_word_le(q, sz);
5185                         if (framing >= m->fields_size - sz)
5186                                 return -EBADMSG;
5187                         if ((m->fields_size - framing) % sz != 0)
5188                                 return -EBADMSG;
5189
5190                         ri = framing;
5191                         r = message_peek_fields(m, &ri, 1, m->fields_size - framing, &offsets);
5192                         if (r < 0)
5193                                 return r;
5194
5195                         n_offsets = (m->fields_size - framing) / sz;
5196                 }
5197         } else
5198                 m->user_body_size = m->body_size;
5199
5200         ri = 0;
5201         while (ri < m->fields_size) {
5202                 _cleanup_free_ char *sig = NULL;
5203                 const char *signature;
5204                 uint64_t field_type;
5205                 size_t item_size = (size_t) -1;
5206
5207                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5208                         uint64_t *u64;
5209
5210                         if (i >= n_offsets)
5211                                 break;
5212
5213                         if (i == 0)
5214                                 ri = 0;
5215                         else
5216                                 ri = ALIGN_TO(bus_gvariant_read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
5217
5218                         r = message_peek_fields(m, &ri, 8, 8, (void**) &u64);
5219                         if (r < 0)
5220                                 return r;
5221
5222                         field_type = BUS_MESSAGE_BSWAP64(m, *u64);
5223                 } else {
5224                         uint8_t *u8;
5225
5226                         r = message_peek_fields(m, &ri, 8, 1, (void**) &u8);
5227                         if (r < 0)
5228                                 return r;
5229
5230                         field_type = *u8;
5231                 }
5232
5233                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5234                         size_t where, end;
5235                         char *b;
5236                         void *q;
5237
5238                         end = bus_gvariant_read_word_le((uint8_t*) offsets + i*sz, sz);
5239
5240                         if (end < ri)
5241                                 return -EBADMSG;
5242
5243                         where = ri = ALIGN_TO(ri, 8);
5244                         item_size = end - ri;
5245                         r = message_peek_fields(m, &where, 1, item_size, &q);
5246                         if (r < 0)
5247                                 return r;
5248
5249                         b = memrchr(q, 0, item_size);
5250                         if (!b)
5251                                 return -EBADMSG;
5252
5253                         sig = strndup(b+1, item_size - (b+1-(char*) q));
5254                         if (!sig)
5255                                 return -ENOMEM;
5256
5257                         signature = sig;
5258                         item_size = b - (char*) q;
5259                 } else {
5260                         r = message_peek_field_signature(m, &ri, 0, &signature);
5261                         if (r < 0)
5262                                 return r;
5263                 }
5264
5265                 switch (field_type) {
5266
5267                 case _BUS_MESSAGE_HEADER_INVALID:
5268                         return -EBADMSG;
5269
5270                 case BUS_MESSAGE_HEADER_PATH:
5271
5272                         if (m->path)
5273                                 return -EBADMSG;
5274
5275                         if (!streq(signature, "o"))
5276                                 return -EBADMSG;
5277
5278                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
5279                         break;
5280
5281                 case BUS_MESSAGE_HEADER_INTERFACE:
5282
5283                         if (m->interface)
5284                                 return -EBADMSG;
5285
5286                         if (!streq(signature, "s"))
5287                                 return -EBADMSG;
5288
5289                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5290                         break;
5291
5292                 case BUS_MESSAGE_HEADER_MEMBER:
5293
5294                         if (m->member)
5295                                 return -EBADMSG;
5296
5297                         if (!streq(signature, "s"))
5298                                 return -EBADMSG;
5299
5300                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5301                         break;
5302
5303                 case BUS_MESSAGE_HEADER_ERROR_NAME:
5304
5305                         if (m->error.name)
5306                                 return -EBADMSG;
5307
5308                         if (!streq(signature, "s"))
5309                                 return -EBADMSG;
5310
5311                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5312                         if (r >= 0)
5313                                 m->error._need_free = -1;
5314
5315                         break;
5316
5317                 case BUS_MESSAGE_HEADER_DESTINATION:
5318
5319                         if (m->destination)
5320                                 return -EBADMSG;
5321
5322                         if (!streq(signature, "s"))
5323                                 return -EBADMSG;
5324
5325                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5326                         break;
5327
5328                 case BUS_MESSAGE_HEADER_SENDER:
5329
5330                         if (m->sender)
5331                                 return -EBADMSG;
5332
5333                         if (!streq(signature, "s"))
5334                                 return -EBADMSG;
5335
5336                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5337
5338                         if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5339                                 m->creds.unique_name = (char*) m->sender;
5340                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5341                         }
5342
5343                         break;
5344
5345
5346                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5347                         const char *s;
5348                         char *c;
5349
5350                         if (BUS_MESSAGE_IS_GVARIANT(m)) /* only applies to dbus1 */
5351                                 return -EBADMSG;
5352
5353                         if (m->root_container.signature)
5354                                 return -EBADMSG;
5355
5356                         if (!streq(signature, "g"))
5357                                 return -EBADMSG;
5358
5359                         r = message_peek_field_signature(m, &ri, item_size, &s);
5360                         if (r < 0)
5361                                 return r;
5362
5363                         c = strdup(s);
5364                         if (!c)
5365                                 return -ENOMEM;
5366
5367                         free(m->root_container.signature);
5368                         m->root_container.signature = c;
5369                         break;
5370                 }
5371
5372                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5373
5374                         if (m->reply_cookie != 0)
5375                                 return -EBADMSG;
5376
5377                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5378                                 /* 64bit on dbus2 */
5379
5380                                 if (!streq(signature, "t"))
5381                                         return -EBADMSG;
5382
5383                                 r = message_peek_field_uint64(m, &ri, item_size, &m->reply_cookie);
5384                                 if (r < 0)
5385                                         return r;
5386                         } else {
5387                                 /* 32bit on dbus1 */
5388                                 uint32_t serial;
5389
5390                                 if (!streq(signature, "u"))
5391                                         return -EBADMSG;
5392
5393                                 r = message_peek_field_uint32(m, &ri, item_size, &serial);
5394                                 if (r < 0)
5395                                         return r;
5396
5397                                 m->reply_cookie = serial;
5398                         }
5399
5400                         if (m->reply_cookie == 0)
5401                                 return -EBADMSG;
5402
5403                         break;
5404
5405                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5406                         if (unix_fds_set)
5407                                 return -EBADMSG;
5408
5409                         if (!streq(signature, "u"))
5410                                 return -EBADMSG;
5411
5412                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5413                         if (r < 0)
5414                                 return -EBADMSG;
5415
5416                         unix_fds_set = true;
5417                         break;
5418
5419                 default:
5420                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5421                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5422                 }
5423
5424                 if (r < 0)
5425                         return r;
5426
5427                 i++;
5428         }
5429
5430         if (m->n_fds != unix_fds)
5431                 return -EBADMSG;
5432
5433         switch (m->header->type) {
5434
5435         case SD_BUS_MESSAGE_SIGNAL:
5436                 if (!m->path || !m->interface || !m->member)
5437                         return -EBADMSG;
5438
5439                 if (m->reply_cookie != 0)
5440                         return -EBADMSG;
5441
5442                 break;
5443
5444         case SD_BUS_MESSAGE_METHOD_CALL:
5445
5446                 if (!m->path || !m->member)
5447                         return -EBADMSG;
5448
5449                 if (m->reply_cookie != 0)
5450                         return -EBADMSG;
5451
5452                 break;
5453
5454         case SD_BUS_MESSAGE_METHOD_RETURN:
5455
5456                 if (m->reply_cookie == 0)
5457                         return -EBADMSG;
5458                 break;
5459
5460         case SD_BUS_MESSAGE_METHOD_ERROR:
5461
5462                 if (m->reply_cookie == 0 || !m->error.name)
5463                         return -EBADMSG;
5464                 break;
5465         }
5466
5467         /* Refuse non-local messages that claim they are local */
5468         if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5469                 return -EBADMSG;
5470         if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5471                 return -EBADMSG;
5472         if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5473                 return -EBADMSG;
5474
5475         m->root_container.end = m->user_body_size;
5476
5477         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5478                 r = build_struct_offsets(
5479                                 m,
5480                                 m->root_container.signature,
5481                                 m->user_body_size,
5482                                 &m->root_container.item_size,
5483                                 &m->root_container.offsets,
5484                                 &m->root_container.n_offsets);
5485                 if (r < 0)
5486                         return r;
5487         }
5488
5489         /* Try to read the error message, but if we can't it's a non-issue */
5490         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5491                 (void) sd_bus_message_read(m, "s", &m->error.message);
5492
5493         return 0;
5494 }
5495
5496 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5497         assert_return(m, -EINVAL);
5498         assert_return(destination, -EINVAL);
5499         assert_return(!m->sealed, -EPERM);
5500         assert_return(!m->destination, -EEXIST);
5501
5502         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5503 }
5504
5505 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5506         size_t total;
5507         void *p, *e;
5508         unsigned i;
5509         struct bus_body_part *part;
5510
5511         assert(m);
5512         assert(buffer);
5513         assert(sz);
5514
5515         total = BUS_MESSAGE_SIZE(m);
5516
5517         p = malloc(total);
5518         if (!p)
5519                 return -ENOMEM;
5520
5521         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5522         MESSAGE_FOREACH_PART(part, i, m)
5523                 e = mempcpy(e, part->data, part->size);
5524
5525         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5526
5527         *buffer = p;
5528         *sz = total;
5529
5530         return 0;
5531 }
5532
5533 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5534         const char *s;
5535         int r;
5536
5537         assert(m);
5538         assert(l);
5539
5540         r = sd_bus_message_enter_container(m, 'a', "s");
5541         if (r <= 0)
5542                 return r;
5543
5544         while ((r = sd_bus_message_read_basic(m, 's', &s)) > 0) {
5545                 r = strv_extend(l, s);
5546                 if (r < 0)
5547                         return r;
5548         }
5549         if (r < 0)
5550                 return r;
5551
5552         r = sd_bus_message_exit_container(m);
5553         if (r < 0)
5554                 return r;
5555
5556         return 1;
5557 }
5558
5559 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5560         char **strv = NULL;
5561         int r;
5562
5563         assert_return(m, -EINVAL);
5564         assert_return(m->sealed, -EPERM);
5565         assert_return(l, -EINVAL);
5566
5567         r = bus_message_read_strv_extend(m, &strv);
5568         if (r <= 0) {
5569                 strv_free(strv);
5570                 return r;
5571         }
5572
5573         *l = strv;
5574         return 1;
5575 }
5576
5577 int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv) {
5578         const char *contents;
5579         unsigned j;
5580         char type;
5581         int r;
5582
5583         assert(m);
5584         assert(str);
5585         assert(strv);
5586
5587         r = sd_bus_message_rewind(m, true);
5588         if (r < 0)
5589                 return r;
5590
5591         for (j = 0;; j++) {
5592                 r = sd_bus_message_peek_type(m, &type, &contents);
5593                 if (r < 0)
5594                         return r;
5595                 if (r == 0)
5596                         return -ENXIO;
5597
5598                 /* Don't match against arguments after the first one we don't understand */
5599                 if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE) &&
5600                     !(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
5601                         return -ENXIO;
5602
5603                 if (j >= i)
5604                         break;
5605
5606                 r = sd_bus_message_skip(m, NULL);
5607                 if (r < 0)
5608                         return r;
5609         }
5610
5611         if (type == SD_BUS_TYPE_ARRAY) {
5612
5613                 r = sd_bus_message_read_strv(m, strv);
5614                 if (r < 0)
5615                         return r;
5616
5617                 *str = NULL;
5618
5619         } else {
5620                 r = sd_bus_message_read_basic(m, type, str);
5621                 if (r < 0)
5622                         return r;
5623
5624                 *strv = NULL;
5625         }
5626
5627         return 0;
5628 }
5629
5630 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5631         assert_return(m, EINVAL);
5632
5633         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5634                 return 0;
5635
5636         return sd_bus_error_get_errno(&m->error);
5637 }
5638
5639 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5640         struct bus_container *c;
5641
5642         assert_return(m, NULL);
5643
5644         c = complete ? &m->root_container : message_get_container(m);
5645         return strempty(c->signature);
5646 }
5647
5648 _public_ int sd_bus_message_is_empty(sd_bus_message *m) {
5649         assert_return(m, -EINVAL);
5650
5651         return isempty(m->root_container.signature);
5652 }
5653
5654 _public_ int sd_bus_message_has_signature(sd_bus_message *m, const char *signature) {
5655         assert_return(m, -EINVAL);
5656
5657         return streq(strempty(m->root_container.signature), strempty(signature));
5658 }
5659
5660 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5661         bool done_something = false;
5662         int r;
5663
5664         assert_return(m, -EINVAL);
5665         assert_return(source, -EINVAL);
5666         assert_return(!m->sealed, -EPERM);
5667         assert_return(source->sealed, -EPERM);
5668
5669         do {
5670                 const char *contents;
5671                 char type;
5672                 union {
5673                         uint8_t u8;
5674                         uint16_t u16;
5675                         int16_t s16;
5676                         uint32_t u32;
5677                         int32_t s32;
5678                         uint64_t u64;
5679                         int64_t s64;
5680                         double d64;
5681                         const char *string;
5682                         int i;
5683                 } basic;
5684
5685                 r = sd_bus_message_peek_type(source, &type, &contents);
5686                 if (r < 0)
5687                         return r;
5688                 if (r == 0)
5689                         break;
5690
5691                 done_something = true;
5692
5693                 if (bus_type_is_container(type) > 0) {
5694
5695                         r = sd_bus_message_enter_container(source, type, contents);
5696                         if (r < 0)
5697                                 return r;
5698
5699                         r = sd_bus_message_open_container(m, type, contents);
5700                         if (r < 0)
5701                                 return r;
5702
5703                         r = sd_bus_message_copy(m, source, true);
5704                         if (r < 0)
5705                                 return r;
5706
5707                         r = sd_bus_message_close_container(m);
5708                         if (r < 0)
5709                                 return r;
5710
5711                         r = sd_bus_message_exit_container(source);
5712                         if (r < 0)
5713                                 return r;
5714
5715                         continue;
5716                 }
5717
5718                 r = sd_bus_message_read_basic(source, type, &basic);
5719                 if (r < 0)
5720                         return r;
5721
5722                 assert(r > 0);
5723
5724                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5725                     type == SD_BUS_TYPE_SIGNATURE ||
5726                     type == SD_BUS_TYPE_STRING)
5727                         r = sd_bus_message_append_basic(m, type, basic.string);
5728                 else
5729                         r = sd_bus_message_append_basic(m, type, &basic);
5730
5731                 if (r < 0)
5732                         return r;
5733
5734         } while (all);
5735
5736         return done_something;
5737 }
5738
5739 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5740         const char *c;
5741         char t;
5742         int r;
5743
5744         assert_return(m, -EINVAL);
5745         assert_return(m->sealed, -EPERM);
5746         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5747         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5748         assert_return(type || contents, -EINVAL);
5749         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5750
5751         r = sd_bus_message_peek_type(m, &t, &c);
5752         if (r <= 0)
5753                 return r;
5754
5755         if (type != 0 && type != t)
5756                 return 0;
5757
5758         if (contents && !streq_ptr(contents, c))
5759                 return 0;
5760
5761         return 1;
5762 }
5763
5764 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5765         assert_return(m, NULL);
5766
5767         return m->bus;
5768 }
5769
5770 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5771         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5772         usec_t timeout;
5773         int r;
5774
5775         assert(bus);
5776         assert(m);
5777         assert(*m);
5778
5779         switch ((*m)->header->type) {
5780
5781         case SD_BUS_MESSAGE_SIGNAL:
5782                 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5783                 if (r < 0)
5784                         return r;
5785
5786                 break;
5787
5788         case SD_BUS_MESSAGE_METHOD_CALL:
5789                 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5790                 if (r < 0)
5791                         return r;
5792
5793                 break;
5794
5795         case SD_BUS_MESSAGE_METHOD_RETURN:
5796         case SD_BUS_MESSAGE_METHOD_ERROR:
5797
5798                 n = message_new(bus, (*m)->header->type);
5799                 if (!n)
5800                         return -ENOMEM;
5801
5802                 n->reply_cookie = (*m)->reply_cookie;
5803
5804                 r = message_append_reply_cookie(n, n->reply_cookie);
5805                 if (r < 0)
5806                         return r;
5807
5808                 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5809                         r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5810                         if (r < 0)
5811                                 return r;
5812
5813                         n->error._need_free = -1;
5814                 }
5815
5816                 break;
5817
5818         default:
5819                 return -EINVAL;
5820         }
5821
5822         if ((*m)->destination && !n->destination) {
5823                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5824                 if (r < 0)
5825                         return r;
5826         }
5827
5828         if ((*m)->sender && !n->sender) {
5829                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5830                 if (r < 0)
5831                         return r;
5832         }
5833
5834         n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5835
5836         r = sd_bus_message_copy(n, *m, true);
5837         if (r < 0)
5838                 return r;
5839
5840         timeout = (*m)->timeout;
5841         if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5842                 timeout = BUS_DEFAULT_TIMEOUT;
5843
5844         r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5845         if (r < 0)
5846                 return r;
5847
5848         sd_bus_message_unref(*m);
5849         *m = n;
5850         n = NULL;
5851
5852         return 0;
5853 }
5854
5855 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5856         assert(m);
5857         assert(sender);
5858
5859         assert_return(!m->sealed, -EPERM);
5860         assert_return(!m->sender, -EPERM);
5861
5862         return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5863 }
5864
5865 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5866         assert_return(m, -EINVAL);
5867         assert_return(priority, -EINVAL);
5868
5869         *priority = m->priority;
5870         return 0;
5871 }
5872
5873 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5874         assert_return(m, -EINVAL);
5875         assert_return(!m->sealed, -EPERM);
5876
5877         m->priority = priority;
5878         return 0;
5879 }