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