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