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