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