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