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