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