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