chiark / gitweb /
sd-bus: fix encoding/decoding gvariant root container
[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         bool fixed_size = true;
2165         size_t n_variable = 0;
2166         unsigned i = 0;
2167         const char *p;
2168         uint8_t *a;
2169         int r;
2170
2171         assert(m);
2172         assert(c);
2173
2174         if (!BUS_MESSAGE_IS_GVARIANT(m))
2175                 return 0;
2176
2177         p = strempty(c->signature);
2178         while (*p != 0) {
2179                 size_t n;
2180
2181                 r = signature_element_length(p, &n);
2182                 if (r < 0)
2183                         return r;
2184                 else {
2185                         char t[n+1];
2186
2187                         memcpy(t, p, n);
2188                         t[n] = 0;
2189
2190                         r = bus_gvariant_is_fixed_size(t);
2191                         if (r < 0)
2192                                 return r;
2193                 }
2194
2195                 assert(!c->need_offsets || i <= c->n_offsets);
2196
2197                 /* We need to add an offset for each item that has a
2198                  * variable size and that is not the last one in the
2199                  * list */
2200                 if (r == 0)
2201                         fixed_size = false;
2202                 if (r == 0 && p[n] != 0)
2203                         n_variable++;
2204
2205                 i++;
2206                 p += n;
2207         }
2208
2209         assert(!c->need_offsets || i == c->n_offsets);
2210         assert(c->need_offsets || n_variable == 0);
2211
2212         if (isempty(c->signature)) {
2213                 /* The unary type is encoded as fixed 1 byte padding */
2214                 a = message_extend_body(m, 1, 1, add_offset, false);
2215                 if (!a)
2216                         return -ENOMEM;
2217
2218                 *a = 0;
2219         } else if (n_variable <= 0) {
2220                 int alignment = 1;
2221
2222                 /* Structures with fixed-size members only have to be
2223                  * fixed-size themselves. But gvariant requires all fixed-size
2224                  * elements to be sized a multiple of their alignment. Hence,
2225                  * we must *always* add final padding after the last member so
2226                  * the overall size of the structure is properly aligned. */
2227                 if (fixed_size)
2228                         alignment = bus_gvariant_get_alignment(strempty(c->signature));
2229
2230                 assert(alignment > 0);
2231
2232                 a = message_extend_body(m, alignment, 0, add_offset, false);
2233                 if (!a)
2234                         return -ENOMEM;
2235         } else {
2236                 size_t sz;
2237                 unsigned j;
2238
2239                 assert(c->offsets[c->n_offsets-1] == m->body_size);
2240
2241                 sz = bus_gvariant_determine_word_size(m->body_size - c->begin, n_variable);
2242
2243                 a = message_extend_body(m, 1, sz * n_variable, add_offset, false);
2244                 if (!a)
2245                         return -ENOMEM;
2246
2247                 p = strempty(c->signature);
2248                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2249                         unsigned k;
2250                         size_t n;
2251
2252                         r = signature_element_length(p, &n);
2253                         if (r < 0)
2254                                 return r;
2255                         else {
2256                                 char t[n+1];
2257
2258                                 memcpy(t, p, n);
2259                                 t[n] = 0;
2260
2261                                 p += n;
2262
2263                                 r = bus_gvariant_is_fixed_size(t);
2264                                 if (r < 0)
2265                                         return r;
2266                                 if (r > 0 || p[0] == 0)
2267                                         continue;
2268                         }
2269
2270                         k = n_variable - 1 - j;
2271
2272                         bus_gvariant_write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2273
2274                         j++;
2275                 }
2276         }
2277
2278         return 0;
2279 }
2280
2281 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2282         struct bus_container *c;
2283         int r;
2284
2285         assert_return(m, -EINVAL);
2286         assert_return(!m->sealed, -EPERM);
2287         assert_return(m->n_containers > 0, -EINVAL);
2288         assert_return(!m->poisoned, -ESTALE);
2289
2290         c = message_get_container(m);
2291
2292         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2293                 if (c->signature && c->signature[c->index] != 0)
2294                         return -EINVAL;
2295
2296         m->n_containers--;
2297
2298         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2299                 r = bus_message_close_array(m, c);
2300         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2301                 r = bus_message_close_variant(m, c);
2302         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2303                 r = bus_message_close_struct(m, c, true);
2304         else
2305                 assert_not_reached("Unknown container type");
2306
2307         free(c->signature);
2308         free(c->offsets);
2309
2310         return r;
2311 }
2312
2313 typedef struct {
2314         const char *types;
2315         unsigned n_struct;
2316         unsigned n_array;
2317 } TypeStack;
2318
2319 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2320         assert(stack);
2321         assert(max > 0);
2322
2323         if (*i >= max)
2324                 return -EINVAL;
2325
2326         stack[*i].types = types;
2327         stack[*i].n_struct = n_struct;
2328         stack[*i].n_array = n_array;
2329         (*i)++;
2330
2331         return 0;
2332 }
2333
2334 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2335         assert(stack);
2336         assert(max > 0);
2337         assert(types);
2338         assert(n_struct);
2339         assert(n_array);
2340
2341         if (*i <= 0)
2342                 return 0;
2343
2344         (*i)--;
2345         *types = stack[*i].types;
2346         *n_struct = stack[*i].n_struct;
2347         *n_array = stack[*i].n_array;
2348
2349         return 1;
2350 }
2351
2352 int bus_message_append_ap(
2353                 sd_bus_message *m,
2354                 const char *types,
2355                 va_list ap) {
2356
2357         unsigned n_array, n_struct;
2358         TypeStack stack[BUS_CONTAINER_DEPTH];
2359         unsigned stack_ptr = 0;
2360         int r;
2361
2362         assert(m);
2363
2364         if (!types)
2365                 return 0;
2366
2367         n_array = (unsigned) -1;
2368         n_struct = strlen(types);
2369
2370         for (;;) {
2371                 const char *t;
2372
2373                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2374                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2375                         if (r < 0)
2376                                 return r;
2377                         if (r == 0)
2378                                 break;
2379
2380                         r = sd_bus_message_close_container(m);
2381                         if (r < 0)
2382                                 return r;
2383
2384                         continue;
2385                 }
2386
2387                 t = types;
2388                 if (n_array != (unsigned) -1)
2389                         n_array --;
2390                 else {
2391                         types ++;
2392                         n_struct--;
2393                 }
2394
2395                 switch (*t) {
2396
2397                 case SD_BUS_TYPE_BYTE: {
2398                         uint8_t x;
2399
2400                         x = (uint8_t) va_arg(ap, int);
2401                         r = sd_bus_message_append_basic(m, *t, &x);
2402                         break;
2403                 }
2404
2405                 case SD_BUS_TYPE_BOOLEAN:
2406                 case SD_BUS_TYPE_INT32:
2407                 case SD_BUS_TYPE_UINT32:
2408                 case SD_BUS_TYPE_UNIX_FD: {
2409                         uint32_t x;
2410
2411                         /* We assume a boolean is the same as int32_t */
2412                         assert_cc(sizeof(int32_t) == sizeof(int));
2413
2414                         x = va_arg(ap, uint32_t);
2415                         r = sd_bus_message_append_basic(m, *t, &x);
2416                         break;
2417                 }
2418
2419                 case SD_BUS_TYPE_INT16:
2420                 case SD_BUS_TYPE_UINT16: {
2421                         uint16_t x;
2422
2423                         x = (uint16_t) va_arg(ap, int);
2424                         r = sd_bus_message_append_basic(m, *t, &x);
2425                         break;
2426                 }
2427
2428                 case SD_BUS_TYPE_INT64:
2429                 case SD_BUS_TYPE_UINT64: {
2430                         uint64_t x;
2431
2432                         x = va_arg(ap, uint64_t);
2433                         r = sd_bus_message_append_basic(m, *t, &x);
2434                         break;
2435                 }
2436
2437                 case SD_BUS_TYPE_DOUBLE: {
2438                         double x;
2439
2440                         x = va_arg(ap, double);
2441                         r = sd_bus_message_append_basic(m, *t, &x);
2442                         break;
2443                 }
2444
2445                 case SD_BUS_TYPE_STRING:
2446                 case SD_BUS_TYPE_OBJECT_PATH:
2447                 case SD_BUS_TYPE_SIGNATURE: {
2448                         const char *x;
2449
2450                         x = va_arg(ap, const char*);
2451                         r = sd_bus_message_append_basic(m, *t, x);
2452                         break;
2453                 }
2454
2455                 case SD_BUS_TYPE_ARRAY: {
2456                         size_t k;
2457
2458                         r = signature_element_length(t + 1, &k);
2459                         if (r < 0)
2460                                 return r;
2461
2462                         {
2463                                 char s[k + 1];
2464                                 memcpy(s, t + 1, k);
2465                                 s[k] = 0;
2466
2467                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2468                                 if (r < 0)
2469                                         return r;
2470                         }
2471
2472                         if (n_array == (unsigned) -1) {
2473                                 types += k;
2474                                 n_struct -= k;
2475                         }
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 = t + 1;
2482                         n_struct = k;
2483                         n_array = va_arg(ap, unsigned);
2484
2485                         break;
2486                 }
2487
2488                 case SD_BUS_TYPE_VARIANT: {
2489                         const char *s;
2490
2491                         s = va_arg(ap, const char*);
2492                         if (!s)
2493                                 return -EINVAL;
2494
2495                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2496                         if (r < 0)
2497                                 return r;
2498
2499                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2500                         if (r < 0)
2501                                 return r;
2502
2503                         types = s;
2504                         n_struct = strlen(s);
2505                         n_array = (unsigned) -1;
2506
2507                         break;
2508                 }
2509
2510                 case SD_BUS_TYPE_STRUCT_BEGIN:
2511                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2512                         size_t k;
2513
2514                         r = signature_element_length(t, &k);
2515                         if (r < 0)
2516                                 return r;
2517
2518                         {
2519                                 char s[k - 1];
2520
2521                                 memcpy(s, t + 1, k - 2);
2522                                 s[k - 2] = 0;
2523
2524                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2525                                 if (r < 0)
2526                                         return r;
2527                         }
2528
2529                         if (n_array == (unsigned) -1) {
2530                                 types += k - 1;
2531                                 n_struct -= k - 1;
2532                         }
2533
2534                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2535                         if (r < 0)
2536                                 return r;
2537
2538                         types = t + 1;
2539                         n_struct = k - 2;
2540                         n_array = (unsigned) -1;
2541
2542                         break;
2543                 }
2544
2545                 default:
2546                         r = -EINVAL;
2547                 }
2548
2549                 if (r < 0)
2550                         return r;
2551         }
2552
2553         return 1;
2554 }
2555
2556 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2557         va_list ap;
2558         int r;
2559
2560         assert_return(m, -EINVAL);
2561         assert_return(types, -EINVAL);
2562         assert_return(!m->sealed, -EPERM);
2563         assert_return(!m->poisoned, -ESTALE);
2564
2565         va_start(ap, types);
2566         r = bus_message_append_ap(m, types, ap);
2567         va_end(ap);
2568
2569         return r;
2570 }
2571
2572 _public_ int sd_bus_message_append_array_space(
2573                 sd_bus_message *m,
2574                 char type,
2575                 size_t size,
2576                 void **ptr) {
2577
2578         ssize_t align, sz;
2579         void *a;
2580         int r;
2581
2582         assert_return(m, -EINVAL);
2583         assert_return(!m->sealed, -EPERM);
2584         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2585         assert_return(ptr || size == 0, -EINVAL);
2586         assert_return(!m->poisoned, -ESTALE);
2587
2588         /* alignment and size of the trivial types (except bool) is
2589          * identical for gvariant and dbus1 marshalling */
2590         align = bus_type_get_alignment(type);
2591         sz = bus_type_get_size(type);
2592
2593         assert_se(align > 0);
2594         assert_se(sz > 0);
2595
2596         if (size % sz != 0)
2597                 return -EINVAL;
2598
2599         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2600         if (r < 0)
2601                 return r;
2602
2603         a = message_extend_body(m, align, size, false, false);
2604         if (!a)
2605                 return -ENOMEM;
2606
2607         r = sd_bus_message_close_container(m);
2608         if (r < 0)
2609                 return r;
2610
2611         *ptr = a;
2612         return 0;
2613 }
2614
2615 _public_ int sd_bus_message_append_array(
2616                 sd_bus_message *m,
2617                 char type,
2618                 const void *ptr,
2619                 size_t size) {
2620         int r;
2621         void *p;
2622
2623         assert_return(m, -EINVAL);
2624         assert_return(!m->sealed, -EPERM);
2625         assert_return(bus_type_is_trivial(type), -EINVAL);
2626         assert_return(ptr || size == 0, -EINVAL);
2627         assert_return(!m->poisoned, -ESTALE);
2628
2629         r = sd_bus_message_append_array_space(m, type, size, &p);
2630         if (r < 0)
2631                 return r;
2632
2633         if (size > 0)
2634                 memcpy(p, ptr, size);
2635
2636         return 0;
2637 }
2638
2639 _public_ int sd_bus_message_append_array_iovec(
2640                 sd_bus_message *m,
2641                 char type,
2642                 const struct iovec *iov,
2643                 unsigned n) {
2644
2645         size_t size;
2646         unsigned i;
2647         void *p;
2648         int r;
2649
2650         assert_return(m, -EINVAL);
2651         assert_return(!m->sealed, -EPERM);
2652         assert_return(bus_type_is_trivial(type), -EINVAL);
2653         assert_return(iov || n == 0, -EINVAL);
2654         assert_return(!m->poisoned, -ESTALE);
2655
2656         size = IOVEC_TOTAL_SIZE(iov, n);
2657
2658         r = sd_bus_message_append_array_space(m, type, size, &p);
2659         if (r < 0)
2660                 return r;
2661
2662         for (i = 0; i < n; i++) {
2663
2664                 if (iov[i].iov_base)
2665                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2666                 else
2667                         memzero(p, iov[i].iov_len);
2668
2669                 p = (uint8_t*) p + iov[i].iov_len;
2670         }
2671
2672         return 0;
2673 }
2674
2675 _public_ int sd_bus_message_append_array_memfd(
2676                 sd_bus_message *m,
2677                 char type,
2678                 int memfd,
2679                 uint64_t offset,
2680                 uint64_t size) {
2681
2682         _cleanup_close_ int copy_fd = -1;
2683         struct bus_body_part *part;
2684         ssize_t align, sz;
2685         uint64_t real_size;
2686         void *a;
2687         int r;
2688
2689         assert_return(m, -EINVAL);
2690         assert_return(memfd >= 0, -EINVAL);
2691         assert_return(bus_type_is_trivial(type), -EINVAL);
2692         assert_return(size > 0, -EINVAL);
2693         assert_return(!m->sealed, -EPERM);
2694         assert_return(!m->poisoned, -ESTALE);
2695
2696         r = memfd_set_sealed(memfd);
2697         if (r < 0)
2698                 return r;
2699
2700         copy_fd = dup(memfd);
2701         if (copy_fd < 0)
2702                 return copy_fd;
2703
2704         r = memfd_get_size(memfd, &real_size);
2705         if (r < 0)
2706                 return r;
2707
2708         if (offset == 0 && size == (uint64_t) -1)
2709                 size = real_size;
2710         else if (offset + size > real_size)
2711                 return -EMSGSIZE;
2712
2713         align = bus_type_get_alignment(type);
2714         sz = bus_type_get_size(type);
2715
2716         assert_se(align > 0);
2717         assert_se(sz > 0);
2718
2719         if (offset % align != 0)
2720                 return -EINVAL;
2721
2722         if (size % sz != 0)
2723                 return -EINVAL;
2724
2725         if (size > (uint64_t) (uint32_t) -1)
2726                 return -EINVAL;
2727
2728         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2729         if (r < 0)
2730                 return r;
2731
2732         a = message_extend_body(m, align, 0, false, false);
2733         if (!a)
2734                 return -ENOMEM;
2735
2736         part = message_append_part(m);
2737         if (!part)
2738                 return -ENOMEM;
2739
2740         part->memfd = copy_fd;
2741         part->memfd_offset = offset;
2742         part->sealed = true;
2743         part->size = size;
2744         copy_fd = -1;
2745
2746         m->body_size += size;
2747         message_extend_containers(m, size);
2748
2749         return sd_bus_message_close_container(m);
2750 }
2751
2752 _public_ int sd_bus_message_append_string_memfd(
2753                 sd_bus_message *m,
2754                 int memfd,
2755                 uint64_t offset,
2756                 uint64_t size) {
2757
2758         _cleanup_close_ int copy_fd = -1;
2759         struct bus_body_part *part;
2760         struct bus_container *c;
2761         uint64_t real_size;
2762         void *a;
2763         int r;
2764
2765         assert_return(m, -EINVAL);
2766         assert_return(memfd >= 0, -EINVAL);
2767         assert_return(size > 0, -EINVAL);
2768         assert_return(!m->sealed, -EPERM);
2769         assert_return(!m->poisoned, -ESTALE);
2770
2771         r = memfd_set_sealed(memfd);
2772         if (r < 0)
2773                 return r;
2774
2775         copy_fd = dup(memfd);
2776         if (copy_fd < 0)
2777                 return copy_fd;
2778
2779         r = memfd_get_size(memfd, &real_size);
2780         if (r < 0)
2781                 return r;
2782
2783         if (offset == 0 && size == (uint64_t) -1)
2784                 size = real_size;
2785         else if (offset + size > real_size)
2786                 return -EMSGSIZE;
2787
2788         /* We require this to be NUL terminated */
2789         if (size == 0)
2790                 return -EINVAL;
2791
2792         if (size > (uint64_t) (uint32_t) -1)
2793                 return -EINVAL;
2794
2795         c = message_get_container(m);
2796         if (c->signature && c->signature[c->index]) {
2797                 /* Container signature is already set */
2798
2799                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2800                         return -ENXIO;
2801         } else {
2802                 char *e;
2803
2804                 /* Maybe we can append to the signature? But only if this is the top-level container */
2805                 if (c->enclosing != 0)
2806                         return -ENXIO;
2807
2808                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2809                 if (!e) {
2810                         m->poisoned = true;
2811                         return -ENOMEM;
2812                 }
2813         }
2814
2815         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2816                 a = message_extend_body(m, 4, 4, false, false);
2817                 if (!a)
2818                         return -ENOMEM;
2819
2820                 *(uint32_t*) a = size - 1;
2821         }
2822
2823         part = message_append_part(m);
2824         if (!part)
2825                 return -ENOMEM;
2826
2827         part->memfd = copy_fd;
2828         part->memfd_offset = offset;
2829         part->sealed = true;
2830         part->size = size;
2831         copy_fd = -1;
2832
2833         m->body_size += size;
2834         message_extend_containers(m, size);
2835
2836         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2837                 r = message_add_offset(m, m->body_size);
2838                 if (r < 0) {
2839                         m->poisoned = true;
2840                         return -ENOMEM;
2841                 }
2842         }
2843
2844         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2845                 c->index++;
2846
2847         return 0;
2848 }
2849
2850 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2851         char **i;
2852         int r;
2853
2854         assert_return(m, -EINVAL);
2855         assert_return(!m->sealed, -EPERM);
2856         assert_return(!m->poisoned, -ESTALE);
2857
2858         r = sd_bus_message_open_container(m, 'a', "s");
2859         if (r < 0)
2860                 return r;
2861
2862         STRV_FOREACH(i, l) {
2863                 r = sd_bus_message_append_basic(m, 's', *i);
2864                 if (r < 0)
2865                         return r;
2866         }
2867
2868         return sd_bus_message_close_container(m);
2869 }
2870
2871 static int bus_message_close_header(sd_bus_message *m) {
2872
2873         assert(m);
2874
2875         /* The actual user data is finished now, we just complete the
2876            variant and struct now (at least on gvariant). Remember
2877            this position, so that during parsing we know where to to
2878            put the outer container end. */
2879         m->user_body_size = m->body_size;
2880
2881         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2882                 const char *signature;
2883                 size_t sz, l;
2884                 void *d;
2885
2886                 /* Add offset table to end of fields array */
2887                 if (m->n_header_offsets >= 1) {
2888                         uint8_t *a;
2889                         unsigned i;
2890
2891                         assert(m->fields_size == m->header_offsets[m->n_header_offsets-1]);
2892
2893                         sz = bus_gvariant_determine_word_size(m->fields_size, m->n_header_offsets);
2894                         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2895                         if (!a)
2896                                 return -ENOMEM;
2897
2898                         for (i = 0; i < m->n_header_offsets; i++)
2899                                 bus_gvariant_write_word_le(a + sz*i, sz, m->header_offsets[i]);
2900                 }
2901
2902                 /* Add gvariant NUL byte plus signature to the end of
2903                  * the body, followed by the final offset pointing to
2904                  * the end of the fields array */
2905
2906                 signature = strempty(m->root_container.signature);
2907                 l = strlen(signature);
2908
2909                 sz = bus_gvariant_determine_word_size(sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size + 1 + l + 2, 1);
2910                 d = message_extend_body(m, 1, 1 + l + 2 + sz, false, true);
2911                 if (!d)
2912                         return -ENOMEM;
2913
2914                 *(uint8_t*) d = 0;
2915                 *((uint8_t*) d + 1) = SD_BUS_TYPE_STRUCT_BEGIN;
2916                 memcpy((uint8_t*) d + 2, signature, l);
2917                 *((uint8_t*) d + 1 + l + 1) = SD_BUS_TYPE_STRUCT_END;
2918
2919                 bus_gvariant_write_word_le((uint8_t*) d + 1 + l + 2, sz, sizeof(struct bus_header) + m->fields_size);
2920
2921                 m->footer = d;
2922                 m->footer_accessible = 1 + l + 2 + sz;
2923         } else {
2924                 m->header->dbus1.fields_size = m->fields_size;
2925                 m->header->dbus1.body_size = m->body_size;
2926         }
2927
2928         return 0;
2929 }
2930
2931 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2932         struct bus_body_part *part;
2933         size_t a;
2934         unsigned i;
2935         int r;
2936
2937         assert(m);
2938
2939         if (m->sealed)
2940                 return -EPERM;
2941
2942         if (m->n_containers > 0)
2943                 return -EBADMSG;
2944
2945         if (m->poisoned)
2946                 return -ESTALE;
2947
2948         if (cookie > 0xffffffffULL &&
2949             !BUS_MESSAGE_IS_GVARIANT(m))
2950                 return -EOPNOTSUPP;
2951
2952         /* In vtables the return signature of method calls is listed,
2953          * let's check if they match if this is a response */
2954         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2955             m->enforced_reply_signature &&
2956             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2957                 return -ENOMSG;
2958
2959         /* If gvariant marshalling is used we need to close the body structure */
2960         r = bus_message_close_struct(m, &m->root_container, false);
2961         if (r < 0)
2962                 return r;
2963
2964         /* If there's a non-trivial signature set, then add it in
2965          * here, but only on dbus1 */
2966         if (!isempty(m->root_container.signature) && !BUS_MESSAGE_IS_GVARIANT(m)) {
2967                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2968                 if (r < 0)
2969                         return r;
2970         }
2971
2972         if (m->n_fds > 0) {
2973                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2974                 if (r < 0)
2975                         return r;
2976         }
2977
2978         r = bus_message_close_header(m);
2979         if (r < 0)
2980                 return r;
2981
2982         if (BUS_MESSAGE_IS_GVARIANT(m))
2983                 m->header->dbus2.cookie = cookie;
2984         else
2985                 m->header->dbus1.serial = (uint32_t) cookie;
2986
2987         m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2988
2989         /* Add padding at the end of the fields part, since we know
2990          * the body needs to start at an 8 byte alignment. We made
2991          * sure we allocated enough space for this, so all we need to
2992          * do here is to zero it out. */
2993         a = ALIGN8(m->fields_size) - m->fields_size;
2994         if (a > 0)
2995                 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + m->fields_size, a);
2996
2997         /* If this is something we can send as memfd, then let's seal
2998         the memfd now. Note that we can send memfds as payload only
2999         for directed messages, and not for broadcasts. */
3000         if (m->destination && m->bus->use_memfd) {
3001                 MESSAGE_FOREACH_PART(part, i, m)
3002                         if (part->memfd >= 0 &&
3003                             !part->sealed &&
3004                             (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0) &&
3005                             part != m->body_end) { /* The last part may never be sent as memfd */
3006                                 uint64_t sz;
3007
3008                                 /* Try to seal it if that makes
3009                                  * sense. First, unmap our own map to
3010                                  * make sure we don't keep it busy. */
3011                                 bus_body_part_unmap(part);
3012
3013                                 /* Then, sync up real memfd size */
3014                                 sz = part->size;
3015                                 r = memfd_set_size(part->memfd, sz);
3016                                 if (r < 0)
3017                                         return r;
3018
3019                                 /* Finally, try to seal */
3020                                 if (memfd_set_sealed(part->memfd) >= 0)
3021                                         part->sealed = true;
3022                         }
3023         }
3024
3025         m->root_container.end = m->user_body_size;
3026         m->root_container.index = 0;
3027         m->root_container.offset_index = 0;
3028         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
3029
3030         m->sealed = true;
3031
3032         return 0;
3033 }
3034
3035 int bus_body_part_map(struct bus_body_part *part) {
3036         void *p;
3037         size_t psz, shift;
3038
3039         assert_se(part);
3040
3041         if (part->data)
3042                 return 0;
3043
3044         if (part->size <= 0)
3045                 return 0;
3046
3047         /* For smaller zero parts (as used for padding) we don't need to map anything... */
3048         if (part->memfd < 0 && part->is_zero && part->size < 8) {
3049                 static const uint8_t zeroes[7] = { };
3050                 part->data = (void*) zeroes;
3051                 return 0;
3052         }
3053
3054         shift = part->memfd_offset - ((part->memfd_offset / page_size()) * page_size());
3055         psz = PAGE_ALIGN(part->size + shift);
3056
3057         if (part->memfd >= 0)
3058                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset - shift);
3059         else if (part->is_zero)
3060                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
3061         else
3062                 return -EINVAL;
3063
3064         if (p == MAP_FAILED)
3065                 return -errno;
3066
3067         part->mapped = psz;
3068         part->mmap_begin = p;
3069         part->data = (uint8_t*) p + shift;
3070         part->munmap_this = true;
3071
3072         return 0;
3073 }
3074
3075 void bus_body_part_unmap(struct bus_body_part *part) {
3076
3077         assert_se(part);
3078
3079         if (part->memfd < 0)
3080                 return;
3081
3082         if (!part->mmap_begin)
3083                 return;
3084
3085         if (!part->munmap_this)
3086                 return;
3087
3088         assert_se(munmap(part->mmap_begin, part->mapped) == 0);
3089
3090         part->mmap_begin = NULL;
3091         part->data = NULL;
3092         part->mapped = 0;
3093         part->munmap_this = false;
3094
3095         return;
3096 }
3097
3098 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
3099         size_t k, start, end;
3100
3101         assert(rindex);
3102         assert(align > 0);
3103
3104         start = ALIGN_TO((size_t) *rindex, align);
3105         end = start + nbytes;
3106
3107         if (end > sz)
3108                 return -EBADMSG;
3109
3110         /* Verify that padding is 0 */
3111         for (k = *rindex; k < start; k++)
3112                 if (((const uint8_t*) p)[k] != 0)
3113                         return -EBADMSG;
3114
3115         if (r)
3116                 *r = (uint8_t*) p + start;
3117
3118         *rindex = end;
3119
3120         return 1;
3121 }
3122
3123 static bool message_end_of_signature(sd_bus_message *m) {
3124         struct bus_container *c;
3125
3126         assert(m);
3127
3128         c = message_get_container(m);
3129         return !c->signature || c->signature[c->index] == 0;
3130 }
3131
3132 static bool message_end_of_array(sd_bus_message *m, size_t index) {
3133         struct bus_container *c;
3134
3135         assert(m);
3136
3137         c = message_get_container(m);
3138         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3139                 return false;
3140
3141         if (BUS_MESSAGE_IS_GVARIANT(m))
3142                 return index >= c->end;
3143         else {
3144                 assert(c->array_size);
3145                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
3146         }
3147 }
3148
3149 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
3150         assert_return(m, -EINVAL);
3151         assert_return(m->sealed, -EPERM);
3152
3153         if (complete && m->n_containers > 0)
3154                 return false;
3155
3156         if (message_end_of_signature(m))
3157                 return true;
3158
3159         if (message_end_of_array(m, m->rindex))
3160                 return true;
3161
3162         return false;
3163 }
3164
3165 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
3166         struct bus_body_part *part;
3167         size_t begin;
3168         int r;
3169
3170         assert(m);
3171
3172         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
3173                 part = m->cached_rindex_part;
3174                 begin = m->cached_rindex_part_begin;
3175         } else {
3176                 part = &m->body;
3177                 begin = 0;
3178         }
3179
3180         while (part) {
3181                 if (index < begin)
3182                         return NULL;
3183
3184                 if (index + sz <= begin + part->size) {
3185
3186                         r = bus_body_part_map(part);
3187                         if (r < 0)
3188                                 return NULL;
3189
3190                         if (p)
3191                                 *p = (uint8_t*) part->data + index - begin;
3192
3193                         m->cached_rindex_part = part;
3194                         m->cached_rindex_part_begin = begin;
3195
3196                         return part;
3197                 }
3198
3199                 begin += part->size;
3200                 part = part->next;
3201         }
3202
3203         return NULL;
3204 }
3205
3206 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3207         int r;
3208
3209         assert(m);
3210         assert(c);
3211         assert(rindex);
3212
3213         if (!BUS_MESSAGE_IS_GVARIANT(m))
3214                 return 0;
3215
3216         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3217                 int sz;
3218
3219                 sz = bus_gvariant_get_size(c->signature);
3220                 if (sz < 0) {
3221                         int alignment;
3222
3223                         if (c->offset_index+1 >= c->n_offsets)
3224                                 goto end;
3225
3226                         /* Variable-size array */
3227
3228                         alignment = bus_gvariant_get_alignment(c->signature);
3229                         assert(alignment > 0);
3230
3231                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3232                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3233                 } else {
3234
3235                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3236                                 goto end;
3237
3238                         /* Fixed-size array */
3239                         *rindex = c->begin + (c->offset_index+1) * sz;
3240                         c->item_size = sz;
3241                 }
3242
3243                 c->offset_index++;
3244
3245         } else if (c->enclosing == 0 ||
3246                    c->enclosing == SD_BUS_TYPE_STRUCT ||
3247                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3248
3249                 int alignment;
3250                 size_t n, j;
3251
3252                 if (c->offset_index+1 >= c->n_offsets)
3253                         goto end;
3254
3255                 r = signature_element_length(c->signature + c->index, &n);
3256                 if (r < 0)
3257                         return r;
3258
3259                 r = signature_element_length(c->signature + c->index + n, &j);
3260                 if (r < 0)
3261                         return r;
3262                 else {
3263                         char t[j+1];
3264                         memcpy(t, c->signature + c->index + n, j);
3265                         t[j] = 0;
3266
3267                         alignment = bus_gvariant_get_alignment(t);
3268                 }
3269
3270                 assert(alignment > 0);
3271
3272                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3273                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3274
3275                 c->offset_index++;
3276
3277         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3278                 goto end;
3279         else
3280                 assert_not_reached("Unknown container type");
3281
3282         return 0;
3283
3284 end:
3285         /* Reached the end */
3286         *rindex = c->end;
3287         c->item_size = 0;
3288         return 0;
3289 }
3290
3291
3292 static int message_peek_body(
3293                 sd_bus_message *m,
3294                 size_t *rindex,
3295                 size_t align,
3296                 size_t nbytes,
3297                 void **ret) {
3298
3299         size_t k, start, end, padding;
3300         struct bus_body_part *part;
3301         uint8_t *q;
3302
3303         assert(m);
3304         assert(rindex);
3305         assert(align > 0);
3306
3307         start = ALIGN_TO((size_t) *rindex, align);
3308         padding = start - *rindex;
3309         end = start + nbytes;
3310
3311         if (end > m->user_body_size)
3312                 return -EBADMSG;
3313
3314         part = find_part(m, *rindex, padding, (void**) &q);
3315         if (!part)
3316                 return -EBADMSG;
3317
3318         if (q) {
3319                 /* Verify padding */
3320                 for (k = 0; k < padding; k++)
3321                         if (q[k] != 0)
3322                                 return -EBADMSG;
3323         }
3324
3325         part = find_part(m, start, nbytes, (void**) &q);
3326         if (!part || (nbytes > 0 && !q))
3327                 return -EBADMSG;
3328
3329         *rindex = end;
3330
3331         if (ret)
3332                 *ret = q;
3333
3334         return 0;
3335 }
3336
3337 static bool validate_nul(const char *s, size_t l) {
3338
3339         /* Check for NUL chars in the string */
3340         if (memchr(s, 0, l))
3341                 return false;
3342
3343         /* Check for NUL termination */
3344         if (s[l] != 0)
3345                 return false;
3346
3347         return true;
3348 }
3349
3350 static bool validate_string(const char *s, size_t l) {
3351
3352         if (!validate_nul(s, l))
3353                 return false;
3354
3355         /* Check if valid UTF8 */
3356         if (!utf8_is_valid(s))
3357                 return false;
3358
3359         return true;
3360 }
3361
3362 static bool validate_signature(const char *s, size_t l) {
3363
3364         if (!validate_nul(s, l))
3365                 return false;
3366
3367         /* Check if valid signature */
3368         if (!signature_is_valid(s, true))
3369                 return false;
3370
3371         return true;
3372 }
3373
3374 static bool validate_object_path(const char *s, size_t l) {
3375
3376         if (!validate_nul(s, l))
3377                 return false;
3378
3379         if (!object_path_is_valid(s))
3380                 return false;
3381
3382         return true;
3383 }
3384
3385 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3386         struct bus_container *c;
3387         size_t rindex;
3388         void *q;
3389         int r;
3390
3391         assert_return(m, -EINVAL);
3392         assert_return(m->sealed, -EPERM);
3393         assert_return(bus_type_is_basic(type), -EINVAL);
3394
3395         if (message_end_of_signature(m))
3396                 return -ENXIO;
3397
3398         if (message_end_of_array(m, m->rindex))
3399                 return 0;
3400
3401         c = message_get_container(m);
3402         if (c->signature[c->index] != type)
3403                 return -ENXIO;
3404
3405         rindex = m->rindex;
3406
3407         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3408
3409                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3410                         bool ok;
3411
3412                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3413                         if (r < 0)
3414                                 return r;
3415
3416                         if (type == SD_BUS_TYPE_STRING)
3417                                 ok = validate_string(q, c->item_size-1);
3418                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3419                                 ok = validate_object_path(q, c->item_size-1);
3420                         else
3421                                 ok = validate_signature(q, c->item_size-1);
3422
3423                         if (!ok)
3424                                 return -EBADMSG;
3425
3426                         if (p)
3427                                 *(const char**) p = q;
3428                 } else {
3429                         int sz, align;
3430
3431                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3432                         assert(sz > 0);
3433                         if ((size_t) sz != c->item_size)
3434                                 return -EBADMSG;
3435
3436                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3437                         assert(align > 0);
3438
3439                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3440                         if (r < 0)
3441                                 return r;
3442
3443                         switch (type) {
3444
3445                         case SD_BUS_TYPE_BYTE:
3446                                 if (p)
3447                                         *(uint8_t*) p = *(uint8_t*) q;
3448                                 break;
3449
3450                         case SD_BUS_TYPE_BOOLEAN:
3451                                 if (p)
3452                                         *(int*) p = !!*(uint8_t*) q;
3453                                 break;
3454
3455                         case SD_BUS_TYPE_INT16:
3456                         case SD_BUS_TYPE_UINT16:
3457                                 if (p)
3458                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3459                                 break;
3460
3461                         case SD_BUS_TYPE_INT32:
3462                         case SD_BUS_TYPE_UINT32:
3463                                 if (p)
3464                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3465                                 break;
3466
3467                         case SD_BUS_TYPE_INT64:
3468                         case SD_BUS_TYPE_UINT64:
3469                         case SD_BUS_TYPE_DOUBLE:
3470                                 if (p)
3471                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3472                                 break;
3473
3474                         case SD_BUS_TYPE_UNIX_FD: {
3475                                 uint32_t j;
3476
3477                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3478                                 if (j >= m->n_fds)
3479                                         return -EBADMSG;
3480
3481                                 if (p)
3482                                         *(int*) p = m->fds[j];
3483
3484                                 break;
3485                         }
3486
3487                         default:
3488                                 assert_not_reached("unexpected type");
3489                         }
3490                 }
3491
3492                 r = container_next_item(m, c, &rindex);
3493                 if (r < 0)
3494                         return r;
3495         } else {
3496
3497                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3498                         uint32_t l;
3499                         bool ok;
3500
3501                         r = message_peek_body(m, &rindex, 4, 4, &q);
3502                         if (r < 0)
3503                                 return r;
3504
3505                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3506                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3507                         if (r < 0)
3508                                 return r;
3509
3510                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3511                                 ok = validate_object_path(q, l);
3512                         else
3513                                 ok = validate_string(q, l);
3514                         if (!ok)
3515                                 return -EBADMSG;
3516
3517                         if (p)
3518                                 *(const char**) p = q;
3519
3520                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3521                         uint8_t l;
3522
3523                         r = message_peek_body(m, &rindex, 1, 1, &q);
3524                         if (r < 0)
3525                                 return r;
3526
3527                         l = *(uint8_t*) q;
3528                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3529                         if (r < 0)
3530                                 return r;
3531
3532                         if (!validate_signature(q, l))
3533                                 return -EBADMSG;
3534
3535                         if (p)
3536                                 *(const char**) p = q;
3537
3538                 } else {
3539                         ssize_t sz, align;
3540
3541                         align = bus_type_get_alignment(type);
3542                         assert(align > 0);
3543
3544                         sz = bus_type_get_size(type);
3545                         assert(sz > 0);
3546
3547                         r = message_peek_body(m, &rindex, align, sz, &q);
3548                         if (r < 0)
3549                                 return r;
3550
3551                         switch (type) {
3552
3553                         case SD_BUS_TYPE_BYTE:
3554                                 if (p)
3555                                         *(uint8_t*) p = *(uint8_t*) q;
3556                                 break;
3557
3558                         case SD_BUS_TYPE_BOOLEAN:
3559                                 if (p)
3560                                         *(int*) p = !!*(uint32_t*) q;
3561                                 break;
3562
3563                         case SD_BUS_TYPE_INT16:
3564                         case SD_BUS_TYPE_UINT16:
3565                                 if (p)
3566                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3567                                 break;
3568
3569                         case SD_BUS_TYPE_INT32:
3570                         case SD_BUS_TYPE_UINT32:
3571                                 if (p)
3572                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3573                                 break;
3574
3575                         case SD_BUS_TYPE_INT64:
3576                         case SD_BUS_TYPE_UINT64:
3577                         case SD_BUS_TYPE_DOUBLE:
3578                                 if (p)
3579                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3580                                 break;
3581
3582                         case SD_BUS_TYPE_UNIX_FD: {
3583                                 uint32_t j;
3584
3585                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3586                                 if (j >= m->n_fds)
3587                                         return -EBADMSG;
3588
3589                                 if (p)
3590                                         *(int*) p = m->fds[j];
3591                                 break;
3592                         }
3593
3594                         default:
3595                                 assert_not_reached("Unknown basic type...");
3596                         }
3597                 }
3598         }
3599
3600         m->rindex = rindex;
3601
3602         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3603                 c->index++;
3604
3605         return 1;
3606 }
3607
3608 static int bus_message_enter_array(
3609                 sd_bus_message *m,
3610                 struct bus_container *c,
3611                 const char *contents,
3612                 uint32_t **array_size,
3613                 size_t *item_size,
3614                 size_t **offsets,
3615                 size_t *n_offsets) {
3616
3617         size_t rindex;
3618         void *q;
3619         int r, alignment;
3620
3621         assert(m);
3622         assert(c);
3623         assert(contents);
3624         assert(array_size);
3625         assert(item_size);
3626         assert(offsets);
3627         assert(n_offsets);
3628
3629         if (!signature_is_single(contents, true))
3630                 return -EINVAL;
3631
3632         if (!c->signature || c->signature[c->index] == 0)
3633                 return -ENXIO;
3634
3635         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3636                 return -ENXIO;
3637
3638         if (!startswith(c->signature + c->index + 1, contents))
3639                 return -ENXIO;
3640
3641         rindex = m->rindex;
3642
3643         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3644                 /* dbus1 */
3645
3646                 r = message_peek_body(m, &rindex, 4, 4, &q);
3647                 if (r < 0)
3648                         return r;
3649
3650                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3651                         return -EBADMSG;
3652
3653                 alignment = bus_type_get_alignment(contents[0]);
3654                 if (alignment < 0)
3655                         return alignment;
3656
3657                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3658                 if (r < 0)
3659                         return r;
3660
3661                 *array_size = (uint32_t*) q;
3662
3663         } else if (c->item_size <= 0) {
3664
3665                 /* gvariant: empty array */
3666                 *item_size = 0;
3667                 *offsets = NULL;
3668                 *n_offsets = 0;
3669
3670         } else if (bus_gvariant_is_fixed_size(contents)) {
3671
3672                 /* gvariant: fixed length array */
3673                 *item_size = bus_gvariant_get_size(contents);
3674                 *offsets = NULL;
3675                 *n_offsets = 0;
3676
3677         } else {
3678                 size_t where, p = 0, framing, sz;
3679                 unsigned i;
3680
3681                 /* gvariant: variable length array */
3682                 sz = bus_gvariant_determine_word_size(c->item_size, 0);
3683
3684                 where = rindex + c->item_size - sz;
3685                 r = message_peek_body(m, &where, 1, sz, &q);
3686                 if (r < 0)
3687                         return r;
3688
3689                 framing = bus_gvariant_read_word_le(q, sz);
3690                 if (framing > c->item_size - sz)
3691                         return -EBADMSG;
3692                 if ((c->item_size - framing) % sz != 0)
3693                         return -EBADMSG;
3694
3695                 *n_offsets = (c->item_size - framing) / sz;
3696
3697                 where = rindex + framing;
3698                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3699                 if (r < 0)
3700                         return r;
3701
3702                 *offsets = new(size_t, *n_offsets);
3703                 if (!*offsets)
3704                         return -ENOMEM;
3705
3706                 for (i = 0; i < *n_offsets; i++) {
3707                         size_t x;
3708
3709                         x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
3710                         if (x > c->item_size - sz)
3711                                 return -EBADMSG;
3712                         if (x < p)
3713                                 return -EBADMSG;
3714
3715                         (*offsets)[i] = rindex + x;
3716                         p = x;
3717                 }
3718
3719                 *item_size = (*offsets)[0] - rindex;
3720         }
3721
3722         m->rindex = rindex;
3723
3724         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3725                 c->index += 1 + strlen(contents);
3726
3727         return 1;
3728 }
3729
3730 static int bus_message_enter_variant(
3731                 sd_bus_message *m,
3732                 struct bus_container *c,
3733                 const char *contents,
3734                 size_t *item_size) {
3735
3736         size_t rindex;
3737         uint8_t l;
3738         void *q;
3739         int r;
3740
3741         assert(m);
3742         assert(c);
3743         assert(contents);
3744         assert(item_size);
3745
3746         if (!signature_is_single(contents, false))
3747                 return -EINVAL;
3748
3749         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3750                 return -EINVAL;
3751
3752         if (!c->signature || c->signature[c->index] == 0)
3753                 return -ENXIO;
3754
3755         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3756                 return -ENXIO;
3757
3758         rindex = m->rindex;
3759
3760         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3761                 size_t k, where;
3762
3763                 k = strlen(contents);
3764                 if (1+k > c->item_size)
3765                         return -EBADMSG;
3766
3767                 where = rindex + c->item_size - (1+k);
3768                 r = message_peek_body(m, &where, 1, 1+k, &q);
3769                 if (r < 0)
3770                         return r;
3771
3772                 if (*(char*) q != 0)
3773                         return -EBADMSG;
3774
3775                 if (memcmp((uint8_t*) q+1, contents, k))
3776                         return -ENXIO;
3777
3778                 *item_size = c->item_size - (1+k);
3779
3780         } else {
3781                 r = message_peek_body(m, &rindex, 1, 1, &q);
3782                 if (r < 0)
3783                         return r;
3784
3785                 l = *(uint8_t*) q;
3786                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3787                 if (r < 0)
3788                         return r;
3789
3790                 if (!validate_signature(q, l))
3791                         return -EBADMSG;
3792
3793                 if (!streq(q, contents))
3794                         return -ENXIO;
3795         }
3796
3797         m->rindex = rindex;
3798
3799         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3800                 c->index++;
3801
3802         return 1;
3803 }
3804
3805 static int build_struct_offsets(
3806                 sd_bus_message *m,
3807                 const char *signature,
3808                 size_t size,
3809                 size_t *item_size,
3810                 size_t **offsets,
3811                 size_t *n_offsets) {
3812
3813         unsigned n_variable = 0, n_total = 0, v;
3814         size_t previous = 0, where;
3815         const char *p;
3816         size_t sz;
3817         void *q;
3818         int r;
3819
3820         assert(m);
3821         assert(item_size);
3822         assert(offsets);
3823         assert(n_offsets);
3824
3825         if (isempty(signature)) {
3826                 /* Unary type is encoded as *fixed* 1 byte padding */
3827                 r = message_peek_body(m, &m->rindex, 1, 1, &q);
3828                 if (r < 0)
3829                         return r;
3830
3831                 if (*(uint8_t *) q != 0)
3832                         return -EBADMSG;
3833
3834                 *item_size = 0;
3835                 *offsets = NULL;
3836                 *n_offsets = 0;
3837                 return 0;
3838         }
3839
3840         sz = bus_gvariant_determine_word_size(size, 0);
3841         if (sz <= 0)
3842                 return -EBADMSG;
3843
3844         /* First, loop over signature and count variable elements and
3845          * elements in general. We use this to know how large the
3846          * offset array is at the end of the structure. Note that
3847          * GVariant only stores offsets for all variable size elements
3848          * that are not the last item. */
3849
3850         p = signature;
3851         while (*p != 0) {
3852                 size_t n;
3853
3854                 r = signature_element_length(p, &n);
3855                 if (r < 0)
3856                         return r;
3857                 else {
3858                         char t[n+1];
3859
3860                         memcpy(t, p, n);
3861                         t[n] = 0;
3862
3863                         r = bus_gvariant_is_fixed_size(t);
3864                 }
3865
3866                 if (r < 0)
3867                         return r;
3868                 if (r == 0 && p[n] != 0) /* except the last item */
3869                         n_variable ++;
3870                 n_total++;
3871
3872                 p += n;
3873         }
3874
3875         if (size < n_variable * sz)
3876                 return -EBADMSG;
3877
3878         where = m->rindex + size - (n_variable * sz);
3879         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3880         if (r < 0)
3881                 return r;
3882
3883         v = n_variable;
3884
3885         *offsets = new(size_t, n_total);
3886         if (!*offsets)
3887                 return -ENOMEM;
3888
3889         *n_offsets = 0;
3890
3891         /* Second, loop again and build an offset table */
3892         p = signature;
3893         while (*p != 0) {
3894                 size_t n, offset;
3895                 int k;
3896
3897                 r = signature_element_length(p, &n);
3898                 if (r < 0)
3899                         return r;
3900                 else {
3901                         char t[n+1];
3902
3903                         memcpy(t, p, n);
3904                         t[n] = 0;
3905
3906                         k = bus_gvariant_get_size(t);
3907                         if (k < 0) {
3908                                 size_t x;
3909
3910                                 /* variable size */
3911                                 if (v > 0) {
3912                                         v--;
3913
3914                                         x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
3915                                         if (x >= size)
3916                                                 return -EBADMSG;
3917                                         if (m->rindex + x < previous)
3918                                                 return -EBADMSG;
3919                                 } else
3920                                         /* The last item's end
3921                                          * is determined from
3922                                          * the start of the
3923                                          * offset array */
3924                                         x = size - (n_variable * sz);
3925
3926                                 offset = m->rindex + x;
3927
3928                         } else {
3929                                 size_t align;
3930
3931                                 /* fixed size */
3932                                 align = bus_gvariant_get_alignment(t);
3933                                 assert(align > 0);
3934
3935                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3936                         }
3937                 }
3938
3939                 previous = (*offsets)[(*n_offsets)++] = offset;
3940                 p += n;
3941         }
3942
3943         assert(v == 0);
3944         assert(*n_offsets == n_total);
3945
3946         *item_size = (*offsets)[0] - m->rindex;
3947         return 0;
3948 }
3949
3950 static int enter_struct_or_dict_entry(
3951                 sd_bus_message *m,
3952                 struct bus_container *c,
3953                 const char *contents,
3954                 size_t *item_size,
3955                 size_t **offsets,
3956                 size_t *n_offsets) {
3957
3958         int r;
3959
3960         assert(m);
3961         assert(c);
3962         assert(contents);
3963         assert(item_size);
3964         assert(offsets);
3965         assert(n_offsets);
3966
3967         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3968
3969                 /* dbus1 */
3970                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3971                 if (r < 0)
3972                         return r;
3973
3974         } else
3975                 /* gvariant with contents */
3976                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3977
3978         return 0;
3979 }
3980
3981 static int bus_message_enter_struct(
3982                 sd_bus_message *m,
3983                 struct bus_container *c,
3984                 const char *contents,
3985                 size_t *item_size,
3986                 size_t **offsets,
3987                 size_t *n_offsets) {
3988
3989         size_t l;
3990         int r;
3991
3992         assert(m);
3993         assert(c);
3994         assert(contents);
3995         assert(item_size);
3996         assert(offsets);
3997         assert(n_offsets);
3998
3999         if (!signature_is_valid(contents, false))
4000                 return -EINVAL;
4001
4002         if (!c->signature || c->signature[c->index] == 0)
4003                 return -ENXIO;
4004
4005         l = strlen(contents);
4006
4007         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
4008             !startswith(c->signature + c->index + 1, contents) ||
4009             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
4010                 return -ENXIO;
4011
4012         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
4013         if (r < 0)
4014                 return r;
4015
4016         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4017                 c->index += 1 + l + 1;
4018
4019         return 1;
4020 }
4021
4022 static int bus_message_enter_dict_entry(
4023                 sd_bus_message *m,
4024                 struct bus_container *c,
4025                 const char *contents,
4026                 size_t *item_size,
4027                 size_t **offsets,
4028                 size_t *n_offsets) {
4029
4030         size_t l;
4031         int r;
4032
4033         assert(m);
4034         assert(c);
4035         assert(contents);
4036
4037         if (!signature_is_pair(contents))
4038                 return -EINVAL;
4039
4040         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4041                 return -ENXIO;
4042
4043         if (!c->signature || c->signature[c->index] == 0)
4044                 return 0;
4045
4046         l = strlen(contents);
4047
4048         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
4049             !startswith(c->signature + c->index + 1, contents) ||
4050             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
4051                 return -ENXIO;
4052
4053         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
4054         if (r < 0)
4055                 return r;
4056
4057         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4058                 c->index += 1 + l + 1;
4059
4060         return 1;
4061 }
4062
4063 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
4064                                             char type,
4065                                             const char *contents) {
4066         struct bus_container *c, *w;
4067         uint32_t *array_size = NULL;
4068         char *signature;
4069         size_t before;
4070         size_t *offsets = NULL;
4071         size_t n_offsets = 0, item_size = 0;
4072         int r;
4073
4074         assert_return(m, -EINVAL);
4075         assert_return(m->sealed, -EPERM);
4076         assert_return(type != 0 || !contents, -EINVAL);
4077
4078         if (type == 0 || !contents) {
4079                 const char *cc;
4080                 char tt;
4081
4082                 /* Allow entering into anonymous containers */
4083                 r = sd_bus_message_peek_type(m, &tt, &cc);
4084                 if (r < 0)
4085                         return r;
4086
4087                 if (type != 0 && type != tt)
4088                         return -ENXIO;
4089
4090                 if (contents && !streq(contents, cc))
4091                         return -ENXIO;
4092
4093                 type = tt;
4094                 contents = cc;
4095         }
4096
4097         /*
4098          * We enforce a global limit on container depth, that is much
4099          * higher than the 32 structs and 32 arrays the specification
4100          * mandates. This is simpler to implement for us, and we need
4101          * this only to ensure our container array doesn't grow
4102          * without bounds. We are happy to return any data from a
4103          * message as long as the data itself is valid, even if the
4104          * overall message might be not.
4105          *
4106          * Note that the message signature is validated when
4107          * parsing the headers, and that validation does check the
4108          * 32/32 limit.
4109          *
4110          * Note that the specification defines no limits on the depth
4111          * of stacked variants, but we do.
4112          */
4113         if (m->n_containers >= BUS_CONTAINER_DEPTH)
4114                 return -EBADMSG;
4115
4116         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
4117                 return -ENOMEM;
4118
4119         if (message_end_of_signature(m))
4120                 return -ENXIO;
4121
4122         if (message_end_of_array(m, m->rindex))
4123                 return 0;
4124
4125         c = message_get_container(m);
4126
4127         signature = strdup(contents);
4128         if (!signature)
4129                 return -ENOMEM;
4130
4131         c->saved_index = c->index;
4132         before = m->rindex;
4133
4134         if (type == SD_BUS_TYPE_ARRAY)
4135                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
4136         else if (type == SD_BUS_TYPE_VARIANT)
4137                 r = bus_message_enter_variant(m, c, contents, &item_size);
4138         else if (type == SD_BUS_TYPE_STRUCT)
4139                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
4140         else if (type == SD_BUS_TYPE_DICT_ENTRY)
4141                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
4142         else
4143                 r = -EINVAL;
4144
4145         if (r <= 0) {
4146                 free(signature);
4147                 free(offsets);
4148                 return r;
4149         }
4150
4151         /* OK, let's fill it in */
4152         w = m->containers + m->n_containers++;
4153         w->enclosing = type;
4154         w->signature = signature;
4155         w->peeked_signature = NULL;
4156         w->index = 0;
4157
4158         w->before = before;
4159         w->begin = m->rindex;
4160
4161         /* Unary type has fixed size of 1, but virtual size of 0 */
4162         if (BUS_MESSAGE_IS_GVARIANT(m) &&
4163             type == SD_BUS_TYPE_STRUCT &&
4164             isempty(signature))
4165                 w->end = m->rindex + 0;
4166         else
4167                 w->end = m->rindex + c->item_size;
4168
4169         w->array_size = array_size;
4170         w->item_size = item_size;
4171         w->offsets = offsets;
4172         w->n_offsets = n_offsets;
4173         w->offset_index = 0;
4174
4175         return 1;
4176 }
4177
4178 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
4179         struct bus_container *c;
4180         unsigned saved;
4181         int r;
4182
4183         assert_return(m, -EINVAL);
4184         assert_return(m->sealed, -EPERM);
4185         assert_return(m->n_containers > 0, -ENXIO);
4186
4187         c = message_get_container(m);
4188
4189         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
4190                 if (c->signature && c->signature[c->index] != 0)
4191                         return -EBUSY;
4192         }
4193
4194         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4195                 if (m->rindex < c->end)
4196                         return -EBUSY;
4197
4198         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
4199                 uint32_t l;
4200
4201                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4202                 if (c->begin + l != m->rindex)
4203                         return -EBUSY;
4204         }
4205
4206         free(c->signature);
4207         free(c->peeked_signature);
4208         free(c->offsets);
4209         m->n_containers--;
4210
4211         c = message_get_container(m);
4212
4213         saved = c->index;
4214         c->index = c->saved_index;
4215         r = container_next_item(m, c, &m->rindex);
4216         c->index = saved;
4217         if (r < 0)
4218                 return r;
4219
4220         return 1;
4221 }
4222
4223 static void message_quit_container(sd_bus_message *m) {
4224         struct bus_container *c;
4225
4226         assert(m);
4227         assert(m->sealed);
4228         assert(m->n_containers > 0);
4229
4230         c = message_get_container(m);
4231
4232         /* Undo seeks */
4233         assert(m->rindex >= c->before);
4234         m->rindex = c->before;
4235
4236         /* Free container */
4237         free(c->signature);
4238         free(c->offsets);
4239         m->n_containers--;
4240
4241         /* Correct index of new top-level container */
4242         c = message_get_container(m);
4243         c->index = c->saved_index;
4244 }
4245
4246 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4247         struct bus_container *c;
4248         int r;
4249
4250         assert_return(m, -EINVAL);
4251         assert_return(m->sealed, -EPERM);
4252
4253         if (message_end_of_signature(m))
4254                 goto eof;
4255
4256         if (message_end_of_array(m, m->rindex))
4257                 goto eof;
4258
4259         c = message_get_container(m);
4260
4261         if (bus_type_is_basic(c->signature[c->index])) {
4262                 if (contents)
4263                         *contents = NULL;
4264                 if (type)
4265                         *type = c->signature[c->index];
4266                 return 1;
4267         }
4268
4269         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4270
4271                 if (contents) {
4272                         size_t l;
4273                         char *sig;
4274
4275                         r = signature_element_length(c->signature+c->index+1, &l);
4276                         if (r < 0)
4277                                 return r;
4278
4279                         assert(l >= 1);
4280
4281                         sig = strndup(c->signature + c->index + 1, l);
4282                         if (!sig)
4283                                 return -ENOMEM;
4284
4285                         free(c->peeked_signature);
4286                         *contents = c->peeked_signature = sig;
4287                 }
4288
4289                 if (type)
4290                         *type = SD_BUS_TYPE_ARRAY;
4291
4292                 return 1;
4293         }
4294
4295         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4296             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4297
4298                 if (contents) {
4299                         size_t l;
4300                         char *sig;
4301
4302                         r = signature_element_length(c->signature+c->index, &l);
4303                         if (r < 0)
4304                                 return r;
4305
4306                         assert(l >= 2);
4307                         sig = strndup(c->signature + c->index + 1, l - 2);
4308                         if (!sig)
4309                                 return -ENOMEM;
4310
4311                         free(c->peeked_signature);
4312                         *contents = c->peeked_signature = sig;
4313                 }
4314
4315                 if (type)
4316                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4317
4318                 return 1;
4319         }
4320
4321         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4322                 if (contents) {
4323                         void *q;
4324
4325                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4326                                 size_t k;
4327
4328                                 if (c->item_size < 2)
4329                                         return -EBADMSG;
4330
4331                                 /* Look for the NUL delimiter that
4332                                    separates the payload from the
4333                                    signature. Since the body might be
4334                                    in a different part that then the
4335                                    signature we map byte by byte. */
4336
4337                                 for (k = 2; k <= c->item_size; k++) {
4338                                         size_t where;
4339
4340                                         where = m->rindex + c->item_size - k;
4341                                         r = message_peek_body(m, &where, 1, k, &q);
4342                                         if (r < 0)
4343                                                 return r;
4344
4345                                         if (*(char*) q == 0)
4346                                                 break;
4347                                 }
4348
4349                                 if (k > c->item_size)
4350                                         return -EBADMSG;
4351
4352                                 free(c->peeked_signature);
4353                                 c->peeked_signature = strndup((char*) q + 1, k - 1);
4354                                 if (!c->peeked_signature)
4355                                         return -ENOMEM;
4356
4357                                 if (!signature_is_valid(c->peeked_signature, true))
4358                                         return -EBADMSG;
4359
4360                                 *contents = c->peeked_signature;
4361                         } else {
4362                                 size_t rindex, l;
4363
4364                                 rindex = m->rindex;
4365                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4366                                 if (r < 0)
4367                                         return r;
4368
4369                                 l = *(uint8_t*) q;
4370                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4371                                 if (r < 0)
4372                                         return r;
4373
4374                                 if (!validate_signature(q, l))
4375                                         return -EBADMSG;
4376
4377                                 *contents = q;
4378                         }
4379                 }
4380
4381                 if (type)
4382                         *type = SD_BUS_TYPE_VARIANT;
4383
4384                 return 1;
4385         }
4386
4387         return -EINVAL;
4388
4389 eof:
4390         if (type)
4391                 *type = 0;
4392         if (contents)
4393                 *contents = NULL;
4394         return 0;
4395 }
4396
4397 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4398         struct bus_container *c;
4399
4400         assert_return(m, -EINVAL);
4401         assert_return(m->sealed, -EPERM);
4402
4403         if (complete) {
4404                 message_reset_containers(m);
4405                 m->rindex = 0;
4406
4407                 c = message_get_container(m);
4408         } else {
4409                 c = message_get_container(m);
4410
4411                 c->offset_index = 0;
4412                 c->index = 0;
4413                 m->rindex = c->begin;
4414         }
4415
4416         c->offset_index = 0;
4417         c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4418
4419         return !isempty(c->signature);
4420 }
4421
4422 static int message_read_ap(
4423                 sd_bus_message *m,
4424                 const char *types,
4425                 va_list ap) {
4426
4427         unsigned n_array, n_struct;
4428         TypeStack stack[BUS_CONTAINER_DEPTH];
4429         unsigned stack_ptr = 0;
4430         unsigned n_loop = 0;
4431         int r;
4432
4433         assert(m);
4434
4435         if (isempty(types))
4436                 return 0;
4437
4438         /* Ideally, we'd just call ourselves recursively on every
4439          * complex type. However, the state of a va_list that is
4440          * passed to a function is undefined after that function
4441          * returns. This means we need to docode the va_list linearly
4442          * in a single stackframe. We hence implement our own
4443          * home-grown stack in an array. */
4444
4445         n_array = (unsigned) -1; /* length of current array entries */
4446         n_struct = strlen(types); /* length of current struct contents signature */
4447
4448         for (;;) {
4449                 const char *t;
4450
4451                 n_loop++;
4452
4453                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4454                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4455                         if (r < 0)
4456                                 return r;
4457                         if (r == 0)
4458                                 break;
4459
4460                         r = sd_bus_message_exit_container(m);
4461                         if (r < 0)
4462                                 return r;
4463
4464                         continue;
4465                 }
4466
4467                 t = types;
4468                 if (n_array != (unsigned) -1)
4469                         n_array --;
4470                 else {
4471                         types ++;
4472                         n_struct--;
4473                 }
4474
4475                 switch (*t) {
4476
4477                 case SD_BUS_TYPE_BYTE:
4478                 case SD_BUS_TYPE_BOOLEAN:
4479                 case SD_BUS_TYPE_INT16:
4480                 case SD_BUS_TYPE_UINT16:
4481                 case SD_BUS_TYPE_INT32:
4482                 case SD_BUS_TYPE_UINT32:
4483                 case SD_BUS_TYPE_INT64:
4484                 case SD_BUS_TYPE_UINT64:
4485                 case SD_BUS_TYPE_DOUBLE:
4486                 case SD_BUS_TYPE_STRING:
4487                 case SD_BUS_TYPE_OBJECT_PATH:
4488                 case SD_BUS_TYPE_SIGNATURE:
4489                 case SD_BUS_TYPE_UNIX_FD: {
4490                         void *p;
4491
4492                         p = va_arg(ap, void*);
4493                         r = sd_bus_message_read_basic(m, *t, p);
4494                         if (r < 0)
4495                                 return r;
4496                         if (r == 0) {
4497                                 if (n_loop <= 1)
4498                                         return 0;
4499
4500                                 return -ENXIO;
4501                         }
4502
4503                         break;
4504                 }
4505
4506                 case SD_BUS_TYPE_ARRAY: {
4507                         size_t k;
4508
4509                         r = signature_element_length(t + 1, &k);
4510                         if (r < 0)
4511                                 return r;
4512
4513                         {
4514                                 char s[k + 1];
4515                                 memcpy(s, t + 1, k);
4516                                 s[k] = 0;
4517
4518                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4519                                 if (r < 0)
4520                                         return r;
4521                                 if (r == 0) {
4522                                         if (n_loop <= 1)
4523                                                 return 0;
4524
4525                                         return -ENXIO;
4526                                 }
4527                         }
4528
4529                         if (n_array == (unsigned) -1) {
4530                                 types += k;
4531                                 n_struct -= k;
4532                         }
4533
4534                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4535                         if (r < 0)
4536                                 return r;
4537
4538                         types = t + 1;
4539                         n_struct = k;
4540                         n_array = va_arg(ap, unsigned);
4541
4542                         break;
4543                 }
4544
4545                 case SD_BUS_TYPE_VARIANT: {
4546                         const char *s;
4547
4548                         s = va_arg(ap, const char *);
4549                         if (!s)
4550                                 return -EINVAL;
4551
4552                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4553                         if (r < 0)
4554                                 return r;
4555                         if (r == 0) {
4556                                 if (n_loop <= 1)
4557                                         return 0;
4558
4559                                 return -ENXIO;
4560                         }
4561
4562                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4563                         if (r < 0)
4564                                 return r;
4565
4566                         types = s;
4567                         n_struct = strlen(s);
4568                         n_array = (unsigned) -1;
4569
4570                         break;
4571                 }
4572
4573                 case SD_BUS_TYPE_STRUCT_BEGIN:
4574                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4575                         size_t k;
4576
4577                         r = signature_element_length(t, &k);
4578                         if (r < 0)
4579                                 return r;
4580
4581                         {
4582                                 char s[k - 1];
4583                                 memcpy(s, t + 1, k - 2);
4584                                 s[k - 2] = 0;
4585
4586                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4587                                 if (r < 0)
4588                                         return r;
4589                                 if (r == 0) {
4590                                         if (n_loop <= 1)
4591                                                 return 0;
4592                                         return -ENXIO;
4593                                 }
4594                         }
4595
4596                         if (n_array == (unsigned) -1) {
4597                                 types += k - 1;
4598                                 n_struct -= k - 1;
4599                         }
4600
4601                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4602                         if (r < 0)
4603                                 return r;
4604
4605                         types = t + 1;
4606                         n_struct = k - 2;
4607                         n_array = (unsigned) -1;
4608
4609                         break;
4610                 }
4611
4612                 default:
4613                         return -EINVAL;
4614                 }
4615         }
4616
4617         return 1;
4618 }
4619
4620 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4621         va_list ap;
4622         int r;
4623
4624         assert_return(m, -EINVAL);
4625         assert_return(m->sealed, -EPERM);
4626         assert_return(types, -EINVAL);
4627
4628         va_start(ap, types);
4629         r = message_read_ap(m, types, ap);
4630         va_end(ap);
4631
4632         return r;
4633 }
4634
4635 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4636         int r;
4637
4638         assert_return(m, -EINVAL);
4639         assert_return(m->sealed, -EPERM);
4640
4641         /* If types is NULL, read exactly one element */
4642         if (!types) {
4643                 struct bus_container *c;
4644                 size_t l;
4645
4646                 if (message_end_of_signature(m))
4647                         return -ENXIO;
4648
4649                 if (message_end_of_array(m, m->rindex))
4650                         return 0;
4651
4652                 c = message_get_container(m);
4653
4654                 r = signature_element_length(c->signature + c->index, &l);
4655                 if (r < 0)
4656                         return r;
4657
4658                 types = strndupa(c->signature + c->index, l);
4659         }
4660
4661         switch (*types) {
4662
4663         case 0: /* Nothing to drop */
4664                 return 0;
4665
4666         case SD_BUS_TYPE_BYTE:
4667         case SD_BUS_TYPE_BOOLEAN:
4668         case SD_BUS_TYPE_INT16:
4669         case SD_BUS_TYPE_UINT16:
4670         case SD_BUS_TYPE_INT32:
4671         case SD_BUS_TYPE_UINT32:
4672         case SD_BUS_TYPE_INT64:
4673         case SD_BUS_TYPE_UINT64:
4674         case SD_BUS_TYPE_DOUBLE:
4675         case SD_BUS_TYPE_STRING:
4676         case SD_BUS_TYPE_OBJECT_PATH:
4677         case SD_BUS_TYPE_SIGNATURE:
4678         case SD_BUS_TYPE_UNIX_FD:
4679
4680                 r = sd_bus_message_read_basic(m, *types, NULL);
4681                 if (r <= 0)
4682                         return r;
4683
4684                 r = sd_bus_message_skip(m, types + 1);
4685                 if (r < 0)
4686                         return r;
4687
4688                 return 1;
4689
4690         case SD_BUS_TYPE_ARRAY: {
4691                 size_t k;
4692
4693                 r = signature_element_length(types + 1, &k);
4694                 if (r < 0)
4695                         return r;
4696
4697                 {
4698                         char s[k+1];
4699                         memcpy(s, types+1, k);
4700                         s[k] = 0;
4701
4702                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4703                         if (r <= 0)
4704                                 return r;
4705
4706                         for (;;) {
4707                                 r = sd_bus_message_skip(m, s);
4708                                 if (r < 0)
4709                                         return r;
4710                                 if (r == 0)
4711                                         break;
4712                         }
4713
4714                         r = sd_bus_message_exit_container(m);
4715                         if (r < 0)
4716                                 return r;
4717                 }
4718
4719                 r = sd_bus_message_skip(m, types + 1 + k);
4720                 if (r < 0)
4721                         return r;
4722
4723                 return 1;
4724         }
4725
4726         case SD_BUS_TYPE_VARIANT: {
4727                 const char *contents;
4728                 char x;
4729
4730                 r = sd_bus_message_peek_type(m, &x, &contents);
4731                 if (r <= 0)
4732                         return r;
4733
4734                 if (x != SD_BUS_TYPE_VARIANT)
4735                         return -ENXIO;
4736
4737                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4738                 if (r <= 0)
4739                         return r;
4740
4741                 r = sd_bus_message_skip(m, contents);
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                 r = sd_bus_message_skip(m, types + 1);
4751                 if (r < 0)
4752                         return r;
4753
4754                 return 1;
4755         }
4756
4757         case SD_BUS_TYPE_STRUCT_BEGIN:
4758         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4759                 size_t k;
4760
4761                 r = signature_element_length(types, &k);
4762                 if (r < 0)
4763                         return r;
4764
4765                 {
4766                         char s[k-1];
4767                         memcpy(s, types+1, k-2);
4768                         s[k-2] = 0;
4769
4770                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4771                         if (r <= 0)
4772                                 return r;
4773
4774                         r = sd_bus_message_skip(m, s);
4775                         if (r < 0)
4776                                 return r;
4777
4778                         r = sd_bus_message_exit_container(m);
4779                         if (r < 0)
4780                                 return r;
4781                 }
4782
4783                 r = sd_bus_message_skip(m, types + k);
4784                 if (r < 0)
4785                         return r;
4786
4787                 return 1;
4788         }
4789
4790         default:
4791                 return -EINVAL;
4792         }
4793 }
4794
4795 _public_ int sd_bus_message_read_array(
4796                 sd_bus_message *m,
4797                 char type,
4798                 const void **ptr,
4799                 size_t *size) {
4800
4801         struct bus_container *c;
4802         void *p;
4803         size_t sz;
4804         ssize_t align;
4805         int r;
4806
4807         assert_return(m, -EINVAL);
4808         assert_return(m->sealed, -EPERM);
4809         assert_return(bus_type_is_trivial(type), -EINVAL);
4810         assert_return(ptr, -EINVAL);
4811         assert_return(size, -EINVAL);
4812         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -EOPNOTSUPP);
4813
4814         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4815         if (r <= 0)
4816                 return r;
4817
4818         c = message_get_container(m);
4819
4820         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4821                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4822                 if (align < 0)
4823                         return align;
4824
4825                 sz = c->end - c->begin;
4826         } else {
4827                 align = bus_type_get_alignment(type);
4828                 if (align < 0)
4829                         return align;
4830
4831                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4832         }
4833
4834         if (sz == 0)
4835                 /* Zero length array, let's return some aligned
4836                  * pointer that is not NULL */
4837                 p = (uint8_t*) NULL + align;
4838         else {
4839                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4840                 if (r < 0)
4841                         goto fail;
4842         }
4843
4844         r = sd_bus_message_exit_container(m);
4845         if (r < 0)
4846                 goto fail;
4847
4848         *ptr = (const void*) p;
4849         *size = sz;
4850
4851         return 1;
4852
4853 fail:
4854         message_quit_container(m);
4855         return r;
4856 }
4857
4858 static int message_peek_fields(
4859                 sd_bus_message *m,
4860                 size_t *rindex,
4861                 size_t align,
4862                 size_t nbytes,
4863                 void **ret) {
4864
4865         assert(m);
4866         assert(rindex);
4867         assert(align > 0);
4868
4869         return buffer_peek(BUS_MESSAGE_FIELDS(m), m->fields_size, rindex, align, nbytes, ret);
4870 }
4871
4872 static int message_peek_field_uint32(
4873                 sd_bus_message *m,
4874                 size_t *ri,
4875                 size_t item_size,
4876                 uint32_t *ret) {
4877
4878         int r;
4879         void *q;
4880
4881         assert(m);
4882         assert(ri);
4883
4884         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4885                 return -EBADMSG;
4886
4887         /* identical for gvariant and dbus1 */
4888
4889         r = message_peek_fields(m, ri, 4, 4, &q);
4890         if (r < 0)
4891                 return r;
4892
4893         if (ret)
4894                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4895
4896         return 0;
4897 }
4898
4899 static int message_peek_field_uint64(
4900                 sd_bus_message *m,
4901                 size_t *ri,
4902                 size_t item_size,
4903                 uint64_t *ret) {
4904
4905         int r;
4906         void *q;
4907
4908         assert(m);
4909         assert(ri);
4910
4911         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 8)
4912                 return -EBADMSG;
4913
4914         /* identical for gvariant and dbus1 */
4915
4916         r = message_peek_fields(m, ri, 8, 8, &q);
4917         if (r < 0)
4918                 return r;
4919
4920         if (ret)
4921                 *ret = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
4922
4923         return 0;
4924 }
4925
4926 static int message_peek_field_string(
4927                 sd_bus_message *m,
4928                 bool (*validate)(const char *p),
4929                 size_t *ri,
4930                 size_t item_size,
4931                 const char **ret) {
4932
4933         uint32_t l;
4934         int r;
4935         void *q;
4936
4937         assert(m);
4938         assert(ri);
4939
4940         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4941
4942                 if (item_size <= 0)
4943                         return -EBADMSG;
4944
4945                 r = message_peek_fields(m, ri, 1, item_size, &q);
4946                 if (r < 0)
4947                         return r;
4948
4949                 l = item_size - 1;
4950         } else {
4951                 r = message_peek_field_uint32(m, ri, 4, &l);
4952                 if (r < 0)
4953                         return r;
4954
4955                 r = message_peek_fields(m, ri, 1, l+1, &q);
4956                 if (r < 0)
4957                         return r;
4958         }
4959
4960         if (validate) {
4961                 if (!validate_nul(q, l))
4962                         return -EBADMSG;
4963
4964                 if (!validate(q))
4965                         return -EBADMSG;
4966         } else {
4967                 if (!validate_string(q, l))
4968                         return -EBADMSG;
4969         }
4970
4971         if (ret)
4972                 *ret = q;
4973
4974         return 0;
4975 }
4976
4977 static int message_peek_field_signature(
4978                 sd_bus_message *m,
4979                 size_t *ri,
4980                 size_t item_size,
4981                 const char **ret) {
4982
4983         size_t l;
4984         int r;
4985         void *q;
4986
4987         assert(m);
4988         assert(ri);
4989
4990         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4991
4992                 if (item_size <= 0)
4993                         return -EBADMSG;
4994
4995                 r = message_peek_fields(m, ri, 1, item_size, &q);
4996                 if (r < 0)
4997                         return r;
4998
4999                 l = item_size - 1;
5000         } else {
5001                 r = message_peek_fields(m, ri, 1, 1, &q);
5002                 if (r < 0)
5003                         return r;
5004
5005                 l = *(uint8_t*) q;
5006                 r = message_peek_fields(m, ri, 1, l+1, &q);
5007                 if (r < 0)
5008                         return r;
5009         }
5010
5011         if (!validate_signature(q, l))
5012                 return -EBADMSG;
5013
5014         if (ret)
5015                 *ret = q;
5016
5017         return 0;
5018 }
5019
5020 static int message_skip_fields(
5021                 sd_bus_message *m,
5022                 size_t *ri,
5023                 uint32_t array_size,
5024                 const char **signature) {
5025
5026         size_t original_index;
5027         int r;
5028
5029         assert(m);
5030         assert(ri);
5031         assert(signature);
5032         assert(!BUS_MESSAGE_IS_GVARIANT(m));
5033
5034         original_index = *ri;
5035
5036         for (;;) {
5037                 char t;
5038                 size_t l;
5039
5040                 if (array_size != (uint32_t) -1 &&
5041                     array_size <= *ri - original_index)
5042                         return 0;
5043
5044                 t = **signature;
5045                 if (!t)
5046                         return 0;
5047
5048                 if (t == SD_BUS_TYPE_STRING) {
5049
5050                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
5051                         if (r < 0)
5052                                 return r;
5053
5054                         (*signature)++;
5055
5056                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
5057
5058                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
5059                         if (r < 0)
5060                                 return r;
5061
5062                         (*signature)++;
5063
5064                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
5065
5066                         r = message_peek_field_signature(m, ri, 0, NULL);
5067                         if (r < 0)
5068                                 return r;
5069
5070                         (*signature)++;
5071
5072                 } else if (bus_type_is_basic(t)) {
5073                         ssize_t align, k;
5074
5075                         align = bus_type_get_alignment(t);
5076                         k = bus_type_get_size(t);
5077                         assert(align > 0 && k > 0);
5078
5079                         r = message_peek_fields(m, ri, align, k, NULL);
5080                         if (r < 0)
5081                                 return r;
5082
5083                         (*signature)++;
5084
5085                 } else if (t == SD_BUS_TYPE_ARRAY) {
5086
5087                         r = signature_element_length(*signature+1, &l);
5088                         if (r < 0)
5089                                 return r;
5090
5091                         assert(l >= 1);
5092                         {
5093                                 char sig[l-1], *s;
5094                                 uint32_t nas;
5095                                 int alignment;
5096
5097                                 strncpy(sig, *signature + 1, l-1);
5098                                 s = sig;
5099
5100                                 alignment = bus_type_get_alignment(sig[0]);
5101                                 if (alignment < 0)
5102                                         return alignment;
5103
5104                                 r = message_peek_field_uint32(m, ri, 0, &nas);
5105                                 if (r < 0)
5106                                         return r;
5107                                 if (nas > BUS_ARRAY_MAX_SIZE)
5108                                         return -EBADMSG;
5109
5110                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
5111                                 if (r < 0)
5112                                         return r;
5113
5114                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
5115                                 if (r < 0)
5116                                         return r;
5117                         }
5118
5119                         (*signature) += 1 + l;
5120
5121                 } else if (t == SD_BUS_TYPE_VARIANT) {
5122                         const char *s;
5123
5124                         r = message_peek_field_signature(m, ri, 0, &s);
5125                         if (r < 0)
5126                                 return r;
5127
5128                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5129                         if (r < 0)
5130                                 return r;
5131
5132                         (*signature)++;
5133
5134                 } else if (t == SD_BUS_TYPE_STRUCT ||
5135                            t == SD_BUS_TYPE_DICT_ENTRY) {
5136
5137                         r = signature_element_length(*signature, &l);
5138                         if (r < 0)
5139                                 return r;
5140
5141                         assert(l >= 2);
5142                         {
5143                                 char sig[l-1], *s;
5144                                 strncpy(sig, *signature + 1, l-1);
5145                                 s = sig;
5146
5147                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5148                                 if (r < 0)
5149                                         return r;
5150                         }
5151
5152                         *signature += l;
5153                 } else
5154                         return -EINVAL;
5155         }
5156 }
5157
5158 int bus_message_parse_fields(sd_bus_message *m) {
5159         size_t ri;
5160         int r;
5161         uint32_t unix_fds = 0;
5162         bool unix_fds_set = false;
5163         void *offsets = NULL;
5164         unsigned n_offsets = 0;
5165         size_t sz = 0;
5166         unsigned i = 0;
5167
5168         assert(m);
5169
5170         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5171                 char *p;
5172
5173                 /* Read the signature from the end of the body variant first */
5174                 sz = bus_gvariant_determine_word_size(BUS_MESSAGE_SIZE(m), 0);
5175                 if (m->footer_accessible < 1 + sz)
5176                         return -EBADMSG;
5177
5178                 p = (char*) m->footer + m->footer_accessible - (1 + sz);
5179                 for (;;) {
5180                         if (p < (char*) m->footer)
5181                                 return -EBADMSG;
5182
5183                         if (*p == 0) {
5184                                 size_t l;
5185                                 char *c;
5186
5187                                 /* We found the beginning of the signature
5188                                  * string, yay! We require the body to be a
5189                                  * structure, so verify it and then strip the
5190                                  * opening/closing brackets. */
5191
5192                                 l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
5193                                 if (l < 2 ||
5194                                     p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
5195                                     p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
5196                                         return -EBADMSG;
5197
5198                                 c = strndup(p + 1 + 1, l - 2);
5199                                 if (!c)
5200                                         return -ENOMEM;
5201
5202                                 free(m->root_container.signature);
5203                                 m->root_container.signature = c;
5204                                 break;
5205                         }
5206
5207                         p--;
5208                 }
5209
5210                 /* Calculate the actual user body size, by removing
5211                  * the trailing variant signature and struct offset
5212                  * table */
5213                 m->user_body_size = m->body_size - ((char*) m->footer + m->footer_accessible - p);
5214
5215                 /* Pull out the offset table for the fields array */
5216                 sz = bus_gvariant_determine_word_size(m->fields_size, 0);
5217                 if (sz > 0) {
5218                         size_t framing;
5219                         void *q;
5220
5221                         ri = m->fields_size - sz;
5222                         r = message_peek_fields(m, &ri, 1, sz, &q);
5223                         if (r < 0)
5224                                 return r;
5225
5226                         framing = bus_gvariant_read_word_le(q, sz);
5227                         if (framing >= m->fields_size - sz)
5228                                 return -EBADMSG;
5229                         if ((m->fields_size - framing) % sz != 0)
5230                                 return -EBADMSG;
5231
5232                         ri = framing;
5233                         r = message_peek_fields(m, &ri, 1, m->fields_size - framing, &offsets);
5234                         if (r < 0)
5235                                 return r;
5236
5237                         n_offsets = (m->fields_size - framing) / sz;
5238                 }
5239         } else
5240                 m->user_body_size = m->body_size;
5241
5242         ri = 0;
5243         while (ri < m->fields_size) {
5244                 _cleanup_free_ char *sig = NULL;
5245                 const char *signature;
5246                 uint64_t field_type;
5247                 size_t item_size = (size_t) -1;
5248
5249                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5250                         uint64_t *u64;
5251
5252                         if (i >= n_offsets)
5253                                 break;
5254
5255                         if (i == 0)
5256                                 ri = 0;
5257                         else
5258                                 ri = ALIGN_TO(bus_gvariant_read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
5259
5260                         r = message_peek_fields(m, &ri, 8, 8, (void**) &u64);
5261                         if (r < 0)
5262                                 return r;
5263
5264                         field_type = BUS_MESSAGE_BSWAP64(m, *u64);
5265                 } else {
5266                         uint8_t *u8;
5267
5268                         r = message_peek_fields(m, &ri, 8, 1, (void**) &u8);
5269                         if (r < 0)
5270                                 return r;
5271
5272                         field_type = *u8;
5273                 }
5274
5275                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5276                         size_t where, end;
5277                         char *b;
5278                         void *q;
5279
5280                         end = bus_gvariant_read_word_le((uint8_t*) offsets + i*sz, sz);
5281
5282                         if (end < ri)
5283                                 return -EBADMSG;
5284
5285                         where = ri = ALIGN_TO(ri, 8);
5286                         item_size = end - ri;
5287                         r = message_peek_fields(m, &where, 1, item_size, &q);
5288                         if (r < 0)
5289                                 return r;
5290
5291                         b = memrchr(q, 0, item_size);
5292                         if (!b)
5293                                 return -EBADMSG;
5294
5295                         sig = strndup(b+1, item_size - (b+1-(char*) q));
5296                         if (!sig)
5297                                 return -ENOMEM;
5298
5299                         signature = sig;
5300                         item_size = b - (char*) q;
5301                 } else {
5302                         r = message_peek_field_signature(m, &ri, 0, &signature);
5303                         if (r < 0)
5304                                 return r;
5305                 }
5306
5307                 switch (field_type) {
5308
5309                 case _BUS_MESSAGE_HEADER_INVALID:
5310                         return -EBADMSG;
5311
5312                 case BUS_MESSAGE_HEADER_PATH:
5313
5314                         if (m->path)
5315                                 return -EBADMSG;
5316
5317                         if (!streq(signature, "o"))
5318                                 return -EBADMSG;
5319
5320                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
5321                         break;
5322
5323                 case BUS_MESSAGE_HEADER_INTERFACE:
5324
5325                         if (m->interface)
5326                                 return -EBADMSG;
5327
5328                         if (!streq(signature, "s"))
5329                                 return -EBADMSG;
5330
5331                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5332                         break;
5333
5334                 case BUS_MESSAGE_HEADER_MEMBER:
5335
5336                         if (m->member)
5337                                 return -EBADMSG;
5338
5339                         if (!streq(signature, "s"))
5340                                 return -EBADMSG;
5341
5342                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5343                         break;
5344
5345                 case BUS_MESSAGE_HEADER_ERROR_NAME:
5346
5347                         if (m->error.name)
5348                                 return -EBADMSG;
5349
5350                         if (!streq(signature, "s"))
5351                                 return -EBADMSG;
5352
5353                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5354                         if (r >= 0)
5355                                 m->error._need_free = -1;
5356
5357                         break;
5358
5359                 case BUS_MESSAGE_HEADER_DESTINATION:
5360
5361                         if (m->destination)
5362                                 return -EBADMSG;
5363
5364                         if (!streq(signature, "s"))
5365                                 return -EBADMSG;
5366
5367                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5368                         break;
5369
5370                 case BUS_MESSAGE_HEADER_SENDER:
5371
5372                         if (m->sender)
5373                                 return -EBADMSG;
5374
5375                         if (!streq(signature, "s"))
5376                                 return -EBADMSG;
5377
5378                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5379
5380                         if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5381                                 m->creds.unique_name = (char*) m->sender;
5382                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5383                         }
5384
5385                         break;
5386
5387
5388                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5389                         const char *s;
5390                         char *c;
5391
5392                         if (BUS_MESSAGE_IS_GVARIANT(m)) /* only applies to dbus1 */
5393                                 return -EBADMSG;
5394
5395                         if (m->root_container.signature)
5396                                 return -EBADMSG;
5397
5398                         if (!streq(signature, "g"))
5399                                 return -EBADMSG;
5400
5401                         r = message_peek_field_signature(m, &ri, item_size, &s);
5402                         if (r < 0)
5403                                 return r;
5404
5405                         c = strdup(s);
5406                         if (!c)
5407                                 return -ENOMEM;
5408
5409                         free(m->root_container.signature);
5410                         m->root_container.signature = c;
5411                         break;
5412                 }
5413
5414                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5415
5416                         if (m->reply_cookie != 0)
5417                                 return -EBADMSG;
5418
5419                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5420                                 /* 64bit on dbus2 */
5421
5422                                 if (!streq(signature, "t"))
5423                                         return -EBADMSG;
5424
5425                                 r = message_peek_field_uint64(m, &ri, item_size, &m->reply_cookie);
5426                                 if (r < 0)
5427                                         return r;
5428                         } else {
5429                                 /* 32bit on dbus1 */
5430                                 uint32_t serial;
5431
5432                                 if (!streq(signature, "u"))
5433                                         return -EBADMSG;
5434
5435                                 r = message_peek_field_uint32(m, &ri, item_size, &serial);
5436                                 if (r < 0)
5437                                         return r;
5438
5439                                 m->reply_cookie = serial;
5440                         }
5441
5442                         if (m->reply_cookie == 0)
5443                                 return -EBADMSG;
5444
5445                         break;
5446
5447                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5448                         if (unix_fds_set)
5449                                 return -EBADMSG;
5450
5451                         if (!streq(signature, "u"))
5452                                 return -EBADMSG;
5453
5454                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5455                         if (r < 0)
5456                                 return -EBADMSG;
5457
5458                         unix_fds_set = true;
5459                         break;
5460
5461                 default:
5462                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5463                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5464                 }
5465
5466                 if (r < 0)
5467                         return r;
5468
5469                 i++;
5470         }
5471
5472         if (m->n_fds != unix_fds)
5473                 return -EBADMSG;
5474
5475         switch (m->header->type) {
5476
5477         case SD_BUS_MESSAGE_SIGNAL:
5478                 if (!m->path || !m->interface || !m->member)
5479                         return -EBADMSG;
5480
5481                 if (m->reply_cookie != 0)
5482                         return -EBADMSG;
5483
5484                 break;
5485
5486         case SD_BUS_MESSAGE_METHOD_CALL:
5487
5488                 if (!m->path || !m->member)
5489                         return -EBADMSG;
5490
5491                 if (m->reply_cookie != 0)
5492                         return -EBADMSG;
5493
5494                 break;
5495
5496         case SD_BUS_MESSAGE_METHOD_RETURN:
5497
5498                 if (m->reply_cookie == 0)
5499                         return -EBADMSG;
5500                 break;
5501
5502         case SD_BUS_MESSAGE_METHOD_ERROR:
5503
5504                 if (m->reply_cookie == 0 || !m->error.name)
5505                         return -EBADMSG;
5506                 break;
5507         }
5508
5509         /* Refuse non-local messages that claim they are local */
5510         if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5511                 return -EBADMSG;
5512         if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5513                 return -EBADMSG;
5514         if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5515                 return -EBADMSG;
5516
5517         m->root_container.end = m->user_body_size;
5518
5519         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5520                 r = build_struct_offsets(
5521                                 m,
5522                                 m->root_container.signature,
5523                                 m->user_body_size,
5524                                 &m->root_container.item_size,
5525                                 &m->root_container.offsets,
5526                                 &m->root_container.n_offsets);
5527                 if (r < 0)
5528                         return r;
5529         }
5530
5531         /* Try to read the error message, but if we can't it's a non-issue */
5532         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5533                 (void) sd_bus_message_read(m, "s", &m->error.message);
5534
5535         return 0;
5536 }
5537
5538 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5539         assert_return(m, -EINVAL);
5540         assert_return(destination, -EINVAL);
5541         assert_return(!m->sealed, -EPERM);
5542         assert_return(!m->destination, -EEXIST);
5543
5544         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5545 }
5546
5547 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5548         size_t total;
5549         void *p, *e;
5550         unsigned i;
5551         struct bus_body_part *part;
5552
5553         assert(m);
5554         assert(buffer);
5555         assert(sz);
5556
5557         total = BUS_MESSAGE_SIZE(m);
5558
5559         p = malloc(total);
5560         if (!p)
5561                 return -ENOMEM;
5562
5563         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5564         MESSAGE_FOREACH_PART(part, i, m)
5565                 e = mempcpy(e, part->data, part->size);
5566
5567         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5568
5569         *buffer = p;
5570         *sz = total;
5571
5572         return 0;
5573 }
5574
5575 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5576         const char *s;
5577         int r;
5578
5579         assert(m);
5580         assert(l);
5581
5582         r = sd_bus_message_enter_container(m, 'a', "s");
5583         if (r <= 0)
5584                 return r;
5585
5586         while ((r = sd_bus_message_read_basic(m, 's', &s)) > 0) {
5587                 r = strv_extend(l, s);
5588                 if (r < 0)
5589                         return r;
5590         }
5591         if (r < 0)
5592                 return r;
5593
5594         r = sd_bus_message_exit_container(m);
5595         if (r < 0)
5596                 return r;
5597
5598         return 1;
5599 }
5600
5601 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5602         char **strv = NULL;
5603         int r;
5604
5605         assert_return(m, -EINVAL);
5606         assert_return(m->sealed, -EPERM);
5607         assert_return(l, -EINVAL);
5608
5609         r = bus_message_read_strv_extend(m, &strv);
5610         if (r <= 0) {
5611                 strv_free(strv);
5612                 return r;
5613         }
5614
5615         *l = strv;
5616         return 1;
5617 }
5618
5619 int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv) {
5620         const char *contents;
5621         unsigned j;
5622         char type;
5623         int r;
5624
5625         assert(m);
5626         assert(str);
5627         assert(strv);
5628
5629         r = sd_bus_message_rewind(m, true);
5630         if (r < 0)
5631                 return r;
5632
5633         for (j = 0;; j++) {
5634                 r = sd_bus_message_peek_type(m, &type, &contents);
5635                 if (r < 0)
5636                         return r;
5637                 if (r == 0)
5638                         return -ENXIO;
5639
5640                 /* Don't match against arguments after the first one we don't understand */
5641                 if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE) &&
5642                     !(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
5643                         return -ENXIO;
5644
5645                 if (j >= i)
5646                         break;
5647
5648                 r = sd_bus_message_skip(m, NULL);
5649                 if (r < 0)
5650                         return r;
5651         }
5652
5653         if (type == SD_BUS_TYPE_ARRAY) {
5654
5655                 r = sd_bus_message_read_strv(m, strv);
5656                 if (r < 0)
5657                         return r;
5658
5659                 *str = NULL;
5660
5661         } else {
5662                 r = sd_bus_message_read_basic(m, type, str);
5663                 if (r < 0)
5664                         return r;
5665
5666                 *strv = NULL;
5667         }
5668
5669         return 0;
5670 }
5671
5672 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5673         assert_return(m, EINVAL);
5674
5675         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5676                 return 0;
5677
5678         return sd_bus_error_get_errno(&m->error);
5679 }
5680
5681 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5682         struct bus_container *c;
5683
5684         assert_return(m, NULL);
5685
5686         c = complete ? &m->root_container : message_get_container(m);
5687         return strempty(c->signature);
5688 }
5689
5690 _public_ int sd_bus_message_is_empty(sd_bus_message *m) {
5691         assert_return(m, -EINVAL);
5692
5693         return isempty(m->root_container.signature);
5694 }
5695
5696 _public_ int sd_bus_message_has_signature(sd_bus_message *m, const char *signature) {
5697         assert_return(m, -EINVAL);
5698
5699         return streq(strempty(m->root_container.signature), strempty(signature));
5700 }
5701
5702 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5703         bool done_something = false;
5704         int r;
5705
5706         assert_return(m, -EINVAL);
5707         assert_return(source, -EINVAL);
5708         assert_return(!m->sealed, -EPERM);
5709         assert_return(source->sealed, -EPERM);
5710
5711         do {
5712                 const char *contents;
5713                 char type;
5714                 union {
5715                         uint8_t u8;
5716                         uint16_t u16;
5717                         int16_t s16;
5718                         uint32_t u32;
5719                         int32_t s32;
5720                         uint64_t u64;
5721                         int64_t s64;
5722                         double d64;
5723                         const char *string;
5724                         int i;
5725                 } basic;
5726
5727                 r = sd_bus_message_peek_type(source, &type, &contents);
5728                 if (r < 0)
5729                         return r;
5730                 if (r == 0)
5731                         break;
5732
5733                 done_something = true;
5734
5735                 if (bus_type_is_container(type) > 0) {
5736
5737                         r = sd_bus_message_enter_container(source, type, contents);
5738                         if (r < 0)
5739                                 return r;
5740
5741                         r = sd_bus_message_open_container(m, type, contents);
5742                         if (r < 0)
5743                                 return r;
5744
5745                         r = sd_bus_message_copy(m, source, true);
5746                         if (r < 0)
5747                                 return r;
5748
5749                         r = sd_bus_message_close_container(m);
5750                         if (r < 0)
5751                                 return r;
5752
5753                         r = sd_bus_message_exit_container(source);
5754                         if (r < 0)
5755                                 return r;
5756
5757                         continue;
5758                 }
5759
5760                 r = sd_bus_message_read_basic(source, type, &basic);
5761                 if (r < 0)
5762                         return r;
5763
5764                 assert(r > 0);
5765
5766                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5767                     type == SD_BUS_TYPE_SIGNATURE ||
5768                     type == SD_BUS_TYPE_STRING)
5769                         r = sd_bus_message_append_basic(m, type, basic.string);
5770                 else
5771                         r = sd_bus_message_append_basic(m, type, &basic);
5772
5773                 if (r < 0)
5774                         return r;
5775
5776         } while (all);
5777
5778         return done_something;
5779 }
5780
5781 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5782         const char *c;
5783         char t;
5784         int r;
5785
5786         assert_return(m, -EINVAL);
5787         assert_return(m->sealed, -EPERM);
5788         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5789         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5790         assert_return(type || contents, -EINVAL);
5791         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5792
5793         r = sd_bus_message_peek_type(m, &t, &c);
5794         if (r <= 0)
5795                 return r;
5796
5797         if (type != 0 && type != t)
5798                 return 0;
5799
5800         if (contents && !streq_ptr(contents, c))
5801                 return 0;
5802
5803         return 1;
5804 }
5805
5806 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5807         assert_return(m, NULL);
5808
5809         return m->bus;
5810 }
5811
5812 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5813         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5814         usec_t timeout;
5815         int r;
5816
5817         assert(bus);
5818         assert(m);
5819         assert(*m);
5820
5821         switch ((*m)->header->type) {
5822
5823         case SD_BUS_MESSAGE_SIGNAL:
5824                 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5825                 if (r < 0)
5826                         return r;
5827
5828                 break;
5829
5830         case SD_BUS_MESSAGE_METHOD_CALL:
5831                 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5832                 if (r < 0)
5833                         return r;
5834
5835                 break;
5836
5837         case SD_BUS_MESSAGE_METHOD_RETURN:
5838         case SD_BUS_MESSAGE_METHOD_ERROR:
5839
5840                 n = message_new(bus, (*m)->header->type);
5841                 if (!n)
5842                         return -ENOMEM;
5843
5844                 n->reply_cookie = (*m)->reply_cookie;
5845
5846                 r = message_append_reply_cookie(n, n->reply_cookie);
5847                 if (r < 0)
5848                         return r;
5849
5850                 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5851                         r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5852                         if (r < 0)
5853                                 return r;
5854
5855                         n->error._need_free = -1;
5856                 }
5857
5858                 break;
5859
5860         default:
5861                 return -EINVAL;
5862         }
5863
5864         if ((*m)->destination && !n->destination) {
5865                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5866                 if (r < 0)
5867                         return r;
5868         }
5869
5870         if ((*m)->sender && !n->sender) {
5871                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5872                 if (r < 0)
5873                         return r;
5874         }
5875
5876         n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5877
5878         r = sd_bus_message_copy(n, *m, true);
5879         if (r < 0)
5880                 return r;
5881
5882         timeout = (*m)->timeout;
5883         if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5884                 timeout = BUS_DEFAULT_TIMEOUT;
5885
5886         r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5887         if (r < 0)
5888                 return r;
5889
5890         sd_bus_message_unref(*m);
5891         *m = n;
5892         n = NULL;
5893
5894         return 0;
5895 }
5896
5897 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5898         assert(m);
5899         assert(sender);
5900
5901         assert_return(!m->sealed, -EPERM);
5902         assert_return(!m->sender, -EPERM);
5903
5904         return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5905 }
5906
5907 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5908         assert_return(m, -EINVAL);
5909         assert_return(priority, -EINVAL);
5910
5911         *priority = m->priority;
5912         return 0;
5913 }
5914
5915 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5916         assert_return(m, -EINVAL);
5917         assert_return(!m->sealed, -EPERM);
5918
5919         m->priority = priority;
5920         return 0;
5921 }