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