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