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