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